10 type Listener struct {
17 addr2peer map[string]cltPeer
18 id2peer map[PeerID]cltPeer
22 // Listen listens for packets on conn until it is closed.
23 func Listen(conn net.PacketConn) *Listener {
27 clts: make(chan cltPeer),
28 errs: make(chan error),
30 addr2peer: make(map[string]cltPeer),
31 id2peer: make(map[PeerID]cltPeer),
34 pkts := make(chan netPkt)
35 go readNetPkts(l.conn, pkts, l.errs)
37 for pkt := range pkts {
38 if err := l.processNetPkt(pkt); err != nil {
45 for _, clt := range l.addr2peer {
53 // Accept waits for and returns a connecting Peer.
54 // You should keep calling this until it returns net.ErrClosed
55 // so it doesn't leak a goroutine.
56 func (l *Listener) Accept() (*Peer, error) {
58 case clt, ok := <-l.clts:
64 return nil, net.ErrClosed
74 // Addr returns the net.PacketConn the Listener is listening on.
75 func (l *Listener) Conn() net.PacketConn { return l.conn }
77 var ErrOutOfPeerIDs = errors.New("out of peer ids")
82 accepted chan struct{} // close-only
85 func (l *Listener) processNetPkt(pkt netPkt) error {
89 addrstr := pkt.SrcAddr.String()
91 clt, ok := l.addr2peer[addrstr]
94 for l.id2peer[l.peerID].Peer != nil || l.peerID < PeerIDCltMin {
95 if l.peerID == prev-1 {
96 return ErrOutOfPeerIDs
101 pkts := make(chan netPkt, 256)
104 Peer: newPeer(l.conn, pkt.SrcAddr, l.peerID, PeerIDSrv),
106 accepted: make(chan struct{}),
109 l.addr2peer[addrstr] = clt
110 l.id2peer[clt.ID()] = clt
112 data := make([]byte, 1+1+2)
113 data[0] = uint8(rawTypeCtl)
114 data[1] = uint8(ctlSetPeerID)
115 be.PutUint16(data[2:4], uint16(clt.ID()))
116 if _, err := clt.sendRaw(rawPkt{Data: data}); err != nil {
117 if errors.Is(err, net.ErrClosed) {
120 return fmt.Errorf("can't set client peer id: %w", err)
129 clt.processNetPkts(pkts)
137 delete(l.addr2peer, addrstr)
138 delete(l.id2peer, clt.ID())
148 case clt.pkts <- pkt:
150 // It's OK to drop packets if the buffer is full
151 // because MT RUDP can cope with packet loss.