mirror of
https://github.com/3proxy/3proxy.git
synced 2026-08-13 12:19:17 +08:00
Compare commits
3 Commits
75021a2003
...
4fb5c95704
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fb5c95704 | ||
|
|
13a57812e5 | ||
|
|
a43c95023d |
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>
|
||||||
|
|
||||||
|
|||||||
18
src/conf.c
18
src/conf.c
@ -839,6 +839,24 @@ static int h_parent(int argc, unsigned char **argv){
|
|||||||
chains->cidr = atoi(cidr + 1);
|
chains->cidr = atoi(cidr + 1);
|
||||||
}
|
}
|
||||||
*SAPORT(&chains->addr) = htons((uint16_t)atoi((char *)argv[4]));
|
*SAPORT(&chains->addr) = htons((uint16_t)atoi((char *)argv[4]));
|
||||||
|
switch(chains->type){
|
||||||
|
case R_POP3:
|
||||||
|
case R_SMTP:
|
||||||
|
case R_FTP:
|
||||||
|
case R_ADMIN:
|
||||||
|
case R_TLS:
|
||||||
|
case R_DNS:
|
||||||
|
case R_HA:
|
||||||
|
if(!SAISNULL(&chains->addr) || *SAPORT(&chains->addr)){
|
||||||
|
fprintf(stderr, "Chaining error: chain type (%s) is a local redirection, it requires 0.0.0.0 as address and 0 as port on line %d\n", argv[2], linenum);
|
||||||
|
free(chains->exthost);
|
||||||
|
free(chains);
|
||||||
|
return(4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(argc > 5) chains->extuser = (unsigned char *)strdup((char *)argv[5]);
|
if(argc > 5) chains->extuser = (unsigned char *)strdup((char *)argv[5]);
|
||||||
if(argc > 6) chains->extpass = (unsigned char *)strdup((char *)argv[6]);
|
if(argc > 6) chains->extpass = (unsigned char *)strdup((char *)argv[6]);
|
||||||
if(!acl->chains) {
|
if(!acl->chains) {
|
||||||
|
|||||||
@ -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':
|
||||||
|
|||||||
@ -3,6 +3,19 @@
|
|||||||
struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}};
|
struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}};
|
||||||
struct nserver authnserver;
|
struct nserver authnserver;
|
||||||
|
|
||||||
|
static int dnsqmatch(const unsigned char *a, const unsigned char *b, int len){
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < len; i++){
|
||||||
|
unsigned char c1 = a[i], c2 = b[i];
|
||||||
|
|
||||||
|
if(c1 >= 'A' && c1 <= 'Z') c1 += 'a' - 'A';
|
||||||
|
if(c2 >= 'A' && c2 <= 'Z') c2 += 'a' - 'A';
|
||||||
|
if(c1 != c2) return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_t *retttl, struct clientparam* param, int makeauth){
|
uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_t *retttl, struct clientparam* param, int makeauth){
|
||||||
|
|
||||||
@ -23,9 +36,12 @@ uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_
|
|||||||
SOCKET sock;
|
SOCKET sock;
|
||||||
uint32_t ttl;
|
uint32_t ttl;
|
||||||
PROXYSOCKADDRTYPE addr;
|
PROXYSOCKADDRTYPE addr;
|
||||||
|
PROXYSOCKADDRTYPE from;
|
||||||
PROXYSOCKADDRTYPE *sinsr, *sinsl;
|
PROXYSOCKADDRTYPE *sinsr, *sinsl;
|
||||||
int usetcp = 0;
|
int usetcp = 0;
|
||||||
unsigned short serial = 1;
|
unsigned short serial = 1;
|
||||||
|
unsigned char qbuf[300];
|
||||||
|
int qlen;
|
||||||
|
|
||||||
buf = b+2;
|
buf = b+2;
|
||||||
|
|
||||||
@ -92,6 +108,9 @@ uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_
|
|||||||
buf[len++] = (makeauth == 1)? 0x0c : (af==AF_INET6? 0x1c:0x01);/* PTR:host address */
|
buf[len++] = (makeauth == 1)? 0x0c : (af==AF_INET6? 0x1c:0x01);/* PTR:host address */
|
||||||
buf[len++] = 0;
|
buf[len++] = 0;
|
||||||
buf[len++] = 1; /* INET */
|
buf[len++] = 1; /* INET */
|
||||||
|
qlen = len - 12;
|
||||||
|
memcpy(qbuf, buf + 12, qlen);
|
||||||
|
|
||||||
if(usetcp){
|
if(usetcp){
|
||||||
buf-=2;
|
buf-=2;
|
||||||
*(unsigned short*)buf = htons(len);
|
*(unsigned short*)buf = htons(len);
|
||||||
@ -104,30 +123,41 @@ uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(param) param->statscli64 += len;
|
if(param) param->statscli64 += len;
|
||||||
len = sockrecvfrom(NULL, sock, (struct sockaddr *)sinsr, buf, 4096, conf.timeouts[DNS_TO]*1000);
|
len = sockrecvfrom(NULL, sock, (struct sockaddr *)&from, buf, 4096, conf.timeouts[DNS_TO]*1000);
|
||||||
|
if(len > 13 && usetcp){
|
||||||
|
unsigned short us;
|
||||||
|
us = ntohs(*(unsigned short*)buf);
|
||||||
|
len-=2;
|
||||||
|
buf+=2;
|
||||||
|
if(us > 4096 || us < len) len = 0;
|
||||||
|
else if(us > len){
|
||||||
|
if(sockrecvfrom(NULL, sock, (struct sockaddr *)&from, buf+len, us-len, conf.timeouts[DNS_TO]*1000) != us-len) len = 0;
|
||||||
|
else len = us;
|
||||||
|
}
|
||||||
|
}
|
||||||
so._shutdown(so.state, sock, SHUT_RDWR);
|
so._shutdown(so.state, sock, SHUT_RDWR);
|
||||||
so._closesocket(so.state, sock);
|
so._closesocket(so.state, sock);
|
||||||
if(len <= 13) {
|
if(len <= 13) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(param) param->statssrv64 += len;
|
if(param) param->statssrv64 += len;
|
||||||
if(usetcp){
|
if(!usetcp && (*SAFAMILY(&from) != *SAFAMILY(sinsr) ||
|
||||||
unsigned short us;
|
memcmp(SAADDR(&from), SAADDR(sinsr), SAADDRLEN(sinsr)) ||
|
||||||
us = ntohs(*(unsigned short*)buf);
|
*SAPORT(&from) != *SAPORT(sinsr))) {
|
||||||
len-=2;
|
continue; /* not from the server we asked */
|
||||||
buf+=2;
|
|
||||||
if(us > 4096 || us < len || (us > len && sockrecvfrom(NULL, sock, (struct sockaddr *)sinsr, buf+len, us-len, conf.timeouts[DNS_TO]*1000) != us-len)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(*(unsigned short *)buf != serial)continue;
|
if(*(unsigned short *)buf != serial)continue;
|
||||||
if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
|
if(!(buf[2] & 0x80)) continue; /* not a response */
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
nq = buf[5] + (((unsigned short)buf[4])<<8);
|
nq = buf[5] + (((unsigned short)buf[4])<<8);
|
||||||
if (nq != 1) {
|
if (nq != 1) {
|
||||||
continue; /* we did only 1 request */
|
continue; /* we did only 1 request */
|
||||||
}
|
}
|
||||||
|
if(len < 12 + qlen || dnsqmatch(buf + 12, qbuf, qlen)) {
|
||||||
|
continue; /* question does not match the query */
|
||||||
|
}
|
||||||
|
if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
for(k = 13; k<len && buf[k]; k++) {
|
for(k = 13; k<len && buf[k]; k++) {
|
||||||
}
|
}
|
||||||
k++;
|
k++;
|
||||||
|
|||||||
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