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

📄 address.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: address.c,v 1.75 1999/12/22 09:29:22 karls Exp $";__BEGIN_DECLSstatic struct socksfd_t socksfdinit;static int *dv;static unsigned int dc;static struct socksfd_t *socksfdv;static unsigned int socksfdc;static intsocks_sigblock __P((sigset_t *oldmask));/* * Blocks signals that can change socksfdv, writing the old *	signalmask to "oldmask". * Returns: *		On success: 0 *		On failure: -1 */__END_DECLSstruct socksfd_t *socks_addaddr(clientfd, socksfd)	unsigned int clientfd;	struct socksfd_t *socksfd;{	const char *function = "socks_addaddr()";#if 0 /* DEBUG */	if (socksfd->state.command != -1 && !socksfd->state.system)		slog(LOG_DEBUG, "%s: %d", function, clientfd);#endif	SASSERTX(socksfd->state.command		== -1	||	 socksfd->state.command				== SOCKS_BIND	||	 socksfd->state.command				== SOCKS_CONNECT	||	 socksfd->state.command				== SOCKS_UDPASSOCIATE);	if (socks_addfd(clientfd) != 0)		serrx(EXIT_FAILURE, "%s: %s", function, NOMEM);	if (socksfdc < dc) { /* init/reallocate */		sigset_t oldmask;		if (socksfdinit.control == 0) {	/* not initialized */			socksfdinit.control = -1;			/* other members have ok default value. */		}		if (socks_sigblock(&oldmask) != 0)			return NULL;		if ((socksfdv = (struct socksfd_t *)realloc(socksfdv,		sizeof(*socksfdv) * dc)) == NULL)			serrx(EXIT_FAILURE, "%s: %s", function, NOMEM);		/* init new objects */		while (socksfdc < dc)			socksfdv[socksfdc++] = socksfdinit;		if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)			swarn("%s: sigprocmask()", function);	}	switch (socksfd->state.command) {		case SOCKS_BIND:#if SOCKS_TRYHARDER			if ((socksfd->state.lock = socks_mklock(SOCKS_LOCKFILE)) == -1)				swarn("%s: socks_mklock()", function);#endif			break;	}	socksfdv[clientfd] = *socksfd;	socksfdv[clientfd].allocated = 1;	return &socksfdv[clientfd];}struct socksfd_t *socks_getaddr(d)	unsigned int d;{	if (socks_isaddr(d))		return &socksfdv[d];	return NULL;}voidsocks_rmaddr(d)	unsigned int d;{/*	const char *function = "socks_rmaddr()";  */#if 0 /* DEBUG */	if (!socks_isaddr(d)	|| (!socksfdv[d].state.command != -1 && !socksfdv[d].state.system))		slog(LOG_DEBUG, "%s: %d", function, d);#endif	if (!socks_isaddr(d))		return;	socks_rmfd(d);	switch (socksfdv[d].state.version) {		case MSPROXY_V2:			if (socksfdv[d].control != -1)				close(socksfdv[d].control);			break;		case SOCKS_V4:		case SOCKS_V5:			if (!socksfdv[d].state.system)				switch (socksfdv[d].state.command) {					case SOCKS_BIND:						if (socksfdv[d].control != -1						&& d != (unsigned int)socksfdv[d].control)							close(socksfdv[d].control);						break;					case SOCKS_CONNECT:						break; /* no separate controlconnection. */					case SOCKS_UDPASSOCIATE:						if (socksfdv[d].control != -1)							close(socksfdv[d].control);						break;					default:						SERRX(socksfdv[d].state.command);				}			switch (socksfdv[d].state.command) {				case SOCKS_BIND:#if SOCKS_TRYHARDER					if (close(socksfdv[d].state.lock) != 0)						swarn("socks_rmaddr()");#endif					break;			}	}	socksfdv[d] = socksfdinit;}intsocks_isaddr(d)	unsigned int d;{	if (d < socksfdc && socksfdv[d].allocated)		return 1;	return 0;}intsocks_addrisok(s)	unsigned int s;{	const char *function = "socks_addrisok()";	const int errno_s = errno;	int matched;	sigset_t oldmask;	if (socks_sigblock(&oldmask) != 0)		return 0;	matched = 0;	do {		struct socksfd_t *socksfd;		struct sockaddr local;		socklen_t locallen;		locallen = sizeof(local);		if (getsockname((int)s, &local, &locallen) != 0)			break;		socksfd = socks_getaddr(s);		if (socksfd != NULL) {			if (!sockaddrareeq(&local, &socksfd->local))				break;			/* check remote endpoint too? */			matched = 1;		}		else { /* unknown descriptor.  Try to check whether it's a dup. */			int duped;			if ((duped = socks_addrmatch(&local, NULL, NULL)) != -1) {				struct socksfd_t nsocksfd;				socksfd = socksfddup(socks_getaddr((unsigned int)duped), &nsocksfd);				if (socksfd == NULL) {					swarn("%s: socksfddup()", function);					break;				}				socks_addaddr(s, socksfd);				matched = 1;			}			break;		}	/* CONSTCOND */	} while (0);	if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)		swarn("%s: sigprocmask()", function);	errno = errno_s;	return matched;}intsocks_addrcontrol(local, remote)	const struct sockaddr *local;	const struct sockaddr *remote;{	unsigned int i;	for (i = 0; i < socksfdc; ++i) {		struct sockaddr localcontrol, remotecontrol;		if (!socks_isaddr((unsigned int)i))			continue;		if (local != NULL) {			socklen_t len = sizeof(localcontrol);			if (getsockname(socksfdv[i].control, &localcontrol, &len) != 0)				continue;			if (!sockaddrareeq(local, &localcontrol))				continue;		}		if (remote != NULL) {			socklen_t len = sizeof(remotecontrol);			if (getpeername(socksfdv[i].control, &remotecontrol, &len) != 0)				continue;			if (!sockaddrareeq(remote, &remotecontrol))				continue;		}		return i;	}	return -1;}intsocks_addrmatch(local, remote, state)	const struct sockaddr *local;	const struct sockaddr *remote;	const struct socksstate_t *state;{	unsigned int i;	for (i = 0; i < socksfdc; ++i) {		if (!socks_isaddr(i))			continue;		/*		 * only compare fields that have a valid value in request to compare		 * against.		 */		if (local != NULL)			if (!sockaddrareeq(local, &socksfdv[i].local))				continue;		if (remote != NULL)			if (!sockaddrareeq(remote, &socksfdv[i].remote))				continue;		if (state != NULL) {			if (state->version != -1)				if (state->version != socksfdv[i].state.version)					continue;			if (state->command != -1)				if (state->command != socksfdv[i].state.command)					continue;			if (state->inprogress != -1)				if (state->inprogress != socksfdv[i].state.inprogress)					continue;			if (state->acceptpending != -1)				if (state->acceptpending != socksfdv[i].state.acceptpending)					continue;		}		return i;	}	return -1;}intsocks_addfd(d)	unsigned int d;{	const char *function = "socks_addfd()";	if (d >= dc)	{ /* init/reallocate */		sigset_t oldmask;		int *newfdv;		unsigned int newfdc;		if (socks_sigblock(&oldmask) != 0)			return -1;		newfdc = MAX(d + 1, (unsigned int)getdtablesize());		if ((newfdv = (int *)realloc(dv, sizeof(*dv) * newfdc)) == NULL)			serrx(EXIT_FAILURE, "%s: %s", function, NOMEM);		dv = newfdv;		/* init all to -1, a illegal value for a d. */		while (dc < newfdc)			dv[dc++] = -1;		if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)			swarn("%s: sigprocmask()", function);	}	dv[d] = d;	return 0;}intsocks_isfd(d)	unsigned int d;{	if (d >= dc || dv[d] == -1)		return 0;	return 1;}voidsocks_rmfd(d)	unsigned int d;{	if (socks_isfd(d))		dv[d] = -1;}struct socksfd_t *socksfddup(old, new)	const struct socksfd_t *old;	struct socksfd_t *new;{	*new = *old;	/* init most stuff. */	switch (old->state.command) {		case SOCKS_BIND:		case SOCKS_UDPASSOCIATE:			if ((new->control = socketoptdup(old->control)) == -1)				return NULL;			break;		case SOCKS_CONNECT:			/* only descriptor for connect is the one client has. */			break;		default:			SERRX(old->state.command);	}	return new;}static intsocks_sigblock(oldmask)	sigset_t *oldmask;{	const char *function = "socks_sigblock()";	sigset_t newmask;	/*	 * block signals that might change socksfd.	 */	sigemptyset(&newmask);	sigaddset(&newmask, SIGIO);	sigaddset(&newmask, SIGCHLD);	if (sigprocmask(SIG_BLOCK, &newmask, oldmask) != 0) {		swarn("%s: sigprocmask()", function);		return -1;	}	return 0;}#if 0voidccinit(void){	const char *function = "cc()";	struct sigaction sigact;	struct itimerval itimer;	slog(LOG_DEBUG, function);	if (sigaction(SIGALRM, NULL, &sigact) != 0) {		swarn("%s: sigaction(SIGALRM)", function);		return;	}	if (sigact.sa_handler != SIG_DFL	&&  sigact.sa_handler != SIG_IGN) {		swarnx("%s: could not install signalhandler for SIGALRM, already set",		function);		return;	}	sigemptyset(&sigact.sa_mask);	sigact.sa_flags = SA_RESTART;	sigact.sa_handler = cc_socksfdv;	if (sigaction(SIGALRM, &sigact, NULL) != 0) {		swarn("%s: sigaction(SIGALRM)", function);		return;	}	itimer.it_interval.tv_sec		= 1;	itimer.it_interval.tv_usec		= 0;	itimer.it_value.tv_sec			= 1;	itimer.it_value.tv_usec			= 1;	if (setitimer(ITIMER_REAL, &itimer, NULL) != 0)		swarn("%s: setitimer()", function);}#endif#if DIAGNOSTICvoidcc_socksfdv(sig)	int sig;{	unsigned int i;	for (i = 0; i < socksfdc; ++i) {		if (!socksfdv[i].allocated)			continue;		if (socksfdv[i].state.system)			SERRX(i);	}}#endif /* DIAGNOSTIC */

⌨️ 快捷键说明

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