예제 #1
0
파일: types.c 프로젝트: NICMx/Jool
bool pool4_range_touches(const struct pool4_range *r1,
		const struct pool4_range *r2)
{
	return addr4_equals(&r1->addr, &r2->addr)
			&& port_range_touches(&r1->ports, &r2->ports);
}
예제 #2
0
파일: bib_test.c 프로젝트: patybarron/NAT64
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;
}
예제 #3
0
파일: types.c 프로젝트: NICMx/Jool
bool pool4_range_equals(struct pool4_range *r1, struct pool4_range *r2)
{
	return addr4_equals(&r1->addr, &r2->addr)
			&& port_range_equals(&r1->ports, &r2->ports);
}