From 09376463b579cdc6a13da84f9f14c8f42503fb72 Mon Sep 17 00:00:00 2001 From: CaiYueTing Date: Thu, 17 Aug 2023 17:19:26 +0800 Subject: [PATCH 1/7] feat: add listern and server with options --- server.go | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/server.go b/server.go index 2a1cc24e..85cf3779 100644 --- a/server.go +++ b/server.go @@ -78,3 +78,83 @@ func ListenAndServeDTLS(network string, addr string, config *piondtls.Config, ha s := dtls.NewServer(options.WithMux(handler)) return s.Serve(l) } + +// ListenAndServeWithOption Starts a server on address and network specified Invoke options +// for incoming queries. +func ListenAndServeWithOptions(network, addr string, opts ...any) (err error) { + tcpOptions := []tcpServer.Option{} + udpOptions := []udpServer.Option{} + for _, opt := range opts { + switch opt.(type) { + case tcpServer.Option: + o, _ := opt.(tcpServer.Option) + tcpOptions = append(tcpOptions, o) + case udpServer.Option: + o, _ := opt.(udpServer.Option) + udpOptions = append(udpOptions, o) + default: + return fmt.Errorf("only support tcpServer.Option, udpServer.Option and dtlsServer.Option") + } + } + + switch network { + case "udp", "udp4", "udp6", "": + l, err := net.NewListenUDP(network, addr) + if err != nil { + return err + } + defer func() { + if errC := l.Close(); errC != nil && err == nil { + err = errC + } + }() + s := udp.NewServer(udpOptions...) + return s.Serve(l) + case "tcp", "tcp4", "tcp6": + l, err := net.NewTCPListener(network, addr) + if err != nil { + return err + } + defer func() { + if errC := l.Close(); errC != nil && err == nil { + err = errC + } + }() + s := tcp.NewServer(tcpOptions...) + return s.Serve(l) + default: + return fmt.Errorf("invalid network (%v)", network) + } +} + +// ListenAndServeTCPTLSWithOptions Starts a server on address and network over TLS specified Invoke options +// for incoming queries. +func ListenAndServeTCPTLSWithOptions(network, addr string, config *tls.Config, opts ...tcpServer.Option) (err error) { + l, err := net.NewTLSListener(network, addr, config) + if err != nil { + return err + } + defer func() { + if errC := l.Close(); errC != nil && err == nil { + err = errC + } + }() + s := tcp.NewServer(opts...) + return s.Serve(l) +} + +// ListenAndServeDTLSWithOptions Starts a server on address and network over DTLS specified Invoke options +// for incoming queries. +func ListenAndServeDTLSWithOptions(network string, addr string, config *piondtls.Config, opts ...dtlsServer.Option) (err error) { + l, err := net.NewDTLSListener(network, addr, config) + if err != nil { + return err + } + defer func() { + if errC := l.Close(); errC != nil && err == nil { + err = errC + } + }() + s := dtls.NewServer(opts...) + return s.Serve(l) +} From e445c3d3d9e134ed63195387327905ce8eb29353 Mon Sep 17 00:00:00 2001 From: CaiYueTing Date: Thu, 17 Aug 2023 17:41:29 +0800 Subject: [PATCH 2/7] fix: add import pkg and update func description --- server.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server.go b/server.go index 85cf3779..9dcc9d6d 100644 --- a/server.go +++ b/server.go @@ -12,6 +12,10 @@ import ( "github.com/plgd-dev/go-coap/v3/options" "github.com/plgd-dev/go-coap/v3/tcp" "github.com/plgd-dev/go-coap/v3/udp" + + dtlsServer "github.com/plgd-dev/go-coap/v3/dtls/server" + tcpServer "github.com/plgd-dev/go-coap/v3/tcp/server" + udpServer "github.com/plgd-dev/go-coap/v3/udp/server" ) // ListenAndServe Starts a server on address and network specified Invoke handler @@ -80,7 +84,7 @@ func ListenAndServeDTLS(network string, addr string, config *piondtls.Config, ha } // ListenAndServeWithOption Starts a server on address and network specified Invoke options -// for incoming queries. +// for incoming queries. The options is only support tcpServer.Option and udpServer.Option func ListenAndServeWithOptions(network, addr string, opts ...any) (err error) { tcpOptions := []tcpServer.Option{} udpOptions := []udpServer.Option{} @@ -93,7 +97,7 @@ func ListenAndServeWithOptions(network, addr string, opts ...any) (err error) { o, _ := opt.(udpServer.Option) udpOptions = append(udpOptions, o) default: - return fmt.Errorf("only support tcpServer.Option, udpServer.Option and dtlsServer.Option") + return fmt.Errorf("only support tcpServer.Option and udpServer.Option") } } From 5c848e6a6ff44a964bc005a089c14af496742d9e Mon Sep 17 00:00:00 2001 From: CaiYueTing Date: Thu, 17 Aug 2023 17:41:46 +0800 Subject: [PATCH 3/7] feat: add options server example --- examples/options/server/main.go | 89 +++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 examples/options/server/main.go diff --git a/examples/options/server/main.go b/examples/options/server/main.go new file mode 100644 index 00000000..d5e3ee6a --- /dev/null +++ b/examples/options/server/main.go @@ -0,0 +1,89 @@ +package main + +import ( + "bytes" + "context" + "crypto/tls" + "fmt" + "log" + + piondtls "github.com/pion/dtls/v2" + 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" + "github.com/plgd-dev/go-coap/v3/mux" + "github.com/plgd-dev/go-coap/v3/options" + + dtlsServer "github.com/plgd-dev/go-coap/v3/dtls/server" + tcpServer "github.com/plgd-dev/go-coap/v3/tcp/server" + udpClient "github.com/plgd-dev/go-coap/v3/udp/client" +) + +func handleA(w mux.ResponseWriter, r *mux.Message) { + log.Printf("got message in handleA: %+v from %v\n", r, w.Conn().RemoteAddr()) + err := w.SetResponse(codes.GET, message.TextPlain, bytes.NewReader([]byte("A hello world"))) + if err != nil { + log.Printf("cannot set response: %v", err) + } +} + +func handleB(w mux.ResponseWriter, r *mux.Message) { + log.Printf("got message in handleB: %+v from %v\n", r, w.Conn().RemoteAddr()) + customResp := w.Conn().AcquireMessage(r.Context()) + defer w.Conn().ReleaseMessage(customResp) + customResp.SetCode(codes.Content) + customResp.SetToken(r.Token()) + customResp.SetContentFormat(message.TextPlain) + customResp.SetBody(bytes.NewReader([]byte("B hello world"))) + err := w.Conn().WriteMessage(customResp) + if err != nil { + log.Printf("cannot set response: %v", err) + } +} + +func handleOnNewConn(cc *udpClient.Conn) { + dtlsConn, ok := cc.NetConn().(*piondtls.Conn) + if !ok { + log.Fatalf("invalid type %T", cc.NetConn()) + } + clientId := dtlsConn.ConnectionState().IdentityHint + cc.SetContextValue("clientId", clientId) + cc.AddOnClose(func() { + clientId := dtlsConn.ConnectionState().IdentityHint + log.Printf("closed connection clientId: %s", clientId) + }) +} + +func main() { + m := mux.NewRouter() + m.Handle("/a", mux.HandlerFunc(handleA)) + m.Handle("/b", mux.HandlerFunc(handleB)) + + tcpOpts := []tcpServer.Option{} + tcpOpts = append(tcpOpts, options.WithMux(m), options.WithContext(context.Background())) + + dtlsOpts := []dtlsServer.Option{} + dtlsOpts = append(dtlsOpts, options.WithMux(m), options.WithContext(context.Background())) + + go func() { + // serve a tcp server on :5686 + log.Fatal(coap.ListenAndServeWithOptions("tcp", ":5686", tcpOpts)) + }() + + go func() { + // serve a tls tcp server on :5687 + log.Fatal(coap.ListenAndServeTCPTLSWithOptions("tcp", "5687", &tls.Config{}, tcpOpts...)) + }() + + go func() { + // serve a udp dtls server on :5688 + log.Fatal(coap.ListenAndServeDTLSWithOptions("udp", ":5688", &piondtls.Config{ + PSK: func(hint []byte) ([]byte, error) { + fmt.Printf("Client's hint: %s \n", hint) + return []byte{0xAB, 0xC1, 0x23}, nil + }, + PSKIdentityHint: []byte("Pion DTLS Client"), + CipherSuites: []piondtls.CipherSuiteID{piondtls.TLS_PSK_WITH_AES_128_CCM_8}, + }, dtlsOpts...)) + }() +} From 8ce0c706393082adf344d271ba7d6e4fb760d557 Mon Sep 17 00:00:00 2001 From: CaiYueTing Date: Thu, 17 Aug 2023 18:12:44 +0800 Subject: [PATCH 4/7] fix: add option in example coode --- examples/options/server/main.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/options/server/main.go b/examples/options/server/main.go index d5e3ee6a..451e5104 100644 --- a/examples/options/server/main.go +++ b/examples/options/server/main.go @@ -60,10 +60,16 @@ func main() { m.Handle("/b", mux.HandlerFunc(handleB)) tcpOpts := []tcpServer.Option{} - tcpOpts = append(tcpOpts, options.WithMux(m), options.WithContext(context.Background())) + tcpOpts = append(tcpOpts, + options.WithMux(m), + options.WithContext(context.Background())) dtlsOpts := []dtlsServer.Option{} - dtlsOpts = append(dtlsOpts, options.WithMux(m), options.WithContext(context.Background())) + dtlsOpts = append(dtlsOpts, + options.WithMux(m), + options.WithContext(context.Background()), + options.WithOnNewConn(handleOnNewConn), + ) go func() { // serve a tcp server on :5686 From d39cb6360b8de0409fe5dd0ddd2da1de8d485c67 Mon Sep 17 00:00:00 2001 From: YTC Date: Thu, 17 Aug 2023 23:44:33 +0800 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20=F0=9F=90=9B=20make=20linter=20happy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/server.go b/server.go index 9dcc9d6d..1df5ab69 100644 --- a/server.go +++ b/server.go @@ -7,14 +7,13 @@ import ( piondtls "github.com/pion/dtls/v2" "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" "github.com/plgd-dev/go-coap/v3/net" "github.com/plgd-dev/go-coap/v3/options" "github.com/plgd-dev/go-coap/v3/tcp" - "github.com/plgd-dev/go-coap/v3/udp" - - dtlsServer "github.com/plgd-dev/go-coap/v3/dtls/server" tcpServer "github.com/plgd-dev/go-coap/v3/tcp/server" + "github.com/plgd-dev/go-coap/v3/udp" udpServer "github.com/plgd-dev/go-coap/v3/udp/server" ) @@ -89,12 +88,10 @@ func ListenAndServeWithOptions(network, addr string, opts ...any) (err error) { tcpOptions := []tcpServer.Option{} udpOptions := []udpServer.Option{} for _, opt := range opts { - switch opt.(type) { + switch o := opt.(type) { case tcpServer.Option: - o, _ := opt.(tcpServer.Option) tcpOptions = append(tcpOptions, o) case udpServer.Option: - o, _ := opt.(udpServer.Option) udpOptions = append(udpOptions, o) default: return fmt.Errorf("only support tcpServer.Option and udpServer.Option") From cb348967ae01e5def9ac1fc1edd128c2589e6b27 Mon Sep 17 00:00:00 2001 From: CaiYueTing Date: Wed, 24 Jul 2024 20:38:37 +0800 Subject: [PATCH 6/7] refactor: use error string instead of multierror pkg import --- go.mod | 2 -- go.sum | 5 ----- message/pool/message.go | 9 ++++----- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 497ffb44..25a11900 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.20 require ( github.com/dsnet/golib/memfile v1.0.0 - github.com/hashicorp/go-multierror v1.1.1 github.com/pion/dtls/v2 v2.2.8-0.20240701035148-45e16a098c47 github.com/pion/transport/v3 v3.0.2 github.com/stretchr/testify v1.9.0 @@ -16,7 +15,6 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/crypto v0.24.0 // indirect diff --git a/go.sum b/go.sum index 0aa3ed81..04c81f77 100644 --- a/go.sum +++ b/go.sum @@ -3,11 +3,6 @@ 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/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= 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/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= diff --git a/message/pool/message.go b/message/pool/message.go index 82327243..e3eac274 100644 --- a/message/pool/message.go +++ b/message/pool/message.go @@ -6,8 +6,8 @@ import ( "errors" "fmt" "io" + "strings" - multierror "github.com/hashicorp/go-multierror" "github.com/plgd-dev/go-coap/v3/message" "github.com/plgd-dev/go-coap/v3/message/codes" "github.com/plgd-dev/go-coap/v3/net" @@ -617,13 +617,12 @@ func (r *Message) Clone(msg *Message) error { } _, err = io.Copy(buf, r.Body()) if err != nil { - var errs *multierror.Error - errs = multierror.Append(errs, err) + errStr := []string{err.Error()} _, errS := r.Body().Seek(n, io.SeekStart) if errS != nil { - errs = multierror.Append(errs, errS) + errStr = append(errStr, errS.Error()) } - return errs.ErrorOrNil() + return fmt.Errorf("%d errors occurred:\n\t%s", len(errStr), strings.Join(errStr, "\n\t")) } _, err = r.Body().Seek(n, io.SeekStart) if err != nil { From c1d9fb8fc089dec51d21334d672f56e5566c7fd9 Mon Sep 17 00:00:00 2001 From: CaiYueTing Date: Wed, 24 Jul 2024 21:07:00 +0800 Subject: [PATCH 7/7] fix: use error of array instead of error string of array --- message/pool/message.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/message/pool/message.go b/message/pool/message.go index e3eac274..59fbe9fe 100644 --- a/message/pool/message.go +++ b/message/pool/message.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "strings" "github.com/plgd-dev/go-coap/v3/message" "github.com/plgd-dev/go-coap/v3/message/codes" @@ -617,12 +616,12 @@ func (r *Message) Clone(msg *Message) error { } _, err = io.Copy(buf, r.Body()) if err != nil { - errStr := []string{err.Error()} + errs := []error{err} _, errS := r.Body().Seek(n, io.SeekStart) if errS != nil { - errStr = append(errStr, errS.Error()) + errs = append(errs, errS) } - return fmt.Errorf("%d errors occurred:\n\t%s", len(errStr), strings.Join(errStr, "\n\t")) + return errors.Join(errs...) } _, err = r.Body().Seek(n, io.SeekStart) if err != nil {