static void test_routerlist_router_is_already_dir_fetching(void *arg) { (void)arg; tor_addr_port_t test_ap, null_addr_ap, zero_port_ap; /* Setup */ tor_addr_parse(&test_ap.addr, TEST_ADDR_STR); test_ap.port = TEST_DIR_PORT; tor_addr_make_null(&null_addr_ap.addr, AF_INET6); null_addr_ap.port = TEST_DIR_PORT; tor_addr_parse(&zero_port_ap.addr, TEST_ADDR_STR); zero_port_ap.port = 0; MOCK(connection_get_by_type_addr_port_purpose, mock_connection_get_by_type_addr_port_purpose); /* Test that we never get 1 from a NULL connection */ mocked_connection = NULL; tt_assert(router_is_already_dir_fetching(&test_ap, 1, 1) == 0); tt_assert(router_is_already_dir_fetching(&test_ap, 1, 0) == 0); tt_assert(router_is_already_dir_fetching(&test_ap, 0, 1) == 0); /* We always expect 0 in these cases */ tt_assert(router_is_already_dir_fetching(&test_ap, 0, 0) == 0); tt_assert(router_is_already_dir_fetching(NULL, 1, 1) == 0); tt_assert(router_is_already_dir_fetching(&null_addr_ap, 1, 1) == 0); tt_assert(router_is_already_dir_fetching(&zero_port_ap, 1, 1) == 0); /* Test that we get 1 with a connection in the appropriate circumstances */ mocked_connection = connection_new(CONN_TYPE_DIR, AF_INET); tt_assert(router_is_already_dir_fetching(&test_ap, 1, 1) == 1); tt_assert(router_is_already_dir_fetching(&test_ap, 1, 0) == 1); tt_assert(router_is_already_dir_fetching(&test_ap, 0, 1) == 1); /* Test that we get 0 even with a connection in the appropriate * circumstances */ tt_assert(router_is_already_dir_fetching(&test_ap, 0, 0) == 0); tt_assert(router_is_already_dir_fetching(NULL, 1, 1) == 0); tt_assert(router_is_already_dir_fetching(&null_addr_ap, 1, 1) == 0); tt_assert(router_is_already_dir_fetching(&zero_port_ap, 1, 1) == 0); done: /* If a connection is never set up, connection_free chokes on it. */ if (mocked_connection) { buf_free(mocked_connection->inbuf); buf_free(mocked_connection->outbuf); } tor_free(mocked_connection); UNMOCK(connection_get_by_type_addr_port_purpose); }
/** * Calling get_configured_bridge_by_exact_addr_port_digest() with a digest that * we do have, and an addr:port pair we do have, should return the bridge. */ static void test_bridges_get_configured_bridge_by_exact_addr_port_digest_both(void *arg) { char digest[DIGEST_LEN]; bridge_info_t *bridge; const char fingerprint[HEX_DIGEST_LEN] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); uint16_t port = 4444; char ret_addr[16]; int ret; helper_add_bridges_to_bridgelist(arg); base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN); ret = tor_addr_parse(addr, "4.4.4.4"); tt_int_op(ret, OP_EQ, 2); // it returns the address family on success bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, digest); tt_ptr_op(bridge, OP_NE, NULL); tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0); tt_str_op("4.4.4.4", OP_EQ, ret_addr); done: tor_free(addr); mark_bridge_list(); sweep_bridge_list(); }
/** * Calling get_configured_bridge_by_exact_addr_port_digest() with no digest, * and an addr:port pair we do have, should return the bridge. */ static void test_bridges_get_configured_bridge_by_exact_addr_port_digest_aonly(void *arg) { bridge_info_t *bridge; tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); uint16_t port = 4444; char ret_addr[16]; int ret; helper_add_bridges_to_bridgelist(arg); ret = tor_addr_parse(addr, "4.4.4.4"); tt_int_op(ret, OP_EQ, 2); // it returns the address family on success bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, NULL); tt_ptr_op(bridge, OP_NE, NULL); tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0); tt_str_op("4.4.4.4", OP_EQ, ret_addr); done: tor_free(addr); mark_bridge_list(); sweep_bridge_list(); }
/** * Calling get_configured_bridge_by_exact_addr_port_digest() with a digest that * we do have, and an addr:port pair we don't have, should return NULL. */ static void test_bridges_get_configured_bridge_by_exact_addr_port_digest_donly(void *arg) { char digest[DIGEST_LEN]; bridge_info_t *bridge; const char fingerprint[HEX_DIGEST_LEN] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); uint16_t port = 11111; int ret; helper_add_bridges_to_bridgelist(arg); // We don't actually have a bridge with this addr:port pair base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN); ret = tor_addr_parse(addr, "111.111.111.111"); tt_int_op(ret, OP_EQ, 2); // it returns the address family on success bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, digest); tt_ptr_op(bridge, OP_EQ, NULL); done: tor_free(addr); mark_bridge_list(); sweep_bridge_list(); }
/** * Calling bridge_resolve_conflicts() with an identical bridge to one we've * already configure should mark the pre-configured bridge for removal. */ static void test_bridges_bridge_resolve_conflicts(void *arg) { tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); uint16_t port = 4444; const char *digest = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; const char *transport = "apple"; int ret; helper_add_bridges_to_bridgelist(arg); ret = tor_addr_parse(addr, "4.4.4.4"); tt_int_op(ret, OP_EQ, 2); // it returns the address family on success bridge_resolve_conflicts((const tor_addr_t*)addr, port, digest, transport); /* The bridge should now be marked for removal, and removed when we sweep the * bridge_list */ sweep_bridge_list(); ret = addr_is_a_configured_bridge((const tor_addr_t*)addr, port, digest); tt_int_op(ret, OP_EQ, 0); done: tor_free(addr); mark_bridge_list(); sweep_bridge_list(); }
/** * Calling get_transport_by_bridge_addrport() with the address and port of a * configured bridge which uses a pluggable transport when there is no global * transport_list should return -1 and the transport_t should be NULL. */ static void test_bridges_get_transport_by_bridge_addrport_no_ptlist(void *arg) { transport_t *transport = NULL; tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); uint16_t port = 1234; int ret; helper_add_bridges_to_bridgelist(arg); ret = tor_addr_parse(addr, "1.2.3.4"); tt_int_op(ret, OP_EQ, 2); // it returns the address family on success? /* This will fail because the global transport_list has nothing in it, and so * transport_get_by_name() has nothing to return, even the the bridge *did* * say it had an obfs4 transport. */ ret = get_transport_by_bridge_addrport((const tor_addr_t*)addr, port, (const transport_t**)&transport); tt_int_op(ret, OP_EQ, -1); // returns -1 on failure tt_ptr_op(transport, OP_EQ, NULL); done: tor_free(addr); mark_bridge_list(); sweep_bridge_list(); }
static void NS(test_main)(void *arg) { int retval; int made_pending; const tor_addr_t *resolved_addr; tor_addr_t addr_to_compare; (void)arg; tor_addr_parse(&addr_to_compare, "8.8.8.8"); or_circuit_t *on_circ = tor_malloc_zero(sizeof(or_circuit_t)); edge_connection_t *exitconn = create_valid_exitconn(); TO_CONN(exitconn)->address = tor_strdup("8.8.8.8"); retval = dns_resolve_impl(exitconn, 1, on_circ, NULL, &made_pending, NULL); resolved_addr = &(exitconn->base_.addr); tt_int_op(retval,OP_EQ,1); tt_assert(tor_addr_eq(resolved_addr, (const tor_addr_t *)&addr_to_compare)); tt_int_op(exitconn->address_ttl,OP_EQ,DEFAULT_DNS_TTL); done: tor_free(on_circ); tor_free(TO_CONN(exitconn)->address); tor_free(exitconn); return; }
/** * Calling get_transport_by_bridge_addrport() with the address and port of a * configured bridge which uses a pluggable transport should return 0 and set * appropriate transport_t. */ static void test_bridges_get_transport_by_bridge_addrport(void *arg) { transport_t *transport = NULL; tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); uint16_t port = 1234; int ret; helper_add_bridges_to_bridgelist(arg); mark_transport_list(); // Also initialise our transport_list ret = tor_addr_parse(addr, "1.2.3.4"); tt_int_op(ret, OP_EQ, 2); // it returns the address family on success? /* After we mock transport_get_by_name() to return a bogus transport_t with * the name it was asked for, the call should succeed. */ MOCK(transport_get_by_name, mock_transport_get_by_name); ret = get_transport_by_bridge_addrport((const tor_addr_t*)addr, port, (const transport_t**)&transport); tt_int_op(ret, OP_EQ, 0); // returns 0 on success tt_ptr_op(transport, OP_NE, NULL); tt_str_op(transport->name, OP_EQ, "obfs4"); done: UNMOCK(transport_get_by_name); tor_free(addr); transport_free(transport); mark_bridge_list(); sweep_bridge_list(); }
static void test_addr_is_loopback(void *data) { static const struct loopback_item { const char *name; int is_loopback; } loopback_items[] = { { "::1", 1 }, { "127.0.0.1", 1 }, { "127.99.100.101", 1 }, { "128.99.100.101", 0 }, { "8.8.8.8", 0 }, { "0.0.0.0", 0 }, { "::2", 0 }, { "::", 0 }, { "::1.0.0.0", 0 }, { NULL, 0 } }; int i; tor_addr_t addr; (void)data; for (i=0; loopback_items[i].name; ++i) { tt_int_op(tor_addr_parse(&addr, loopback_items[i].name), OP_GE, 0); tt_int_op(tor_addr_is_loopback(&addr), OP_EQ, loopback_items[i].is_loopback); } tor_addr_make_unspec(&addr); tt_int_op(tor_addr_is_loopback(&addr), OP_EQ, 0); done: ; }
static void test_virtaddrmap(void *data) { /* Let's start with a bunch of random addresses. */ int ipv6, bits, iter, b; virtual_addr_conf_t cfg[2]; uint8_t bytes[16]; (void)data; tor_addr_parse(&cfg[0].addr, "64.65.0.0"); tor_addr_parse(&cfg[1].addr, "3491:c0c0::"); for (ipv6 = 0; ipv6 <= 1; ++ipv6) { for (bits = 0; bits < 18; ++bits) { tor_addr_t last_a; cfg[ipv6].bits = bits; memset(bytes, 0, sizeof(bytes)); tor_addr_copy(&last_a, &cfg[ipv6].addr); /* Generate 128 addresses with each addr/bits combination. */ for (iter = 0; iter < 128; ++iter) { tor_addr_t a; get_random_virtual_addr(&cfg[ipv6], &a); //printf("%s\n", fmt_addr(&a)); /* Make sure that the first b bits match the configured network */ tt_int_op(0, OP_EQ, tor_addr_compare_masked(&a, &cfg[ipv6].addr, bits, CMP_EXACT)); /* And track which bits have been different between pairs of * addresses */ update_difference(ipv6, bytes, &last_a, &a); } /* Now make sure all but the first 'bits' bits of bytes are true */ for (b = bits+1; b < (ipv6?128:32); ++b) { tt_assert(1 & (bytes[b/8] >> (7-(b&7)))); } } } done: ; }
/** Set *<b>out</b> to a newly allocated SOCKS4a resolve request with * <b>username</b> and <b>hostname</b> as provided. Return the number * of bytes in the request. */ static ssize_t build_socks_resolve_request(char **out, const char *username, const char *hostname, int reverse, int version) { size_t len = 0; tor_assert(out); tor_assert(username); tor_assert(hostname); if (version == 4) { len = 8 + strlen(username) + 1 + strlen(hostname) + 1; *out = tor_malloc(len); (*out)[0] = 4; /* SOCKS version 4 */ (*out)[1] = '\xF0'; /* Command: resolve. */ set_uint16((*out)+2, htons(0)); /* port: 0. */ set_uint32((*out)+4, htonl(0x00000001u)); /* addr: 0.0.0.1 */ memcpy((*out)+8, username, strlen(username)+1); memcpy((*out)+8+strlen(username)+1, hostname, strlen(hostname)+1); } else if (version == 5) { int is_ip_address; tor_addr_t addr; size_t addrlen; int ipv6; is_ip_address = tor_addr_parse(&addr, hostname) != -1; if (!is_ip_address && reverse) { log_err(LD_GENERAL, "Tried to do a reverse lookup on a non-IP!"); return -1; } ipv6 = reverse && tor_addr_family(&addr) == AF_INET6; addrlen = reverse ? (ipv6 ? 16 : 4) : 1 + strlen(hostname); len = 6 + addrlen; *out = tor_malloc(len); (*out)[0] = 5; /* SOCKS version 5 */ (*out)[1] = reverse ? '\xF1' : '\xF0'; /* RESOLVE_PTR or RESOLVE */ (*out)[2] = 0; /* reserved. */ if (reverse) { (*out)[3] = ipv6 ? 4 : 1; if (ipv6) memcpy((*out)+4, tor_addr_to_in6_addr8(&addr), 16); else set_uint32((*out)+4, tor_addr_to_ipv4n(&addr)); } else { (*out)[3] = 3; (*out)[4] = (char)(uint8_t)(addrlen - 1); memcpy((*out)+5, hostname, addrlen - 1); } set_uint16((*out)+4+addrlen, 0); /* port */ } else { tor_assert(0); } return len; }
/** * Mock transport_get_by_name() to simply return a transport_t for the * transport name that was input to it. */ static transport_t * mock_transport_get_by_name(const char *name) { tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); uint16_t port = 9999; int socksv = 9; char *args = tor_strdup("foo=bar"); if (!mock_transport) { tor_addr_parse(addr, "99.99.99.99"); mock_transport = transport_new(addr, port, name, socksv, args); } tor_free(addr); tor_free(args); return mock_transport; }
/** Test tor_addr_parse() and tor_addr_port_parse(). */ static void test_addr_parse(void *arg) { int r; tor_addr_t addr; char buf[TOR_ADDR_BUF_LEN]; uint16_t port = 0; /* Correct call. */ (void)arg; r= tor_addr_parse(&addr, "192.0.2.1"); tt_int_op(r,OP_EQ, AF_INET); tor_addr_to_str(buf, &addr, sizeof(buf), 0); tt_str_op(buf,OP_EQ, "192.0.2.1"); r= tor_addr_parse(&addr, "11:22::33:44"); tt_int_op(r,OP_EQ, AF_INET6); tor_addr_to_str(buf, &addr, sizeof(buf), 0); tt_str_op(buf,OP_EQ, "11:22::33:44"); r= tor_addr_parse(&addr, "[11:22::33:44]"); tt_int_op(r,OP_EQ, AF_INET6); tor_addr_to_str(buf, &addr, sizeof(buf), 0); tt_str_op(buf,OP_EQ, "11:22::33:44"); r= tor_addr_parse(&addr, "11:22:33:44:55:66:1.2.3.4"); tt_int_op(r,OP_EQ, AF_INET6); tor_addr_to_str(buf, &addr, sizeof(buf), 0); tt_str_op(buf,OP_EQ, "11:22:33:44:55:66:102:304"); r= tor_addr_parse(&addr, "11:22::33:44:1.2.3.4"); tt_int_op(r,OP_EQ, AF_INET6); tor_addr_to_str(buf, &addr, sizeof(buf), 0); tt_str_op(buf,OP_EQ, "11:22::33:44:102:304"); /* Empty string. */ r= tor_addr_parse(&addr, ""); tt_int_op(r,OP_EQ, -1); /* Square brackets around IPv4 address. */ r= tor_addr_parse(&addr, "[192.0.2.1]"); tt_int_op(r,OP_EQ, -1); /* Only left square bracket. */ r= tor_addr_parse(&addr, "[11:22::33:44"); tt_int_op(r,OP_EQ, -1); /* Only right square bracket. */ r= tor_addr_parse(&addr, "11:22::33:44]"); tt_int_op(r,OP_EQ, -1); /* Leading colon. */ r= tor_addr_parse(&addr, ":11:22::33:44"); tt_int_op(r,OP_EQ, -1); /* Trailing colon. */ r= tor_addr_parse(&addr, "11:22::33:44:"); tt_int_op(r,OP_EQ, -1); /* Too many hex words in IPv4-mapped IPv6 address. */ r= tor_addr_parse(&addr, "11:22:33:44:55:66:77:88:1.2.3.4"); tt_int_op(r,OP_EQ, -1); /* Correct call. */ r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.1:1234", &addr, &port, -1); tt_int_op(r, OP_EQ, 0); tor_addr_to_str(buf, &addr, sizeof(buf), 0); tt_str_op(buf,OP_EQ, "192.0.2.1"); tt_int_op(port,OP_EQ, 1234); r= tor_addr_port_parse(LOG_DEBUG, "[::1]:1234", &addr, &port, -1); tt_int_op(r, OP_EQ, 0); tor_addr_to_str(buf, &addr, sizeof(buf), 0); tt_str_op(buf,OP_EQ, "::1"); tt_int_op(port,OP_EQ, 1234); /* Domain name. */ r= tor_addr_port_parse(LOG_DEBUG, "torproject.org:1234", &addr, &port, -1); tt_int_op(r, OP_EQ, -1); /* Only IP. */ r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.2", &addr, &port, -1); tt_int_op(r, OP_EQ, -1); r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.2", &addr, &port, 200); tt_int_op(r, OP_EQ, 0); tt_int_op(port,OP_EQ,200); r= tor_addr_port_parse(LOG_DEBUG, "[::1]", &addr, &port, -1); tt_int_op(r, OP_EQ, -1); r= tor_addr_port_parse(LOG_DEBUG, "[::1]", &addr, &port, 400); tt_int_op(r, OP_EQ, 0); tt_int_op(port,OP_EQ,400); /* Bad port. */ r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.2:66666", &addr, &port, -1); tt_int_op(r, OP_EQ, -1); r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.2:66666", &addr, &port, 200); tt_int_op(r, OP_EQ, -1); /* Only domain name */ r= tor_addr_port_parse(LOG_DEBUG, "torproject.org", &addr, &port, -1); tt_int_op(r, OP_EQ, -1); r= tor_addr_port_parse(LOG_DEBUG, "torproject.org", &addr, &port, 200); tt_int_op(r, OP_EQ, -1); /* Bad IP address */ r= tor_addr_port_parse(LOG_DEBUG, "192.0.2:1234", &addr, &port, -1); tt_int_op(r, OP_EQ, -1); /* Make sure that the default port has lower priority than the real one */ r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.2:1337", &addr, &port, 200); tt_int_op(r, OP_EQ, 0); tt_int_op(port,OP_EQ,1337); r= tor_addr_port_parse(LOG_DEBUG, "[::1]:1369", &addr, &port, 200); tt_int_op(r, OP_EQ, 0); tt_int_op(port,OP_EQ,1369); done: ; }
static void test_circbw_relay(void *arg) { cell_t cell; relay_header_t rh; tor_addr_t addr; edge_connection_t *edgeconn; entry_connection_t *entryconn1=NULL; origin_circuit_t *circ; int delivered = 0; int overhead = 0; (void)arg; MOCK(connection_mark_unattached_ap_, mock_connection_mark_unattached_ap_); MOCK(connection_start_reading, mock_start_reading); MOCK(connection_mark_for_close_internal_, mock_mark_for_close); MOCK(relay_send_command_from_edge_, mock_send_command); MOCK(circuit_mark_for_close_, mock_mark_circ_for_close); circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0); circ->cpath->state = CPATH_STATE_AWAITING_KEYS; circ->cpath->deliver_window = CIRCWINDOW_START; entryconn1 = fake_entry_conn(circ, 1); edgeconn = ENTRY_TO_EDGE_CONN(entryconn1); /* Stream id 0: Not counted */ PACK_CELL(0, RELAY_COMMAND_END, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Stream id 1: Counted */ PACK_CELL(1, RELAY_COMMAND_END, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_COUNTED_BW(); /* Properly formatted connect cell: counted */ PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234"); tor_addr_parse(&addr, "30.40.50.60"); rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE, &addr, 1024); relay_header_pack((uint8_t*)&cell.payload, &rh); \ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_COUNTED_BW(); /* Properly formatted resolved cell in correct state: counted */ edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT; entryconn1->socks_request->command = SOCKS_COMMAND_RESOLVE; edgeconn->on_circuit = TO_CIRCUIT(circ); PACK_CELL(1, RELAY_COMMAND_RESOLVED, "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_COUNTED_BW(); edgeconn->base_.state = AP_CONN_STATE_OPEN; entryconn1->socks_request->has_finished = 1; /* Connected cell after open: not counted */ PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Resolved cell after open: not counted */ PACK_CELL(1, RELAY_COMMAND_RESOLVED, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Drop cell: not counted */ PACK_CELL(1, RELAY_COMMAND_DROP, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Data cell on stream 0: not counted */ PACK_CELL(0, RELAY_COMMAND_DATA, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Data cell on open connection: counted */ ENTRY_TO_CONN(entryconn1)->marked_for_close = 0; PACK_CELL(1, RELAY_COMMAND_DATA, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_COUNTED_BW(); /* Empty Data cell on open connection: not counted */ ENTRY_TO_CONN(entryconn1)->marked_for_close = 0; PACK_CELL(1, RELAY_COMMAND_DATA, ""); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Sendme on valid stream: counted */ edgeconn->package_window -= STREAMWINDOW_INCREMENT; ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0; PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_COUNTED_BW(); /* Sendme on valid stream with full window: not counted */ ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0; PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234"); edgeconn->package_window = STREAMWINDOW_START; connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Sendme on unknown stream: not counted */ ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0; PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Sendme on circuit with full window: not counted */ PACK_CELL(0, RELAY_COMMAND_SENDME, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Sendme on circuit with non-full window: counted */ PACK_CELL(0, RELAY_COMMAND_SENDME, "Data1234"); circ->cpath->package_window = 900; connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_COUNTED_BW(); /* Invalid extended cell: not counted */ PACK_CELL(1, RELAY_COMMAND_EXTENDED2, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Invalid extended cell: not counted */ PACK_CELL(1, RELAY_COMMAND_EXTENDED, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Invalid HS cell: not counted */ PACK_CELL(1, RELAY_COMMAND_ESTABLISH_INTRO, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL, circ->cpath); ASSERT_UNCOUNTED_BW(); /* "Valid" HS cell in expected state: counted */ TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_C_ESTABLISH_REND; PACK_CELL(1, RELAY_COMMAND_RENDEZVOUS_ESTABLISHED, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL, circ->cpath); ASSERT_COUNTED_BW(); /* End cell on non-closed connection: counted */ PACK_CELL(1, RELAY_COMMAND_END, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn, circ->cpath); ASSERT_COUNTED_BW(); /* End cell on connection that already got one: not counted */ PACK_CELL(1, RELAY_COMMAND_END, "Data1234"); connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL, circ->cpath); ASSERT_UNCOUNTED_BW(); /* Simulate closed stream on entryconn, then test: */ if (!subtest_circbw_halfclosed(circ, 2)) goto done; circ->base_.purpose = CIRCUIT_PURPOSE_PATH_BIAS_TESTING; if (!subtest_circbw_halfclosed(circ, 6)) goto done; /* Path bias: truncated */ tt_int_op(circ->base_.marked_for_close, OP_EQ, 0); PACK_CELL(0, RELAY_COMMAND_TRUNCATED, "Data1234"); pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell); tt_int_op(circ->base_.marked_for_close, OP_EQ, 1); done: UNMOCK(connection_start_reading); UNMOCK(connection_mark_unattached_ap_); UNMOCK(connection_mark_for_close_internal_); UNMOCK(relay_send_command_from_edge_); UNMOCK(circuit_mark_for_close_); circuit_free_(TO_CIRCUIT(circ)); connection_free_minimal(ENTRY_TO_CONN(entryconn1)); }
/** Run unit tests for IPv6 encoding/decoding/manipulation functions. */ static void test_addr_ip6_helpers(void) { char buf[TOR_ADDR_BUF_LEN], bug[TOR_ADDR_BUF_LEN]; char rbuf[REVERSE_LOOKUP_NAME_BUF_LEN]; struct in6_addr a1, a2; tor_addr_t t1, t2; int r, i; uint16_t port1, port2; maskbits_t mask; const char *p1; struct sockaddr_storage sa_storage; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; /* Test tor_inet_ntop and tor_inet_pton: IPv6 */ { const char *ip = "2001::1234"; const char *ip_ffff = "::ffff:192.168.1.2"; /* good round trip */ test_eq(tor_inet_pton(AF_INET6, ip, &a1), 1); test_eq_ptr(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), &buf); test_streq(buf, ip); /* good round trip - ::ffff:0:0 style */ test_eq(tor_inet_pton(AF_INET6, ip_ffff, &a2), 1); test_eq_ptr(tor_inet_ntop(AF_INET6, &a2, buf, sizeof(buf)), &buf); test_streq(buf, ip_ffff); /* just long enough buffer (remember \0) */ test_streq(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)+1), ip); test_streq(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)+1), ip_ffff); /* too short buffer (remember \0) */ test_eq_ptr(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)), NULL); test_eq_ptr(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)), NULL); } /* ==== Converting to and from sockaddr_t. */ sin = (struct sockaddr_in *)&sa_storage; sin->sin_family = AF_INET; sin->sin_port = 9090; sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL); test_eq(tor_addr_family(&t1), AF_INET); test_eq(tor_addr_to_ipv4h(&t1), 0x7f7f0102); memset(&sa_storage, 0, sizeof(sa_storage)); test_eq(sizeof(struct sockaddr_in), tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); test_eq(1234, ntohs(sin->sin_port)); test_eq(0x7f7f0102, ntohl(sin->sin_addr.s_addr)); memset(&sa_storage, 0, sizeof(sa_storage)); sin6 = (struct sockaddr_in6 *)&sa_storage; sin6->sin6_family = AF_INET6; sin6->sin6_port = htons(7070); sin6->sin6_addr.s6_addr[0] = 128; tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, NULL); test_eq(tor_addr_family(&t1), AF_INET6); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); test_streq(p1, "8000::"); memset(&sa_storage, 0, sizeof(sa_storage)); test_eq(sizeof(struct sockaddr_in6), tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); test_eq(AF_INET6, sin6->sin6_family); test_eq(9999, ntohs(sin6->sin6_port)); test_eq(0x80000000, ntohl(S6_ADDR32(sin6->sin6_addr)[0])); /* ==== tor_addr_lookup: static cases. (Can't test dns without knowing we * have a good resolver. */ test_eq(0, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1)); test_eq(AF_INET, tor_addr_family(&t1)); test_eq(tor_addr_to_ipv4h(&t1), 0x7f808182); test_eq(0, tor_addr_lookup("9000::5", AF_UNSPEC, &t1)); test_eq(AF_INET6, tor_addr_family(&t1)); test_eq(0x90, tor_addr_to_in6_addr8(&t1)[0]); test_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14)); test_eq(0x05, tor_addr_to_in6_addr8(&t1)[15]); /* === Test pton: valid af_inet6 */ /* Simple, valid parsing. */ r = tor_inet_pton(AF_INET6, "0102:0304:0506:0708:090A:0B0C:0D0E:0F10", &a1); test_assert(r==1); for (i=0;i<16;++i) { test_eq(i+1, (int)a1.s6_addr[i]); } /* ipv4 ending. */ test_pton6_same("0102:0304:0506:0708:090A:0B0C:0D0E:0F10", "0102:0304:0506:0708:090A:0B0C:13.14.15.16"); /* shortened words. */ test_pton6_same("0001:0099:BEEF:0000:0123:FFFF:0001:0001", "1:99:BEEF:0:0123:FFFF:1:1"); /* zeros at the beginning */ test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:1:1"); test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:0.1.0.1"); /* zeros in the middle. */ test_pton6_same("fe80:0000:0000:0000:0202:1111:0001:0001", "fe80::202:1111:1:1"); /* zeros at the end. */ test_pton6_same("1000:0001:0000:0007:0000:0000:0000:0000", "1000:1:0:7::"); /* === Test ntop: af_inet6 */ test_ntop6_reduces("0:0:0:0:0:0:0:0", "::"); test_ntop6_reduces("0001:0099:BEEF:0006:0123:FFFF:0001:0001", "1:99:beef:6:123:ffff:1:1"); //test_ntop6_reduces("0:0:0:0:0:0:c0a8:0101", "::192.168.1.1"); test_ntop6_reduces("0:0:0:0:0:ffff:c0a8:0101", "::ffff:192.168.1.1"); test_ntop6_reduces("002:0:0000:0:3::4", "2::3:0:0:4"); test_ntop6_reduces("0:0::1:0:3", "::1:0:3"); test_ntop6_reduces("008:0::0", "8::"); test_ntop6_reduces("0:0:0:0:0:ffff::1", "::ffff:0.0.0.1"); test_ntop6_reduces("abcd:0:0:0:0:0:7f00::", "abcd::7f00:0"); test_ntop6_reduces("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:1:1"); test_ntop6_reduces("fe80:0000:0000:0000:0202:1111:0001:0001", "fe80::202:1111:1:1"); test_ntop6_reduces("1000:0001:0000:0007:0000:0000:0000:0000", "1000:1:0:7::"); /* Bad af param */ test_eq(tor_inet_pton(AF_UNSPEC, 0, 0), -1); /* === Test pton: invalid in6. */ test_pton6_bad("foobar."); test_pton6_bad("-1::"); test_pton6_bad("00001::"); test_pton6_bad("10000::"); test_pton6_bad("::10000"); test_pton6_bad("55555::"); test_pton6_bad("9:-60::"); test_pton6_bad("9:+60::"); test_pton6_bad("9|60::"); test_pton6_bad("0x60::"); test_pton6_bad("::0x60"); test_pton6_bad("9:0x60::"); test_pton6_bad("1:2:33333:4:0002:3::"); test_pton6_bad("1:2:3333:4:fish:3::"); test_pton6_bad("1:2:3:4:5:6:7:8:9"); test_pton6_bad("1:2:3:4:5:6:7"); test_pton6_bad("1:2:3:4:5:6:1.2.3.4.5"); test_pton6_bad("1:2:3:4:5:6:1.2.3"); test_pton6_bad("::1.2.3"); test_pton6_bad("::1.2.3.4.5"); test_pton6_bad("::ffff:0xff.0.0.0"); test_pton6_bad("::ffff:ff.0.0.0"); test_pton6_bad("::ffff:256.0.0.0"); test_pton6_bad("::ffff:-1.0.0.0"); test_pton6_bad("99"); test_pton6_bad(""); test_pton6_bad("."); test_pton6_bad(":"); test_pton6_bad("1::2::3:4"); test_pton6_bad("a:::b:c"); test_pton6_bad(":::a:b:c"); test_pton6_bad("a:b:c:::"); /* test internal checking */ test_external_ip("fbff:ffff::2:7", 0); test_internal_ip("fc01::2:7", 0); test_internal_ip("fc01::02:7", 0); test_internal_ip("fc01::002:7", 0); test_internal_ip("fc01::0002:7", 0); test_internal_ip("fdff:ffff::f:f", 0); test_external_ip("fe00::3:f", 0); test_external_ip("fe7f:ffff::2:7", 0); test_internal_ip("fe80::2:7", 0); test_internal_ip("febf:ffff::f:f", 0); test_internal_ip("fec0::2:7:7", 0); test_internal_ip("feff:ffff::e:7:7", 0); test_external_ip("ff00::e:7:7", 0); test_internal_ip("::", 0); test_internal_ip("::1", 0); test_internal_ip("::1", 1); test_internal_ip("::", 0); test_external_ip("::", 1); test_external_ip("::2", 0); test_external_ip("2001::", 0); test_external_ip("ffff::", 0); test_external_ip("::ffff:0.0.0.0", 1); test_internal_ip("::ffff:0.0.0.0", 0); test_internal_ip("::ffff:0.255.255.255", 0); test_external_ip("::ffff:1.0.0.0", 0); test_external_ip("::ffff:9.255.255.255", 0); test_internal_ip("::ffff:10.0.0.0", 0); test_internal_ip("::ffff:10.255.255.255", 0); test_external_ip("::ffff:11.0.0.0", 0); test_external_ip("::ffff:126.255.255.255", 0); test_internal_ip("::ffff:127.0.0.0", 0); test_internal_ip("::ffff:127.255.255.255", 0); test_external_ip("::ffff:128.0.0.0", 0); test_external_ip("::ffff:172.15.255.255", 0); test_internal_ip("::ffff:172.16.0.0", 0); test_internal_ip("::ffff:172.31.255.255", 0); test_external_ip("::ffff:172.32.0.0", 0); test_external_ip("::ffff:192.167.255.255", 0); test_internal_ip("::ffff:192.168.0.0", 0); test_internal_ip("::ffff:192.168.255.255", 0); test_external_ip("::ffff:192.169.0.0", 0); test_external_ip("::ffff:169.253.255.255", 0); test_internal_ip("::ffff:169.254.0.0", 0); test_internal_ip("::ffff:169.254.255.255", 0); test_external_ip("::ffff:169.255.0.0", 0); test_assert(is_internal_IP(0x7f000001, 0)); /* tor_addr_compare(tor_addr_t x2) */ test_addr_compare("ffff::", ==, "ffff::0"); test_addr_compare("0::3:2:1", <, "0::ffff:0.3.2.1"); test_addr_compare("0::2:2:1", <, "0::ffff:0.3.2.1"); test_addr_compare("0::ffff:0.3.2.1", >, "0::0:0:0"); test_addr_compare("0::ffff:5.2.2.1", <, "::ffff:6.0.0.0"); /* XXXX wrong. */ tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL); test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0); tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL); test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0); /* test compare_masked */ test_addr_compare_masked("ffff::", ==, "ffff::0", 128); test_addr_compare_masked("ffff::", ==, "ffff::0", 64); test_addr_compare_masked("0::2:2:1", <, "0::8000:2:1", 81); test_addr_compare_masked("0::2:2:1", ==, "0::8000:2:1", 80); /* Test undecorated tor_addr_to_str */ test_eq(AF_INET6, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); test_streq(p1, "123:45:6789::5005:11"); test_eq(AF_INET, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); test_streq(p1, "18.0.0.1"); /* Test decorated tor_addr_to_str */ test_eq(AF_INET6, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); test_streq(p1, "[123:45:6789::5005:11]"); test_eq(AF_INET, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); test_streq(p1, "18.0.0.1"); /* Test buffer bounds checking of tor_addr_to_str */ test_eq(AF_INET6, tor_addr_parse(&t1, "::")); /* 2 + \0 */ test_eq_ptr(tor_addr_to_str(buf, &t1, 2, 0), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 3, 0), "::"); test_eq_ptr(tor_addr_to_str(buf, &t1, 4, 1), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 5, 1), "[::]"); test_eq(AF_INET6, tor_addr_parse(&t1, "2000::1337")); /* 10 + \0 */ test_eq_ptr(tor_addr_to_str(buf, &t1, 10, 0), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 11, 0), "2000::1337"); test_eq_ptr(tor_addr_to_str(buf, &t1, 12, 1), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 13, 1), "[2000::1337]"); test_eq(AF_INET, tor_addr_parse(&t1, "1.2.3.4")); /* 7 + \0 */ test_eq_ptr(tor_addr_to_str(buf, &t1, 7, 0), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 8, 0), "1.2.3.4"); test_eq(AF_INET, tor_addr_parse(&t1, "255.255.255.255")); /* 15 + \0 */ test_eq_ptr(tor_addr_to_str(buf, &t1, 15, 0), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 16, 0), "255.255.255.255"); test_eq_ptr(tor_addr_to_str(buf, &t1, 15, 1), NULL); /* too short buf */ test_streq(tor_addr_to_str(buf, &t1, 16, 1), "255.255.255.255"); t1.family = AF_UNSPEC; test_eq_ptr(tor_addr_to_str(buf, &t1, sizeof(buf), 0), NULL); /* Test tor_addr_parse_PTR_name */ i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 0); test_eq(0, i); i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 1); test_eq(0, i); i = tor_addr_parse_PTR_name(&t1, "1.0.168.192.in-addr.arpa", AF_UNSPEC, 1); test_eq(1, i); test_eq(tor_addr_family(&t1), AF_INET); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); test_streq(p1, "192.168.0.1"); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 0); test_eq(0, i); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 1); test_eq(1, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); test_streq(p1, "192.168.0.99"); memset(&t1, 0, sizeof(t1)); i = tor_addr_parse_PTR_name(&t1, "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); test_eq(1, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); test_streq(p1, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]"); /* Failing cases. */ i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "32.1.1.in-addr.arpa", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, ".in-addr.arpa", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_UNSPEC, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_INET6, 0); test_eq(i, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_INET, 0); test_eq(i, -1); /* === Test tor_addr_to_PTR_name */ /* Stage IPv4 addr */ memset(&sa_storage, 0, sizeof(sa_storage)); sin = (struct sockaddr_in *)&sa_storage; sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl(0x7f010203); /* 127.1.2.3 */ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL); /* Check IPv4 PTR - too short buffer */ test_eq(tor_addr_to_PTR_name(rbuf, 1, &t1), -1); test_eq(tor_addr_to_PTR_name(rbuf, strlen("3.2.1.127.in-addr.arpa") - 1, &t1), -1); /* Check IPv4 PTR - valid addr */ test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1), strlen("3.2.1.127.in-addr.arpa")); test_streq(rbuf, "3.2.1.127.in-addr.arpa"); /* Invalid addr family */ t1.family = AF_UNSPEC; test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1), -1); /* Stage IPv6 addr */ memset(&sa_storage, 0, sizeof(sa_storage)); sin6 = (struct sockaddr_in6 *)&sa_storage; sin6->sin6_family = AF_INET6; sin6->sin6_addr.s6_addr[0] = 0x80; /* 8000::abcd */ sin6->sin6_addr.s6_addr[14] = 0xab; sin6->sin6_addr.s6_addr[15] = 0xcd; tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, NULL); { const char* addr_PTR = "d.c.b.a.0.0.0.0.0.0.0.0.0.0.0.0." "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.ip6.arpa"; /* Check IPv6 PTR - too short buffer */ test_eq(tor_addr_to_PTR_name(rbuf, 0, &t1), -1); test_eq(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1), -1); /* Check IPv6 PTR - valid addr */ test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1), strlen(addr_PTR)); test_streq(rbuf, addr_PTR); } /* test tor_addr_parse_mask_ports */ test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6, 0, 0, 0, 0x0000000f, 17, 47, 95); test_streq(p1, "::f"); //test_addr_parse("[::fefe:4.1.1.7/120]:999-1000"); //test_addr_parse_check("::fefe:401:107", 120, 999, 1000); test_addr_mask_ports_parse("[::ffff:4.1.1.7]/120:443", AF_INET6, 0, 0, 0x0000ffff, 0x04010107, 120, 443, 443); test_streq(p1, "::ffff:4.1.1.7"); test_addr_mask_ports_parse("[abcd:2::44a:0]:2-65000", AF_INET6, 0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000); test_streq(p1, "abcd:2::44a:0"); r=tor_addr_parse_mask_ports("[fefef::]/112", &t1, NULL, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("efef::/112", &t1, NULL, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]", &t1, NULL, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL); test_assert(r == -1); /* Test for V4-mapped address with mask < 96. (arguably not valid) */ r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]", &t1, &mask, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("1.1.2.2/33", &t1, &mask, NULL, NULL); test_assert(r == -1); r=tor_addr_parse_mask_ports("1.1.2.2/31", &t1, &mask, NULL, NULL); test_assert(r == AF_INET); r=tor_addr_parse_mask_ports("[efef::]/112", &t1, &mask, &port1, &port2); test_assert(r == AF_INET6); test_assert(port1 == 1); test_assert(port2 == 65535); /* make sure inet address lengths >= max */ test_assert(INET_NTOA_BUF_LEN >= sizeof("255.255.255.255")); test_assert(TOR_ADDR_BUF_LEN >= sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")); test_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr)); /* get interface addresses */ r = get_interface_address6(LOG_DEBUG, AF_INET, &t1); i = get_interface_address6(LOG_DEBUG, AF_INET6, &t2); TT_BLATHER(("v4 address: %s (family=%d)", fmt_addr(&t1), tor_addr_family(&t1))); TT_BLATHER(("v6 address: %s (family=%d)", fmt_addr(&t2), tor_addr_family(&t2))); done: ; }
static void test_pt_parsing(void *arg) { char line[200]; transport_t *transport = NULL; tor_addr_t test_addr; managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t)); (void)arg; mp->conf_state = PT_PROTO_INFANT; mp->transports = smartlist_new(); /* incomplete cmethod */ strlcpy(line,"CMETHOD trebuchet",sizeof(line)); tt_int_op(parse_cmethod_line(line, mp), OP_LT, 0); reset_mp(mp); /* wrong proxy type */ strlcpy(line,"CMETHOD trebuchet dog 127.0.0.1:1999",sizeof(line)); tt_int_op(parse_cmethod_line(line, mp), OP_LT, 0); reset_mp(mp); /* wrong addrport */ strlcpy(line,"CMETHOD trebuchet socks4 abcd",sizeof(line)); tt_int_op(parse_cmethod_line(line, mp), OP_LT, 0); reset_mp(mp); /* correct line */ strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line)); tt_int_op(parse_cmethod_line(line, mp), OP_EQ, 0); tt_int_op(smartlist_len(mp->transports), OP_EQ, 1); transport = smartlist_get(mp->transports, 0); /* test registered address of transport */ tor_addr_parse(&test_addr, "127.0.0.1"); tt_assert(tor_addr_eq(&test_addr, &transport->addr)); /* test registered port of transport */ tt_uint_op(transport->port, OP_EQ, 1999); /* test registered SOCKS version of transport */ tt_int_op(transport->socks_version, OP_EQ, PROXY_SOCKS5); /* test registered name of transport */ tt_str_op(transport->name,OP_EQ, "trebuchet"); reset_mp(mp); /* incomplete smethod */ strlcpy(line,"SMETHOD trebuchet",sizeof(line)); tt_int_op(parse_smethod_line(line, mp), OP_LT, 0); reset_mp(mp); /* wrong addr type */ strlcpy(line,"SMETHOD trebuchet abcd",sizeof(line)); tt_int_op(parse_smethod_line(line, mp), OP_LT, 0); reset_mp(mp); /* cowwect */ strlcpy(line,"SMETHOD trebuchy 127.0.0.2:2999",sizeof(line)); tt_int_op(parse_smethod_line(line, mp), OP_EQ, 0); tt_int_op(smartlist_len(mp->transports), OP_EQ, 1); transport = smartlist_get(mp->transports, 0); /* test registered address of transport */ tor_addr_parse(&test_addr, "127.0.0.2"); tt_assert(tor_addr_eq(&test_addr, &transport->addr)); /* test registered port of transport */ tt_uint_op(transport->port, OP_EQ, 2999); /* test registered name of transport */ tt_str_op(transport->name,OP_EQ, "trebuchy"); reset_mp(mp); /* Include some arguments. Good ones. */ strlcpy(line,"SMETHOD trebuchet 127.0.0.1:9999 " "ARGS:counterweight=3,sling=snappy", sizeof(line)); tt_int_op(parse_smethod_line(line, mp), OP_EQ, 0); tt_int_op(1, OP_EQ, smartlist_len(mp->transports)); { const transport_t *transport_ = smartlist_get(mp->transports, 0); tt_assert(transport_); tt_str_op(transport_->name, OP_EQ, "trebuchet"); tt_int_op(transport_->port, OP_EQ, 9999); tt_str_op(fmt_addr(&transport_->addr), OP_EQ, "127.0.0.1"); tt_str_op(transport_->extra_info_args, OP_EQ, "counterweight=3,sling=snappy"); } reset_mp(mp); /* unsupported version */ strlcpy(line,"VERSION 666",sizeof(line)); tt_int_op(parse_version(line, mp), OP_LT, 0); /* incomplete VERSION */ strlcpy(line,"VERSION ",sizeof(line)); tt_int_op(parse_version(line, mp), OP_LT, 0); /* correct VERSION */ strlcpy(line,"VERSION 1",sizeof(line)); tt_int_op(parse_version(line, mp), OP_EQ, 0); done: reset_mp(mp); smartlist_free(mp->transports); tor_free(mp); }
hs_desc_intro_point_t * hs_helper_build_intro_point(const ed25519_keypair_t *signing_kp, time_t now, const char *addr, int legacy) { int ret; ed25519_keypair_t auth_kp; hs_desc_intro_point_t *intro_point = NULL; hs_desc_intro_point_t *ip = hs_desc_intro_point_new(); /* For a usable intro point we need at least two link specifiers: One legacy * keyid and one ipv4 */ { tor_addr_t a; tor_addr_make_unspec(&a); link_specifier_t *ls_legacy = link_specifier_new(); link_specifier_t *ls_ip = link_specifier_new(); link_specifier_set_ls_type(ls_legacy, LS_LEGACY_ID); memset(link_specifier_getarray_un_legacy_id(ls_legacy), 'C', link_specifier_getlen_un_legacy_id(ls_legacy)); int family = tor_addr_parse(&a, addr); switch (family) { case AF_INET: link_specifier_set_ls_type(ls_ip, LS_IPV4); link_specifier_set_un_ipv4_addr(ls_ip, tor_addr_to_ipv4h(&a)); link_specifier_set_un_ipv4_port(ls_ip, 9001); break; case AF_INET6: link_specifier_set_ls_type(ls_ip, LS_IPV6); memcpy(link_specifier_getarray_un_ipv6_addr(ls_ip), tor_addr_to_in6_addr8(&a), link_specifier_getlen_un_ipv6_addr(ls_ip)); link_specifier_set_un_ipv6_port(ls_ip, 9001); break; default: /* Stop the test, not supposed to have an error. * Compare with -1 to show the actual family. */ tt_int_op(family, OP_EQ, -1); } smartlist_add(ip->link_specifiers, ls_legacy); smartlist_add(ip->link_specifiers, ls_ip); } ret = ed25519_keypair_generate(&auth_kp, 0); tt_int_op(ret, ==, 0); ip->auth_key_cert = tor_cert_create(signing_kp, CERT_TYPE_AUTH_HS_IP_KEY, &auth_kp.pubkey, now, HS_DESC_CERT_LIFETIME, CERT_FLAG_INCLUDE_SIGNING_KEY); tt_assert(ip->auth_key_cert); if (legacy) { ip->legacy.key = crypto_pk_new(); tt_assert(ip->legacy.key); ret = crypto_pk_generate_key(ip->legacy.key); tt_int_op(ret, ==, 0); ssize_t cert_len = tor_make_rsa_ed25519_crosscert( &signing_kp->pubkey, ip->legacy.key, now + HS_DESC_CERT_LIFETIME, &ip->legacy.cert.encoded); tt_assert(ip->legacy.cert.encoded); tt_u64_op(cert_len, OP_GT, 0); ip->legacy.cert.len = cert_len; } /* Encryption key. */ { int signbit; curve25519_keypair_t curve25519_kp; ed25519_keypair_t ed25519_kp; tor_cert_t *cross_cert; ret = curve25519_keypair_generate(&curve25519_kp, 0); tt_int_op(ret, ==, 0); ed25519_keypair_from_curve25519_keypair(&ed25519_kp, &signbit, &curve25519_kp); cross_cert = tor_cert_create(signing_kp, CERT_TYPE_CROSS_HS_IP_KEYS, &ed25519_kp.pubkey, time(NULL), HS_DESC_CERT_LIFETIME, CERT_FLAG_INCLUDE_SIGNING_KEY); tt_assert(cross_cert); ip->enc_key_cert = cross_cert; } intro_point = ip; done: if (intro_point == NULL) tor_free(ip); return intro_point; }
static void test_virtaddrmap_persist(void *data) { (void)data; const char *a, *b, *c; tor_addr_t addr; char *ones = NULL; addressmap_init(); // Try a hostname. a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME, tor_strdup("foobar.baz")); tt_assert(a); tt_assert(!strcmpend(a, ".virtual")); // mock crypto_rand to repeat the same result twice; make sure we get // different outcomes. (Because even though the odds for receiving the // same 80-bit address twice is only 1/2^40, it could still happen for // some user -- but running our test through 2^40 iterations isn't // reasonable.) canned_data = "1234567890" // the first call returns this. "1234567890" // the second call returns this. "abcdefghij"; // the third call returns this. canned_data_len = 30; MOCK(crypto_rand, crypto_canned); a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME, tor_strdup("quuxit.baz")); b = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME, tor_strdup("nescio.baz")); tt_assert(a); tt_assert(b); tt_str_op(a, OP_EQ, "gezdgnbvgy3tqojq.virtual"); tt_str_op(b, OP_EQ, "mfrggzdfmztwq2lk.virtual"); // Now try something to get us an ipv4 address UNMOCK(crypto_rand); tt_int_op(0,OP_EQ, parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, NULL)); a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, tor_strdup("foobar.baz")); tt_assert(a); tt_assert(!strcmpstart(a, "192.168.")); tor_addr_parse(&addr, a); tt_int_op(AF_INET, OP_EQ, tor_addr_family(&addr)); b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, tor_strdup("quuxit.baz")); tt_str_op(b, OP_NE, a); tt_assert(!strcmpstart(b, "192.168.")); // Try some canned entropy and verify all the we discard duplicates, // addresses that end with 0, and addresses that end with 255. MOCK(crypto_rand, crypto_canned); canned_data = "\x01\x02\x03\x04" // okay "\x01\x02\x03\x04" // duplicate "\x03\x04\x00\x00" // bad ending 1 "\x05\x05\x00\xff" // bad ending 2 "\x05\x06\x07\xf0"; // okay canned_data_len = 20; a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, tor_strdup("wumble.onion")); b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, tor_strdup("wumpus.onion")); tt_str_op(a, OP_EQ, "192.168.3.4"); tt_str_op(b, OP_EQ, "192.168.7.240"); // Now try IPv6! UNMOCK(crypto_rand); tt_int_op(0,OP_EQ, parse_virtual_addr_network("1010:F000::/20", AF_INET6, 0, NULL)); a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6, tor_strdup("foobar.baz")); tt_assert(a); tt_assert(!strcmpstart(a, "[1010:f")); tor_addr_parse(&addr, a); tt_int_op(AF_INET6, OP_EQ, tor_addr_family(&addr)); b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6, tor_strdup("quuxit.baz")); tt_str_op(b, OP_NE, a); tt_assert(!strcmpstart(b, "[1010:f")); // Try IPv6 with canned entropy, to make sure we detect duplicates. MOCK(crypto_rand, crypto_canned); canned_data = "acanthopterygian" // okay "cinematographist" // okay "acanthopterygian" // duplicate "acanthopterygian" // duplicate "acanthopterygian" // duplicate "cinematographist" // duplicate "coadministration"; // okay canned_data_len = 16 * 7; a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6, tor_strdup("wuffle.baz")); b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6, tor_strdup("gribble.baz")); c = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6, tor_strdup("surprisingly-legible.baz")); tt_str_op(a, OP_EQ, "[1010:f16e:7468:6f70:7465:7279:6769:616e]"); tt_str_op(b, OP_EQ, "[1010:fe65:6d61:746f:6772:6170:6869:7374]"); tt_str_op(c, OP_EQ, "[1010:f164:6d69:6e69:7374:7261:7469:6f6e]"); // Try address exhaustion: make sure we can actually fail if we // get too many already-existing addresses. canned_data_len = 128*1024; canned_data = ones = tor_malloc(canned_data_len); memset(ones, 1, canned_data_len); // There is some chance this one will fail if a previous random // allocation gave out the address already. a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, tor_strdup("might-work.onion")); if (a) { tt_str_op(a, OP_EQ, "192.168.1.1"); } setup_capture_of_logs(LOG_WARN); // This one will definitely fail, since we've set up the RNG to hand // out "1" forever. b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, tor_strdup("wont-work.onion")); tt_assert(b == NULL); expect_single_log_msg_containing("Ran out of virtual addresses!"); done: UNMOCK(crypto_rand); tor_free(ones); addressmap_free_all(); teardown_capture_of_logs(); }
/** Parse the encoded introduction points in <b>intro_points_encoded</b> of * length <b>intro_points_encoded_size</b> and write the result to the * descriptor in <b>parsed</b>; return the number of successfully parsed * introduction points or -1 in case of a failure. */ int rend_parse_introduction_points(rend_service_descriptor_t *parsed, const char *intro_points_encoded, size_t intro_points_encoded_size) { const char *current_ipo, *end_of_intro_points; smartlist_t *tokens = NULL; directory_token_t *tok; rend_intro_point_t *intro; extend_info_t *info; int result, num_ok=1; memarea_t *area = NULL; tor_assert(parsed); /** Function may only be invoked once. */ tor_assert(!parsed->intro_nodes); if (!intro_points_encoded || intro_points_encoded_size == 0) { log_warn(LD_REND, "Empty or zero size introduction point list"); goto err; } /* Consider one intro point after the other. */ current_ipo = intro_points_encoded; end_of_intro_points = intro_points_encoded + intro_points_encoded_size; tokens = smartlist_new(); parsed->intro_nodes = smartlist_new(); area = memarea_new(); while (!fast_memcmpstart(current_ipo, end_of_intro_points-current_ipo, "introduction-point ")) { /* Determine end of string. */ const char *eos = tor_memstr(current_ipo, end_of_intro_points-current_ipo, "\nintroduction-point "); if (!eos) eos = end_of_intro_points; else eos = eos+1; tor_assert(eos <= intro_points_encoded+intro_points_encoded_size); /* Free tokens and clear token list. */ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t)); smartlist_clear(tokens); memarea_clear(area); /* Tokenize string. */ if (tokenize_string(area, current_ipo, eos, tokens, ipo_token_table, 0)) { log_warn(LD_REND, "Error tokenizing introduction point"); goto err; } /* Advance to next introduction point, if available. */ current_ipo = eos; /* Check minimum allowed length of introduction point. */ if (smartlist_len(tokens) < 5) { log_warn(LD_REND, "Impossibly short introduction point."); goto err; } /* Allocate new intro point and extend info. */ intro = tor_malloc_zero(sizeof(rend_intro_point_t)); info = intro->extend_info = tor_malloc_zero(sizeof(extend_info_t)); /* Parse identifier. */ tok = find_by_keyword(tokens, R_IPO_IDENTIFIER); if (base32_decode(info->identity_digest, DIGEST_LEN, tok->args[0], REND_INTRO_POINT_ID_LEN_BASE32) < 0) { log_warn(LD_REND, "Identity digest contains illegal characters: %s", tok->args[0]); rend_intro_point_free(intro); goto err; } /* Write identifier to nickname. */ info->nickname[0] = '$'; base16_encode(info->nickname + 1, sizeof(info->nickname) - 1, info->identity_digest, DIGEST_LEN); /* Parse IP address. */ tok = find_by_keyword(tokens, R_IPO_IP_ADDRESS); if (tor_addr_parse(&info->addr, tok->args[0])<0) { log_warn(LD_REND, "Could not parse introduction point address."); rend_intro_point_free(intro); goto err; } if (tor_addr_family(&info->addr) != AF_INET) { log_warn(LD_REND, "Introduction point address was not ipv4."); rend_intro_point_free(intro); goto err; } /* Parse onion port. */ tok = find_by_keyword(tokens, R_IPO_ONION_PORT); info->port = (uint16_t) tor_parse_long(tok->args[0],10,1,65535, &num_ok,NULL); if (!info->port || !num_ok) { log_warn(LD_REND, "Introduction point onion port %s is invalid", escaped(tok->args[0])); rend_intro_point_free(intro); goto err; } /* Parse onion key. */ tok = find_by_keyword(tokens, R_IPO_ONION_KEY); if (!crypto_pk_public_exponent_ok(tok->key)) { log_warn(LD_REND, "Introduction point's onion key had invalid exponent."); rend_intro_point_free(intro); goto err; } info->onion_key = tok->key; tok->key = NULL; /* Prevent free */ /* Parse service key. */ tok = find_by_keyword(tokens, R_IPO_SERVICE_KEY); if (!crypto_pk_public_exponent_ok(tok->key)) { log_warn(LD_REND, "Introduction point key had invalid exponent."); rend_intro_point_free(intro); goto err; } intro->intro_key = tok->key; tok->key = NULL; /* Prevent free */ /* Add extend info to list of introduction points. */ smartlist_add(parsed->intro_nodes, intro); } result = smartlist_len(parsed->intro_nodes); goto done; err: result = -1; done: /* Free tokens and clear token list. */ if (tokens) { SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t)); smartlist_free(tokens); } if (area) memarea_drop_all(area); return result; }
/** Run unit tests for IPv6 encoding/decoding/manipulation functions. */ static void test_addr_ip6_helpers(void *arg) { char buf[TOR_ADDR_BUF_LEN], bug[TOR_ADDR_BUF_LEN]; char rbuf[REVERSE_LOOKUP_NAME_BUF_LEN]; struct in6_addr a1, a2; tor_addr_t t1, t2; int r, i; uint16_t port1, port2; maskbits_t mask; const char *p1; struct sockaddr_storage sa_storage; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; /* Test tor_inet_ntop and tor_inet_pton: IPv6 */ (void)arg; { const char *ip = "2001::1234"; const char *ip_ffff = "::ffff:192.168.1.2"; /* good round trip */ tt_int_op(tor_inet_pton(AF_INET6, ip, &a1),OP_EQ, 1); tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)),OP_EQ, &buf); tt_str_op(buf,OP_EQ, ip); /* good round trip - ::ffff:0:0 style */ tt_int_op(tor_inet_pton(AF_INET6, ip_ffff, &a2),OP_EQ, 1); tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, sizeof(buf)),OP_EQ, &buf); tt_str_op(buf,OP_EQ, ip_ffff); /* just long enough buffer (remember \0) */ tt_str_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)+1),OP_EQ, ip); tt_str_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)+1),OP_EQ, ip_ffff); /* too short buffer (remember \0) */ tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)),OP_EQ, NULL); tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)),OP_EQ, NULL); } /* ==== Converting to and from sockaddr_t. */ sin = (struct sockaddr_in *)&sa_storage; sin->sin_family = AF_INET; sin->sin_port = htons(9090); sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, &port1); tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ, 0x7f7f0102); tt_int_op(port1, OP_EQ, 9090); memset(&sa_storage, 0, sizeof(sa_storage)); tt_int_op(sizeof(struct sockaddr_in),OP_EQ, tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); tt_int_op(1234,OP_EQ, ntohs(sin->sin_port)); tt_int_op(0x7f7f0102,OP_EQ, ntohl(sin->sin_addr.s_addr)); memset(&sa_storage, 0, sizeof(sa_storage)); sin6 = (struct sockaddr_in6 *)&sa_storage; sin6->sin6_family = AF_INET6; sin6->sin6_port = htons(7070); sin6->sin6_addr.s6_addr[0] = 128; tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, &port1); tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET6); tt_int_op(port1, OP_EQ, 7070); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); tt_str_op(p1,OP_EQ, "8000::"); memset(&sa_storage, 0, sizeof(sa_storage)); tt_int_op(sizeof(struct sockaddr_in6),OP_EQ, tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); tt_int_op(AF_INET6,OP_EQ, sin6->sin6_family); tt_int_op(9999,OP_EQ, ntohs(sin6->sin6_port)); tt_int_op(0x80000000,OP_EQ, ntohl(S6_ADDR32(sin6->sin6_addr)[0])); /* ==== tor_addr_lookup: static cases. (Can't test dns without knowing we * have a good resolver. */ tt_int_op(0,OP_EQ, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1)); tt_int_op(AF_INET,OP_EQ, tor_addr_family(&t1)); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ, 0x7f808182); tt_int_op(0,OP_EQ, tor_addr_lookup("9000::5", AF_UNSPEC, &t1)); tt_int_op(AF_INET6,OP_EQ, tor_addr_family(&t1)); tt_int_op(0x90,OP_EQ, tor_addr_to_in6_addr8(&t1)[0]); tt_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14)); tt_int_op(0x05,OP_EQ, tor_addr_to_in6_addr8(&t1)[15]); /* === Test pton: valid af_inet6 */ /* Simple, valid parsing. */ r = tor_inet_pton(AF_INET6, "0102:0304:0506:0708:090A:0B0C:0D0E:0F10", &a1); tt_int_op(r, OP_EQ, 1); for (i=0;i<16;++i) { tt_int_op(i+1,OP_EQ, (int)a1.s6_addr[i]); } /* ipv4 ending. */ test_pton6_same("0102:0304:0506:0708:090A:0B0C:0D0E:0F10", "0102:0304:0506:0708:090A:0B0C:13.14.15.16"); /* shortened words. */ test_pton6_same("0001:0099:BEEF:0000:0123:FFFF:0001:0001", "1:99:BEEF:0:0123:FFFF:1:1"); /* zeros at the beginning */ test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:1:1"); test_pton6_same("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:0.1.0.1"); /* zeros in the middle. */ test_pton6_same("fe80:0000:0000:0000:0202:1111:0001:0001", "fe80::202:1111:1:1"); /* zeros at the end. */ test_pton6_same("1000:0001:0000:0007:0000:0000:0000:0000", "1000:1:0:7::"); /* === Test ntop: af_inet6 */ test_ntop6_reduces("0:0:0:0:0:0:0:0", "::"); test_ntop6_reduces("0001:0099:BEEF:0006:0123:FFFF:0001:0001", "1:99:beef:6:123:ffff:1:1"); //test_ntop6_reduces("0:0:0:0:0:0:c0a8:0101", "::192.168.1.1"); test_ntop6_reduces("0:0:0:0:0:ffff:c0a8:0101", "::ffff:192.168.1.1"); test_ntop6_reduces("0:0:0:0:0:0:c0a8:0101", "::192.168.1.1"); test_ntop6_reduces("002:0:0000:0:3::4", "2::3:0:0:4"); test_ntop6_reduces("0:0::1:0:3", "::1:0:3"); test_ntop6_reduces("008:0::0", "8::"); test_ntop6_reduces("0:0:0:0:0:ffff::1", "::ffff:0.0.0.1"); test_ntop6_reduces("abcd:0:0:0:0:0:7f00::", "abcd::7f00:0"); test_ntop6_reduces("0000:0000:0000:0000:0009:C0A8:0001:0001", "::9:c0a8:1:1"); test_ntop6_reduces("fe80:0000:0000:0000:0202:1111:0001:0001", "fe80::202:1111:1:1"); test_ntop6_reduces("1000:0001:0000:0007:0000:0000:0000:0000", "1000:1:0:7::"); /* Bad af param */ tt_int_op(tor_inet_pton(AF_UNSPEC, 0, 0),OP_EQ, -1); /* === Test pton: invalid in6. */ test_pton6_bad("foobar."); test_pton6_bad("-1::"); test_pton6_bad("00001::"); test_pton6_bad("10000::"); test_pton6_bad("::10000"); test_pton6_bad("55555::"); test_pton6_bad("9:-60::"); test_pton6_bad("9:+60::"); test_pton6_bad("9|60::"); test_pton6_bad("0x60::"); test_pton6_bad("::0x60"); test_pton6_bad("9:0x60::"); test_pton6_bad("1:2:33333:4:0002:3::"); test_pton6_bad("1:2:3333:4:fish:3::"); test_pton6_bad("1:2:3:4:5:6:7:8:9"); test_pton6_bad("1:2:3:4:5:6:7"); test_pton6_bad("1:2:3:4:5:6:1.2.3.4.5"); test_pton6_bad("1:2:3:4:5:6:1.2.3"); test_pton6_bad("::1.2.3"); test_pton6_bad("::1.2.3.4.5"); test_pton6_bad("::ffff:0xff.0.0.0"); test_pton6_bad("::ffff:ff.0.0.0"); test_pton6_bad("::ffff:256.0.0.0"); test_pton6_bad("::ffff:-1.0.0.0"); test_pton6_bad("99"); test_pton6_bad(""); test_pton6_bad("."); test_pton6_bad(":"); test_pton6_bad("1::2::3:4"); test_pton6_bad("a:::b:c"); test_pton6_bad(":::a:b:c"); test_pton6_bad("a:b:c:::"); test_pton6_bad("1.2.3.4"); test_pton6_bad(":1.2.3.4"); test_pton6_bad(".2.3.4"); /* Regression tests for 22789. */ test_pton6_bad("0xfoo"); test_pton6_bad("0x88"); test_pton6_bad("0xyxxy"); test_pton6_bad("0XFOO"); test_pton6_bad("0X88"); test_pton6_bad("0XYXXY"); test_pton6_bad("0x"); test_pton6_bad("0X"); /* test internal checking */ test_external_ip("fbff:ffff::2:7", 0); test_internal_ip("fc01::2:7", 0); test_internal_ip("fc01::02:7", 0); test_internal_ip("fc01::002:7", 0); test_internal_ip("fc01::0002:7", 0); test_internal_ip("fdff:ffff::f:f", 0); test_external_ip("fe00::3:f", 0); test_external_ip("fe7f:ffff::2:7", 0); test_internal_ip("fe80::2:7", 0); test_internal_ip("febf:ffff::f:f", 0); test_internal_ip("fec0::2:7:7", 0); test_internal_ip("feff:ffff::e:7:7", 0); test_external_ip("ff00::e:7:7", 0); test_internal_ip("::", 0); test_internal_ip("::1", 0); test_internal_ip("::1", 1); test_internal_ip("::", 0); test_external_ip("::", 1); test_external_ip("::2", 0); test_external_ip("2001::", 0); test_external_ip("ffff::", 0); test_external_ip("::ffff:0.0.0.0", 1); test_internal_ip("::ffff:0.0.0.0", 0); test_internal_ip("::ffff:0.255.255.255", 0); test_external_ip("::ffff:1.0.0.0", 0); test_external_ip("::ffff:9.255.255.255", 0); test_internal_ip("::ffff:10.0.0.0", 0); test_internal_ip("::ffff:10.255.255.255", 0); test_external_ip("::ffff:11.0.0.0", 0); test_external_ip("::ffff:126.255.255.255", 0); test_internal_ip("::ffff:127.0.0.0", 0); test_internal_ip("::ffff:127.255.255.255", 0); test_external_ip("::ffff:128.0.0.0", 0); test_external_ip("::ffff:172.15.255.255", 0); test_internal_ip("::ffff:172.16.0.0", 0); test_internal_ip("::ffff:172.31.255.255", 0); test_external_ip("::ffff:172.32.0.0", 0); test_external_ip("::ffff:192.167.255.255", 0); test_internal_ip("::ffff:192.168.0.0", 0); test_internal_ip("::ffff:192.168.255.255", 0); test_external_ip("::ffff:192.169.0.0", 0); test_external_ip("::ffff:169.253.255.255", 0); test_internal_ip("::ffff:169.254.0.0", 0); test_internal_ip("::ffff:169.254.255.255", 0); test_external_ip("::ffff:169.255.0.0", 0); /* tor_addr_compare(tor_addr_t x2) */ test_addr_compare("ffff::", OP_EQ, "ffff::0"); test_addr_compare("0::3:2:1", OP_LT, "0::ffff:0.3.2.1"); test_addr_compare("0::2:2:1", OP_LT, "0::ffff:0.3.2.1"); test_addr_compare("0::ffff:0.3.2.1", OP_GT, "0::0:0:0"); test_addr_compare("0::ffff:5.2.2.1", OP_LT, "::ffff:6.0.0.0"); /* XXXX wrong. */ tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", 0, &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL); tt_int_op(tor_addr_compare(&t1, &t2, CMP_SEMANTIC), OP_EQ, 0); tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", 0, &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL); tt_int_op(tor_addr_compare(&t1, &t2, CMP_SEMANTIC), OP_LT, 0); /* test compare_masked */ test_addr_compare_masked("ffff::", OP_EQ, "ffff::0", 128); test_addr_compare_masked("ffff::", OP_EQ, "ffff::0", 64); test_addr_compare_masked("0::2:2:1", OP_LT, "0::8000:2:1", 81); test_addr_compare_masked("0::2:2:1", OP_EQ, "0::8000:2:1", 80); /* Test undecorated tor_addr_to_str */ tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); tt_str_op(p1,OP_EQ, "123:45:6789::5005:11"); tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); tt_str_op(p1,OP_EQ, "18.0.0.1"); /* Test decorated tor_addr_to_str */ tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "[123:45:6789::5005:11]"); tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "18.0.0.1"); /* Test buffer bounds checking of tor_addr_to_str */ tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "::")); /* 2 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 2, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 3, 0),OP_EQ, "::"); tt_ptr_op(tor_addr_to_str(buf, &t1, 4, 1),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 5, 1),OP_EQ, "[::]"); tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "2000::1337")); /* 10 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 10, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 11, 0),OP_EQ, "2000::1337"); tt_ptr_op(tor_addr_to_str(buf, &t1, 12, 1),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 13, 1),OP_EQ, "[2000::1337]"); tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "1.2.3.4")); /* 7 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 7, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 8, 0),OP_EQ, "1.2.3.4"); tt_int_op(AF_INET, OP_EQ, tor_addr_parse(&t1, "255.255.255.255")); /* 15 + \0 */ tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 0),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 16, 0),OP_EQ, "255.255.255.255"); tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 1),OP_EQ, NULL); /* too short buf */ tt_str_op(tor_addr_to_str(buf, &t1, 16, 1),OP_EQ, "255.255.255.255"); t1.family = AF_UNSPEC; tt_ptr_op(tor_addr_to_str(buf, &t1, sizeof(buf), 0),OP_EQ, NULL); /* Test tor_addr_parse_PTR_name */ i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 0); tt_int_op(0,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 1); tt_int_op(0,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "9999999999999999999999999999.in-addr.arpa", AF_UNSPEC, 1); tt_int_op(-1,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "1.0.168.192.in-addr.arpa", AF_UNSPEC, 1); tt_int_op(1,OP_EQ, i); tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "192.168.0.1"); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 0); tt_int_op(0,OP_EQ, i); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 1); tt_int_op(1,OP_EQ, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "192.168.0.99"); memset(&t1, 0, sizeof(t1)); i = tor_addr_parse_PTR_name(&t1, "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(1,OP_EQ, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); tt_str_op(p1,OP_EQ, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]"); /* Failing cases. */ i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "32.1.1.in-addr.arpa", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, ".in-addr.arpa", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_UNSPEC, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_INET6, 0); tt_int_op(i,OP_EQ, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_INET, 0); tt_int_op(i,OP_EQ, -1); /* === Test tor_addr_to_PTR_name */ /* Stage IPv4 addr */ memset(&sa_storage, 0, sizeof(sa_storage)); sin = (struct sockaddr_in *)&sa_storage; sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl(0x7f010203); /* 127.1.2.3 */ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL); /* Check IPv4 PTR - too short buffer */ tt_int_op(tor_addr_to_PTR_name(rbuf, 1, &t1),OP_EQ, -1); tt_int_op(tor_addr_to_PTR_name(rbuf, strlen("3.2.1.127.in-addr.arpa") - 1, &t1),OP_EQ, -1); /* Check IPv4 PTR - valid addr */ tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ, strlen("3.2.1.127.in-addr.arpa")); tt_str_op(rbuf,OP_EQ, "3.2.1.127.in-addr.arpa"); /* Invalid addr family */ t1.family = AF_UNSPEC; tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ, -1); /* Stage IPv6 addr */ memset(&sa_storage, 0, sizeof(sa_storage)); sin6 = (struct sockaddr_in6 *)&sa_storage; sin6->sin6_family = AF_INET6; sin6->sin6_addr.s6_addr[0] = 0x80; /* 8000::abcd */ sin6->sin6_addr.s6_addr[14] = 0xab; sin6->sin6_addr.s6_addr[15] = 0xcd; tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, NULL); { const char* addr_PTR = "d.c.b.a.0.0.0.0.0.0.0.0.0.0.0.0." "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.ip6.arpa"; /* Check IPv6 PTR - too short buffer */ tt_int_op(tor_addr_to_PTR_name(rbuf, 0, &t1),OP_EQ, -1); tt_int_op(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1),OP_EQ, -1); /* Check IPv6 PTR - valid addr */ tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ, strlen(addr_PTR)); tt_str_op(rbuf,OP_EQ, addr_PTR); } /* XXXX turn this into a separate function; it's not all IPv6. */ /* test tor_addr_parse_mask_ports */ test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6, 0, 0, 0, 0x0000000f, 17, 47, 95); tt_str_op(p1,OP_EQ, "::f"); //test_addr_parse("[::fefe:4.1.1.7/120]:999-1000"); //test_addr_parse_check("::fefe:401:107", 120, 999, 1000); test_addr_mask_ports_parse("[::ffff:4.1.1.7]/120:443", AF_INET6, 0, 0, 0x0000ffff, 0x04010107, 120, 443, 443); tt_str_op(p1,OP_EQ, "::ffff:4.1.1.7"); test_addr_mask_ports_parse("[abcd:2::44a:0]:2-65000", AF_INET6, 0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000); tt_str_op(p1,OP_EQ, "abcd:2::44a:0"); /* Try some long addresses. */ r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, AF_INET6); r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:11111]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111:1]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports( "[ffff:1111:1111:1111:1111:1111:1111:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* Try some failing cases. */ r=tor_addr_parse_mask_ports("[fefef::]/112", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[fefe::/112", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[fefe::", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[fefe::X]", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("efef::/112", 0, &t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]",0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/fred",0,&t1,&mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/255.255.0.0", 0,&t1, NULL, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* This one will get rejected because it isn't a pure prefix. */ r=tor_addr_parse_mask_ports("1.1.2.3/255.255.64.0",0,&t1, &mask,NULL,NULL); tt_int_op(r, OP_EQ, -1); /* Test for V4-mapped address with mask < 96. (arguably not valid) */ r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("1.1.2.2/33",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* Try extended wildcard addresses with out TAPMP_EXTENDED_STAR*/ r=tor_addr_parse_mask_ports("*4",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("*6",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); tt_int_op(r, OP_EQ, -1); /* Try a mask with a wildcard. */ r=tor_addr_parse_mask_ports("*/16",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("*4/16",TAPMP_EXTENDED_STAR, &t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("*6/30",TAPMP_EXTENDED_STAR, &t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, -1); /* Basic mask tests*/ r=tor_addr_parse_mask_ports("1.1.2.2/31",0,&t1, &mask, NULL, NULL); tt_int_op(r, OP_EQ, AF_INET); tt_int_op(mask,OP_EQ,31); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x01010202); r=tor_addr_parse_mask_ports("3.4.16.032:1-2",0,&t1, &mask, &port1, &port2); tt_int_op(r, OP_EQ, AF_INET); tt_int_op(mask,OP_EQ,32); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x03041020); tt_uint_op(port1, OP_EQ, 1); tt_uint_op(port2, OP_EQ, 2); r=tor_addr_parse_mask_ports("1.1.2.3/255.255.128.0",0,&t1, &mask,NULL,NULL); tt_int_op(r, OP_EQ, AF_INET); tt_int_op(mask,OP_EQ,17); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x01010203); r=tor_addr_parse_mask_ports("[efef::]/112",0,&t1, &mask, &port1, &port2); tt_int_op(r, OP_EQ, AF_INET6); tt_uint_op(port1, OP_EQ, 1); tt_uint_op(port2, OP_EQ, 65535); /* Try regular wildcard behavior without TAPMP_EXTENDED_STAR */ r=tor_addr_parse_mask_ports("*:80-443",0,&t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_INET); /* Old users of this always get inet */ tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,80); tt_int_op(port2,OP_EQ,443); /* Now try wildcards *with* TAPMP_EXTENDED_STAR */ r=tor_addr_parse_mask_ports("*:8000-9000",TAPMP_EXTENDED_STAR, &t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_UNSPEC); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_UNSPEC); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,8000); tt_int_op(port2,OP_EQ,9000); r=tor_addr_parse_mask_ports("*4:6667",TAPMP_EXTENDED_STAR, &t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_INET); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,6667); tt_int_op(port2,OP_EQ,6667); r=tor_addr_parse_mask_ports("*6",TAPMP_EXTENDED_STAR, &t1,&mask,&port1,&port2); tt_int_op(r,OP_EQ,AF_INET6); tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET6); tt_assert(tor_mem_is_zero((const char*)tor_addr_to_in6_addr32(&t1), 16)); tt_int_op(mask,OP_EQ,0); tt_int_op(port1,OP_EQ,1); tt_int_op(port2,OP_EQ,65535); /* make sure inet address lengths >= max */ tt_int_op(INET_NTOA_BUF_LEN, OP_GE, sizeof("255.255.255.255")); tt_int_op(TOR_ADDR_BUF_LEN, OP_GE, sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")); tt_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr)); /* get interface addresses */ r = get_interface_address6(LOG_DEBUG, AF_INET, &t1); tt_int_op(r, OP_LE, 0); // "it worked or it didn't" i = get_interface_address6(LOG_DEBUG, AF_INET6, &t2); tt_int_op(i, OP_LE, 0); // "it worked or it didn't" TT_BLATHER(("v4 address: %s (family=%d)", fmt_addr(&t1), tor_addr_family(&t1))); TT_BLATHER(("v6 address: %s (family=%d)", fmt_addr(&t2), tor_addr_family(&t2))); done: ; }
/** * Generate a routerstatus for v3_networkstatus test. */ vote_routerstatus_t * dir_common_gen_routerstatus_for_v3ns(int idx, time_t now) { vote_routerstatus_t *vrs=NULL; routerstatus_t *rs = NULL; tor_addr_t addr_ipv6; char *method_list = NULL; switch (idx) { case 0: /* Generate the first routerstatus. */ vrs = tor_malloc_zero(sizeof(vote_routerstatus_t)); rs = &vrs->status; vrs->version = tor_strdup("0.1.2.14"); rs->published_on = now-1500; strlcpy(rs->nickname, "router2", sizeof(rs->nickname)); memset(rs->identity_digest, TEST_DIR_ROUTER_ID_1, DIGEST_LEN); memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_1, DIGEST_LEN); rs->addr = 0x99008801; rs->or_port = 443; rs->dir_port = 8000; /* all flags but running and v2dir cleared */ rs->is_flagged_running = 1; rs->is_v2_dir = 1; break; case 1: /* Generate the second routerstatus. */ vrs = tor_malloc_zero(sizeof(vote_routerstatus_t)); rs = &vrs->status; vrs->version = tor_strdup("0.2.0.5"); rs->published_on = now-1000; strlcpy(rs->nickname, "router1", sizeof(rs->nickname)); memset(rs->identity_digest, TEST_DIR_ROUTER_ID_2, DIGEST_LEN); memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_2, DIGEST_LEN); rs->addr = 0x99009901; rs->or_port = 443; rs->dir_port = 0; tor_addr_parse(&addr_ipv6, "[1:2:3::4]"); tor_addr_copy(&rs->ipv6_addr, &addr_ipv6); rs->ipv6_orport = 4711; rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running = rs->is_valid = rs->is_possible_guard = rs->is_v2_dir = 1; break; case 2: /* Generate the third routerstatus. */ vrs = tor_malloc_zero(sizeof(vote_routerstatus_t)); rs = &vrs->status; vrs->version = tor_strdup("0.1.0.3"); rs->published_on = now-1000; strlcpy(rs->nickname, "router3", sizeof(rs->nickname)); memset(rs->identity_digest, TEST_DIR_ROUTER_ID_3, DIGEST_LEN); memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_3, DIGEST_LEN); rs->addr = 0xAA009901; rs->or_port = 400; rs->dir_port = 9999; rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running = rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1; break; case 3: /* Generate a fourth routerstatus that is not running. */ vrs = tor_malloc_zero(sizeof(vote_routerstatus_t)); rs = &vrs->status; vrs->version = tor_strdup("0.1.6.3"); rs->published_on = now-1000; strlcpy(rs->nickname, "router4", sizeof(rs->nickname)); memset(rs->identity_digest, TEST_DIR_ROUTER_ID_4, DIGEST_LEN); memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_4, DIGEST_LEN); rs->addr = 0xC0000203; rs->or_port = 500; rs->dir_port = 1999; rs->is_v2_dir = 1; /* Running flag (and others) cleared */ break; case 4: /* No more for this test; return NULL */ vrs = NULL; break; default: /* Shouldn't happen */ tt_assert(0); } if (vrs) { vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t)); method_list = make_consensus_method_list(MIN_SUPPORTED_CONSENSUS_METHOD, MAX_SUPPORTED_CONSENSUS_METHOD, ","); tor_asprintf(&vrs->microdesc->microdesc_hash_line, "m %s " "sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n", method_list, idx); } done: tor_free(method_list); return vrs; }
static void test_cfmt_connected_cells(void *arg) { relay_header_t rh; 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. */ make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "", 0); relay_header_unpack(&rh, cell.payload); r = connected_cell_parse(&rh, &cell, &addr, &ttl); tt_int_op(r, ==, 0); tt_int_op(tor_addr_family(&addr), ==, AF_UNSPEC); tt_int_op(ttl, ==, -1); /* A slightly less oldschool one: only an IPv4 address */ make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x20\x30\x40\x50", 4); relay_header_unpack(&rh, cell.payload); 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), ==, "32.48.64.80"); tt_int_op(ttl, ==, -1); /* Bogus but understandable: truncated TTL */ make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x11\x12\x13\x14\x15", 5); relay_header_unpack(&rh, cell.payload); 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), ==, "17.18.19.20"); tt_int_op(ttl, ==, -1); /* Regular IPv4 one: address and TTL */ make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x02\x03\x04\x05\x00\x00\x0e\x10", 8); relay_header_unpack(&rh, cell.payload); 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), ==, "2.3.4.5"); tt_int_op(ttl, ==, 3600); /* IPv4 with too-big TTL */ make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x02\x03\x04\x05\xf0\x00\x00\x00", 8); relay_header_unpack(&rh, cell.payload); 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), ==, "2.3.4.5"); tt_int_op(ttl, ==, -1); /* IPv6 (ttl is mandatory) */ make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x00\x00\x00\x00\x06" "\x26\x07\xf8\xb0\x40\x0c\x0c\x02" "\x00\x00\x00\x00\x00\x00\x00\x68" "\x00\x00\x02\x58", 25); relay_header_unpack(&rh, cell.payload); 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), ==, "2607:f8b0:400c:c02::68"); tt_int_op(ttl, ==, 600); /* IPv6 (ttl too big) */ make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x00\x00\x00\x00\x06" "\x26\x07\xf8\xb0\x40\x0c\x0c\x02" "\x00\x00\x00\x00\x00\x00\x00\x68" "\x90\x00\x02\x58", 25); relay_header_unpack(&rh, cell.payload); 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), ==, "2607:f8b0:400c:c02::68"); tt_int_op(ttl, ==, -1); /* Bogus size: 3. */ make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x00\x01\x02", 3); relay_header_unpack(&rh, cell.payload); r = connected_cell_parse(&rh, &cell, &addr, &ttl); tt_int_op(r, ==, -1); /* Bogus family: 7. */ make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x00\x00\x00\x00\x07" "\x26\x07\xf8\xb0\x40\x0c\x0c\x02" "\x00\x00\x00\x00\x00\x00\x00\x68" "\x90\x00\x02\x58", 25); relay_header_unpack(&rh, cell.payload); r = connected_cell_parse(&rh, &cell, &addr, &ttl); tt_int_op(r, ==, -1); /* Truncated IPv6. */ make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x00\x00\x00\x00\x06" "\x26\x07\xf8\xb0\x40\x0c\x0c\x02" "\x00\x00\x00\x00\x00\x00\x00\x68" "\x00\x00\x02", 24); relay_header_unpack(&rh, cell.payload); 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); }