139 lines
3.0 KiB
Go
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
|
|
}
|