package peer import ( "fmt" "log" "net/netip" "runtime/debug" "vppn/fasttime" ) func (peer *Peer) netReader() { defer func() { if r := recover(); r != nil { fmt.Println("stacktrace from panic: \n" + string(debug.Stack())) } }() var ( dupList = &dupList{} n int srcAddr netip.AddrPort nonce Nonce packet = make([]byte, BUFFER_SIZE) decrypted = make([]byte, BUFFER_SIZE) route *route ok bool err error conn = peer.conn ip = peer.ip counters = [2][256]uint64{} // Counter by stream and IP. ) NEXT_PACKET: n, srcAddr, err = conn.ReadFromUDPAddrPort(packet[:BUFFER_SIZE]) if err != nil { log.Fatalf("Failed to read UDP packet: %v", err) } srcAddr = netip.AddrPortFrom(srcAddr.Addr().Unmap(), srcAddr.Port()) if n < NONCE_SIZE { log.Printf("Dropping short UDP packet: %d", n) goto NEXT_PACKET } packet = packet[:n] nonce.Parse(packet[n-NONCE_SIZE:]) // Drop after 8 seconds. if nonce.Timestamp < fasttime.Now()-8 { log.Printf("Dropping old packet: %d", nonce.Timestamp) goto NEXT_PACKET } if nonce.StreamID > 1 { log.Printf("Dropping invalid stream ID: %+v", nonce) goto NEXT_PACKET } if dupList.isDuplicate(nonce.Counter) { //if nonce.Counter+64 <= counters[nonce.StreamID][nonce.SourceIP] { log.Printf("Dropping packet with bad counter: %d (-%d) - %v", nonce.Counter, counters[nonce.StreamID][nonce.SourceIP]-nonce.Counter, srcAddr) goto NEXT_PACKET } route = peer.router.GetRoute(nonce.SourceIP) if route == nil { log.Printf("Dropping packet without route: %+v", nonce) goto NEXT_PACKET } decrypted, ok = decryptPacket(route.EncSharedKey, packet, decrypted) if !ok { log.Printf("Failed to decrypt packet: %v", nonce) goto NEXT_PACKET } // Only updated after we've decrypted. if nonce.Counter > counters[nonce.StreamID][nonce.SourceIP] { counters[nonce.StreamID][nonce.SourceIP] = nonce.Counter } switch ip { case nonce.DestIP: goto PROCESS_LOCAL case nonce.ViaIP: goto FORWARD default: log.Printf("Invalid nonce: %+v", nonce) goto NEXT_PACKET } PROCESS_LOCAL: switch nonce.StreamID { case STREAM_DATA: goto WRITE_IFACE_DATA case STREAM_ROUTING: goto WRITE_ROUTING_PACKET default: log.Printf("Invalid stream ID: %d", nonce.StreamID) goto NEXT_PACKET } WRITE_IFACE_DATA: if _, err = peer.iface.Write(decrypted); err != nil { log.Fatalf("Failed to write to interface: %v", err) } goto NEXT_PACKET WRITE_ROUTING_PACKET: peer.router.HandlePacket(srcAddr, nonce, decrypted) goto NEXT_PACKET FORWARD: route = peer.router.GetRoute(nonce.DestIP) if route == nil || !route.Up { log.Printf("Dropping mediated packet, route not available: %v", nonce) goto NEXT_PACKET } // We don't forward twice. if route.useMediator { log.Printf("Dropping double-forward packet: %v", nonce) goto NEXT_PACKET } if _, err = conn.WriteToUDPAddrPort(decrypted, route.Addr); err != nil { log.Fatalf("Failed to forward packet: %v", err) } goto NEXT_PACKET }