6
6
"fmt"
7
7
"io"
8
8
"net"
9
+ "strings"
9
10
"sync"
10
11
11
12
logging "github.com/ipfs/go-log/v2"
@@ -42,9 +43,15 @@ type UDPMux struct {
42
43
43
44
queue chan Candidate
44
45
45
- mx sync.Mutex
46
+ mx sync.Mutex
47
+ // ufragMap allows us to multiplex incoming STUN packets based on ufrag
46
48
ufragMap map [ufragConnKey ]* muxedConnection
47
- addrMap map [string ]* muxedConnection
49
+ // addrMap allows us to correctly direct incoming packets after the connection
50
+ // is established and ufrag isn't available on all packets
51
+ addrMap map [string ]* muxedConnection
52
+ // ufragAddrMap allows us to clean up all addresses from the addrMap once
53
+ // connection is closed
54
+ ufragAddrMap map [ufragConnKey ][]net.Addr
48
55
49
56
// the context controls the lifecycle of the mux
50
57
wg sync.WaitGroup
@@ -57,12 +64,13 @@ var _ ice.UDPMux = &UDPMux{}
57
64
func NewUDPMux (socket net.PacketConn ) * UDPMux {
58
65
ctx , cancel := context .WithCancel (context .Background ())
59
66
mux := & UDPMux {
60
- ctx : ctx ,
61
- cancel : cancel ,
62
- socket : socket ,
63
- ufragMap : make (map [ufragConnKey ]* muxedConnection ),
64
- addrMap : make (map [string ]* muxedConnection ),
65
- queue : make (chan Candidate , 32 ),
67
+ ctx : ctx ,
68
+ cancel : cancel ,
69
+ socket : socket ,
70
+ ufragMap : make (map [ufragConnKey ]* muxedConnection ),
71
+ addrMap : make (map [string ]* muxedConnection ),
72
+ ufragAddrMap : make (map [ufragConnKey ][]net.Addr ),
73
+ queue : make (chan Candidate , 32 ),
66
74
}
67
75
68
76
return mux
@@ -130,7 +138,11 @@ func (mux *UDPMux) readLoop() {
130
138
131
139
n , addr , err := mux .socket .ReadFrom (buf )
132
140
if err != nil {
133
- log .Errorf ("error reading from socket: %v" , err )
141
+ if strings .Contains (err .Error (), "use of closed network connection" ) {
142
+ log .Debugf ("readLoop exiting: socket %s closed" , mux .socket .LocalAddr ())
143
+ } else {
144
+ log .Errorf ("error reading from socket %s: %v" , mux .socket .LocalAddr (), err )
145
+ }
134
146
pool .Put (buf )
135
147
return
136
148
}
@@ -157,7 +169,7 @@ func (mux *UDPMux) processPacket(buf []byte, addr net.Addr) (processed bool) {
157
169
conn , ok := mux .addrMap [addr .String ()]
158
170
mux .mx .Unlock ()
159
171
if ok {
160
- if err := conn .Push (buf ); err != nil {
172
+ if err := conn .Push (buf , addr ); err != nil {
161
173
log .Debugf ("could not push packet: %v" , err )
162
174
return false
163
175
}
@@ -196,7 +208,7 @@ func (mux *UDPMux) processPacket(buf []byte, addr net.Addr) (processed bool) {
196
208
}
197
209
}
198
210
199
- if err := conn .Push (buf ); err != nil {
211
+ if err := conn .Push (buf , addr ); err != nil {
200
212
log .Debugf ("could not push packet: %v" , err )
201
213
return false
202
214
}
@@ -250,9 +262,12 @@ func (mux *UDPMux) RemoveConnByUfrag(ufrag string) {
250
262
251
263
for _ , isIPv6 := range [... ]bool {true , false } {
252
264
key := ufragConnKey {ufrag : ufrag , isIPv6 : isIPv6 }
253
- if conn , ok := mux .ufragMap [key ]; ok {
265
+ if _ , ok := mux .ufragMap [key ]; ok {
254
266
delete (mux .ufragMap , key )
255
- delete (mux .addrMap , conn .RemoteAddr ().String ())
267
+ for _ , addr := range mux .ufragAddrMap [key ] {
268
+ delete (mux .addrMap , addr .String ())
269
+ }
270
+ delete (mux .ufragAddrMap , key )
256
271
}
257
272
}
258
273
}
@@ -264,12 +279,14 @@ func (mux *UDPMux) getOrCreateConn(ufrag string, isIPv6 bool, _ *UDPMux, addr ne
264
279
defer mux .mx .Unlock ()
265
280
266
281
if conn , ok := mux .ufragMap [key ]; ok {
282
+ mux .addrMap [addr .String ()] = conn
283
+ mux .ufragAddrMap [key ] = append (mux .ufragAddrMap [key ], addr )
267
284
return false , conn
268
285
}
269
286
270
- conn := newMuxedConnection (mux , func () { mux .RemoveConnByUfrag (ufrag ) }, addr )
287
+ conn := newMuxedConnection (mux , func () { mux .RemoveConnByUfrag (ufrag ) })
271
288
mux .ufragMap [key ] = conn
272
289
mux .addrMap [addr .String ()] = conn
273
-
290
+ mux . ufragAddrMap [ key ] = append ( mux . ufragAddrMap [ key ], addr )
274
291
return true , conn
275
292
}
0 commit comments