bool test_allocate_ipv4_transport_address( void )
{
    struct tuple tuple;
    struct ipv4_tuple_address tuple_addr;
    struct in_addr expected_addr;
    bool success = true;

    success &= str_to_addr4_verbose(IPV4_ALLOCATED_ADDR, &expected_addr);
    success &= inject_bib_entry( IPPROTO_ICMP );
    success &= inject_bib_entry( IPPROTO_TCP );
    success &= inject_bib_entry( IPPROTO_UDP );
    if (!success)
    	return false;

    init_tuple_for_test_ipv6(&tuple, IPPROTO_ICMP);
	success &= assert_true(allocate_ipv4_transport_address(&tuple, IPPROTO_ICMP, &tuple_addr),
		"Function result for ICMP");
	success &= assert_equals_ipv4(&expected_addr , &tuple_addr.address, "IPv4 address for ICMP");

	init_tuple_for_test_ipv6(&tuple, IPPROTO_TCP);
	success &= assert_true(allocate_ipv4_transport_address(&tuple, IPPROTO_TCP, &tuple_addr),
		"Function result for TCP");
	success &= assert_equals_ipv4(&expected_addr , &tuple_addr.address, "IPv4 address for TCP");
	success &= assert_true(tuple_addr.l4_id > 1023, "Port range for TCP");

	init_tuple_for_test_ipv6(&tuple, IPPROTO_UDP);
	success &= assert_true(allocate_ipv4_transport_address(&tuple, IPPROTO_UDP, &tuple_addr),
		"Function result for UDP");
	success &= assert_equals_ipv4(&expected_addr , &tuple_addr.address, "IPv4 address for UDP");
	success &= assert_true(tuple_addr.l4_id % 2 == 0, "Port parity for UDP");
	success &= assert_true( tuple_addr.l4_id > 1023, "Port range for UDP");

    return success;
}
static bool test_6to4(l4_protocol l4_proto)
{
	struct tuple incoming, outgoing;
	bool success = true;

	incoming.src.addr.ipv6 = remote_ipv6;
	incoming.dst.addr.ipv6 = local_ipv6;
	incoming.src.l4_id = 1500; /* Lookup will use this. */
	incoming.dst.l4_id = 123; /* Whatever */
	incoming.l3_proto = L3PROTO_IPV6;
	incoming.l4_proto = l4_proto;

	if (l4_proto != L4PROTO_ICMP) {
		success &= assert_equals_int(VER_CONTINUE, tuple5(&incoming, &outgoing), "Function5 call");
		success &= assert_equals_u16(80, outgoing.src.l4_id, "Source port");
		success &= assert_equals_u16(123, outgoing.dst.l4_id, "Destination port");
	} else {
		success &= assert_equals_int(VER_CONTINUE, tuple3(&incoming, &outgoing), "Function3 call");
		success &= assert_equals_u16(80, outgoing.icmp_id, "ICMP ID");
	}
	success &= assert_equals_ipv4(&local_ipv4, &outgoing.src.addr.ipv4, "Source address");
	success &= assert_equals_ipv4(&remote_ipv4, &outgoing.dst.addr.ipv4, "Destination address");
	success &= assert_equals_u16(L3PROTO_IPV4, outgoing.l3_proto, "Layer-3 protocol");
	success &= assert_equals_u8(l4_proto, outgoing.l4_proto, "Layer-4 protocol");

	return success;
}
Esempio n. 3
0
bool validate_ipv4_hdr(struct iphdr *hdr, u16 total_len, u16 id, u16 df, u16 mf, u16 frag_off,
                       u8 protocol, struct tuple *tuple4)
{
    struct in_addr addr;
    bool success = true;

    success &= assert_equals_u8(4, hdr->version, "IPv4hdr-Version");
    success &= assert_equals_u8(5, hdr->ihl, "IPv4hdr-IHL");
    success &= assert_equals_u8(0, hdr->tos, "IPv4hdr-TOS");
    success &= assert_equals_u16(total_len, be16_to_cpu(hdr->tot_len), "IPv4hdr-total length");
    success &= assert_equals_u16(id, be16_to_cpu(hdr->id), "IPv4hdr-ID");
    success &= assert_equals_u16(df, be16_to_cpu(hdr->frag_off) & IP_DF, "IPv4hdr-DF");
    success &= assert_equals_u16(mf, be16_to_cpu(hdr->frag_off) & IP_MF, "IPv4hdr-MF");
    success &= assert_equals_u16(frag_off, get_fragment_offset_ipv4(hdr), "IPv4hdr-Frag offset");
    /* success &= assert_equals_u8(, hdr->ttl, "IPv4 header - TTL"); */
    success &= assert_equals_u8(protocol, hdr->protocol, "IPv4hdr-protocol");

    addr.s_addr = hdr->saddr;
    success &= assert_equals_ipv4(&tuple4->src.addr4.l3, &addr, "IPv4hdr-src address");

    addr.s_addr = hdr->daddr;
    success &= assert_equals_ipv4(&tuple4->dst.addr4.l3, &addr, "IPv4hdr-dst address");

    return success;
}
Esempio n. 4
0
static bool test_get_any_addr_aux(l4_protocol proto, int min_range, int max_range, int range_step,
		int range_outside)
{
	struct ipv4_transport_addr tuple_addr;
	int p;
	bool success = true;

	for (p = min_range; p <= max_range; p += range_step) {
		success &= assert_equals_int(0, pool4_get_any_addr(proto, p, &tuple_addr),
				"Matched borrow 1-result");
		success &= assert_equals_ipv4(&expected_ips[0], &tuple_addr.l3,
				"Matched borrow 1-address");
		success &= assert_false(ports[0][tuple_addr.l4], "Matched borrow 1-port");
		ports[0][tuple_addr.l4] = true;

		success &= assert_equals_int(0, pool4_get_any_addr(proto, p, &tuple_addr),
				"Matched borrow 2-result");
		success &= assert_equals_ipv4(&expected_ips[1], &tuple_addr.l3,
				"Matched borrow 2-address");
		success &= assert_false(ports[1][tuple_addr.l4], "Matched borrow 2-port");
		ports[1][tuple_addr.l4] = true;

		if (!success)
			return success;
	}

	/* At this point, the pool should not have low even ports, so it should lend random data. */
	for (p = 0; p < range_outside; p += 1) {
		success &= assert_equals_int(0, pool4_get_any_addr(proto, 10, &tuple_addr),
				"Mismatched borrow 1-result");
		success &= assert_equals_ipv4(&expected_ips[0], &tuple_addr.l3,
				"Mismatched borrow 1-address");
		success &= assert_false(ports[0][tuple_addr.l4], "Mismatched borrow 1-port");
		ports[0][tuple_addr.l4] = true;

		success &= assert_equals_int(0, pool4_get_any_addr(proto, 10, &tuple_addr),
				"Mismatched borrow 2-result");
		success &= assert_equals_ipv4(&expected_ips[1], &tuple_addr.l3,
				"Mismatched borrow 2-address");
		success &= assert_false(ports[1][tuple_addr.l4], "Mismatched borrow 2-port");
		ports[1][tuple_addr.l4] = true;

		if (!success)
			return success;
	}

	/* The pool ran out of ports. */
	success &= assert_equals_int(-ESRCH, pool4_get_any_addr(proto, 10, &tuple_addr),
			"Exhausted pool");

	return success;
}
Esempio n. 5
0
static bool test_allocate_aux(struct tuple *tuple6, struct in_addr *same_addr,
		struct in_addr *out_addr, bool test_port)
{
	struct ipv4_transport_addr result;
	bool success = true;
	struct host6_node *host6;

