Example #1
0
int main(int argc, char **argv)
{
  Connection con;
  PortConnection port;
  const char *name = TIMING_NAME;
  const char *other, *now;

  struct sigaction sa;
  sa.sa_handler= SIG_IGN;
  sa.sa_flags=SA_NOCLDWAIT;
  /* this old code produced a warning 
    struct sigaction sa = {
    SIG_IGN, 0, 0, SA_NOCLDWAIT
    };*/

  x = time(0);

  sigaction (SIGCHLD, &sa, 0);

  {
    char buf[1024];
    FILE *x;

    x = fopen ("modulus.hex", "r");
    if (! x) { perror ("modulus.hex"); exit (2); }
    fgets (buf, 1024, x);
    fclose (x);
    LHex2Long (buf, &n);
  }

  /***************  Globales Port eröffnen  ***************/
  if (!(port=OpenPort(name))) {
    fprintf(stderr,"TIMING_DAEMON: Kann das Dämon-Port \"%s\" nicht erzeugen: %s\n",name,NET_ErrorText());
    exit(20);
  }

  /******************* Hauptschleife **********************/
  while (1) {

    /**************  Auf Verbindung auf dem Port warten  ****************/
    if (!(con=WaitAtPort(port))) {
      fprintf(stderr,"TIMING_DAEMON: WaitAtPort ging schief: %s\n",NET_ErrorText());
      exit(20);
    }
    other = PeerName(port);
    now = Now();

    fprintf (stderr, "Connect from %s: %s\n", other, now);
    fflush (stderr);

    x += time(0);
    handle_connection (con, other, now);
    DisConnect (con);
  }

  return 0;
}
int
RecvBytes(Socket sd,
          void *bytes,
          size_t byteSize,
          double timeOut) {

  double end;
  int isPipe;
  char *nextByte;
  fd_set readFds;
  int recvd;
  double start;
  int totalRecvd;
  struct timeval tout;
  void (*was)(int);

  isPipe = FD_ISSET(sd, &connectedPipes);
  FD_ZERO(&readFds);
  FD_SET(sd, &readFds);

  tout.tv_sec = (int)timeOut;
  tout.tv_usec = 0;

  start = CurrentTime();
  was = signal(SIGALRM, RecvTimeOut);
  nextByte = (char *)bytes;

  for(totalRecvd = 0; totalRecvd < byteSize; totalRecvd += recvd) {
    
    recvd = 0;
    switch (select(FD_SETSIZE, &readFds, NULL, NULL, &tout)) {

    case -1:
      if(errno == EINTR) {
        end = CurrentTime();
        if((int)(end - start) < timeOut) {
          tout.tv_sec = (int)(timeOut - (end - start));
          continue;
        }
      }
      signal(SIGALRM, was);
      FAIL2("RecvBytes: select %d failed %s\n", sd, strerror(errno));
      break;

    case 0:
      if(!isPipe) {
        end = CurrentTime();
        SetPktTimeOut(sd, end - start, 1);
      }
      signal(SIGALRM, was);
      FAIL3("RecvBytes: timed out socket %d after %d/%fs\n",
            sd, tout.tv_sec, timeOut);
      break;

    default:
      SetRealTimer((unsigned int)timeOut);

 	  recvd = read(sd, nextByte, (size_t)(byteSize - totalRecvd));

      RESETREALTIMER;

      if(recvd <= 0) {
		WARN3("RecvBytes: read() on descriptor %d returned %d (errno=%d).\n", sd, recvd, errno);
        if(!isPipe) {
          end = CurrentTime();
          SetPktTimeOut(sd, end - start, 0);
        }
        signal(SIGALRM, was);
        FAIL5("RecvBytes: sd %d (addr:%s) failed with %s after %d of %d\n",
              sd, PeerName(sd), strerror(errno), totalRecvd, byteSize);
      }
      break;

    }

    nextByte += recvd;

  }

  return(1);

}
int
IncomingRequest(double timeOut,
                Socket *sd) {

  Socket dead;
  Socket i;
  char lookahead;
  Socket newSock;
  double now;
  struct sockaddr_in peer_in;
  SOCKLEN_T peer_in_len = sizeof(peer_in);
  fd_set readFds;
  struct timeval tout;
  double wakeup;

  /*
  ** nextToService is used to make sure that every connection gets a chance to
  ** be serviced.  If we always started checking at 0, very active connections
  ** with small descriptor numbers could starve larger-descriptor connections.
  */
  static Socket nextToService = 0;

  *sd = NO_SOCKET;
  tout.tv_usec = 0;
  wakeup = CurrentTime() + timeOut;

  while((now = CurrentTime()) < wakeup) {

    /* Construct in readFds the union of connected ears, pipes, and sockets. */
    readFds = connectedSockets;
    for(i = 0; i < FD_SETSIZE; i++) {
      if(FD_ISSET(i, &connectedPipes)) {
        FD_SET(i, &readFds);
      }
    }
    for(i = 0; i < FD_SETSIZE; i++) {
      if(FD_ISSET(i, &connectedEars)) {
        FD_SET(i, &readFds);
      }
    }

    tout.tv_sec = (unsigned int)wakeup - (unsigned int)now;

    switch(select(FD_SETSIZE, &readFds, NULL, NULL, &tout)) {

    case -1:
      if(errno == EINTR) {
        continue;
      }
      else if(errno == EINVAL) {
        /* we blew it somehow -- this is mostly for osf... */
        /* can be because (from man page):
          [EINVAL] The time limit specified by the timeout parameter is invalid.

                   The nfds parameter is less than 0, or greater than or equal
                   to FD_SETSIZE.

                   One of the specified file descriptors refers to a STREAM or
                   multiplexer that is linked (directly or indirectly)
                   downstream from a multiplexer.
        */

        FAIL4("IncomingRequest: invalid select - nfds: %d, rfds: %d, to: %d.%d",
              FD_SETSIZE, readFds, tout.tv_sec, tout.tv_usec);
      }
      else {
        FAIL1("IncomingRequest: select error %d\n", errno);
      }
      break;

    case 0:
      /* timeout */
      break;

    default:

      i = nextToService;

      while(1) {

        if(FD_ISSET(i, &readFds)) {

          if(FD_ISSET(i, &connectedEars)) {
            /* Add the new connection to connectedSockets. */
            newSock = accept(i, (struct sockaddr *)&peer_in, &peer_in_len);
            if(newSock == -1) {
              SocketFailure(SIGPIPE);
            }
            else {
              ConditionSocket(newSock);
	      if (debug > 0) {
                  DDEBUG2("IncomingRequest: connected socket %d to %s\n",
                      newSock, PeerName(newSock));
	      }
              FD_SET(newSock, &connectedSockets);
            }
          }
          else if(FD_ISSET(i, &connectedPipes)) {
            *sd = i;
            nextToService = (i + 1) % FD_SETSIZE;
            return(1);
          }
          else {
            /* Existing socket connection. */
            if(recv(i, &lookahead, 1, MSG_PEEK) > 0) {
              *sd = i;
              nextToService = (i + 1) % FD_SETSIZE;
              return(1);
            }
            else {
              /*
              ** This is how we find out about connections closed by a peer.
              ** Drop it from our list of known connections.
              */
		if (debug > 0) {
                  DDEBUG1("IncomingRequest: Dropping closed connection %d\n", i);
		}
              dead = i;
              DROP_SOCKET(&dead);
            }
          }

        }

        i = (i + 1) % FD_SETSIZE;
        if(i == nextToService) {
          /* We've been through the entire set without finding a request. */
          break;
        }

      }
      break;

    }

  }

  return(0);

}
int
CallAddr(IPAddress addr,
         short port,
         Socket *sock,
         double timeOut) {

  struct sockaddr_in server; /* remote host address */
  Socket sd;
  int one = 1;
  int sock_opt_len = sizeof(int);
  double start;
  double end;
  double ltimeout;
  void (*was)(int);

  was = signal(SIGALRM, ConnectTimeOut);

  memset((char *)&server, 0, sizeof(server));
  server.sin_addr.s_addr = addr;
  server.sin_family = AF_INET;
  server.sin_port = htons((u_short)port);

  sd = socket(AF_INET, SOCK_STREAM, 0);

  if(sd < 0) {
    *sock = NO_SOCKET;
    signal(SIGALRM, was);
    FAIL("CallAddr: cannot create socket to server\n");
  }

  if(setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, (char *)&one, sock_opt_len) < 0) {
    WARN("CallAddr: keepalive option failed\n");
  }

  if(setsockopt(sd, TcpProtoNumber(),
                TCP_NODELAY, (char *)&one, sock_opt_len) < 0) {
    WARN("CallAddr: couldn't set NODELAY flag\n");
  }

  ltimeout = ConnTimeOut(addr);

  if(ltimeout == 0.0)
    ltimeout = timeOut;

  SetRealTimer((unsigned int)ltimeout);
  start = CurrentTime();
  
  if(connect(sd, (struct sockaddr *)&server, sizeof(server)) < 0) {
    shutdown(sd, 2);
    close(sd);
    *sock = NO_SOCKET;
    RESETREALTIMER;
    if(errno == EINTR) {
      /* this was a timeout */
      end = CurrentTime();
      InsertHashAddr(addr);
      SetConnTimeOut(addr, end - start, 1);
    }
    signal(SIGALRM,was);
    FAIL("CallAddr: connect failed\n");
  }

  end = CurrentTime();
  RESETREALTIMER;

  *sock = sd;
  if (debug > 0) {
      DDEBUG2("CallAddr: connected socket %d to %s\n", sd, PeerName(sd));
  }
  FD_SET(sd, &connectedSockets);

  InsertHash(sd);
  SetConnTimeOut(addr, end - start, 0);
  SetPktTimeOut(sd, end - start, 0);

  signal(SIGALRM,was);
  return(1);

}