From 97222d69b309222560a10cae1dac43ebf39af98b Mon Sep 17 00:00:00 2001 From: Daniel Adam Date: Thu, 1 Aug 2024 09:38:17 +0200 Subject: [PATCH] Upgrade to github.com/pion/dtls/v3 --- .golangci.yml | 3 - dtls/client.go | 4 +- dtls/client_test.go | 124 +++++++++--------------- dtls/example_test.go | 2 +- dtls/server/server.go | 31 +++--- dtls/server_test.go | 19 ++-- examples/dtls/cid/client/main.go | 2 +- examples/dtls/cid/server/main.go | 2 +- examples/dtls/pki/client/main.go | 2 +- examples/dtls/pki/server/main.go | 11 +-- examples/dtls/psk/client/main.go | 2 +- examples/dtls/psk/server/main.go | 2 +- examples/options/server/main.go | 2 +- go.mod | 10 +- go.sum | 64 ++----------- net/dtlslistener.go | 158 +++---------------------------- net/options.go | 21 ---- net/tlslistener_test.go | 9 +- server.go | 2 +- tcp/server/server.go | 2 +- 20 files changed, 111 insertions(+), 361 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 6c6b4dc1..f7b6a08c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -5,9 +5,6 @@ linters-settings: enable: - nilness - shadow - gomoddirectives: - replace-allow-list: - - github.com/pion/dtls/v2 linters: enable: diff --git a/dtls/client.go b/dtls/client.go index 96ac267d..99439df2 100644 --- a/dtls/client.go +++ b/dtls/client.go @@ -4,8 +4,8 @@ import ( "fmt" "time" - "github.com/pion/dtls/v2" - dtlsnet "github.com/pion/dtls/v2/pkg/net" + "github.com/pion/dtls/v3" + dtlsnet "github.com/pion/dtls/v3/pkg/net" "github.com/plgd-dev/go-coap/v3/dtls/server" "github.com/plgd-dev/go-coap/v3/message" "github.com/plgd-dev/go-coap/v3/message/codes" diff --git a/dtls/client_test.go b/dtls/client_test.go index 60526191..b437e371 100644 --- a/dtls/client_test.go +++ b/dtls/client_test.go @@ -11,7 +11,7 @@ import ( "testing" "time" - piondtls "github.com/pion/dtls/v2" + piondtls "github.com/pion/dtls/v3" "github.com/plgd-dev/go-coap/v3/dtls" "github.com/plgd-dev/go-coap/v3/message" "github.com/plgd-dev/go-coap/v3/message/codes" @@ -20,9 +20,9 @@ import ( coapNet "github.com/plgd-dev/go-coap/v3/net" "github.com/plgd-dev/go-coap/v3/net/responsewriter" "github.com/plgd-dev/go-coap/v3/options" - "github.com/plgd-dev/go-coap/v3/options/config" "github.com/plgd-dev/go-coap/v3/pkg/runner/periodic" "github.com/plgd-dev/go-coap/v3/udp/client" + udpClient "github.com/plgd-dev/go-coap/v3/udp/client" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/atomic" @@ -123,7 +123,7 @@ func TestConnGet(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*3600) + ctx, cancel := context.WithTimeout(context.Background(), Timeout) defer cancel() got, err := cc.Get(ctx, tt.args.path, tt.args.opts...) if tt.wantErr { @@ -216,7 +216,7 @@ func TestConnGetSeparateMessage(t *testing.T) { require.NoError(t, errC) }() - ctx, cancel := context.WithTimeout(context.Background(), time.Second*3600) + ctx, cancel := context.WithTimeout(context.Background(), Timeout) defer cancel() req, err := cc.NewGetRequest(ctx, "/a") @@ -340,7 +340,7 @@ func TestConnPost(t *testing.T) { require.NoError(t, errC) }() - ctx, cancel := context.WithTimeout(context.Background(), time.Second*3600) + ctx, cancel := context.WithTimeout(context.Background(), Timeout) defer cancel() got, err := cc.Post(ctx, tt.args.path, tt.args.contentFormat, tt.args.payload, tt.args.opts...) if tt.wantErr { @@ -475,7 +475,7 @@ func TestConnPut(t *testing.T) { require.NoError(t, errC) }() - ctx, cancel := context.WithTimeout(context.Background(), time.Second*3600) + ctx, cancel := context.WithTimeout(context.Background(), Timeout) defer cancel() got, err := cc.Put(ctx, tt.args.path, tt.args.contentFormat, tt.args.payload, tt.args.opts...) if tt.wantErr { @@ -590,7 +590,7 @@ func TestConnDelete(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*3600) + ctx, cancel := context.WithTimeout(context.Background(), Timeout) defer cancel() got, err := cc.Delete(ctx, tt.args.path, tt.args.opts...) if tt.wantErr { @@ -654,58 +654,12 @@ func TestConnPing(t *testing.T) { require.NoError(t, err) } -func TestConnHandeShakeFailure(t *testing.T) { - dtlsCfg := &piondtls.Config{ - PSK: func(hint []byte) ([]byte, error) { - fmt.Printf("Hint: %s \n", hint) - return []byte{0xAB, 0xC1, 0x23}, nil - }, - PSKIdentityHint: []byte("Pion DTLS Server"), - CipherSuites: []piondtls.CipherSuiteID{piondtls.TLS_PSK_WITH_AES_128_CCM_8}, - ConnectContextMaker: func() (context.Context, func()) { - return context.WithTimeout(context.Background(), 1*time.Second) - }, - } - l, err := coapNet.NewDTLSListener("udp", "", dtlsCfg) - require.NoError(t, err) - defer func() { - errC := l.Close() - require.NoError(t, errC) - }() - var wg sync.WaitGroup - defer wg.Wait() - - s := dtls.NewServer() - defer s.Stop() - - wg.Add(1) - go func() { - defer wg.Done() - errS := s.Serve(l) - assert.NoError(t, errS) - }() - - dtlsCfgClient := &piondtls.Config{ - PSK: func(hint []byte) ([]byte, error) { - fmt.Printf("Hint: %s \n", hint) - return []byte{0xAB, 0xC1, 0x24}, nil - }, - PSKIdentityHint: []byte("Pion DTLS Client"), - CipherSuites: []piondtls.CipherSuiteID{piondtls.TLS_PSK_WITH_AES_128_CCM_8}, - ConnectContextMaker: func() (context.Context, func()) { - return context.WithTimeout(context.Background(), 1*time.Second) - }, - } - _, err = dtls.Dial(l.Addr().String(), dtlsCfgClient) - require.Error(t, err) -} - func TestClientInactiveMonitor(t *testing.T) { var inactivityDetected atomic.Bool ctx, cancel := context.WithTimeout(context.Background(), Timeout) defer cancel() - serverCgf, clientCgf, _, err := createDTLSConfig(ctx) + serverCgf, clientCgf, _, err := createDTLSConfig() require.NoError(t, err) ld, err := coapNet.NewDTLSListener("udp4", "", serverCgf) @@ -745,7 +699,9 @@ func TestClientInactiveMonitor(t *testing.T) { serverWg.Wait() }() - cc, err := dtls.Dial(ld.Addr().String(), clientCgf, + cc, err := dtls.Dial( + ld.Addr().String(), + clientCgf, options.WithInactivityMonitor(100*time.Millisecond, func(cc *client.Conn) { require.False(t, inactivityDetected.Load()) inactivityDetected.Store(true) @@ -774,65 +730,73 @@ func TestClientInactiveMonitor(t *testing.T) { func TestClientKeepAliveMonitor(t *testing.T) { var inactivityDetected atomic.Bool - ctx, cancel := context.WithTimeout(context.Background(), Timeout) - defer cancel() - serverCgf, clientCgf, _, err := createDTLSConfig(ctx) + serverCgf, clientCgf, _, err := createDTLSConfig() require.NoError(t, err) - ld, err := coapNet.NewDTLSListener("udp4", "", serverCgf) require.NoError(t, err) + defer func() { + errC := ld.Close() + require.NoError(t, errC) + }() - checkClose := semaphore.NewWeighted(1) - err = checkClose.Acquire(ctx, 1) + ctx, cancel := context.WithTimeout(context.Background(), Timeout) + defer cancel() + + checkClose := semaphore.NewWeighted(2) + err = checkClose.Acquire(ctx, 2) require.NoError(t, err) + sd := dtls.NewServer( + options.WithOnNewConn(func(cc *client.Conn) { + t.Log("server - new connection") + cc.AddOnClose(func() { + t.Log("server - client is closed") + checkClose.Release(1) + }) + }), + options.WithPeriodicRunner(periodic.New(ctx.Done(), time.Millisecond*10)), + options.WithRequestMonitor(func(_ *udpClient.Conn, req *pool.Message) (bool, error) { + t.Logf("server - received message: %+v\n", req) + // lets drop all messages, this will trigger keep alive because of inactivity + return true, nil + }), + ) var serverWg sync.WaitGroup serverWg.Add(1) go func() { defer serverWg.Done() - for { - c, errA := ld.AcceptWithContext(ctx) - if errA != nil { - if errors.Is(errA, coapNet.ErrListenerIsClosed) { - return - } - } - defer c.Close() - assert.NoError(t, errA) - } + errS := sd.Serve(ld) + assert.NoError(t, errS) }() defer func() { - errC := ld.Close() - require.NoError(t, errC) + sd.Stop() + serverWg.Wait() }() cc, err := dtls.Dial( ld.Addr().String(), clientCgf, options.WithKeepAlive(3, 100*time.Millisecond, func(cc *client.Conn) { + t.Log("client - close for inactivity") require.False(t, inactivityDetected.Load()) inactivityDetected.Store(true) errC := cc.Close() require.NoError(t, errC) }), options.WithPeriodicRunner(periodic.New(ctx.Done(), time.Millisecond*10)), - options.WithReceivedMessageQueueSize(32), - options.WithProcessReceivedMessageFunc(func(req *pool.Message, cc *client.Conn, handler config.HandlerFunc[*client.Conn]) { - cc.ProcessReceivedMessageWithHandler(req, handler) - }), ) require.NoError(t, err) cc.AddOnClose(func() { + t.Log("connection is closed") checkClose.Release(1) }) // send ping to create server side connection ctxPing, cancel := context.WithTimeout(ctx, time.Second) defer cancel() - err = cc.Ping(ctxPing) - require.Error(t, err) + _ = cc.Ping(ctxPing) - err = checkClose.Acquire(ctx, 1) + err = checkClose.Acquire(ctx, 2) require.NoError(t, err) require.True(t, inactivityDetected.Load()) } diff --git a/dtls/example_test.go b/dtls/example_test.go index c41a9601..92d10d2d 100644 --- a/dtls/example_test.go +++ b/dtls/example_test.go @@ -7,7 +7,7 @@ import ( "log" "time" - piondtls "github.com/pion/dtls/v2" + piondtls "github.com/pion/dtls/v3" "github.com/plgd-dev/go-coap/v3/dtls" "github.com/plgd-dev/go-coap/v3/net" ) diff --git a/dtls/server/server.go b/dtls/server/server.go index 1f879a67..88211b08 100644 --- a/dtls/server/server.go +++ b/dtls/server/server.go @@ -95,6 +95,14 @@ func (s *Server) checkAndSetListener(l Listener) error { return nil } +func (s *Server) popListener() Listener { + s.listenMutex.Lock() + defer s.listenMutex.Unlock() + l := s.listen + s.listen = nil + return l +} + func (s *Server) checkAcceptError(err error) bool { if err == nil { return true @@ -134,11 +142,8 @@ func (s *Server) Serve(l Listener) error { return err } defer func() { - s.listenMutex.Lock() - defer s.listenMutex.Unlock() - s.listen = nil + s.Stop() }() - var wg sync.WaitGroup defer wg.Wait() @@ -158,11 +163,9 @@ func (s *Server) Serve(l Listener) error { continue } wg.Add(1) - var cc *udpClient.Conn inactivityMonitor := s.cfg.CreateInactivityMonitor() requestMonitor := s.cfg.RequestMonitor - - cc = s.createConn(coapNet.NewConn(rw), inactivityMonitor, requestMonitor) + cc := s.createConn(coapNet.NewConn(rw), inactivityMonitor, requestMonitor) if s.cfg.OnNewConn != nil { s.cfg.OnNewConn(cc) } @@ -176,14 +179,12 @@ func (s *Server) Serve(l Listener) error { // Stop stops server without wait of ends Serve function. func (s *Server) Stop() { s.cancel() - s.listenMutex.Lock() - l := s.listen - s.listen = nil - s.listenMutex.Unlock() - if l != nil { - if err := l.Close(); err != nil { - s.cfg.Errors(fmt.Errorf("cannot close listener: %w", err)) - } + l := s.popListener() + if l == nil { + return + } + if err := l.Close(); err != nil { + s.cfg.Errors(fmt.Errorf("cannot close listener: %w", err)) } } diff --git a/dtls/server_test.go b/dtls/server_test.go index cde36991..d6d3df19 100644 --- a/dtls/server_test.go +++ b/dtls/server_test.go @@ -12,7 +12,7 @@ import ( "testing" "time" - piondtls "github.com/pion/dtls/v2" + piondtls "github.com/pion/dtls/v3" "github.com/plgd-dev/go-coap/v3/dtls" "github.com/plgd-dev/go-coap/v3/examples/dtls/pki" "github.com/plgd-dev/go-coap/v3/message" @@ -85,7 +85,7 @@ func TestServerCleanUpConns(t *testing.T) { <-cc.Done() } -func createDTLSConfig(ctx context.Context) (serverConfig *piondtls.Config, clientConfig *piondtls.Config, clientSerial *big.Int, err error) { +func createDTLSConfig() (serverConfig *piondtls.Config, clientConfig *piondtls.Config, clientSerial *big.Int, err error) { // root cert ca, rootBytes, _, caPriv, err := pki.GenerateCA() if err != nil { @@ -111,9 +111,6 @@ func createDTLSConfig(ctx context.Context) (serverConfig *piondtls.Config, clien ExtendedMasterSecret: piondtls.RequireExtendedMasterSecret, ClientCAs: certPool, ClientAuth: piondtls.RequireAndVerifyClientCert, - ConnectContextMaker: func() (context.Context, func()) { - return context.WithTimeout(ctx, 30*time.Second) - }, } // client cert @@ -142,9 +139,9 @@ func createDTLSConfig(ctx context.Context) (serverConfig *piondtls.Config, clien } func TestServerSetContextValueWithPKI(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*3600) + ctx, cancel := context.WithTimeout(context.Background(), Timeout) defer cancel() - serverCgf, clientCgf, clientSerial, err := createDTLSConfig(ctx) + serverCgf, clientCgf, clientSerial, err := createDTLSConfig() require.NoError(t, err) ld, err := coapNet.NewDTLSListener("udp4", "", serverCgf) @@ -191,9 +188,9 @@ func TestServerSetContextValueWithPKI(t *testing.T) { func TestServerInactiveMonitor(t *testing.T) { var inactivityDetected atomic.Bool - ctx, cancel := context.WithTimeout(context.Background(), time.Second*8) + ctx, cancel := context.WithTimeout(context.Background(), Timeout) defer cancel() - serverCgf, clientCgf, _, err := createDTLSConfig(ctx) + serverCgf, clientCgf, _, err := createDTLSConfig() require.NoError(t, err) ld, err := coapNet.NewDTLSListener("udp4", "", serverCgf) @@ -266,9 +263,9 @@ func TestServerInactiveMonitor(t *testing.T) { func TestServerKeepAliveMonitor(t *testing.T) { var inactivityDetected atomic.Bool - ctx, cancel := context.WithTimeout(context.Background(), time.Second*8) + ctx, cancel := context.WithTimeout(context.Background(), Timeout) defer cancel() - serverCgf, clientCgf, _, err := createDTLSConfig(ctx) + serverCgf, clientCgf, _, err := createDTLSConfig() require.NoError(t, err) ld, err := coapNet.NewDTLSListener("udp4", "", serverCgf) diff --git a/examples/dtls/cid/client/main.go b/examples/dtls/cid/client/main.go index 8e71c47a..8abafc4a 100644 --- a/examples/dtls/cid/client/main.go +++ b/examples/dtls/cid/client/main.go @@ -6,7 +6,7 @@ import ( "log" "net" - piondtls "github.com/pion/dtls/v2" + piondtls "github.com/pion/dtls/v3" "github.com/plgd-dev/go-coap/v3/dtls" ) diff --git a/examples/dtls/cid/server/main.go b/examples/dtls/cid/server/main.go index a5564bf1..dac59e3c 100644 --- a/examples/dtls/cid/server/main.go +++ b/examples/dtls/cid/server/main.go @@ -8,7 +8,7 @@ import ( "net" "time" - piondtls "github.com/pion/dtls/v2" + piondtls "github.com/pion/dtls/v3" "github.com/plgd-dev/go-coap/v3/dtls/server" "github.com/plgd-dev/go-coap/v3/message" "github.com/plgd-dev/go-coap/v3/message/codes" diff --git a/examples/dtls/pki/client/main.go b/examples/dtls/pki/client/main.go index c69fd0e6..5f2d8d94 100644 --- a/examples/dtls/pki/client/main.go +++ b/examples/dtls/pki/client/main.go @@ -7,7 +7,7 @@ import ( "os" "time" - piondtls "github.com/pion/dtls/v2" + piondtls "github.com/pion/dtls/v3" "github.com/plgd-dev/go-coap/v3/dtls" "github.com/plgd-dev/go-coap/v3/examples/dtls/pki" ) diff --git a/examples/dtls/pki/server/main.go b/examples/dtls/pki/server/main.go index b45427f2..3395382d 100644 --- a/examples/dtls/pki/server/main.go +++ b/examples/dtls/pki/server/main.go @@ -2,15 +2,13 @@ package main import ( "bytes" - "context" "crypto/tls" "crypto/x509" "fmt" "log" "math/big" - "time" - piondtls "github.com/pion/dtls/v2" + piondtls "github.com/pion/dtls/v3" "github.com/plgd-dev/go-coap/v3/dtls" "github.com/plgd-dev/go-coap/v3/examples/dtls/pki" "github.com/plgd-dev/go-coap/v3/message" @@ -57,7 +55,7 @@ func main() { m := mux.NewRouter() m.Handle("/a", mux.HandlerFunc(handleA)) - config, err := createServerConfig(context.Background()) + config, err := createServerConfig() if err != nil { log.Fatalln(err) return @@ -76,7 +74,7 @@ func listenAndServeDTLS(network string, addr string, config *piondtls.Config, ha return s.Serve(l) } -func createServerConfig(ctx context.Context) (*piondtls.Config, error) { +func createServerConfig() (*piondtls.Config, error) { // root cert ca, rootBytes, _, caPriv, err := pki.GenerateCA() if err != nil { @@ -102,8 +100,5 @@ func createServerConfig(ctx context.Context) (*piondtls.Config, error) { ExtendedMasterSecret: piondtls.RequireExtendedMasterSecret, ClientCAs: certPool, ClientAuth: piondtls.RequireAndVerifyClientCert, - ConnectContextMaker: func() (context.Context, func()) { - return context.WithTimeout(ctx, 30*time.Second) - }, }, nil } diff --git a/examples/dtls/psk/client/main.go b/examples/dtls/psk/client/main.go index 51cde6d9..a692e76e 100644 --- a/examples/dtls/psk/client/main.go +++ b/examples/dtls/psk/client/main.go @@ -7,7 +7,7 @@ import ( "os" "time" - piondtls "github.com/pion/dtls/v2" + piondtls "github.com/pion/dtls/v3" "github.com/plgd-dev/go-coap/v3/dtls" ) diff --git a/examples/dtls/psk/server/main.go b/examples/dtls/psk/server/main.go index aafd2b18..4c91f8a9 100644 --- a/examples/dtls/psk/server/main.go +++ b/examples/dtls/psk/server/main.go @@ -5,7 +5,7 @@ import ( "fmt" "log" - piondtls "github.com/pion/dtls/v2" + piondtls "github.com/pion/dtls/v3" coap "github.com/plgd-dev/go-coap/v3" "github.com/plgd-dev/go-coap/v3/message" "github.com/plgd-dev/go-coap/v3/message/codes" diff --git a/examples/options/server/main.go b/examples/options/server/main.go index 451e5104..f01bcb37 100644 --- a/examples/options/server/main.go +++ b/examples/options/server/main.go @@ -7,7 +7,7 @@ import ( "fmt" "log" - piondtls "github.com/pion/dtls/v2" + piondtls "github.com/pion/dtls/v3" coap "github.com/plgd-dev/go-coap/v3" "github.com/plgd-dev/go-coap/v3/message" "github.com/plgd-dev/go-coap/v3/message/codes" diff --git a/go.mod b/go.mod index 25a11900..445a94ac 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,7 @@ go 1.20 require ( github.com/dsnet/golib/memfile v1.0.0 - github.com/pion/dtls/v2 v2.2.8-0.20240701035148-45e16a098c47 - github.com/pion/transport/v3 v3.0.2 + github.com/pion/dtls/v3 v3.0.0 github.com/stretchr/testify v1.9.0 go.uber.org/atomic v1.11.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 @@ -16,12 +15,9 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pion/logging v0.2.2 // indirect + github.com/pion/transport/v3 v3.0.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/crypto v0.24.0 // indirect - golang.org/x/sys v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) - -// note: github.com/pion/dtls/v2/pkg/net package is not yet available in release branches, -// so we force to the use of the pinned master branch -replace github.com/pion/dtls/v2 => github.com/pion/dtls/v2 v2.2.8-0.20240701035148-45e16a098c47 diff --git a/go.sum b/go.sum index 04c81f77..3a88f318 100644 --- a/go.sum +++ b/go.sum @@ -1,82 +1,30 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dsnet/golib/memfile v1.0.0 h1:J9pUspY2bDCbF9o+YGwcf3uG6MdyITfh/Fk3/CaEiFs= github.com/dsnet/golib/memfile v1.0.0/go.mod h1:tXGNW9q3RwvWt1VV2qrRKlSSz0npnh12yftCSCy2T64= -github.com/pion/dtls/v2 v2.2.8-0.20240701035148-45e16a098c47 h1:WCUn5hJZLLMoOvedDEDA/OFzaYbZy7G71mQ9h5GiQ/o= -github.com/pion/dtls/v2 v2.2.8-0.20240701035148-45e16a098c47/go.mod h1:8eXNLDNOiXaHvo/wOFnFcr/yinEimCDUQ512tlOSvPo= +github.com/pion/dtls/v3 v3.0.0 h1:m2hzwPkzqoBjVKXm5ymNuX01OAjht82TdFL6LoTzgi4= +github.com/pion/dtls/v3 v3.0.0/go.mod h1:tiX7NaneB0wNoRaUpaMVP7igAlkMCTQkbpiY+OfeIi0= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4= -github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0= +github.com/pion/transport/v3 v3.0.5 h1:ofVrcbPNqVPuKaTO5AMFnFuJ1ZX7ElYiWzC5PCf9YVQ= +github.com/pion/transport/v3 v3.0.5/go.mod h1:HvJr2N/JwNJAfipsRleqwFoR3t/pWyHeZUs89v3+t5s= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/net/dtlslistener.go b/net/dtlslistener.go index 4a7379b6..d0d23397 100644 --- a/net/dtlslistener.go +++ b/net/dtlslistener.go @@ -2,145 +2,35 @@ package net import ( "context" - "errors" "fmt" "net" - "sync" - "time" - dtls "github.com/pion/dtls/v2" - dtlsnet "github.com/pion/dtls/v2/pkg/net" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" - "github.com/pion/transport/v3/udp" + dtls "github.com/pion/dtls/v3" "go.uber.org/atomic" ) -type GoPoolFunc = func(f func()) error - -var DefaultDTLSListenerConfig = DTLSListenerConfig{ - GoPool: func(f func()) error { - go f() - return nil - }, -} - -type DTLSListenerConfig struct { - GoPool GoPoolFunc -} - -type acceptedConn struct { - conn net.Conn - err error -} - // DTLSListener is a DTLS listener that provides accept with context. type DTLSListener struct { - listener net.Listener - config *dtls.Config - closed atomic.Bool - goPool GoPoolFunc - acceptedConnChan chan acceptedConn - wg sync.WaitGroup - done chan struct{} -} - -func tlsPacketFilter(packet []byte) bool { - pkts, err := recordlayer.UnpackDatagram(packet) - if err != nil || len(pkts) < 1 { - return false - } - h := &recordlayer.Header{} - if err := h.Unmarshal(pkts[0]); err != nil { - return false - } - return h.ContentType == protocol.ContentTypeHandshake + listener net.Listener + config *dtls.Config + closed atomic.Bool } // NewDTLSListener creates dtls listener. // Known networks are "udp", "udp4" (IPv4-only), "udp6" (IPv6-only). -func NewDTLSListener(network string, addr string, dtlsCfg *dtls.Config, opts ...DTLSListenerOption) (*DTLSListener, error) { +func NewDTLSListener(network string, addr string, dtlsCfg *dtls.Config) (*DTLSListener, error) { a, err := net.ResolveUDPAddr(network, addr) if err != nil { return nil, fmt.Errorf("cannot resolve address: %w", err) } - cfg := DefaultDTLSListenerConfig - for _, o := range opts { - o.ApplyDTLS(&cfg) - } - - if cfg.GoPool == nil { - return nil, errors.New("empty go pool") - } - - l := DTLSListener{ - goPool: cfg.GoPool, - config: dtlsCfg, - acceptedConnChan: make(chan acceptedConn, 256), - done: make(chan struct{}), - } - connectContextMaker := dtlsCfg.ConnectContextMaker - if connectContextMaker == nil { - connectContextMaker = func() (context.Context, func()) { - return context.WithTimeout(context.Background(), 30*time.Second) - } - } - dtlsCfg.ConnectContextMaker = func() (context.Context, func()) { - ctx, cancel := connectContextMaker() - if l.closed.Load() { - cancel() - } - return ctx, cancel - } - - lc := udp.ListenConfig{ - AcceptFilter: tlsPacketFilter, - } - l.listener, err = lc.Listen(network, a) - if err != nil { - return nil, err - } - l.wg.Add(1) - go l.run() - return &l, nil -} - -func (l *DTLSListener) send(conn net.Conn, err error) { - select { - case <-l.done: - case l.acceptedConnChan <- acceptedConn{ - conn: conn, - err: err, - }: - } -} - -func (l *DTLSListener) accept() error { - c, err := l.listener.Accept() + dtls, err := dtls.Listen(network, a, dtlsCfg) if err != nil { - l.send(nil, err) - return err - } - err = l.goPool(func() { - l.send(dtls.Server(dtlsnet.PacketConnFromConn(c), c.RemoteAddr(), l.config)) - }) - if err != nil { - _ = c.Close() - } - return err -} - -func (l *DTLSListener) run() { - defer l.wg.Done() - for { - if l.closed.Load() { - return - } - err := l.accept() - if errors.Is(err, udp.ErrClosedListener) { - return - } + return nil, fmt.Errorf("cannot create new net tcp listener: %w", err) } + return &DTLSListener{ + listener: dtls, + config: dtlsCfg, + }, nil } // AcceptWithContext waits with context for a generic Conn. @@ -153,27 +43,11 @@ func (l *DTLSListener) AcceptWithContext(ctx context.Context) (net.Conn, error) if l.closed.Load() { return nil, ErrListenerIsClosed } - for { - select { - case <-ctx.Done(): - return nil, ctx.Err() - case <-l.done: - return nil, ErrListenerIsClosed - case d := <-l.acceptedConnChan: - err := d.err - if errors.Is(err, context.DeadlineExceeded) { - // we don't want to report error handshake deadline exceeded - continue - } - if errors.Is(err, udp.ErrClosedListener) { - return nil, ErrListenerIsClosed - } - if err != nil { - return nil, err - } - return d.conn, nil - } + rw, err := l.listener.Accept() + if err != nil { + return nil, err } + return rw, nil } // Accept waits for a generic Conn. @@ -186,8 +60,6 @@ func (l *DTLSListener) Close() error { if !l.closed.CompareAndSwap(false, true) { return nil } - close(l.done) - defer l.wg.Wait() return l.listener.Close() } diff --git a/net/options.go b/net/options.go index c037ef9c..a18578ad 100644 --- a/net/options.go +++ b/net/options.go @@ -120,24 +120,3 @@ func (m MulticastInterfaceErrorOpt) applyMC(o *MulticastOptions) { func WithMulticastInterfaceError(interfaceError InterfaceError) MulticastOption { return &MulticastInterfaceErrorOpt{interfaceError: interfaceError} } - -// A DTLSListenerOption sets options such as gopool. -type DTLSListenerOption interface { - ApplyDTLS(*DTLSListenerConfig) -} - -// GoPoolOpt gopool option. -type GoPoolOpt struct { - goPool GoPoolFunc -} - -func (o GoPoolOpt) ApplyDTLS(cfg *DTLSListenerConfig) { - cfg.GoPool = o.goPool -} - -// WithGoPool sets function for managing spawning go routines -// for handling incoming request's. -// Eg: https://github.com/panjf2000/ants. -func WithGoPool(goPool GoPoolFunc) GoPoolOpt { - return GoPoolOpt{goPool: goPool} -} diff --git a/net/tlslistener_test.go b/net/tlslistener_test.go index 5c9576c3..c36ea990 100644 --- a/net/tlslistener_test.go +++ b/net/tlslistener_test.go @@ -1,4 +1,4 @@ -package net +package net_test import ( "context" @@ -10,6 +10,7 @@ import ( "testing" "time" + coapNet "github.com/plgd-dev/go-coap/v3/net" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -82,7 +83,7 @@ func TestTLSListenerAcceptWithContext(t *testing.T) { }() config := SetTLSConfig(t) - listener, err := NewTLSListener("tcp", "127.0.0.1:", config) + listener, err := coapNet.NewTLSListener("tcp", "127.0.0.1:", config) require.NoError(t, err) defer func() { err := listener.Close() @@ -168,7 +169,7 @@ func TestTLSListenerCheckForInfinitLoop(t *testing.T) { }() config := SetTLSConfig(t) - listener, err := NewTLSListener("tcp", "127.0.0.1:", config) + listener, err := coapNet.NewTLSListener("tcp", "127.0.0.1:", config) require.NoError(t, err) defer func() { err := listener.Close() @@ -215,7 +216,7 @@ func TestTLSListenerCheckForInfinitLoop(t *testing.T) { } require.NoError(t, err) b := make([]byte, 1024) - c := NewConn(con) + c := coapNet.NewConn(con) _, err = c.ReadWithContext(context.Background(), b) require.Error(t, err) assert.Contains(t, err.Error(), "EOF") diff --git a/server.go b/server.go index bec94646..10d54a1f 100644 --- a/server.go +++ b/server.go @@ -6,7 +6,7 @@ import ( "errors" "fmt" - piondtls "github.com/pion/dtls/v2" + piondtls "github.com/pion/dtls/v3" "github.com/plgd-dev/go-coap/v3/dtls" dtlsServer "github.com/plgd-dev/go-coap/v3/dtls/server" "github.com/plgd-dev/go-coap/v3/mux" diff --git a/tcp/server/server.go b/tcp/server/server.go index 08f6e079..cb78cdd9 100644 --- a/tcp/server/server.go +++ b/tcp/server/server.go @@ -160,7 +160,7 @@ func (s *Server) Serve(l Listener) error { if ok := s.checkAcceptError(err); !ok { return nil } - if rw == nil { + if err != nil || rw == nil { continue } wg.Add(1)