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

📄 sockd_request.c

📁 sock protocol ,it is useful!
💻 C
📖 第 1 页 / 共 3 页
字号:
					if (connect(sv[reply], &clientaddr, sizeof(clientaddr)) != 0) {						iolog(&bindio.rule, &bindio.state, OPERATION_ABORT,						&bindio.src, &bindio.dst, NULL, 0);						break;					}				}				if (bindio.state.extension.bind) {					/*					 * flushio() will close all descriptors set in io packet					 * so dup what we need to keep going.					 */					if ((bindio.control.s = dup(sv[childpipe])) == -1) {						switch (errno) {							case EMFILE:							case ENFILE:								swarn("%s: dup()", function);								++emfile;								continue;							default:								SERR(bindio.control.s);						}					}				}				else					bindio.control.s = sv[client];				bindio.control.laddr	= request->to;				bindio.control.raddr	= request->from;				bindio.control.state	= bindio.state;				/* back to blocking. */				if (fcntl(sv[remote], F_SETFL, flags) == -1) {					swarn("%s: fcntl()", function);					break;				}				if (bindio.state.extension.bind) {					bindio.in.s			= sv[reply];					bindio.in.laddr	= replyaddr;					bindio.in.state	= bindio.state;				}				else {					bindio.in			= bindio.control;					bindio.in.laddr	= request->from;				}				/* LINTED pointer casts may be troublesome */				bindio.in.raddr					= *(struct sockaddr_in *)&clientaddr;				bindio.out.s						= sv[remote];				/* LINTED pointer casts may be troublesome */				bindio.out.laddr					= *(struct sockaddr_in *)&boundaddr;				/* LINTED pointer casts may be troublesome */				bindio.out.raddr					= *(struct sockaddr_in *)&remoteaddr;				bindio.out.state.auth.method	= AUTHMETHOD_NONE;				if (bindio.state.extension.bind)					/* add to list, client will query. */					iolist = io_add(iolist, &bindio);				else {					response.host = bindio.dst;					flushio(mother, sv[client], &response, &bindio);					sv[client] = sv[remote] = -1; /* flushio() closes; closev(). */					break;	/* only one connection to relay and that is done. */				}			}			if (bindio.state.extension.bind) {				struct sockd_io_t *rmio;				/* delete any connections we have queued. */				while ((rmio = io_find(iolist, NULL)) != NULL) {					close_iodescriptors(rmio);					iolist = io_remove(iolist, rmio);				}			}			closev(sv, ELEMENTS(sv));			break;		}		case SOCKS_CONNECT: {			socklen_t sinlen;			if (socks_connect(out, &io.dst) != 0) {				iolog(&io.rule, &io.state, OPERATION_ABORT, &io.src, &io.dst,				NULL, 0);				send_failure(request->s, &response,				errno2reply(errno, response.version));				close(request->s);				break;			}			io.in.s			= request->s;			io.in.laddr		= request->to;			io.in.raddr		= request->from;			io.in.state		= io.state;			io.out.s			= out;			io.out.state	= io.state;			sinlen			= sizeof(io.out.raddr);			/* LINTED pointer casts may be troublesome */			if (getpeername(io.out.s, (struct sockaddr *)&io.out.raddr, &sinlen)			!= 0) {				swarn("%s: getpeername(io.out.s)", function);				send_failure(request->s, &response, SOCKS_FAILURE);				close(request->s);				break;			}			sinlen = sizeof(io.out.laddr);			/* LINTED pointer casts may be troublesome */			if (getsockname(io.out.s, (struct sockaddr *)&io.out.laddr, &sinlen)			!= 0) {				swarn("%s: getsockname(io.out.s)", function);				send_failure(request->s, &response, SOCKS_FAILURE);				close(request->s);				break;			}			/* LINTED pointer casts may be troublesome */			sockaddr2sockshost((struct sockaddr *)&io.out.laddr, &response.host);			response.reply	= (char)sockscode(response.version, SOCKS_SUCCESS);			flushio(mother, request->s, &response, &io);			break;		}		case SOCKS_UDPASSOCIATE: {			struct sockaddr_in client;			socklen_t boundlen;			int clientfd;			/* socket we receive datagram's from client on */			if ((clientfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {				swarn("%s: socket(SOCK_DGRAM)", function);				send_failure(request->s, &response, SOCKS_FAILURE);				close(request->s);				break;			}			setsockoptions(clientfd);			/* LINTED pointer casts may be troublesome */			sockshost2sockaddr(&request->req.host, (struct sockaddr *)&client);			io.in.s					= clientfd;			io.in.state				= io.state;			io.in.raddr				= client;			io.in.laddr				= request->to;			io.in.laddr.sin_port = htons(0);			/*			 * bind to address for receiving udp packets so we can tell client			 * where to send its packets.			 */			/* LINTED pointer casts may be troublesome */			if (sockd_bind(clientfd, (struct sockaddr *)&io.in.laddr, 0) != 0) {				/* LINTED pointer casts may be troublesome */				swarn("%s: bind(%s)", function,				sockaddr2string((struct sockaddr *)&io.in.laddr, a, sizeof(a)));				send_failure(request->s, &response, SOCKS_FAILURE);				close(request->s);				close(clientfd);				break;			}			boundlen = sizeof(io.in.laddr);			/* LINTED pointer casts may be troublesome */			if (getsockname(clientfd, (struct sockaddr *)&io.in.laddr, &boundlen)			!= 0) {				swarn("%s: getsockname(clientfd)", function);				send_failure(request->s, &response, SOCKS_FAILURE);				close(request->s);				close(clientfd);				break;			}			io.out.s							= out;			io.out.state					= io.state;			io.out.state.auth.method	= AUTHMETHOD_NONE;			boundlen = sizeof(io.out.laddr);			/* LINTED pointer casts may be troublesome */			if (getsockname(out, (struct sockaddr *)&io.out.laddr, &boundlen)			!= 0) {				swarn("%s: getsockname(out)", function);				send_failure(request->s, &response, SOCKS_FAILURE);				close(request->s);				close(clientfd);				break;			}			/* remote out changes each time, set to INADDR_ANY for now. */			bzero(&io.out.raddr, sizeof(io.out.raddr));			io.out.raddr.sin_family			= AF_INET;			io.out.raddr.sin_addr.s_addr	= htonl(INADDR_ANY);			io.out.raddr.sin_port			= htons(0);			io.control.s						= request->s;			io.control.laddr					= request->from;			io.control.raddr					= request->to;			io.control.state					= io.state;			if (request->req.flag & SOCKS_USECLIENTPORT)				if (client.sin_port == io.out.laddr.sin_port)					response.flag |= SOCKS_USECLIENTPORT;			/* LINTED pointer casts may be troublesome */			sockaddr2sockshost((struct sockaddr *)&io.in.laddr, &response.host);			response.reply	= (char)sockscode(response.version, SOCKS_SUCCESS);			flushio(mother, request->s, &response, &io);			break;		}		default:			SERRX(request->req.command);	}	close(out);}static voidflushio(mother, clientcontrol, response, io)	int mother;	int clientcontrol;	const struct response_t *response;	struct sockd_io_t *io;{	const char *function = "flushio()";	socklen_t len;	int sndlowat, value;	float skew;	switch (io->state.command) {		case SOCKS_UDPASSOCIATE:			sndlowat = SOCKD_BUFSIZEUDP;			skew		= 1.0; /* no skew. */			break;		default:			sndlowat = SOCKD_BUFSIZETCP;			skew		= LOWATSKEW;	}	/* set socket options for relay process. */#if SOCKD_IOMAX == 1	/* only one client per process; doesn't matter much whether we block. */	io->in.sndlowat	= sndlowat;	io->out.sndlowat	= sndlowat;#elif	HAVE_SO_SNDLOWAT	len = sizeof(value);	if (getsockopt(io->in.s, SOL_SOCKET, SO_SNDBUF, &value, &len) != 0)		swarn("%s: getsockopt(in, SO_SNDBUF)", function);	sndlowat = MIN(sndlowat, value * skew);	if (setsockopt(io->in.s, SOL_SOCKET, SO_SNDLOWAT, &sndlowat,	sizeof(sndlowat)) != 0)		swarn("%s: setsockopt(in, SO_SNDLOWAT)", function);	len = sizeof(io->in.sndlowat);	if (getsockopt(io->in.s, SOL_SOCKET, SO_SNDLOWAT, &io->in.sndlowat, &len)	!= 0)		swarn("%s: getsockopt(in, SO_SNDLOWAT)", function);	len = sizeof(value);	if (getsockopt(io->out.s, SOL_SOCKET, SO_SNDBUF, &value, &len) != 0)		swarn("%s: getsockopt(out, SO_SNDBUF)", function);	sndlowat = MIN(sndlowat, value * skew);	if (setsockopt(io->out.s, SOL_SOCKET, SO_SNDLOWAT, &sndlowat,	sizeof(sndlowat)) != 0)		swarn("%s: setsockopt(out, SO_SNDLOWAT", function);	len = sizeof(io->out.sndlowat);	if (getsockopt(io->in.s, SOL_SOCKET, SO_SNDLOWAT, &io->out.sndlowat, &len)	!= 0)		swarn("%s: getsockopt(in, SO_SNDLOWAT", function);#else	/* SOCKD_IOMAX > 1 && !HAVE_SO_SNDLOWAT. */	switch (io->state.command) {		case SOCKS_UDPASSOCIATE:			len = sizeof(sndlowat);			if (getsockopt(io->in.s, SOL_SOCKET, SO_SNDBUF, &sndlowat, &len) != 0){				swarn("%s: getsockopt(SO_SNDBUF", function);				io->in.sndlowat = SOCKD_BUFSIZEUDP;			}			else if (sndlowat == 0)				io->in.sndlowat = SOCKD_BUFSIZEUDP;			else				io->in.sndlowat = sndlowat;			len = sizeof(sndlowat);			if (getsockopt(io->out.s, SOL_SOCKET, SO_SNDBUF, &sndlowat, &len)			!= 0) {				swarn("%s: getsockopt(SO_SNDBUF", function);				io->out.sndlowat = SOCKD_BUFSIZEUDP;			}			else if (sndlowat == 0)				io->out.sndlowat = SOCKD_BUFSIZEUDP;			else				io->out.sndlowat = sndlowat;			break;		default:			/* TCP; use minimum guess. */			io->in.sndlowat	= SO_SNDLOWAT_SIZE;			io->out.sndlowat	= SO_SNDLOWAT_SIZE;	}#endif  /* SOCKD_IOMAX > 1 && !HAVE_SO_SNDLOWAT */	SASSERTX(io->in.sndlowat > 0	&& io->out.sndlowat >= sizeof(struct udpheader_t));	if (send_response(clientcontrol, response) == 0)		if (send_io(mother, io) != 0)			serr(EXIT_FAILURE, "%s: sending io to mother failed", function);	close_iodescriptors(io);}static voidproctitleupdate(from)	const struct sockaddr *from;{	char fromstring[MAXSOCKADDRSTRING];	setproctitle("requestcompleter: %s",	from == NULL ?	"<idle>" : sockaddr2string(from, fromstring, sizeof(fromstring)));}static struct sockd_io_t *io_add(iolist, newio)	struct sockd_io_t *iolist;	const struct sockd_io_t *newio;{	const char *function = "io_add()";	struct sockd_io_t *io, *previo;	SASSERTX(newio->next == NULL);	previo = io = iolist;	while (io != NULL) {		previo = io;		io = io->next;	}	if ((io = (struct sockd_io_t *)malloc(sizeof(*newio))) == NULL)		swarnx("%s: %s", function, NOMEM);	else {		*io = *newio;		if (previo == NULL)			previo = io;		else			previo->next = io;	}	return iolist == NULL ? previo : iolist;}static struct sockd_io_t *io_remove(iolist, rmio)	struct sockd_io_t *iolist;	struct sockd_io_t *rmio;{	struct sockd_io_t *io, *previo;	SASSERTX(iolist != NULL);	if (iolist == rmio) {		iolist = rmio->next;		free(rmio);		return iolist;	}	previo = iolist;	io = iolist->next;	while (io != NULL) {		if (io == rmio) {			previo->next = rmio->next;			free(rmio);			break;		}		previo = io;		io = io->next;	}	return iolist;}static struct sockd_io_t *io_find(iolist, addr)	struct sockd_io_t *iolist;	const struct sockaddr *addr;{	struct sockd_io_t *io;	if (addr == NULL)		return iolist;	io = iolist;	while (io != NULL)		/* LINTED pointer casts may be troublesome */		if (sockaddrareeq((struct sockaddr *)&io->in.laddr, addr)		||  sockaddrareeq((struct sockaddr *)&io->out.laddr, addr)		||  sockaddrareeq((struct sockaddr *)&io->control.laddr, addr))			return io;		else			io = io->next;	/* XXX should actually check that the io is still "active". */	return NULL;}

⌨️ 快捷键说明

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