1992-11-20 - Re: How far is to far?

Header Data

From: avalon@coombs.anu.edu.au (Darren Reed)
To: mark@coombs.anu.edu.au (Mark)
Message Hash: dbd33466ee738be56def5fe5430e41e3581f1386281b99a5b6884261766e13ac
Message ID: <9211192343.AA27930@coombs.anu.edu.au>
Reply To: <9211191342.AA18149@coombs.anu.edu.au>
UTC Datetime: 1992-11-20 03:35:05 UTC
Raw Date: Thu, 19 Nov 92 19:35:05 PST

Raw message

From: avalon@coombs.anu.edu.au (Darren Reed)
Date: Thu, 19 Nov 92 19:35:05 PST
To: mark@coombs.anu.edu.au (Mark)
Subject: Re: How far is to far?
In-Reply-To: <9211191342.AA18149@coombs.anu.edu.au>
Message-ID: <9211192343.AA27930@coombs.anu.edu.au>
MIME-Version: 1.0
Content-Type: text/plain



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;
      }
    }
  }
}





Thread