vppn/node/conn.go
2024-12-16 20:51:30 +01:00

104 lines
1.9 KiB
Go

package node
import (
"log"
"net"
"net/netip"
"vppn/fasttime"
)
type connWriter struct {
*net.UDPConn
localIP byte
buf []byte
counters [256]uint64
lookup func(byte) *peer
}
func newConnWriter(conn *net.UDPConn, localIP byte, lookup func(byte) *peer) *connWriter {
w := &connWriter{
UDPConn: conn,
localIP: localIP,
buf: make([]byte, bufferSize),
lookup: lookup,
}
for i := range w.counters {
w.counters[i] = uint64(fasttime.Now() << 30)
}
return w
}
func (w *connWriter) WriteTo(remoteIP, packetType byte, data []byte) error {
peer := w.lookup(remoteIP)
if peer == nil || peer.Addr == nil {
log.Printf("No peer: %d", remoteIP)
return nil
}
w.counters[remoteIP]++
h := header{
Counter: w.counters[remoteIP],
SourceIP: w.localIP,
ViaIP: 0,
DestIP: remoteIP,
PacketType: packetType,
DataSize: uint16(len(data)),
}
buf := w.buf[:len(data)+headerSize]
h.Marshal(buf)
copy(buf[headerSize:], data)
_, err := w.WriteToUDPAddrPort(buf, *peer.Addr)
return err
}
// ----------------------------------------------------------------------------
type connReader struct {
*net.UDPConn
localIP byte
counters [256]uint64
lookup func(byte) *peer
}
func newConnReader(conn *net.UDPConn, localIP byte, lookup func(byte) *peer) *connReader {
return &connReader{
UDPConn: conn,
localIP: localIP,
lookup: lookup,
}
}
func (r *connReader) Read(buf []byte) (remoteAddr netip.AddrPort, h header, data []byte, err error) {
var n int
for {
n, remoteAddr, err = r.ReadFromUDPAddrPort(buf[:bufferSize])
if err != nil {
return
}
buf = buf[:n]
if n < headerSize {
continue // Packet it soo short.
}
h.Parse(buf)
data = buf[headerSize:]
if len(data) != int(h.DataSize) {
continue // Packet is corrupt.
}
if h.Counter > r.counters[h.SourceIP] {
r.counters[h.SourceIP] = h.Counter
}
return
}
}