| 
					
				 | 
			
			
				@@ -392,6 +392,38 @@ connection_edge_finished_flushing(edge_connection_t *conn) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** DOCDOC */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define MAX_CONNECTED_CELL_PAYLOAD_LEN 25 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** DOCDOC */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* private */int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+connected_cell_format_payload(uint8_t *payload_out, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              const tor_addr_t *addr, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              uint32_t ttl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const sa_family_t family = tor_addr_family(addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int connected_payload_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (family == AF_INET) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    set_uint32(payload_out, tor_addr_to_ipv4n(addr)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    connected_payload_len = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else if (family == AF_INET6) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    set_uint32(payload_out, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    set_uint8(payload_out + 4, 6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    memcpy(payload_out + 5, tor_addr_to_in6_addr8(addr), 16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    connected_payload_len = 21; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  set_uint32(payload_out + connected_payload_len, htonl(dns_clip_ttl(ttl))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  connected_payload_len += 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_assert(connected_payload_len <= MAX_CONNECTED_CELL_PAYLOAD_LEN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return connected_payload_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** Connected handler for exit connections: start writing pending 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * data, deliver 'CONNECTED' relay cells as appropriate, and check 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * any pending data that may have been received. */ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -423,22 +455,16 @@ connection_edge_finished_connecting(edge_connection_t *edge_conn) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                      RELAY_COMMAND_CONNECTED, NULL, 0) < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return 0; /* circuit is closed, don't continue */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    char connected_payload[20]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int connected_payload_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (tor_addr_family(&conn->addr) == AF_INET) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      set_uint32(connected_payload, tor_addr_to_ipv4n(&conn->addr)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      set_uint32(connected_payload+4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 htonl(dns_clip_ttl(edge_conn->address_ttl))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      connected_payload_len = 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      memcpy(connected_payload, tor_addr_to_in6_addr8(&conn->addr), 16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      set_uint32(connected_payload+16, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 htonl(dns_clip_ttl(edge_conn->address_ttl))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      connected_payload_len = 20; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint8_t connected_payload[MAX_CONNECTED_CELL_PAYLOAD_LEN]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int connected_payload_len = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      connected_cell_format_payload(connected_payload, &conn->addr, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    edge_conn->address_ttl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (connected_payload_len < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (connection_edge_send_command(edge_conn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                 RELAY_COMMAND_CONNECTED, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                 connected_payload, connected_payload_len) < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        RELAY_COMMAND_CONNECTED, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        (char*)connected_payload, connected_payload_len) < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       return 0; /* circuit is closed, don't continue */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_assert(edge_conn->package_window > 0); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2554,21 +2580,20 @@ connection_exit_connect(edge_connection_t *edge_conn) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                  RELAY_COMMAND_CONNECTED, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                  NULL, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { /* normal stream */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    char connected_payload[20]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int connected_payload_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (tor_addr_family(&conn->addr) == AF_INET) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      set_uint32(connected_payload, tor_addr_to_ipv4n(&conn->addr)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      connected_payload_len = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      memcpy(connected_payload, tor_addr_to_in6_addr8(&conn->addr), 16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      connected_payload_len = 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint8_t connected_payload[MAX_CONNECTED_CELL_PAYLOAD_LEN]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int connected_payload_len = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      connected_cell_format_payload(connected_payload, &conn->addr, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    edge_conn->address_ttl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (connected_payload_len < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      connection_edge_end(edge_conn, END_STREAM_REASON_INTERNAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      connection_free(conn); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    set_uint32(connected_payload+connected_payload_len, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               htonl(dns_clip_ttl(edge_conn->address_ttl))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    connected_payload_len += 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     connection_edge_send_command(edge_conn, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                  RELAY_COMMAND_CONNECTED, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                 connected_payload, connected_payload_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 (char*)connected_payload, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 connected_payload_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |