func (c *Component) ListenUDP(address string) (*net.UDPConn, error) {
	udpAddr, err := net.ResolveUDPAddr("udp", address)
	if err != nil {
		return nil, err
	}
	return net.ListenUDP("udp", udpAddr)
}
ListenUDP starts a listener on a UDP address.
package component
import (
	"crypto/tls"
	"net"
	"go.thethings.network/lorawan-stack/v3/pkg/errors"
	"go.thethings.network/lorawan-stack/v3/pkg/log"
)
var (
	errListenEndpoint = errors.Define("listen_endpoint", "could not listen on `{endpoint}` address")
	errListener       = errors.Define("listener", "could not create `{protocol}` listener")
)
type Listener interface {
	TLS(opts ...TLSConfigOption) (net.Listener, error)
	TCP() (net.Listener, error)
	Addr() net.Addr
	Close() error
}
type listener struct {
	c *Component
	tcp     net.Listener
	tcpUsed bool
	tls     net.Listener
	tlsUsed bool
}
func (l *listener) Addr() net.Addr {
	return l.tcp.Addr()
}
func (l *listener) TLS(opts ...TLSConfigOption) (net.Listener, error) {
	if l.tcpUsed || l.tlsUsed {
		return nil, errors.New("listener already in use")
	}
	config, err := l.c.GetTLSServerConfig(l.c.Context(), opts...)
	if err != nil {
		return nil, err
	}
	l.tls = tls.NewListener(l.tcp, config)
	l.tlsUsed = true
	return l.tls, nil
}
func (l *listener) TCP() (net.Listener, error) {
	if l.tcpUsed || l.tlsUsed {
		return nil, errors.New("listener already in use")
	}
	l.tcpUsed = true
	return l.tcp, nil
}
func (l *listener) Close() error {
	if l.tlsUsed {
		return l.tls.Close()
	}
	return l.tcp.Close()
}
func (c *Component) ListenTCP(address string) (Listener, error) {
	c.tcpListenersMu.Lock()
	defer c.tcpListenersMu.Unlock()
	l, ok := c.tcpListeners[address]
	if !ok {
		c.logger.WithField("address", address).Debug("Creating listener")
		lis, err := net.Listen("tcp", address)
		if err != nil {
			return nil, err
		}
		l = &listener{
			c:   c,
			tcp: lis,
		}
		c.tcpListeners[address] = l
	}
	return l, nil
}