package srt import ( "net" ) type Intake struct { max_conns int tunnels []*Tunnel socket net.PacketConn buffer []byte } func NewIntake(l net.PacketConn, max_conns int) (*Intake) { intake := new(Intake) intake.max_conns = max_conns intake.tunnels = make([]*Tunnel, 0) intake.buffer = make([]byte, 1500) intake.socket = l return intake } func (intake *Intake) NewTunnel(l net.PacketConn, peer net.Addr) (*Tunnel) { if len(intake.tunnels) < intake.max_conns { tunnel := new(Tunnel) tunnel.socket = l tunnel.peer = peer tunnel.queue = make(chan []byte, 10) intake.tunnels = append(intake.tunnels, tunnel) go tunnel.Start() return tunnel } return nil } func (intake *Intake) get_tunnel(peer net.Addr) (*Tunnel) { var tunnel *Tunnel for i := 0; i < len(intake.tunnels); i++ { if intake.tunnels[i].broken { intake.tunnels = append(intake.tunnels[:i], intake.tunnels[i+1:]...) i-- continue } if intake.tunnels[i].peer.String() == peer.String() { tunnel = intake.tunnels[i] } } if tunnel == nil { tunnel = intake.NewTunnel(intake.socket, peer) } return tunnel } func (intake *Intake) Read() { n, peer, err := intake.socket.ReadFrom(intake.buffer) if err != nil { return } tunnel := intake.get_tunnel(peer) if tunnel == nil { return } pkt := make([]byte, n) copy(pkt, intake.buffer[:n]) select { case tunnel.queue <- pkt: default: tunnel.broken = true } }