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

84 lines
1.9 KiB
Go

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)
}