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

📄 config.c

📁 sock protocol ,it is useful!
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (list == NULL)		return 0;	while (*list != NULL)		if (hostareeq(host, *list))			return 1;		else			++list;	return 0;}static inthostareeq(domain, remotedomain)	const char *domain;	const char *remotedomain;{	const int domainlen = strlen(domain);	const int remotedomainlen = strlen(remotedomain);	if	(*domain == '.')	{ /* match everything ending in domain */		if (domainlen - 1 > remotedomainlen)			return 0;	/* address to compare against too short, can't match. */		return strcasecmp(domain + 1,		remotedomain + (remotedomainlen - (domainlen - 1))) == 0;	}	else /* need exact match. */		return strcasecmp(domain, remotedomain) == 0;}#if SOCKS_CLIENTstruct route_t *addroute(newroute)	const struct route_t *newroute;{	const char *function = "addroute()";	static const struct serverstate_t state;	struct route_t *route;	if ((route = (struct route_t *)malloc(sizeof(*route))) == NULL)		serrx(1, "%s: %s", function, NOMEM);	*route = *newroute;	/* check gateway. */	/* if no command set, set all. */	if (memcmp(&state.command, &route->gw.state.command, sizeof(state.command))	== 0)		memset(&route->gw.state.command, UCHAR_MAX,		sizeof(route->gw.state.command));	/* if no protocol set, set all. */	if (memcmp(&state.protocol, &route->gw.state.protocol,	sizeof(state.protocol)) == 0)		memset(&route->gw.state.protocol, UCHAR_MAX,		sizeof(route->gw.state.protocol));	/* if no proxyprotocol set, set all except msproxy. */	if (memcmp(&state.proxyprotocol, &route->gw.state.proxyprotocol,	sizeof(state.proxyprotocol)) == 0) {		memset(&route->gw.state.proxyprotocol, UCHAR_MAX,		sizeof(route->gw.state.proxyprotocol));		route->gw.state.proxyprotocol.msproxy_v2 = 0;	}	/* if no method set, set all we support. */	if (route->gw.state.methodc == 0) {		int *methodv = route->gw.state.methodv;		int *methodc = &route->gw.state.methodc;		methodv[(*methodc)++] = AUTHMETHOD_NONE;		methodv[(*methodc)++] = AUTHMETHOD_UNAME;	}	if (config.route == NULL) {		config.route = route;		config.route->number = 1;	}	else {		/* append rule to the end of list. */		struct route_t *lastroute;		lastroute = config.route;		while (lastroute->next != NULL)			lastroute = lastroute->next;		route->number = lastroute->number + 1;		lastroute->next = route;	}	route->next = NULL;	return route;}voidshowroute(route)	const struct route_t *route;{	char hstring[MAXSOCKSHOSTSTRING];	char addr[MAXRULEADDRSTRING];	slog(LOG_INFO, "route #%d", route->number);	slog(LOG_INFO, "src: %s",	ruleaddress2string(&route->src, addr, sizeof(addr)));	slog(LOG_INFO, "dst: %s",	ruleaddress2string(&route->dst, addr, sizeof(addr)));	slog(LOG_INFO, "gateway: %s",	sockshost2string(&route->gw.host, hstring, sizeof(hstring)));	showstate(&route->gw.state);}struct route_t *socks_getroute(req, src, dst)	const struct request_t *req;	const struct sockshost_t *src;	const struct sockshost_t *dst;{	struct route_t *route;	int protocol;#if SOCKS_CLIENT	clientinit();#endif	for (route = config.route; route != NULL; route = route->next) {		if (route->state.bad)			continue; /* XXX code to retry and remove bad status when ok. */		switch (req->version) {			case SOCKS_V4:				if (!route->gw.state.proxyprotocol.socks_v4)					continue;				switch (req->host.atype) {					case SOCKS_ADDR_IPV4:						break;					case SOCKS_ADDR_IPV6:					case SOCKS_ADDR_DOMAIN:						continue; /* not failure, just checking. */					default:						SERRX(req->host.atype); /* failure, nothing else exists. */				}				break;			case SOCKS_V5:				if (!route->gw.state.proxyprotocol.socks_v5)					continue;				switch (req->host.atype) {					case SOCKS_ADDR_IPV4:					case SOCKS_ADDR_IPV6:					case SOCKS_ADDR_DOMAIN:						break;					default:						SERRX(req->host.atype); /* failure, nothing else exists. */				}				break;			case MSPROXY_V2:				if (!route->gw.state.proxyprotocol.msproxy_v2)					continue;				break;			default:				SERRX(req->version);		}		switch (req->command) {			case SOCKS_BIND:				if (!route->gw.state.command.bind)					continue;				if (req->host.atype == SOCKS_ADDR_IPV4				&&  req->host.addr.ipv4.s_addr == htonl(0))					if (req->version == MSPROXY_V2)						; /* supports binding wildcard */					else if (!route->gw.state.extension.bind)						continue;				break;			case SOCKS_CONNECT:				if (!route->gw.state.command.connect)					continue;				break;			case SOCKS_UDPASSOCIATE:				if (!route->gw.state.command.udpassociate)					continue;				break;			default:				SERRX(req->command);		}		/* server supports protocol? */		switch (req->command) {			case SOCKS_BIND:			case SOCKS_CONNECT:				if (!route->gw.state.protocol.tcp)					continue;				protocol = SOCKS_TCP;				break;			case SOCKS_UDPASSOCIATE:				if (!route->gw.state.protocol.udp)					continue;				protocol = SOCKS_UDP;				break;			default:				SERRX(req->command);		}		if (src != NULL)			if (!addressmatch(&route->src, src, protocol, 0))				continue;		if (dst != NULL)			if (!addressmatch(&route->dst, dst, protocol, 0))				continue;		if (route->state.direct)			return NULL; /* don't use any route, connect directly. */		break;	/* all matched */	}	return route;}struct route_t *socks_connectroute(s, packet, src, dst)	int s;	struct socks_t *packet;	const struct sockshost_t *src;	const struct sockshost_t *dst;{	const char *function = "socks_connectroute()";	int sdup, current_s, errno_s;	struct route_t *route;	/*	 * This is a little tricky since we attempt to support trying	 * more than one socksserver.  If the first one fails, we try	 * the next, etc.  Ofcourse, if connect() on one socket fails,	 * that socket can no longer be used, so we need to be able to	 * copy/dup the original socket as much as possible.  Later,	 * if it turned out a connection failed and we had to use a	 * different socket than the orignal 's', we try to dup the	 * differently numbered socket to 's' and hope the best.	 *	 * sdup:			copy of the original socket.  Need to create this	 *					before the first connectattempt since the connectattempt	 *				   could prevent us from doing it later, depending on failure	 *					reason.	 *	 * current_s:	socket to use for next connection attempt.  For the	 *					first attempt this is 's'.	 */	errno			= 0; /* let caller differentiate between missing route and not.*/	current_s	= s;	sdup			= -1;	while ((route = socks_getroute(&packet->req, src, dst)) != NULL) {		char hstring[MAXSOCKSHOSTSTRING];		/* inside loop since if no route, no need for it. */		if (sdup == -1)			sdup = socketoptdup(s);		if (current_s == -1)			if ((current_s = socketoptdup(sdup == -1 ? s : sdup)) == -1)				return NULL;		slog(LOG_DEBUG, "%s: trying route #%d (%s)",		function, route->number,		sockshost2string(&route->gw.host, hstring, sizeof(hstring)));		if (socks_connect(current_s, &route->gw.host) == 0)			break;		else			/*			 * Check whether the error indicates bad socksserver or			 * something else.			 */			if (errno == EINPROGRESS) {				SASSERTX(current_s == s);				break;			}			else if (errno == EADDRINUSE) {				/* see Rbind() for explanation. */				SASSERTX(current_s == s);				route = NULL;				break;			}			else {				swarn("%s: socks_connect(%s)",				function, sockshost2string(&route->gw.host, hstring,				sizeof(hstring)));				socks_badroute(route);				close(current_s);				current_s = -1;		}	}	errno_s = errno;	if (sdup != -1)		close(sdup);	if (current_s != s && current_s != -1)	{		/* created a new socket for connect, need to make it same descriptor #. */		if (dup2(current_s, s) == -1) {			close(current_s);			return NULL;		}		close(current_s);#if SOCKS_SERVER && HAVE_LIBWRAP		if ((current_s = fcntl(s, F_GETFD, 0)) == -1		|| fcntl(s, F_SETFD, current_s | FD_CLOEXEC) == -1)			swarn("%s: fcntl(F_GETFD/F_SETFD)", function);#endif	}	if (route != NULL) {		static int init;		packet->gw = route->gw;		/* need to set up misc. crap for msproxy stuff. */		if (!init && route->gw.state.proxyprotocol.msproxy_v2) {			if (msproxy_init() != 0)				;	/* yes, then what? */			init = 1;		}	}	errno = errno_s;	return route;}voidsocks_badroute(route)	struct route_t *route;{	const char *function = "socks_badroute()";	slog(LOG_DEBUG, "%s: badrouting route #%d", function, route->number);	route->state.bad = 1;}struct request_t *socks_requestpolish(req, src, dst)	struct request_t *req;	const struct sockshost_t *src;	const struct sockshost_t *dst;{	const char *function = "socks_requestpolish()";	unsigned char version;	if (socks_getroute(req, src, dst) != NULL)		return req;	switch (req->command) {		case SOCKS_BIND:		case SOCKS_CONNECT:			break;		case SOCKS_UDPASSOCIATE:			SERRX(req->command);	/* currently not implemented, shouldn't happen. */			/* NOTREACHED */		default:			SERRX(req->command);	}	/* unsupported version? */	switch (req->version) {		case SOCKS_V4:			req->version = SOCKS_V5;			break;		case SOCKS_V5:			req->version = SOCKS_V4;			break;	}	if (socks_getroute(req, src, dst) != NULL)		return req;	SASSERTX(req->version != MSPROXY_V2); /* never gets set outside function. */	version = req->version;	req->version = MSPROXY_V2;	if (socks_getroute(req, src, dst) != NULL)		return req;	req->version = version;	switch (req->command) {		case SOCKS_BIND:			if (req->host.addr.ipv4.s_addr == htonl(0)) {				const in_port_t originalport = req->host.port;				const int originalversion = req->version;				/* attempting to use bind extension, can we retry without it? */				/* LINTED pointer casts may be troublesome */				if (ADDRISBOUND(config.state.lastconnect)) {					fakesockaddr2sockshost(&config.state.lastconnect, &req->host);					/*					 * v4 and v5 differ in how portnumber is treated					 * so we need to be a little smarter than just returning					 * the result of the next socks_requestpolish()					 * while we still have the original portnumber.					 */					switch (req->version) {						case SOCKS_V4:							/* LINTED pointer casts may be troublesome */							req->host.port = ((struct sockaddr_in *)							&config.state.lastconnect)->sin_port;							break;						case SOCKS_V5:							/* only wants ip address. */							req->host.port = originalport;							break;						default:							SERRX(req->version);					}					if (socks_requestpolish(req, src, dst) == NULL)						return NULL;					/*					 * else, it may be that socks_requestpolish() was					 * forced to change req.version to succeed, we then					 * need to change req->host.port due to difference in					 * v4 and v5 semantics.					*/					if (req->version != originalversion) { /* version changed. */						/* currently it can only change from 4 to 5, or 5 to 4. */						switch (req->version) {							case SOCKS_V4:								/* LINTED pointer casts may be troublesome */								req->host.port = ((struct sockaddr_in *)								&config.state.lastconnect)->sin_port;								break;							case SOCKS_V5:								req->host.port = originalport;								break;							default:								SERRX(req->version);						}					}					return socks_requestpolish(req, src, dst);				}				else					slog(LOG_DEBUG,					"%s: couldn't find route for bind, try enabling bind extension?",					function);			}			break;	}	return NULL;}#endif /* SOCKS_CLIENT */voidshowstate(state)	const struct serverstate_t *state;{	int i;	char buf[1024];	size_t bufused;	bufused = snprintf(buf, sizeof(buf), "command(s): ");	if (state->command.bind)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		SOCKS_BINDs);	if (state->command.bindreply)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		SOCKS_BINDREPLYs);	if (state->command.connect)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		SOCKS_CONNECTs);	if (state->command.udpassociate)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		SOCKS_UDPASSOCIATEs);	if (state->command.udpreply)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		SOCKS_UDPREPLYs);	slog(LOG_INFO, buf);	bufused = snprintf(buf, sizeof(buf), "extension(s): ");	if (state->extension.bind)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "bind");	slog(LOG_INFO, buf);	bufused = snprintf(buf, sizeof(buf), "protocol(s): ");	if (state->protocol.tcp)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		PROTOCOL_TCPs);	if (state->protocol.udp)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		PROTOCOL_UDPs);	slog(LOG_INFO, buf);	bufused = snprintf(buf, sizeof(buf), "method(s): ");	for (i = 0; i < state->methodc; ++i)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",		method2string(state->methodv[i]));	slog(LOG_INFO, buf);	bufused = snprintf(buf, sizeof(buf), "proxyprotocol(s): ");	if (state->proxyprotocol.socks_v4)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "socks v4, ");	if (state->proxyprotocol.socks_v5)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "socks v5, ");	if (state->proxyprotocol.msproxy_v2)		bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "msproxy v2");	slog(LOG_INFO, buf);}

⌨️ 快捷键说明

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