	if (host6_node_get_or_create(&tuple6->src.addr6.l3, &host6))
		return false;

	success &= assert_equals_int(0, allocate_transport_address(host6, tuple6, &result),
			"function result");

	/* BTW: Because in_addrs are __be32s, "1.1.1.1" is the same as "0x1010101U" */
	success &= assert_true(result.l3.s_addr == htonl(0x1010101U)
			|| result.l3.s_addr == htonl(0x2020202U), "Result address is in pool");
	if (same_addr)
		success &= assert_equals_ipv4(same_addr, &result.l3, "Result address was recycled");
	if (test_port) {
		success &= assert_true(is_same_range(tuple6->src.addr6.l4, result.l4),
				"Result port is in the requested range");
		success &= assert_true(is_same_parity(tuple6->src.addr6.l4, result.l4),
				"Result port has the same parity as requested");
	}

	success &= bib_inject(&tuple6->src.addr6.l3, tuple6->src.addr6.l4, &result.l3, result.l4,
			L4PROTO_UDP) != NULL;

	if (out_addr)
		*out_addr = result.l3;

	host6_node_return(host6);

	return success;
}
Esempio n. 6
0
static bool assert_tuple_addr(struct in_addr *expected_address, __u16 expected_port,
		struct ipv4_tuple_address *actual, char *test_name)
{
	bool success = true;
	success &= assert_equals_ipv4(expected_address, &actual->address, test_name);
	success &= assert_equals_u16(expected_port, actual->l4_id, test_name);
	return success;
}
Esempio n. 7
0
bool test_addr_6to4(struct in6_addr *src, struct ipv6_prefix *prefix, struct in_addr *expected)
{
	struct in_addr actual;
	bool success = true;

	success &= assert_true(addr_6to4(src, prefix, &actual), "Extract IPv4-result");
	success &= assert_equals_ipv4(expected, &actual, "Extract IPv4-out");

	return success;
}
static bool test_6to4(bool (*function)(struct tuple *, struct tuple *),
		u_int8_t in_l4_protocol, u_int8_t out_l4_protocol)
{
	struct tuple incoming, outgoing;
	bool success = true;

	incoming.src.addr.ipv6 = remote_ipv6;
	incoming.dst.addr.ipv6 = local_ipv6;
	incoming.src.l4_id = 1500; // Lookup will use this.
	incoming.dst.l4_id = 123; // Whatever
	incoming.l3_proto = PF_INET6;
	incoming.l4_proto = in_l4_protocol;

	success &= assert_true(function(&incoming, &outgoing), "Function call");
	success &= assert_equals_ipv4(&local_ipv4, &outgoing.src.addr.ipv4, "Source address");
	success &= assert_equals_ipv4(&remote_ipv4, &outgoing.dst.addr.ipv4, "Destination address");
	success &= assert_equals_u16(PF_INET, outgoing.l3_proto, "Layer-3 protocol");
	success &= assert_equals_u8(out_l4_protocol, outgoing.l4_proto, "Layer-4 protocol");
	// TODO (test) need to test ports?

	return success;
}
bool test_transport_address_ipv4( void )
{
    struct in_addr addr;
    struct ipv4_tuple_address ta;
    bool success = true;

    if (!str_to_addr4_verbose(IPV4_TRANSPORT_ADDR, &addr))
    	return false;
    transport_address_ipv4( addr, IPV4_TRANSPORT_PORT, &ta );
    
    success &= assert_equals_ipv4(&ta.address, &addr,
        "Check that the address part of an IPv4 transport address is correct.");
    success &= assert_equals_u16(ta.l4_id, IPV4_TRANSPORT_PORT,
        "Check that the port part of an IPv4 transport address is correct.");

    return success;
}
Esempio n. 10
0
static bool test_get_any_aux(u_int8_t l4protocol, u32 port_min, u32 port_max, u32 step, char *test_name)
{
    u32 addr_ctr, port_ctr;
    struct ipv4_tuple_address result;
    bool success = true;

    for (addr_ctr = 0; addr_ctr < ARRAY_SIZE(expected_ips); addr_ctr++) {
        for (port_ctr = port_min; port_ctr <= port_max; port_ctr += step) {
            success &= assert_true(pool4_get_any(l4protocol, port_ctr, &result), test_name);
            success &= assert_equals_ipv4(&expected_ips[addr_ctr], &result.address, test_name);
            success &= assert_false(ports[addr_ctr][result.l4_id], test_name);
            ports[addr_ctr][result.l4_id] = true;
        }
    }
    success &= assert_false(pool4_get_any(l4protocol, 0, &result), test_name);

    return success;
}
bool test_extract_ipv4_from_ipv6( void )
{
    struct in6_addr addr6;
    struct in_addr extracted4;
    struct in_addr correct4;
    bool success = true;

    if (pool6_init(NULL, 0) != 0)
    	return false;
    success &= str_to_addr6_verbose(IPV6_EXTRACT_ADDR, &addr6);
    success &= str_to_addr4_verbose(IPV4_EXTRACTED_ADDR, &correct4);

    success &= assert_true(extract_ipv4(&addr6, &extracted4),
        "Check that an IPv4 address can be extracted from an IPv6 address.");
    success &= assert_equals_ipv4(&extracted4, &correct4, 
        "Assert that the extraction of the IPv4 address was correct.");

	pool6_destroy();
	return success;
}
Esempio n. 12
0
bool test_allocate_ipv4_transport_address( void )
{
	u_int8_t protocols[] = { IPPROTO_ICMP, IPPROTO_TCP, IPPROTO_UDP };
	__u16 expected_ports[] = { IPV6_ALLOCATE_PORT, IPV6_ALLOCATE_PORT, IPV6_ALLOCATE_PORT };

    struct in_addr expected_addr;
    
    struct tuple tuple;
    struct ipv4_tuple_address new_ipv4_transport_address;

    bool success = true;
    int i;

    success &= pool6_init();
    success &= pool4_init(true);
    success &= bib_init();
    success &= str_to_addr4_verbose(IPV4_ALLOCATED_ADDR, &expected_addr);
    success &= inject_bib_entry( IPPROTO_ICMP );
    success &= inject_bib_entry( IPPROTO_TCP );
    success &= inject_bib_entry( IPPROTO_UDP );
    if (!success)
    	return false;

    for (i = 0; i < ARRAY_SIZE(protocols); i++)
    {
		init_tuple_for_test_ipv6(&tuple, protocols[i]);

		success &= assert_true(allocate_ipv4_transport_address(&tuple, protocols[i], &new_ipv4_transport_address),
			"Check that we can allocate a brand new IPv4 transport address.");
		success &= assert_equals_ipv4(&expected_addr , &new_ipv4_transport_address.address,
			"Check that the allocated IPv4 address is correct.");
		success &= assert_equals_u16( expected_ports[i], new_ipv4_transport_address.l4_id,
			"Check that the allocated IPv4 port is correct.");
    }

    bib_destroy();
    pool4_destroy();
    pool6_destroy();

    return success;
}
Esempio n. 13
0
/**
 * Only UDP and its lower even range of ports is tested here.
 */
