diff options
author | kali kaneko (leap communications) <kali@leap.se> | 2021-11-29 01:46:27 +0100 |
---|---|---|
committer | kali kaneko (leap communications) <kali@leap.se> | 2021-11-29 18:14:16 +0100 |
commit | 18f52af5be3a9a0c73811706108f790d65ee9c67 (patch) | |
tree | e13cbacb47d56919caa9c44a2b45dec1497a7860 /vendor/github.com/pion/turn/v2/server.go | |
parent | ebcef0d57b6ecb5a40c6579f6be07182dd3033ba (diff) |
[pkg] update vendor
Diffstat (limited to 'vendor/github.com/pion/turn/v2/server.go')
-rw-r--r-- | vendor/github.com/pion/turn/v2/server.go | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/vendor/github.com/pion/turn/v2/server.go b/vendor/github.com/pion/turn/v2/server.go new file mode 100644 index 0000000..c8deba8 --- /dev/null +++ b/vendor/github.com/pion/turn/v2/server.go @@ -0,0 +1,161 @@ +// Package turn contains the public API for pion/turn, a toolkit for building TURN clients and servers +package turn + +import ( + "fmt" + "net" + "sync" + "time" + + "github.com/pion/logging" + "github.com/pion/turn/v2/internal/allocation" + "github.com/pion/turn/v2/internal/proto" + "github.com/pion/turn/v2/internal/server" +) + +const ( + inboundMTU = 1500 +) + +// Server is an instance of the Pion TURN Server +type Server struct { + log logging.LeveledLogger + authHandler AuthHandler + realm string + channelBindTimeout time.Duration + nonces *sync.Map + + packetConnConfigs []PacketConnConfig + listenerConfigs []ListenerConfig +} + +// NewServer creates the Pion TURN server +func NewServer(config ServerConfig) (*Server, error) { + if err := config.validate(); err != nil { + return nil, err + } + + loggerFactory := config.LoggerFactory + if loggerFactory == nil { + loggerFactory = logging.NewDefaultLoggerFactory() + } + + s := &Server{ + log: loggerFactory.NewLogger("turn"), + authHandler: config.AuthHandler, + realm: config.Realm, + channelBindTimeout: config.ChannelBindTimeout, + packetConnConfigs: config.PacketConnConfigs, + listenerConfigs: config.ListenerConfigs, + nonces: &sync.Map{}, + } + + if s.channelBindTimeout == 0 { + s.channelBindTimeout = proto.DefaultLifetime + } + + for i := range s.packetConnConfigs { + go func(p PacketConnConfig) { + allocationManager, err := allocation.NewManager(allocation.ManagerConfig{ + AllocatePacketConn: p.RelayAddressGenerator.AllocatePacketConn, + AllocateConn: p.RelayAddressGenerator.AllocateConn, + LeveledLogger: s.log, + }) + if err != nil { + s.log.Errorf("exit read loop on error: %s", err.Error()) + return + } + defer func() { + if err := allocationManager.Close(); err != nil { + s.log.Errorf("Failed to close AllocationManager: %s", err.Error()) + } + }() + + s.readLoop(p.PacketConn, allocationManager) + }(s.packetConnConfigs[i]) + } + + for _, listener := range s.listenerConfigs { + go func(l ListenerConfig) { + allocationManager, err := allocation.NewManager(allocation.ManagerConfig{ + AllocatePacketConn: l.RelayAddressGenerator.AllocatePacketConn, + AllocateConn: l.RelayAddressGenerator.AllocateConn, + LeveledLogger: s.log, + }) + if err != nil { + s.log.Errorf("exit read loop on error: %s", err.Error()) + return + } + defer func() { + if err := allocationManager.Close(); err != nil { + s.log.Errorf("Failed to close AllocationManager: %s", err.Error()) + } + }() + + for { + conn, err := l.Listener.Accept() + if err != nil { + s.log.Debugf("exit accept loop on error: %s", err.Error()) + return + } + + go s.readLoop(NewSTUNConn(conn), allocationManager) + } + }(listener) + } + + return s, nil +} + +// Close stops the TURN Server. It cleans up any associated state and closes all connections it is managing +func (s *Server) Close() error { + var errors []error + + for _, p := range s.packetConnConfigs { + if err := p.PacketConn.Close(); err != nil { + errors = append(errors, err) + } + } + + for _, l := range s.listenerConfigs { + if err := l.Listener.Close(); err != nil { + errors = append(errors, err) + } + } + + if len(errors) == 0 { + return nil + } + + err := errFailedToClose + for _, e := range errors { + err = fmt.Errorf("%s; Close error (%v) ", err.Error(), e) //nolint:goerr113 + } + + return err +} + +func (s *Server) readLoop(p net.PacketConn, allocationManager *allocation.Manager) { + buf := make([]byte, inboundMTU) + for { + n, addr, err := p.ReadFrom(buf) + if err != nil { + s.log.Debugf("exit read loop on error: %s", err.Error()) + return + } + + if err := server.HandleRequest(server.Request{ + Conn: p, + SrcAddr: addr, + Buff: buf[:n], + Log: s.log, + AuthHandler: s.authHandler, + Realm: s.realm, + AllocationManager: allocationManager, + ChannelBindTimeout: s.channelBindTimeout, + Nonces: s.nonces, + }); err != nil { + s.log.Errorf("error when handling datagram: %v", err) + } + } +} |