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 signingKey []byte } func newConnSender(conn *net.UDPConn, srcIP, streamID byte, signingPrivKey []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. signingKey: signingPrivKey, } } func (cs *connSender) send(packetType byte, packet []byte, route *route) { cs.counter++ nonce := Nonce{ Timestamp: fasttime.Now(), Counter: cs.counter, SourceIP: cs.sourceIP, ViaIP: route.ViaIP, DestIP: route.PeerIP, StreamID: cs.streamID, PacketType: packetType, } nonce.Marshal(cs.nonceBuf) encrypted := encryptPacket(route.EncSharedKey, cs.nonceBuf, packet, cs.encrypted) var toSend []byte if route.ViaIP != 0 { toSend = signPacket(cs.signingKey, encrypted, packet) } else { toSend = encrypted } if _, err := cs.conn.WriteToUDPAddrPort(toSend, route.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 *route) { s.lock.Lock() defer s.lock.Unlock() s.sender.send(packetType, packet, route) }