Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for a fixed number of proxies that are *always* used #366

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 50 additions & 20 deletions src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -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 {
Expand All @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions src/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, ...);

Expand Down Expand Up @@ -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
Expand Down
21 changes: 20 additions & 1 deletion src/libproxychains.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -438,6 +439,16 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
}
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")) {
Expand Down Expand Up @@ -520,6 +531,14 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
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));
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions src/proxychains.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down