code: func (t *NetTransport) udpListen(udpLn *net.UDPConn) {
  	defer t.wg.Done()
  	for {
  		// Do a blocking read into a fresh buffer. Grab a time stamp as
  		// close as possible to the I/O.
  		buf := make([]byte, udpPacketBufSize)
  		n, addr, err := udpLn.ReadFrom(buf)
  		ts := time.Now()
  		if err != nil {
  			if s := atomic.LoadInt32(&t.shutdown); s == 1 {
  				break
  			}
  
  			t.logger.Printf("[ERR] memberlist: Error reading UDP packet: %v", err)
  			continue
  		}
  
  		// Check the length - it needs to have at least one byte to be a
  		// proper message.
  		if n < 1 {
  			t.logger.Printf("[ERR] memberlist: UDP packet too short (%d bytes) %s",
  				len(buf), LogAddress(addr))
  			continue
  		}
  
  		// Ingest the packet.
  		metrics.IncrCounter([]string{"memberlist", "udp", "received"}, float32(n))
  		t.packetCh <- &Packet{
  			Buf:       buf[:n],
  			From:      addr,
  			Timestamp: ts,
  		}
  	}
  }
docs: // udpListen is a long running goroutine that accepts incoming UDP packets and
  // hands them off to the packet channel.