static void blast_client_deallocate(blast_client_t* client) { int isock, ssize = 0; if (client->sock) socket_deallocate(client->sock); for (isock = 0, ssize = array_size(client->socks); isock < ssize; ++isock) socket_deallocate(client->socks[isock]); array_deallocate(client->socks); array_deallocate(client->pending); }
DECLARE_TEST(tcp, blocking) { socket_t* sock = tcp_socket_allocate(); socket_set_blocking(sock, false); EXPECT_FALSE(socket_blocking(sock)); socket_set_blocking(sock, true); EXPECT_TRUE(socket_blocking(sock)); socket_deallocate(sock); return 0; }
DECLARE_TEST(udp, datagram_ipv6) { network_address_t** address_local = 0; network_address_t* address = 0; network_address_t* address_server = 0; test_datagram_arg_t client_arg[4]; int server_port; int state, iaddr, asize; thread_t threads[5]; socket_t* sock_server; socket_t* sock_client[4]; if (!network_supports_ipv6()) return 0; sock_server = udp_socket_allocate(); sock_client[0] = udp_socket_allocate(); sock_client[1] = udp_socket_allocate(); sock_client[2] = udp_socket_allocate(); sock_client[3] = udp_socket_allocate(); address_local = network_address_local(); for (iaddr = 0, asize = array_size(address_local); iaddr < asize; ++iaddr) { if (network_address_family(address_local[iaddr]) == NETWORK_ADDRESSFAMILY_IPV6) { address = address_local[iaddr]; break; } } EXPECT_NE(address, 0); do { server_port = random32_range(1024, 35535); network_address_ip_set_port(address, server_port); if (socket_bind(sock_server, address)) break; } while (true); address_server = network_address_clone(address); network_address_ip_set_port(address_server, server_port); network_address_array_deallocate(address_local); state = socket_state(sock_server); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[0]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[1]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[2]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); state = socket_state(sock_client[3]); EXPECT_TRUE(state == SOCKETSTATE_NOTCONNECTED); socket_set_blocking(sock_server, true); socket_set_blocking(sock_client[0], true); socket_set_blocking(sock_client[1], true); socket_set_blocking(sock_client[2], true); socket_set_blocking(sock_client[3], true); client_arg[0].sock = sock_client[0]; client_arg[0].target = address_server; client_arg[1].sock = sock_client[1]; client_arg[1].target = address_server; client_arg[2].sock = sock_client[2]; client_arg[2].target = address_server; client_arg[3].sock = sock_client[3]; client_arg[3].target = address_server; thread_initialize(&threads[0], datagram_server_blocking_thread, sock_server, STRING_CONST("server_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[1], datagram_client_blocking_thread, &client_arg[0], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[2], datagram_client_blocking_thread, &client_arg[1], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[3], datagram_client_blocking_thread, &client_arg[2], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[4], datagram_client_blocking_thread, &client_arg[3], STRING_CONST("client_thread"), THREAD_PRIORITY_NORMAL, 0); thread_start(&threads[0]); thread_start(&threads[1]); thread_start(&threads[2]); thread_start(&threads[3]); thread_start(&threads[4]); test_wait_for_threads_startup(threads, 5); thread_finalize(&threads[0]); thread_finalize(&threads[1]); thread_finalize(&threads[2]); thread_finalize(&threads[3]); thread_finalize(&threads[4]); socket_deallocate(sock_server); socket_deallocate(sock_client[0]); socket_deallocate(sock_client[1]); socket_deallocate(sock_client[2]); socket_deallocate(sock_client[3]); memory_deallocate(address_server); return 0; }
DECLARE_TEST(udp, stream_ipv6) { network_address_t** address_local = 0; network_address_t* address = 0; int server_port, client_port; int state, iaddr, asize; thread_t threads[2]; socket_t* sock_server; socket_t* sock_client; if (!network_supports_ipv6()) return 0; sock_server = udp_socket_allocate(); sock_client = udp_socket_allocate(); address_local = network_address_local(); for (iaddr = 0, asize = array_size(address_local); iaddr < asize; ++iaddr) { if (network_address_family(address_local[iaddr]) == NETWORK_ADDRESSFAMILY_IPV6) { address = address_local[iaddr]; break; } } EXPECT_NE(address, 0); do { server_port = random32_range(1024, 35535); network_address_ip_set_port(address, server_port); if (socket_bind(sock_server, address)) break; } while (true); do { client_port = random32_range(1024, 35535); network_address_ip_set_port(address, client_port); if (socket_bind(sock_client, address)) break; } while (true); socket_set_blocking(sock_server, false); socket_set_blocking(sock_client, false); network_address_ip_set_port(address, client_port); socket_connect(sock_server, address, 0); network_address_ip_set_port(address, server_port); socket_connect(sock_client, address, 0); network_address_array_deallocate(address_local); state = socket_state(sock_server); EXPECT_TRUE(state == SOCKETSTATE_CONNECTED); state = socket_state(sock_client); EXPECT_TRUE(state == SOCKETSTATE_CONNECTED); socket_set_blocking(sock_server, true); socket_set_blocking(sock_client, true); thread_initialize(&threads[0], stream_blocking_thread, sock_server, STRING_CONST("io_thread"), THREAD_PRIORITY_NORMAL, 0); thread_initialize(&threads[1], stream_blocking_thread, sock_client, STRING_CONST("io_thread"), THREAD_PRIORITY_NORMAL, 0); thread_start(&threads[0]); thread_start(&threads[1]); test_wait_for_threads_startup(threads, 2); thread_finalize(&threads[0]); thread_finalize(&threads[1]); socket_deallocate(sock_server); socket_deallocate(sock_client); return 0; }
static int blast_client_handshake(blast_client_t* client) { int isock, ssize; socket_t** socks; if (blast_time_elapsed_ms(client->last_send) > 10) blast_client_send_handshake(client, client->readers[client->current]); if (client->sock) { socks = &client->sock; ssize = 1; } else { socks = client->socks; ssize = array_size(client->socks); } for (isock = 0; isock < ssize; ++isock) { const network_address_t* address = 0; char packetbuffer[PACKET_DATABUF_SIZE]; size_t size = udp_socket_recvfrom(socks[isock], packetbuffer, sizeof(packetbuffer), &address); if (size > 0) { packet_t* packet = (packet_t*)packetbuffer; if (packet->type == PACKET_HANDSHAKE) { char buffer[NETWORK_ADDRESS_NUMERIC_MAX_LENGTH]; string_t addr = network_address_to_string(buffer, sizeof(buffer), address, true); packet_handshake_t* handshake = (packet_handshake_t*)packet; log_infof(HASH_BLAST, STRING_CONST("Got handshake packet from %.*s (seq %d, timestamp %lld, latency %lld ms)"), STRING_FORMAT(addr), (int)packet->seq, (tick_t)packet->timestamp, blast_timestamp_elapsed_ms(client->begin_send, packet->timestamp)); if (!client->sock) { client->target = address; client->sock = client->socks[isock]; client->socks[isock] = 0; } if (client->state == BLAST_STATE_HANDSHAKE) { log_infof(HASH_BLAST, STRING_CONST("Begin transfer of '%.*s' %lld bytes with token %d to %.*s"), STRING_FORMAT(client->readers[client->current]->name), client->readers[client->current]->size, handshake->token, STRING_FORMAT(addr)); client->token = (unsigned int)handshake->token; client->begin_send = time_current(); client->last_send = 0; client->seq = 0; array_clear(client->pending); client->state = BLAST_STATE_TRANSFER; return 1; } } else { log_warnf(HASH_BLAST, WARNING_SUSPICIOUS, STRING_CONST("Unknown datagram on socket in handshake state")); } } } if (client->state != BLAST_STATE_HANDSHAKE) { for (isock = 0, ssize = array_size(client->socks); isock < ssize; ++isock) { socket_t* sock = client->socks[isock]; socket_deallocate(sock); } array_deallocate(client->socks); client->socks = 0; } return 1; }
DECLARE_TEST(tcp, bind) { bool has_ipv4 = network_supports_ipv4(); bool has_ipv6 = network_supports_ipv6(); bool was_bound = false; unsigned int port; if (has_ipv4) { socket_t* sock = tcp_socket_allocate(); EXPECT_EQ(socket_address_local(sock), 0); EXPECT_EQ(socket_address_remote(sock), 0); EXPECT_EQ(socket_state(sock), SOCKETSTATE_NOTCONNECTED); for (port = 31890; !was_bound && (port < 32890); ++port) { network_address_t* address = network_address_ipv4_any(); network_address_ip_set_port(address, port); if (socket_bind(sock, address)) { EXPECT_NE(socket_address_local(sock), 0); EXPECT_EQ(socket_address_remote(sock), 0); EXPECT_EQ(socket_state(sock), SOCKETSTATE_NOTCONNECTED); EXPECT_TRUE(network_address_equal(socket_address_local(sock), address)); was_bound = true; } memory_deallocate(address); } EXPECT_TRUE(was_bound); socket_deallocate(sock); } if (has_ipv6) { socket_t* sock = tcp_socket_allocate(); was_bound = false; for (port = 31890; !was_bound && (port < 32890); ++port) { network_address_t* address = network_address_ipv6_any(); network_address_ip_set_port(address, port); if (socket_bind(sock, address)) { EXPECT_NE(socket_address_local(sock), 0); EXPECT_EQ(socket_address_remote(sock), 0); EXPECT_EQ(socket_state(sock), SOCKETSTATE_NOTCONNECTED); EXPECT_TRUE(network_address_equal(socket_address_local(sock), address)); was_bound = true; } memory_deallocate(address); } EXPECT_TRUE(was_bound); socket_deallocate(sock); } return 0; }
DECLARE_TEST(tcp, create) { socket_t* sock = tcp_socket_allocate(); socket_deallocate(sock); return 0; }