Exemplo n.º 1
0
int connectTOX(int sock,SAP addr,int leng,int timeout,PVStr(cstat))
{	int rcode;
	int ri;
	double Start = Time();
	int delay;
	int poolN;

	/* 9.8.2 trial to avoid too slow connect() ... */
	/*
	int expsockbuf(int sock,int in,int out);
	int set_keepalive(int sock,int on);
	void setsockREUSE(int sock,int onoff);
	int setsockSHARE(int sock,int onoff);
	if( isWindowsCE() ){
		set_keepalive(sock,1);
		//expsockbuf(sock,8*1024,8*1024);
		setsockREUSE(sock,1);
		setsockSHARE(sock,1);
	}
	*/

	poolN = sockPoolN;
	LOGX_tcpCon++;
	rcode = connectTO1(sock,addr,leng,timeout,BVStr(cstat));
	if( rcode == 0 ){
		LOGX_tcpConSuccess++;
		delay = (int)((Time()-Start)*1000);
		LOGX_tcpConDelays += delay;
		if( LOGX_tcpConDelayMax < delay )
			LOGX_tcpConDelayMax = delay;

		if( lCONNQUE() )
		if( sockPoolN <= poolN )
		{
			int nsock,nrcode;
			nsock = dupSocket(sock);
			setNonblockingIO(nsock,1);
			nrcode = connect(nsock,addr,leng);
			setNonblockingIO(nsock,0);
			putConnSocket(sock,nsock,addr,leng,"queued",nrcode);
		}
	}
	if( rcode != 0 ){
		switch( errno ){
		  case ECONNREFUSED:
		  case EFAULT:
			/* should be the default */
			break;
		  case EHOSTUNREACH:
		  case ENETUNREACH:
		  default:
			rcode = dialup(sock,addr,leng,timeout,BVStr(cstat),rcode);
			break;
		}
	}
	return rcode;
}
Exemplo n.º 2
0
static int dialup(int sock,SAP addr,int leng,int timeout,PVStr(cstat),int rcode){
	int serrno = errno;
	int ccode;
	int nrcode;
	int nerrno;
	int nsock;
	int ri;

	if( !isWindowsCE() ){
		return -1;
	}

	nsock = dupSocket(sock);
	ccode = dialupTOX("CONNECT",sock,addr,leng,timeout,BVStr(cstat));
	if( 0 ){ // no dialup
		goto EXIT;
	}
	setNonblockingIO(nsock,1);
	for( ri = 0; ri < 10; ri++ ){
		nrcode = connect(nsock,addr,leng);
		if( errno == EISCONN ){
			nrcode = 0;
			serrno = 0;
			rcode = 0;
			break;
		}
		if( nrcode == 0 )
			break;
		nerrno = errno;
		msleep(500);
	}
	setNonblockingIO(nsock,0);
	if( nrcode == 0 ){
		dup2(nsock,sock);
		serrno = nerrno;
		rcode = 0;
	}
EXIT:
	close(nsock);
	errno = serrno;
	return rcode;
}
Exemplo n.º 3
0
void SetNonblockingIO(PCStr(what),int sock,int on)
{	int onbio,nnbio;

	if( sock < 0 )
		return;

	onbio = getNonblockingIO(sock);
	setNonblockingIO(sock,on);
	nnbio = getNonblockingIO(sock);
	if( onbio != nnbio )
		syslog_DEBUG("NBIO[%s][%d] %d -> %d\n",what,sock,onbio,nnbio);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
void notify_ADMINX(Connection *xConn,PCStr(admin),PCStr(what),PCStr(body))
{   FILE *tmp;
    FILE *bt;
    Connection ConnBuff,*Conn = &ConnBuff;
    CStr(head,1024);
    CStr(me,128);
    CStr(date,128);
    CStr(load,128);
    CStr(cwd,1024);
    CStr(uname,128);
    int now;
    const char *bugbox = "*****@*****.**";
    CStr(msgid,1024);
    CStr(buf,1024);

    if( strncasecmp(what,"sig",3) != 0 )
        if( strncasecmp(what,"failed",6) != 0 )
            if( strncasecmp(what,"modified",8) != 0 )
                if( strncasecmp(what,"approved",8) != 0 )
                    if( strncasecmp(what,"detected",8) != 0 )
                        if( strncasecmp(what,"[",1) != 0 ) /* abort in child process */
                            return;

    if( admin == NULL || *admin == 0 )
        admin = getADMIN1();

    now = time(NULL);
    if( xConn )
        *Conn = *xConn;
    else	bzero(Conn,sizeof(Connection));
    tmp = TMPFILE("NOTIFY");

    head[0] = 0;
    if( gethostname(me,sizeof(me)) != 0 )
        strcpy(me,"?");
    sprintf(msgid,"%d.%d.%d@%s",getpid(),itime(0),getuid(),me);

    StrftimeLocal(AVStr(date),sizeof(date),TIMEFORM_RFC822,now,0);
    Xsprintf(TVStr(head),"Subject: DeleGate-Report: %s\r\n",what);
    Xsprintf(TVStr(head),"From: [%d]@%s\r\n",getuid(),me);
    Xsprintf(TVStr(head),"To: %s (DeleGate ADMIN)\r\n",admin);
    Xsprintf(TVStr(head),"Reply-To: %s\r\n",bugbox);
    Xsprintf(TVStr(head),"Date: %s\r\n",date);
    Xsprintf(TVStr(head),"Message-Id: <%s>\r\n",msgid);
    Xsprintf(TVStr(head),"Content-Type: text/plain\r\n");
    fprintf(tmp,"%s\r\n",head);
    fprintf(tmp,"PLEASE FORWARD THIS MESSAGE TO <%s>.\r\n",bugbox);
    fprintf(tmp,"IT WILL BE HELPFUL FOR DEBUGGING.\r\n");
    fprintf(tmp,"\r\n");
    fprintf(tmp,"%s",head);
    fprintf(tmp,"Event: %s\r\n",what);
    Uname(AVStr(uname));
    fprintf(tmp,"Version: %s (%s)\r\n",DELEGATE_verdate(),uname);
    fprintf(tmp,"Host: %s\r\n",me);
    fprintf(tmp,"Owner: uid=%d/%d, gid=%d/%d\r\n",
            geteuid(),getuid(),getegid(),getgid());
    StrftimeLocal(AVStr(date),sizeof(date),TIMEFORM_RFC822,START_TIME,0);
    fprintf(tmp,"Started: %s\r\n",date);
    fprintf(tmp,"Pid: %d\r\n",getpid());
    cwd[0] = 0;
    IGNRETS getcwd(cwd,sizeof(cwd));
    fprintf(tmp,"Cwd: %s\r\n",cwd);
    strfLoadStat(AVStr(load),sizeof(load),"%L (%l)",now);
    fprintf(tmp,"Load: %s\r\n",load);
    fprintf(tmp,"Stack: %X %d/%d\r\n",p2i(STACK_PEAK),ll2i(STACK_BASE-STACK_PEAK),
            STACK_SIZE);
    fprintf(tmp,"\r\n");

    if( iamServer() ) {
    } else {
        fprintf(tmp,"Client-Proto: %s\r\n",CLNT_PROTO);
        fprintf(tmp,"Client-Host: %s:%d\r\n",Client_Addr(buf),Client_Port);
        if( TeleportHost[0] )
            fprintf(tmp,"Rident-Host: %s:%d..%s:%d\r\n",TelesockHost,TelesockPort,
                    TeleportAddr,TeleportPort);
        fprintf(tmp,"\r\n");
    }
    fprintf(tmp,"%s\r\n",body);

    /*
    	if( strncasecmp(what,"sig",3) == 0 || *what == '[' ){
    */
    if( strncasecmp(what,"sig",3) == 0
            || strncasecmp(what,"failed",6) == 0
            || *what == '[' ) {
        fprintf(tmp,"--iLog--begin\r\n");
        iLOGdump1(tmp,0);
        fprintf(tmp,"--iLog--end\r\n");

        fprintf(tmp,"\r\n");
        fprintf(tmp,"--AbortLog--begin\r\n");
        putAbortLog(tmp);
        fprintf(tmp,"--AbortLog--end\r\n");
    }

    if( strncasecmp(what,"sig",3) == 0 ) {
        int btout[2];
        double Start = Time();
        int rcc;

        fprintf(tmp,"\r\n");
        fprintf(tmp,"--BackTrace--begin\r\n");
        fflush(tmp);

        if( pipe(btout) == 0 ) {
            setNonblockingIO(btout[1],1);
            bt = fdopen(btout[1],"w");
            putBackTrace(bt);
            fclose(bt);
            bt = fdopen(btout[0],"r");
            rcc = file_copyTimeout(bt,tmp,NULL,128*1024,NULL,15);
            fclose(bt);
            sv1log("BatckTrace: %dB / %.1fs\n",rcc,Time()-Start);
        } else {
            bt = TMPFILE("BackTrace");
            putBackTrace(bt);
            fseek(bt,0,0);
            copyfile1(bt,tmp);
            fclose(bt);
        }
        fprintf(tmp,"\r\n");
        fprintf(tmp,"--BackTrace--end\r\n");
    }

    fflush(tmp);
    fseek(tmp,0,0);
    if( curLogFp() ) {
        CStr(line,1024);
        while( fgets(line,sizeof(line),tmp) != NULL )
            fprintf(curLogFp(),"--ABORT-- %s",line);
        fseek(tmp,0,0);
    }
    Conn->co_mask = (CONN_NOPROXY | CONN_NOMASTER);
    sendmail1(Conn,admin,admin,tmp,NULL);
    fclose(tmp);
}