On 10/13/03(04:39) I wrote in <_A2445@delegate-en.ML_> |You can get data from a client on UDP, relay it via chained DeleGate over |TCP, then put it to a server on UDP. Supposing the DeleGate confronting a |client is hostA:1234/udp, and the target UDP server is hostU:5678/udp, |a pair of tcprelay-DeleGate to relay between UDP client/server should be |configured like this: | | client <--UDP--> hostA <--TCP--> hostB <--UDP--> hostU(server) | | [hostA] delegated -PhostA:1234/udp SERVER=tcprelay://hostB:3456 | [hostB] delegated -PhostB:3456 SERVER=tcprelay://hostU:5678 CONNECT=udp | |But if this works for your purpose, it might not be good for parallel clients |and/or heavy usage. At least you need TIMEOUT=io:10s or so to sweep |DeleGate processes which will not do accept UDP packet any more. I implemented a practical way to convey UDP over TCP by "SockMux" protocol as the enclosed patch. It consumes just one DeleGate process at each end, and a single TCP connection between them for multiple parallel UDP associations. It is used like this: [hostA] delegated SERVER=sockmux://hostB:3456 PORT=1234/udp [hostB] delegated SERVER=sockmux -PhostB:3456 SERVER=tcprelay://hostU:5678,-in CONNECT=udp Cheers, Yutaka -- D G Yutaka Sato <pfqcabdyi-mykgh45kr7dw.ml@delegate.org> http://www.delegate.org/y.sato/ ( - ) National Institute of Advanced Industrial Science and Technology (AIST) _< >_ 1-1-4 Umezono, Tsukuba, Ibaraki, 305-8568 Japan Do the more with the less -- B. Fuller diff -cr ../../dist/delegate8.7.3/src/delegated.c ./delegated.c *** ../../dist/delegate8.7.3/src/delegated.c Wed Oct 1 11:35:56 2003 --- ./delegated.c Tue Oct 14 12:06:57 2003 *************** *** 3800,3805 **** --- 3800,3806 ---- Finish(0); } if( streq(proto,"sockmux") ){ + scanEnv(Conn,P_CONNECT,scan_CONNECT); sox_main(ac,av,Conn,ServSock(),SERVER_PORT()); Finish(0); } diff -cr ../../dist/delegate8.7.3/src/master.c ./master.c *** ../../dist/delegate8.7.3/src/master.c Fri Aug 29 11:45:24 2003 --- ./master.c Tue Oct 14 12:21:02 2003 *************** *** 1540,1545 **** --- 1540,1548 ---- /* ACCEPT */ case 'a': case 'A': + if( isUDPsock(sock) ){ + nsock = UDPaccept(sock,-1,ACC_TIMEOUT); + }else nsock = ACCEPT(sock,0,-1,ACC_TIMEOUT); sock = nsock; if( 0 <= sock ) diff -cr ../../dist/delegate8.7.3/src/sox.c ./sox.c *** ../../dist/delegate8.7.3/src/sox.c Thu Aug 28 06:29:19 2003 --- ./sox.c Tue Oct 14 11:35:35 2003 *************** *** 59,64 **** --- 59,66 ---- extern int CFI_DISABLE; extern char *numscanX(); extern char *getADMIN(); + int SOXMUX_UDP_TIMEOUT = 180; + int SOXMUX_UDP_MAX = 64; /* * SIMPLE SOCKET TUNNELING MULTIPLEXER PROTOCOL *************** *** 140,145 **** --- 142,148 ---- unsigned int s_rsentN; /* sent to remote agent */ unsigned int s_rsent; /* bytes sent */ unsigned int s_rpendN; /* pending status caused */ + unsigned int s_time; /* the clock of the last activity */ } Stats; typedef struct { *************** *** 154,159 **** --- 157,163 ---- Stats a_stats; short a_commin; /* Laid of commin */ short a_commout; /* Laid of commout */ + short a_Ludp; /* local port is UDP */ } Agent; #define a_recv a_stats.s_rrecv *************** *** 165,170 **** --- 169,175 ---- #define a_lpend a_lbuf.b_rem typedef struct { + int s_time; int s_clock; int s_nlaid; Stats s_stats; *************** *** 491,501 **** --- 496,545 ---- sox->s_nlaid = ci + 1; return ci; } + + static sweepAgents(sox) + Sox *sox; + { int ai,idle,nudp,maxi,maxit; + Agent *Ap,*Api; + + nudp = 0; + Api = 0; + maxit = -1; + for( ai = 0; ai < Agents; ai++ ){ + Ap = Agentpv[ai]; + if( !Ap->a_Ludp ) + continue; + + nudp++; + idle = sox->s_time - Ap->a_stats.s_time; + if( maxit < idle ){ + Api = Ap; + maxit = idle; + } + if( idle < SOXMUX_UDP_TIMEOUT ) + continue; + + Ap->a_stat = SOX_CLOSED; + Trace("Timeout L#%d[%d]%d idle=%ds", + Ap->a_Laid,Ap->a_abid,Ap->a_sock, + idle); + } + if( SOXMUX_UDP_MAX < nudp ){ + if( Api->a_stat != SOX_CLOSED ){ + Trace("Pushout L#%d[%d]%d idle=%ds", + Api->a_Laid,Api->a_abid,Api->a_sock, + sox->s_time - Api->a_stats.s_time); + Api->a_stat = SOX_CLOSED; + } + } + } static Agent *newAgent(sox,raid,sock,stat) Sox *sox; { Agent *Apn; int bid; + sweepAgents(sox); + AgentSerno++; Apn = Agentpv[Agents++]; bid = Apn->a_abid; *************** *** 718,723 **** --- 762,768 ---- set_nodelay(clsock,1); Apn = newAgent(sox,-1,clsock,SOX_CONNECT); + Apn->a_Ludp = isUDPsock(clsock); aid = Apn->a_Laid; Apn->a_remote = 0; Qfdset = 0; *************** *** 1105,1110 **** --- 1150,1156 ---- Packet packb,*pack = &packb; sox->s_clock++; + sox->s_time = time(0); if( Qfdset == 0 ) sox_fdset(sox); *************** *** 1282,1287 **** --- 1328,1334 ---- Api->a_sent += PK_Leng(pack); Api->a_sentN++; Api->a_rpend += PK_Leng(pack); + Api->a_stats.s_time = sox->s_time; if( OOB ){ TpendN++; Api->a_pendN++; *************** *** 1347,1352 **** --- 1394,1400 ---- ApR = Agentpv[ci]; ApR->a_recv += PK_Leng(pack); ApR->a_recvN++; + ApR->a_stats.s_time = sox->s_time; break; } } diff -cr ../../dist/delegate8.7.3/src/svport.c ./svport.c *** ../../dist/delegate8.7.3/src/svport.c Thu Aug 7 12:36:43 2003 --- ./svport.c Tue Oct 14 12:18:40 2003 *************** *** 845,854 **** --- 845,869 ---- int port1,port2,port; int sock; int pi; + char *dp,mod[32]; + int nlisten; host[0] = 0; port1 = 0; port2 = 0; + + mod[0] = 0; + if( dp = strchr(hostport,'/') ) + wordScan(dp+1,mod); + if( dp = strchr(hostport,':') ) + dp = strchr(dp,'.'); + else dp = strchr(hostport,'.'); + if( dp != NULL ) + wordScan(dp+1,mod); + nlisten = DELEGATE_LISTEN; + if( streq(mod,"udp") ) + nlisten = -1; + if( strchr(hostport,':') ) sscanf(hostport,"%[^:]:%d-%d",host,&port1,&port2); else sscanf(hostport,"%d-%d",&port1,&port2); *************** *** 856,862 **** --- 871,880 ---- port2 = port1; for( port = port1; port <= port2; port++ ){ + /* sock = findopen_port("reservePORT",host,port,DELEGATE_LISTEN); + */ + sock = findopen_port("reservePORT",host,port,nlisten); if( sock < 0 ){ fprintf(stderr,"CANNOT BIND PORT %d\r\n",port); exit(1);