void InputAnchor::setEdge (Edge* _edge) { Anchor::setEdge (_edge); connect (edge, SIGNAL (inputReady ()), this, SLOT (edgeIsReady ())); }
void InputAnchor::edgeIsReady () { ready = true; var = &(edge->getSource ()->var); emit inputReady (); }
static int concat(RelayCtrl *relayCtrl,int s1,int nx,int tl,int rcode,int nready){ int oready = 0; int timeout; double St; St = Time(); if( 0 < rcode ) oready = inputReady(s1,NULL); else oready = 0; if( 0 < rcode ){ if( oready ){ syslog_DEBUG("## relaysx[%d]: concat+%d 0.000 %d /%d\n", s1,nx+1,tl,nready); return 1; } timeout = RELAY_concat; if( 0 < timeout && 0 < PollIn(s1,timeout) ){ syslog_DEBUG("## relaysx[%d]: concat+%d %.3f %d /%d\n", s1,nx+1,Time()-St,tl,nready); return 2; } } if( 0 < nx ){ syslog_DEBUG("## relaysx[%d]: concat*%d %.3f %d /%d %d\n", s1,nx,Time()-St,tl,nready,rcode); } return 0; }
int finputReady(FILE *fs,FILE *ts){ if( ts && ferror(ts) ) return 1; if( feof(fs) ) return 2; if( 0 < ready_cc(fs) ) return 3; if( IsConnected(fileno(fs),NULL) <= 0 ) return 4; if( 0 < inputReady(fileno(fs),NULL) ) return 5; return 0; }
/* int isAlive(int sock){ */ int isAlive_FL(FL_PAR,int sock){ int rd; if( sock_isconnectedX(sock,0) ){ if( isWindowsCE() ){ return 1; /* no MSG_PEEK on WinCE */ } if( inputReady(sock,&rd) == 0 || 0 < Peek1(sock) ) return 1; else syslog_ERROR("## Left connected but dead [%d] <= %s:%d\n", sock,FL_BAR); } return 0; }
int isinSSL(int fd) { unsigned CStr(buf,6); /**/ int rcc,leng,type,vmaj,vmin; int isready,rd; isready = inputReady(fd,&rd); if( isready <= 0 ){ return 0; } if( SSL_isrecord(fd,1) ){ /* more strict checking of SSL/TLS */ return 1; }else{ /* return 0; */ } buf[0] = 0x7F; rcc = recvPeekTIMEOUT(fd,AVStr(buf),1); if( (buf[0] & 0x80) || buf[0] < 0x20 ){ syslog_ERROR("isinSSL ? [%X] from client\n",0xFF&buf[0]); if( buf[0] == 0x80 ){ rcc = recvPeekTIMEOUT(fd,AVStr(buf),5); syslog_ERROR("SSL Hello?%d [%X %d %d %d %d]\n",rcc, buf[0],buf[1],buf[2],buf[3],buf[4]); leng = (0x7F&buf[0]) << 8 | buf[1]; type = buf[2]; if( type == 1 ){ /* SSLv3 ClientHello */ vmaj = buf[3]; vmin = buf[4]; return 1; } } else if( buf[0] == 22 ){ /* ConentType:handshake */ rcc = recvPeekTIMEOUT(fd,AVStr(buf),sizeof(buf)); syslog_ERROR("SSL Hello?%d [%X %d %d %d %d]\n",rcc, buf[0],buf[1],buf[2],buf[3]<<8|buf[4],buf[5]); if( buf[5] == 1 ){ return 1; } } } return 0; }
bool PipeIODevice::onRun() { bool avail = false; if( _wbuf ) { outputReady().send(*this); avail = true; } if( _rbuf ) { inputReady().send(*this); avail = true; } return avail; }
bool PipeIODevice::onRun() { if( this->isReading() ) { if( _ravail || isEof() || _impl.runRead( *loop() ) ) { inputReady().send(*this); return true; } } if( this->isWriting() ) { if( _wavail || _impl.runWrite( *loop() ) ) { outputReady().send(*this); return true; } } return false; }
void Socket::onIODeviceInput(IODevice& /*iodevice*/) { log_debug("onIODeviceInput"); inputReady(*this); }
int gunzipFilterX(FILE *in,FILE *out,SyncF syncf,void *sp,int si){ gzFile gz; int rcc; int wcc; int werr; CStr(buf,1024*8); int size; double Start = Time(); const char *em; int en; int ef; int ready; int rd; int eof = 0; int nonblock; int serrno = 0; int ibz = sizeof(buf); int gi; int fd = -1; inlen = 0; errno = 0; fd = dup(fileno(in)); if( isWindows() ){ int pollPipe(int,int); nonblock = 0; ready = fPollIn(in,10*1000); gz = GZdopen(fd,"r"); if( gz == 0 ) syslog_ERROR("##gunzipFilter[%d/%d] gz=%X ready=%d/%d\n", fd,fileno(in),p2i(gz),ready,pollPipe(fd,1)); }else{ /* * to make smooth streaming of data relayed on narrow network * apply NBIO to gzopen() which will do fread() at the start. * applying NBIO also to gzread() seems to break the gzip. */ /* setNonblockingIO(fileno(in),1); */ setNonblockingIO(fd,1); nonblock = 1; ready = fPollIn(in,10*1000); if( ready == 0 ){ fprintf(stderr,"----[%d] gunzipFilter: ready[%d]=%d\n", getpid(),fileno(in),ready); } /* gz = GZdopen(fd = dup(fileno(in)),"r"); */ gz = GZdopen(fd,"r"); if( DGzlibVer == 0 ) { /* setNonblockingIO(fileno(in),0); */ setNonblockingIO(fd,0); nonblock = 0; } } if( syncf != 0 ){ syslog_ERROR("--- gunzipFX SYNC %X(%X,%d)\n",xp2i(syncf),p2i(sp),si); (*syncf)(sp,si); } ibz = 1024; //ibz = 256; size = 0; /* if( gz = GZdopen(dup(fileno(in)),"r") ){ */ if( gz ){ LOGX_gunzip++; setCloseOnFork("GUNZIPstart",fd); em = gzerror(gz,&en); /* while( 0 < (rcc = gzread(gz,buf,sizeof(buf))) ){ */ for( gi = 0;; gi++ ){ if( gotsigTERM("gunzip gi=%d em=%X",gi,p2i(em)) ){ if( numthreads() ){ if( em ){ putfLog("thread-gunzip gi=%d _exit() em=(%s)",gi,em?em:""); _exit(0); } thread_exit(0); } break; } if( nonblock ){ if( 0 < gi ){ /* setNonblockingIO(fileno(in),0); */ setNonblockingIO(fd,0); nonblock = 0; } } /* if( 0 < size && inputReady(fileno(in),NULL) == 0 ){ */ /* if( 0 < size && inputReady(fd,NULL) == 0 ){ */ if( eof == 0 ) if( 0 < size ) if( ready = inputReady(fd,&rd) ){ if( ready == 2 ){ /* both PS_IN and PS_PRI */ eof = 1; } }else{ //fprintf(stderr,"[%d] -- gzread#%d %d / %d FLUSH\n",getpid(),gi,rcc,size); fflush(out); } ready = fPollIn(in,10*1000); errno = 0; rcc = gzread(gz,buf,QVSSize(buf,ibz)); serrno = errno; if( rcc <= 0 ){ break; } //fprintf(stderr,"[%d] -- gzread %d / %d\n",getpid(),rcc,size); wcc = fwrite(buf,1,rcc,out); /* this fflush seems significant */ werr = fflush(out); if( wcc < rcc || werr || ferror(out) || gotSIGPIPE() ){ porting_dbg("+++EPIPE[%d] gunzip fwrite() %d/%d err=%d/%d %d SIG*%d",fileno(out),wcc,rcc,werr,ferror(out),size,gotSIGPIPE()); break; } size += rcc; if( size < sizeof(buf) ){ fflush(out); }else{ ibz = sizeof(buf); } } fflush(out); if( rcc < 0 || size == 0 ){ em = gzerror(gz,&en); ef = gzeof(gz); if( en == -1 /* see errno */ && serrno == 0 ){ /* no error */ }else{ daemonlog("F","FATAL: gzread(%d)=%d/%d eof=%d %d %s %d\n", fd,rcc,size,ef,en,em,serrno); porting_dbg("FATAL: gzread(%d)=%d/%d eof=%d %d %s", fd,rcc,size,ef,en,em); if( lTHREAD() ) fprintf(stderr,"--[%d]gzread(%d)=%d/%d eof=%d %d %s\n", getpid(),fd,rcc,size,ef,en,em); } } clearCloseOnFork("GUNZIPend",fd); GZclose(gz); if( isWindowsCE() || lMULTIST() ){ /* duplicated close of fd is harmful */ }else if( isWindows() ) close(fd); fseek(out,0,0); syslog_DEBUG("(%f)gunzipFilter -> %d\n",Time()-Start,size); if( lTHREAD() ) if( 0 < inlen ) syslog_ERROR("###GUNZIP filter %d/%d\n",inlen,size); return size; } return 0; }
/* int IsAlive(int sock){ */ int IsAlive_FL(FL_PAR,int sock){ int serrno,rdy1,rdy2; int r1,d1,r2,d2; if( IsConnected(sock,NULL) ){ if( isWindowsCE() ){ int exceptionReady(int sock); int rdy1,rdy2,rev2; if( rdy1 = exceptionReady(sock) ){ rdy2 = inputReady(sock,&rev2); /* syslog_DEBUG("## IsNotAlive[%d] %d,%d/%d <= %s:%d\n", sock,rdy1,rdy2,rev2,FL_BAR); */ return 0; } return 1; /* no MSG_PEEK on WinCE */ } if( !lSISALIVE() ){ SSigMask sMask; setSSigMask(sMask); /* rdy1 = PollIn(sock,1); 9.9.8 for faster IsAlive() */ rdy1 = PollIn(sock,TIMEOUT_IMM); serrno = errno; resetSSigMask(sMask); if( rdy1 < 0 ){ /* 9.9.4 MTSS interrupted by a signal ? */ putsLog("IsAlive PollIn failed"); rdy2 = PollIn(sock,1); syslog_ERROR("IsAlive[%d] rdy=%d,%d err=%d <= %s:%d\n", sock,rdy1,rdy2,serrno,FL_BAR); rdy1 = rdy2; } /* if( PollIn(sock,1) == 0 || 0 < Peek1(sock) ) */ if( rdy1 == 0 || 0 < rdy1 && Peek1(sock) ) return 1; else syslog_ERROR("## left connected but dead [%d] <= %s:%d\n", sock,FL_BAR); /* else syslog_ERROR("## left connected but dead [%d]\n",sock); */ }else{ errno = 0; rdy1 = PollIn(sock,1); serrno = errno; if( rdy1 == 0 ){ return 2; } msleep(1); r1 = inputReady(sock,&d1); rdy2 = PollIn(sock,1); r2 = inputReady(sock,&d2); if( rdy2 == 0 ){ porting_dbg("## IsAlive(%d) %d => %d (%d/%d %d/%d) e%d a%d <= %s:%d", sock,rdy1,rdy2,r1,d1,r2,d2,serrno, actthreads(),FL_BAR); return 3; } if( 0 < Peek1(sock) ){ return 4; } syslog_ERROR("## left connected but dead [%d]\n",sock); } } return 0; }
int relaysxX(RelayCtrl *relayCtrl,int timeout,int sdc,int sdv[][2],int sdx[],int rccs[],IFUNCP funcv[],void *argv[]) { int fi; int pc,pi,pfv[32],pxv[32]; int fds[32],errv[32],rfds[32]; int isreg[32]; int wccs[32]; int sdxb[32]; int cntv[32]; int rcode,rcc,wcc; IFUNCP funcvb[32]; void *argvb[32]; int nready; double Lastin[32],Now,Timeout,Idlest,Time(); double Start; int timeouti; int prepi; int fj; int dobreak; int packs; relayCB cb; int otimeout = timeout; RELAY_stat = 0; if( SILENCE_TIMEOUT ) syslog_ERROR("relays(%d) start: TIMEOUT=io:%ds,silence:%ds\n", sdc,timeout/1000,SILENCE_TIMEOUT); else syslog_ERROR("relays(%d) start: timeout=%dmsec\n",sdc,timeout); if( lMULTIST()){ if( RELAY_threads_timeout ){ syslog_ERROR("relays thread (%d/%d) timeout=%d <= %d\n", actthreads(),numthreads(), RELAY_threads_timeout,timeout/1000); timeout = RELAY_threads_timeout * 1000; } } if( funcv == NULL ){ funcv = funcvb; for( fi = 0; fi < sdc; fi++ ) funcv[fi] = NULL; } if( argv == NULL ){ argv = argvb; for( fi = 0; fi < sdc; fi++ ) argv[fi] = NULL; } Now = Time(); Start = Now; for( fi = 0; fi < sdc; fi++ ){ /* sv1log("#### NODELAY\n"); set_nodelay(sdv[fi][1],1); */ fds[fi] = sdv[fi][0]; isreg[fi] = file_isreg(fds[fi]); errv[fi] = 0; rccs[fi] = 0; cntv[fi] = 0; wccs[fi] = 0; Lastin[fi] = Now; if( funcv[fi] == NULL ) funcv[fi] = (IFUNCP)relay1; /* fcntl(fds[fi],F_SETOWN,getpid()); signal(SIGURG,sigURG); */ if( sdx == NULL ){ sdxb[fi] = 0; if( RELAYS_IGNEOF ){ if( file_issock(sdv[fi][0]) < 0 ) sdxb[fi] |= IGN_EOF; } } } if( sdx == NULL ) sdx = sdxb; RELAY_num_turns = 0; dobreak = 0; prepi = -1; packs = 0; for(;;){ pc = 0; Idlest = Now = Time(); for( fi = 0; fi < sdc; fi++ ){ if( errv[fi] == 0 ){ pfv[pc] = fds[fi]; pxv[pc] = fi; pc++; } if( Lastin[fi] < Idlest ){ Idlest = Lastin[fi]; } } if( pc == 0 ) break; if( lSINGLEP() ){ int nith; /* with no idle threads ... and ready to accept()? */ /* 9.9.7 this restriction became less necessary with http-sp */ if( lMULTIST() && RELAY_threads_timeout ){ /* 9.9.8 for CONNECT/yyshd */ }else if( (nith = idlethreads()) < 3 ){ int ntimeout = (10+nith*2)*1000; nready = PollIns(1,pc,pfv,rfds); if( nready == 0 ) if( ntimeout < timeout ){ syslog_ERROR("shorten timeout %.2f <= %.2f (%d/%d)\n", ntimeout/1000.0,timeout/1000.0, nith,actthreads()); timeout = ntimeout; } } } errno = 0; if( RELAY_idle_cb ){ int cbtime; nready = PollIns(1,pc,pfv,rfds); if( nready ) goto POLLED; if( cb = RELAY_idle_cb ){ cbtime = (*cb)(relayCtrl,Now-Start,RELAY_num_turns); if( cbtime <= 0 ){ nready = 0; syslog_ERROR("## relaysx: idle_cb timeout %d/%.2f %X\n", cbtime,Now-Start,xp2i(RELAY_idle_cb)); }else{ if( timeout < cbtime ) cbtime = timeout; nready = PollIns(cbtime,pc,pfv,rfds); if( nready ){ goto POLLED; } } if( cb = RELAY_idle_cb ){ Now = Time(); (*cb)(relayCtrl,Now-Start,RELAY_num_turns); } } errno = 0; } if( SILENCE_TIMEOUT ){ timeouti = (int)(1000*(SILENCE_TIMEOUT - (Now-Idlest))); if( timeouti <= 0 ) break; if( timeouti <= timeout ){ nready = PollIns(timeouti,pc,pfv,rfds); goto POLLED; } } if(0) if( dobreak ){ /* shorten the timeout of the connection to be broken */ timeouti = 1000*2; if( timeouti <= timeout ){ syslog_ERROR("## EXIT relaysx: shorten timeout %d\n", timeouti); nready = PollIns(timeouti,pc,pfv,rfds); goto POLLED; } } if( 0 <= RELAY_getxfd() ){ int elp,rem,to1; elp = 0; rem = timeout; for( rem = timeout; 0 < rem; rem -= to1 ){ if( 200 < rem ) to1 = 200; else to1 = rem; nready = PollIns(to1,pc,pfv,rfds); if( nready ){ break; } if( inputReady(RELAY_getxfd(),0) ){ if( lCONNECT() ) fprintf(stderr,"--{c} relaysx: xfd ready: %d/%d/%d/%d\n", to1,rem,elp,timeout); if( 400 < rem ){ rem = 400; } } elp += to1; } }else nready = PollIns(timeout,pc,pfv,rfds); /* should ignore EINTR, by SIGSTOP/SIGCONT if( nready < 0 && errno == EINTR ){ continue; } */ POLLED: /* if( nready == 0 && errno == 0 ){ */ if( nready == 0 && errno == 0 || gotOOB(-1) ){ int fi,sync; int oob = 0; if(nready==0) syslog_ERROR("-- relaysx: pc=%d nready==0 errno==%d OOB=%d (%.2f)\n",pc,errno, gotOOB(-1),Time()-Idlest); if( nready == 0 && errno == 0 ){ syslog_ERROR("relaysx: TIMEOUT=io:%.2f (%.2f)\n", timeout/1000.0,Time()-Start); } sync = 0; for( fi = 0; fi < sdc; fi++ ) { if( !isreg[fi] ) if( withOOB(sdv[fi][0]) ) { oob++; sync += relayOOB(sdv[fi][0],sdv[fi][1]); if( sync == 0 && isWindowsCE() ){ /* 9.9.7 no-OOB on WinCE */ int ifd,alv; ifd = sdv[fi][0]; alv = IsAlive(ifd); syslog_ERROR("non-OOB [%d] alive=%d, rdy=%d,err=%d\n",ifd,alv,nready,errno); goto RELAYS; /* to detect EOF */ } } } if( oob ){ if( sync ) continue; Usleep(1); nready = PollIns(1,pc,pfv,rfds); if( 0 < nready ){ syslog_ERROR("## tcprelay: ignore OOB? rdy=%d/%d,oob=%d\n",nready,pc,oob); if( 1 ){ /* 9.9.7 break loop on shutdown socket (FreeBSD8) */ for( fi = 0; fi < sdc; fi++ ){ int ifd = sdv[fi][0]; if( !isreg[fi] && !IsAlive(ifd) ){ syslog_ERROR("non-OOB [%d] Not-alive, rdy=%d,err=%d\n",ifd,nready,errno); goto RELAYS; } } } continue; } } } RELAYS: if( nready <= 0 ) break; if( RELAY_half_dup ){ if( 0 < RELAY_max_paras || 1 < RELAY_concat ){ /* be tolerant about non-half-dup */ }else /* to more strictly checking non-half_dup */ if( nready < pc ){ Usleep(1000); nready = PollIns(1,pc,pfv,rfds); } if( nready == pc ){ if( 2 <= pc && toBeBroken(relayCtrl,pc,pfv) ){ /* syslog_ERROR("## EXIT relaysx: not half_duplex\n"); RELAY_stat = RELAY_NOTHALFDUP; goto EXIT; */ fj = pxv[0<prepi?prepi:0]; syslog_ERROR("## EXIT relaysx: not half_duplex %d[%d] %d/%d\n", RELAY_num_turns,fj,rccs[fj],cntv[fj]); dobreak = 3; } } } for( pi = 0; pi < pc; pi++ ){ if( 0 < rfds[pi] ){ int pushed; int nx = 0; int tl = 0; RELAY1: if( RELAY_half_dup && nready == pc ){ if( pi != prepi ){ /* postpone for serialize, * relay as half-dup as possible */ continue; } } fi = pxv[pi]; if( pi != prepi ){ if( dobreak ){ /* syslog_ERROR("## EXIT relaysx: %d\n",dobreak); */ fj = pxv[0<prepi?prepi:0]; syslog_ERROR("## EXIT relaysx: break=%d %d [%d] %d/%d\n", dobreak,RELAY_num_turns,fj,rccs[fj],cntv[fj]); goto EXIT; } RELAY_num_turns++; packs = 0; } if( RELAY_max_packintvl ){ if( pi == prepi ){ double intvl; intvl = Time() - Lastin[fi]; if( RELAY_max_packintvl < intvl ){ if( RELAY_num_turns <= 5 ){ syslog_ERROR("## %d[%d] max-intvl(%d)<%d\n", RELAY_num_turns,pi,(int)(1000*RELAY_max_packintvl),(int)(1000*intvl)); syslog_ERROR("## %d[%d] max-intvl<%d\n", RELAY_num_turns,pi,(int)(1000*intvl)); }else { RELAY_packintvl = intvl; dobreak = 1; /* syslog_ERROR("## EXIT relaysx: max-intvl<%d\n", (int)(1000*intvl)); */ fj = pxv[0<prepi?prepi:0]; syslog_ERROR("## EXIT relaysx: max-intvl<%d %d [%d] %d/%d\n", (int)(1000*intvl),RELAY_num_turns,fj,rccs[fj],cntv[fj]); } } }else{ if( dobreak ) goto EXIT; } } if( RELAY_max_turns && pi != prepi ){ if( Now-Start < RELAY_thru_time ){ }else if( RELAY_max_turns < RELAY_num_turns ){ syslog_ERROR("## EXIT relaysx: max_turns=%d\n", RELAY_num_turns); goto EXIT; } } prepi = pi; pushed = 0 <= top_fd(sdv[fi][0],0); rcode = (*funcv[fi])(argv[fi],sdv[fi][0],sdv[fi][1],&rcc,&wcc); Lastin[fi] = Time(); /* rccs[fi] += wcc; */ rccs[fi] += rcc; wccs[fi] += wcc; cntv[fi] += 1; packs += 1; if( RELAY_half_dup /* && RELAY_ssl_only */ ){ CStr(spack,32); unsigned char *up = (unsigned char*)lastpack; sprintf(spack,"%2X %2X %2X %2X %2X", up[0],up[1],up[2],up[3],up[4]); syslog_DEBUG("%2d.%d %2d->%2d %4d [%s]\n", RELAY_num_turns,packs, sdv[fi][0],sdv[fi][1],rcc, spack); /* the first packet in the turn of the side * must begin with a heaer of a SSL frame. * (CONNECT for STARTTLS on HTTP might be * allowed...) */ if( RELAY_ssl_peek || RELAY_ssl_only ){ if( RELAY_ssl_peek ){ /* new-140518b */ syslog_ERROR("SSL %2d.%d [%d]->[%d] %4d [%s]\n", RELAY_num_turns,packs, sdv[fi][0],sdv[fi][1],rcc, spack); } if( packs == 1 && 5 <= lastpackLeng ){ /* if( 0x20 < up[0] && up[0] != 0x80 ){ */ if( isSSLrecord(up,spack,lastpackLeng,pfv[fi]) < 0 ){ if( RELAY_ssl_only ){ /* mod-140518a */ syslog_ERROR("## EXIT relaysx: non-SSL [%s]\n", spack); dobreak = 2; } } } lastpackLeng = 0; if( RELAY_half_dup ){ int s1 = sdv[fi][0]; if( concat(relayCtrl,s1,nx,tl,rcode,nready) ){ nx++; tl += rcode; goto RELAY1; } } } } if( pushed && rcode == -1 && errno == EAGAIN ){ syslog_ERROR("## relaysx() pop_fd:%d\n", sdv[fi][0]); }else if( rcode <= 0 ){ syslog_ERROR( "relays[%d]: [%d->EOF] %d(%di+%do)\n", fi,fds[fi],rcode,rcc,wcc); if( sdx == NULL || (sdx[fi] & IGN_EOF) == 0 ) goto EXIT; else errv[fi] = 1; } } } } EXIT: for( fi = 0; fi < sdc; fi++ ) syslog_ERROR("relays[%d]: [%d->%d] %d bytes / %d -> %d\n",fi, sdv[fi][0],sdv[fi][1],rccs[fi],cntv[fi],wccs[fi]); /* syslog_ERROR("relays[%d]: [%d->%d] %d bytes / %d\n",fi, sdv[fi][0],sdv[fi][1],rccs[fi],cntv[fi]); */ return 0; }
void TcpStream::onInput(IODevice&) { inputReady(*this); }