mirror of
https://github.com/3proxy/3proxy.git
synced 2025-02-23 10:35:40 +08:00
Connect back proxy functionality added
-r and -R options added to support connect back functionality between two instances of proxy
This commit is contained in:
parent
6529b9cea1
commit
a2b5af6dab
18
src/common.c
18
src/common.c
@ -216,6 +216,24 @@ int ceparseargs(const char *str){
|
||||
|
||||
#endif
|
||||
|
||||
void parsehost(int family, char *host, struct sockaddr *sa){
|
||||
char *sp=NULL,*se=NULL;
|
||||
unsigned short port;
|
||||
|
||||
if(*host == '[') se=strchr(host, ']');
|
||||
if ( (sp = strchr(se?se:host, ':')) ) *sp = 0;
|
||||
if(se){
|
||||
*se = 0;
|
||||
}
|
||||
if(sp){
|
||||
port = atoi(sp+1);
|
||||
}
|
||||
getip46(family, host + (se!=0), (struct sockaddr *)sa);
|
||||
if(se) *se = ']';
|
||||
if(sp) *sp = ':';
|
||||
*SAPORT(sa) = htons(port);
|
||||
}
|
||||
|
||||
int parsehostname(char *hostname, struct clientparam *param, unsigned short port){
|
||||
char *sp=NULL,*se=NULL;
|
||||
|
||||
|
@ -235,10 +235,12 @@ void mschap(const unsigned char *win_password,
|
||||
struct hashtable;
|
||||
void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires);
|
||||
|
||||
void parsehost(int family, char *host, struct sockaddr *sa);
|
||||
int parsehostname(char *hostname, struct clientparam *param, unsigned short port);
|
||||
int parseusername(char *username, struct clientparam *param, int extpasswd);
|
||||
int parseconnusername(char *username, struct clientparam *param, int extpasswd, unsigned short port);
|
||||
int ACLmatches(struct ace* acentry, struct clientparam * param);
|
||||
int checkACL(struct clientparam * param);
|
||||
|
||||
unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, unsigned *retttl, struct clientparam* param, int makeauth);
|
||||
|
||||
|
137
src/proxymain.c
137
src/proxymain.c
@ -9,8 +9,46 @@
|
||||
#include "proxy.h"
|
||||
|
||||
|
||||
#define param ((struct clientparam *) p)
|
||||
#ifdef _WIN32
|
||||
DWORD WINAPI threadfunc(LPVOID p) {
|
||||
#else
|
||||
void * threadfunc (void *p) {
|
||||
#endif
|
||||
if(param->srv->cbsock != INVALID_SOCKET){
|
||||
SASIZETYPE size = sizeof(param->sinsr);
|
||||
param->remsock = so._accept(param->srv->cbsock, (struct sockaddr*)¶m->sinsr, &size);
|
||||
if(param->remsock == INVALID_SOCKET) {
|
||||
param->res = 13;
|
||||
param->srv->logfunc(param, "Connect back accept() failed");
|
||||
#ifdef _WIN32
|
||||
return 0;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
#ifndef WITHMAIN
|
||||
memcpy(¶m->req, ¶m->sinsr, size);
|
||||
if(param->srv->acl) param->res = checkACL(param);
|
||||
if(param->res){
|
||||
param->srv->logfunc(param, "Connect back ACL failed");
|
||||
}
|
||||
#ifdef _WIN32
|
||||
return 0;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
((struct clientparam *) p)->srv->pf((struct clientparam *)p);
|
||||
#ifdef _WIN32
|
||||
return 0;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
#undef param
|
||||
|
||||
|
||||
|
||||
@ -42,7 +80,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
|
||||
|
||||
|
||||
SOCKET sock = INVALID_SOCKET;
|
||||
SOCKET sock = INVALID_SOCKET, new_sock = INVALID_SOCKET;
|
||||
int i=0;
|
||||
SASIZETYPE size;
|
||||
pthread_t thread;
|
||||
@ -53,8 +91,15 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
unsigned sleeptime;
|
||||
unsigned char buf[256];
|
||||
char *hostname=NULL;
|
||||
int opt = 1, isudp;
|
||||
int opt = 1, isudp = 0, iscbl = 0, iscbc = 0;
|
||||
unsigned char *cbc_string = NULL, *cbl_string = NULL;
|
||||
#ifndef NOIPV6
|
||||
struct sockaddr_in6 cbsa;
|
||||
#else
|
||||
struct sockaddr_in cbsa;
|
||||
#endif
|
||||
FILE *fp = NULL;
|
||||
struct linger lg;
|
||||
int nlog = 5000;
|
||||
char loghelp[] =
|
||||
#ifdef STDMAIN
|
||||
@ -73,6 +118,8 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
" -t be silent (do not log service start/stop)\n"
|
||||
" -iIP ip address or internal interface (clients are expected to connect)\n"
|
||||
" -eIP ip address or external interface (outgoing connection will have this)\n"
|
||||
" -rIP:PORT Use IP:port for connect back proxy instead of listen port\n"
|
||||
" -RPORT Use PORT to listen connect back proxy connection to pass data to\n"
|
||||
" -4 Use IPv4 for outgoing connections\n"
|
||||
" -6 Use IPv6 for outgoing connections\n"
|
||||
" -46 Prefer IPv4 for outgoing connections, use both IPv4 and IPv6\n"
|
||||
@ -85,8 +132,6 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
int inetd = 0;
|
||||
#endif
|
||||
#endif
|
||||
SOCKET new_sock = INVALID_SOCKET;
|
||||
struct linger lg;
|
||||
#ifdef _WIN32
|
||||
HANDLE h;
|
||||
#endif
|
||||
@ -222,6 +267,14 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
case 'h':
|
||||
hostname = argv[i] + 2;
|
||||
break;
|
||||
case 'r':
|
||||
cbc_string = mystrdup(argv[i] + 2);
|
||||
iscbc = 1;
|
||||
break;
|
||||
case 'R':
|
||||
cbl_string = mystrdup(argv[i] + 2);
|
||||
iscbl = 1;
|
||||
break;
|
||||
case 'u':
|
||||
srv.nouser = 1;
|
||||
break;
|
||||
@ -255,6 +308,8 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
"Available options are:\n"
|
||||
"%s"
|
||||
" -pPORT - service port to accept connections\n"
|
||||
" -RIP:PORT - connect back IP:PORT to listen and accept connections\n"
|
||||
" -rIP:PORT - connect back IP:PORT to establish connect back connection\n"
|
||||
"%s"
|
||||
"\tExample: %s -i127.0.0.1\n\n"
|
||||
"%s",
|
||||
@ -284,6 +339,8 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
" [-e<external_ip>] <port_to_bind>"
|
||||
" <target_hostname> <target_port>\n"
|
||||
"Available options are:\n"
|
||||
" -RIP:PORT - connect back IP:PORT to listen and accept connections\n"
|
||||
" -rIP:PORT - connect back IP:PORT to establish connect back connection\n"
|
||||
"%s"
|
||||
"%s"
|
||||
"\tExample: %s -d -i127.0.0.1 6666 serv.somehost.ru 6666\n\n"
|
||||
@ -343,6 +400,19 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
memset(&defparam.sincr, 0, sizeof(defparam.sincr));
|
||||
memset(&defparam.sincl, 0, sizeof(defparam.sincl));
|
||||
memset(&defparam.sinsl, 0, sizeof(defparam.sinsl));
|
||||
memset(&defparam.sinsr, 0, sizeof(defparam.sinsr));
|
||||
memset(&defparam.req, 0, sizeof(defparam.req));
|
||||
*SAFAMILY(&defparam.sincr) = AF_INET;
|
||||
*SAFAMILY(&defparam.sincl) = AF_INET;
|
||||
*SAFAMILY(&defparam.sinsl) = AF_INET;
|
||||
*SAFAMILY(&defparam.sinsr) = AF_INET;
|
||||
*SAFAMILY(&defparam.req) = AF_INET;
|
||||
|
||||
if (!iscbc) {
|
||||
if(srv.srvsock == INVALID_SOCKET){
|
||||
|
||||
if(!isudp){
|
||||
@ -351,7 +421,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
sock=so._socket(SASOCK(&srv.intsa), SOCK_STREAM, IPPROTO_TCP);
|
||||
}
|
||||
else {
|
||||
sock=so._socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
sock=so._socket(SASOCK(&srv.intsa), SOCK_DGRAM, IPPROTO_UDP);
|
||||
}
|
||||
if( sock == INVALID_SOCKET) {
|
||||
perror("socket()");
|
||||
@ -368,7 +438,6 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
so._setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int));
|
||||
#endif
|
||||
}
|
||||
|
||||
size = sizeof(srv.intsa);
|
||||
for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv.intsa, size)==-1; usleep(sleeptime)) {
|
||||
sprintf((char *)buf, "bind(): %s", strerror(errno));
|
||||
@ -389,20 +458,29 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
else
|
||||
defparam.clisock = sock;
|
||||
|
||||
if(!srv.silent){
|
||||
if(!srv.silent && !iscbc){
|
||||
sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self());
|
||||
(*srv.logfunc)(&defparam, buf);
|
||||
}
|
||||
memset(&defparam.sincr, 0, sizeof(defparam.sincr));
|
||||
memset(&defparam.sincl, 0, sizeof(defparam.sincl));
|
||||
memset(&defparam.sinsl, 0, sizeof(defparam.sinsl));
|
||||
memset(&defparam.sinsr, 0, sizeof(defparam.sinsr));
|
||||
memset(&defparam.req, 0, sizeof(defparam.req));
|
||||
*SAFAMILY(&defparam.sincr) = AF_INET;
|
||||
*SAFAMILY(&defparam.sincl) = AF_INET;
|
||||
*SAFAMILY(&defparam.sinsl) = AF_INET;
|
||||
*SAFAMILY(&defparam.sinsr) = AF_INET;
|
||||
*SAFAMILY(&defparam.req) = AF_INET;
|
||||
}
|
||||
else {
|
||||
parsehost(srv.family, cbc_string, (struct sockaddr *)&defparam.sincr);
|
||||
}
|
||||
if(iscbl){
|
||||
parsehost(srv.family, cbl_string, (struct sockaddr *)&cbsa);
|
||||
if((srv.cbsock=so._socket(SASOCK(&cbsa), SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) {
|
||||
(*srv.logfunc)(&defparam, "Failed to allocate connect back socket");
|
||||
return -6;
|
||||
}
|
||||
if(so._bind(srv.cbsock, (struct sockaddr*)&cbsa, sizeof(cbsa))==-1) {
|
||||
(*srv.logfunc)(&defparam, "Failed to bind connect back socket");
|
||||
return -7;
|
||||
}
|
||||
if(so._listen(srv.cbsock, 1 + (srv.maxchild>>4))==-1) {
|
||||
(*srv.logfunc)(&defparam, "Failed to listen connect back socket");
|
||||
return -8;
|
||||
}
|
||||
}
|
||||
|
||||
srv.fds.fd = sock;
|
||||
srv.fds.events = POLLIN;
|
||||
@ -419,6 +497,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
}
|
||||
usleep(SLEEPTIME);
|
||||
}
|
||||
if (iscbc) break;
|
||||
if (conf.paused != srv.version) break;
|
||||
if (srv.fds.events & POLLIN) {
|
||||
error = so._poll(&srv.fds, 1, 1000);
|
||||
@ -439,12 +518,24 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
if((conf.paused != srv.version) || (error < 0)) break;
|
||||
if(!isudp){
|
||||
size = sizeof(defparam.sincr);
|
||||
if(iscbc){
|
||||
new_sock=so._socket(SASOCK(&defparam.sincr), SOCK_STREAM, IPPROTO_TCP);
|
||||
if(new_sock != INVALID_SOCKET){
|
||||
if(so._connect(new_sock,(struct sockaddr *)&defparam.sincr,sizeof(defparam.sincr))) {
|
||||
so._closesocket(new_sock);
|
||||
new_sock = INVALID_SOCKET;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
new_sock = so._accept(sock, (struct sockaddr*)&defparam.sincr, &size);
|
||||
if(new_sock == INVALID_SOCKET){
|
||||
sprintf((char *)buf, "accept(): %s", strerror(errno));
|
||||
if(!srv.silent)(*srv.logfunc)(&defparam, buf);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
size = sizeof(defparam.sincl);
|
||||
if(so._getsockname(new_sock, (struct sockaddr *)&defparam.sincl, &size)){
|
||||
sprintf((char *)buf, "getsockname(): %s", strerror(errno));
|
||||
@ -490,9 +581,9 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
}
|
||||
#ifdef _WIN32
|
||||
#ifndef _WINCE
|
||||
h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)16384, (BEGINTHREADFUNC)srv.pf, (void *) newparam, 0, &thread);
|
||||
h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)16384, threadfunc, (void *) newparam, 0, &thread);
|
||||
#else
|
||||
h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)32768, (BEGINTHREADFUNC)srv.pf, (void *) newparam, 0, &thread);
|
||||
h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)32768, threadfunc, (void *) newparam, 0, &thread);
|
||||
#endif
|
||||
srv.childcount++;
|
||||
if (h) {
|
||||
@ -506,7 +597,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
}
|
||||
#else
|
||||
|
||||
error = pthread_create(&thread, &pa, (PTHREADFUNC)srv.pf, (void *)newparam);
|
||||
error = pthread_create(&thread, &pa, threadfunc, (void *)newparam);
|
||||
srv.childcount++;
|
||||
if(error){
|
||||
sprintf((char *)buf, "pthread_create(): %s", strerror(error));
|
||||
@ -527,6 +618,8 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
if(fp) fclose(fp);
|
||||
srvfree(&srv);
|
||||
if(defparam.hostname)myfree(defparam.hostname);
|
||||
if(cbc_string)myfree(cbc_string);
|
||||
if(cbl_string)myfree(cbc_string);
|
||||
|
||||
#ifndef STDMAIN
|
||||
if(srv.next)srv.next->prev = srv.prev;
|
||||
@ -553,6 +646,7 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
|
||||
srv->srvsock = INVALID_SOCKET;
|
||||
srv->logdumpsrv = conf.logdumpsrv;
|
||||
srv->logdumpcli = conf.logdumpcli;
|
||||
srv->cbsock = INVALID_SOCKET;
|
||||
memset(param, 0, sizeof(struct clientparam));
|
||||
param->srv = srv;
|
||||
param->remsock = param->clisock = param->ctrlsock = param->ctrlsocksrv = INVALID_SOCKET;
|
||||
@ -588,6 +682,7 @@ void srvinit2(struct srvparam * srv, struct clientparam *param){
|
||||
|
||||
void srvfree(struct srvparam * srv){
|
||||
if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock);
|
||||
if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->cbsock);
|
||||
srv->srvsock = INVALID_SOCKET;
|
||||
srv->service = S_ZOMBIE;
|
||||
while(srv->child) usleep(SLEEPTIME * 100);
|
||||
|
@ -34,7 +34,6 @@ extern "C" {
|
||||
#define pthread_mutex_lock(x) EnterCriticalSection(x)
|
||||
#define pthread_mutex_unlock(x) LeaveCriticalSection(x)
|
||||
#define pthread_mutex_destroy(x) DeleteCriticalSection(x)
|
||||
typedef unsigned (__stdcall *BEGINTHREADFUNC)(void *);
|
||||
#ifdef MSVC
|
||||
#pragma warning (disable : 4996)
|
||||
#endif
|
||||
@ -140,6 +139,8 @@ typedef enum {
|
||||
S_FTPPR,
|
||||
S_SMTPP,
|
||||
S_ICQPR,
|
||||
S_REVLI,
|
||||
S_REVCO,
|
||||
/*
|
||||
S_MSNPR,
|
||||
*/
|
||||
@ -162,7 +163,6 @@ typedef void * (*EXTENDFUNC) (struct node *node);
|
||||
typedef void (*CBFUNC)(void *cb, char * buf, int inbuf);
|
||||
typedef void (*PRINTFUNC) (struct node *node, CBFUNC cbf, void*cb);
|
||||
typedef int (*PLUGINFUNC) (struct pluginlink *pluginlink, int argc, char** argv);
|
||||
typedef void * (*PTHREADFUNC)(void *);
|
||||
|
||||
struct auth {
|
||||
struct auth *next;
|
||||
@ -360,7 +360,7 @@ struct srvparam {
|
||||
LOGFUNC logfunc;
|
||||
AUTHFUNC authfunc;
|
||||
PROXYFUNC pf;
|
||||
SOCKET srvsock;
|
||||
SOCKET srvsock, cbsock;
|
||||
int childcount;
|
||||
int maxchild;
|
||||
int version;
|
||||
|
@ -1,2 +1,2 @@
|
||||
#define VERSION "3proxy-0.8b-devel"
|
||||
#define BUILDDATE "150904014330"
|
||||
#define BUILDDATE "150920205624"
|
||||
|
Loading…
Reference in New Issue
Block a user