void tun_serv(struct arguments *args) { int fd_udp = 0, fd_tun = 0; /* init server state */ struct tun_state *state = init_tun_state(args); /* create tun if and sockets */ tun(state, &fd_tun); fd_udp = udp_sock(state->public_port, 1, state->public_addr); /* run capture threads */ xthread_create(capture_notun, (void *) state, 1); if (!args->capture_notun_only) xthread_create(capture_tun, (void *) state, 1); synchronize(); /* run server */ debug_print("running serv ...\n"); xthread_create(serv_thread, (void*) state, 1); /* init select loop */ fd_set input_set; struct timeval tv; int sel = 0, fd_max = 0; char buf[BUFF_SIZE], *buffer; buffer = buf; if (state->planetlab) { buffer[0]=0;buffer[1]=0; buffer[2]=8;buffer[3]=0; buffer+=4; } fd_max=max(fd_tun,fd_udp); loop=1; signal(SIGINT, serv_shutdown); signal(SIGTERM, serv_shutdown); while (loop) { FD_ZERO(&input_set); FD_SET(fd_udp, &input_set); FD_SET(fd_tun, &input_set); sel = xselect(&input_set, fd_max, &tv, state->inactivity_timeout); if (sel == 0) { debug_print("timeout\n"); break; } else if (sel > 0) { if (FD_ISSET(fd_udp, &input_set)) tun_serv_out(fd_udp, fd_tun, state, buffer); if (FD_ISSET(fd_tun, &input_set)) tun_serv_in(fd_udp, fd_tun, state, buffer); } } }
inline udp_sock udp_getsocket() { int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //if(sock == INVALID_SOCKET) // printf("error"); return udp_sock(sock); }
inline udp_sock conditional_accept(udp_sock& sock) { if(!sock_readable(sock)) return udp_sock(-1); struct sockaddr_storage their_addr; socklen_t addr_len = sizeof their_addr; int new_fd = accept(sock.get(), (struct sockaddr *)&their_addr, &addr_len); udp_sock new_sock(new_fd); return new_sock; }
inline udp_sock udp_host(const std::string& serverport = SERVERPORT) { networking_init(); int sockfd; struct addrinfo hints, *servinfo, *p; int rv; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; // set to AF_INET to force IPv4 hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; // use my IP if ((rv = getaddrinfo(NULL, serverport.c_str(), &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); exit(1); } // loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("listener: socket"); continue; } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { CLOSE(sockfd); perror("listener: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "listener: failed to bind socket\n"); udp_sock bad; bad.make_invalid(); return bad; } freeaddrinfo(servinfo); return udp_sock(sockfd); }