88 lines
1.5 KiB
Go
88 lines
1.5 KiB
Go
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
|
|
}
|