mirror of
				https://github.com/rofl0r/proxychains-ng.git
				synced 2025-11-04 00:56:03 +00:00 
			
		
		
		
	add support for a fixed number of proxies that are *always* used
e.g. for having tor fixed as first proxy, then using the rest for random selection.
This commit is contained in:
		
							
								
								
									
										70
									
								
								src/core.c
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								src/core.c
									
									
									
									
									
								
							@@ -475,7 +475,8 @@ static proxy_data *select_proxy(select_type how, proxy_data * pd, unsigned int p
 | 
			
		||||
		case RANDOMLY:
 | 
			
		||||
			do {
 | 
			
		||||
				k++;
 | 
			
		||||
				i = rand() % proxy_count;
 | 
			
		||||
				i = rand() % (proxy_count-proxychains_fixed_chain);
 | 
			
		||||
				i += proxychains_fixed_chain;
 | 
			
		||||
			} while(pd[i].ps != PLAY_STATE && k < proxy_count * 100);
 | 
			
		||||
			break;
 | 
			
		||||
		case FIFOLY:
 | 
			
		||||
@@ -563,9 +564,38 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
 | 
			
		||||
	return retcode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int strict_connect(
 | 
			
		||||
	unsigned *alive_count,
 | 
			
		||||
	unsigned *offset,
 | 
			
		||||
	int *ns,
 | 
			
		||||
	proxy_data **p1, proxy_data **p2,
 | 
			
		||||
	unsigned proxy_count, proxy_data * pd)
 | 
			
		||||
{
 | 
			
		||||
	*alive_count = calc_alive(pd, proxy_count);
 | 
			
		||||
	*offset = 0;
 | 
			
		||||
	if(!(*p1 = select_proxy(FIFOLY, pd, proxy_count, offset))) {
 | 
			
		||||
		PDEBUG("select_proxy failed\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	if(SUCCESS != start_chain(ns, *p1, ST)) {
 | 
			
		||||
		PDEBUG("start_chain failed\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	while(*offset < proxy_count) {
 | 
			
		||||
		if(!(*p2 = select_proxy(FIFOLY, pd, proxy_count, offset)))
 | 
			
		||||
			break;
 | 
			
		||||
		if(SUCCESS != chain_step(*ns, *p1, *p2)) {
 | 
			
		||||
			PDEBUG("chain_step failed\n");
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		*p1 = *p2;
 | 
			
		||||
	}
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int connect_proxy_chain(int sock, ip_type target_ip,
 | 
			
		||||
			unsigned short target_port, proxy_data * pd,
 | 
			
		||||
			unsigned int proxy_count, chain_type ct, unsigned int max_chain) {
 | 
			
		||||
			unsigned int proxy_count, chain_type ct) {
 | 
			
		||||
	proxy_data p4;
 | 
			
		||||
	proxy_data *p1, *p2, *p3;
 | 
			
		||||
	int ns = -1;
 | 
			
		||||
@@ -575,6 +605,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
 | 
			
		||||
	unsigned int curr_len = 0;
 | 
			
		||||
	unsigned int looped = 0; // went back to start of list in RR mode
 | 
			
		||||
	unsigned int rr_loop_max = 14;
 | 
			
		||||
	unsigned int max_chain = proxychains_max_chain;
 | 
			
		||||
 | 
			
		||||
	p3 = &p4;
 | 
			
		||||
 | 
			
		||||
@@ -583,9 +614,14 @@ int connect_proxy_chain(int sock, ip_type target_ip,
 | 
			
		||||
	again:
 | 
			
		||||
	rc = -1;
 | 
			
		||||
	DUMP_PROXY_CHAIN(pd, proxy_count);
 | 
			
		||||
	if(proxychains_fixed_chain) {
 | 
			
		||||
		if(!strict_connect(&alive_count, &offset, &ns, &p1, &p2, proxychains_fixed_chain, pd))
 | 
			
		||||
			goto error_strict;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch (ct) {
 | 
			
		||||
		case DYNAMIC_TYPE:
 | 
			
		||||
			if(proxychains_fixed_chain) goto dyn_fixed_resume;
 | 
			
		||||
			alive_count = calc_alive(pd, proxy_count);
 | 
			
		||||
			offset = 0;
 | 
			
		||||
			do {
 | 
			
		||||
@@ -601,6 +637,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
 | 
			
		||||
					goto again;
 | 
			
		||||
				}
 | 
			
		||||
				p1 = p2;
 | 
			
		||||
		dyn_fixed_resume:;
 | 
			
		||||
			}
 | 
			
		||||
			//proxychains_write_log(TP);
 | 
			
		||||
			p3->ip = target_ip;
 | 
			
		||||
@@ -610,6 +647,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case ROUND_ROBIN_TYPE:
 | 
			
		||||
			// FIXME: add support for fixed_len
 | 
			
		||||
			alive_count = calc_alive(pd, proxy_count);
 | 
			
		||||
			offset = proxychains_proxy_offset;
 | 
			
		||||
			if(alive_count < max_chain)
 | 
			
		||||
@@ -660,25 +698,8 @@ int connect_proxy_chain(int sock, ip_type target_ip,
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case STRICT_TYPE:
 | 
			
		||||
			alive_count = calc_alive(pd, proxy_count);
 | 
			
		||||
			offset = 0;
 | 
			
		||||
			if(!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) {
 | 
			
		||||
				PDEBUG("select_proxy failed\n");
 | 
			
		||||
			if(!strict_connect(&alive_count, &offset, &ns, &p1, &p2, proxy_count, pd))
 | 
			
		||||
				goto error_strict;
 | 
			
		||||
			}
 | 
			
		||||
			if(SUCCESS != start_chain(&ns, p1, ST)) {
 | 
			
		||||
				PDEBUG("start_chain failed\n");
 | 
			
		||||
				goto error_strict;
 | 
			
		||||
			}
 | 
			
		||||
			while(offset < proxy_count) {
 | 
			
		||||
				if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
 | 
			
		||||
					break;
 | 
			
		||||
				if(SUCCESS != chain_step(ns, p1, p2)) {
 | 
			
		||||
					PDEBUG("chain_step failed\n");
 | 
			
		||||
					goto error_strict;
 | 
			
		||||
				}
 | 
			
		||||
				p1 = p2;
 | 
			
		||||
			}
 | 
			
		||||
			//proxychains_write_log(TP);
 | 
			
		||||
			p3->ip = target_ip;
 | 
			
		||||
			p3->port = target_port;
 | 
			
		||||
@@ -687,6 +708,12 @@ int connect_proxy_chain(int sock, ip_type target_ip,
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case RANDOM_TYPE:
 | 
			
		||||
			if(proxychains_fixed_chain) {
 | 
			
		||||
				if(alive_count < max_chain)
 | 
			
		||||
					goto error_more;
 | 
			
		||||
				curr_len = proxychains_fixed_chain - 1;
 | 
			
		||||
				goto random_fixed_resume;
 | 
			
		||||
			}
 | 
			
		||||
			alive_count = calc_alive(pd, proxy_count);
 | 
			
		||||
			if(alive_count < max_chain)
 | 
			
		||||
				goto error_more;
 | 
			
		||||
@@ -695,6 +722,9 @@ int connect_proxy_chain(int sock, ip_type target_ip,
 | 
			
		||||
				if(!(p1 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
 | 
			
		||||
					goto error_more;
 | 
			
		||||
			} while(SUCCESS != start_chain(&ns, p1, RT) && offset < max_chain);
 | 
			
		||||
 | 
			
		||||
		random_fixed_resume:;
 | 
			
		||||
 | 
			
		||||
			while(++curr_len < max_chain) {
 | 
			
		||||
				if(!(p2 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
 | 
			
		||||
					goto error_more;
 | 
			
		||||
 
 | 
			
		||||
@@ -84,8 +84,7 @@ typedef struct {
 | 
			
		||||
} proxy_data;
 | 
			
		||||
 | 
			
		||||
int connect_proxy_chain (int sock, ip_type target_ip, unsigned short target_port,
 | 
			
		||||
			 proxy_data * pd, unsigned int proxy_count, chain_type ct,
 | 
			
		||||
			 unsigned int max_chain );
 | 
			
		||||
			 proxy_data * pd, unsigned int proxy_count, chain_type ct );
 | 
			
		||||
 | 
			
		||||
void proxychains_write_log(char *str, ...);
 | 
			
		||||
 | 
			
		||||
@@ -130,6 +129,9 @@ void proxy_freeaddrinfo(struct addrinfo *res);
 | 
			
		||||
void core_initialize(void);
 | 
			
		||||
void core_unload(void);
 | 
			
		||||
 | 
			
		||||
extern unsigned int proxychains_max_chain;
 | 
			
		||||
extern unsigned int proxychains_fixed_chain;
 | 
			
		||||
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -71,6 +71,7 @@ unsigned int proxychains_proxy_count = 0;
 | 
			
		||||
unsigned int proxychains_proxy_offset = 0;
 | 
			
		||||
int proxychains_got_chain_data = 0;
 | 
			
		||||
unsigned int proxychains_max_chain = 1;
 | 
			
		||||
unsigned int proxychains_fixed_chain = 0;
 | 
			
		||||
int proxychains_quiet_mode = 0;
 | 
			
		||||
enum dns_lookup_flavor proxychains_resolver = DNSLF_LIBC;
 | 
			
		||||
localaddr_arg localnet_addr[MAX_LOCALNET];
 | 
			
		||||
@@ -438,6 +439,16 @@ inv_host:
 | 
			
		||||
					}
 | 
			
		||||
					len = atoi(++pc);
 | 
			
		||||
					proxychains_max_chain = (len ? len : 1);
 | 
			
		||||
				} else if(STR_STARTSWITH(buff, "fixed_len")) {
 | 
			
		||||
					char *pc;
 | 
			
		||||
					int len;
 | 
			
		||||
					pc = strchr(buff, '=');
 | 
			
		||||
					if(!pc) {
 | 
			
		||||
						fprintf(stderr, "error: missing equals sign '=' in fixed_len directive.\n");
 | 
			
		||||
						exit(1);
 | 
			
		||||
					}
 | 
			
		||||
					len = atoi(++pc);
 | 
			
		||||
					proxychains_fixed_chain = (len ? len : 1);
 | 
			
		||||
				} else if(!strcmp(buff, "quiet_mode")) {
 | 
			
		||||
					proxychains_quiet_mode = 1;
 | 
			
		||||
				} else if(!strcmp(buff, "proxy_dns_old")) {
 | 
			
		||||
@@ -520,6 +531,14 @@ inv_host:
 | 
			
		||||
		fprintf(stderr, "error: no valid proxy found in config\n");
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
	if(proxychains_max_chain <= proxychains_fixed_chain) {
 | 
			
		||||
		fprintf(stderr, "error: fixed_len needs to be smaller than chain_len\n");
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
	if(proxychains_fixed_chain > count) {
 | 
			
		||||
		fprintf(stderr, "error: fixed_len > proxycount\n");
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
	*proxy_count = count;
 | 
			
		||||
	proxychains_got_chain_data = 1;
 | 
			
		||||
	PDEBUG("proxy_dns: %s\n", rdns_resolver_string(proxychains_resolver));
 | 
			
		||||
@@ -630,7 +649,7 @@ int connect(int sock, const struct sockaddr *addr, unsigned int len) {
 | 
			
		||||
	ret = connect_proxy_chain(sock,
 | 
			
		||||
				  dest_ip,
 | 
			
		||||
				  htons(port),
 | 
			
		||||
				  proxychains_pd, proxychains_proxy_count, proxychains_ct, proxychains_max_chain);
 | 
			
		||||
				  proxychains_pd, proxychains_proxy_count, proxychains_ct);
 | 
			
		||||
 | 
			
		||||
	fcntl(sock, F_SETFL, flags);
 | 
			
		||||
	if(ret != SUCCESS)
 | 
			
		||||
 
 | 
			
		||||
@@ -45,6 +45,12 @@ strict_chain
 | 
			
		||||
# Make sense only if random_chain or round_robin_chain
 | 
			
		||||
#chain_len = 2
 | 
			
		||||
 | 
			
		||||
# use this if you want to use e.g. random_chain but always have
 | 
			
		||||
# e.g. tor as first proxy. in that case only chain_len - fixed_len proxies
 | 
			
		||||
# will be used for random chain.
 | 
			
		||||
# currently only implemented for dynamic_chain and random_chain.
 | 
			
		||||
#fixed_len = 1
 | 
			
		||||
 | 
			
		||||
# Quiet mode (no output from library)
 | 
			
		||||
#quiet_mode
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user