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"
|
||||
/* 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__
|
||||
#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);
|
||||
}
|
||||
*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 > 6) chains->extpass = (unsigned char *)strdup((char *)argv[6]);
|
||||
if(!acl->chains) {
|
||||
|
||||
@ -205,6 +205,7 @@ extern int timeouts[12];
|
||||
int sockmap(struct clientparam * param, int timeo, int usesplice);
|
||||
int udpsockmap(struct clientparam * param, int timeo);
|
||||
int udpbind(struct clientparam * param);
|
||||
int socks5_setaddr(int family, int atyp, const unsigned char *addr, PROXYSOCKADDRTYPE *sa);
|
||||
#ifdef __linux__
|
||||
int switch_ns(struct srvparam *srv, int target_fd);
|
||||
#endif
|
||||
|
||||
@ -505,8 +505,8 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
}
|
||||
break;
|
||||
case 'N':
|
||||
if(argv[i][3] == '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);
|
||||
if(argv[i][2] == 'e') getip46(46, (unsigned char *)argv[i]+3, (struct sockaddr *)&srv.extNat);
|
||||
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);
|
||||
break;
|
||||
case 'n':
|
||||
|
||||
@ -3,6 +3,19 @@
|
||||
struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}};
|
||||
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){
|
||||
|
||||
@ -23,9 +36,12 @@ uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_
|
||||
SOCKET sock;
|
||||
uint32_t ttl;
|
||||
PROXYSOCKADDRTYPE addr;
|
||||
PROXYSOCKADDRTYPE from;
|
||||
PROXYSOCKADDRTYPE *sinsr, *sinsl;
|
||||
int usetcp = 0;
|
||||
unsigned short serial = 1;
|
||||
unsigned char qbuf[300];
|
||||
int qlen;
|
||||
|
||||
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++] = 0;
|
||||
buf[len++] = 1; /* INET */
|
||||
qlen = len - 12;
|
||||
memcpy(qbuf, buf + 12, qlen);
|
||||
|
||||
if(usetcp){
|
||||
buf-=2;
|
||||
*(unsigned short*)buf = htons(len);
|
||||
@ -104,30 +123,41 @@ uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_
|
||||
continue;
|
||||
}
|
||||
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._closesocket(so.state, sock);
|
||||
if(len <= 13) {
|
||||
continue;
|
||||
}
|
||||
if(param) param->statssrv64 += len;
|
||||
if(usetcp){
|
||||
unsigned short us;
|
||||
us = ntohs(*(unsigned short*)buf);
|
||||
len-=2;
|
||||
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(!usetcp && (*SAFAMILY(&from) != *SAFAMILY(sinsr) ||
|
||||
memcmp(SAADDR(&from), SAADDR(sinsr), SAADDRLEN(sinsr)) ||
|
||||
*SAPORT(&from) != *SAPORT(sinsr))) {
|
||||
continue; /* not from the server we asked */
|
||||
}
|
||||
if(*(unsigned short *)buf != serial)continue;
|
||||
if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
|
||||
return 0;
|
||||
}
|
||||
if(!(buf[2] & 0x80)) continue; /* not a response */
|
||||
nq = buf[5] + (((unsigned short)buf[4])<<8);
|
||||
if (nq != 1) {
|
||||
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++) {
|
||||
}
|
||||
k++;
|
||||
|
||||
30
src/socks.c
30
src/socks.c
@ -107,38 +107,20 @@ void * sockschild(struct clientparam* param) {
|
||||
}
|
||||
|
||||
size = 4;
|
||||
*SAFAMILY(¶m->sinsr) = *SAFAMILY(¶m->req) = AF_INET;
|
||||
switch(c) {
|
||||
#ifndef NOIPV6
|
||||
case 4:
|
||||
if(param->srv->family == 4) RETURN(997);
|
||||
size = 16;
|
||||
*SAFAMILY(¶m->sinsr) = *SAFAMILY(¶m->req) = AF_INET6;
|
||||
#endif
|
||||
case 1:
|
||||
for (i = 0; i<size; i++){
|
||||
if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
|
||||
buf[i] = (unsigned char)res;
|
||||
}
|
||||
#ifndef NOIPV6
|
||||
if (c == 1 && param->srv->family==6){
|
||||
char prefix[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255};
|
||||
*SAFAMILY(¶m->sinsr) = *SAFAMILY(¶m->req) = AF_INET6;
|
||||
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);
|
||||
}
|
||||
res = socks5_setaddr(param->srv->family, c, buf, ¶m->req);
|
||||
if(res == 1) {RETURN(997);}
|
||||
if(res == 2 && command == 1) {RETURN(431);}
|
||||
param->sinsr = param->req;
|
||||
myinet_ntop(*SAFAMILY(¶m->sinsr), SAADDR(¶m->sinsr), (char *)buf, 64);
|
||||
break;
|
||||
case 3:
|
||||
@ -285,7 +267,7 @@ CLEANRET:
|
||||
|
||||
sasize = sizeof(sin);
|
||||
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;
|
||||
port = *SAPORT(&sin);
|
||||
sin = param->srv->extNat;
|
||||
@ -293,7 +275,7 @@ CLEANRET:
|
||||
}
|
||||
else {
|
||||
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;
|
||||
port = *SAPORT(&sin);
|
||||
sin = param->srv->intNat;
|
||||
|
||||
@ -257,16 +257,16 @@ int udpsockmap(struct clientparam *param, int timeo)
|
||||
memset(&dst, 0, sizeof(dst));
|
||||
switch (base[3]) {
|
||||
case 1:
|
||||
*SAFAMILY(&dst) = AF_INET;
|
||||
memcpy(SAADDR(&dst), base + 4, 4);
|
||||
if (socks5_setaddr(param->srv->family, 1, base + 4, &dst)) continue;
|
||||
i = 8;
|
||||
break;
|
||||
#ifndef NOIPV6
|
||||
case 4:
|
||||
if (len < 22) return 484;
|
||||
*SAFAMILY(&dst) = AF_INET6;
|
||||
memcpy(SAADDR(&dst), base + 4, 16);
|
||||
if (socks5_setaddr(param->srv->family, 4, base + 4, &dst)) continue;
|
||||
i = 20;
|
||||
break;
|
||||
#endif
|
||||
case 3: {
|
||||
int sz = base[4];
|
||||
if (len < 7 + sz) return 485;
|
||||
@ -309,7 +309,8 @@ int udpsockmap(struct clientparam *param, int timeo)
|
||||
if (!nhops) param->sinsr = dst;
|
||||
|
||||
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;
|
||||
ares = (*param->srv->authfunc)(param);
|
||||
param->preauth = 0;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user