github.com/pion/dtls/v2@v2.2.12/listener.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
     2  // SPDX-License-Identifier: MIT
     3  
     4  package dtls
     5  
     6  import (
     7  	"net"
     8  
     9  	"github.com/pion/dtls/v2/pkg/protocol"
    10  	"github.com/pion/dtls/v2/pkg/protocol/recordlayer"
    11  	"github.com/pion/transport/v2/udp"
    12  )
    13  
    14  // Listen creates a DTLS listener
    15  func Listen(network string, laddr *net.UDPAddr, config *Config) (net.Listener, error) {
    16  	if err := validateConfig(config); err != nil {
    17  		return nil, err
    18  	}
    19  
    20  	lc := udp.ListenConfig{
    21  		AcceptFilter: func(packet []byte) bool {
    22  			pkts, err := recordlayer.UnpackDatagram(packet)
    23  			if err != nil || len(pkts) < 1 {
    24  				return false
    25  			}
    26  			h := &recordlayer.Header{}
    27  			if err := h.Unmarshal(pkts[0]); err != nil {
    28  				return false
    29  			}
    30  			return h.ContentType == protocol.ContentTypeHandshake
    31  		},
    32  	}
    33  	parent, err := lc.Listen(network, laddr)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  	return &listener{
    38  		config: config,
    39  		parent: parent,
    40  	}, nil
    41  }
    42  
    43  // NewListener creates a DTLS listener which accepts connections from an inner Listener.
    44  func NewListener(inner net.Listener, config *Config) (net.Listener, error) {
    45  	if err := validateConfig(config); err != nil {
    46  		return nil, err
    47  	}
    48  
    49  	return &listener{
    50  		config: config,
    51  		parent: inner,
    52  	}, nil
    53  }
    54  
    55  // listener represents a DTLS listener
    56  type listener struct {
    57  	config *Config
    58  	parent net.Listener
    59  }
    60  
    61  // Accept waits for and returns the next connection to the listener.
    62  // You have to either close or read on all connection that are created.
    63  // Connection handshake will timeout using ConnectContextMaker in the Config.
    64  // If you want to specify the timeout duration, set ConnectContextMaker.
    65  func (l *listener) Accept() (net.Conn, error) {
    66  	c, err := l.parent.Accept()
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	return Server(c, l.config)
    71  }
    72  
    73  // Close closes the listener.
    74  // Any blocked Accept operations will be unblocked and return errors.
    75  // Already Accepted connections are not closed.
    76  func (l *listener) Close() error {
    77  	return l.parent.Close()
    78  }
    79  
    80  // Addr returns the listener's network address.
    81  func (l *listener) Addr() net.Addr {
    82  	return l.parent.Addr()
    83  }