Exemple #1
0
static scanListFunc vsap1(PCStr(vsap))
{	CStr(host,MaxHostNameLen);
	int port;
	CStr(methods,256);
	int ri;

	if( 8 <= serverX ){
		daemonlog("F","VSAP[%d] %s -- ignored too many conf.\n",
			serverX,vsap);
		return -1;
	}

	host[0] = 0;
	port = 0;
	methods[0] = 0;
	Xsscanf(vsap,"%[^:/]%*[:/]%d%*[/:]%s",AVStr(host),&port,AVStr(methods));
	daemonlog("E","VSAP[%d] %s:%d\n",serverX,host,port);

	serverV[serverX].r_host = stralloc(host);
	serverV[serverX].r_port = port;
	serverV[serverX].r_hostport = stralloc(vsap);

	if( methods[0] == 0 ){
		serverV[serverX].r_methods = FOR_CONNECT | FOR_ACCEPT; 
	}else{
		if( strstr(methods,"CONNECT") )
			serverV[serverX].r_methods |= FOR_CONNECT;
		if( strstr(methods,"ACCEPT") )
			serverV[serverX].r_methods |= FOR_ACCEPT;
		if( isinListX(methods,"HTTP","c") )
			serverV[serverX].r_methods |= FOR_HTALL;
	}
	serverX++;
	return 0;
}
Exemple #2
0
void Abort(int code,PCStr(fmt),...){
	const char *body = 0;
	VARGS(8,fmt);

	setgotsigTERM(99);
	if( errno == ENOMEM ){
		body = "#### EXIT on insufficient memory, exceeded data or stack limitation, or exausted swap space. ####";
		daemonlog("F","%s\n",body);
	}
	daemonlog("F",fmt,VA8);

	if( code == 0 ){
		Connection *Conn = curClient.cl_Conn;
		Connection ConnBuf;
		CStr(reason,256);
		const char *dp;

		if( Conn == NULL ){
			Conn = &ConnBuf;
			bzero(Conn,sizeof(Conn));
		}
		sprintf(reason,fmt,VA8);
		if( dp = strpbrk(reason,"\r\n") )
			truncVStr(dp);
		notify_ADMINX(Conn,getADMIN1(),reason,body);
		Finish(-1);
	}else{
		abort();
	}
}
Exemple #3
0
static int SockPrintf(int sock,PCStr(fmt),...)
{	CStr(msg,1024);
	int wcc;
	VARGS(8,fmt);

	sprintf(msg,fmt,VA8);
	wcc = write(sock,msg,strlen(msg));
	daemonlog("D","I-SAY: %s",msg);
	return wcc;
}
Exemple #4
0
static void closeSvSocks()
{	int fi,svsock;

	for( fi = 1; fi <= SvSockN; fi++ ){
		svsock = SvSocks[fi].a_sock;
		close(svsock);
		del_svsock(svsock);
		daemonlog("D","## close SVSOCK %d\n",svsock);
	}
	SvSockN = 0;
}
Exemple #5
0
static void __BtLog(const char *fmt,...) {
    CStr(msg,64);
    double Lap = Time()-dStart;
    VARGS(8,fmt);

    sprintf(msg,fmt,VA8);
    daemonlog("F","## %.3f %s\n",Lap,msg);
    fprintf(dout,"[%d] ## %.3f %s\n",getpid(),Lap,msg);
    fflush(dout);
    fprintf(stderr,"[%d] ## %.3f %s\n",getpid(),Lap,msg);
}
Exemple #6
0
static void lprintf(PCStr(fmt),...){
	CStr(msg,1024);
	IStr(peer,MaxHostNameLen);
	IStr(host,MaxHostNameLen);
	VARGS(8,fmt);

	printf(fmt,VA8);
	getpairName(0,AVStr(host),AVStr(peer));
	sprintf(msg,"[%s][%s] ",peer,host);
	Xsprintf(TVStr(msg),fmt,VA8);
	daemonlog("F","%s",msg);
}
Exemple #7
0
int CTX_VSAPconnect(Connection *Conn,PVStr(sockname),PVStr(peername))
{	CStr(resp,1024);
	int rsock;
	int cid;
	int acode;

	rsock = open_vsap(Conn,FOR_HTCONNECT);
	if( 0 <= rsock ){
		rsock = ConnectViaHTTP(Conn,rsock,0,
			BVStr(sockname),BVStr(peername));
		if( 0 <= rsock ){
			goto EXIT;
		}
		return -1;
	}
	rsock = open_vsap(Conn,FOR_CONNECT);
	if( rsock < 0 )
		return -1;
	if( elnumof(Socknames) <= rsock ){
		close(rsock);
		return -1;
	}


	if( sockname[0] != 0 ){
		SockPrintf(rsock,"%s BIND %s\r\n",VER,sockname);
		RecvLine(rsock,resp,sizeof(resp));
	}

	SockPrintf(rsock,"%s CONNECT %s\r\n",VER,peername);
	if( RecvLine(rsock,resp,sizeof(resp)) <= 0 ){
		close(rsock);
		return -1;
	}
	daemonlog("D","VSAPd says: %s",resp);
	if( !resp_OK(resp) ){
		close(rsock);
		return -1;
	}

	SockPrintf(rsock,"RELAY\r\n");
	Xsscanf(resp,"%*s %*d %d %s %s connected.",&cid,AVStr(sockname),AVStr(peername));

EXIT:
	sv1log("-- VSAPconnect[%d][%s][%s]\n",rsock,sockname,peername);
	Socknames[rsock] = stralloc(sockname);
	Peernames[rsock] = stralloc(peername);
	return rsock;
}
Exemple #8
0
static int intcom(PCStr(arg),int src,int dst,int *rccp,int *wccp)
{	int rcc,wcc,rcode;
	CStr(req,1024);

	daemonlog("E","## intcom: %d->d\n",src,dst);
	rcc = RecvLine(src,req,sizeof(req));
	if( rcc <= 0 )
		return -1;
	if( rccp ) *rccp = rcc;
	rcode = 0;
	wcc = SockPrintf(dst,"%s %d interrupted by \"%s\"",VER,OK_ACCEPT,req);
	if( strncasecmp(req,"BREAK",5) == 0 )
		rcode = -1;
	return rcode;
}
Exemple #9
0
static FILE *stopServ(PCStr(what),PCStr(mode),PCStr(host))
{	CStr(path,1024);
	FILE *fp;

	if( host == 0 )
		return 0;

	sprintf(path,"%s/%s",SHUTOUT,host);
	DELEGATE_substfile(AVStr(path),"",VStrNULL,VStrNULL,VStrNULL);
	fp = dirfopen(what,AVStr(path),mode);
	if( fp == NULL )
		return 0;
	daemonlog("F","#### %s [%s]\n",what,path);
	return fp;
}
Exemple #10
0
int open_vsap(Connection *Conn,int method)
{	int rsock;
	int ri;
	const char *host;
	int port;

	if( serverX == 0 )
		return -1;

	rsock = -1;
	for( ri = 0; ri < serverX; ri++ ){
		if( acceptedViaVSAP == 0 )
			if( (serverV[ri].r_methods & method) == 0 )
				continue;
		if( method == FOR_HTACCEPT )
		if( serverV[ri].r_methods & FOR_HTACCEPT ){
			return 1;
		}
		host = serverV[ri].r_host;
		port = serverV[ri].r_port;
		rsock = -1;
		if( method & (FOR_HTBIND|FOR_HTCONNECT) ){
			rsock = connectViaUpper(Conn,"VSAP","http",host,port);
		}
		if( rsock < 0 )
		rsock = Socket1("VSAP",NEWSOCK,VStrANYPORT,host,port,0,NULL,0);
		if( 0 <= rsock )
			break;
	}
	if( method & (FOR_HTCONNECT|FOR_HTBIND|FOR_HTACCEPT) ){
		return rsock;
	}
	if( 0 <= rsock ){
		const char *auth;
		CStr(authb,256);
		if( get_MYAUTH(Conn,AVStr(authb),"vsap",host,port) )
			auth = authb;
		else	auth = getenv("VSAP_AUTH");
		if( auth ){
			CStr(resp,256);
			SockPrintf(rsock,"%s AUTH %s\r\n",VER,auth);
			RecvLine(rsock,resp,sizeof(resp));
			daemonlog((char*)(resp_OK(resp)?"D":"E"),"## AUTH: %s",resp);
		}
	}
	return rsock;
}
Exemple #11
0
static int do_connect(int lsock,PCStr(rport),int toC)
{	CStr(host,MaxHostNameLen);
	int port;
	int clsock;
	CStr(sockname,MaxHostNameLen);
	CStr(peername,MaxHostNameLen);
	int wcc;
	int sockid;

	if( rport[0] == '/' ){
		clsock = client_open_un("vsap",rport,60);
		daemonlog("E","## CLPORT %s [%d]\n",rport,clsock);
		if( clsock < 0 ){
		wcc = SockPrintf(toC,"%s %d not connected\r\n",VER,NO_BIND);
		return -1;
		}
		strcpy(sockname,rport);
		strcpy(peername,rport);
		goto CONNECTED;
	}

	strcpy(host,"127.0.0.1");
	port = 0;
	if( strchr(rport,':') )
		Xsscanf(rport,"%[^:]:%d",AVStr(host),&port);
	else	sscanf(rport,"%d",&port);

	clsock = Socket1("VSAP",lsock,NULL,NULL,NULL,VStrANYPORT,host,port,0,NULL,0);
	if( clsock < 0 ){
		wcc = SockPrintf(toC,"%s %d cannot connect %s\r\n",
			VER,NO_CONNECT,rport);
		return -1;
	}
	getpairName(clsock,AVStr(sockname),AVStr(peername));

CONNECTED:
	sockid = add_clsock(clsock);
	wcc = SockPrintf(toC,"%s %d %d %s %s connected.\r\n",
		VER,OK_CONNECT,sockid,sockname,rport);

	return clsock;
}
Exemple #12
0
static int wait_thread(int tid,int timeout){
	double St;
	int xtid,rcc,xi,wcc;
	int xtids[128];
	int xtidn = 0;
	int rcode;

	if( ThreadsWaitTO == 0 || ThreadsDone[0] < 0 ){
		return 0;
	}

	St = Time();
	rcode = -1;
	WaitingThreads++;
	for(;;){
		if( PollIn(ThreadsDone[0],timeout) == 0 ){
			daemonlog("F","thread_wait(%X,%d) timeout\n",
				tid,timeout);
			break;
		}
		xtid = -1;
		rcc = read(ThreadsDone[0],&xtid,sizeof(xtid));
		if( lTHREAD() ){
			syslog_ERROR("thread_wait(%X) = %d %X %d/%d\n",
				tid,rcc,xtid,(int)(1000*(Time()-St)),timeout);
		}
		if( xtid == tid ){
			rcode = 0;
			break;
		}
		xtids[xtidn++] = xtid;
	}
	if( 0 < xtidn ){
		for( xi = 0; xi < xtidn; xi++ ){
			xtid = xtids[xi];
			wcc = write(ThreadsDone[1],&xtid,sizeof(tid));
		}
	}
	WaitingThreads--;
	return rcode;
}
/*
#define fork forkX
*/
int ForkY(PCStr(what),int (*xproc)(const char *what,int xpid))
{   register int pid;

    endhostent();
    MyPID = 0;
    pid = fork();

    if( xproc )
        if( pid == -1 && errno == EAGAIN ) {
            int fi,xi,xn = 0,xid = 0;
            for( fi = 0; fi < 30 && pid < 0 && errno == EAGAIN; fi++ ) {
                usleep((100+fi*10)*1000);
                if( 0 < (xi = NoHangWait()) ) {
                    xid = xi;
                    xn++;
                    if( (*xproc)(what,xi) != 0 )
                        break;
                }
                pid = fork();
            }
            if( pid != 0 ) {
                fprintf(stderr,"----[%d] Fork(%s) AGAIN(%d/%d/%d)=%d\n",
                        getpid(),what,fi,xn,xid,pid);
            }
        }
    if( pid == -1 ) {
        /*
        syslog_ERROR("-- FAILED fork(%s), errno=%d\n",what,errno);
        */
        daemonlog("F","-- FAILED fork(%s), errno=%d\n",what,errno);
    } else if( pid == 0 ) {
        syslog_ERROR("-- Fork(%s): %d -> %d\n",what,getppid(),MyPID);
    }
    else {
        if( lTRVERB() )
            if( doTracePid == getpid() )
                TraceLog("+ Fork(%s) = %d\n",what,pid);
    }
    return pid;
}
Exemple #14
0
static int getStopService(Connection *Conn,PCStr(addr))
{	FILE *fp;
	int mtime,now;

	if( lSINGLEP() ){
		return 0;
	}
	fp = stopServ("getStopService","r",addr); 
	if( fp == NULL )
		return 0;
	mtime = file_mtime(fileno(fp));
	fclose(fp);
	if( SHUTOUT_TIMEOUT ){
		now = time(NULL);
		if( SHUTOUT_TIMEOUT < now-mtime ){
			daemonlog("F","#### getStopService: expired = %d > %d\n",
				now-mtime,SHUTOUT_TIMEOUT);
			return 0;
		}
	}
	return 1;
}
Exemple #15
0
static FILE *setStopService(PCStr(addr))
{
	/*
	daemonlog("F","####! EMERGENCY STOP !####\n");
	*/
	if( newthreads() || numthreads() || pnumthreads() ){
		extern const char *SSLstage;
		int getXf_list(PVStr(Xf));
		IStr(Xf,128);

		setgotsigTERM(999);
		getXf_list(AVStr(Xf));
		putfLog("####! thread-EMERGENCY-STOP !#### %X in (%s)(%s)(%s)",
			ismainthread(),Xf,SSLstage?SSLstage:"",PRTHstage);
		dumpThreads("thread-EMERGENCY-STOP");
	}
	daemonlog("F","####! EMERGENCY STOP !#### [%d.%X]%X %d/%d\n",
		getpid(),getthreadid(),ismainthread(),
		actthreads(),numthreads());

	return stopServ("setStopService","a",addr);
}
Exemple #16
0
void notify_overflow(PCStr(what),PCStr(buf),int off)
{   CStr(msg,1024);
    refQStr(mp,msg); /**/
    const char *mx;
    int ci,ch;

    mx = msg + (sizeof(msg)-1);
    mp = msg;
    for( ci = 0; ci < off; ci++ ) {
        if( mx <= mp )
            break;
        ch = buf[ci] & 0xFF;
        if( 0x40 <= ch && ch < 0x7F || ch == ' ' ) {
            setVStrPtrInc(mp,ch);
        } else {
            sprintf(mp,"%%%02X",ch);
            mp += 3;
        }
    }
    setVStrEnd(mp,0);
    daemonlog("F","#### Overflow: %s: %d: %s\n",what,off,msg);
}
Exemple #17
0
FILE *dgfopen(PCStr(what),PCStr(base),PCStr(rpath),PCStr(mode)){
	FILE *fp;
	CStr(npath,1024);
	CStr(xpath,1024);

	if( upath_off_limit(rpath,AVStr(npath)) ){
		daemonlog("F","%s: off limit (%s / %s)\n",what,base,rpath);
		return NULL;
	}
	sprintf(xpath,"%s",base);
	Substfile(xpath);
	if( *xpath && strtailchr(xpath) != '/' )
		strcat(xpath,"/");
	strcat(xpath,rpath);
	fp = dirfopen(what,AVStr(xpath),mode);
	/*
	if( fp == NULL ){
		daemonlog("F","%s: can't open(%s): %s\n",what,mode,xpath);
	}
	*/
	return fp;
}
Exemple #18
0
static int do_accept(PCStr(lport),PCStr(opts),int shared,int priobase,int fromC,int toC)
{	int shlock,exlock;
	CStr(shlockpath,1024);
	CStr(exlockpath,1024);
	CStr(host,1024);
	int port;
	const char *op;
	CStr(opt1,128);
	int rcode;
	int clsock;
	int wcc;
	CStr(sockname,MaxHostNameLen);
	CStr(peername,MaxHostNameLen);
	int fi,fdv[32],rfv[32],nready;
	int svsock;
	int priority,timeout;
	int start;

	clsock = -1;
	if( SvSockN < 1 ){
		SockPrintf(toC,"%s %d no socket to accept\r\n",VER,NO_ACCEPT);
		return -1;
	}

	/* repeat until accept succeed and authorization OK,
	 * while the client's connection is alive ...
	 */
	shlock = -1;
	host[0] = 0;
	port = 0;
	if( strchr(host,':') )
		Xsscanf(lport,"%[^:]:%d",AVStr(host),&port);
	else	sscanf(lport,"%d",&port);

	priority = 0;
	timeout = 0;
	for( op = wordScan(opts,opt1); *opt1; op = wordScan(op,opt1) ){
		if( strncmp(opt1,"-p=",3) == 0 ){
			priority = atoi(opt1+3);
		}else
		if( strncmp(opt1,"-t=",3) == 0 ){
			timeout = atoi(opt1+3);
		}else	break;
	}
	if( priobase == 0 )
		priority = 0;
	daemonlog("D","accept: priority=%d timeout=%d\n",priority,timeout);

	if( shared ){
		const char *ltype;
		int rem;
		start = time(0L);
		shlock = PortLocks(lport,2,AVStr(shlockpath));
		rcode = -1;
		for(;;){
			if( priority ){
				rcode = lock_exclusiveTO(shlock,1000,NULL);
				ltype = "exclusive";
			}else{	rcode = lock_sharedTO(shlock,1000,NULL);
				ltype = "shared";
			}
			if( !IsAlive(toC) ){
			daemonlog("E","## disconnected during LOCKing\n");
				goto EXIT;
			}
			if( rcode == 0 )
				break;
			if( timeout <= time(0L) - start )
				break;
		}
		rem = timeout - (time(0L) - start);
		if( rcode != 0 && rem <= 0 ){
		daemonlog("E","## accept: timedout during %s LOCKing (%d)\n",
				ltype,timeout);
			goto EXIT;
		}
		daemonlog("D","## accept: %s LOCKed (%d)\n",ltype,timeout-rem);
	}

	daemonlog("D","## START accept at %d (%d ports)\n",port,SvSockN);
	for(;;){
	RETRY:
		fdv[0] = fromC;
		for( fi = 1; fi <= SvSockN; fi++ ){
			fdv[fi] = SvSocks[fi].a_sock;
			if( !shared && 0 < bind_nlisten )
				Listen(fdv[fi],bind_nlisten);
		}

		nready = PollIns(timeout*1000,1+SvSockN,fdv,rfv);
		if( nready <= 0 )
			break;
		if( rfv[0] != 0 && !IsAlive(fromC) )
		{
			daemonlog("E","## disconnected during POLLing\n");
			break;
		}

		svsock = -1;
		for( fi = 1; fi <= SvSockN; fi++ ){
			if( rfv[fi] < 0 )
				goto EXIT;
			if( 0 < rfv[fi] ){
				svsock = fdv[fi];
				break;
			}
		}
		if( svsock < 0 )
			break;

/* not lport but the real port-number of svsock ? */
		exlock = PortLocks(lport,3,AVStr(exlockpath));
		start = time(0L);
		rcode = -1;
		for(;;){
			rcode = lock_exclusiveTO(exlock,1000,NULL);
			if( !IsAlive(toC) ){
			daemonlog("E","## disconnected during ACCEPT LOCKing\n");
				rcode = -1;
				break;
			}
			if( rcode == 0 )
				break;
			if( timeout <= time(0L) - start ){
			daemonlog("E","## timedout during ACCEPT LOCKing\n");
				lock_unlock(exlock);
				goto RETRY;
			}
		}
		if( rcode == 0 ){
			if( PollIn(svsock,1) <= 0 ){
			daemonlog("E","## be snatched during ACCEPT LOCKing\n");
				lock_unlock(exlock);
				goto RETRY;
			}else{
				clsock = ACCEPT(svsock,1,-1,timeout);
			}
		}

		if( !shared )
			closeSvSocks();

		if( 0 <= exlock )
			lock_unlock(exlock);

		if( 0 <= shlock ){
			lock_unlock(shlock);
			shlock = -1;
		}
		break;
	}

EXIT:
	if( !shared )
		closeSvSocks();

	if( 0 <= bind_exlock ){
		lock_unlock(bind_exlock);
		bind_exlock = -1;
	}

	if( clsock < 0 )
		daemonlog("D","## FAILED accept at %d\n",port);

	if( 0 <= shlock )
		lock_unlock(shlock);
	return clsock;
}
Exemple #19
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;
}
Exemple #20
0
int gzipFilterX(FILE *in,FILE *out,SyncXF syncf,void *sp,int si){
	gzFile gz;
	int len,rcc;
	CStr(buf,1024*8);
	int size;
	int gsize;
	int wcc;
	int bcc = 0;
	double Start = Time();
	double Prevf = 0;
	int ibz = sizeof(buf);
	int gi;
	int fd = -1;
	int ofd = fileno(out);
	int xfd;
	int zerr = 0;
	/*
	int rready = -1;
	*/

	errno = 0;
	fd = dup(fileno(out));
	if( fd < 0 ){
		syslog_ERROR("--gzipFilter[%d]<-[%d] errno=%d\n",fd,ofd,errno);
		return -1;
	}

	/*
	if( 0 <= GZIPready )
		rready = dup(GZIPready);
	*/
	len = 0;
	/*
	if( gz = GZdopen(dup(fileno(out)),"w") ){
	*/
	if( file_isSOCKET(ofd) || file_ISSOCK(ofd) )
	if( !IsConnected(ofd,NULL) || !IsAlive(ofd) ){

fprintf(stderr,"[%d.%X] gzip DISCONN\n",getpid(),getthreadid());
fprintf(stderr,"[%d.%X] gzip DISCONN fd[%d] con=%d isSOCK=%d,%d,%d\n",
getpid(),getthreadid(),ofd,IsConnected(ofd,NULL),
file_isSOCKET(ofd),file_ISSOCK(ofd),file_issock(ofd));

		sendsync(rready,1);
		close(fd);
		return -1;
	}
	gz = GZdopen(fd,"w");
	if( file_isSOCKET(ofd) || file_ISSOCK(ofd) )
	if( !IsConnected(ofd,NULL) || !IsAlive(ofd) ){

fprintf(stderr,"[%d.%X] gzip DISCONN gx=%d\n",getpid(),getthreadid(),p2i(gz));
fprintf(stderr,"[%d.%X] gzip DISCONN fd[%d] con=%d isSOCK=%d,%d,%d\n",
getpid(),getthreadid(),ofd,IsConnected(ofd,NULL),
file_isSOCKET(ofd),file_ISSOCK(ofd),file_issock(ofd));

		close(fd);
		sendsync(rready,2);
		close(fd);
		return -1;
	}

	if( gz ){
		LOGX_gzip++;
		if( Gzip_NoFlush ){
			GZDBG(stderr,"-- %X gzip flush disabled(%d)\n",
				TID,Gzip_NoFlush);
		}
		Prevf = Time();

		sendsync(rready,0);
		setCloseOnFork("GZIPstart",fd);
		/*
		while( rcc = fread(buf,1,sizeof(buf),in) ){
		*/
		for( gi = 0;; gi++ ){
			if( gotsigTERM("gzip gi=%d",gi) ){
				if( numthreads() && !ismainthread() ){
					thread_exit(0);
				}
				break;
			}
			if( !Gzip_NoFlush )
			if( bcc )
			if( 0 < len && finputReady(in,NULL) == 0 ){
				zerr =
				gzflush(gz,Z_SYNC_FLUSH);
if( zerr ){
porting_dbg("+++EPIPE[%d] gzflush() zerr=%d %d SIG*%d",fd,zerr,len,gotSIGPIPE());
}
				bcc = 0;
			}
			if( lSINGLEP() ) /* could be generic */
			{
				if( 0 < len )
				if( !Gzip_NoFlush
				 || 4 < gi && 5 < Time()-Prevf
				){
				GZDBG(stderr,"-- %X gzip flush %d(%f) %d/%d\n",
				TID,Gzip_NoFlush,Time()-Start,len,gi);
					Prevf = Time();
					zerr = gzflush(gz,Z_SYNC_FLUSH);
					bcc = 0;
					if( zerr ){
				GZDBG(stderr,"-- %X gzip gzflush()%d err=%d\n",
				TID,len,zerr);
						break;
					}
				}
			}
			/*
			rcc = fread(buf,1,sizeof(buf),in);
			*/
			rcc = xread(in,AVStr(buf),QVSSize(buf,ibz));

			if( rcc <= 0 ){
				break;
			}
			wcc =
			gzwrite(gz,buf,rcc);

//fprintf(stderr,"[%d] Gzwrite %d/%d / %d\n",getpid(),wcc,rcc,len);

if( wcc <= 0 ){
porting_dbg("+++EPIPE[%d] gzwrite() %d/%d %d SIG*%d",fd,wcc,rcc,len,gotSIGPIPE());
fprintf(stderr,"[%d] Gzwrite %d/%d / %d\n",getpid(),wcc,rcc,len);
break;
}

			if( wcc != rcc ){
				syslog_ERROR("gzwrite %d/%d\n",wcc,rcc);
			}
			if( 0 < wcc ){
				bcc += wcc;
			}
			if( sizeof(buf) <= len ){
				ibz = sizeof(buf);
			}
			if( !Gzip_NoFlush )
			if( bcc )
			if( sizeof(buf) <= bcc || len < 16*1024 ){
				zerr =
				gzflush(gz,Z_SYNC_FLUSH);
				bcc = 0;
			}
			if( zerr || gotSIGPIPE() ){
porting_dbg("+++EPIPE[%d] gzflush() zerr=%d %d SIG*%d",fd,zerr,len,gotSIGPIPE());
				break;
			}
			len += rcc;
		}
		if( len == 0 ){
			const char *em;
			int en;
			int ef;
			em = gzerror(gz,&en);
			ef = gzeof(gz);
			if( en == -1 /* see errno */ && errno == 0 ){
				/* no error */
			}else{
			daemonlog("F","FATAL: gzwrite(%d)=%d/%d eof=%d %d %s\n",
				fd,len,bcc,ef,en,em);
			porting_dbg("FATAL: gzwrite(%d)=%d/%d eof=%d %d %s",
				fd,len,bcc,ef,en,em);
			}
		}
		clearCloseOnFork("GZIPend",fd);
		gzflush(gz,Z_SYNC_FLUSH);
		xfd = dup(fd);
		gsize = GZtell(gz);
		GZclose(gz);
		if( isWindowsCE() || lMULTIST() ){
			/* duplicated close of fd is harmful */
		}else
		if( isWindows() ) close(fd); /* to clear osf-handle mapping */
		Lseek(xfd,0,2);
		size = Lseek(xfd,0,1);
		Lseek(xfd,0,0);
		close(xfd);
		syslog_DEBUG("(%f)gzipFilter %d -> %d / %d\n",Time()-Start,
			len,gsize,size);
		return len;
	}
	sendsync(rready,3);
	close(fd);
	return 0;
}
Exemple #21
0
int spawnFilter(Connection *Conn,int iomode,int tofil[],int sock,iFUNCP func,PCStr(args))
{	CStr(ein,32);
	int ac;
	const char *av[256]; /**/
	CStr(epath,1024);
	CStr(logtype,64);
	CStr(logtype2,64);
	int fin; /* input at the filter side */
	int fout; /* output at the DeleGate side */
	int pid;
	int wcc;
	int wi;
	int fio[2]; /* a pipe to inherit Conn. */
	FILE *out;
	SpawnArgs spawnArgs;

	iLog("--- spawnFilter sock=%d func=%X args=%X",sock,xp2i(func),p2i(args));
	fin = tofil[0];
	fout = tofil[1];
	pipeX(fio,8*1024);
	out = fdopen(fio[1],"w");
	sprintf(ein,"%d/%d/%d/%d %d/%d",fio[0],fio[1],fin,fout,
		CHILD_SERNO,CHILD_SERNO_MULTI);
	/*
	sprintf(ein,"%d/%d/%d/%d",fio[0],fio[1],fin,fout);
	*/
	/*
	sprintf(ein,"%d/%d",fin,fout);
	*/

	sprintf(epath,"%s=%s",P_EXEC_PATH,EXEC_PATH);
	ac = 0;
	av[ac++] = /*DeleGate1*/ "DeleGate";
	av[ac++] = /*FuncFILTER*/ "(Filter)";
	av[ac++] = ein;
	av[ac++] = epath;

	/*
	sprintf(logtype,"-L0x%x",LOG_type);
	*/
	sprintf(logtype,"-L0x%x/%d",LOG_type,curLogFd());
	av[ac++] = logtype;
	if( LOG_type2 || LOG_bugs ){
		sprintf(logtype2,"-L20x%x/%x",LOG_type2,LOG_bugs);
		av[ac++] = logtype2;
	}
	ac += copy_param("f",elnumof(av)-ac,&av[ac],&main_argv[1]);
	av[ac] = NULL;

	Conn->fi_func = func;
	if( args == NULL )
		Conn->fi_arglen = 0;
	else	Conn->fi_arglen = strlen(args)+1;
	Conn->fi_iomode = iomode;
	Conn->fi_logfd  = curLogFd();

	if( file_isreg(sock) ){
		/* it might be TMPFILE() with CloseOnExec flag set */
		clearCloseOnExec(sock);
	}
	Conn->fi_topeer = sock;
	Conn->fi_dupclsock = 0;
	if( Conn->fi_issock = file_ISSOCK(sock) ){
		setclientsock(sock);
		if( sock == ClientSock
		 || SocketOf(sock) == SocketOf(ClientSock) )
			Conn->fi_dupclsock = 1;
			
	}

	/* might be emulating spawn() on Unix */
	sigsetmask(sigblock(0) & ~sigmask(SIGHUP) );

	pid = Spawnvp("openFilter",EXEC_PATH,av);
	Verbose("## spawnFilter: %d -> %d\n",getpid(),pid);
	if( pid <= 0 ){
		/* 9.6.3 don't freeze in fwrite() to the pipe ... */
		fclose(out);
		close(fio[0]);
		daemonlog("F","spawnFilter: FAILED %d\n",pid);
		porting_dbg("--FATAL: spawnFilter: FAILED spawn %d",pid);
		putpplog("--FATAL: spawnFilter: FAILED spawn %d\n",pid);
		return pid;
	}

/*
	wcc = write(fout,Conn,sizeof(Connection));
	if( Conn->cl_reqbuf )
		write(fout,Conn->cl_reqbuf,Conn->cl_reqbufsize);
	if( args != NULL )
		write(fout,args,strlen(args)+1);
*/
	close(fio[0]); /* close here to get EPIPE on write(fio[1]) */

	if( MountOptions ){
		spawnArgs.sa_mountserno = MountSerno(MountOptions);
		spawnArgs.sa_moptslen = strlen(MountOptions)+1;
	}else{
		spawnArgs.sa_mountserno = 0;
		spawnArgs.sa_moptslen = 0;
	}
	wcc = fwrite(&spawnArgs,1,sizeof(spawnArgs),out);
	wcc = fwrite(Conn,1,sizeof(Connection),out);
	if( Conn->cl_reqbuf )
		fwrite(Conn->cl_reqbuf,1,Conn->cl_reqbufsize,out);
	if( args != NULL )
		fwrite(args,1,strlen(args)+1,out);
	if( MountOptions && spawnArgs.sa_moptslen ){
		fwrite(MountOptions,1,spawnArgs.sa_moptslen,out);
		setMountOptions(FL_ARG,Conn,0);
	}
	fclose(out);

	/* If the iomode == READ then
	 * must wait till the client finish to read the written environment
	 * not to read it by myself.
	 * (in the case of FFROMCL, payload data may be ready, but cannot
	 *  identify whether or not it is env. data or payload data ...)
	 * If the iomode == WRITE and filter is direct system-command then
	 * must wait not to make buffered data be not passed to the filter.
	 */
	/*
	if( iomode == 0 || iomode != 0 && 0 < PollIn(fin,1) ){
		sv1log("## wait the filter finish reading enviroment\n");
		msleep(100);
	}
	*/

	return pid;
}
Exemple #22
0
int STLS_error(Connection *Conn,int fromC){
	int fail = 0;
	int nready;
	char statb[2];
	/*
	char stat;
	*/
	int stat;
	FILE *fst;
	double Start;
	int ni;

	if( ClientFlags & PF_STLS_ON ){
		/* SSLway is active already */
		return 0;
	}

	Start = Time();
	IGNRETZ pipe(CFI_SYNC);
	FromC = fromC;

	if( STLS_wait_set == 0 ){
		if( streq("https",CLNT_PROTO) ){
			STLS_implicit_wait = 2;
		}else
		if( isinList("tcprelay",CLNT_PROTO) ){
			STLS_implicit_wait = 1;
		}else
		if( isinList("ftps,telnets,pop3s,imaps,nntps,ldaps",
			CLNT_PROTO) ){
			STLS_implicit_wait = 2;
		}else
		if( isinList("socks",CLNT_PROTO) ){
			STLS_implicit_wait = 1;
		}
		else
		if( isinList("yysh",CLNT_PROTO) ){
			STLS_implicit_wait = 8;
		}else
		if( isinList("yymux",CLNT_PROTO) ){
			STLS_implicit_wait = 15;
		}else
		if( AccPort_Flags & SVP_SSL ){
			STLS_implicit_wait = 2;
			sv1log("----Port/SSL -P%d.%X\n",
				AccPort_Port,AccPort_Flags);
		}
	}
	if( needSTLS(Conn) ){
		/*
		daemonlog("E","ERROR: SSL/cl is not detected\n");
		*/
daemonlog("E","ERROR: SSL/cl is not detected (%.2f %.2f){%.2f %s %X}\n",
			Start-ClntConnTime,Time()-ClntConnTime,
			STLS_implicit_wait,CLNT_PROTO,AccPort_Flags);
		fail = -1;
		goto EEXIT;
	}
	if( (ClientFlags & PF_STLS_ON) == 0 ){
		/* no sslway is invoked */
		goto EEXIT;
	}

	close(CFI_SYNC[1]); CFI_SYNC[1] = 0;
	fst = fdopen(CFI_SYNC[0],"r");
	statb[0] = statb[1] = stat = 0;
	for(;;){
		nready = fPollIn(fst,1000);
		if( nready == 0 )
		if( stat == 0 || stat == 'W' ){
			sv1log("waiting CFI_SYNC from sslway (%d)...\n",300);
			nready = fPollIn(fst,300*1000);
		}
		if( 0 < nready )
			stat = getc(fst);
		else	stat = -2;
		statb[0] = stat;
		if( isalnum(stat) ){
			sv1log("%.3f CFI_SYNC ready=%d [%X/%s]\n",
				Time()-Start,nready,stat,statb);
		}else{
			sv1log("%.3f CFI_SYNC ready=%d [%X]\n",
				Time()-Start,nready,stat);
		}
		if( nready <= 0 || stat < 0 || stat == EOF )
			break;
		if( stat == '\n' )
			break;
	}
	if( nready <= 0 || stat < 0 || stat == EOF || !IsAlive(fromC) ){
		/*
		daemonlog("E","ERROR: SSL/cl disconnected\n");
		*/
		daemonlog("E","ERROR: SSL/cl disconnected: %d %X %d[%d]\n",
			nready,stat,IsAlive(fromC),fromC);
		fail = -2;
	}
	goto EXIT;
EEXIT:
	close(CFI_SYNC[1]); CFI_SYNC[1] = 0;
EXIT:
	close(CFI_SYNC[0]); CFI_SYNC[0] = 0;
	FromC = -1;
	return fail;
}
Exemple #23
0
/*
 * try to do I/O every MAX_NICE_SLEEP seconds
 * to reduce the cost for process switch
 * without decreasing the speed of relay
 */
