Hi all,

first of all, thanx for the nice vtun!

Then I have a patch. I was using vtun over some UMTS connection and then I hit a nasty NAT. Worked fine over TCP, of course, but the issue was that the UDP stream was mapped by the NAT box to a different port. And I really wanted to keep the UDP encapsulation (most of my packets would be RTP and I do have packet-loss).

So vtun does the handshake but the the UDP socket is mapped to another port on the NAT as the one that the client behind NAT indicated in the handshake. The UDP connect happens with the parameters as the source of the TCP packets and the indicated port in the handshake, which means that the actual NATed UDP packets are dropped.

The idea, which seems to work, was to delay the connect until the first packet is received and then use the real UDP from address. This of course would not work if applied on both sides, so I added an extra parameter ("-N" NAT hack) and a couple of global variables to orchestrate the delayed connect of the UDP socket. I also disabled the first Echo Request as there would be no destination port to send to (this however could be worked around by using sendto() instead of write()).

Well, I hacked this quickly, so probably many things are not kosher with the line of the project, but it should be enough to get the idea.

I am looking forward for feedback, even if you would completely reject the patch.

Cheers,
-Dragos

--
Best Regards,
Dragos Vingarzan

diff -b -w -a -p vtun-3.0.1_orig/linkfd.c vtun-3.0.1/linkfd.c
*** vtun-3.0.1_orig/linkfd.c	2006-12-11 01:55:06.000000000 -0600
--- vtun-3.0.1/linkfd.c	2009-02-13 11:10:43.000000000 -0600
*************** int lfd_linker(void)
*** 212,217 ****
--- 212,219 ----
          return 0; 
       }
  
+ 	/* because server can't send the first VTUN_ECHO_REQ as it would be probably disconnected */
+ 	if (!vtun.nat_hack)
       	proto_write(fd1, buf, VTUN_ECHO_REQ);     	
  
       maxfd = (fd1 > fd2 ? fd1 : fd2) + 1;
diff -b -w -a -p vtun-3.0.1_orig/main.c vtun-3.0.1/main.c
*** vtun-3.0.1_orig/main.c	2006-12-11 01:55:06.000000000 -0600
--- vtun-3.0.1/main.c	2009-02-13 11:10:17.000000000 -0600
*************** int main(int argc, char *argv[], char *e
*** 76,81 ****
--- 76,82 ----
       vtun.bind_addr.port = -1;
       vtun.svr_type = -1;
       vtun.syslog   = LOG_DAEMON;
+      vtun.nat_hack = 0;
  
       /* Initialize default host options */
       memset(&default_host, 0, sizeof(default_host));
*************** int main(int argc, char *argv[], char *e
*** 89,95 ****
       /* Start logging to syslog and stderr */
       openlog("vtund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
  
!      while( (opt=getopt(argc,argv,"misf:P:L:t:np")) != EOF ){
  	switch(opt){
  	    case 'm':
  	        if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) {
--- 90,96 ----
       /* Start logging to syslog and stderr */
       openlog("vtund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
  
!      while( (opt=getopt(argc,argv,"misNf:P:L:t:np")) != EOF ){
  	switch(opt){
  	    case 'm':
  	        if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) {
*************** int main(int argc, char *argv[], char *e
*** 102,107 ****
--- 103,111 ----
  	    case 's':
  		svr = 1;
  		break;
+ 	    case 'N':
+ 		vtun.nat_hack = 1;
+ 		break;
  	    case 'L':
  		vtun.svr_addr = strdup(optarg);
  		break;
diff -b -w -a -p vtun-3.0.1_orig/netlib.c vtun-3.0.1/netlib.c
*** vtun-3.0.1_orig/netlib.c	2006-12-11 01:55:06.000000000 -0600
--- vtun-3.0.1/netlib.c	2009-02-13 11:09:08.000000000 -0600
*************** unsigned long getifaddr(char * ifname) 
*** 138,143 ****
--- 138,145 ----
       return addr.sin_addr.s_addr;
  }
  
+ extern struct vtun_opts vtun;
+ int is_rmt_fd_connected=1;      
  /* 
   * Establish UDP session with host connected to fd(socket).
   * Returns connected UDP socket or -1 on error.
*************** int udp_session(struct vtun_host *host) 
*** 190,199 ****
--- 192,205 ----
       }
  
      saddr.sin_port = port;
+ 	if (vtun.nat_hack)
+ 		is_rmt_fd_connected=0;
+ 	else{
  		if( connect(s,(struct sockaddr *)&saddr,sizeof(saddr)) ){
  			vtun_syslog(LOG_ERR,"Can't connect socket");
  			return -1;
  		}
+ 	} 
  	host->sopt.rport = htons(port);
  
       /* Close TCP socket and replace with UDP socket */	
diff -b -w -a -p vtun-3.0.1_orig/vtund.8 vtun-3.0.1/vtund.8
*** vtun-3.0.1_orig/vtund.8	2006-12-11 01:55:06.000000000 -0600
--- vtun-3.0.1/vtund.8	2009-02-13 12:06:49.000000000 -0600
*************** vtund \- VTun(Virtual Tunnel) daemon.
*** 25,30 ****
--- 25,33 ----
  [ 
  .I -P port 
  ]
+ [ 
+ .I -N
+ ]
  .LP 
  .B vtund 
  [ 
*************** vtund \- VTun(Virtual Tunnel) daemon.
*** 45,50 ****
--- 48,56 ----
  [ 
  .I -n 
  ] 
+ [ 
+ .I -N
+ ]
  <
  .I session 
  >
*************** Read config information from the
*** 75,80 ****
--- 81,89 ----
  .TP 
  .I -n 
  Do not become daemon.
+ .TP 
+ .I -N 
+ Employ the NAT hack for UDP \- in case you want to transport your tunnel over NAT, but the NAT is assigning another outbound port for the UDP packets as for the TCP ones in the handshake. This hack practically disables the first ECHO\-Request packet and delays the UDP socket connect until a first packet has been received over UDP. Do not use for the end behind NAT, just for the one outside. This is of course unsafe as the tunnel can be easily hi\-jacked at the beginning. 
  .SS Server mode: 
  .TP 
  .I -s
diff -b -w -a -p vtun-3.0.1_orig/vtun.h vtun-3.0.1/vtun.h
*** vtun-3.0.1_orig/vtun.h	2006-12-11 01:55:06.000000000 -0600
--- vtun-3.0.1/vtun.h	2009-02-13 11:03:33.000000000 -0600
*************** struct vtun_opts {
*** 206,211 ****
--- 206,212 ----
     struct vtun_addr bind_addr;	 /* Server should listen on this address */
     int  svr_type;	 /* Server mode */
     int  syslog; 	 /* Facility to log messages to syslog under */
+    int  nat_hack;
  };
  #define VTUN_STAND_ALONE	0 
  #define VTUN_INETD		1	
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
VTun-devel mailing list
VTun-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vtun-devel

Reply via email to