Browse Source

Merge pull request #13 from eyakubovich/master

Fixed buffer being too small when MTU is greater than 1500
Eugene Yakubovich 10 năm trước cách đây
mục cha
commit
2a7af51582
5 tập tin đã thay đổi với 32 bổ sung27 xóa
  1. 4 3
      udp/cproxy.go
  2. 16 12
      udp/proxy.c
  3. 7 7
      udp/proxy.go
  4. 1 1
      udp/proxy.h
  5. 4 4
      udp/run.go

+ 4 - 3
udp/cproxy.go

@@ -17,7 +17,7 @@ import (
 	"github.com/coreos-inc/kolach/subnet"
 )
 
-func runCProxy(tun *os.File, conn *os.File, ctl *os.File, tunIP pkg.IP4) {
+func runCProxy(tun *os.File, conn *os.File, ctl *os.File, tunIP pkg.IP4, tunMTU uint) {
 	var log_errors int
 	if log.V(1) {
 		log_errors = 1
@@ -28,6 +28,7 @@ func runCProxy(tun *os.File, conn *os.File, ctl *os.File, tunIP pkg.IP4) {
 		C.int(conn.Fd()),
 		C.int(ctl.Fd()),
 		C.in_addr_t(tunIP.NetworkOrder()),
+		C.size_t(tunMTU),
 		C.int(log_errors),
 	)
 }
@@ -54,7 +55,7 @@ func newCtlSockets() (*os.File, *os.File, error) {
 	return f1, f2, nil
 }
 
-func fastProxy(sm *subnet.SubnetManager, tun *os.File, conn *net.UDPConn, tunIP pkg.IP4, port int) {
+func fastProxy(sm *subnet.SubnetManager, tun *os.File, conn *net.UDPConn, tunIP pkg.IP4, tunMTU uint, port int) {
 	log.Info("Running fast proxy loop")
 
 	c, err := conn.File()
@@ -72,7 +73,7 @@ func fastProxy(sm *subnet.SubnetManager, tun *os.File, conn *net.UDPConn, tunIP
 	defer ctl.Close()
 	defer peerCtl.Close()
 
-	go runCProxy(tun, c, peerCtl, tunIP)
+	go runCProxy(tun, c, peerCtl, tunIP, tunMTU)
 
 	log.Info("Watching for new subnet leases")
 	evts := make(chan subnet.EventBatch)

+ 16 - 12
udp/proxy.c

@@ -16,8 +16,6 @@
 #define CMD_DEFINE
 #include "proxy.h"
 
-#define MTU 1500
-
 struct ip_net {
 	in_addr_t ip;
 	in_addr_t mask;
@@ -292,13 +290,11 @@ inline static int decrement_ttl(struct iphdr *iph) {
 	return 1;
 }
 
-static void tun_to_udp(int tun, int sock) {
-	char buf[MTU] __attribute__ ((aligned (4)));
-
+static void tun_to_udp(int tun, int sock, char *buf, size_t buflen) {
 	struct iphdr *iph;
 	struct sockaddr_in *next_hop;
 
-	ssize_t pktlen = tun_recv_packet(tun, buf, MTU);
+	ssize_t pktlen = tun_recv_packet(tun, buf, buflen);
 	if( pktlen < 0 )
 		return;
 	
@@ -320,11 +316,10 @@ static void tun_to_udp(int tun, int sock) {
 	sock_send_packet(sock, buf, pktlen, next_hop);
 }
 
-static void udp_to_tun(int sock, int tun) {
-	char buf[MTU] __attribute__ ((aligned (4)));
+static void udp_to_tun(int sock, int tun, char *buf, size_t buflen) {
 	struct iphdr *iph;
 
-	ssize_t pktlen = recv(sock, buf, MTU, 0);
+	ssize_t pktlen = recv(sock, buf, buflen, 0);
 	if( pktlen < 0 ) {
 		return;
 	}
@@ -375,7 +370,8 @@ static void process_cmd(int ctl) {
 }
 
 
-void run_proxy(int tun, int sock, int ctl, in_addr_t tun_ip, int log_errors) {
+void run_proxy(int tun, int sock, int ctl, in_addr_t tun_ip, size_t tun_mtu, int log_errors) {
+	char *buf;
 	struct pollfd fds[3] = {
 		{
 			.fd = tun,
@@ -395,6 +391,12 @@ void run_proxy(int tun, int sock, int ctl, in_addr_t tun_ip, int log_errors) {
 	tun_addr = tun_ip;
 	log_enabled = log_errors;
 
+	buf = (char *) malloc(tun_mtu);
+	if( !buf ) {
+		log_error("Failed to allocate %d byte buffer\n", tun_mtu);
+		exit(1);
+	}
+
 	while( !exit_flag ) {
 		int nfds = poll(fds, 3, -1);
 		if( nfds < 0 ) {
@@ -403,13 +405,15 @@ void run_proxy(int tun, int sock, int ctl, in_addr_t tun_ip, int log_errors) {
 		}
 
 		if( fds[0].revents & POLLIN )
-			tun_to_udp(tun, sock);
+			tun_to_udp(tun, sock, buf, tun_mtu);
 
 		if( fds[1].revents & POLLIN )
-			udp_to_tun(sock, tun);
+			udp_to_tun(sock, tun, buf, tun_mtu);
 
 		if( fds[2].revents & POLLIN )
 			process_cmd(ctl);
 	}
+
+	free(buf);
 }
 

+ 7 - 7
udp/proxy.go

@@ -103,13 +103,13 @@ func (r *Router) routePacket(pkt []byte, conn *net.UDPConn) {
 	log.V(1).Info("No route found for ", dstIP)
 }
 
-func proxy(sm *subnet.SubnetManager, tun *os.File, conn *net.UDPConn, port int) {
+func proxy(sm *subnet.SubnetManager, tun *os.File, conn *net.UDPConn, tunMTU uint, port int) {
 	log.Info("Running slow proxy loop")
 
 	rtr := NewRouter(port)
 
-	go proxyTunToUdp(rtr, tun, conn)
-	go proxyUdpToTun(conn, tun)
+	go proxyTunToUdp(rtr, tun, conn, tunMTU)
+	go proxyUdpToTun(conn, tun, tunMTU)
 
 	log.Info("Watching for new subnet leases")
 	evts := make(chan subnet.EventBatch)
@@ -137,8 +137,8 @@ func proxy(sm *subnet.SubnetManager, tun *os.File, conn *net.UDPConn, port int)
 	}
 }
 
-func proxyTunToUdp(r *Router, tun *os.File, conn *net.UDPConn) {
-	pkt := make([]byte, 1600)
+func proxyTunToUdp(r *Router, tun *os.File, conn *net.UDPConn, tunMTU uint) {
+	pkt := make([]byte, tunMTU)
 	for {
 		nbytes, err := tun.Read(pkt)
 		if err != nil {
@@ -149,8 +149,8 @@ func proxyTunToUdp(r *Router, tun *os.File, conn *net.UDPConn) {
 	}
 }
 
-func proxyUdpToTun(conn *net.UDPConn, tun *os.File) {
-	pkt := make([]byte, 1600)
+func proxyUdpToTun(conn *net.UDPConn, tun *os.File, tunMTU uint) {
+	pkt := make([]byte, tunMTU)
 	for {
 		nrecv, err := conn.Read(pkt)
 		if err != nil {

+ 1 - 1
udp/proxy.h

@@ -21,6 +21,6 @@ typedef struct command {
 	short     next_hop_port;
 } command;
 
-void run_proxy(int tun, int sock, int ctl, in_addr_t tun_ip, int log_errors);
+void run_proxy(int tun, int sock, int ctl, in_addr_t tun_ip, size_t tun_mtu, int log_errors);
 
 #endif

+ 4 - 4
udp/run.go

@@ -15,7 +15,6 @@ import (
 
 const (
 	encapOverhead = 28 // 20 bytes IP hdr + 8 bytes UDP hdr
-	defaultMTU    = 1500 - encapOverhead
 )
 
 func configureIface(ifname string, ipn pkg.IP4Net, mtu int) error {
@@ -105,7 +104,8 @@ func Run(sm *subnet.SubnetManager, iface *net.Interface, ip net.IP, port int, fa
 	if iface.MTU > 0 {
 		mtu = iface.MTU - encapOverhead
 	} else {
-		mtu = defaultMTU
+		log.Errorf("Failed to determine MTU for %s interface", ip)
+		return
 	}
 
 	err = configureIface(tunName, ipn, mtu)
@@ -118,8 +118,8 @@ func Run(sm *subnet.SubnetManager, iface *net.Interface, ip net.IP, port int, fa
 	ready(sn, mtu)
 
 	if fast {
-		fastProxy(sm, tun, conn, ipn.IP, port)
+		fastProxy(sm, tun, conn, ipn.IP, uint(mtu), port)
 	} else {
-		proxy(sm, tun, conn, port)
+		proxy(sm, tun, conn, uint(mtu), port)
 	}
 }