| 
					
				 | 
			
			
				@@ -55,6 +55,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/or/circuitbuild.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/or/circuitlist.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/or/circuituse.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "core/or/circuitpadding.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "lib/compress/compress.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "app/config/config.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/mainloop/connection.h" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -80,7 +81,6 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "feature/nodelist/describe.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "feature/nodelist/routerlist.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/or/scheduler.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#include "feature/stats/rephist.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/or/cell_st.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/or/cell_queue_st.h" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -293,7 +293,9 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /* not recognized. pass it on. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* not recognized. inform circpad and pass it on. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  circpad_deliver_unrecognized_cell_events(circ, cell_direction); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (cell_direction == CELL_DIRECTION_OUT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cell->circ_id = circ->n_circ_id; /* switch it */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     chan = circ->n_chan; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -524,6 +526,7 @@ relay_command_to_string(uint8_t command) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case RELAY_COMMAND_INTRODUCE_ACK: return "INTRODUCE_ACK"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case RELAY_COMMAND_EXTEND2: return "EXTEND2"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case RELAY_COMMAND_EXTENDED2: return "EXTENDED2"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case RELAY_COMMAND_PADDING_NEGOTIATE: return "PADDING_NEGOTIATE"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       tor_snprintf(buf, sizeof(buf), "Unrecognized relay command %u", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    (unsigned)command); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -577,8 +580,8 @@ relay_send_command_from_edge_,(streamid_t stream_id, circuit_t *circ, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   log_debug(LD_OR,"delivering %d cell %s.", relay_command, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cell_direction == CELL_DIRECTION_OUT ? "forward" : "backward"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (relay_command == RELAY_COMMAND_DROP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    rep_hist_padding_count_write(PADDING_TYPE_DROP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Tell circpad we're sending a relay cell */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  circpad_deliver_sent_relay_cell_events(circ, relay_command); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* If we are sending an END cell and this circuit is used for a tunneled 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    * directory request, advance its state. */ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1483,9 +1486,11 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Tell circpad that we've recieved a recognized cell */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  circpad_deliver_recognized_relay_cell_events(circ, rh.command, layer_hint); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* either conn is NULL, in which case we've got a control cell, or else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    * conn points to the recognized stream. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (conn && !connection_state_is_open(TO_CONN(conn))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (conn->base_.type == CONN_TYPE_EXIT && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         (conn->base_.state == EXIT_CONN_STATE_CONNECTING || 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1506,8 +1511,14 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   switch (rh.command) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case RELAY_COMMAND_DROP: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      rep_hist_padding_count_read(PADDING_TYPE_DROP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//      log_info(domain,"Got a relay-level padding cell. Dropping."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /* Already examined in circpad_deliver_recognized_relay_cell_events */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case RELAY_COMMAND_PADDING_NEGOTIATE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      circpad_handle_padding_negotiate(circ, cell); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case RELAY_COMMAND_PADDING_NEGOTIATED: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (circpad_handle_padding_negotiated(circ, cell, layer_hint) == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case RELAY_COMMAND_BEGIN: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     case RELAY_COMMAND_BEGIN_DIR: 
			 |