mirror of
https://github.com/3proxy/3proxy.git
synced 2026-08-13 12:19:17 +08:00
Fix: -Ne/-Ni, -4 / -6 handling for udp mapping in socks, mixed family support in udp
This commit is contained in:
parent
a43c95023d
commit
13a57812e5
33
src/common.c
33
src/common.c
@ -9,6 +9,39 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
|
/* returns 0 on success, 1 if atyp is not supported for family, 2 if the
|
||||||
|
address is null. The address is set in both the 0 and the 2 case. */
|
||||||
|
int socks5_setaddr(int family, int atyp, const unsigned char *addr, PROXYSOCKADDRTYPE *sa){
|
||||||
|
int i, len = 4;
|
||||||
|
|
||||||
|
memset(sa, 0, sizeof(*sa));
|
||||||
|
if(atyp == 4){
|
||||||
|
#ifdef NOIPV6
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
if(family == 4) return 1;
|
||||||
|
len = 16;
|
||||||
|
*SAFAMILY(sa) = AF_INET6;
|
||||||
|
memcpy(SAADDR(sa), addr, 16);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifndef NOIPV6
|
||||||
|
else if(family == 6){
|
||||||
|
unsigned char prefix[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255};
|
||||||
|
|
||||||
|
*SAFAMILY(sa) = AF_INET6;
|
||||||
|
memcpy(SAADDR(sa), prefix, 12);
|
||||||
|
memcpy(12 + (unsigned char *)SAADDR(sa), addr, 4);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
*SAFAMILY(sa) = AF_INET;
|
||||||
|
memcpy(SAADDR(sa), addr, 4);
|
||||||
|
}
|
||||||
|
for(i = 0; i < len && !addr[i]; i++);
|
||||||
|
return (i == len)? 2 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
|
||||||
|
|||||||
@ -205,6 +205,7 @@ extern int timeouts[12];
|
|||||||
int sockmap(struct clientparam * param, int timeo, int usesplice);
|
int sockmap(struct clientparam * param, int timeo, int usesplice);
|
||||||
int udpsockmap(struct clientparam * param, int timeo);
|
int udpsockmap(struct clientparam * param, int timeo);
|
||||||
int udpbind(struct clientparam * param);
|
int udpbind(struct clientparam * param);
|
||||||
|
int socks5_setaddr(int family, int atyp, const unsigned char *addr, PROXYSOCKADDRTYPE *sa);
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
int switch_ns(struct srvparam *srv, int target_fd);
|
int switch_ns(struct srvparam *srv, int target_fd);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -505,8 +505,8 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
if(argv[i][3] == 'e') getip46(46, (unsigned char *)argv[i]+3, (struct sockaddr *)&srv.extNat);
|
if(argv[i][2] == 'e') getip46(46, (unsigned char *)argv[i]+3, (struct sockaddr *)&srv.extNat);
|
||||||
else if(argv[i][3] == 'i') getip46(46, (unsigned char *)argv[i]+3, (struct sockaddr *)&srv.intNat);
|
else if(argv[i][2] == 'i') getip46(46, (unsigned char *)argv[i]+3, (struct sockaddr *)&srv.intNat);
|
||||||
else getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat);
|
else getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
|
|||||||
30
src/socks.c
30
src/socks.c
@ -107,38 +107,20 @@ void * sockschild(struct clientparam* param) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size = 4;
|
size = 4;
|
||||||
*SAFAMILY(¶m->sinsr) = *SAFAMILY(¶m->req) = AF_INET;
|
|
||||||
switch(c) {
|
switch(c) {
|
||||||
#ifndef NOIPV6
|
#ifndef NOIPV6
|
||||||
case 4:
|
case 4:
|
||||||
if(param->srv->family == 4) RETURN(997);
|
|
||||||
size = 16;
|
size = 16;
|
||||||
*SAFAMILY(¶m->sinsr) = *SAFAMILY(¶m->req) = AF_INET6;
|
|
||||||
#endif
|
#endif
|
||||||
case 1:
|
case 1:
|
||||||
for (i = 0; i<size; i++){
|
for (i = 0; i<size; i++){
|
||||||
if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
|
if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
|
||||||
buf[i] = (unsigned char)res;
|
buf[i] = (unsigned char)res;
|
||||||
}
|
}
|
||||||
#ifndef NOIPV6
|
res = socks5_setaddr(param->srv->family, c, buf, ¶m->req);
|
||||||
if (c == 1 && param->srv->family==6){
|
if(res == 1) {RETURN(997);}
|
||||||
char prefix[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255};
|
if(res == 2 && command == 1) {RETURN(431);}
|
||||||
*SAFAMILY(¶m->sinsr) = *SAFAMILY(¶m->req) = AF_INET6;
|
param->sinsr = param->req;
|
||||||
memcpy(SAADDR(¶m->sinsr), prefix, 12);
|
|
||||||
memcpy(12 + (char *)SAADDR(¶m->sinsr), buf, 4);
|
|
||||||
memcpy(SAADDR(¶m->req), prefix, 12);
|
|
||||||
memcpy(12 + (char *)SAADDR(¶m->req), buf, 4);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#endif
|
|
||||||
memcpy(SAADDR(¶m->sinsr), buf, size);
|
|
||||||
memcpy(SAADDR(¶m->req), buf, size);
|
|
||||||
#ifndef NOIPV6
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(command == 1 && SAISNULL(¶m->req)) {
|
|
||||||
RETURN(431);
|
|
||||||
}
|
|
||||||
myinet_ntop(*SAFAMILY(¶m->sinsr), SAADDR(¶m->sinsr), (char *)buf, 64);
|
myinet_ntop(*SAFAMILY(¶m->sinsr), SAADDR(¶m->sinsr), (char *)buf, 64);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
@ -285,7 +267,7 @@ CLEANRET:
|
|||||||
|
|
||||||
sasize = sizeof(sin);
|
sasize = sizeof(sin);
|
||||||
if(command != 3 && param->remsock != INVALID_SOCKET) param->srv->so._getsockname(param->sostate, param->remsock, (struct sockaddr *)&sin, &sasize);
|
if(command != 3 && param->remsock != INVALID_SOCKET) param->srv->so._getsockname(param->sostate, param->remsock, (struct sockaddr *)&sin, &sasize);
|
||||||
if(!SAISNULL(¶m->srv->extNat)){
|
if(command != 3 && !SAISNULL(¶m->srv->extNat)){
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
port = *SAPORT(&sin);
|
port = *SAPORT(&sin);
|
||||||
sin = param->srv->extNat;
|
sin = param->srv->extNat;
|
||||||
@ -293,7 +275,7 @@ CLEANRET:
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
param->srv->so._getsockname(param->sostate, param->clisock, (struct sockaddr *)&sin, &sasize);
|
param->srv->so._getsockname(param->sostate, param->clisock, (struct sockaddr *)&sin, &sasize);
|
||||||
if(!SAISNULL(¶m->srv->intNat)){
|
if(command == 3 && !SAISNULL(¶m->srv->intNat)){
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
port = *SAPORT(&sin);
|
port = *SAPORT(&sin);
|
||||||
sin = param->srv->intNat;
|
sin = param->srv->intNat;
|
||||||
|
|||||||
@ -257,16 +257,16 @@ int udpsockmap(struct clientparam *param, int timeo)
|
|||||||
memset(&dst, 0, sizeof(dst));
|
memset(&dst, 0, sizeof(dst));
|
||||||
switch (base[3]) {
|
switch (base[3]) {
|
||||||
case 1:
|
case 1:
|
||||||
*SAFAMILY(&dst) = AF_INET;
|
if (socks5_setaddr(param->srv->family, 1, base + 4, &dst)) continue;
|
||||||
memcpy(SAADDR(&dst), base + 4, 4);
|
|
||||||
i = 8;
|
i = 8;
|
||||||
break;
|
break;
|
||||||
|
#ifndef NOIPV6
|
||||||
case 4:
|
case 4:
|
||||||
if (len < 22) return 484;
|
if (len < 22) return 484;
|
||||||
*SAFAMILY(&dst) = AF_INET6;
|
if (socks5_setaddr(param->srv->family, 4, base + 4, &dst)) continue;
|
||||||
memcpy(SAADDR(&dst), base + 4, 16);
|
|
||||||
i = 20;
|
i = 20;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case 3: {
|
case 3: {
|
||||||
int sz = base[4];
|
int sz = base[4];
|
||||||
if (len < 7 + sz) return 485;
|
if (len < 7 + sz) return 485;
|
||||||
@ -309,7 +309,8 @@ int udpsockmap(struct clientparam *param, int timeo)
|
|||||||
if (!nhops) param->sinsr = dst;
|
if (!nhops) param->sinsr = dst;
|
||||||
|
|
||||||
if (!havedst) reconnect = 1;
|
if (!havedst) reconnect = 1;
|
||||||
else if ((param->srv->udpauth & 2) && !param->dstindep) {
|
else if (!nhops && *SAFAMILY(&dst) != *SAFAMILY(¶m->sinsl)) reconnect = 1;
|
||||||
|
if (havedst && (param->srv->udpauth & 2) && !param->dstindep) {
|
||||||
param->preauth = 2;
|
param->preauth = 2;
|
||||||
ares = (*param->srv->authfunc)(param);
|
ares = (*param->srv->authfunc)(param);
|
||||||
param->preauth = 0;
|
param->preauth = 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user