package peer import ( "log" "net" "runtime/debug" "sync" "vppn/fasttime" ) type connSender struct { conn *net.UDPConn sourceIP byte streamID byte encrypted []byte nonceBuf []byte counter uint64 } func newConnSender(conn *net.UDPConn, srcIP, streamID byte) *connSender { return &connSender{ conn: conn, sourceIP: srcIP, streamID: streamID, encrypted: make([]byte, BUFFER_SIZE), nonceBuf: make([]byte, NONCE_SIZE), counter: uint64(fasttime.Now()) << 30, // Ensure counter is always increasing. } } func (cs *connSender) send(packetType byte, packet []byte, dstRoute, viaRoute *route) { if dstRoute.useMediator && viaRoute == nil { log.Printf("Dropping forwarded packet: no mediator.") return } cs.counter++ nonce := Nonce{ Timestamp: fasttime.Now(), Counter: cs.counter, SourceIP: cs.sourceIP, DestIP: dstRoute.PeerIP, StreamID: cs.streamID, PacketType: packetType, } if dstRoute.useMediator { nonce.ViaIP = viaRoute.PeerIP } nonce.Marshal(cs.nonceBuf) addr := dstRoute.Addr encrypted := encryptPacket(dstRoute.EncSharedKey, cs.nonceBuf, packet, cs.encrypted) if viaRoute != nil { packet, encrypted = encrypted, packet encrypted = encryptPacket(viaRoute.EncSharedKey, cs.nonceBuf, packet, encrypted) addr = viaRoute.Addr } if _, err := cs.conn.WriteToUDPAddrPort(encrypted, addr); err != nil { log.Fatalf("Failed to write UDP packet: %v\n%s", err, debug.Stack()) } } // ---------------------------------------------------------------------------- type safeConnSender struct { lock sync.Mutex sender *connSender } func newSafeConnSender(sender *connSender) *safeConnSender { return &safeConnSender{sender: sender} } func (s *safeConnSender) send(packetType byte, packet []byte, route, viaRoute *route) { s.lock.Lock() defer s.lock.Unlock() s.sender.send(packetType, packet, route, viaRoute) }