diff --git a/ncat/ncat_listen.c b/ncat/ncat_listen.c index ed40ae16f..4a3a7a2ce 100644 --- a/ncat/ncat_listen.c +++ b/ncat/ncat_listen.c @@ -233,6 +233,7 @@ static int ncat_listen_stream(int proto) fd_set listen_fds; struct timeval tv; struct timeval *tvp = NULL; + unsigned int num_sockets; /* clear out structs */ FD_ZERO(&master_readfds); @@ -268,24 +269,36 @@ static int ncat_listen_stream(int proto) for (i = 0; i < NUM_LISTEN_ADDRS; i++) listen_socket[i] = -1; + num_sockets = 0; for (i = 0; i < num_listenaddrs; i++) { /* setup the main listening socket */ - listen_socket[i] = do_listen(SOCK_STREAM, proto, &listenaddrs[i]); - if (listen_socket[i] == -1) - bye("do_listen: %s", socket_strerror(socket_errno())); + listen_socket[num_sockets] = do_listen(SOCK_STREAM, proto, &listenaddrs[i]); + if (listen_socket[num_sockets] == -1) { + logdebug("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno())); + continue; + } /* Make our listening socket non-blocking because there are timing issues * which could cause us to block on accept() even though select() says it's * readable. See UNPv1 2nd ed, p422 for more. */ - unblock_socket(listen_socket[i]); + unblock_socket(listen_socket[num_sockets]); /* setup select sets and max fd */ - FD_SET(listen_socket[i], &master_readfds); - add_fd(&client_fdlist, listen_socket[i]); + FD_SET(listen_socket[num_sockets], &master_readfds); + add_fd(&client_fdlist, listen_socket[num_sockets]); - FD_SET(listen_socket[i], &listen_fds); + FD_SET(listen_socket[num_sockets], &listen_fds); + + num_sockets++; } + if (num_sockets == 0) { + if (num_listenaddrs == 1) + bye("Unable to open listening socket on %s: %s", inet_ntop_ez(&listenaddrs[0].storage, sizeof(listenaddrs[0].storage)), socket_strerror(socket_errno())); + else + bye("Unable to open any listening sockets."); + } + add_fd(&client_fdlist, STDIN_FILENO); init_fdlist(&broadcast_fdlist, o.conn_limit); @@ -621,7 +634,10 @@ int read_socket(int recv_fd) */ static int ncat_listen_dgram(int proto) { - int sockfd[NUM_LISTEN_ADDRS]; + struct { + int fd; + union sockaddr_u addr; + } sockfd[NUM_LISTEN_ADDRS]; int i, fdn = -1; int fdmax, nbytes, n, fds_ready; char buf[DEFAULT_UDP_BUF_LEN] = { 0 }; @@ -631,9 +647,11 @@ static int ncat_listen_dgram(int proto) socklen_t sslen = sizeof(remotess.storage); struct timeval tv; struct timeval *tvp = NULL; + unsigned int num_sockets; for (i = 0; i < NUM_LISTEN_ADDRS; i++) { - sockfd[i] = -1; + sockfd[i].fd = -1; + sockfd[i].addr.storage.ss_family = AF_UNSPEC; } FD_ZERO(&read_fds); @@ -658,13 +676,24 @@ static int ncat_listen_dgram(int proto) FD_ZERO(&listen_fds); init_fdlist(&listen_fdlist, num_listenaddrs); + num_sockets = 0; for (i = 0; i < num_listenaddrs; i++) { /* create the UDP listen sockets */ - sockfd[i] = do_listen(SOCK_DGRAM, proto, &listenaddrs[i]); - if (sockfd[i] == -1) - bye("do_listen: %s", socket_strerror(socket_errno())); - FD_SET(sockfd[i], &listen_fds); - add_fd(&listen_fdlist, sockfd[i]); + sockfd[num_sockets].fd = do_listen(SOCK_DGRAM, proto, &listenaddrs[i]); + if (sockfd[num_sockets].fd == -1) { + logdebug("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno())); + continue; + } + FD_SET(sockfd[num_sockets].fd, &listen_fds); + add_fd(&listen_fdlist, sockfd[num_sockets].fd); + sockfd[num_sockets].addr = listenaddrs[i]; + num_sockets++; + } + if (num_sockets == 0) { + if (num_listenaddrs == 1) + bye("Unable to open listening socket on %s: %s", inet_ntop_ez(&listenaddrs[0].storage, sizeof(listenaddrs[0].storage)), socket_strerror(socket_errno())); + else + bye("Unable to open any listening sockets."); } if (o.idletimeout > 0) @@ -675,15 +704,15 @@ static int ncat_listen_dgram(int proto) if (fdn != -1) { /*remove socket descriptor which is burnt */ - FD_CLR(sockfd[fdn], &listen_fds); - rm_fd(&listen_fdlist, sockfd[fdn]); + FD_CLR(sockfd[fdn].fd, &listen_fds); + rm_fd(&listen_fdlist, sockfd[fdn].fd); /* Rebuild the udp socket which got burnt */ - sockfd[fdn] = do_listen(SOCK_DGRAM, proto, &listenaddrs[fdn]); - if (sockfd[fdn] == -1) + sockfd[fdn].fd = do_listen(SOCK_DGRAM, proto, &sockfd[fdn].addr); + if (sockfd[fdn].fd == -1) bye("do_listen: %s", socket_strerror(socket_errno())); - FD_SET(sockfd[fdn], &listen_fds); - add_fd(&listen_fdlist, sockfd[fdn]); + FD_SET(sockfd[fdn].fd, &listen_fds); + add_fd(&listen_fdlist, sockfd[fdn].fd); } fdn = -1; @@ -720,8 +749,8 @@ static int ncat_listen_dgram(int proto) continue; /* Check each listening socket */ - for (j = 0; j < num_listenaddrs; j++) { - if (i == sockfd[j]) { + for (j = 0; j < num_sockets; j++) { + if (i == sockfd[j].fd) { if (o.debug > 1) logdebug("Valid descriptor %d \n", i); fdn = j; diff --git a/ncat/ncat_proxy.c b/ncat/ncat_proxy.c index 23ab8e211..8757e5244 100644 --- a/ncat/ncat_proxy.c +++ b/ncat/ncat_proxy.c @@ -192,6 +192,7 @@ int ncat_http_server(void) union sockaddr_u conn; struct timeval tv; struct timeval *tvp = NULL; + unsigned int num_sockets; #ifndef WIN32 Signal(SIGCHLD, proxyreaper); @@ -216,18 +217,28 @@ int ncat_http_server(void) init_fdlist(&listen_fdlist, num_listenaddrs); /* Listen on each address, set up lists for select */ + num_sockets = 0; for (i = 0; i < num_listenaddrs; i++) { - listen_socket[i] = do_listen(SOCK_STREAM, IPPROTO_TCP, &listenaddrs[i]); - if (listen_socket[i] == -1) - bye("do_listen: %s", socket_strerror(socket_errno())); + listen_socket[num_sockets] = do_listen(SOCK_STREAM, IPPROTO_TCP, &listenaddrs[i]); + if (listen_socket[num_sockets] == -1) { + logdebug("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno())); + continue; + } /* make us not block on accepts in wierd cases. See ncat_listen.c:209 */ - unblock_socket(listen_socket[i]); + unblock_socket(listen_socket[num_sockets]); /* setup select sets and max fd */ - FD_SET(listen_socket[i], &listen_fds); - add_fd(&listen_fdlist, listen_socket[i]); + FD_SET(listen_socket[num_sockets], &listen_fds); + add_fd(&listen_fdlist, listen_socket[num_sockets]); + num_sockets++; + } + if (num_sockets == 0) { + if (num_listenaddrs == 1) + bye("Unable to open listening socket on %s: %s", inet_ntop_ez(&listenaddrs[0].storage, sizeof(listenaddrs[0].storage)), socket_strerror(socket_errno())); + else + bye("Unable to open any listening sockets."); } if (o.idletimeout > 0) @@ -261,7 +272,7 @@ int ncat_http_server(void) continue; /* Check each listening socket */ - for (j = 0; j < num_listenaddrs; j++) { + for (j = 0; j < num_sockets; j++) { if (i == listen_socket[j]) { fds_ready--; c = accept(i, &conn.sockaddr, &sslen);