vppn/peer/peer-netreader.go
2024-12-13 21:30:06 +01:00

139 lines
3.0 KiB
Go

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
}