/* relay OOB (maybe SYNCH signal of Telnet) */ int relayOOB(int in,int out) { CStr(buff,128); int rcc; int pi,nready; CStr(oobb,128); int oobx = 0; int noob = 0; /* msleep(1); SetNonblockingIO("relayOOB",in,1); rcc = recvOOB(in,AVStr(buff),sizeof(buff)); SetNonblockingIO("relayOOB",in,0); if( rcc != 1 ) return 0; */ SetNonblockingIO("relayOOB",in,1); oobx = 0; rcc = recv(in,buff,sizeof(buff),MSG_PEEK|MSG_OOB); if( 0 < rcc ){ rcc = recv(in,oobb+oobx,sizeof(oobb)-oobx,MSG_OOB); oobx += rcc; while( 0 < withOOB(in) ){ errno = 0; rcc = recv(in,buff,sizeof(buff),MSG_PEEK); /* recv() even with MSG_PEEK seems to clear * "exceptfds" in select() */ if( rcc < 0 && errno == EAGAIN ){ syslog_ERROR("relay OOB: EAGAIN\n"); msleep(1); }else if( 0 < rcc && 0 < withOOB(in) ){ /* maybe skipping non-OOB before OOB ... */ CStr(vb,32); refQStr(vp,vb); int i; for( i = 0; i < rcc; i++ ){ if( sizeof(vb) <= (vp-vb)+3 ){ break; } if( 0 < i ) setVStrPtrInc(vp,' '); sprintf(vp,"%02X",0xFF&buff[i]); vp += strlen(vp); } syslog_DEBUG("relay pre-OOB: %d [%s]\n",rcc,vb); rcc = recv(in,buff,sizeof(buff),0); noob += rcc; send(out,buff,rcc,0); }else{ break; } } } if( 0 <= oobx ){ send(out,oobb,oobx,MSG_OOB); syslog_DEBUG("relay OOB: [%d]->[%d] %dbytes (%02X)\n", in,out,oobx,oobb[0]&0xFF); } SetNonblockingIO("relayOOB",in,0); return oobx; syslog_DEBUG("relay OOB: [%d]->[%d] %dbytes (%x)\n", in,out,rcc,buff[0]&0xFF); sendOOB(out,buff,rcc); /* if the protocol is Telnet, * in-band data should be ignored until the MARK(242) ... */ for( pi = 0; pi < 50; pi++ ){ if( nready = PollIn(in,1) ) break; msleep(10); } syslog_DEBUG("relay OOB: nready=%d after %dms\n",nready,pi*10); return 1; }
void handleWrite(clientHandle_t * ch, selcmd_t * sc) { int i; fd_set *rfds, *wfds, *efds; char *buf; int code; int scode; char c; int nbytes; rfds = IOMGR_AllocFDSet(); wfds = IOMGR_AllocFDSet(); efds = IOMGR_AllocFDSet(); assert(rfds && wfds && efds); if (sc->sc_delay > 0) { IOMGR_Sleep(sc->sc_delay); } Log("(handleWrite 0x%x) waking after %d second sleep.\n", ch->ch_pid, sc->sc_delay); if (sc->sc_flags & SC_WAIT_OOB) sendOOB(ch->ch_fd); buf = (char *)malloc(sc->sc_info); assert(buf); i = 0; while (1) { FD_ZERO(rfds); FD_SET(ch->ch_fd, rfds); FD_ZERO(efds); FD_SET(ch->ch_fd, efds); FD_ZERO(wfds); scode = IOMGR_Select(ch->ch_fd + 1, rfds, wfds, efds, (struct timeval *)0); assert(scode > 0); if (FD_ISSET(ch->ch_fd, rfds)) { assert(i < sc->sc_info); code = read(ch->ch_fd, &buf[i], 1); i++; write_I++; if (code != 1) { Log("code =%d\n", code); assert(code == 1); } /* Test for valid fds */ assertNullFDSet(ch->ch_fd, rfds); assertNullFDSet(-1, wfds); assertNullFDSet(-1, efds); if (c == END_DATA || i >= sc->sc_info) { break; } } } Log("Read %d bytes of data.\n", sc->sc_info); nbytes = write(ch->ch_fd, buf, sc->sc_info); assert(nbytes == sc->sc_info); Log("Wrote data back to client.\n"); IOMGR_FreeFDSet(rfds); IOMGR_FreeFDSet(wfds); IOMGR_FreeFDSet(efds); }
main(int ac, char **av) { int i; int on = 1; char *hostname = 0; struct hostent *hostent; int host; /* net order. */ short port = -1; /* host order. */ int setFD = 0; int sockFD; struct sockaddr_in saddr; int reqOOB = 0; int putOOB = 0; int delay = 5; int doEnd = 0; int doWrite = 0; int writeSize = 0; program = av[0]; signal(SIGIO, sigIO); for (i = 1; i < ac; i++) { if (!strcmp("-fd", av[i])) { if (++i >= ac) { printf("Missing number for -fd option.\n"); Usage(); } setFD = atoi(av[i]); if (setFD <= 2) { printf("%s: %d: file descriptor must be at least 3.\n", program, setFD); Usage(); } } else if (!strcmp("-end", av[i])) { doEnd = 1; } else if (!strcmp("-delay", av[i])) { if (++i >= ac) { printf("%s: Missing time for -delay option.\n", program); Usage(); } delay = atoi(av[i]); if (delay < 0) { printf("%s: %s: delay must be at least 0 seconds.\n", program, av[i]); Usage(); } } else if (!strcmp("-write", av[i])) { doWrite = 1; if (++i >= ac) { printf("%s: Missing size for -write option.\n", program); Usage(); } writeSize = atoi(av[i]); if (writeSize < 1) { printf("%s: %s: Write size must be at least 1 byte.\n", program, av[i]); Usage(); } } else if (!strcmp("-oob", av[i])) { reqOOB = 1; } else if (!strcmp("-soob", av[i])) { putOOB = 1; } else { if (!hostname) { hostname = av[i]; } else if (port == -1) { port = atoi(av[i]); if (port <= 0) { printf("%s: %s: port must be at least 1\n", program, av[i]); Usage(); } } else { printf("%s: %s: Unknown argument.\n", program, av[i]); } } } if (!hostname) { printf("%s: Missing hostname and port.\n", program); Usage(); } if (port == -1) { printf("%s: Missing port.\n", program); Usage(); } if (writeSize == 0 && doEnd == 0 && putOOB == 0) { printf("%s: Missing action.\n", program); Usage(); } if (!setFD) { setFD = 31; printf("%s: Using default socket of %d.\n", program, setFD); } if (!(hostent = gethostbyname(hostname))) { printf("%s: Failed to find host entry for %s.\n", program, hostname); exit(1); } memcpy((void *)&host, (const void *)hostent->h_addr, sizeof(host)); OpenFDs(setFD); /* Connect to server. */ sockFD = socket(AF_INET, SOCK_STREAM, 0); if (sockFD < 0) { Die(0, "socket"); } printf("%s: Using socket at file descriptor %d.\n", program, sockFD); memset((void *)&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = host; /* already in network byte order. */ saddr.sin_port = htons(port); if (connect(sockFD, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { assert(0); } if (doEnd) { sendEnd(sockFD); } else if (putOOB) { Log("Will send OOB in 2 seconds.\n"); sleep(2); sendOOB(sockFD); Log("Sent OOB, sleeping for 5 seconds.\n"); sleep(5); Log("Sent OOB, exiting.\n"); } else { IOMGR_Initialize(); sendTest(sockFD, delay, reqOOB, writeSize); } close(sockFD); }