summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorteor <teor@torproject.org>2020-04-14 15:08:42 +1000
committerteor <teor@torproject.org>2020-04-29 22:43:09 +1000
commitbd6ab90ad4b40a64c604c1a4b6b37da6991fad9e (patch)
tree832476a193af3ecb73d6858ed532f9127eb858c5 /src/core
parent3253c357eeae3434da62bf720a451aa19f0ddd32 (diff)
downloadtor-bd6ab90ad4b40a64c604c1a4b6b37da6991fad9e.tar.gz
tor-bd6ab90ad4b40a64c604c1a4b6b37da6991fad9e.zip
core/or: Support IPv6 EXTEND2 cells
Allow clients and relays to send dual-stack and IPv6-only EXTEND2 cells. Parse dual-stack and IPv6-only EXTEND2 cells on relays. Relays do not make connections or extend circuits via IPv6: that's the next step. Closes ticket 33901.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/or/onion.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/src/core/or/onion.c b/src/core/or/onion.c
index 45144b5e6c..543d9f3e47 100644
--- a/src/core/or/onion.c
+++ b/src/core/or/onion.c
@@ -240,11 +240,21 @@ created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in)
static int
check_extend_cell(const extend_cell_t *cell)
{
+ const bool is_extend2 = (cell->cell_type == RELAY_COMMAND_EXTEND2);
+
if (tor_digest_is_zero((const char*)cell->node_id))
return -1;
- /* We don't currently allow EXTEND2 cells without an IPv4 address */
- if (tor_addr_family(&cell->orport_ipv4.addr) == AF_UNSPEC)
- return -1;
+ if (tor_addr_family(&cell->orport_ipv4.addr) == AF_UNSPEC) {
+ /* EXTEND cells must have an IPv4 address. */
+ if (!is_extend2) {
+ return -1;
+ }
+ /* EXTEND2 cells must have at least one IP address.
+ * It can be IPv4 or IPv6. */
+ if (tor_addr_family(&cell->orport_ipv6.addr) == AF_UNSPEC) {
+ return -1;
+ }
+ }
if (cell->create_cell.cell_type == CELL_CREATE) {
if (cell->cell_type != RELAY_COMMAND_EXTEND)
return -1;
@@ -364,7 +374,12 @@ extend_cell_from_extend2_cell_body(extend_cell_t *cell_out,
}
}
- if (!found_rsa_id || !found_ipv4) /* These are mandatory */
+ /* EXTEND2 cells must have an RSA ID */
+ if (!found_rsa_id)
+ return -1;
+
+ /* EXTEND2 cells must have at least one IP address */
+ if (!found_ipv4 && !found_ipv6)
return -1;
return create_cell_from_create2_cell_body(&cell_out->create_cell,
@@ -620,12 +635,13 @@ extend_cell_format(uint8_t *command_out, uint16_t *len_out,
break;
case RELAY_COMMAND_EXTEND2:
{
- uint8_t n_specifiers = 2;
+ uint8_t n_specifiers = 1;
*command_out = RELAY_COMMAND_EXTEND2;
extend2_cell_body_t *cell = extend2_cell_body_new();
link_specifier_t *ls;
- {
- /* IPv4 specifier first. */
+ if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv4, 0)) {
+ /* Maybe IPv4 specifier first. */
+ ++n_specifiers;
ls = link_specifier_new();
extend2_cell_body_add_ls(cell, ls);
ls->ls_type = LS_IPV4;
@@ -651,6 +667,17 @@ extend_cell_format(uint8_t *command_out, uint16_t *len_out,
ls->ls_len = 32;
memcpy(ls->un_ed25519_id, cell_in->ed_pubkey.pubkey, 32);
}
+ if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv6, 0)) {
+ /* Then maybe IPv6 specifier. */
+ ++n_specifiers;
+ ls = link_specifier_new();
+ extend2_cell_body_add_ls(cell, ls);
+ ls->ls_type = LS_IPV6;
+ ls->ls_len = 18;
+ tor_addr_get_ipv6_bytes((char *)ls->un_ipv6_addr,
+ &cell_in->orport_ipv6.addr);
+ ls->un_ipv6_port = cell_in->orport_ipv6.port;
+ }
cell->n_spec = n_specifiers;
/* Now, the handshake */