| 
					
				 | 
			
			
				@@ -4,10 +4,14 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define CONNECTION_PRIVATE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define TOR_CHANNEL_INTERNAL_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define CONTROL_PRIVATE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define OCIRC_EVENT_PRIVATE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define ORCONN_EVENT_PRIVATE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/or/or.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/or/channel.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/or/channeltls.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/or/circuitlist.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "core/or/ocirc_event.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "core/or/orconn_event.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "core/mainloop/connection.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "feature/control/control.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "test/test.h" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -351,10 +355,10 @@ test_cntev_dirboot_defer_desc(void *arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* This event should get deferred */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   control_event_boot_dir(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   assert_bootmsg("0 TAG=starting"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DIR, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_bootmsg("5 TAG=conn_dir"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  control_event_bootstrap(BOOTSTRAP_STATUS_CONN, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("5 TAG=conn"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_bootmsg("10 TAG=handshake_dir"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("14 TAG=handshake"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* The deferred event should appear */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   control_event_boot_first_orconn(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   assert_bootmsg("45 TAG=requesting_descriptors"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -374,21 +378,159 @@ test_cntev_dirboot_defer_orconn(void *arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   assert_bootmsg("0 TAG=starting"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* This event should get deferred */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  control_event_boot_dir(BOOTSTRAP_STATUS_CONN_OR, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  control_event_boot_dir(BOOTSTRAP_STATUS_ENOUGH_DIRINFO, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   assert_bootmsg("0 TAG=starting"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DIR, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_bootmsg("5 TAG=conn_dir"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  control_event_bootstrap(BOOTSTRAP_STATUS_CONN, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("5 TAG=conn"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_bootmsg("10 TAG=handshake_dir"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("14 TAG=handshake"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* The deferred event should appear */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   control_event_boot_first_orconn(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  assert_bootmsg("80 TAG=conn_or"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("75 TAG=enough_dirinfo"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(saved_event_str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   UNMOCK(queue_control_event_string); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#define TEST(name, flags)                                               \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+setup_orconn_state(orconn_event_msg_t *msg, uint64_t gid, uint64_t chan, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                   int proxy_type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  msg->type = ORCONN_MSGTYPE_STATE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  msg->u.state.gid = gid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  msg->u.state.chan = chan; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  msg->u.state.proxy_type = proxy_type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+send_orconn_state(orconn_event_msg_t *msg, uint8_t state) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  msg->u.state.state = state; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  orconn_event_publish(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+send_ocirc_chan(uint32_t gid, uint64_t chan, bool onehop) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ocirc_event_msg_t msg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  msg.type = OCIRC_MSGTYPE_CHAN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  msg.u.chan.gid = gid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  msg.u.chan.chan = chan; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  msg.u.chan.onehop = onehop; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ocirc_event_publish(&msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+test_cntev_orconn_state(void *arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  orconn_event_msg_t conn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (void)arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MOCK(queue_control_event_string, mock_queue_control_event_string); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  setup_orconn_state(&conn, 1, 1, PROXY_NONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_CONNECTING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_ocirc_chan(1, 1, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("5 TAG=conn"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_TLS_HANDSHAKING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("10 TAG=conn_done"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_OR_HANDSHAKING_V3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("14 TAG=handshake"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_OPEN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("15 TAG=handshake_done"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  conn.u.state.gid = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  conn.u.state.chan = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_CONNECTING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* It doesn't know it's an origin circuit yet */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("15 TAG=handshake_done"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_ocirc_chan(2, 2, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("80 TAG=ap_conn"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_TLS_HANDSHAKING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("85 TAG=ap_conn_done"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_OR_HANDSHAKING_V3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("89 TAG=ap_handshake"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_OPEN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("90 TAG=ap_handshake_done"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_free(saved_event_str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  UNMOCK(queue_control_event_string); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+test_cntev_orconn_state_pt(void *arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  orconn_event_msg_t conn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (void)arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MOCK(queue_control_event_string, mock_queue_control_event_string); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  setup_orconn_state(&conn, 1, 1, PROXY_PLUGGABLE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_ocirc_chan(1, 1, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_CONNECTING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("1 TAG=conn_pt"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_PROXY_HANDSHAKING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("2 TAG=conn_done_pt"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_TLS_HANDSHAKING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("10 TAG=conn_done"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_OR_HANDSHAKING_V3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("14 TAG=handshake"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_OPEN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("15 TAG=handshake_done"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_ocirc_chan(2, 2, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  conn.u.state.gid = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  conn.u.state.chan = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_CONNECTING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("76 TAG=ap_conn_pt"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_PROXY_HANDSHAKING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("77 TAG=ap_conn_done_pt"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_free(saved_event_str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  UNMOCK(queue_control_event_string); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+test_cntev_orconn_state_proxy(void *arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  orconn_event_msg_t conn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (void)arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MOCK(queue_control_event_string, mock_queue_control_event_string); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  setup_orconn_state(&conn, 1, 1, PROXY_CONNECT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_ocirc_chan(1, 1, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_CONNECTING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("3 TAG=conn_proxy"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_PROXY_HANDSHAKING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("4 TAG=conn_done_proxy"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_TLS_HANDSHAKING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("10 TAG=conn_done"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_OR_HANDSHAKING_V3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("14 TAG=handshake"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_OPEN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("15 TAG=handshake_done"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_ocirc_chan(2, 2, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  conn.u.state.gid = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  conn.u.state.chan = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_CONNECTING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("78 TAG=ap_conn_proxy"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  send_orconn_state(&conn, OR_CONN_STATE_PROXY_HANDSHAKING); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  assert_bootmsg("79 TAG=ap_conn_done_proxy"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_free(saved_event_str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  UNMOCK(queue_control_event_string); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define TEST(name, flags)                               \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { #name, test_cntev_ ## name, flags, 0, NULL } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 struct testcase_t controller_event_tests[] = { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -398,5 +540,8 @@ struct testcase_t controller_event_tests[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   TEST(event_mask, TT_FORK), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   TEST(dirboot_defer_desc, TT_FORK), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   TEST(dirboot_defer_orconn, TT_FORK), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TEST(orconn_state, TT_FORK), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TEST(orconn_state_pt, TT_FORK), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  TEST(orconn_state_proxy, TT_FORK), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   END_OF_TESTCASES 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 |