int connectToX(PCStr(addr),int port,int delayms,int infd) { int rcode,sock,nready,fdv[2],qev[2],rev[2]; double Start1; CStr(stat,64); Start1 = Time(); nready = rev[0] = rev[1] = 0; sock = Socket1("SMTP-CB", -1,NULL,NULL,NULL, VStrNULL,0, NULL,0, 0,NULL,0); if( sock < 0 ){ rcode = -1; goto EXIT; } if( connectTimeout(sock,addr,port,1) == 0 ){ rcode = 0; goto EXIT; } Start1 = Time(); fdv[0] = infd; qev[0] = PS_IN; fdv[1] = sock; qev[1] = PS_OUT|PS_PRI; nready = PollInsOuts(delayms,2,fdv,qev,rev); if( nready <= 0 ){ rcode = -2; goto EXIT; } if( (rev[1] & PS_OUT) == 0 ){ rcode = -3; goto EXIT; } if( IsAlive(sock) ){ rcode = 0; goto EXIT; } rcode = -4; EXIT: if( rcode != 0 ){ if( 0 <= sock ){ close(sock); sock = -1; } } sprintf(stat,"%d[%d %s %s]", sock, sock_isconnected(sock), IsConnected(sock,NULL)?"Connected":"-", IsAlive(sock)?"Alive":"-"); sv1log("#CToX%d %s %s:%d %d[%o][%o] %s %dms\n", rcode,rcode==0?"OK":"ERR", addr,port, nready,rev[0],rev[1], stat,(int)(1000*(Time()-Start1))); return sock; }
int xi_lpx_isconnected(xi_socket_t so) { #ifdef __KPI_SOCKET__ return sock_isconnected(so); #else int retval; int s; thread_funnel_set(network_flock, TRUE); s = splnet(); retval = (so->so_state & SS_ISCONNECTED) != 0; splx(s); (void) thread_funnel_set(network_flock, FALSE); return retval; #endif }
int connectTO1(int sock,SAP addr,int leng,int timeout,PVStr(cstat)) { int NB; int rcode; int nready; int serrno; double Start = Time(); int csock; int pending = 0; if( 0 <= getConnSocket(sock,addr,leng,&csock,&pending) ){ dup2(csock,sock); close(csock); LOGX_tcpConPrefOk++; sprintf(cstat,"Prf"); return 0; } if( timeout == 0 ) { rcode = connect(sock,addr,leng); if( rcode != 0 ){ switch( errno ){ case ECONNREFUSED: case ENETUNREACH: case EHOSTUNREACH: LOGX_tcpConRefused++; break; default: LOGX_tcpConTimeout++; break; } } return rcode; } NB = getNonblockingIO(sock); if( NB < 0 ){ syslog_ERROR("connectTO: assume in non-blocking mode\n"); NB = 0; } if( !NB ) rcode = setNonblockingIO(sock,1); errno = 0; rcode = connect(sock,addr,leng); serrno = errno; if( rcode == 0 ){ if( !NB ) setNonblockingIO(sock,0); return 0; } if( errno == EISCONN ){ if( !NB ) setNonblockingIO(sock,0); return 0; } switch( errno ){ case ECONNREFUSED: case ENETUNREACH: case EHOSTUNREACH: syslog_ERROR("## connect[%d] refused (%d)\n",sock,errno); LOGX_tcpConRefused++; return -1; } nready = 0; if( lCONNPARA() && 0 < SLOW_CONN && SLOW_CONN < timeout ){ /* should poll pending connect() too ... */ if( pending ){ } nready = PollOut(sock,SLOW_CONN); if( nready == 0 ){ if( pending && 0 <= getConnSocket(sock,addr,leng,&csock,&pending) ){ putConnSocket(sock,dup(sock),addr,leng,"pending",rcode); dup2(csock,sock); close(csock); LOGX_tcpConParaOk++; sprintf(cstat,"Pnd"); }else if( PCON_PERSERV < pending ){ /* don't make too many pending connect() to a server */ }else{ int nsock; nsock = dupSocket(sock); if( 0 <= nsock ){ int rdv[2]; if( !NB ) setNonblockingIO(nsock,1); errno = 0; rcode = connect(nsock,addr,leng); LOGX_tcpConParaTried++; if( rcode == 0 ){ nready = 9; }else{ int skv[2]; skv[0] = sock; skv[1] = nsock; nready = PollOuts(timeout-SLOW_CONN,2,skv,rdv); timeout = 1; } if( nready == 9 || 0 < nready && rdv[0] == 0 && 0 < rdv[1] ){ putConnSocket(sock,dup(sock),addr,leng,"overtook",rcode); dup2(nsock,sock); close(nsock); LOGX_tcpConParaOk++; sprintf(cstat,"Ovr"); porting_dbg("## para.conn.%d %d/%d+%d %.2f %d", nready, LOGX_tcpConParaOk,LOGX_tcpConParaTried, LOGX_tcpConSuccess,Time()-Start,errno); }else{ putConnSocket(nsock,nsock,addr,leng,"unused",rcode); } } } } } if( !NB ) setNonblockingIO(sock,0); if( nready == 0 ){ nready = PollOut(sock,timeout); } /* 9.8.0 get appropriate errno by SO_ERROR in non-blocking connect */ /* if( serrno == EINPROGRESS ){ */ if( serrno == EINPROGRESS || serrno == EWOULDBLOCK /* 9.8.2 Windows returns this */ ){ int err = 0; int len = sizeof(err); if( getsockopt(sock,SOL_SOCKET,SO_ERROR,&err,&len) == 0 ){ syslog_DEBUG("connect[%d] ready=%d, err=%d\n", sock,nready,err); if( err != 0 ) if( err != ECONNREFUSED ) porting_dbg("[%X][%u] connectTO rdy=%d err=%d/%d/%d GOT %d/%d %s %.2f/%d", TID,getppid(),nready,serrno,EWOULDBLOCK,EINPROGRESS,err,len, VSA_ntoa((VSAddr*)addr),Time()-Start,timeout); switch( err ){ case ECONNREFUSED: case ENETUNREACH: case EHOSTUNREACH: errno = err; LOGX_tcpConRefused++; return -1; } } else{ /* fprintf(stderr,"-- %X connectTO rdy=%d err=%d/%d/%d NG errno=%d\n", TID,nready,serrno,EWOULDBLOCK,EINPROGRESS,errno); */ } } if( nready <= 0 ){ if( *cstat == '-' ){ /* ( ConnectFlags & COF_TERSE ) */ }else syslog_ERROR("## connect[%d] TIMEOUT(%d) e%d\n",sock,timeout,serrno); errno = ETIMEDOUT; LOGX_tcpConTimeout++; return -1; } if( !sock_isconnected(sock) ){ msleep(10); if( !sock_isconnected(sock) ){ syslog_ERROR("## connect[%d] failure (%d)\n",sock,errno); errno = ETIMEDOUT; LOGX_tcpConTimeout++; return -1; } else{ syslog_ERROR("## connect[%d] delayed success\n",sock); } } return 0; }
static int getConnSocket(int sock,SAP addr,int leng,int *rcsock,int *pending){ int si; int csi = -1; SockPool *sp; int got_csock = -1; double Now = Time(); double Age = 0; static int getOk; static int getNg; int rcode = -1; setupCSC("getConnSocket",sockCSC,sizeof(sockCSC)); enterCSC(sockCSC); *pending = 0; for( si = 0; si < elnumof(sockPool); si++ ){ sp = &sockPool[si]; if( sp->sp_Time == 0 ) continue; if( PCON_TIMEOUT < Now - sp->sp_Time ){ LOGX_tcpConAbandon2++; abandon(sp,1); continue; } if( sp->sp_leng != leng ){ continue; } if( bcmp(addr,&sp->sp_addr,leng) != 0 && VSA_addrcomp((VSAddr*)addr,&sp->sp_addr) != 0 ){ continue; } rcode = sp->sp_rcode; if( rcode == RCODE_RECYC ){ if( /* HTTP && */ inoutReady(sp->sp_sock,1) || !sock_isconnected(sp->sp_sock) ){ getNg++; /* porting_dbg("--getConnSock(%d/%d) age=%.2f [%d] NO-R %d:%d", si,sockPoolN,Now-sp->sp_Time,sp->sp_sock,getNg,getOk); */ LOGX_tcpConAbandon3++; abandon(sp,2); continue; } LOGX_tcpConRecycleOk++; }else{ if( inoutReady(sp->sp_sock,2) == 0 ){ if( PCON_TIMEOUT < Now - sp->sp_Time ){ porting_dbg("--getConnSock(%d/%d)%s age=%.2f [%d] NO-A", si,sockPoolN,sp->sp_what,Now-sp->sp_Time,sp->sp_sock); LOGX_tcpConAbandon4++; abandon(sp,3); }else{ *pending += 1; } continue; } if( !sock_isconnected(sp->sp_sock) ){ porting_dbg("--getConnSock(%d/%d)%s age=%.2f [%d] NO-B", si,sockPoolN,sp->sp_what,Now-sp->sp_Time,sp->sp_sock); LOGX_tcpConAbandon4++; abandon(sp,3); continue; } } getOk++; if( rcode != RCODE_RECYC ) porting_dbg("--getConnSock(%d/%d)%s age=%.2f [%d] OK (%d)", si,sockPoolN,sp->sp_what,Now-sp->sp_Time,sp->sp_sock,getOk); syslog_ERROR("--getConnSock(%d/%d)%s age=%.2f [%d] OK (%d)\n", si,sockPoolN,sp->sp_what,Now-sp->sp_Time,sp->sp_sock,getOk); Age = Now - sp->sp_Time; sp->sp_Time = 0; sockPoolN--; csi = si; got_csock = sp->sp_sock; break; } leaveCSC(sockCSC); if( got_csock < 0 ){ return -1; } if( rcode != RCODE_RECYC ) porting_dbg("--getConnSocket(%d)[%d]>>>%d[%d]", sockPoolN,sock,csi,got_csock); setfdowner(got_csock,getthreadid(),getthreadgid(0)); *rcsock = got_csock; syslog_ERROR("--getConnSocket([%d]%d)<-[%d]%d %.2f (%d)\n", sock,SocketOf(sock),got_csock,SocketOf(got_csock), Age,*pending); return 0; }