mirror of
https://github.com/3proxy/3proxy.git
synced 2025-02-23 02:25:40 +08:00
Support IPv6 for parent proxy
Parent proxy can be on IPv6 network (except SOCKS4).
This commit is contained in:
parent
d2437975b7
commit
8a6632f0d1
@ -1147,8 +1147,8 @@ static int h_parent(int argc, unsigned char **argv){
|
||||
fprintf(stderr, "Chaining error: bad chain type (%s)\n", argv[2]);
|
||||
return(4);
|
||||
}
|
||||
chains->redirip = getip(argv[3]);
|
||||
chains->redirport = htons((unsigned short)atoi((char *)argv[4]));
|
||||
if(!getip46(46, argv[3], (struct sockaddr *)&chains->addr)) return 5;
|
||||
*SAPORT(&chains->addr) = htons((unsigned short)atoi((char *)argv[4]));
|
||||
if(argc > 5) chains->extuser = (unsigned char *)mystrdup((char *)argv[5]);
|
||||
if(argc > 6) chains->extpass = (unsigned char *)mystrdup((char *)argv[6]);
|
||||
return 0;
|
||||
@ -1523,13 +1523,14 @@ static int h_ace(int argc, unsigned char **argv){
|
||||
switch(acl->action){
|
||||
case REDIRECT:
|
||||
acl->chains = myalloc(sizeof(struct chain));
|
||||
memset(acl->chains, 0, sizeof(struct chain));
|
||||
if(!acl->chains) {
|
||||
fprintf(stderr, "No memory for ACL entry, line %d\n", linenum);
|
||||
return(2);
|
||||
}
|
||||
acl->chains->type = R_HTTP;
|
||||
acl->chains->redirip = getip(argv[1]);
|
||||
acl->chains->redirport = htons((unsigned short)atoi((char *)argv[2]));
|
||||
if(!getip46(46, argv[1], (struct sockaddr *)&acl->chains->addr)) return 5;
|
||||
*SAPORT(&acl->chains->addr) = htons((unsigned short)atoi((char *)argv[2]));
|
||||
acl->chains->weight = 1000;
|
||||
acl->chains->extuser = NULL;
|
||||
acl->chains->extpass = NULL;
|
||||
|
58
src/auth.c
58
src/auth.c
@ -13,16 +13,13 @@
|
||||
#define RECORDSIZE 18
|
||||
|
||||
|
||||
int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned long ip, unsigned short port){
|
||||
int clientnegotiate(struct chain * redir, struct clientparam * param, struct sockaddr * addr){
|
||||
unsigned char buf[1024];
|
||||
struct in_addr ina;
|
||||
int res;
|
||||
int len=0;
|
||||
unsigned char * user, *pass;
|
||||
|
||||
ina.s_addr = ip;
|
||||
|
||||
|
||||
user = redir->extuser;
|
||||
pass = redir->extpass;
|
||||
if(user) {
|
||||
@ -39,15 +36,17 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned l
|
||||
case R_CONNECT:
|
||||
case R_CONNECTP:
|
||||
{
|
||||
sprintf((char *)buf, "CONNECT ");
|
||||
len = sprintf((char *)buf, "CONNECT ");
|
||||
if(redir->type == R_CONNECTP && param->hostname) {
|
||||
len = 8 + sprintf((char *)buf + 8, "%.256s", param->hostname);
|
||||
len =+ sprintf((char *)buf + len, "%.256s", param->hostname);
|
||||
}
|
||||
else {
|
||||
len = 8 + myinet_ntop(AF_INET, &ina, (char *)buf+8, 256);
|
||||
if(*SAFAMILY(addr) == AF_INET6) buf[len++] = '[';
|
||||
len += myinet_ntop(AF_INET, SAADDR(addr), (char *)buf+8, 256);
|
||||
if(*SAFAMILY(addr) == AF_INET6) buf[len++] = ']';
|
||||
}
|
||||
len += sprintf((char *)buf + len,
|
||||
":%hu HTTP/1.0\r\nProxy-Connection: keep-alive\r\n", ntohs(port));
|
||||
":%hu HTTP/1.0\r\nProxy-Connection: keep-alive\r\n", *SAPORT(addr));
|
||||
if(user){
|
||||
unsigned char username[256];
|
||||
len += sprintf((char *)buf + len, "Proxy-authorization: basic ");
|
||||
@ -73,14 +72,15 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned l
|
||||
case R_SOCKS4B:
|
||||
{
|
||||
|
||||
if(*SAFAMILY(addr) != AF_INET) return 44;
|
||||
buf[0] = 4;
|
||||
buf[1] = 1;
|
||||
memcpy(buf+2, &port, 2);
|
||||
memcpy(buf+2, SAPORT(addr), 2);
|
||||
if(redir->type == R_SOCKS4P && param->hostname) {
|
||||
buf[4] = buf[5] = buf[6] = 0;
|
||||
buf[7] = 3;
|
||||
}
|
||||
else memcpy(buf+4, &ip, 4);
|
||||
else memcpy(buf+4, SAADDR(addr), 4);
|
||||
if(!user)user = (unsigned char *)"anonymous";
|
||||
len = (int)strlen((char *)user) + 1;
|
||||
memcpy(buf+8, user, len);
|
||||
@ -162,11 +162,12 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned l
|
||||
len += 5;
|
||||
}
|
||||
else {
|
||||
buf[3] = 1;
|
||||
memcpy(buf+4, &ip, 4);
|
||||
len = 8;
|
||||
len = 3;
|
||||
buf[len++] = (*SAFAMILY(addr) == AF_INET)? 1 : 4;
|
||||
memcpy(buf+len, SAADDR(addr), SAADDRLEN(addr));
|
||||
len += SAADDRLEN(addr);
|
||||
}
|
||||
memcpy(buf+len, &port, 2);
|
||||
memcpy(buf+len, SAPORT(addr), 2);
|
||||
len += 2;
|
||||
if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) != len){
|
||||
return 51;
|
||||
@ -210,7 +211,9 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
|
||||
if(param->remsock != INVALID_SOCKET) {
|
||||
return 0;
|
||||
}
|
||||
if(!memcmp(SAADDR(¶m->req),"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",SAADDRLEN(¶m->req)) || !*SAPORT(¶m->req)) return 100;
|
||||
if(SAISNULL(¶m->req) || !*SAPORT(¶m->req)) {
|
||||
return 100;
|
||||
}
|
||||
|
||||
r2 = (myrand(param, sizeof(struct clientparam))%1000);
|
||||
|
||||
@ -231,7 +234,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
|
||||
r2 = (myrand(param, sizeof(struct clientparam))%1000);
|
||||
}
|
||||
if(!connected){
|
||||
if(!cur->redirip && !cur->redirport){
|
||||
if(SAISNULL(&cur->addr) && !*SAPORT(&cur->addr)){
|
||||
if(cur->extuser){
|
||||
if(param->extusername)
|
||||
myfree(param->extusername);
|
||||
@ -266,19 +269,14 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if(!cur->redirport && cur->redirip) {
|
||||
else if(!*SAPORT(&cur->addr) && !SAISNULL(&cur->addr)) {
|
||||
unsigned short port = *SAPORT(¶m->sinsr);
|
||||
memset(¶m->sinsl, 0, sizeof(param->sinsr));
|
||||
*SAFAMILY(¶m->sinsr) = AF_INET;
|
||||
*(unsigned long *)SAADDR(¶m->sinsr) = cur->redirip;
|
||||
memcpy(¶m->sinsr, &cur->addr, SASIZE(&cur->addr));
|
||||
*SAPORT(¶m->sinsr) = port;
|
||||
}
|
||||
else if(!cur->redirip && cur->redirport) *SAPORT(¶m->sinsr) = cur->redirport;
|
||||
else if(*SAFAMILY(¶m->req) == AF_INET){
|
||||
memset(¶m->sinsr, 0, sizeof(param->sinsr));
|
||||
*SAFAMILY(¶m->sinsr) = AF_INET;
|
||||
*(unsigned long *)SAADDR(¶m->sinsr) = cur->redirip;
|
||||
*SAPORT(¶m->sinsr) = cur->redirport;
|
||||
else if(SAISNULL(&cur->addr) && *SAPORT(&cur->addr)) *SAPORT(¶m->sinsr) = *SAPORT(&cur->addr);
|
||||
else {
|
||||
memcpy(¶m->sinsr, &cur->addr, SASIZE(&cur->addr));
|
||||
}
|
||||
|
||||
if((res = alwaysauth(param))){
|
||||
@ -286,7 +284,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
|
||||
}
|
||||
}
|
||||
else {
|
||||
res = (redir && *SAFAMILY(¶m->req) == AF_INET)?clientnegotiate(redir, param, cur->redirip, cur->redirport):0;
|
||||
res = (redir)?clientnegotiate(redir, param, (struct sockaddr *)&cur->addr):0;
|
||||
if(res) return res;
|
||||
}
|
||||
redir = cur;
|
||||
@ -309,7 +307,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
|
||||
}
|
||||
|
||||
if(!connected) return 9;
|
||||
return (redir && *SAFAMILY(¶m->req) == AF_INET)?clientnegotiate(redir, param, *(unsigned long *)SAADDR(¶m->req), *SAPORT(¶m->req)):0;
|
||||
return (redir)?clientnegotiate(redir, param, (struct sockaddr *)¶m->req):0;
|
||||
}
|
||||
|
||||
int IPInentry(struct sockaddr *sa, struct iplist *ipentry){
|
||||
@ -347,7 +345,7 @@ int ACLmatches(struct ace* acentry, struct clientparam * param){
|
||||
}
|
||||
if(!ipentry) return 0;
|
||||
}
|
||||
if((acentry->dst && memcmp(SAADDR(¶m->req), "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", SAADDRLEN(¶m->req))) || (acentry->dstnames && param->hostname)) {
|
||||
if((acentry->dst && SAISNULL(¶m->req)) || (acentry->dstnames && param->hostname)) {
|
||||
for(ipentry = acentry->dst; ipentry; ipentry = ipentry->next)
|
||||
if(IPInentry((struct sockaddr *)¶m->req, ipentry)) {
|
||||
break;
|
||||
@ -596,7 +594,7 @@ int checkACL(struct clientparam * param){
|
||||
if(param->operation < 256 && !(param->operation & CONNECT)){
|
||||
continue;
|
||||
}
|
||||
if(param->redirected && acentry->chains && !acentry->chains->redirip && !acentry->chains->redirport) {
|
||||
if(param->redirected && acentry->chains && SAISNULL(&acentry->chains->addr) && !*SAPORT(&acentry->chains->addr)) {
|
||||
continue;
|
||||
}
|
||||
memcpy(&dup, acentry, sizeof(struct ace));
|
||||
|
10
src/common.c
10
src/common.c
@ -36,7 +36,7 @@ int myinet_ntop(int af, void *src, char *dst, socklen_t size){
|
||||
}
|
||||
*dst = 0;
|
||||
inet_ntop(af, src, dst, size);
|
||||
return strlen(dst);
|
||||
return (int)strlen(dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -90,6 +90,8 @@ struct extparam conf = {
|
||||
|
||||
int numservers=0;
|
||||
|
||||
char* NULLADDR="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
|
||||
int myrand(void * entropy, int len){
|
||||
int i;
|
||||
unsigned short init;
|
||||
@ -613,8 +615,10 @@ int doconnect(struct clientparam * param){
|
||||
else {
|
||||
struct linger lg;
|
||||
|
||||
if(!memcmp(SAADDR(¶m->sinsr), "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", SAADDRLEN(¶m->sinsr))){
|
||||
if(!memcmp(SAADDR(¶m->req), "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", SAADDRLEN(¶m->req))) return 100;
|
||||
if(SAISNULL(¶m->sinsr)){
|
||||
if(SAISNULL(¶m->req)) {
|
||||
return 100;
|
||||
}
|
||||
*SAFAMILY(¶m->sinsr) = *SAFAMILY(¶m->req);
|
||||
memcpy(SAADDR(¶m->sinsr), SAADDR(¶m->req), SAADDRLEN(¶m->req));
|
||||
}
|
||||
|
@ -344,12 +344,8 @@ static void * ef_chain_type(struct node * node){
|
||||
}
|
||||
}
|
||||
|
||||
static void * ef_chain_ip(struct node * node){
|
||||
return &((struct chain *)node->value) -> redirip;
|
||||
}
|
||||
|
||||
static void * ef_chain_port(struct node * node){
|
||||
return &((struct chain *)node->value) -> redirport;
|
||||
static void * ef_chain_addr(struct node * node){
|
||||
return &((struct chain *)node->value) -> addr;
|
||||
}
|
||||
|
||||
static void * ef_chain_weight(struct node * node){
|
||||
@ -690,12 +686,11 @@ static struct property prop_pwlist[] = {
|
||||
};
|
||||
|
||||
static struct property prop_chain[] = {
|
||||
{prop_chain + 1, "ip", ef_chain_ip, TYPE_IP, "parent ip address"},
|
||||
{prop_chain + 2, "port", ef_chain_port, TYPE_PORT, "parent port"},
|
||||
{prop_chain + 3, "type", ef_chain_type, TYPE_STRING, "parent type"},
|
||||
{prop_chain + 4, "weight", ef_chain_weight, TYPE_SHORT, "parent weight 0-1000"},
|
||||
{prop_chain + 5, "user", ef_chain_user, TYPE_STRING, "parent login"},
|
||||
{prop_chain + 6, "password", ef_chain_password, TYPE_STRING, "parent password"},
|
||||
{prop_chain + 1, "addr", ef_chain_addr, TYPE_SA, "parent address"},
|
||||
{prop_chain + 2, "type", ef_chain_type, TYPE_STRING, "parent type"},
|
||||
{prop_chain + 3, "weight", ef_chain_weight, TYPE_SHORT, "parent weight 0-1000"},
|
||||
{prop_chain + 4, "user", ef_chain_user, TYPE_STRING, "parent login"},
|
||||
{prop_chain + 5, "password", ef_chain_password, TYPE_STRING, "parent password"},
|
||||
{NULL, "next", ef_chain_next, TYPE_CHAIN, "next"}
|
||||
};
|
||||
|
||||
|
@ -102,7 +102,7 @@ void * sockschild(struct clientparam* param) {
|
||||
*SAFAMILY(¶m->sinsr) = *SAFAMILY(¶m->req) = (c == 1)? AF_INET:AF_INET6;
|
||||
memcpy(SAADDR(¶m->sinsr), buf, size);
|
||||
memcpy(SAADDR(¶m->req), buf, size);
|
||||
if(command==1 && !memcmp(SAADDR(¶m->req), "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", size)) {
|
||||
if(command==1 && SAISNULL(¶m->req)) {
|
||||
RETURN(421);
|
||||
}
|
||||
myinet_ntop(*SAFAMILY(¶m->sinsr), SAADDR(¶m->sinsr), (char *)buf, 64);
|
||||
@ -269,7 +269,7 @@ fflush(stderr);
|
||||
param->res = 462;
|
||||
break;
|
||||
}
|
||||
if(!memcmp(SAADDR(¶m->req),"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",SAADDRLEN(¶m->req)) &&
|
||||
if(SAISNULL(¶m->req) &&
|
||||
memcmp(SAADDR(¶m->req),SAADDR(¶m->sinsr),SAADDRLEN(¶m->req))) {
|
||||
param->res = 470;
|
||||
break;
|
||||
|
@ -108,14 +108,17 @@ int
|
||||
#define SAADDRLEN(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? 16:4)
|
||||
#define SASOCK(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? PF_INET6:PF_INET)
|
||||
#define SASIZE(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in))
|
||||
#define SAISNULL(sa) (!memcmp(((struct sockaddr_in *)sa)->sin_family == AF_INET6? (unsigned char *)((struct sockaddr_in6 *)sa)->sin6_addr.u.Byte : (unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr, NULLADDR, (((struct sockaddr_in *)sa)->sin_family == AF_INET6? 16:4)))
|
||||
#else
|
||||
#define SAPORT(sa) (&((struct sockaddr_in *)sa)->sin_port)
|
||||
#define SAADDR(sa) ((unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr)
|
||||
#define SAADDRLEN(sa) (4)
|
||||
#define SASOCK(sa) (PF_INET)
|
||||
#define SASIZE(sa) (sizeof(struct sockaddr_in))
|
||||
#define SAISNULL(sa) (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0)
|
||||
#endif
|
||||
|
||||
extern char* NULLADDR;
|
||||
typedef enum {
|
||||
CLIENT,
|
||||
SERVER
|
||||
@ -228,8 +231,11 @@ typedef enum {
|
||||
struct chain {
|
||||
struct chain * next;
|
||||
int type;
|
||||
unsigned long redirip;
|
||||
unsigned short redirport;
|
||||
#ifndef NOIPV6
|
||||
struct sockaddr_in6 addr;
|
||||
#else
|
||||
struct sockaddr_in addr;
|
||||
#endif
|
||||
unsigned short weight;
|
||||
unsigned char * extuser;
|
||||
unsigned char * extpass;
|
||||
|
@ -40,7 +40,7 @@ void * udppmchild(struct clientparam* param) {
|
||||
|
||||
|
||||
if(!param->hostname)parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport));
|
||||
if (!memcmp(SAADDR(¶m->req), "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", SAADDRLEN(¶m->req))) {
|
||||
if (SAISNULL(¶m->req)) {
|
||||
param->srv->fds.events = POLLIN;
|
||||
RETURN (100);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user