| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- /*
- 3APA3A simpliest proxy server
- (c) 2002-2016 by Vladimir Dubrovin <3proxy@3proxy.ru>
- please read License Agreement
- */
- #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));
- if (SAISNULL(¶m->req)) {
- 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;
- i = sockrecvfrom(param->srv->srvsock, (struct sockaddr *)¶m->sincr, param->clibuf, param->clibufsize, 0);
- if(i<=0){
- param->srv->fds.events = POLLIN;
- RETURN (214);
- }
- param->cliinbuf = i;
- #ifdef _WIN32
- if((param->clisock=so._socket(SASOCK(¶m->sincr), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
- RETURN(818);
- }
- if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (char *)&ul, sizeof(int))) {RETURN(820);};
- ioctlsocket(param->clisock, FIONBIO, &ul);
- 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,SASIZE(¶m->sinsl))) {
- RETURN(822);
- }
- #else
- param->clisock = param->srv->srvsock;
- #endif
- #ifndef NOIPV6
- memcpy(¶m->sinsl, *SAFAMILY(¶m->req) == AF_INET? (struct sockaddr *)¶m->srv->extsa : (struct sockaddr *)¶m->srv->extsa6, SASIZE(¶m->req));
- #else
- memcpy(¶m->sinsl, ¶m->srv->extsa, SASIZE(¶m->req));
- #endif
- *SAPORT(¶m->sinsl) = 0;
- if ((param->remsock=so._socket(SASOCK(¶m->sinsl), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
- if(so._bind(param->remsock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->sinsl))) {RETURN (12);}
- #ifdef _WIN32
- ioctlsocket(param->remsock, FIONBIO, &ul);
- #else
- fcntl(param->remsock,F_SETFL,O_NONBLOCK);
- #endif
- memcpy(¶m->sinsr, ¶m->req, sizeof(param->req));
- 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
|