⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dirsend.c

📁 sock5代理服务器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	-	-	-	-	-	-	-	-	*//* * This routine is called when a timeout occurs. It includes the code that * was formerly used when select() returned 0 (indicating a timeout). *//*ARGSUSED*/static voidtimeoutProc(client_data,id)XtPointer client_data;XtIntervalId *id;{    if (gaps || ackpend) { /* Send acknowledgment */	/* Acks are piggybacked on retries - If we have received */	/* an ack from the server, then the packet sent is only  */	/* an ack and the rest of the message will be empty      */#ifdef DEBUG	if (pfs_debug > 2) {            fprintf(stderr,"Acknowledging (%s).\n",		    (ackpend ? "requested" : "gaps"));	}	#endif	if (gaps && verbose)	  fprintf (stderr, "Searching...\n");	retryDirsend();	return;    }    if (retries-- > 0) {	timeout.tv_sec = CLIENT_DIRSRV_BACKOFF(timeout.tv_sec);#ifdef DEBUG	if (pfs_debug > 2) {            fprintf(stderr,"Timed out.  Setting timeout to %d seconds.\n", 		    (int)timeout.tv_sec);	}#endif	retryDirsend();	return;    }#ifdef DEBUG    if (pfs_debug) {	fprintf(stderr, "select failed(timeoutProc): readfds=%x ",		*(int *)&readfds);	perror("");    }#endif    close(lp);    perrno = DIRSEND_SELECT_FAILED;    ptlfree(first);    ptlfree(pkt);    /* return(NULL); */    dirsendReturn = NULL;    dirsendDone = DSRET_TIMEOUT;}/*	-	-	-	-	-	-	-	-	*//* * This function is called whenever there's something to read on the * connection. It includes the code that was run when select() returned * greater than 0 (indicating read ready). *//*ARGSUSED*/static voidreadProc(client_data,source,id)XtPointer client_data;int *source;XtInputId *id;{    from_sz = sizeof(from);    next->start = next->dat;    if ((nr = recvfrom(lp, next->start, sizeof(next->dat), 0, (struct sockaddr *)&from, &from_sz)) < 0) {#ifdef DEBUG        if (pfs_debug) perror("recvfrom");#endif	close(lp);	perrno = DIRSEND_BAD_RECV;	ptlfree(first);	ptlfree(pkt);	/* return(NULL) */	dirsendReturn = NULL;	dirsendDone = DSRET_RECV_ERROR;        return;    }    next->length = nr;    next->start[next->length] = 0;#ifdef DEBUG    if (pfs_debug > 2)        fprintf(stderr,"Received packet from %s\n", inet_ntoa(from.sin_addr));#endif    /* For the current format, if the first byte is less than             */    /* 20, then the first two bits are a version number and the next six  */    /* are the header length (including the first byte).                  */    if((hdr_len = (unsigned char) *(next->start)) < 20) {	ctlptr = next->start + 1;	next->seq = 0;	if(hdr_len >= 3) { 	/* Connection ID */	    bcopy(ctlptr, (char *)&stmp,2);	    if(stmp) pkt_cid = ntohs(stmp);	    ctlptr += 2;	}	if (pkt_cid<0)	  pkt_cid = 65536+pkt_cid;	if(pkt_cid && this_conn_id && (pkt_cid != ntohs(this_conn_id))) {	    /* The packet is not for us */	    /* goto keep_waiting; */#ifdef DEBUG	  if (pfs_debug > 20)	    fprintf(stderr,"Packet not for us %d,%d,%d\n",		    pkt_cid,this_conn_id,ntohs(this_conn_id));#endif	    keepWaitingDirsend();	    return;	}	if(hdr_len >= 5) {	/* Packet number */	    bcopy(ctlptr, (char *)&stmp,2);	    next->seq = ntohs(stmp);	    ctlptr += 2;	}	else { /* No packet number specified, so this is the only one */	    next->seq = 1;	    nd_pkts = 1;	}	if(hdr_len >= 7) {	    /* Total number of packets */	    bcopy(ctlptr, (char *)&stmp,2);  /* 0 means don't know      */	    if(stmp) nd_pkts = ntohs(stmp);	    ctlptr += 2;	}	if(hdr_len >= 9) {	/* Receievd through */	    bcopy(ctlptr, (char *)&stmp,2);  /* 1 means received request */#ifndef USE_V3_PROT	    if((stmp) && (ntohs(stmp) == 1)) {		/* Future retries will be acks only */		pkt->length = 9;		bcopy((char *)&zero, pkt->start+3,2);#ifdef DEBUG		if(pfs_debug > 2) 		    fprintf(stderr,"Server acked request - retries will be acks only\n");#endif	    }#endif	    ctlptr += 2;	}	if(hdr_len >= 11) {	/* Backoff */	    bcopy(ctlptr, (char *)&stmp,2);	    if(stmp) {		backoff = (short) ntohs(stmp);#ifdef DEBUG		if(pfs_debug > 2) 		    fprintf(stderr,"Backing off to %d seconds\n", backoff);#endif		timeout.tv_sec = backoff;		if ((backoff > 60) && (first == next) && (no_pkts == 0)) {		    /* Probably a long queue on the server - don't give up */		    retries = client_dirsrv_retry;		}	    }	    ctlptr += 2;	}	if(hdr_len >= 12) {	/* Flags (1st byte) */	    bcopy(ctlptr, (char *)&rdflag11,1);	    if(rdflag11 & 0x80) {#ifdef DEBUG		if(pfs_debug > 2) 		    fprintf(stderr,"Ack requested\n");#endif		ackpend++;	    }	    if(rdflag11 & 0x40) {#ifdef DEBUG		if(pfs_debug > 2) 		    fprintf(stderr,"Sequenced control packet\n");#endif		next->length = -1;		scpflag++;	    }	    ctlptr += 1;	}	if(hdr_len >= 13) {	/* Flags (2nd byte) */	    /* Reserved for future use */	    bcopy(ctlptr, (char *)&rdflag12,1);	    ctlptr += 1;	}	if(next->seq == 0) {	    /* goto keep_waiting; */	    keepWaitingDirsend();	    return;	}	if(next->length >= 0) next->length -= hdr_len;	next->start += hdr_len;	goto done_old;    }    pkt_cid = 0;    /* if intermediate format (between old and new), then process */    /* and go to done_old                                         */    ctlptr = next->start + max(0,next->length-20);    while(*ctlptr) ctlptr++;    /* Control fields start after the terminating null */    ctlptr++;    /* Until old version are gone, must be 4 extra bytes minimum */    /* When no version 3 servers, can remove the -4              */    if(ctlptr < (next->start + next->length - 4)) {	/* Connection ID */	bcopy(ctlptr, (char *)&stmp,2);	if(stmp) pkt_cid = ntohs(stmp);	ctlptr += 2;	if(pkt_cid && this_conn_id && (pkt_cid != ntohs(this_conn_id))) {	    /* The packet is not for us */	    /* goto keep_waiting; */	    keepWaitingDirsend();	    return;	}	/* Packet number */	if(ctlptr < (next->start + next->length)) {	    bcopy(ctlptr, (char *)&stmp,2);	    next->seq = ntohs(stmp);	    ctlptr += 2;	}	/* Total number of packets */	if(ctlptr < (next->start + next->length)) {	    bcopy(ctlptr, (char *)&stmp,2);	    if(stmp) nd_pkts = ntohs(stmp);	    ctlptr += 2;	}	/* Receievd through */	if(ctlptr < (next->start + next->length)) {	    /* Not supported by clients */	    ctlptr += 2;	}	/* Backoff */	if(ctlptr < (next->start + next->length)) {	    bcopy(ctlptr, (char *)&stmp,2);	    backoff = ntohs(stmp);#ifdef DEBUG	    if(pfs_debug > 2) 		fprintf(stderr,"Backing off to %d seconds\n", backoff);#endif	    if (verbose && backoff)	      fprintf (stderr, "Searching...\n");	    if(backoff) timeout.tv_sec = backoff;	    ctlptr += 2;	}	if(next->seq == 0) {	    /* goto keep_waiting; */	    keepWaitingDirsend();	    return;	}	goto done_old;    }    /* Notes that we have to start searching 11 bytes before the    */    /* expected start of the MULTI-PACKET line because the message  */    /* might include up to 10 bytes of data after the trailing null */    /* The order of those bytes is two bytes each for Connection ID */    /* Packet-no, of, Received-through, Backoff                     */    seqtxt = nlsindex(next->start + max(0,next->length - 40),"MULTI-PACKET");     if(seqtxt) seqtxt+= 13;    if((nd_pkts == 0) && (no_pkts == 0) && (seqtxt == NULL)) goto all_done;    tmp = sscanf(seqtxt,"%d OF %d", &(next->seq), &nd_pkts);#ifdef DEBUG        if (pfs_debug && (tmp == 0)) 	fprintf(stderr,"Cant read packet sequence number: %s", seqtxt);    #endif done_old:#ifdef DEBUG    if(pfs_debug > 2) fprintf(stderr,"Packet %d of %d\n",next->seq,nd_pkts);#endif    if ((first == next) && (no_pkts == 0)) {	if(first->seq == 1) {	    comp_thru = first;	    /* If only one packet, then return it */	    if(nd_pkts == 1) goto all_done;	}	else gaps++;	no_pkts = 1;	next = ptalloc();	/* goto keep_waiting; */	keepWaitingDirsend();	return;    }	    if(comp_thru && (next->seq <= comp_thru->seq))	ptfree(next);    else if (next->seq < first->seq) {	vtmp = first;	first = next;	first->next = vtmp;	first->previous = NULL;	vtmp->previous = first;	if(first->seq == 1) comp_thru = first;	no_pkts++;    }    else {	vtmp = (comp_thru ? comp_thru : first);	while (vtmp->seq < next->seq) {	    if(vtmp->next == NULL) {		vtmp->next = next;		next->previous = vtmp;		next->next = NULL;		no_pkts++;		goto ins_done;	    }	    vtmp = vtmp->next;	}	if(vtmp->seq == next->seq)	    ptfree(next);	else {	    vtmp->previous->next = next;	    next->previous = vtmp->previous;	    next->next = vtmp;	    vtmp->previous = next;	    no_pkts++;	}    }   ins_done:	    while(comp_thru && comp_thru->next && 	  (comp_thru->next->seq == (comp_thru->seq + 1))) {	comp_thru = comp_thru->next;#ifndef USE_V3_PROT	recvd_thru = htons(comp_thru->seq);	bcopy((char *)&recvd_thru,pkt->start+7,2); /* Let server know we got it */#endif	/* We've made progress, so reset retry count */	retries = client_dirsrv_retry;	/* Also, next retry will be only an acknowledgement */	/* but for now, we can't fill in the ack field      */#ifdef DEBUG	if(pfs_debug > 2) 	    fprintf(stderr,"Packets now received through %d\n",comp_thru->seq);#endif    }    /* See if there are any gaps */    if(!comp_thru || comp_thru->next) gaps++;    else gaps = 0;    if ((nd_pkts == 0) || (no_pkts < nd_pkts)) {	next = ptalloc();	/* goto keep_waiting; */	keepWaitingDirsend();	return;    } all_done:    if(ackpend) { /* Send acknowledgement if requested */#ifdef DEBUG	if (pfs_debug > 2) {	    if (to.sin_family == AF_INET)		fprintf(stderr,"Acknowledging final packet to %s(%d)\n",			to_hostname, ntohs(this_conn_id));            else                fprintf(stderr,"Acknowledging final packet\n");	    (void) fflush(stderr);	}#endif	ns = sendto(lp,(char *)(pkt->start), pkt->length, 0, (struct sockaddr *)&to, S_AD_SZ);	if(ns != pkt->length) {#ifdef DEBUG	    if (pfs_debug) {		fprintf(stderr,"\nsent only %d/%d: ",ns, pkt->length);		perror("");	    }#endif	}    }    close(lp);    ptlfree(pkt);    /* Get rid of any sequenced control packets */    if(scpflag) {	while(first && (first->length < 0)) {	    vtmp = first;	    first = first->next;	    if(first) first->previous = NULL;	    ptfree(vtmp);	}	vtmp = first;	while(vtmp && vtmp->next) {	    if(vtmp->next->length < 0) {		if(vtmp->next->next) {		    vtmp->next = vtmp->next->next;		    ptfree(vtmp->next->previous);		    vtmp->next->previous = vtmp;		}		else {		    ptfree(vtmp->next);		    vtmp->next = NULL;		}	    }	    vtmp = vtmp->next;	}    }    /* return(first); */    dirsendReturn = first;    dirsendDone = DSRET_DONE;}static voidprocessEvent(){    /* select - either recv is ready, or timeout */    /* see if timeout or error or wrong descriptor */    tmp = select(lp + 1, &readfds, (SELECTARG *)0, (SELECTARG *)0, selwait);    if (tmp == 0) {	timeoutProc(NULL,&timerId);    } else if ((tmp < 0) || !FD_ISSET(lp,&readfds)) {#ifdef DEBUG	if (pfs_debug) {	    fprintf(stderr, "select failed(processEvent): readfds=%x ",		    *(int *)&readfds);	    perror("");	}#endif	close(lp);	perrno = DIRSEND_SELECT_FAILED;	ptlfree(first);	ptlfree(pkt);	/* return(NULL); */	dirsendReturn = NULL;	dirsendDone = DSRET_SELECT_ERROR;    } else {	readProc(NULL,&lp,&inputId);    }}voidabortDirsend(){    if (!dirsendDone) {	close(lp);	ptlfree(first);	ptlfree(pkt);	dirsendReturn = NULL;	dirsendDone = DSRET_ABORTED;    }    return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -