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

📄 raccept.c

📁 sock protocol ,it is useful!
💻 C
字号:
/* * Copyright (c) 1997, 1998, 1999 *      Inferno Nettverk A/S, Norway.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. The above copyright notice, this list of conditions and the following *    disclaimer must appear in all copies of the software, derivative works *    or modified versions, and any portions thereof, aswell as in all *    supporting documentation. * 2. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software developed by *      Inferno Nettverk A/S, Norway. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Inferno Nettverk A/S requests users of this software to return to * *  Software Distribution Coordinator  or  sdc@inet.no *  Inferno Nettverk A/S *  Oslo Research Park *  Gaustadal閑n 21 *  N-0349 Oslo *  Norway * * any improvements or extensions that they make and grant Inferno Nettverk A/S * the rights to redistribute these changes. * */#include "common.h"static const char rcsid[] ="$Id: Raccept.c,v 1.67 1999/09/02 10:41:11 michaels Exp $";intRaccept(s, addr, addrlen)	int s;	struct sockaddr *addr;	socklen_t *addrlen;{	const char *function = "Raccept()";	char addrstring[MAXSOCKADDRSTRING];	struct sockaddr accepted;	struct socks_t packet;	struct socksfd_t *socksfd;	fd_set rset;	int fdbits, p, iotype, remote;	/* can't call Raccept() on unknown descriptors. */	if (!socks_addrisok((unsigned int)s)) {		socks_rmaddr((unsigned int)s);		return accept(s, addr, addrlen);	}	socksfd = socks_getaddr((unsigned int)s);	SASSERTX(socksfd != NULL);	bzero(&packet, sizeof(packet));	packet.version = (unsigned char)socksfd->state.version;	if ((iotype = fcntl(s, F_GETFL, 0)) == -1)		return -1;#if SOCKS_TRYHARDER	/*	 * Perhaps overkill, but try to be as compatible as possible.	 * BSD supports multiple process' calling accept(2) on	 * the same descriptor, try to support that functionality by locking	 * the socksfd object ourself in this function, so another process	 * calling Raccept() on this object will fail.	 */	if (iotype & NONBLOCKING)		p = socks_lock(socksfd->state.lock, F_WRLCK, 0);	else		p = socks_lock(socksfd->state.lock, F_WRLCK, -1);	if (p != 0)		return -1;#endif /* SOCKS_TRYHARDER */	FD_ZERO(&rset);	fdbits = -1;	/* check socket we listen on because we support ordinary connects. */	FD_SET(s, &rset);	fdbits = MAX(fdbits, s);	switch (packet.version) {		case SOCKS_V4:		case SOCKS_V5:			/* connection to server, for forwarded connections or errors. */			FD_SET(socksfd->control, &rset);			fdbits = MAX(fdbits, socksfd->control);			break;		case MSPROXY_V2:			break;	/* controlconnection checked asynchronously. */		default:			SERRX(packet.version);	}	SASSERTX(fdbits >= 0);	++fdbits;	if (iotype & NONBLOCKING) {		struct timeval timeout;		timeout.tv_sec		= 0;		timeout.tv_usec	= 0;		if ((p = selectn(fdbits, &rset, NULL, NULL, &timeout)) == 0) {			errno = EWOULDBLOCK;			p = -1;		}	}	else		p = selectn(fdbits, &rset, NULL, NULL, NULL);	if (p == -1) {#if SOCKS_TRYHARDER		socks_unlock(socksfd->state.lock);#endif /* SOCKS_TRYHARDER */		return -1;	}	SASSERTX(p > 0);	if (FD_ISSET(s, &rset)) { /* pending connection on datasocket. */		socklen_t len;		len = sizeof(accepted);		if ((remote = accept(s, &accepted, &len)) == -1) {#if SOCKS_TRYHARDER			socks_unlock(socksfd->state.lock);#endif /* SOCKS_TRYHARDER */			return -1;		}		slog(LOG_DEBUG, "%s: accepted: %s",		function, sockaddr2string(&accepted, addrstring, sizeof(addrstring)));		if (socksfd->state.acceptpending) {			/*			 * connection forwarded by server or a ordinary connect?			 */			/* LINTED pointer casts may be troublesome */			if (((struct sockaddr_in *)&accepted)->sin_addr.s_addr			==  ((struct sockaddr_in *)&socksfd->reply)->sin_addr.s_addr) {				/* matches servers ip address, could be forwarded. */				int forwarded;				switch (socksfd->state.version) {					case SOCKS_V4:					case SOCKS_V5:						packet.req.version	= (char)socksfd->state.version;						packet.req.command	= SOCKS_BIND;						packet.req.flag		= 0;						sockaddr2sockshost(&accepted, &packet.req.host);						packet.req.auth		= &socksfd->state.auth;						if (socks_sendrequest(socksfd->control, &packet.req) != 0)							return -1;						if (socks_recvresponse(socksfd->control, &packet.res,						packet.req.version) != 0) {#if SOCKS_TRYHARDER							socks_unlock(socksfd->state.lock);#endif							return -1;						}						if (packet.res.host.atype != SOCKS_ADDR_IPV4) {							swarnx("%s: unexpected atype in bindquery response: %d",							function, packet.res.host.atype);#if SOCKS_TRYHARDER							socks_unlock(socksfd->state.lock);#endif							return -1;						}						if (packet.res.host.addr.ipv4.s_addr == htonl(0))							forwarded = 0;						else							forwarded = 1;						break;					case MSPROXY_V2:						if (sockaddrareeq(&socksfd->reply, &accepted)) {							/* socksfd->accepted filled in by sigio(). */							accepted = socksfd->accepted;							sockaddr2sockshost(&socksfd->accepted, &packet.res.host);							/* seems to support only one forward. */							socksfd->state.acceptpending = 0;							forwarded = 1;						}						else							forwarded = 0;						break;					default:						SERRX(socksfd->state.version);				}				if (forwarded) {					/* a separate socket with it's own remote address. */					socksfd = socks_addaddr((unsigned int)remote, socksfd);					fakesockshost2sockaddr(&packet.res.host, &accepted);					socksfd->accepted = accepted;					/* has a different local address if INADDR_ANY was bound. */					/* LINTED pointer casts may be troublesome */					if (((struct sockaddr_in *)&socksfd->local)->sin_addr.s_addr					== htonl(INADDR_ANY)) {						len = sizeof(socksfd->local);						if (getsockname(remote, &socksfd->local, &len) != 0)							swarn("%s: getsockname(remote)", function);					}				}				/* else; ordinary connect. */			}		}		/* else; not bind extension, must be a ordinary connect. */	}	else { /* pending connection on controlchannel, server wants to forward. */		SASSERTX(FD_ISSET(socksfd->control, &rset));		switch (packet.version) {			case SOCKS_V4:			case SOCKS_V5:				if (socks_recvresponse(socksfd->control, &packet.res,				packet.version) != 0) {#if SOCKS_TRYHARDER					socks_unlock(socksfd->state.lock);#endif					return -1;				}				fakesockshost2sockaddr(&packet.res.host, &accepted);				socksfd->accepted = accepted;				remote = socksfd->control;				break;			case MSPROXY_V2:				SERRX(0); /* should not be checked, so not checked either. */				break;			default:				SERRX(packet.version);		}	}#if SOCKS_TRYHARDER	socks_unlock(socksfd->state.lock);#endif	if (addr != NULL) {		*addrlen = MIN(*addrlen, sizeof(accepted));		memcpy(addr, &accepted, (size_t)*addrlen);	}	return remote;}

⌨️ 快捷键说明

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