@@ -248,6 +248,81 @@ func WrapNetListener(nl net.Listener) (Listener, error) {
248248 }, nil
249249}
250250
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+
251326// InterfaceMultiaddrs will return the addresses matching net.InterfaceAddrs
252327func InterfaceMultiaddrs () ([]ma.Multiaddr , error ) {
253328 addrs , err := net .InterfaceAddrs ()
0 commit comments