package peer import ( "fmt" "log" "net" "net/netip" "runtime/debug" "vppn/fasttime" ) func (peer *Peer) ifReader() { defer func() { if r := recover(); r != nil { fmt.Println("stacktrace from panic: \n" + string(debug.Stack())) } }() var ( n int destIP byte router = peer.router route *route iface = peer.iface nonce = Nonce{ SourceIP: peer.ip, PacketType: PACKET_TYPE_DATA, StreamID: STREAM_DATA, } err error now uint64 counterTS uint64 counter uint64 packet = make([]byte, BUFFER_SIZE) encrypted = make([]byte, BUFFER_SIZE) nonceBuf = make([]byte, NONCE_SIZE) toSend []byte signingKey = peer.signPrivKey reqPool = make(chan udpWriteReq, 1024) writeChan = make(chan udpWriteReq, 1024) ) for range cap(reqPool) { reqPool <- udpWriteReq{Packet: make([]byte, BUFFER_SIZE)} } go udpWriter(writeChan, peer.conn, reqPool) for { n, err = iface.Read(packet[:BUFFER_SIZE]) if err != nil { log.Fatalf("Failed to read from interface: %v", err) } if n < 20 { log.Printf("Dropping small packet: %d", n) continue } packet = packet[:n] destIP = packet[19] route = router.GetRoute(destIP) if route == nil { log.Printf("Dropping packet for non-existent IP: %d", destIP) continue } now = uint64(fasttime.Now()) if counterTS < now { counterTS = now counter = now << 30 } counter++ nonce.Counter = counter nonce.ViaIP = route.ViaIP nonce.DestIP = destIP MarshalNonce(nonce, nonceBuf) encrypted = encryptPacket(route.EncSharedKey, nonceBuf, packet, encrypted) if route.ViaIP != 0 { toSend = signPacket(signingKey, encrypted, packet) } else { toSend = encrypted } req := <-reqPool req.Addr = route.Addr req.Packet = req.Packet[:len(toSend)] copy(req.Packet, toSend) writeChan <- req } } type udpWriteReq struct { Addr netip.AddrPort Packet []byte } func udpWriter(in chan udpWriteReq, conn *net.UDPConn, reqPool chan udpWriteReq) { var err error for req := range in { if _, err = conn.WriteToUDPAddrPort(req.Packet, req.Addr); err != nil { log.Fatalf("Failed to write UDP packet: %v", err) } reqPool <- req } }