diff --git a/src/udpipe.cpp b/src/udpipe.cpp index 8467e6f..3d350ba 100644 --- a/src/udpipe.cpp +++ b/src/udpipe.cpp @@ -38,12 +38,11 @@ void usage(){ fprintf(stderr, "\t-f path \t\tturn on encryption, path=path to key file\n"); fprintf(stderr, "\t-v verbose\n"); fprintf(stderr, "\t-t timeout\t\tforce udpipe to timeout if no data transfered\n"); - - exit(1); } void initialize_thread_args(thread_args *args){ + args->listen_ip = NULL; args->ip = NULL; args->port = NULL; args->blast = 0; @@ -72,9 +71,13 @@ int main(int argc, char *argv[]){ int n_crypto_threads = 1; // ----------- [ Read in options - while ((opt = getopt (argc, argv, "t:hvsn:lp:f:")) != -1){ + while ((opt = getopt (argc, argv, "i:t:hvsn:lp:f:")) != -1){ switch (opt){ - + + case 'i': + args.listen_ip = optarg; + break; + case 's': args.print_speed = 1; break; @@ -161,6 +164,9 @@ int main(int argc, char *argv[]){ cerr << "error: Please specify server host." << endl; exit(1); } + if (args.verbose) + fprintf(stderr, "Attempting connection to %s\n", args.ip); + } if (args.verbose) @@ -196,7 +202,7 @@ int main(int argc, char *argv[]){ if (key) memset(key, 0, strlen(key)); - // ----------- [ Spawn correct process + // Spawn correct process if (operation == SERVER){ run_server(&args); diff --git a/src/udpipe.h b/src/udpipe.h index 4a0d9f4..462709c 100644 --- a/src/udpipe.h +++ b/src/udpipe.h @@ -44,6 +44,7 @@ typedef struct rs_args{ typedef struct thread_args{ crypto *enc; crypto *dec; + char *listen_ip; char *ip; char *port; int blast; diff --git a/src/udpipe_server.cpp b/src/udpipe_server.cpp index f855036..9965df4 100644 --- a/src/udpipe_server.cpp +++ b/src/udpipe_server.cpp @@ -22,9 +22,10 @@ and limitations under the License. #include #include #include - #include "udpipe.h" +#include + using std::cerr; using std::endl; using std::string; @@ -45,35 +46,57 @@ int run_server(thread_args *args){ int udp_buff = args->udp_buff; // 67108864; int mss = args->mss; - if (args->verbose) fprintf(stderr, "[server] Starting UDT...\n"); UDT::startup(); addrinfo hints; addrinfo* res; + struct sockaddr_in my_addr; - memset(&hints, 0, sizeof(struct addrinfo)); + // switch to turn on ip specification or not + int specify_ip = !(args->listen_ip == NULL); - hints.ai_flags = AI_PASSIVE; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; + if (args->verbose) + fprintf(stderr, "Listening on specific ip: %s\n", args->listen_ip); - string service(port); + // char* ip; - if (0 != getaddrinfo(NULL, service.c_str(), &hints, &res)) { - cerr << "illegal port number or port is busy.\n" << endl; - return 1; + // if (specify_ip) + // ip = strdup(args->listen_ip); + + if (specify_ip){ + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons(atoi(port)); + my_addr.sin_addr.s_addr = inet_addr(args->listen_ip); + + bzero(&(my_addr.sin_zero), 8); + } else { + memset(&hints, 0, sizeof(struct addrinfo)); + + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + string service(port); + + if (0 != getaddrinfo(NULL, service.c_str(), &hints, &res)) { + cerr << "illegal port number or port is busy.\n" << endl; + return 1; + } } buffer_size = udt_buff; - if (args->verbose) fprintf(stderr, "[server] Creating socket...\n"); UDTSOCKET serv; - serv = UDT::socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (specify_ip){ + serv = UDT::socket(AF_INET, SOCK_STREAM, 0); + } else { + serv = UDT::socket(res->ai_family, res->ai_socktype, res->ai_protocol); + } // UDT Options if (blast) @@ -83,21 +106,32 @@ int run_server(thread_args *args){ UDT::setsockopt(serv, 0, UDT_RCVBUF, &udt_buff, sizeof(int)); UDT::setsockopt(serv, 0, UDP_RCVBUF, &udp_buff, sizeof(int)); + // printf("Binding to %s\n", inet_ntoa(sin.sin_addr)); if (args->verbose) - fprintf(stderr, "[server] Binding socket...\n"); + fprintf(stderr, "[server] Binding socket...\n"); + int r; - if (UDT::ERROR == UDT::bind(serv, res->ai_addr, res->ai_addrlen)) { - cerr << "bind: " << UDT::getlasterror().getErrorMessage() << endl; - return 1; + if (specify_ip){ + r = UDT::bind(serv, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)); + } else { + r = UDT::bind(serv, res->ai_addr, res->ai_addrlen); } + if (UDT::ERROR == r){ + cerr << "bind: " << UDT::getlasterror().getErrorMessage() << endl; + return 1; + } + + if (UDT::ERROR == UDT::listen(serv, 10)){ cerr << "listen: " << UDT::getlasterror().getErrorMessage() << endl; return 1; } + + sockaddr_storage clientaddr; int addrlen = sizeof(clientaddr);