@@ -248,6 +248,81 @@ func WrapNetListener(nl net.Listener) (Listener, error) {
248
248
}, nil
249
249
}
250
250
251
+ // A PacketConn is a generic packet oriented network connection which uses an
252
+ // underlying net.PacketConn, wrapped with the locally bound Multiaddr.
253
+ type PacketConn interface {
254
+ Connection () net.PacketConn
255
+
256
+ Multiaddr () ma.Multiaddr
257
+
258
+ ReadFrom (b []byte ) (int , ma.Multiaddr , error )
259
+ WriteTo (b []byte , maddr ma.Multiaddr ) (int , error )
260
+
261
+ Close () error
262
+ }
263
+
264
+ // maPacketConn implements PacketConn
265
+ type maPacketConn struct {
266
+ net.PacketConn
267
+ laddr ma.Multiaddr
268
+ }
269
+
270
+ // Connection returns the embedded net.PacketConn.
271
+ func (l * maPacketConn ) Connection () net.PacketConn {
272
+ return l .PacketConn
273
+ }
274
+
275
+ // Multiaddr returns the bound local Multiaddr.
276
+ func (l * maPacketConn ) Multiaddr () ma.Multiaddr {
277
+ return l .laddr
278
+ }
279
+
280
+ func (l * maPacketConn ) ReadFrom (b []byte ) (int , ma.Multiaddr , error ) {
281
+ n , addr , err := l .PacketConn .ReadFrom (b )
282
+ maddr , _ := FromNetAddr (addr )
283
+ return n , maddr , err
284
+ }
285
+
286
+ func (l * maPacketConn ) WriteTo (b []byte , maddr ma.Multiaddr ) (int , error ) {
287
+ addr , err := ToNetAddr (maddr )
288
+ if err != nil {
289
+ return 0 , err
290
+ }
291
+ return l .PacketConn .WriteTo (b , addr )
292
+ }
293
+
294
+ // ListenPacket announces on the local network address laddr.
295
+ // The Multiaddr must be a packet driven network, like udp4 or udp6.
296
+ // See Dial for the syntax of laddr.
297
+ func ListenPacket (laddr ma.Multiaddr ) (PacketConn , error ) {
298
+ lnet , lnaddr , err := DialArgs (laddr )
299
+ if err != nil {
300
+ return nil , err
301
+ }
302
+
303
+ pc , err := net .ListenPacket (lnet , lnaddr )
304
+ if err != nil {
305
+ return nil , err
306
+ }
307
+
308
+ // We want to fetch the new multiaddr from the listener, as it may
309
+ // have resolved to some other value. WrapPacketConn does this.
310
+ return WrapPacketConn (pc )
311
+ }
312
+
313
+ // WrapPacketConn wraps a net.PacketConn with a manet.PacketConn.
314
+ func WrapPacketConn (pc net.PacketConn ) (PacketConn , error ) {
315
+ laddr , err := FromNetAddr (pc .LocalAddr ())
316
+ if err != nil {
317
+ return nil , err
318
+ }
319
+
320
+ return & maPacketConn {
321
+ PacketConn : pc ,
322
+ laddr : laddr ,
323
+ }, nil
324
+ }
325
+
251
326
// InterfaceMultiaddrs will return the addresses matching net.InterfaceAddrs
252
327
func InterfaceMultiaddrs () ([]ma.Multiaddr , error ) {
253
328
addrs , err := net .InterfaceAddrs ()
0 commit comments