2014-04-08 17:03:21 +08:00
|
|
|
/*
|
|
|
|
3APA3A simpliest proxy server
|
|
|
|
(c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
|
|
|
|
|
|
|
|
please read License Agreement
|
|
|
|
|
|
|
|
$Id: udppm.c,v 1.27 2012-02-05 22:29:03 vlad Exp $
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "proxy.h"
|
|
|
|
|
|
|
|
#ifndef PORTMAP
|
|
|
|
#define PORTMAP
|
|
|
|
#endif
|
|
|
|
#ifndef UDP
|
|
|
|
#define UDP
|
|
|
|
#endif
|
|
|
|
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
|
|
|
|
|
|
|
|
|
|
|
struct udpmap {
|
|
|
|
struct udpmap *next;
|
|
|
|
time_t updated;
|
|
|
|
SOCKET s;
|
|
|
|
int single;
|
|
|
|
unsigned long cliip;
|
|
|
|
unsigned short cliport;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void * udppmchild(struct clientparam* param) {
|
|
|
|
unsigned char *buf = NULL;
|
|
|
|
int res, i;
|
|
|
|
#ifdef _WIN32
|
|
|
|
SASIZETYPE size;
|
|
|
|
unsigned long ul = 1;
|
|
|
|
#endif
|
|
|
|
struct udpmap *udpmappings = NULL;
|
|
|
|
struct pollfd fds[256];
|
|
|
|
|
|
|
|
|
|
|
|
if(!param->hostname)parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport));
|
2014-10-20 01:54:24 +08:00
|
|
|
if (!memcmp(SAADDR(¶m->req), "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", SAADDRLEN(¶m->req))) {
|
2014-04-08 17:03:21 +08:00
|
|
|
param->srv->fds.events = POLLIN;
|
|
|
|
RETURN (100);
|
|
|
|
}
|
|
|
|
if(!param->clibuf && (!(param->clibuf=myalloc(UDPBUFSIZE)) || !(param->clibufsize = UDPBUFSIZE))){
|
|
|
|
param->srv->fds.events = POLLIN;
|
|
|
|
RETURN (21);
|
|
|
|
}
|
|
|
|
param->cliinbuf = param->clioffset = 0;
|
2014-05-11 09:04:04 +08:00
|
|
|
i = sockrecvfrom(param->srv->srvsock, (struct sockaddr *)¶m->sincr, param->clibuf, param->clibufsize, 0);
|
2014-04-08 17:03:21 +08:00
|
|
|
if(i<=0){
|
|
|
|
param->srv->fds.events = POLLIN;
|
|
|
|
RETURN (214);
|
|
|
|
}
|
|
|
|
param->cliinbuf = i;
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
2014-05-11 09:04:04 +08:00
|
|
|
if((param->clisock=so._socket(*SAFAMILY(¶m->sincr), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
|
2014-04-08 17:03:21 +08:00
|
|
|
RETURN(818);
|
|
|
|
}
|
|
|
|
if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);};
|
|
|
|
ioctlsocket(param->clisock, FIONBIO, &ul);
|
2014-10-20 01:54:24 +08:00
|
|
|
size = sizeof(param->sinsl);
|
|
|
|
if(so._getsockname(param->srv->srvsock, (struct sockaddr *)¶m->sinsl, &size)) {RETURN(21);};
|
|
|
|
if(so._bind(param->clisock,(struct sockaddr *)¶m->sinsl,sizeof(struct sockaddr_in))) {
|
2014-04-08 17:03:21 +08:00
|
|
|
RETURN(822);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
param->clisock = param->srv->srvsock;
|
|
|
|
#endif
|
|
|
|
|
2014-10-20 01:54:24 +08:00
|
|
|
memcpy(¶m->sinsl, *SAFAMILY(¶m->req) == AF_INET? (struct sockaddr *)¶m->srv->extsa : (struct sockaddr *)¶m->srv->extsa6, SASIZE(¶m->req));
|
|
|
|
*SAPORT(¶m->sinsl) = 0;
|
|
|
|
if ((param->remsock=so._socket(*SAFAMILY(¶m->sinsl), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
|
|
|
|
if(so._bind(param->remsock,(struct sockaddr *)¶m->sinsl,sizeof(param->sinsl))) {RETURN (12);}
|
2014-04-08 17:03:21 +08:00
|
|
|
#ifdef _WIN32
|
|
|
|
ioctlsocket(param->remsock, FIONBIO, &ul);
|
|
|
|
#else
|
|
|
|
fcntl(param->remsock,F_SETFL,O_NONBLOCK);
|
|
|
|
#endif
|
2014-10-20 01:54:24 +08:00
|
|
|
memcpy(¶m->sinsr, ¶m->req, sizeof(param->req));
|
2014-04-08 17:03:21 +08:00
|
|
|
|
|
|
|
param->operation = UDPASSOC;
|
|
|
|
if((res = (*param->srv->authfunc)(param))) {RETURN(res);}
|
|
|
|
if(param->srv->singlepacket) {
|
|
|
|
param->srv->fds.events = POLLIN;
|
|
|
|
}
|
|
|
|
|
|
|
|
param->res = sockmap(param, conf.timeouts[(param->srv->singlepacket)?SINGLEBYTE_L:STRING_L]);
|
|
|
|
if(!param->srv->singlepacket) {
|
|
|
|
param->srv->fds.events = POLLIN;
|
|
|
|
}
|
|
|
|
|
|
|
|
CLEANRET:
|
|
|
|
|
|
|
|
if(buf)myfree(buf);
|
|
|
|
(*param->srv->logfunc)(param, NULL);
|
|
|
|
#ifndef _WIN32
|
|
|
|
param->clisock = INVALID_SOCKET;
|
|
|
|
#endif
|
|
|
|
freeparam(param);
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef WITHMAIN
|
|
|
|
struct proxydef childdef = {
|
|
|
|
udppmchild,
|
|
|
|
0,
|
|
|
|
1,
|
|
|
|
S_UDPPM,
|
|
|
|
" -s single packet UDP service for request/reply (DNS-like) services\n"
|
|
|
|
};
|
|
|
|
#include "proxymain.c"
|
|
|
|
#endif
|