Loading src/or/connection_edge.c +52 −27 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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) (char*)connected_payload, connected_payload_len) < 0) return 0; /* circuit is closed, don't continue */ } tor_assert(edge_conn->package_window > 0); Loading Loading @@ -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); } } Loading src/or/connection_edge.h +3 −1 Original line number Diff line number Diff line Loading @@ -109,7 +109,9 @@ typedef struct begin_cell_t { int begin_cell_parse(const cell_t *cell, begin_cell_t *bcell, uint8_t *end_reason_out); int connected_cell_format_payload(uint8_t *payload_out, const tor_addr_t *addr, uint32_t ttl); #endif #endif Loading src/test/test_cell_formats.c +39 −1 Original line number Diff line number Diff line Loading @@ -231,6 +231,7 @@ test_cfmt_connected_cells(void *arg) cell_t cell; tor_addr_t addr; int ttl, r; char *mem_op_hex_tmp = NULL; (void)arg; /* Let's try an oldschool one with nothing in it. */ Loading Loading @@ -332,8 +333,45 @@ test_cfmt_connected_cells(void *arg) r = connected_cell_parse(&rh, &cell, &addr, &ttl); tt_int_op(r, ==, -1); /* Now make sure we can generate connected cells correctly. */ /* Try an IPv4 address */ memset(&rh, 0, sizeof(rh)); memset(&cell, 0, sizeof(cell)); tor_addr_parse(&addr, "30.40.50.60"); rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE, &addr, 128); tt_int_op(rh.length, ==, 8); test_memeq_hex(cell.payload+RELAY_HEADER_SIZE, "1e28323c" "00000080"); /* Try parsing it. */ tor_addr_make_unspec(&addr); r = connected_cell_parse(&rh, &cell, &addr, &ttl); tt_int_op(r, ==, 0); tt_int_op(tor_addr_family(&addr), ==, AF_INET); tt_str_op(fmt_addr(&addr), ==, "30.40.50.60"); tt_int_op(ttl, ==, 128); /* Try an IPv6 address */ memset(&rh, 0, sizeof(rh)); memset(&cell, 0, sizeof(cell)); tor_addr_parse(&addr, "2620::6b0:b:1a1a:0:26e5:480e"); rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE, &addr, 3600); tt_int_op(rh.length, ==, 25); test_memeq_hex(cell.payload + RELAY_HEADER_SIZE, "00000000" "06" "2620000006b0000b1a1a000026e5480e" "00000e10"); /* Try parsing it. */ tor_addr_make_unspec(&addr); r = connected_cell_parse(&rh, &cell, &addr, &ttl); tt_int_op(r, ==, 0); tt_int_op(tor_addr_family(&addr), ==, AF_INET6); tt_str_op(fmt_addr(&addr), ==, "2620:0:6b0:b:1a1a:0:26e5:480e"); tt_int_op(ttl, ==, 3600); done: ; tor_free(mem_op_hex_tmp); } #define TEST(name, flags) \ Loading Loading
src/or/connection_edge.c +52 −27 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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) (char*)connected_payload, connected_payload_len) < 0) return 0; /* circuit is closed, don't continue */ } tor_assert(edge_conn->package_window > 0); Loading Loading @@ -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); } } Loading
src/or/connection_edge.h +3 −1 Original line number Diff line number Diff line Loading @@ -109,7 +109,9 @@ typedef struct begin_cell_t { int begin_cell_parse(const cell_t *cell, begin_cell_t *bcell, uint8_t *end_reason_out); int connected_cell_format_payload(uint8_t *payload_out, const tor_addr_t *addr, uint32_t ttl); #endif #endif Loading
src/test/test_cell_formats.c +39 −1 Original line number Diff line number Diff line Loading @@ -231,6 +231,7 @@ test_cfmt_connected_cells(void *arg) cell_t cell; tor_addr_t addr; int ttl, r; char *mem_op_hex_tmp = NULL; (void)arg; /* Let's try an oldschool one with nothing in it. */ Loading Loading @@ -332,8 +333,45 @@ test_cfmt_connected_cells(void *arg) r = connected_cell_parse(&rh, &cell, &addr, &ttl); tt_int_op(r, ==, -1); /* Now make sure we can generate connected cells correctly. */ /* Try an IPv4 address */ memset(&rh, 0, sizeof(rh)); memset(&cell, 0, sizeof(cell)); tor_addr_parse(&addr, "30.40.50.60"); rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE, &addr, 128); tt_int_op(rh.length, ==, 8); test_memeq_hex(cell.payload+RELAY_HEADER_SIZE, "1e28323c" "00000080"); /* Try parsing it. */ tor_addr_make_unspec(&addr); r = connected_cell_parse(&rh, &cell, &addr, &ttl); tt_int_op(r, ==, 0); tt_int_op(tor_addr_family(&addr), ==, AF_INET); tt_str_op(fmt_addr(&addr), ==, "30.40.50.60"); tt_int_op(ttl, ==, 128); /* Try an IPv6 address */ memset(&rh, 0, sizeof(rh)); memset(&cell, 0, sizeof(cell)); tor_addr_parse(&addr, "2620::6b0:b:1a1a:0:26e5:480e"); rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE, &addr, 3600); tt_int_op(rh.length, ==, 25); test_memeq_hex(cell.payload + RELAY_HEADER_SIZE, "00000000" "06" "2620000006b0000b1a1a000026e5480e" "00000e10"); /* Try parsing it. */ tor_addr_make_unspec(&addr); r = connected_cell_parse(&rh, &cell, &addr, &ttl); tt_int_op(r, ==, 0); tt_int_op(tor_addr_family(&addr), ==, AF_INET6); tt_str_op(fmt_addr(&addr), ==, "2620:0:6b0:b:1a1a:0:26e5:480e"); tt_int_op(ttl, ==, 3600); done: ; tor_free(mem_op_hex_tmp); } #define TEST(name, flags) \ Loading