static bool test_return_function(void)
{
    struct ipv4_tuple_address query, result;
    bool success = true;
    int addr_ctr, port_ctr;

    /* Try to return the entire pool, even though we haven't borrowed anything. */
    for (addr_ctr = 0; addr_ctr < ARRAY_SIZE(expected_ips); addr_ctr++) {
        result.address = expected_ips[addr_ctr];
        for (port_ctr = 0; port_ctr < 1024; port_ctr += 2) {
            result.l4_id = port_ctr;
            success &= assert_false(pool4_return(IPPROTO_UDP, &result), "");
        }
    }

    /* Borrow the entire pool. */
    for (addr_ctr = 0; addr_ctr < ARRAY_SIZE(expected_ips); addr_ctr++) {
        for (port_ctr = 0; port_ctr < 1024; port_ctr += 2) {
            success &= assert_true(pool4_get_any(IPPROTO_UDP, port_ctr, &result), "Borrow-result");
            success &= assert_equals_ipv4(&expected_ips[addr_ctr], &result.address, "Borrow-addr");
            success &= assert_false(ports[addr_ctr][result.l4_id], "Borrow-port");
            ports[addr_ctr][result.l4_id] = true;
        }
    }
    success &= assert_false(pool4_get_any(IPPROTO_UDP, 0, &result), "Pool should be exhausted.");

    if (!success)
        return success;

    /* Return something from the first address. */
    result.address = expected_ips[0];
    result.l4_id = 1000;
    success &= assert_true(pool4_return(IPPROTO_UDP, &result), "Return");
    ports[0][result.l4_id] = false;

    if (!success)
        return success;

    /* Re-borrow it, assert it's the same one. */
    success &= assert_true(pool4_get_any(IPPROTO_UDP, 0, &result), "");
    success &= assert_equals_ipv4(&expected_ips[0], &result.address, "");
    success &= assert_false(ports[0][result.l4_id], "");
    ports[0][result.l4_id] = true;
    success &= assert_false(pool4_get_any(IPPROTO_UDP, 0, &result), "");

    if (!success)
        return success;

    /*
     * Do the same to the second address. Use get_similar() instead of get_any() to add some quick
     * noise.
     */
    result.address = expected_ips[1];
    result.l4_id = 1000;
    success &= assert_true(pool4_return(IPPROTO_UDP, &result), "Return");
    ports[1][result.l4_id] = false;

    if (!success)
        return success;

    query.address = expected_ips[1];
    query.l4_id = 0;
    success &= assert_true(pool4_get_similar(IPPROTO_UDP, &query, &result), "");
    success &= assert_equals_ipv4(&expected_ips[1], &result.address, "");
    success &= assert_false(ports[1][result.l4_id], "");
    ports[1][result.l4_id] = true;
    success &= assert_false(pool4_get_similar(IPPROTO_UDP, &query, &result), "");

    if (!success)
        return success;

    /* Return some more stuff at once. */
    result.address = expected_ips[0];
    result.l4_id = 46;
    success &= assert_true(pool4_return(IPPROTO_UDP, &result), "Return Addr1-port46");
    ports[0][46] = false;

    result.l4_id = 1000;
    success &= assert_true(pool4_return(IPPROTO_UDP, &result), "Return Addr1-port1000");
    ports[0][1000] = false;

    result.address = expected_ips[1];
    result.l4_id = 0;
    success &= assert_true(pool4_return(IPPROTO_UDP, &result), "ReReturn Addr2-port0");
    ports[1][0] = false;

    if (!success)
        return success;

    /* Reborrow it. */
    success &= assert_true(pool4_get_any(IPPROTO_UDP, 24, &result), "Reborrow Addr1-res-port24");
    success &= assert_equals_ipv4(&expected_ips[0], &result.address, "");
    success &= assert_false(ports[0][result.l4_id], "");
    ports[0][result.l4_id] = true;

    query.address = expected_ips[0];
    query.l4_id = 100;
    success &= assert_true(pool4_get_similar(IPPROTO_UDP, &query, &result), "Reborrow Addr1-res-port100");
    success &= assert_equals_ipv4(&expected_ips[0], &result.address, "");
    success &= assert_false(ports[0][result.l4_id], "");
    ports[0][result.l4_id] = true;

    success &= assert_true(pool4_get_any(IPPROTO_UDP, 56, &result), "ReReborrow Addr2-res-port56");
    success &= assert_equals_ipv4(&expected_ips[1], &result.address, "");
    success &= assert_false(ports[1][result.l4_id], "");
    ports[1][result.l4_id] = true;

    success &= assert_false(pool4_get_any(IPPROTO_UDP, 12, &result), "");

    if (!success)
        return success;

    /* Now return everything. */
    for (addr_ctr = 0; addr_ctr < ARRAY_SIZE(expected_ips); addr_ctr++) {
        result.address = expected_ips[addr_ctr];
        for (port_ctr = 0; port_ctr < 1024; port_ctr += 2) {
            result.l4_id = port_ctr;
            success &= assert_true(pool4_return(IPPROTO_UDP, &result), "");
            ports[addr_ctr][port_ctr] = false;
        }
    }
    success &= assert_false(pool4_return(IPPROTO_UDP, &result), "");

    return success;
}
Esempio n. 14
0
static bool test_allocate_ipv4_transport_address(void)
{
	struct tuple client1tuple, client2tuple, client3tuple;
	struct in_addr client1addr4, client2addr4, client3addr4;
	struct tuple *sharing_client_tuple;
	struct in_addr *non_sharing_addr;
	struct ipv4_transport_addr result;
	struct host6_node *host6;
	unsigned int i = 0;
	bool success = true;

	if (is_error(init_ipv6_tuple(&client1tuple, "1::1", 60000, "64:ff9b::1", 60000, L4PROTO_UDP)))
		goto fail;
	if (is_error(init_ipv6_tuple(&client2tuple, "1::2", 60000, "64:ff9b::2", 60000, L4PROTO_UDP)))
		goto fail;
	if (is_error(init_ipv6_tuple(&client3tuple, "1::3", 60000, "64:ff9b::3", 60000, L4PROTO_UDP)))
		goto fail;

	log_debug("IPv6 client 1 arrives and makes 25 connections.");
	/*
	 * Because it's the same IPv6 client, all of those connections should be masked with the same
	 * IPv4 address. This minimizes confusion from remote IPv4 hosts.
	 */

	client1tuple.src.addr6.l4 = 65511;
	if (!test_allocate_aux(&client1tuple, NULL, &client1addr4, true))
		goto fail;

	for (i = 65512; i < 65536; i++) {
		client1tuple.src.addr6.l4 = i;
		if (!test_allocate_aux(&client1tuple, &client1addr4, NULL, true))
			goto fail;
	}

	log_debug("Client 2 arrives and make 50 connections.");
	/*
	 * All of them should share the same IPv4 address,
	 * which should be different from client1's (again, to minimize confusion).
	 */

	client2tuple.src.addr6.l4 = 65486;
	success &= test_allocate_aux(&client2tuple, NULL, &client2addr4, true);
	success &= assert_true(client1addr4.s_addr != client2addr4.s_addr,
			"the nodes are being masked with different addresses");
	if (!success)
		goto fail;

	for (i = 65487; i < 65536; i++) {
		client2tuple.src.addr6.l4 = i;
		if (!test_allocate_aux(&client2tuple, &client2addr4, NULL, true))
			goto fail;
	}

	log_debug("Client 1 makes another 25 connections.");
	/*
	 * Because there are still ports available, he should still get the same IPv4 address.
	 * Essentially, this proves that client2's intervention doesn't affect client 1's connections.
	 */

	for (i = 65486; i < 65511; i++) {
		client1tuple.src.addr6.l4 = i;
		if (!test_allocate_aux(&client1tuple, &client1addr4, NULL, true))
			goto fail;
	}

	log_debug("Client 3 arrives and hogs up all of its address's low ports.");
	/*
	 * At this point, both IPv4 addresses have 50 high ports taken.
	 * Because both IPv4 addresses are taken, client 3 will share its IPv4 address with someone.
	 */
	client3tuple.src.addr6.l4 = 0;
	if (!test_allocate_aux(&client3tuple, NULL, &client3addr4, true))
		goto fail;

	for (i = 1; i < 1024; i++) {
		client3tuple.src.addr6.l4 = i;
		if (!test_allocate_aux(&client3tuple, &client3addr4, NULL, true))
			goto fail;
	}

	log_debug("The client that shares an address with client 3 requests a low port.");
	/*
	 * Because all of them are taken, he gets the same address but a runner-up high port instead.
	 */

	if (addr4_equals(&client1addr4, &client3addr4)) {
		sharing_client_tuple = &client1tuple;
		non_sharing_addr = &client2addr4;
	} else if (addr4_equals(&client2addr4, &client3addr4)) {
		sharing_client_tuple = &client2tuple;
		non_sharing_addr = &client1addr4;
	} else {
		log_err("Client 3 doesn't share its IPv4 address with anyone, despite validations.");
		goto fail;
	}


	if (is_error(host6_node_get_or_create(&sharing_client_tuple->src.addr6.l3, &host6)))
		goto fail;

	sharing_client_tuple->src.addr6.l4 = 0;
	success &= assert_equals_int(0, allocate_transport_address(host6, sharing_client_tuple,
			&result), "result 3");
	success &= assert_equals_ipv4(&client3addr4, &result.l3, "runnerup still gets his addr");
	success &= assert_true(is_high(result.l4), "runnerup gets a high port");
	success &= bib_inject(&sharing_client_tuple->src.addr6.l3, sharing_client_tuple->src.addr6.l4,
			&result.l3, result.l4, L4PROTO_UDP) != NULL;

	host6_node_return(host6);
	if (!success)
		goto fail;

	log_debug("Client 3 now hogs up all of its address's remaining ports.");
	/* 51 high ports were already taken, so this will stop early. */
	for (i = 1024; i < 65485; i++) {
		client3tuple.src.addr6.l4 = i;
		if (!test_allocate_aux(&client3tuple, &client3addr4, NULL, i != 65484))
			goto fail;
	}

	/*
	 * At this point, client's address has 50 + 1024 + 1 + 64461 = 65536 ports taken.
	 * ie. It no longer has any ports.
	 */

	log_debug("Then, the function will fall back to use the other address.");
	client3tuple.src.addr6.l4 = i;
	if (is_error(host6_node_get_or_create(&client3tuple.src.addr6.l3, &host6)))
		goto fail;

	success &= assert_equals_int(0, allocate_transport_address(host6, &client3tuple, &result),
			"function result");
	success &= assert_true(client3addr4.s_addr != result.l3.s_addr,
			"node gets a runnerup address");
	success &= bib_inject(&client3tuple.src.addr6.l3, client3tuple.src.addr6.l4,
			&result.l3, result.l4, L4PROTO_UDP) != NULL;

	host6_node_return(host6);
	if (!success)
		goto fail;

	log_debug("It will also fall back to use the other address as the other sharing node now hogs "
			"all remaining ports.");
	/*
	 * 51 high ports ports were already taken, so this will stop early.
	 * Also, the sharing client already requested port 0, so we have to start at 1.
	 */
	for (i = 1; i < 65486; i++) {
		sharing_client_tuple->src.addr6.l4 = i;
		if (!test_allocate_aux(sharing_client_tuple, non_sharing_addr, NULL,  i != 65485))
			goto fail;
	}


	log_debug("Now the pool is completely exhausted, so further requests cannot fall back.");

	if (is_error(host6_node_get_or_create(&client1tuple.src.addr6.l3, &host6)))
		goto fail;
	success &= assert_equals_int(-ESRCH, allocate_transport_address(host6, &client1tuple,
			&result), "client 1's request is denied");
	host6_node_return(host6);

	if (is_error(host6_node_get_or_create(&client2tuple.src.addr6.l3, &host6)))
		goto fail;
	success &= assert_equals_int(-ESRCH, allocate_transport_address(host6, &client2tuple,
			&result), "client 2's request is denied");
	host6_node_return(host6);

	if (is_error(host6_node_get_or_create(&client3tuple.src.addr6.l3, &host6)))
		goto fail;
	success &= assert_equals_int(-ESRCH, allocate_transport_address(host6, &client3tuple,
			&result), "client 3's request is denied");
	host6_node_return(host6);

	return success;

fail:
	log_debug("i was %u.", i);
	return false;
}