3proxy/src/udppm.c
Vladimir Dubrovin bebc3894e2
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Waiting to run
Support acls for UDP ASSOC, fix udppm via SOCKSv5
2026-08-11 19:02:54 +03:00

96 lines
2.9 KiB
C

/*
3APA3A simplest proxy server
(c) 2002-2026 by Vladimir Dubrovin <vlad@3proxy.org>
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; }
static void udpparam2hash(const struct hashtable *ht, void *index, uint8_t *hash){
struct clientparam *param = (struct clientparam *)index;
uint32_t m1, m2;
m1 = murmurhash3(SAADDR(&param->srv->intsa), SAADDRLEN(&param->srv->intsa), 0x3a3a3a3a);
m1 = murmurhash3(SAPORT(&param->sincr), 2, m1);
m2 = murmurhash3(SAADDR(&param->sincr), SAADDRLEN(&param->sincr), m1);
m2 = murmurhash3(SAPORT(&param->srv->intsa), 2, m2);
memcpy(hash, &m1, 4);
memcpy(hash+4, &m2, 4);
}
struct hashtable udp_table = {udpparam2hash, udpparam2hash, sizeof(struct clientparam *), 8};
int socks5_udp_build_hdr(unsigned char *buf, PROXYSOCKADDRTYPE *addr);
void * udppmchild(struct clientparam* param) {
int authres;
int i;
int len = 0;
if(parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport))) { RETURN(100) }
#ifndef NOIPV6
param->sinsl = *SAFAMILY(&param->req) == AF_INET6? param->srv->extsa6 : param->srv->extsa;
#else
param->sinsl = param->srv->extsa;
#endif
*SAPORT(&param->sinsl) = 0;
param->sinsr = param->req;
param->operation = UDPASSOC;
authres = (*param->srv->authfunc)(param);
if(authres) { RETURN(authres); }
if((authres = udpbind(param))) { RETURN(authres); }
if(!param->srv->s_option)hashadd(&udp_table, param, &param, MAX_COUNTER_TIME);
if(!param->srvbuf){
if(!(param->srvbuf = malloc(UDPBUFSIZE)))RETURN(11);
param->srvbufsize = UDPBUFSIZE;
}
if(!param->bandlimfunc || !(*param->bandlimfunc)(param, 0, param->srv->udplen)){
if(param->udp_nhops){
for(i=1; i < param->udp_nhops; i++){
len+=socks5_udp_build_hdr(param->srvbuf+len, &param->udp_relay[i-1]);
}
len += socks5_udp_build_hdr(param->srvbuf+len, &param->req);
}
memcpy(param->srvbuf+len, param->srv->udpbuf, param->srv->udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : param->srv->udplen);
len += param->srv->udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : param->srv->udplen;
param->srv->so._sendto(param->sostate, param->remsock, (char *)param->srvbuf, len, 0, (struct sockaddr *)&param->sinsr, SASIZE(&param->sinsr));
param->statscli64 += param->srvinbuf;
param->nwrites++;
}
_3proxy_sem_unlock(udpinit);
param->srvinbuf = 0;
param->clisock = param->srv->srvsock;
param->waitserver64 = 0x7fffffffffffffff;
param->res = udpsockmap(param, conf.timeouts[STRING_L]);
_3proxy_sem_lock(udpinit);
if(!param->srv->s_option)hashdelete(&udp_table, param);
CLEANRET:
_3proxy_sem_unlock(udpinit);
dolog(param, NULL);
param->clisock = INVALID_SOCKET;
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