/* For a given TCP connection, if we have all the bytes we want, do the * next thing */ void tcp_process_data(int b) { int32_t wanted = 0; if(tcp_pend[b].wanted != tcp_pend[b].got || tcp_pend[b].buffer == 0 || tcp_pend[b].state != 0) { return; } if(tcp_pend[b].wanted == 2) { /* If we wanted the length of the DNS * packet */ /* Based on the length of the DNS packet wanted, we next * try to get the DNS packet */ tcp_pend[b].got = 0; wanted = tcp_pend[b].buffer[0]; wanted <<= 8; wanted |= tcp_pend[b].buffer[1]; free(tcp_pend[b].buffer); tcp_pend[b].buffer = 0; if(wanted < 12) { closesocket(tcp_pend[b].local); reset_tcp_pend(b); return; } tcp_pend[b].wanted = wanted; tcp_pend[b].buffer = malloc(wanted + 1); tcp_pend[b].die = get_time() + ((int64_t)timeout_seconds_tcp << 8); } else if(tcp_pend[b].wanted >= 12) { tcp_to_udp(b); } }
int main(int argc, char *argv[]) { struct relay *relays; int relay_count, is_server; int i; fd_set readfds; int max = 0; int ok; parse_args(argc, argv, &relays, &relay_count, &is_server); for (i = 0; i < relay_count; i++) { if (is_server) { setup_server_listen(&relays[i]); } else { setup_tcp_client(&relays[i]); } setup_udp_recv(&relays[i]); setup_udp_send(&relays[i]); } if (is_server) { await_incoming_connections(relays, relay_count); } do { FD_ZERO(&readfds); for (i = 0; i < relay_count; i++) { FD_SET(relays[i].tcp_sock, &readfds); SET_MAX(relays[i].tcp_sock); FD_SET(relays[i].udp_recv_sock, &readfds); SET_MAX(relays[i].udp_recv_sock); } if (select(max, &readfds, NULL, NULL, NULL) < 0) { if (errno != EINTR) { perror("main loop: select"); exit(1); } } ok = 0; for (i = 0; i < relay_count; i++) { if (FD_ISSET(relays[i].tcp_sock, &readfds)) { ok += tcp_to_udp(&relays[i]); } if (FD_ISSET(relays[i].udp_recv_sock, &readfds)) { ok += udp_to_tcp(&relays[i]); } } } while (ok == 0); exit(0); } /* main */