static void blast_client_read_ack(blast_client_t* client) { const network_address_t* address = 0; char databuf[PACKET_DATABUF_SIZE]; size_t size = udp_socket_recvfrom(client->sock, databuf, sizeof(databuf), &address); while (size > 0) { packet_t* packet = (packet_t*)databuf; if (network_address_equal(address, socket_address_remote(client->sock))) { if (packet->type == PACKET_ACK) { packet_ack_t* ack = (packet_ack_t*)packet; blast_client_process_ack(client, ack->ack, packet->timestamp); } else if (packet->type == PACKET_TERMINATE) { log_info(HASH_BLAST, STRING_CONST("Client terminating due to TERMINATE packet from server")); client->state = BLAST_STATE_FINISHED; break; } } else { char buffer[NETWORK_ADDRESS_NUMERIC_MAX_LENGTH]; string_t addr = network_address_to_string(buffer, sizeof(buffer), address, true); log_warnf(HASH_BLAST, WARNING_SUSPICIOUS, STRING_CONST("Ignoring datagram from unknown host %.*s"), STRING_FORMAT(addr)); } size = udp_socket_recvfrom(client->sock, databuf, sizeof(databuf), &address); } }
static void* datagram_client_blocking_thread(void* arg) { int iloop; test_datagram_arg_t* darg = arg; socket_t* sock = darg->sock; network_address_t* target = darg->target; const network_address_t* address; char buffer[1024] = {0}; size_t send = 973; size_t recv; log_debugf(HASH_NETWORK, STRING_CONST("IO start on socket 0x%llx"), sock); for (iloop = 0; iloop < 512; ++iloop) { log_infof(HASH_NETWORK, STRING_CONST("UDP read/write pass %d"), iloop); EXPECT_EQ(udp_socket_sendto(sock, buffer, send, target), send); recv = udp_socket_recvfrom(sock, buffer, send, &address); EXPECT_EQ(recv, send); EXPECT_TRUE(network_address_equal(target, address)); thread_yield(); } log_infof(HASH_NETWORK, STRING_CONST("IO complete on socket 0x%llx"), sock); return 0; }
static void* datagram_server_blocking_thread(void* arg) { int iloop; const network_address_t* from; socket_t* sock = (socket_t*)arg; char buffer[1024]; for (iloop = 0; iloop < 512 * 4; ++iloop) { log_infof(HASH_NETWORK, STRING_CONST("UDP mirror pass %d"), iloop); size_t read = udp_socket_recvfrom(sock, buffer, sizeof(buffer), &from); EXPECT_EQ(read, 973); EXPECT_EQ(udp_socket_sendto(sock, buffer, read, from), read); thread_yield(); } log_infof(HASH_NETWORK, STRING_CONST("IO complete on socket 0x%llx"), sock); return 0; }
static void rxtx_loop() { int ret, send_ret; struct sockaddr_in peer_addr; char peer_ip[32]; uint16_t peer_port; while (!the_working_paras.need_exit) { ret=fd_readable(the_working_paras.sockfd, 0, 10000); if (ret<=0) { if (ret<0 && !the_working_paras.no_verbose) ERR_DBG_PRINT("test fd failed"); continue; } ret=udp_socket_recvfrom(the_working_paras.sockfd ,the_working_paras.buf ,sizeof(the_working_paras.buf) ,&peer_addr); INC_STAT(the_stat_data.rx_times_total); if (ret>0) { INC_STAT(the_stat_data.rx_pkts); INC_STAT_VALUE(the_stat_data.rx_bytes, ret); if (!the_working_paras.no_verbose) { resolve_sockaddr(&peer_addr, peer_ip, sizeof(peer_ip), &peer_port); printf("[%"PRIu64"]got %d bytes from %s:%d\n" ,the_stat_data.rx_pkts ,ret ,peer_ip ,(int)peer_port); if (!the_working_paras.no_prt_pkt) { printf("the data contents is:\n"); print_mem(the_working_paras.buf, ret); } } if (!the_working_paras.only_recv) { if (!the_working_paras.no_verbose) { printf("try send back %d bytes to %s:%d\n" ,ret ,peer_ip ,(int)peer_port); } send_ret=udp_socket_sendto(the_working_paras.sockfd, the_working_paras.buf, ret, &peer_addr); INC_STAT(the_stat_data.tx_pkts_total); INC_STAT_VALUE(the_stat_data.tx_bytes_total, ret); if (send_ret==ret) { INC_STAT(the_stat_data.tx_pkts_succ); INC_STAT_VALUE(the_stat_data.tx_bytes_succ, ret); } else if (send_ret<=0) { INC_STAT(the_stat_data.tx_pkts_fail); INC_STAT_VALUE(the_stat_data.tx_bytes_fail, ret); if (!the_working_paras.no_verbose) ERR_DBG_PRINT("tx failed"); } else DBG_PRINT_QUIT("abnormal event: udp packet was partly sent!"); } } else { INC_STAT(the_stat_data.rx_times_fail); if (!the_working_paras.no_verbose) ERR_DBG_PRINT("rx failed"); } printf("\n\n"); continue; } }
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; }