I've fixed the IP bouncer so it doesnt chew so much cpu any more, backgrounds itself and detachs from the tty. In testing last night, it was using less %cpu than the telnet being used to connect to it on the same machine (hope that bodes well! :). Darren ----------------------------------------------------------------------------- /* This file is telserv.c and is part of the Telnet Server package v. 1.0, written by "Hal-9000". Much of this package was developed by Richard Stephens and my thanks go to "Xanadude" for providing me with that section. Performance fix by Darren Reed. To compile, type "cc -O -s telserv.c -o telserv". */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <fcntl.h> #include <errno.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/ioctl.h> #define SERV_TCP_PORT 12345 /* port I'll listen for connections on */ #define REM_HOST_ADDR "127.0.0.1" /* host I will bounce to */ #define REM_TCP_PORT 19 /* port I will bounce to */ char sbuf[2048], cbuf[2048]; main() { int sockfd, newsockfd, clilen, childpid, opt = 1; struct sockaddr_in cli_addr, serv_addr; sockfd = socket(AF_INET, SOCK_STREAM, 0); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERV_TCP_PORT); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) == -1) { perror("bind"); exit(-1); } listen(sockfd, 5); setpgrp(getpid(), 0); close(0); close(1); close(2); #ifdef TIOCNOTTY if ((newsockfd = open("/dev/tty", O_RDWR)) >= 0) { ioctl(newsockfd, TIOCNOTTY, (char *)0); close(newsockfd); } #endif if (fork()) exit(0); while (1) { clilen = sizeof(cli_addr); newsockfd=accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd == -1) exit(-1); setsockopt(newsockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); /* ** NB: FNDELAY and O_NDELAY aren't the same on all machines and on most ** we want FNDELAY. The differences are subtle but differences all the ** same. */ #ifdef FNDELAY fcntl(newsockfd,F_SETFL,fcntl(newsockfd,F_GETFL,0)|FNDELAY); #else fcntl(newsockfd,F_SETFL,O_NDELAY); #endif childpid = fork(); if (childpid == 0) { /* child process */ close(sockfd); /* close original socket */ telcli(newsockfd); /* process the request */ exit(0); } close(newsockfd); /* parent process */ wait(0); } } telcli(clisockfd) { int servsockfd; struct sockaddr_in serv_addr; bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(REM_HOST_ADDR); serv_addr.sin_port = htons(REM_TCP_PORT); servsockfd = socket(AF_INET, SOCK_STREAM, 0); connect(servsockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); #ifdef FNDELAY fcntl(servsockfd,F_SETFL,fcntl(clisockfd,F_GETFL,0)|FNDELAY); #else fcntl(servsockfd,F_SETFL,O_NDELAY); #endif communicate(servsockfd,clisockfd); close(servsockfd); exit(0); } communicate(sfd,cfd) { char *chead, *ctail, *shead, *stail; int num, nfd, spos, cpos; extern int errno; fd_set rd, wr; chead = ctail = cbuf; cpos = 0; shead = stail = sbuf; spos = 0; while (1) { FD_ZERO(&rd); FD_ZERO(&wr); if (spos < sizeof(sbuf)-1) FD_SET(sfd, &rd); if (ctail > chead) FD_SET(sfd, &wr); if (cpos < sizeof(cbuf)-1) FD_SET(cfd, &rd); if (stail > shead) FD_SET(cfd, &wr); nfd = select(256, &rd, &wr, 0, 0); if (nfd <= 0) continue; if (FD_ISSET(sfd, &rd)) { num=read(sfd,stail,sizeof(sbuf)-spos); if ((num==-1) && (errno != EWOULDBLOCK)) return; if (num==0) return; if (num>0) { spos += num; stail += num; if (!--nfd) continue; } } if (FD_ISSET(cfd, &rd)) { num=read(cfd,ctail,sizeof(cbuf)-cpos); if ((num==-1) && (errno != EWOULDBLOCK)) return; if (num==0) return; if (num>0) { cpos += num; ctail += num; if (!--nfd) continue; } } if (FD_ISSET(sfd, &wr)) { num=write(sfd,chead,ctail-chead); if ((num==-1) && (errno != EWOULDBLOCK)) return; if (num>0) { chead += num; if (chead == ctail) { chead = ctail = cbuf; cpos = 0; } if (!--nfd) continue; } } if (FD_ISSET(cfd, &wr)) { num=write(cfd,shead,stail-shead); if ((num==-1) && (errno != EWOULDBLOCK)) return; if (num>0) { shead += num; if (shead == stail) { shead = stail = sbuf; spos = 0; } if (!--nfd) continue; } } } }