func (r *Router) routePacket(pkt []byte, conn *net.UDPConn) { if len(pkt) < minIP4HdrSize { log.V(1).Infof("Packet too small (%d bytes), unable to route", len(pkt)) return } r.mux.Lock() defer r.mux.Unlock() dstIP := ip.FromBytes(pkt[16:20]) for i, re := range r.routes { if re.sn.Contains(dstIP) { nbytes, err := conn.WriteToUDP(pkt, re.addr) switch { case err != nil: log.V(1).Info("UDP send failed with: ", err) case nbytes != len(pkt): log.V(1).Infof("Was only able to UDP send %d out of %d bytes to %s: ", nbytes, len(pkt), re.addr.IP) } // packets for same dest tend to come in burst. swap to front make it faster for subsequent ones if i != 0 { r.routes[0], r.routes[i] = r.routes[i], r.routes[0] } return } } log.V(1).Info("No route found for ", dstIP) }
func proxyUdpToTun(conn *net.UDPConn, tun *os.File, tunMTU uint) { pkt := make([]byte, tunMTU) for { nrecv, err := conn.Read(pkt) if err != nil { log.V(1).Info("Error reading from socket: ", err) } else { nsent, err := tun.Write(pkt[:nrecv]) switch { case err != nil: log.V(1).Info("Error writing to TUN device: ", err) case nsent != nrecv: log.V(1).Infof("Was only able to write %d out of %d bytes to TUN device: ", nsent, nrecv) } } } }
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 { log.V(1).Info("Error reading from TUN device: ", err) } else { r.routePacket(pkt[:nbytes], conn) } } }
func runCProxy(tun *os.File, conn *os.File, ctl *os.File, tunIP ip.IP4, tunMTU uint) { var log_errors int if log.V(1) { log_errors = 1 } C.run_proxy( C.int(tun.Fd()), C.int(conn.Fd()), C.int(ctl.Fd()), C.in_addr_t(tunIP.NetworkOrder()), C.size_t(tunMTU), C.int(log_errors), ) }