int doNice(PCStr(what),DGC*Conn,int ifd,FILE *ifp,int ofd,FILE *ofp,int niced,FileSize bytes,int count,double since)
{	double now,elapsed;
	double sec1,sec;
	int bsize,isize,osize;

	now = Time();
	elapsed = now - since;

	if( 0 < bytes ){
		int maxbps = CTX_maxbps(Conn);
		if( 0 < maxbps ){
			int bps;
			int slp = 0;
			bps = 8*(int)(bytes/elapsed);
			if( maxbps < bps ){
				if( maxbps*3 < bps ) slp = 4000; else
				if( maxbps*2 < bps ) slp = 2000; else
						     slp = 1000;
				msleep(slp);
				sv1log("-- %lld/%d %f %d/%d bps (%d)\n",
					bytes,count,elapsed, bps,maxbps,slp);
			}
		}
	}

	if( 10 <= (now - since) )
	if( niced < MAX_NICE_VALUE && (0x010000 << niced) < bytes ){
		niced += 1;
		IGNRETZ nice(1);

		bsize = ((int)((bytes/elapsed) * MAX_NICE_SLEEP*2)) & ~0x3FF;
		if( bsize == 0 )
			bsize = MIN_SOCK_BUFSIZE;
		if( MAX_SOCK_BUFSIZE < bsize )
			bsize = MAX_SOCK_BUFSIZE;

		if( 0 <= ifd ) expsockbuf(ifd,bsize,0);
		if( 0 <= ofd ) expsockbuf(ofd,0,bsize);

		isize = osize = 0;
		if( 0 <= ifd )
			getsockbuf(ifd,&isize,&osize);
		daemonlog("E","NICE-%d %dK/%d/%4.2fs %d/p %d/s buf=%d(%d)\n",
			niced,(int)(bytes/1024),
			count,elapsed,(int)(bytes/count),
			(int)(bytes/elapsed),isize,bsize);
	}

	if( actthreads() ){
		/* 9.6.1 not to break the scheduling amoung threads ... */
	}else
	if( 0 < niced )
	if( ifp == NULL || READYCC(ifp) <= 0 )
	if( 0 <= ifd && !readyAlways(ifd) && PollIn(ifd,1) == 0 )
	if( getsockbuf(ifd,&isize,&osize) == 0 ){
		sec = sec1 = (isize/4) / (bytes/elapsed);
		if( MIN_NICE_SLEEP < sec1 ){
			if( MAX_NICE_SLEEP < sec ) sec = MAX_NICE_SLEEP;
		daemonlog("E","NICE-%d %dK/%d/%4.2fs %d/p %d/s: %4.2fs/%4.2fs\n",
				niced,(int)(bytes/1024),
				count,elapsed,(int)(bytes/count),
				(int)(bytes/elapsed),sec,sec1);

			if( ofp != NULL )
				fflush(ofp);
			if( isWindowsCE() ){
			}else
			msleep((int)(sec*1000));
		}
	}
	return niced;
}
Exemple #24
0
int service_vsap(Connection *Conn)
{	CStr(request,1024);
	CStr(reqver,128);
	const char *req;
	int svsock,shared,clsock,rcode;
	CStr(myport,256);
	CStr(sockname,MaxHostNameLen);
	CStr(peername,MaxHostNameLen);
	int wcc,rcc;
	CStr(com,1024);
	CStr(arg,1024);
	const char *argp;
	CStr(opt,32);
	const char *op;
	int timeout;
	int AuthOk;
	FILE *authout;

	minit_vsapsv();
	if( ToS <= 0 || FromS <= 0 ){
		/*
		If the DST_HOST is not local
		connect to the master and simple_relay...
		 */
	}
	if( !isMYSELF(DFLT_HOST) ){
		daemonlog("E","VSAP relaying to %s:%d\n",DFLT_HOST,DFLT_PORT);
		if( ToS < 0 )
			connect_to_serv(Conn,FromC,ToC,0);
		relay_svcl(Conn,FromC,ToC,FromS,ToS);
		close(ToS);
		return 0;
	}

	/*
	timeout = 300;
	*/
	timeout = IO_TIMEOUT;

	shared = 0;
	myport[0] = 0;
	SvSockN = 0;
	ClSockN = 0;
	clsock = -1;
	svsock = -1;
	reqver[0] = 0;

	authout = TMPFILE("VSAP-AUTH");
	if( doAUTH(Conn,NULL,authout,"vsap","-",0,CVStr("user-xxxx:pass-xxxx"),CVStr("host-xxxx"),NULL,NULL) == EOF ){
		AuthOk = 0;
	}else	AuthOk = -1;

	if( ImMaster ){
		sprintf(myport,"%s:%d",DST_HOST,DST_PORT);
	}else
	for(;;){
		if( DDI_fgetsFromCbuf(Conn,AVStr(request),sizeof(request),NULL) == 0 )
		{	int closed = 0;
			for(;;){
				if( PollIn(FromC,1*1000) != 0 )
					break;
				closed |= checkCloseOnTimeout(1);
				if( 0 <= clsock && !IsAlive(clsock) ){
daemonlog("E","## disconnected by peer\n");
SockPrintf(ToC,"%s %d %s.\r\n",VER,NO_GENERIC_BYE,"disconnected by peer");
					close(clsock);del_clsock(clsock);
					goto EXIT;
				}
			}
		if( (rcc = RecvLine(FromC,request,sizeof(request))) <= 0 )
			break;
		}

		daemonlog("D","CLIENT-SAYS: %s",request);
daemonlog("E","CLIENT-SAYS: %s",request);
		req = request;
		if( strncmp(req,"VSAP/",5) == 0 )
			req = wordScan(req,reqver);

		argp = wordScan(req,com);
		arg[0] = 0;
		lineScan(argp,arg);

		if( strcasecmp(com,"AUTH") == 0 ){
			CStr(ahost,MaxHostNameLen);
			ahost[0] = 0;
			if( doAUTH(Conn,NULL,authout,"vsap","-",0,AVStr(arg),AVStr(ahost),NULL,NULL) == EOF ){
			}else{
				AuthOk = 1;
				SockPrintf(ToC,"%s %d OK\r\n",VER,OK_GENERIC);
				continue;
			}
		}
		if( AuthOk == 0 ){
			SockPrintf(ToC,"%s %d forbidden\r\n",VER,NO_PERMISSION);
			sv1log("WITH AUTHORIZER, but NO AUTH from client\n");
			break;
		}

		if( strcasecmp(com,"ECHO") == 0 ){
			CStr(stime,64);
			StrftimeLocal(AVStr(stime),sizeof(stime),TIMEFORM_HTTPD,time(0),0);
			SockPrintf(ToC,"%s %d [%s] %s\r\n",VER,OK_GENERIC,
				stime,arg);
		}else
		if( strcasecmp(com,"CONNECT") == 0 ){
			strcpy(myport,arg);
			if( !vsap_permit(Conn,myport) )
				break;
			clsock = do_connect(svsock,myport,ToC);
			if( clsock < 0 )
				break;
		}else
		if( strcasecmp(com,"BIND") == 0 ){
			CStr(opts,1024);
			opts[0] = 0;
			Xsscanf(arg,"%s %[^\r\n]",AVStr(myport),AVStr(opts));
			if( !vsap_permit(Conn,myport) )
				break;
			svsock = do_bind(-1,AVStr(myport),opts,&shared,AVStr(sockname),ToC);
			if( svsock < 0 )
				break;
		}else
		if( strcasecmp(com,"LISTEN") == 0 ){
			int nlisten = atoi(arg);
			Socket1("VSAP",svsock,NULL,NULL,NULL,VStrANYPORT,ANYPORT,nlisten,NULL,0);
			SockPrintf(ToC,"%s %d listen ok.\r\n",VER,OK_LISTEN);
		}else
		if( strcasecmp(com,"ACCEPT") == 0 ){
			int priority;
			if( Conn->cl_count <= 1 )
				priority = 0;
			else	priority = 1;

			clsock = do_accept(myport,arg,shared,priority,FromC,ToC);
			if( !shared )
				svsock = -1;

			if( clsock < 0 ){
				wcc = SockPrintf(ToC,"%s %d accept fail\r\n",
					VER,NO_ACCEPT);
				break;
			}
			add_clsock(clsock);
			if( myport[0] == '/' ){
				strcpy(sockname,myport);
				strcpy(peername,myport);
			}else	getpairName(clsock,AVStr(sockname),AVStr(peername));
			wcc = SockPrintf(ToC,"%s %d %d %s %s accepted.\r\n",
				VER,OK_ACCEPT,ClSockN,sockname,peername);
		}else
		if( strcasecmp(com,"QUIT") == 0 ){
			SockPrintf(ToC,"%s %d bye.\r\n",VER,OK_BYE);
			break;
		}else
		if( strcasecmp(com,"FORWARD") == 0 ){
			do_forward(Conn,myport,arg,shared,svsock,0,FromC,ToC);
		}else
		if( strcasecmp(com,"RELAY") == 0 ){
/*
-t timeout
 */
			for( op = arg; *op == '-'; ){
				if( strneq(op,"-t=",3) ){
					int to;
					op = numscanX(op+3,AVStr(opt),sizeof(opt));
					to = atoi(opt);
					if( to < timeout )
						timeout = to;
				}else{
					break;
				}
			}

			tcp_relay2(timeout*1000,FromC,clsock,clsock,ToC);
			/*
			set_linger(clsock,10);
			*/
			set_linger(clsock,LIN_TIMEOUT);
			close(clsock);del_clsock(clsock);
			break;
		}else
		if( strcasecmp(com,"PROXY") == 0 ){
			ToS = FromS = ToC;
			ToC = FromC = clsock;
daemonlog("E","##### VSAP switch protocol to '%s'\n",arg);
			if( strcmp(arg,"http")==0 )
				service_http(Conn);
			else
			if( strcmp(arg,"ftp")==0 )
				service_ftp(Conn);
			set_linger(clsock,10);
			close(clsock);del_clsock(clsock);
			break;
		}else
		{
/*
			wcc = write(clsock,req,rcc);
			tcp_relay2(timeout*1000,FromC,clsock,clsock,ToC);
*/
			SockPrintf(ToC,"%s %d %s",VER,NO_GENERIC,request);
		}
	}
EXIT:
	fclose(authout);
	return 0;
}
Exemple #25
0
pid_t
daemonize(mode_t mask,
		const char *rundir,
		const char *pidpath,
		const char *lockpath,
		const char *logpath)
{
	pid_t pid;
	int fd;

	if (getppid() == 1) {                            /* already a daemon */
		return 0;
	}

	if ((pid = fork())) {
		return pid;
	}
                                             /* child (daemon) continues */
	setsid();                              /* obtain a new process group */
	umask(mask);                   /* set newly created file permissions */

                                                /* close all descriptors */
	for (fd = getdtablesize(); fd >= 0; fd--) {
		close(fd);
	}
            /* but stdin, stdout, and stderr are redirected to /dev/null */
	if ((fd = open("/dev/null", O_RDWR)) != 0 || dup(fd) != 1 || dup(fd) != 2) {
		return -1;
	}
	if (logpath) {                                  /* open the logfile */
		time_t start = time(NULL);

		if ((logfp = fopen(logpath, "a")) == NULL) {
			PMNF(errno, ": %s", logpath);
			return -1;
		}

		msgno_hdlr = daemonlog;
		daemonlog("log started: %s", ctime(&start));
	}

	if (lockpath) {
		if ((fd = open(lockpath, O_RDWR | O_CREAT, 0640)) == -1) {
			PMNF(errno, ": %s", lockpath);
			return -1;
		}
		if (lockf(fd, F_TLOCK, 0) == -1) {               /* can not lock */
			PMNF(errno, ": %s: Server already running.", lockpath);
			return -1;
		}
	}
                                             /* first instance continues */
	if (pidpath) {
		char str[10];

		if ((fd = open(pidpath, O_RDWR | O_CREAT, 0640)) == -1) {
			PMNO(errno);
			return -1;
		}
		sprintf(str, "%d\n", getpid());
		if (write(fd, str, strlen(str)) == -1) { /* write pid to lockfile */
			PMNO(errno);
			return -1;
		}
		close(fd);
	}

	if (rundir && chdir(rundir) == -1) {   /* change running directory */
		PMNF(errno, ": %s", rundir);
		return -1;
	}

	signal(SIGTSTP,SIG_IGN);                       /* ignore tty signals */
	signal(SIGTTOU,SIG_IGN);
	signal(SIGTTIN,SIG_IGN);

	return 0;
}
Exemple #26
0
void putBackTrace(FILE *out)
{   CStr(pid,32);
    int cpid,Cpid,nready,xpid;
    int pipes[2],psync[2];
    CStr(command,128);
    const char *path;
    int mpid = getpid();

    if( INHERENT_fork() == 0 )
        return;

    dout = out;
    dStart = Time();

    IGNRETZ pipe(psync);
    if( (Cpid = fork()) == 0 ) { /* the clone to be traced */
        __BtLog("X target");
        close(psync[1]);
        errno = 0;
        nready =
            PollIn(psync[0],10*1000);
        __BtLog("Y target, nready=%d errno=%d",nready,errno);
        if( nready < 0 && errno == EINTR ) {
            /* INTR by ptrace() attach/detach ? */
            errno = 0;
            /* psync[0] become EOF when DBX finised */
            nready = PollIn(psync[0],10*1000);
            __BtLog("Z target, nready=%d errno=%d",nready,errno);
        }
        _exit(0);
    }

    sprintf(pid,"%d",Cpid);
    sprintf(command,"where\ndetach\nquit\n");
    /*
    sprintf(command,"where\nquit\n");
    */

    IGNRETZ pipe(pipes);
    if( (cpid = fork()) == 0 ) {
        close(pipes[1]);
        dup2(pipes[0],0);
        dup2(fileno(out),1);
        dup2(fileno(out),2);
        if( sizeof(void*) == 8 ) { /* DEC ALPHA ? */
            execlp("dbx","dbx",EXEC_PATH,"-pid",pid,(void*)0);
        }
        execlp("dbx","dbx","-q",EXEC_PATH,pid,(void*)0);
        execlp("gdb","gdb","-q",EXEC_PATH,pid,(void*)0);
        path = getenv("PATH");
        fprintf(out,"#### error: no dbx nor gdb in PATH=%s\n",
                path?path:"");
        exit(-1);
    }
    close(pipes[0]);
    IGNRETP write(pipes[1],command,strlen(command));
    close(psync[1]);

    __BtLog("A caller, poll [target=%d DBX=%d]",Cpid,cpid);
    nready = PollIn(psync[0],10*1000);
    __BtLog("B caller, nready=%d errno=%d",nready,errno);
    close(psync[0]);
    close(pipes[1]);
    xpid = NoHangWait();
    if( xpid == 0 ) {
        sleep(1);
        xpid = NoHangWait();
    }
    __BtLog("C caller, xpid=%d [%d %d]",xpid,Cpid,cpid);

    if( xpid != Cpid ) {
        int Xpid;
        Kill(Cpid,9);
        Xpid = NoHangWait();
        if( Xpid == 0 ) {
            sleep(1);
            Xpid = NoHangWait();
        }
        __BtLog("D caller, Xpid=%d [%d %d]",Xpid,Cpid,cpid);
        if( xpid == 0 )
            xpid = Xpid;
    }
    /*
    if( nready == 0 || xpid != cpid ){
    */
    if( xpid != cpid ) {
        int rcode;
        daemonlog("F","\n#### debugger freezed? nready=%d %d/%d/%d\n",
                  nready,xpid,cpid,Cpid);
        fprintf(out,"#### error: nready=%d xpid=%d/%d/%d\n",
                nready,xpid,cpid,Cpid);

        rcode = Kill(cpid,9);
        sleep(3);
        xpid = NoHangWait();
        fprintf(out,"#### Terminate Debugger: kill(%d)=%d xpid=%d\n",
                cpid,rcode,xpid);
        __BtLog("#### Terminate Debugger: kill(%d)=%d xpid=%d\n",
                cpid,rcode,xpid);
    }
}
Exemple #27
0
static int do_bind(int sock,PVStr(lport),PCStr(opts),int *sharedp,PVStr(sockname),int toC)
{	int svsock;
	CStr(host,MaxHostNameLen);
	CStr(ports,256);
	int port;
	int nlisten;
	int wcc;
	int sockid;

	*sharedp = 0;
	host[0] = 0;
	ports[0] = 0;
	port = 0;
	nlisten = 0;

	if( lport[0] == '/' ){
		svsock = server_open_un("vsap",AVStr(lport),1);
		daemonlog("E","## SVPORT %s [%d]\n",lport,svsock);
		if( svsock < 0 ){
		wcc = SockPrintf(toC,"%s %d not bound-1\r\n",VER,NO_BIND);
		return -1;
		}
		strcpy(sockname,lport);
		*sharedp = 1;
		goto BOUND;
	}

	if( strchr(lport,':') )
		Xsscanf(lport,"%[^:]:%s",AVStr(host),AVStr(ports));
	else	Xsscanf(lport,"%s",AVStr(ports));
	port = atoi(ports);

	if( strncmp(opts,"-l=",3) == 0 )
		nlisten = atoi(opts+3);

	daemonlog("D","bind: %s:%d nlisten=%d\n",host,port,nlisten);

	if( 0 <= (svsock = ServSockOf(host,port)) ){
		daemonlog("D","## SVPORT %d\n",svsock);
		*sharedp = 1;
	}else
	if( 0 <= (svsock = ReservedPortSock(host,port)) ){
		daemonlog("D","## RESV_PORT %d\n",svsock);
		*sharedp = 1;
	}else
	if( lSINGLEP()
	 && 0 <= (svsock = findopen_port("VSAP",AVStr(host),port,nlisten)) ){
		daemonlog("D","## SHARED_PORT %d\n",svsock);
		*sharedp = 1;
	}else
	if( 0 <= (svsock = NewPort(lport,AVStr(host),port,toC,nlisten)) ){
		daemonlog("D","## NEW_PORT %d\n",svsock);
		*sharedp = 0;
	}else{
		wcc = SockPrintf(toC,"%s %d not bound-2 %s\r\n",VER,NO_BIND,
			lport);
		return -1;
	}
	gethostName(svsock,AVStr(sockname),"%A:%P");

BOUND:
	sockid = add_svsock(svsock);
	wcc = SockPrintf(toC,"%s %d %d %s bound.\r\n",VER,OK_BIND,
		sockid,sockname);
	return svsock;
}