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

📄 sockd_io.c

📁 sock protocol ,it is useful!
💻 C
📖 第 1 页 / 共 3 页
字号:
						sockaddr2string((struct sockaddr *)&io->in.raddr, src,						sizeof(src)), sockaddr2string(&from, dst, sizeof(dst)));						break;					}					if (connect(io->in.s, &from, sizeof(from)) != 0) {						delete_io(mother, io, io->in.s, IO_ERROR);						return;					}					rstate				= io->state;					rstate.command		= SOCKS_UDPREPLY;					if (!rulespermit(io->in.s, &io->rule, &io->state, &io->src, NULL)					&&  !rulespermit(io->in.s, &io->rule, &rstate, NULL, &io->src)) {						/* can't send, can't receive; drop it. */						delete_io(mother, io, io->in.s, IO_SRCBLOCK);						return;					}				}				io->in.read += r;				/* got packet, pull out socks udp header. */				if (string2udpheader(buf, (size_t)r, &header) == NULL) {					char badfrom[MAXSOCKADDRSTRING];					/* LINTED pointer casts may be troublesome */					swarnx("%s: bad socks udppacket (length = %d) from %s",					function, r, sockaddr2string((struct sockaddr *)&io->in.raddr,					badfrom, sizeof(badfrom)));					break;				}				if (header.frag != 0) {					char badfrom[MAXSOCKADDRSTRING];					/* LINTED pointer casts may be troublesome */					swarnx("%s: %s: fragmented packet from %s.  Not supported",					function, protocol2string(io->state.protocol),					sockaddr2string((struct sockaddr *)&io->in.raddr, badfrom,					sizeof(badfrom)));					break;				}				io->dst = header.host;				/* is the packet to be permitted out? */				permit				= rulespermit(io->in.s, &io->rule, &io->state, &io->src, &io->dst);				/* set r to bytes sent by client sans socks udp header. */				r -= PACKETSIZE_UDP(&header);				iolog(&io->rule, &io->state, OPERATION_IO, &io->src, &io->dst,				&buf[PACKETSIZE_UDP(&header)], (size_t)r);				if (!permit)					break;				/* LINTED pointer casts may be troublesome */				sockshost2sockaddr(&header.host, (struct sockaddr *)&io->out.raddr);				/* LINTED pointer casts may be troublesome */				if ((w = sendto(io->out.s, &buf[PACKETSIZE_UDP(&header)],				(size_t)r, lflags, (struct sockaddr *)&io->out.raddr,				sizeof(io->out.raddr))) != r)					iolog(&io->rule, &io->state, OPERATION_ERROR, &io->src, &io->dst,					NULL, 0);				io->out.written += MAX(0, w);			}			/*			 * Datagram reply from remote present?			 * We first peek at it so we can find out what address it's from,			 * then we check rules and then we read the packet out of the buffer.			 * Reason why we first peek is that if the rule calls libwrap,			 * libwrap would hang since we'd already read the packet and it			 * wants to peek itself.			 * We only peek enough to get the source but this still involves			 * an extra systemcall.  Can we find a better/faster way to do it?			 */			if (FD_ISSET(io->out.s, rset) && FD_ISSET(io->in.s, wset)) {				const int lflags = flags & ~MSG_OOB;				struct connectionstate_t state;				struct sockaddr from;				struct sockshost_t srcsh;				char *newbuf;				/* MSG_PEEK because of libwrap, see above. */				fromlen = sizeof(from);				if ((r = recvfrom(io->out.s, buf, 1, lflags | MSG_PEEK, &from,				&fromlen)) == -1) {					delete_io(mother, io, io->out.s, r);					return;				}				UDPFROMLENCHECK(io->out.s, fromlen);				/*				 * We can get some problems here in the case that				 * the client sends a hostname for destination.				 * If it does it probably means it can't resolve and if				 * we then send it a ipaddress as source, the client				 * wont be able to match our source as it's destination,				 * even if they are the same.				 * We check for this case specifically, though we only catch				 * the last case, which may not always be good enough.				 * We could expand the below check, using addressmatch()				 * instead, but that need not always be right.				 * Better safe than sorry for now.				 */				/* LINTED possible pointer alignment problem */				if (io->dst.atype == SOCKS_ADDR_DOMAIN				&& sockaddrareeq((struct sockaddr *)&io->out.raddr, &from))					srcsh = io->dst;				else					sockaddr2sockshost(&from, &srcsh);				/* only set temporary here for one replypacket at a time. */				state				= io->state;				state.command	= SOCKS_UDPREPLY;				permit				= rulespermit(io->out.s, &io->rule, &state, &srcsh, &io->src);				/* read the peeked packet out of the buffer. */				fromlen = sizeof(from);				if ((r = recvfrom(io->out.s, buf, io->in.sndlowat, lflags, &from,				&fromlen)) == -1) {					delete_io(mother, io, io->out.s, r);					return;				}				io->out.read += r;				iolog(&io->rule, &state, OPERATION_IO, &srcsh, &io->src, buf,				(size_t)r);				if (!permit)					break;				/* add socks udpheader.  */				/* LINTED pointer casts may be troublesome */				newbuf = udpheader_add(&srcsh, buf, (size_t *)&r, sizeof(buf));				SASSERTX(newbuf == buf);				/*				 * XXX socket must be connected but that should always be the				 * case for now since binding udp addresses is not supported.				 */				if ((w = sendto(io->in.s, newbuf, (size_t)r, lflags, NULL, 0))				!= r)					iolog(&io->rule, &state, OPERATION_ERROR, &srcsh, &io->src,					NULL, 0);				io->in.written += MAX(0, w);			}			break;		}		default:			SERRX(io->state.protocol);	}	/*	 * Only thing we expect from client's control connection is a eof.	 * For commands that do not have a controlconnection, we	 * set descriptor to -1 when receiving others.	 */	if (io->control.s != -1 && FD_ISSET(io->control.s, rset)) {		if ((r = read(io->control.s, buf, sizeof(buf))) <= 0)			delete_io(mother, io, io->control.s, r);		else {			char *unexpected, hmmread[MAXSOCKADDRSTRING];			slog(LOG_NOTICE, "%s/control: %d unexpected bytes: %s",			/* LINTED pointer casts may be troublesome */			sockaddr2string((struct sockaddr *)&io->control.raddr, hmmread,			sizeof(hmmread)), r, strcheck(unexpected = str2vis(buf, r)));			free(unexpected);		}	}	/* don't care what direction/descriptors i/o was done over. */	time(&io->time);}static intio_rw(in, out, bad, buf, flag)	struct sockd_io_direction_t *in;	struct sockd_io_direction_t *out;	int *bad;	char *buf;	int flag;{	ssize_t r, w;	size_t len;	if (flag & MSG_OOB)		if (sockatmark(in->s) != 1)			flag &= ~MSG_OOB;	/* we receive oob inline. */	len = flag & MSG_OOB ? 1 : out->sndlowat;	if ((r = recv(in->s, buf, len, flag & ~MSG_OOB)) <= 0) {		*bad = in->s;		return r;	}	in->read += r;	if (flag & MSG_OOB)		in->flags |= MSG_OOB;	/* read oob data.				*/	else		in->flags &= ~MSG_OOB;	/* did not read oob data.	*/	if ((w = send(out->s, buf, (size_t)r, flag)) != r) {		*bad = out->s;		return w;	}	out->written += w;	return w;}static voidproctitleupdate(void){	setproctitle("iorelayer: %d/%d", allocated(), SOCKD_IOMAX);}static struct sockd_io_t *io_getset(set)	fd_set *set;{	int i;	for (i = 0; i < ioc; ++i)		if (iov[i].allocated) {			if (FD_ISSET(iov[i].in.s, set))				return &iov[i];			if (FD_ISSET(iov[i].out.s, set))				return &iov[i];			switch (iov[i].state.command) {				case SOCKS_BIND:				case SOCKS_BINDREPLY:					if (!iov[i].state.extension.bind)						break;					/* else: */ /* FALLTHROUGH */				case SOCKS_UDPASSOCIATE:					if (FD_ISSET(iov[i].control.s, set))						return &iov[i];					break;				default:					break;			}		}	return NULL;}static struct sockd_io_t *io_finddescriptor(d)	int d;{	int i;	for (i = 0; i < ioc; ++i)		if (iov[i].allocated) {			if (d == iov[i].in.s ||	 d == iov[i].out.s)				return &iov[i];			switch (iov[i].state.command) {				case SOCKS_BIND:				case SOCKS_BINDREPLY:					if (!iov[i].state.extension.bind)						break;					/* else: */ /* FALLTHROUGH */				case SOCKS_UDPASSOCIATE:					if (d == iov[i].control.s)						return &iov[i];					break;				default:					break;			}		}	return NULL;}static intio_fillset(set, antiflags)	fd_set *set;	int antiflags;{	int i, max;	FD_ZERO(set);	for (i = 0, max = -1; i < ioc; ++i)		if (iov[i].allocated) {			if (! (antiflags & iov[i].in.flags)) {				FD_SET(iov[i].in.s, set);				max = MAX(max, iov[i].in.s);			}			if (! (antiflags & iov[i].out.flags)) {				FD_SET(iov[i].out.s, set);				max = MAX(max, iov[i].out.s);			}			switch (iov[i].state.command) {				case SOCKS_BIND:				case SOCKS_BINDREPLY:					if (!iov[i].state.extension.bind)						break;					/* else: */ /* FALLTHROUGH */				case SOCKS_UDPASSOCIATE:					if (! (antiflags & iov[i].control.flags)) {						FD_SET(iov[i].control.s, set);						max = MAX(max, iov[i].control.s);					}					break;				default:					break;			}		}	return max;}static struct timeval *io_gettimeout(timeout)	struct timeval *timeout;{	time_t timenow;	int i;	if (allocated() == 0 || config.timeout.io == 0)		return NULL;	timeout->tv_sec	= config.timeout.io;	timeout->tv_usec	= 0;	time(&timenow);	for (i = 0; i < ioc; ++i)		if (!iov[i].allocated)			continue;		else			timeout->tv_sec = MAX(0, MIN(timeout->tv_sec,			difftime(config.timeout.io, (time_t)difftime(timenow, iov[i].time))));	return timeout;}static struct sockd_io_t *io_gettimedout(void){	int i;	time_t timenow;	if (config.timeout.io == 0)		return NULL;	time(&timenow);	for (i = 0; i < ioc; ++i)		if (!iov[i].allocated)			continue;		else			if (difftime(timenow, iov[i].time) >= config.timeout.io)				return &iov[i];	return NULL;}static voidcheckmother(mother, readset)	struct sockd_mother_t *mother;	fd_set *readset;{	if (mother->s != -1 && FD_ISSET(mother->s, readset)) {		FD_CLR(mother->s, readset);		if (recv_io(mother->s, NULL) != 0) {			close(mother->s);			close(mother->ack);			mother->s = mother->ack = -1;		}		else			proctitleupdate();	}}/* ARGSUSED */static voidsiginfo(sig)	int sig;{	int i;	time_t timenow;	time(&timenow);	for (i = 0; i < ioc; ++i)		if (!iov[i].allocated)			continue;		else {			char srcstring[MAXSOCKSHOSTSTRING];			char dststring[MAXSOCKSHOSTSTRING];			slog(LOG_INFO, "%s <-> %s: idle %.0fs",			sockshost2string(&iov[i].src, srcstring, sizeof(srcstring)),			sockshost2string(&iov[i].dst, dststring, sizeof(dststring)),			difftime(timenow, iov[i].time));		}}

⌨️ 快捷键说明

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