81 lines
2.3 KiB
Go
81 lines
2.3 KiB
Go
package peer
|
|
|
|
import (
|
|
"log"
|
|
"net/netip"
|
|
"sync"
|
|
)
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type connWriter struct {
|
|
localIP byte
|
|
conn udpWriter
|
|
|
|
// For sending control packets.
|
|
cBuf1 []byte
|
|
cBuf2 []byte
|
|
|
|
// For sending data packets.
|
|
dBuf1 []byte
|
|
dBuf2 []byte
|
|
|
|
// Lock around for sending on UDP Conn.
|
|
wLock sync.Mutex
|
|
}
|
|
|
|
func newConnWriter(conn udpWriter, localIP byte) *connWriter {
|
|
w := &connWriter{
|
|
localIP: localIP,
|
|
conn: conn,
|
|
cBuf1: make([]byte, bufferSize),
|
|
cBuf2: make([]byte, bufferSize),
|
|
dBuf1: make([]byte, bufferSize),
|
|
dBuf2: make([]byte, bufferSize),
|
|
}
|
|
return w
|
|
}
|
|
|
|
// Not safe for concurrent use. Should only be called by supervisor.
|
|
func (w *connWriter) SendControlPacket(pkt marshaller, route *peerRoute) {
|
|
enc := encryptControlPacket(w.localIP, route, pkt, w.cBuf1, w.cBuf2)
|
|
w.writeTo(enc, route.RemoteAddr)
|
|
}
|
|
|
|
// Relay control packet. Route must not be nil.
|
|
func (w *connWriter) RelayControlPacket(pkt marshaller, route, relay *peerRoute) {
|
|
enc := encryptControlPacket(w.localIP, route, pkt, w.cBuf1, w.cBuf2)
|
|
enc = encryptDataPacket(w.localIP, route.IP, relay, enc, w.cBuf1)
|
|
w.writeTo(enc, relay.RemoteAddr)
|
|
}
|
|
|
|
// Not safe for concurrent use. Should only be called by ifReader.
|
|
func (w *connWriter) SendDataPacket(pkt []byte, route *peerRoute) {
|
|
enc := encryptDataPacket(w.localIP, route.IP, route, pkt, w.dBuf1)
|
|
w.writeTo(enc, route.RemoteAddr)
|
|
}
|
|
|
|
// Relay a data packet. Route must not be nil.
|
|
func (w *connWriter) RelayDataPacket(pkt []byte, route, relay *peerRoute) {
|
|
enc := encryptDataPacket(w.localIP, route.IP, route, pkt, w.dBuf1)
|
|
enc = encryptDataPacket(w.localIP, route.IP, relay, enc, w.dBuf2)
|
|
w.writeTo(enc, relay.RemoteAddr)
|
|
}
|
|
|
|
// Safe for concurrent use. Should only be called by connReader.
|
|
//
|
|
// This function will send pkt to the peer directly. This is used when a peer
|
|
// is acting as a relay and is forwarding already encrypted data for another
|
|
// peer.
|
|
func (w *connWriter) SendEncryptedDataPacket(pkt []byte, route *peerRoute) {
|
|
w.writeTo(pkt, route.RemoteAddr)
|
|
}
|
|
|
|
func (w *connWriter) writeTo(packet []byte, addr netip.AddrPort) {
|
|
w.wLock.Lock()
|
|
if _, err := w.conn.WriteToUDPAddrPort(packet, addr); err != nil {
|
|
log.Printf("[ConnWriter] Failed to write to UDP port: %v", err)
|
|
}
|
|
w.wLock.Unlock()
|
|
}
|