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