[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#792394: vtund sends UDP socket number over the network in host order



severity 792394 important
tags 792394 patch ipv6

Hi!  I ran into this same problem.  The patch
07-dual-family-transport.patch changed it to use host order instead of
network order when sending the UDP port number to the remote host.

Background: When a vtun client connects, it first connects on a TCP port
and gets configuration.  If that configuration tells it to connect on a
UDP port, then there is a bidirectional exchange of UDP port numbers over
the TCP port just before closing the TCP socket.  This exchange is
supposed to happen in network byte order, but an oversight in the patch
caused it to happen in host byte order instead.

Discussion: This is a sticky problem because if you fix it, some small
number of users who had successfully upgraded both endpoints of a tunnel
to the same wrong version will experience difficulty.  The exposure is
somewhat limited by the fact that many users probably do not use UDP.
Also in our favor is that vtund is largely used for historical
compatibility (new Debian<=>Debian tunnels would probably use OpenVPN?)
by users who probably do not upgrade any more often than I do...

At any rate, the current situation is wrong.  Even modern Debian hosts
with different byte orders will be unable to talk to eachother.

Here's my patch, which is relative to the tree after an
"apt-get source vtun".  I'm confident in it (I'm using it right now), but
I'm sorry I don't really know anything about debian packaging so I just
hope this is useful for you guys..

Thanks! - Greg

diff -ur vtun-3.0.3.orig/netlib.c vtun-3.0.3/netlib.c
--- vtun-3.0.3.orig/netlib.c	2018-06-13 20:11:33.000000000 -0400
+++ vtun-3.0.3/netlib.c	2018-06-13 20:30:01.000000000 -0400
@@ -224,18 +224,19 @@
      }
 
      /* Write port of the new UDP socket */
-     port = get_port(&saddr);
+     host->sopt.lport = get_port(&saddr);
+     port = htons(host->sopt.lport);
      if( write_n(host->rmt_fd,(char *)&port,sizeof(short)) < 0 ){
         vtun_syslog(LOG_ERR,"Can't write port number");
         return -1;
      }
-     host->sopt.lport = htons(port);
 
      /* Read port of the other's end UDP socket */
      if( readn_t(host->rmt_fd,&port,sizeof(short),host->timeout) < 0 ){
         vtun_syslog(LOG_ERR,"Can't read port number %s", strerror(errno));
         return -1;
      }
+     port = ntohs(port);
 
      opt = sizeof(saddr);
      if( getpeername(host->rmt_fd,(struct sockaddr *)&saddr,&opt) ){
@@ -260,7 +261,7 @@
      is_rmt_fd_connected=1;
 	}
      
-     host->sopt.rport = htons(port);
+     host->sopt.rport = port;
 
      /* Close TCP socket and replace with UDP socket */	
      close(host->rmt_fd); 


Reply to: