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

📄 connectchild.c

📁 sock protocol ,it is useful!
💻 C
📖 第 1 页 / 共 2 页
字号:
{	const char *function = "run_connectchild()";	int p, rbits;	fd_set rset;	struct sigaction sig;#if 0	slog(LOG_DEBUG, "%s: sleeping for 10s", function);	sleep(10);#endif	sigemptyset(&sig.sa_mask);	sig.sa_flags	= 0;	sig.sa_handler	= SIG_DFL;	if (sigaction(SIGCONT, &sig, NULL) != 0)		serr(EXIT_FAILURE, "%s: sigaction(SIGCONT)", function);	setproctitle("connectchild");	/* CONSTCOND */	while (1) {		int flags;		FD_ZERO(&rset);		FD_SET(mother, &rset);		rbits = mother;		++rbits;		switch (selectn(rbits, &rset, NULL, NULL, NULL)) {			case -1:				SERR(-1);				/* NOTREACHED */		}		if (FD_ISSET(mother, &rset)) {			/*			 * Mother sending us a connected (or in the process of being			 * connected) socket and necessary info to negotiate with			 * proxyserver.			 */			struct childpacket_t req;			struct iovec iov[1];			socklen_t len;			int s, control;			struct sockaddr local, remote;			struct msghdr msg;			CMSG_AALLOC(sizeof(int) * FDPASS_MAX);			iov[0].iov_base	= &req;			iov[0].iov_len		= sizeof(req);			len					= sizeof(req);			msg.msg_iov          = iov;			msg.msg_iovlen       = ELEMENTS(iov);			msg.msg_name         = NULL;			msg.msg_namelen      = 0;			CMSG_SETHDR_RECV(sizeof(cmsgmem));			if ((p = recvmsgn(mother, &msg, 0, len)) != (ssize_t)len) {				switch (p) {					case -1:						serr(EXIT_FAILURE, "%s: recvmsgn()", function);						/* NOTREACHED */					case 0:						serrx(LOG_DEBUG, "%s: recvmsgn(): mother closed", function);						_exit(EXIT_SUCCESS);						/* NOTREACHED */					default:						swarn("%s: recvmsgn(): got %d of %d",						function, p, len);				}				continue;			}			/* how many descriptors are we supposed to receive? */			switch (req.packet.req.version) {				case MSPROXY_V2:					len = 2;	/* control + socket for dataflow. */					break;				case SOCKS_V4:				case SOCKS_V5:					len = 1; /* only controlsocket (which is also datasocket). */					break;				default:					SERRX(req.packet.req.version);			}#if !HAVE_DEFECT_RECVMSG			SASSERTX(CMSG_GETLEN(msg) == sizeof(int) * len);#endif			len = 0;			CMSG_GETOBJECT(control, sizeof(control) * len++);			switch (req.packet.req.version) {				case MSPROXY_V2:					CMSG_GETOBJECT(s, sizeof(s) * len++);					break;				case SOCKS_V4:				case SOCKS_V5:					s = control;	/* datachannel is controlchannel. */					break;				default:					SERRX(req.packet.req.version);			}#if DIAGNOSTIC			len = sizeof(local);			if (getsockname(s, &local, &len) != 0)				SERR(-1);			slog(LOG_DEBUG, "%s: s local: %s",			function, sockaddr2string(&local, NULL, 0));			len = sizeof(local);			if (getsockname(control, &local, &len) == 0)				slog(LOG_DEBUG, "%s: control local: %s",				function, sockaddr2string(&local, NULL, 0));			else				swarn("%s: getsockname(%d)", function, control);			len = sizeof(local);			if (getpeername(control, &local, &len) == 0)				slog(LOG_DEBUG, "%s: control remote: %s",				function, sockaddr2string(&local, NULL, 0));#endif /* DIAGNOSTIC */			/* XXX set socket to blocking while we use it. */			if ((flags = fcntl(s, F_GETFL, 0)) == -1			|| fcntl(s, F_SETFL, flags & ~NONBLOCKING) == -1)				swarn("%s: fcntl(s)");			/* default, in case we don't even get a response. */			req.packet.res.reply = (char)sockscode(req.packet.req.version,			SOCKS_FAILURE);			req.packet.res.version = req.packet.req.version;			if (1) { /* XXX wait for the connection to complete. */				fd_set wset;				FD_ZERO(&wset);				FD_SET(control, &wset);				slog(LOG_DEBUG, "%s: waiting for connectresponse...", function);				switch (selectn(control + 1, NULL, &wset, NULL, NULL)) {					case -1:						SERR(-1);						/* NOTREACHED */					case 0:						SERRX(0);						/* NOTREACHED */				}			}#if !HAVE_SOLARIS_BUGS			len = sizeof(errno);			if (getsockopt(control, SOL_SOCKET, SO_ERROR, &errno, &len) != 0)				SERR(-1);#else /* !HAVE_SOLARIS_2_5_1 */ /* even read() doesn't work right on 2.5.1. */			errno = 0;			recvfrom(control, NULL, 0, 0, NULL, NULL); /* just get errno. */#endif /* !HAVE_SO_ERROR */			if (errno != 0) {				swarn("%s: connect failed", function);				req.packet.state.err = errno;			}			else				/* connected ok. */				p = socks_negotiate(s, control, &req.packet, NULL);			/* XXX back to original. */			if (fcntl(s, F_SETFL, flags) == -1)				swarn("%s: fcntl(s)");			len = sizeof(local);			if (getsockname(control, &local, &len) != 0) {				if (req.packet.state.err == 0) /* not warned. */					swarn("%s: getsockname(control)", function);				/*				 * this is pretty bad, but it could happen unfortunately.				 */				bzero(&local, sizeof(local));				local.sa_family = AF_INET;				/* LINTED pointer casts may be troublesome */				((struct sockaddr_in *)&local)->sin_addr.s_addr				= htonl(INADDR_ANY);				/* LINTED pointer casts may be troublesome */				((struct sockaddr_in *)&local)->sin_port = htons(0);			}			len = sizeof(remote);			if (getpeername(control, &remote, &len) != 0) {				if (req.packet.state.err != 0) /* not warned. */					swarn("%s: getpeername(control)", function);				bzero(&remote, sizeof(remote));				remote.sa_family = AF_INET;				/* LINTED pointer casts may be troublesome */				((struct sockaddr_in *)&remote)->sin_addr.s_addr				= htonl(INADDR_ANY);				/* LINTED pointer casts may be troublesome */				((struct sockaddr_in *)&remote)->sin_port = htons(0);			}			sockaddr2sockshost(&local, &req.src);			sockaddr2sockshost(&remote, &req.dst);			/* send response to mother. */			if ((p = write(mother, &req, sizeof(req))) != sizeof(req))				swarn("%s: write(): %d out of %d", p, sizeof(req));			close(s);			slog(LOG_DEBUG, "raising SIGSTOP");			if (kill(config.state.pid, SIGSTOP) != 0)				serr(EXIT_FAILURE, "raise(SIGSTOP)");		}	}}static voidsigchld(sig)	int sig;{	const char *function = "sigchld()";	const int errno_s = errno;	int status;	slog(LOG_DEBUG, "%s: connectchild: %d", function, config.connectchild);	switch (waitpid(config.connectchild, &status, WNOHANG | WUNTRACED)) {		case -1:			break;		case 0:			/* Does user have a handler for this signal? */			if (oldsig.sa_handler != NULL) {				errno = errno_s;				oldsig.sa_handler(sig);			}			break;		default: {			struct childpacket_t childres;			struct sockaddr localmem, *local = &localmem;			struct sockaddr remotemem, *remote = &remotemem;			socklen_t len;			struct socksfd_t *socksfd;			int p, s;			/* XXX if child dies, set err in all "inprogress" socksfd's. */			if (WIFSIGNALED(status)) {				swarnx("%s: connectchild terminated on signal %d",				function, WTERMSIG(status));				config.connectchild = 0;				close(config.connect_s);				break;			}			if (WIFEXITED(status)) {				swarnx("%s: cconnectchild exited with status %d",				function, WEXITSTATUS(status));				config.connectchild = 0;				close(config.connect_s);				break;			}			SASSERTX(WIFSTOPPED(status));			kill(config.connectchild, SIGCONT);			if ((p = read(config.connect_s, &childres, sizeof(childres)))			!= sizeof(childres)) {				swarn("%s: read(): got %d of %d", function, p, sizeof(childres));				return;			}			sockshost2sockaddr(&childres.src, local);			sockshost2sockaddr(&childres.dst, remote);			slog(LOG_DEBUG, "%s: local = %s",			function, sockaddr2string(local, NULL, 0));			slog(LOG_DEBUG, "%s: remote = %s",			function, sockaddr2string(remote, NULL, 0));			if ((s = socks_addrcontrol(local, remote)) == -1) {				char lstring[MAXSOCKADDRSTRING];				char rstring[MAXSOCKADDRSTRING];				swarnx("%s: hmm, can't find controlsocket for %s <-> %s",				function, sockaddr2string(local, lstring, sizeof(lstring)),				sockaddr2string(remote, rstring, sizeof(rstring)));				return;			}			socksfd = socks_getaddr((unsigned int)s);			SASSERTX(socksfd != NULL);			switch (socksfd->state.version) {				case MSPROXY_V2:					break; /* nothing to do, control separate from data. */				case SOCKS_V4:				case SOCKS_V5:					slog(LOG_DEBUG, "%s: duping %d over %d",					function, socksfd->control, s);					if (dup2(socksfd->control, s) == -1) {						SASSERT(errno != EBADF);						swarn("%s: dup2(socksfd->control, s)", function);						socksfd->state.err = errno;						break;					}					close(socksfd->control);					socksfd->control = s;					break;				default:					SERRX(socksfd->state.version);			}			/*			 * it's possible endpoint changed/got fixed.  Update in case.			 */			len = sizeof(socksfd->local);			if (getsockname(s, &socksfd->local, &len) != 0)				swarn("%s: getsockname(s)", function);			else				slog(LOG_DEBUG, "%s: socksfd->local: %s",				function, sockaddr2string(&socksfd->local, NULL, 0));			len = sizeof(socksfd->server);			if (getpeername(s, &socksfd->server, &len) != 0)				swarn("%s: getpeername(s)", function);			/* child that was supposed to setup relaying finished.  status? */			if (!serverreplyisok(childres.packet.res.version,			childres.packet.res.reply, socksfd->route)) {				socksfd->state.err = errno;				/*				 * XXX If it's a servererror it would be nice to retry, could				 * be there's a backup route.				 */				return;			}			slog(LOG_DEBUG, "serverreplyisok, server will use as src: %s",			sockshost2string(&childres.packet.res.host, NULL, 0));			socksfd->state.msproxy		= childres.packet.state.msproxy;			socksfd->state.inprogress	= 0;			sockshost2sockaddr(&childres.packet.res.host, &socksfd->remote);			/* needed for standard socks bind. */			config.state.lastconnect = socksfd->connected;		}	}	errno = errno_s;}

⌨️ 快捷键说明

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