--- datapipe.c.orig Tue Jan 4 08:48:55 2000 +++ datapipe.c Fri Jul 1 19:55:58 2005 @@ -59,6 +59,7 @@ #include #include #include + #include #define recv(x,y,z,a) read(x,y,z) #define send(x,y,z,a) write(x,y,z) #define closesocket(s) close(s) @@ -77,7 +78,7 @@ time_t activity; }; -#define MAXCLIENTS 20 +#define MAXCLIENTS 128 #define IDLETIMEOUT 300 @@ -88,8 +89,12 @@ SOCKET lsock; char buf[4096]; struct sockaddr_in laddr, oaddr; - int i; + int i, lport, oport; + char *laddr_str, *oaddr_str; struct client_t clients[MAXCLIENTS]; +#if defined(DATAPIPE_REUSEADDR) + int opt = 1; +#endif #if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) @@ -114,7 +119,7 @@ /* determine the listener address and port */ bzero(&laddr, sizeof(struct sockaddr_in)); laddr.sin_family = AF_INET; - laddr.sin_port = htons((unsigned short) atol(argv[2])); + laddr.sin_port = htons((unsigned short)(lport=atol(argv[2]))); laddr.sin_addr.s_addr = inet_addr(argv[1]); if (!laddr.sin_port) { fprintf(stderr, "invalid listener port\n"); @@ -128,12 +133,13 @@ } bcopy(n->h_addr, (char *) &laddr.sin_addr, n->h_length); } + laddr_str=strdup(inet_ntoa(laddr.sin_addr)); /* determine the outgoing address and port */ bzero(&oaddr, sizeof(struct sockaddr_in)); oaddr.sin_family = AF_INET; - oaddr.sin_port = htons((unsigned short) atol(argv[4])); + oaddr.sin_port = htons((unsigned short)(oport=atol(argv[4]))); if (!oaddr.sin_port) { fprintf(stderr, "invalid target port\n"); return 25; @@ -147,6 +153,7 @@ } bcopy(n->h_addr, (char *) &oaddr.sin_addr, n->h_length); } + oaddr_str=strdup(inet_ntoa(oaddr.sin_addr)); /* create the listener socket */ @@ -154,6 +161,21 @@ perror("socket"); return 20; } + { + int j=1; + setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, + (const char *) &j, sizeof(j)); + setsockopt(lsock, SOL_SOCKET, SO_KEEPALIVE, + (const char *) &j, sizeof(j)); + setsockopt(lsock, SOL_SOCKET, SO_LINGER, + (const char *) &j, sizeof(j)); + } +#if defined(DATAPIPE_REUSEADDR) + if (setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) { + perror("setsockopt"); + return 20; + } +#endif if (bind(lsock, (struct sockaddr *)&laddr, sizeof(laddr))) { perror("bind"); return 20; @@ -164,13 +186,14 @@ } - /* change the port in the listener struct to zero, since we will + /* change the port and address in the listener struct to zero, since we will * use it for binding to outgoing local sockets in the future. */ laddr.sin_port = htons(0); + laddr.sin_addr.s_addr = INADDR_ANY; /* fork off into the background. */ -#if !defined(__WIN32__) && !defined(WIN32) && !defined(_WIN32) +#if !defined(__WIN32__) && !defined(WIN32) && !defined(_WIN32) && !defined(DATAPIPE_NOFORK) if ((i = fork()) == -1) { perror("fork"); return 20; @@ -180,7 +203,10 @@ setsid(); #endif - + openlog(argv[0], LOG_NDELAY|LOG_CONS|LOG_PID, LOG_LOCAL4); + syslog( LOG_INFO, "Datapipe started: %s:%i -> %s:%i", + laddr_str, lport, oaddr_str, oport); + /* main polling loop. */ while (1) { @@ -203,15 +229,22 @@ maxsock = (int) clients[i].osock; } if (select(maxsock + 1, &fdsr, NULL, NULL, &tv) < 0) { - return 30; + syslog( LOG_INFO, "select, maxsock=%i", maxsock); + continue; } /* check if there are new connections to accept. */ if (FD_ISSET(lsock, &fdsr)) { - SOCKET csock = accept(lsock, NULL, 0); - + struct sockaddr_in raddr; + int len=sizeof(raddr); + SOCKET csock = accept(lsock, (struct sockaddr *)&raddr, &len); + if(csock >= 0) { + syslog( LOG_INFO, "Connection(%i) from %s:%i to %s:%i -> %s:%i", + csock, inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port), + laddr_str, lport, oaddr_str, oport); + for (i = 0; i < MAXCLIENTS; i++) if (!clients[i].inuse) break; if (i < MAXCLIENTS) @@ -219,16 +252,16 @@ /* connect a socket to the outgoing host/port */ SOCKET osock; if ((osock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - perror("socket"); + syslog( LOG_INFO, "socket\n"); closesocket(csock); } else if (bind(osock, (struct sockaddr *)&laddr, sizeof(laddr))) { - perror("bind"); + syslog( LOG_INFO, "bind\n"); closesocket(csock); closesocket(osock); } else if (connect(osock, (struct sockaddr *)&oaddr, sizeof(oaddr))) { - perror("connect"); + syslog( LOG_INFO, "connect\n"); closesocket(csock); closesocket(osock); } @@ -239,9 +272,14 @@ clients[i].inuse = 1; } } else { - fprintf(stderr, "too many clients\n"); + syslog( LOG_INFO, "too many clients\n"); closesocket(csock); - } + } + } else { + syslog( LOG_INFO, "Connection accept error(%i) from %s:%i to %s:%i -> %s:%i", + csock, inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port), + laddr_str, lport, oaddr_str, oport); + } }