dissertation-2-code/udp/listener.go

92 lines
1.6 KiB
Go
Raw Normal View History

2020-11-25 19:35:31 +00:00
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,
}
}
2020-11-29 22:06:38 +00:00
func NewListener(p *proxy.Proxy, local string, v func() proxy.MacVerifier, g func() proxy.MacGenerator, c func() Congestion) error {
2020-11-25 19:35:31 +00:00
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 {
2020-11-27 17:31:32 +00:00
buf := make([]byte, 6000)
2020-11-25 19:35:31 +00:00
2020-11-27 17:31:32 +00:00
log.Println("listening...")
n, addr, err := pconn.ReadFromUDP(buf)
2020-11-25 19:35:31 +00:00
if err != nil {
panic(err)
}
2020-11-27 17:31:32 +00:00
log.Println("listened")
2020-11-25 19:35:31 +00:00
raddr := fromUdpAddress(*addr)
if f, exists := receivedConnections[raddr]; exists {
2020-11-27 17:31:32 +00:00
log.Println("existing flow")
log.Println("handling...")
f.handleDatagram(buf[:n])
log.Println("handled")
2020-11-25 19:35:31 +00:00
continue
}
2020-11-29 22:06:38 +00:00
v := v()
g := g()
2020-11-27 20:17:59 +00:00
f := newFlow(c(), v)
2020-11-26 22:10:37 +00:00
f.writer = pconn
2020-11-26 22:46:37 +00:00
f.raddr = addr
2020-11-26 22:10:37 +00:00
f.isAlive = true
2020-11-27 17:31:32 +00:00
log.Printf("received new udp connection: %v\n", f)
2020-11-25 19:35:31 +00:00
2020-11-27 17:31:32 +00:00
go f.earlyUpdateLoop(g, 0)
2020-11-25 19:35:31 +00:00
2020-11-27 17:31:32 +00:00
receivedConnections[raddr] = &f
2020-11-25 19:35:31 +00:00
2020-11-29 22:06:38 +00:00
p.AddConsumer(&f, g)
2020-11-25 19:35:31 +00:00
p.AddProducer(&f, v)
2020-11-27 17:31:32 +00:00
log.Println("handling...")
f.handleDatagram(buf[:n])
log.Println("handled")
2020-11-25 19:35:31 +00:00
}
}()
return nil
}