package udp import ( "log" "mpbl3p/proxy" "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 func() proxy.MacVerifier, g func() proxy.MacGenerator, c func() 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, 6000) log.Println("listening...") n, addr, err := pconn.ReadFromUDP(buf) if err != nil { panic(err) } log.Println("listened") raddr := fromUdpAddress(*addr) if f, exists := receivedConnections[raddr]; exists { log.Println("existing flow") log.Println("handling...") f.handleDatagram(buf[:n]) log.Println("handled") continue } v := v() g := g() f := newFlow(c(), v) f.writer = pconn f.raddr = addr f.isAlive = true log.Printf("received new udp connection: %v\n", f) go f.earlyUpdateLoop(g, 0) receivedConnections[raddr] = &f p.AddConsumer(&f, g) p.AddProducer(&f, v) log.Println("handling...") f.handleDatagram(buf[:n]) log.Println("handled") } }() return nil }