|  | @@ -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);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 |