Article delegate-en/2446 of [1-5169] on the server localhost:119
  upper oldest olders older1 this newer1 newers latest
search
[Top/Up] [oldest] - [Older+chunk] - [Newer+chunk] - [newest + Check]
[Reference:<_A2445@delegate-en.ML_>]
Newsgroups: mail-lists.delegate-en

[DeleGate-En] UDP over TCP by SockMux (Re: VOIP Tunneling)
14 Oct 2003 03:37:37 GMT feedback@delegate.org (Yutaka Sato)


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 <y.sato@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);

  admin search upper oldest olders older1 this newer1 newers latest
[Top/Up] [oldest] - [Older+chunk] - [Newer+chunk] - [newest + Check]
@_@V