package udp import ( "errors" "log" "mpbl3p/proxy" "mpbl3p/shared" "net" ) type ComparableUdpAddress struct { IP [16]byte Port int Zone string } func fromUdpAddress(address net.UDPAddr) ComparableUdpAddress { var ip [16]byte for i, b := range []byte(address.IP) { ip[i] = b } return ComparableUdpAddress{ IP: ip, Port: address.Port, Zone: address.Zone, } } func NewListener(p *proxy.Proxy, local string, v proxy.MacVerifier, g proxy.MacGenerator, c Congestion) error { laddr, err := net.ResolveUDPAddr("udp", local) if err != nil { return err } pconn, err := net.ListenUDP("udp", laddr) if err != nil { return err } err = pconn.SetWriteBuffer(0) if err != nil { panic(err) } receivedConnections := make(map[ComparableUdpAddress]*Flow) go func() { for { buf := make([]byte, 1500) _, addr, err := pconn.ReadFromUDP(buf) if err != nil { panic(err) } raddr := fromUdpAddress(*addr) if f, exists := receivedConnections[raddr]; exists { f.handleDatagram(buf) continue } f := newFlow(c, v) f.writer = pconn f.raddr = *addr f.isAlive = true go func() { var err error for !errors.Is(err, shared.ErrDeadConnection) { f.congestion.AwaitEarlyUpdate(0) err = f.Consume(proxy.NewSimplePacket(nil), g) } }() receivedConnections[raddr] = &f log.Printf("received new udp connection: %v\n", f) p.AddConsumer(&f) p.AddProducer(&f, v) } }() return nil }