Browse Source

In round1c, keep only the highest-priority pub_in messages destined to any given receiver id and turn the rest to padding

Ian Goldberg 10 months ago
parent
commit
80a681a261
1 changed files with 48 additions and 1 deletions
  1. 48 1
      Enclave/route.cpp

+ 48 - 1
Enclave/route.cpp

@@ -1182,7 +1182,54 @@ static void round1c_processing(void *cbpointer) {
         printf("round1a_sorted.inserted = %lu, reserved = %lu, bufsize = %lu\n",
             round1a_sorted.inserted, round1a_sorted.reserved,
             round1a_sorted.bufsize);
-        show_messages("In round 1c", round1a_sorted.buf,
+        show_messages("In round 1c before padding pass", round1a_sorted.buf,
+            round1a_sorted.inserted);
+#endif
+        // The round1a_sorted buffer is now sorted by receiver uid and
+        // priority.  Going from the end of the buffer to the beginning
+        // (so as to encounter and keep the highest-priority messages
+        // for any given receiver first), obliviously turn any messages
+        // over the limit of pub_in for any given receiver into padding.
+        for (uint32_t i=0; i<round1a_sorted.inserted; ++i) {
+            uint8_t *header = round1a_sorted.buf +
+                msg_size * (round1a_sorted.inserted - 1 - i);
+            uint32_t receiver_id = *(uint32_t*)header;
+            uint32_t pub_in = uint32_t(g_teems_config.m_pub_in);
+
+            // These are the possible cases and what we need to do in
+            // each case, but we have to evaluate them obliviously
+
+            // receiver_id != next_receiver_id:
+            //    next_receiver_id = receiver_id
+            //    next_rid_count = 1
+            //    become_padding = 0
+            // receiver_id == next_receiver_id && next_rid_count < pub_in:
+            //    next_receiver_id = receiver_id
+            //    next_rid_count = next_rid_count + 1
+            //    become_padding = 0
+            // receiver_id == next_receiver_id && next_rid_count >= pub_in:
+            //    next_receiver_id = receiver_id
+            //    next_rid_count = next_rid_count
+            //    become_padding = 1
+
+            bool same_receiver_id = (receiver_id == next_receiver_id);
+            // If same_receiver_id is 0, reset next_rid_count to 0.
+            // If same_receiver_id is 1, don't change next_rid_count.
+            // This method (AND with -same_receiver_id) is more likely
+            // to be constant time than multiplying by same_receiver_id.
+            next_rid_count &= (-(uint32_t(same_receiver_id)));
+            bool become_padding = (next_rid_count >= pub_in);
+            next_rid_count += !become_padding;
+            next_receiver_id = receiver_id;
+
+            // Obliviously change the receiver id to 0xffffffff
+            // (padding) if become-padding is 1
+            receiver_id |= (-(uint32_t(become_padding)));
+            *(uint32_t*)header = receiver_id;
+        }
+
+#ifdef TRACE_ROUTING
+        show_messages("In round 1c after padding pass", round1a_sorted.buf,
             round1a_sorted.inserted);
 #endif
         send_round_robin_msgs<UidPriorityKey>(route_state.round1c,