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 dupChecks [256]*dupCheck lookup func(byte) *peer } func newConnReader(conn *net.UDPConn, localIP byte, lookup func(byte) *peer) *connReader { r := &connReader{ UDPConn: conn, localIP: localIP, lookup: lookup, } for i := range r.dupChecks { r.dupChecks[i] = newDupCheck(0) } return r } 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 r.dupChecks[h.SourceIP].IsDup(h.Counter) { continue } return } }