diff --git a/README.md b/README.md
index 03c6bc0..a19b61f 100644
--- a/README.md
+++ b/README.md
@@ -16,10 +16,16 @@ When running, please provide following format:
| d | data to be sent in POST or PUT | "" |
| cf | content format | 50 (JSON format) |
+The cli offers DTLS support with PKI certificates.Export the path to the certificate folder with the name `CERT_PATH` before build to enable the DTLS configuration.
+
+```bash
+export CERT_PATH="../certs"
+make
+```
## Examples:
```bash
-coap-cli get channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic -auth 1e1017e6-dee7-45b4-8a13-00e6afeb66eb -o
+coap-cli get channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic -auth 1e1017e6-dee7-45b4-8a13-00e6afeb66eb -o -tls
```
```bash
coap-cli post channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic -auth 1e1017e6-dee7-45b4-8a13-00e6afeb66eb -d "hello world"
diff --git a/certs/ca.crt b/certs/ca.crt
new file mode 100644
index 0000000..2702c99
--- /dev/null
+++ b/certs/ca.crt
@@ -0,0 +1,3 @@
+-----BEGIN CERTIFICATE-----
+^
+-----END CERTIFICATE-----
diff --git a/certs/client.crt b/certs/client.crt
new file mode 100644
index 0000000..2702c99
--- /dev/null
+++ b/certs/client.crt
@@ -0,0 +1,3 @@
+-----BEGIN CERTIFICATE-----
+^
+-----END CERTIFICATE-----
diff --git a/certs/client.key b/certs/client.key
new file mode 100644
index 0000000..b45eae3
--- /dev/null
+++ b/certs/client.key
@@ -0,0 +1,3 @@
+-----BEGIN PRIVATE KEY-----
+^
+-----END PRIVATE KEY-----
diff --git a/certutil/utility.go b/certutil/utility.go
new file mode 100644
index 0000000..0ef35ba
--- /dev/null
+++ b/certutil/utility.go
@@ -0,0 +1,135 @@
+package certutil
+
+import (
+ "context"
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/rsa"
+ "crypto/tls"
+ "crypto/x509"
+ "encoding/pem"
+ "errors"
+ "log"
+ "os"
+ "strings"
+
+ piondtls "github.com/pion/dtls/v2"
+)
+
+// Create pion dtls config from certificates.
+func CreateClientConfig(ctx context.Context, certPath string) (*piondtls.Config, error) {
+ clientKeyBytes, err := os.ReadFile(certPath + "/client.key")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ clientCrtBytes, err := os.ReadFile(certPath + "/client.crt")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ caBytes, err := os.ReadFile(certPath + "/ca.crt")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ certificate, err := LoadKeyAndCertificate(clientKeyBytes, clientCrtBytes)
+ if err != nil {
+ return nil, err
+ }
+ // cert pool
+ certPool, err := LoadCertPool(caBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ return &piondtls.Config{
+ Certificates: []tls.Certificate{*certificate},
+ ExtendedMasterSecret: piondtls.RequireExtendedMasterSecret,
+ RootCAs: certPool,
+ InsecureSkipVerify: true,
+ }, nil
+}
+
+func LoadCertificate(certBytes []byte) (*tls.Certificate, error) {
+ var certificate tls.Certificate
+
+ for {
+ block, rest := pem.Decode(certBytes)
+ if block == nil {
+ break
+ }
+
+ if block.Type != "CERTIFICATE" {
+ return nil, errors.New("block is not a certificate, unable to load certificates")
+ }
+
+ certificate.Certificate = append(certificate.Certificate, block.Bytes)
+ certBytes = rest
+ }
+
+ if len(certificate.Certificate) == 0 {
+ return nil, errors.New("no certificate found, unable to load certificates")
+ }
+
+ return &certificate, nil
+}
+
+func LoadKey(keyBytes []byte) (crypto.PrivateKey, error) {
+ block, _ := pem.Decode(keyBytes)
+ if block == nil || !strings.HasSuffix(block.Type, "PRIVATE KEY") {
+ return nil, errors.New("block is not a private key, unable to load key")
+ }
+
+ if key, err := x509.ParsePKCS1PrivateKey(block.Bytes); err == nil {
+ return key, nil
+ }
+
+ if key, err := x509.ParsePKCS8PrivateKey(block.Bytes); err == nil {
+ switch key := key.(type) {
+ case *rsa.PrivateKey, *ecdsa.PrivateKey:
+ return key, nil
+ default:
+ return nil, errors.New("unknown key time in PKCS#8 wrapping, unable to load key")
+ }
+ }
+
+ if key, err := x509.ParseECPrivateKey(block.Bytes); err == nil {
+ return key, nil
+ }
+
+ return nil, errors.New("no private key found, unable to load key")
+}
+
+// LoadKeyAndCertificate loads client certificate
+func LoadKeyAndCertificate(keyBytes []byte, certBytes []byte) (*tls.Certificate, error) {
+ certificate, err := LoadCertificate(certBytes)
+ if err != nil {
+ return nil, err
+ }
+ key, err := LoadKey(keyBytes)
+ if err != nil {
+ return nil, err
+ }
+ certificate.PrivateKey = key
+ return certificate, nil
+}
+
+// LoadCertPool loads cert pool from ca certificate
+func LoadCertPool(caBytes []byte) (*x509.CertPool, error) {
+ rootCertificate, err := LoadCertificate(caBytes)
+ if err != nil {
+ return nil, err
+ }
+ certPool := x509.NewCertPool()
+ for _, certBytes := range rootCertificate.Certificate {
+ cert, err := x509.ParseCertificate(certBytes)
+ if err != nil {
+ certPool = nil
+ return nil, err
+ }
+ certPool.AddCert(cert)
+ }
+
+ return certPool, nil
+}
diff --git a/cmd/main.go b/cmd/main.go
index 65521fa..8e95a17 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -12,10 +12,11 @@ import (
"syscall"
coap "github.com/mainflux/coap-cli/coap"
- "github.com/plgd-dev/go-coap/v2/message"
- coapmsg "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/message/codes"
- "github.com/plgd-dev/go-coap/v2/udp/message/pool"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ coapmsg "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
)
const (
@@ -36,7 +37,6 @@ mathod: get, put, post or delete
-p port (default: "5683")
-d data to be sent in POST or PUT (default: "")
-cf content format (default: 50 - JSON format))
-
Examples:
coap-cli get channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic -auth 1e1017e6-dee7-45b4-8a13-00e6afeb66eb -o
coap-cli post channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic -auth 1e1017e6-dee7-45b4-8a13-00e6afeb66eb -d "hello world"
@@ -55,7 +55,7 @@ func parseCode(code string) (codes.Code, error) {
case delete:
return codes.DELETE, nil
}
- return 0, errors.New("Message can be GET, POST, PUT or DELETE")
+ return 0, errors.New("MESSAGE CAN BE GET, POST, PUT OR DELETE")
}
func printMsg(m *pool.Message) {
@@ -65,12 +65,14 @@ func printMsg(m *pool.Message) {
}
func main() {
+ certPath := os.Getenv("CERT_PATH")
+
if len(os.Args) < 2 {
log.Fatal(helpCmd)
}
help := strings.ToLower(os.Args[1])
if help == "-h" || help == "--help" {
- log.Println(helpMsg)
+ log.Print(helpMsg)
os.Exit(0)
}
@@ -97,7 +99,7 @@ func main() {
a := flag.String("auth", "", "Auth token")
flag.Parse()
- client, err := coap.New(*h + ":" + *p)
+ client, err := coap.New(*h+":"+*p,certPath)
if err != nil {
log.Fatal("Error creating client: ", err)
}
@@ -123,9 +125,10 @@ func main() {
if err != nil {
log.Fatal("Error observing resource: ", err)
}
- errs := make(chan error, 2)
+ errs := make(chan error, 1)
+
go func() {
- c := make(chan os.Signal)
+ c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT)
errs <- fmt.Errorf("%s", <-c)
}()
diff --git a/coap/client.go b/coap/client.go
index 585fad8..56378cc 100644
--- a/coap/client.go
+++ b/coap/client.go
@@ -8,26 +8,48 @@ import (
"log"
"time"
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/message/codes"
- "github.com/plgd-dev/go-coap/v2/udp"
- "github.com/plgd-dev/go-coap/v2/udp/client"
- "github.com/plgd-dev/go-coap/v2/udp/message/pool"
+ certutil "github.com/mainflux/coap-cli/certutil"
+
+ "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"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "github.com/plgd-dev/go-coap/v3/udp"
+ "github.com/plgd-dev/go-coap/v3/udp/client"
)
// Client represents CoAP client.
type Client struct {
- conn *client.ClientConn
+ conn *client.Conn
+}
+
+// Observation interface
+type NewObservation interface {
+ Cancel(ctx context.Context, opts ...message.Option) error
+ Canceled() bool
}
// New returns new CoAP client connecting it to the server.
-func New(addr string) (Client, error) {
- c, err := udp.Dial(addr)
- if err != nil {
- log.Fatalf("Error dialing: %v", err)
- }
+func New(addr string, certPath string) (Client, error) {
+ switch {
+ case certPath != "":
+ config, err := certutil.CreateClientConfig(context.Background(), certPath)
+ if err != nil {
+ log.Fatalln(err)
+ }
+ co, err := dtls.Dial(addr, config)
+ if err != nil {
+ log.Fatalf("Error dialing: %v", err)
+ }
+ return Client{conn: co}, err
+ default:
+ c, err := udp.Dial(addr)
+ if err != nil {
+ log.Fatalf("Error dialing: %v", err)
+ }
+ return Client{conn: c}, nil
- return Client{conn: c}, nil
+ }
}
// Send send a message.
@@ -45,11 +67,11 @@ func (c Client) Send(path string, msgCode codes.Code, cf message.MediaType, payl
case codes.DELETE:
return c.conn.Delete(ctx, path, opts...)
}
- return nil, errors.New("Invalid message code")
+ return nil, errors.New("INVALID MESSAGE CODE")
}
// Receive receives a message.
-func (c Client) Receive(path string, opts ...message.Option) (*client.Observation, error) {
+func (c Client) Receive(path string, opts ...message.Option) (NewObservation, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
@@ -64,4 +86,5 @@ func (c Client) Receive(path string, opts ...message.Option) (*client.Observatio
fmt.Println("Payload: ", string(body))
}
}, opts...)
+
}
diff --git a/go.mod b/go.mod
index 37011fa..3d19d2d 100644
--- a/go.mod
+++ b/go.mod
@@ -1,12 +1,22 @@
module github.com/mainflux/coap-cli
-go 1.15
+go 1.21
require (
- github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
- github.com/plgd-dev/go-coap/v2 v2.4.0
- golang.org/x/net v0.0.0-20200513185701-a91f0712d120 // indirect
- golang.org/x/sys v0.0.0-20201013081832-0aaa2718063a // indirect
- gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
- gopkg.in/yaml.v2 v2.3.0 // indirect
+ github.com/pion/dtls/v2 v2.2.8-0.20230905141523-2b584af66577
+ github.com/plgd-dev/go-coap/v3 v3.1.5
+)
+
+require (
+ github.com/dsnet/golib/memfile v1.0.0 // indirect
+ github.com/hashicorp/errwrap v1.1.0 // indirect
+ github.com/hashicorp/go-multierror v1.1.1 // indirect
+ github.com/pion/logging v0.2.2 // indirect
+ github.com/pion/transport/v3 v3.0.1 // indirect
+ go.uber.org/atomic v1.11.0 // indirect
+ golang.org/x/crypto v0.13.0 // indirect
+ golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
+ golang.org/x/net v0.15.0 // indirect
+ golang.org/x/sync v0.3.0 // indirect
+ golang.org/x/sys v0.12.0 // indirect
)
diff --git a/go.sum b/go.sum
index 2d2d413..a519133 100644
--- a/go.sum
+++ b/go.sum
@@ -1,199 +1,82 @@
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
-github.com/dsnet/golib/memfile v0.0.0-20190531212259-571cdbcff553/go.mod h1:tXGNW9q3RwvWt1VV2qrRKlSSz0npnh12yftCSCy2T64=
-github.com/dsnet/golib/memfile v0.0.0-20200723050859-c110804dfa93 h1:I48YLRgQEeWsjF7LmNcl62vTHSUfUfEVe3I1oHXiS5o=
-github.com/dsnet/golib/memfile v0.0.0-20200723050859-c110804dfa93/go.mod h1:tXGNW9q3RwvWt1VV2qrRKlSSz0npnh12yftCSCy2T64=
-github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
-github.com/go-acme/lego v2.7.2+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG94USbYxYrZfTkIn0M=
-github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-ocf/go-coap/v2 v2.0.4-0.20200728125043-f38b86f047a7/go.mod h1:X9wVKcaOSx7wBxKcvrWgMQq1R2DNeA7NBLW2osIb8TM=
-github.com/go-ocf/kit v0.0.0-20200728130040-4aebdb6982bc/go.mod h1:TIsoMT/iB7t9P6ahkcOnsmvS83SIJsv9qXRfz/yLf6M=
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
-github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
-github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
-github.com/grpc-ecosystem/go-grpc-middleware v1.2.0/go.mod h1:mJzapYve32yjrKlk9GbyCZHuPgZsrbyIbyKhSzOpg6s=
-github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
-github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/lestrrat-go/iter v0.0.0-20200422075355-fc1769541911/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc=
-github.com/lestrrat-go/jwx v1.0.2/go.mod h1:TPF17WiSFegZo+c20fdpw49QD+/7n4/IsGvEmCSWwT0=
-github.com/lestrrat-go/pdebug v0.0.0-20200204225717-4d6bd78da58d/go.mod h1:B06CSso/AWxiPejj+fheUINGeBKeeEZNt8w+EoU7+L8=
-github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
-github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
-github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
-github.com/pion/dtls/v2 v2.0.1-0.20200503085337-8e86b3a7d585 h1:0v1k/bHrth28TctdEWnrCgLehYn3nOvFAwOwtwmyC34=
-github.com/pion/dtls/v2 v2.0.1-0.20200503085337-8e86b3a7d585/go.mod h1:/GahSOC8ZY/+17zkaGJIG4OUkSGAcZu/N/g3roBOCkM=
+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.20230905141523-2b584af66577 h1:JWOGC998HSupoCjz7RKLpJcQjwnUhgIfHn8pRz9HvCk=
+github.com/pion/dtls/v2 v2.2.8-0.20230905141523-2b584af66577/go.mod h1:gKEfO5iCAoS9mBySDZwcIRU2ksZ2a5HqzU+jTUNTzdM=
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 v0.10.0 h1:9M12BSneJm6ggGhJyWpDveFOstJsTiQjkLf4M44rm80=
-github.com/pion/transport v0.10.0/go.mod h1:BnHnUipd0rZQyTVB2SBGojFHT9CBt5C5TcsJSQGkvSE=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/plgd-dev/go-coap/v2 v2.0.4-0.20200819112225-8eb712b901bc/go.mod h1:+tCi9Q78H/orWRtpVWyBgrr4vKFo2zYtbbxUllerBp4=
-github.com/plgd-dev/go-coap/v2 v2.4.0 h1:pEexScWQ0I+t35gyHSKRciIyJxdmcfosnCX78BZbFzk=
-github.com/plgd-dev/go-coap/v2 v2.4.0/go.mod h1:0lg7sgOTxlHtfyGhPiak214vQ7CuBRD99LbdBCpDRW8=
-github.com/plgd-dev/kit v0.0.0-20200819113605-d5fcf3e94f63 h1:cI6kESUBU1KUHtufZepEkaTsSkLN2kE6xz+Ec5V17q0=
-github.com/plgd-dev/kit v0.0.0-20200819113605-d5fcf3e94f63/go.mod h1:Yl9zisyXfPdtP9hTWlJqjJYXmgU/jtSDKttz9/CeD90=
+github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM=
+github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
+github.com/plgd-dev/go-coap/v3 v3.1.5 h1:Bn3l1fEFvC2XsRibJXIgXonY8GLwYSQP3gYYop5D3l0=
+github.com/plgd-dev/go-coap/v3 v3.1.5/go.mod h1:BbPQ1x6ojsvA1Ccp9kVnIuw3Z3J4b/fhNnG/OwCsksQ=
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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
-github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
-github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasthttp v1.12.0/go.mod h1:229t1eWu9UXTPmoUkbpN/fctKPBY4IJoFXQnxHGXy6E=
-github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
-github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
-github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
-go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
-go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
-go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
-go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
+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/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 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
-golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
-golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
-golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
+golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
+golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
+golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
+golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
+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-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200513185701-a91f0712d120 h1:EZ3cVSzKOlJxAd8e8YAJ7no8nNypTxexh/YE/xW3ZEY=
-golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+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.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
+golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+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.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201013081832-0aaa2718063a h1:bhXnJ7fn2SiL+C8iOWPfNBJKDTjUByftpPW7b9CX94U=
-golang.org/x/sys v0.0.0-20201013081832-0aaa2718063a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+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.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+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.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+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.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+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.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200417140056-c07e33ef3290 h1:NXNmtp0ToD36cui5IqWy95LC4Y6vT/4y3RnPxlQPinU=
-golang.org/x/tools v0.0.0-20200417140056-c07e33ef3290/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+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/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
-gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+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/vendor/github.com/dsnet/golib/memfile/LICENSE.md b/vendor/github.com/dsnet/golib/memfile/LICENSE.md
new file mode 100644
index 0000000..26c8ba0
--- /dev/null
+++ b/vendor/github.com/dsnet/golib/memfile/LICENSE.md
@@ -0,0 +1,24 @@
+Copyright © 2014, Joe Tsai and The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+* Neither the copyright holder nor the names of its contributors may be used to
+endorse or promote products derived from this software without specific prior
+written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/dsnet/golib/memfile/go.mod b/vendor/github.com/dsnet/golib/memfile/go.mod
deleted file mode 100644
index 64d66c3..0000000
--- a/vendor/github.com/dsnet/golib/memfile/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module github.com/dsnet/golib/memfile
-
-go 1.12
diff --git a/vendor/github.com/hashicorp/errwrap/LICENSE b/vendor/github.com/hashicorp/errwrap/LICENSE
new file mode 100644
index 0000000..c33dcc7
--- /dev/null
+++ b/vendor/github.com/hashicorp/errwrap/LICENSE
@@ -0,0 +1,354 @@
+Mozilla Public License, version 2.0
+
+1. Definitions
+
+1.1. “Contributor”
+
+ means each individual or legal entity that creates, contributes to the
+ creation of, or owns Covered Software.
+
+1.2. “Contributor Version”
+
+ means the combination of the Contributions of others (if any) used by a
+ Contributor and that particular Contributor’s Contribution.
+
+1.3. “Contribution”
+
+ means Covered Software of a particular Contributor.
+
+1.4. “Covered Software”
+
+ means Source Code Form to which the initial Contributor has attached the
+ notice in Exhibit A, the Executable Form of such Source Code Form, and
+ Modifications of such Source Code Form, in each case including portions
+ thereof.
+
+1.5. “Incompatible With Secondary Licenses”
+ means
+
+ a. that the initial Contributor has attached the notice described in
+ Exhibit B to the Covered Software; or
+
+ b. that the Covered Software was made available under the terms of version
+ 1.1 or earlier of the License, but not also under the terms of a
+ Secondary License.
+
+1.6. “Executable Form”
+
+ means any form of the work other than Source Code Form.
+
+1.7. “Larger Work”
+
+ means a work that combines Covered Software with other material, in a separate
+ file or files, that is not Covered Software.
+
+1.8. “License”
+
+ means this document.
+
+1.9. “Licensable”
+
+ means having the right to grant, to the maximum extent possible, whether at the
+ time of the initial grant or subsequently, any and all of the rights conveyed by
+ this License.
+
+1.10. “Modifications”
+
+ means any of the following:
+
+ a. any file in Source Code Form that results from an addition to, deletion
+ from, or modification of the contents of Covered Software; or
+
+ b. any new file in Source Code Form that contains any Covered Software.
+
+1.11. “Patent Claims” of a Contributor
+
+ means any patent claim(s), including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by such Contributor that
+ would be infringed, but for the grant of the License, by the making,
+ using, selling, offering for sale, having made, import, or transfer of
+ either its Contributions or its Contributor Version.
+
+1.12. “Secondary License”
+
+ means either the GNU General Public License, Version 2.0, the GNU Lesser
+ General Public License, Version 2.1, the GNU Affero General Public
+ License, Version 3.0, or any later versions of those licenses.
+
+1.13. “Source Code Form”
+
+ means the form of the work preferred for making modifications.
+
+1.14. “You” (or “Your”)
+
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, “You” includes any entity that controls, is
+ controlled by, or is under common control with You. For purposes of this
+ definition, “control” means (a) the power, direct or indirect, to cause
+ the direction or management of such entity, whether by contract or
+ otherwise, or (b) ownership of more than fifty percent (50%) of the
+ outstanding shares or beneficial ownership of such entity.
+
+
+2. License Grants and Conditions
+
+2.1. Grants
+
+ Each Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ a. under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or as
+ part of a Larger Work; and
+
+ b. under Patent Claims of such Contributor to make, use, sell, offer for
+ sale, have made, import, and otherwise transfer either its Contributions
+ or its Contributor Version.
+
+2.2. Effective Date
+
+ The licenses granted in Section 2.1 with respect to any Contribution become
+ effective for each Contribution on the date the Contributor first distributes
+ such Contribution.
+
+2.3. Limitations on Grant Scope
+
+ The licenses granted in this Section 2 are the only rights granted under this
+ License. No additional rights or licenses will be implied from the distribution
+ or licensing of Covered Software under this License. Notwithstanding Section
+ 2.1(b) above, no patent license is granted by a Contributor:
+
+ a. for any code that a Contributor has removed from Covered Software; or
+
+ b. for infringements caused by: (i) Your and any other third party’s
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+ c. under Patent Claims infringed by Covered Software in the absence of its
+ Contributions.
+
+ This License does not grant any rights in the trademarks, service marks, or
+ logos of any Contributor (except as may be necessary to comply with the
+ notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+ No Contributor makes additional grants as a result of Your choice to
+ distribute the Covered Software under a subsequent version of this License
+ (see Section 10.2) or under the terms of a Secondary License (if permitted
+ under the terms of Section 3.3).
+
+2.5. Representation
+
+ Each Contributor represents that the Contributor believes its Contributions
+ are its original creation(s) or it has sufficient rights to grant the
+ rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+ This License is not intended to limit any rights You have under applicable
+ copyright doctrines of fair use, fair dealing, or other equivalents.
+
+2.7. Conditions
+
+ Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
+ Section 2.1.
+
+
+3. Responsibilities
+
+3.1. Distribution of Source Form
+
+ All distribution of Covered Software in Source Code Form, including any
+ Modifications that You create or to which You contribute, must be under the
+ terms of this License. You must inform recipients that the Source Code Form
+ of the Covered Software is governed by the terms of this License, and how
+ they can obtain a copy of this License. You may not attempt to alter or
+ restrict the recipients’ rights in the Source Code Form.
+
+3.2. Distribution of Executable Form
+
+ If You distribute Covered Software in Executable Form then:
+
+ a. such Covered Software must also be made available in Source Code Form,
+ as described in Section 3.1, and You must inform recipients of the
+ Executable Form how they can obtain a copy of such Source Code Form by
+ reasonable means in a timely manner, at a charge no more than the cost
+ of distribution to the recipient; and
+
+ b. You may distribute such Executable Form under the terms of this License,
+ or sublicense it under different terms, provided that the license for
+ the Executable Form does not attempt to limit or alter the recipients’
+ rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+ You may create and distribute a Larger Work under terms of Your choice,
+ provided that You also comply with the requirements of this License for the
+ Covered Software. If the Larger Work is a combination of Covered Software
+ with a work governed by one or more Secondary Licenses, and the Covered
+ Software is not Incompatible With Secondary Licenses, this License permits
+ You to additionally distribute such Covered Software under the terms of
+ such Secondary License(s), so that the recipient of the Larger Work may, at
+ their option, further distribute the Covered Software under the terms of
+ either this License or such Secondary License(s).
+
+3.4. Notices
+
+ You may not remove or alter the substance of any license notices (including
+ copyright notices, patent notices, disclaimers of warranty, or limitations
+ of liability) contained within the Source Code Form of the Covered
+ Software, except that You may alter any license notices to the extent
+ required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+ You may choose to offer, and to charge a fee for, warranty, support,
+ indemnity or liability obligations to one or more recipients of Covered
+ Software. However, You may do so only on Your own behalf, and not on behalf
+ of any Contributor. You must make it absolutely clear that any such
+ warranty, support, indemnity, or liability obligation is offered by You
+ alone, and You hereby agree to indemnify every Contributor for any
+ liability incurred by such Contributor as a result of warranty, support,
+ indemnity or liability terms You offer. You may include additional
+ disclaimers of warranty and limitations of liability specific to any
+ jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+ If it is impossible for You to comply with any of the terms of this License
+ with respect to some or all of the Covered Software due to statute, judicial
+ order, or regulation then You must: (a) comply with the terms of this License
+ to the maximum extent possible; and (b) describe the limitations and the code
+ they affect. Such description must be placed in a text file included with all
+ distributions of the Covered Software under this License. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Termination
+
+5.1. The rights granted under this License will terminate automatically if You
+ fail to comply with any of its terms. However, if You become compliant,
+ then the rights granted under this License from a particular Contributor
+ are reinstated (a) provisionally, unless and until such Contributor
+ explicitly and finally terminates Your grants, and (b) on an ongoing basis,
+ if such Contributor fails to notify You of the non-compliance by some
+ reasonable means prior to 60 days after You have come back into compliance.
+ Moreover, Your grants from a particular Contributor are reinstated on an
+ ongoing basis if such Contributor notifies You of the non-compliance by
+ some reasonable means, this is the first time You have received notice of
+ non-compliance with this License from such Contributor, and You become
+ compliant prior to 30 days after Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+ infringement claim (excluding declaratory judgment actions, counter-claims,
+ and cross-claims) alleging that a Contributor Version directly or
+ indirectly infringes any patent, then the rights granted to You by any and
+ all Contributors for the Covered Software under Section 2.1 of this License
+ shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
+ license agreements (excluding distributors and resellers) which have been
+ validly granted by You or Your distributors under this License prior to
+ termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+ Covered Software is provided under this License on an “as is” basis, without
+ warranty of any kind, either expressed, implied, or statutory, including,
+ without limitation, warranties that the Covered Software is free of defects,
+ merchantable, fit for a particular purpose or non-infringing. The entire
+ risk as to the quality and performance of the Covered Software is with You.
+ Should any Covered Software prove defective in any respect, You (not any
+ Contributor) assume the cost of any necessary servicing, repair, or
+ correction. This disclaimer of warranty constitutes an essential part of this
+ License. No use of any Covered Software is authorized under this License
+ except under this disclaimer.
+
+7. Limitation of Liability
+
+ Under no circumstances and under no legal theory, whether tort (including
+ negligence), contract, or otherwise, shall any Contributor, or anyone who
+ distributes Covered Software as permitted above, be liable to You for any
+ direct, indirect, special, incidental, or consequential damages of any
+ character including, without limitation, damages for lost profits, loss of
+ goodwill, work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses, even if such party shall have been
+ informed of the possibility of such damages. This limitation of liability
+ shall not apply to liability for death or personal injury resulting from such
+ party’s negligence to the extent applicable law prohibits such limitation.
+ Some jurisdictions do not allow the exclusion or limitation of incidental or
+ consequential damages, so this exclusion and limitation may not apply to You.
+
+8. Litigation
+
+ Any litigation relating to this License may be brought only in the courts of
+ a jurisdiction where the defendant maintains its principal place of business
+ and such litigation shall be governed by laws of that jurisdiction, without
+ reference to its conflict-of-law provisions. Nothing in this Section shall
+ prevent a party’s ability to bring cross-claims or counter-claims.
+
+9. Miscellaneous
+
+ This License represents the complete agreement concerning the subject matter
+ hereof. If any provision of this License is held to be unenforceable, such
+ provision shall be reformed only to the extent necessary to make it
+ enforceable. Any law or regulation which provides that the language of a
+ contract shall be construed against the drafter shall not be used to construe
+ this License against a Contributor.
+
+
+10. Versions of the License
+
+10.1. New Versions
+
+ Mozilla Foundation is the license steward. Except as provided in Section
+ 10.3, no one other than the license steward has the right to modify or
+ publish new versions of this License. Each version will be given a
+ distinguishing version number.
+
+10.2. Effect of New Versions
+
+ You may distribute the Covered Software under the terms of the version of
+ the License under which You originally received the Covered Software, or
+ under the terms of any subsequent version published by the license
+ steward.
+
+10.3. Modified Versions
+
+ If you create software not governed by this License, and you want to
+ create a new license for such software, you may create and use a modified
+ version of this License if you rename the license and remove any
+ references to the name of the license steward (except to note that such
+ modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
+ If You choose to distribute Source Code Form that is Incompatible With
+ Secondary Licenses under the terms of this version of the License, the
+ notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+
+ This Source Code Form is subject to the
+ terms of the Mozilla Public License, v.
+ 2.0. If a copy of the MPL was not
+ distributed with this file, You can
+ obtain one at
+ http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular file, then
+You may include the notice in a location (such as a LICENSE file in a relevant
+directory) where a recipient would be likely to look for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - “Incompatible With Secondary Licenses” Notice
+
+ This Source Code Form is “Incompatible
+ With Secondary Licenses”, as defined by
+ the Mozilla Public License, v. 2.0.
+
diff --git a/vendor/github.com/hashicorp/errwrap/README.md b/vendor/github.com/hashicorp/errwrap/README.md
new file mode 100644
index 0000000..444df08
--- /dev/null
+++ b/vendor/github.com/hashicorp/errwrap/README.md
@@ -0,0 +1,89 @@
+# errwrap
+
+`errwrap` is a package for Go that formalizes the pattern of wrapping errors
+and checking if an error contains another error.
+
+There is a common pattern in Go of taking a returned `error` value and
+then wrapping it (such as with `fmt.Errorf`) before returning it. The problem
+with this pattern is that you completely lose the original `error` structure.
+
+Arguably the _correct_ approach is that you should make a custom structure
+implementing the `error` interface, and have the original error as a field
+on that structure, such [as this example](http://golang.org/pkg/os/#PathError).
+This is a good approach, but you have to know the entire chain of possible
+rewrapping that happens, when you might just care about one.
+
+`errwrap` formalizes this pattern (it doesn't matter what approach you use
+above) by giving a single interface for wrapping errors, checking if a specific
+error is wrapped, and extracting that error.
+
+## Installation and Docs
+
+Install using `go get github.com/hashicorp/errwrap`.
+
+Full documentation is available at
+http://godoc.org/github.com/hashicorp/errwrap
+
+## Usage
+
+#### Basic Usage
+
+Below is a very basic example of its usage:
+
+```go
+// A function that always returns an error, but wraps it, like a real
+// function might.
+func tryOpen() error {
+ _, err := os.Open("/i/dont/exist")
+ if err != nil {
+ return errwrap.Wrapf("Doesn't exist: {{err}}", err)
+ }
+
+ return nil
+}
+
+func main() {
+ err := tryOpen()
+
+ // We can use the Contains helpers to check if an error contains
+ // another error. It is safe to do this with a nil error, or with
+ // an error that doesn't even use the errwrap package.
+ if errwrap.Contains(err, "does not exist") {
+ // Do something
+ }
+ if errwrap.ContainsType(err, new(os.PathError)) {
+ // Do something
+ }
+
+ // Or we can use the associated `Get` functions to just extract
+ // a specific error. This would return nil if that specific error doesn't
+ // exist.
+ perr := errwrap.GetType(err, new(os.PathError))
+}
+```
+
+#### Custom Types
+
+If you're already making custom types that properly wrap errors, then
+you can get all the functionality of `errwraps.Contains` and such by
+implementing the `Wrapper` interface with just one function. Example:
+
+```go
+type AppError {
+ Code ErrorCode
+ Err error
+}
+
+func (e *AppError) WrappedErrors() []error {
+ return []error{e.Err}
+}
+```
+
+Now this works:
+
+```go
+err := &AppError{Err: fmt.Errorf("an error")}
+if errwrap.ContainsType(err, fmt.Errorf("")) {
+ // This will work!
+}
+```
diff --git a/vendor/github.com/hashicorp/errwrap/errwrap.go b/vendor/github.com/hashicorp/errwrap/errwrap.go
new file mode 100644
index 0000000..44e368e
--- /dev/null
+++ b/vendor/github.com/hashicorp/errwrap/errwrap.go
@@ -0,0 +1,178 @@
+// Package errwrap implements methods to formalize error wrapping in Go.
+//
+// All of the top-level functions that take an `error` are built to be able
+// to take any error, not just wrapped errors. This allows you to use errwrap
+// without having to type-check and type-cast everywhere.
+package errwrap
+
+import (
+ "errors"
+ "reflect"
+ "strings"
+)
+
+// WalkFunc is the callback called for Walk.
+type WalkFunc func(error)
+
+// Wrapper is an interface that can be implemented by custom types to
+// have all the Contains, Get, etc. functions in errwrap work.
+//
+// When Walk reaches a Wrapper, it will call the callback for every
+// wrapped error in addition to the wrapper itself. Since all the top-level
+// functions in errwrap use Walk, this means that all those functions work
+// with your custom type.
+type Wrapper interface {
+ WrappedErrors() []error
+}
+
+// Wrap defines that outer wraps inner, returning an error type that
+// can be cleanly used with the other methods in this package, such as
+// Contains, GetAll, etc.
+//
+// This function won't modify the error message at all (the outer message
+// will be used).
+func Wrap(outer, inner error) error {
+ return &wrappedError{
+ Outer: outer,
+ Inner: inner,
+ }
+}
+
+// Wrapf wraps an error with a formatting message. This is similar to using
+// `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap
+// errors, you should replace it with this.
+//
+// format is the format of the error message. The string '{{err}}' will
+// be replaced with the original error message.
+//
+// Deprecated: Use fmt.Errorf()
+func Wrapf(format string, err error) error {
+ outerMsg := ""
+ if err != nil {
+ outerMsg = err.Error()
+ }
+
+ outer := errors.New(strings.Replace(
+ format, "{{err}}", outerMsg, -1))
+
+ return Wrap(outer, err)
+}
+
+// Contains checks if the given error contains an error with the
+// message msg. If err is not a wrapped error, this will always return
+// false unless the error itself happens to match this msg.
+func Contains(err error, msg string) bool {
+ return len(GetAll(err, msg)) > 0
+}
+
+// ContainsType checks if the given error contains an error with
+// the same concrete type as v. If err is not a wrapped error, this will
+// check the err itself.
+func ContainsType(err error, v interface{}) bool {
+ return len(GetAllType(err, v)) > 0
+}
+
+// Get is the same as GetAll but returns the deepest matching error.
+func Get(err error, msg string) error {
+ es := GetAll(err, msg)
+ if len(es) > 0 {
+ return es[len(es)-1]
+ }
+
+ return nil
+}
+
+// GetType is the same as GetAllType but returns the deepest matching error.
+func GetType(err error, v interface{}) error {
+ es := GetAllType(err, v)
+ if len(es) > 0 {
+ return es[len(es)-1]
+ }
+
+ return nil
+}
+
+// GetAll gets all the errors that might be wrapped in err with the
+// given message. The order of the errors is such that the outermost
+// matching error (the most recent wrap) is index zero, and so on.
+func GetAll(err error, msg string) []error {
+ var result []error
+
+ Walk(err, func(err error) {
+ if err.Error() == msg {
+ result = append(result, err)
+ }
+ })
+
+ return result
+}
+
+// GetAllType gets all the errors that are the same type as v.
+//
+// The order of the return value is the same as described in GetAll.
+func GetAllType(err error, v interface{}) []error {
+ var result []error
+
+ var search string
+ if v != nil {
+ search = reflect.TypeOf(v).String()
+ }
+ Walk(err, func(err error) {
+ var needle string
+ if err != nil {
+ needle = reflect.TypeOf(err).String()
+ }
+
+ if needle == search {
+ result = append(result, err)
+ }
+ })
+
+ return result
+}
+
+// Walk walks all the wrapped errors in err and calls the callback. If
+// err isn't a wrapped error, this will be called once for err. If err
+// is a wrapped error, the callback will be called for both the wrapper
+// that implements error as well as the wrapped error itself.
+func Walk(err error, cb WalkFunc) {
+ if err == nil {
+ return
+ }
+
+ switch e := err.(type) {
+ case *wrappedError:
+ cb(e.Outer)
+ Walk(e.Inner, cb)
+ case Wrapper:
+ cb(err)
+
+ for _, err := range e.WrappedErrors() {
+ Walk(err, cb)
+ }
+ case interface{ Unwrap() error }:
+ cb(err)
+ Walk(e.Unwrap(), cb)
+ default:
+ cb(err)
+ }
+}
+
+// wrappedError is an implementation of error that has both the
+// outer and inner errors.
+type wrappedError struct {
+ Outer error
+ Inner error
+}
+
+func (w *wrappedError) Error() string {
+ return w.Outer.Error()
+}
+
+func (w *wrappedError) WrappedErrors() []error {
+ return []error{w.Outer, w.Inner}
+}
+
+func (w *wrappedError) Unwrap() error {
+ return w.Inner
+}
diff --git a/vendor/github.com/hashicorp/go-multierror/LICENSE b/vendor/github.com/hashicorp/go-multierror/LICENSE
new file mode 100644
index 0000000..82b4de9
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-multierror/LICENSE
@@ -0,0 +1,353 @@
+Mozilla Public License, version 2.0
+
+1. Definitions
+
+1.1. “Contributor”
+
+ means each individual or legal entity that creates, contributes to the
+ creation of, or owns Covered Software.
+
+1.2. “Contributor Version”
+
+ means the combination of the Contributions of others (if any) used by a
+ Contributor and that particular Contributor’s Contribution.
+
+1.3. “Contribution”
+
+ means Covered Software of a particular Contributor.
+
+1.4. “Covered Software”
+
+ means Source Code Form to which the initial Contributor has attached the
+ notice in Exhibit A, the Executable Form of such Source Code Form, and
+ Modifications of such Source Code Form, in each case including portions
+ thereof.
+
+1.5. “Incompatible With Secondary Licenses”
+ means
+
+ a. that the initial Contributor has attached the notice described in
+ Exhibit B to the Covered Software; or
+
+ b. that the Covered Software was made available under the terms of version
+ 1.1 or earlier of the License, but not also under the terms of a
+ Secondary License.
+
+1.6. “Executable Form”
+
+ means any form of the work other than Source Code Form.
+
+1.7. “Larger Work”
+
+ means a work that combines Covered Software with other material, in a separate
+ file or files, that is not Covered Software.
+
+1.8. “License”
+
+ means this document.
+
+1.9. “Licensable”
+
+ means having the right to grant, to the maximum extent possible, whether at the
+ time of the initial grant or subsequently, any and all of the rights conveyed by
+ this License.
+
+1.10. “Modifications”
+
+ means any of the following:
+
+ a. any file in Source Code Form that results from an addition to, deletion
+ from, or modification of the contents of Covered Software; or
+
+ b. any new file in Source Code Form that contains any Covered Software.
+
+1.11. “Patent Claims” of a Contributor
+
+ means any patent claim(s), including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by such Contributor that
+ would be infringed, but for the grant of the License, by the making,
+ using, selling, offering for sale, having made, import, or transfer of
+ either its Contributions or its Contributor Version.
+
+1.12. “Secondary License”
+
+ means either the GNU General Public License, Version 2.0, the GNU Lesser
+ General Public License, Version 2.1, the GNU Affero General Public
+ License, Version 3.0, or any later versions of those licenses.
+
+1.13. “Source Code Form”
+
+ means the form of the work preferred for making modifications.
+
+1.14. “You” (or “Your”)
+
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, “You” includes any entity that controls, is
+ controlled by, or is under common control with You. For purposes of this
+ definition, “control” means (a) the power, direct or indirect, to cause
+ the direction or management of such entity, whether by contract or
+ otherwise, or (b) ownership of more than fifty percent (50%) of the
+ outstanding shares or beneficial ownership of such entity.
+
+
+2. License Grants and Conditions
+
+2.1. Grants
+
+ Each Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ a. under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or as
+ part of a Larger Work; and
+
+ b. under Patent Claims of such Contributor to make, use, sell, offer for
+ sale, have made, import, and otherwise transfer either its Contributions
+ or its Contributor Version.
+
+2.2. Effective Date
+
+ The licenses granted in Section 2.1 with respect to any Contribution become
+ effective for each Contribution on the date the Contributor first distributes
+ such Contribution.
+
+2.3. Limitations on Grant Scope
+
+ The licenses granted in this Section 2 are the only rights granted under this
+ License. No additional rights or licenses will be implied from the distribution
+ or licensing of Covered Software under this License. Notwithstanding Section
+ 2.1(b) above, no patent license is granted by a Contributor:
+
+ a. for any code that a Contributor has removed from Covered Software; or
+
+ b. for infringements caused by: (i) Your and any other third party’s
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+ c. under Patent Claims infringed by Covered Software in the absence of its
+ Contributions.
+
+ This License does not grant any rights in the trademarks, service marks, or
+ logos of any Contributor (except as may be necessary to comply with the
+ notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+ No Contributor makes additional grants as a result of Your choice to
+ distribute the Covered Software under a subsequent version of this License
+ (see Section 10.2) or under the terms of a Secondary License (if permitted
+ under the terms of Section 3.3).
+
+2.5. Representation
+
+ Each Contributor represents that the Contributor believes its Contributions
+ are its original creation(s) or it has sufficient rights to grant the
+ rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+ This License is not intended to limit any rights You have under applicable
+ copyright doctrines of fair use, fair dealing, or other equivalents.
+
+2.7. Conditions
+
+ Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
+ Section 2.1.
+
+
+3. Responsibilities
+
+3.1. Distribution of Source Form
+
+ All distribution of Covered Software in Source Code Form, including any
+ Modifications that You create or to which You contribute, must be under the
+ terms of this License. You must inform recipients that the Source Code Form
+ of the Covered Software is governed by the terms of this License, and how
+ they can obtain a copy of this License. You may not attempt to alter or
+ restrict the recipients’ rights in the Source Code Form.
+
+3.2. Distribution of Executable Form
+
+ If You distribute Covered Software in Executable Form then:
+
+ a. such Covered Software must also be made available in Source Code Form,
+ as described in Section 3.1, and You must inform recipients of the
+ Executable Form how they can obtain a copy of such Source Code Form by
+ reasonable means in a timely manner, at a charge no more than the cost
+ of distribution to the recipient; and
+
+ b. You may distribute such Executable Form under the terms of this License,
+ or sublicense it under different terms, provided that the license for
+ the Executable Form does not attempt to limit or alter the recipients’
+ rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+ You may create and distribute a Larger Work under terms of Your choice,
+ provided that You also comply with the requirements of this License for the
+ Covered Software. If the Larger Work is a combination of Covered Software
+ with a work governed by one or more Secondary Licenses, and the Covered
+ Software is not Incompatible With Secondary Licenses, this License permits
+ You to additionally distribute such Covered Software under the terms of
+ such Secondary License(s), so that the recipient of the Larger Work may, at
+ their option, further distribute the Covered Software under the terms of
+ either this License or such Secondary License(s).
+
+3.4. Notices
+
+ You may not remove or alter the substance of any license notices (including
+ copyright notices, patent notices, disclaimers of warranty, or limitations
+ of liability) contained within the Source Code Form of the Covered
+ Software, except that You may alter any license notices to the extent
+ required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+ You may choose to offer, and to charge a fee for, warranty, support,
+ indemnity or liability obligations to one or more recipients of Covered
+ Software. However, You may do so only on Your own behalf, and not on behalf
+ of any Contributor. You must make it absolutely clear that any such
+ warranty, support, indemnity, or liability obligation is offered by You
+ alone, and You hereby agree to indemnify every Contributor for any
+ liability incurred by such Contributor as a result of warranty, support,
+ indemnity or liability terms You offer. You may include additional
+ disclaimers of warranty and limitations of liability specific to any
+ jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+ If it is impossible for You to comply with any of the terms of this License
+ with respect to some or all of the Covered Software due to statute, judicial
+ order, or regulation then You must: (a) comply with the terms of this License
+ to the maximum extent possible; and (b) describe the limitations and the code
+ they affect. Such description must be placed in a text file included with all
+ distributions of the Covered Software under this License. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Termination
+
+5.1. The rights granted under this License will terminate automatically if You
+ fail to comply with any of its terms. However, if You become compliant,
+ then the rights granted under this License from a particular Contributor
+ are reinstated (a) provisionally, unless and until such Contributor
+ explicitly and finally terminates Your grants, and (b) on an ongoing basis,
+ if such Contributor fails to notify You of the non-compliance by some
+ reasonable means prior to 60 days after You have come back into compliance.
+ Moreover, Your grants from a particular Contributor are reinstated on an
+ ongoing basis if such Contributor notifies You of the non-compliance by
+ some reasonable means, this is the first time You have received notice of
+ non-compliance with this License from such Contributor, and You become
+ compliant prior to 30 days after Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+ infringement claim (excluding declaratory judgment actions, counter-claims,
+ and cross-claims) alleging that a Contributor Version directly or
+ indirectly infringes any patent, then the rights granted to You by any and
+ all Contributors for the Covered Software under Section 2.1 of this License
+ shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
+ license agreements (excluding distributors and resellers) which have been
+ validly granted by You or Your distributors under this License prior to
+ termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+ Covered Software is provided under this License on an “as is” basis, without
+ warranty of any kind, either expressed, implied, or statutory, including,
+ without limitation, warranties that the Covered Software is free of defects,
+ merchantable, fit for a particular purpose or non-infringing. The entire
+ risk as to the quality and performance of the Covered Software is with You.
+ Should any Covered Software prove defective in any respect, You (not any
+ Contributor) assume the cost of any necessary servicing, repair, or
+ correction. This disclaimer of warranty constitutes an essential part of this
+ License. No use of any Covered Software is authorized under this License
+ except under this disclaimer.
+
+7. Limitation of Liability
+
+ Under no circumstances and under no legal theory, whether tort (including
+ negligence), contract, or otherwise, shall any Contributor, or anyone who
+ distributes Covered Software as permitted above, be liable to You for any
+ direct, indirect, special, incidental, or consequential damages of any
+ character including, without limitation, damages for lost profits, loss of
+ goodwill, work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses, even if such party shall have been
+ informed of the possibility of such damages. This limitation of liability
+ shall not apply to liability for death or personal injury resulting from such
+ party’s negligence to the extent applicable law prohibits such limitation.
+ Some jurisdictions do not allow the exclusion or limitation of incidental or
+ consequential damages, so this exclusion and limitation may not apply to You.
+
+8. Litigation
+
+ Any litigation relating to this License may be brought only in the courts of
+ a jurisdiction where the defendant maintains its principal place of business
+ and such litigation shall be governed by laws of that jurisdiction, without
+ reference to its conflict-of-law provisions. Nothing in this Section shall
+ prevent a party’s ability to bring cross-claims or counter-claims.
+
+9. Miscellaneous
+
+ This License represents the complete agreement concerning the subject matter
+ hereof. If any provision of this License is held to be unenforceable, such
+ provision shall be reformed only to the extent necessary to make it
+ enforceable. Any law or regulation which provides that the language of a
+ contract shall be construed against the drafter shall not be used to construe
+ this License against a Contributor.
+
+
+10. Versions of the License
+
+10.1. New Versions
+
+ Mozilla Foundation is the license steward. Except as provided in Section
+ 10.3, no one other than the license steward has the right to modify or
+ publish new versions of this License. Each version will be given a
+ distinguishing version number.
+
+10.2. Effect of New Versions
+
+ You may distribute the Covered Software under the terms of the version of
+ the License under which You originally received the Covered Software, or
+ under the terms of any subsequent version published by the license
+ steward.
+
+10.3. Modified Versions
+
+ If you create software not governed by this License, and you want to
+ create a new license for such software, you may create and use a modified
+ version of this License if you rename the license and remove any
+ references to the name of the license steward (except to note that such
+ modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
+ If You choose to distribute Source Code Form that is Incompatible With
+ Secondary Licenses under the terms of this version of the License, the
+ notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+
+ This Source Code Form is subject to the
+ terms of the Mozilla Public License, v.
+ 2.0. If a copy of the MPL was not
+ distributed with this file, You can
+ obtain one at
+ http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular file, then
+You may include the notice in a location (such as a LICENSE file in a relevant
+directory) where a recipient would be likely to look for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - “Incompatible With Secondary Licenses” Notice
+
+ This Source Code Form is “Incompatible
+ With Secondary Licenses”, as defined by
+ the Mozilla Public License, v. 2.0.
diff --git a/vendor/github.com/hashicorp/go-multierror/Makefile b/vendor/github.com/hashicorp/go-multierror/Makefile
new file mode 100644
index 0000000..b97cd6e
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-multierror/Makefile
@@ -0,0 +1,31 @@
+TEST?=./...
+
+default: test
+
+# test runs the test suite and vets the code.
+test: generate
+ @echo "==> Running tests..."
+ @go list $(TEST) \
+ | grep -v "/vendor/" \
+ | xargs -n1 go test -timeout=60s -parallel=10 ${TESTARGS}
+
+# testrace runs the race checker
+testrace: generate
+ @echo "==> Running tests (race)..."
+ @go list $(TEST) \
+ | grep -v "/vendor/" \
+ | xargs -n1 go test -timeout=60s -race ${TESTARGS}
+
+# updatedeps installs all the dependencies needed to run and build.
+updatedeps:
+ @sh -c "'${CURDIR}/scripts/deps.sh' '${NAME}'"
+
+# generate runs `go generate` to build the dynamically generated source files.
+generate:
+ @echo "==> Generating..."
+ @find . -type f -name '.DS_Store' -delete
+ @go list ./... \
+ | grep -v "/vendor/" \
+ | xargs -n1 go generate
+
+.PHONY: default test testrace updatedeps generate
diff --git a/vendor/github.com/hashicorp/go-multierror/README.md b/vendor/github.com/hashicorp/go-multierror/README.md
new file mode 100644
index 0000000..71dd308
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-multierror/README.md
@@ -0,0 +1,150 @@
+# go-multierror
+
+[](https://circleci.com/gh/hashicorp/go-multierror)
+[](https://pkg.go.dev/github.com/hashicorp/go-multierror)
+
+
+[circleci]: https://app.circleci.com/pipelines/github/hashicorp/go-multierror
+[godocs]: https://pkg.go.dev/github.com/hashicorp/go-multierror
+
+`go-multierror` is a package for Go that provides a mechanism for
+representing a list of `error` values as a single `error`.
+
+This allows a function in Go to return an `error` that might actually
+be a list of errors. If the caller knows this, they can unwrap the
+list and access the errors. If the caller doesn't know, the error
+formats to a nice human-readable format.
+
+`go-multierror` is fully compatible with the Go standard library
+[errors](https://golang.org/pkg/errors/) package, including the
+functions `As`, `Is`, and `Unwrap`. This provides a standardized approach
+for introspecting on error values.
+
+## Installation and Docs
+
+Install using `go get github.com/hashicorp/go-multierror`.
+
+Full documentation is available at
+https://pkg.go.dev/github.com/hashicorp/go-multierror
+
+### Requires go version 1.13 or newer
+
+`go-multierror` requires go version 1.13 or newer. Go 1.13 introduced
+[error wrapping](https://golang.org/doc/go1.13#error_wrapping), which
+this library takes advantage of.
+
+If you need to use an earlier version of go, you can use the
+[v1.0.0](https://github.com/hashicorp/go-multierror/tree/v1.0.0)
+tag, which doesn't rely on features in go 1.13.
+
+If you see compile errors that look like the below, it's likely that
+you're on an older version of go:
+
+```
+/go/src/github.com/hashicorp/go-multierror/multierror.go:112:9: undefined: errors.As
+/go/src/github.com/hashicorp/go-multierror/multierror.go:117:9: undefined: errors.Is
+```
+
+## Usage
+
+go-multierror is easy to use and purposely built to be unobtrusive in
+existing Go applications/libraries that may not be aware of it.
+
+**Building a list of errors**
+
+The `Append` function is used to create a list of errors. This function
+behaves a lot like the Go built-in `append` function: it doesn't matter
+if the first argument is nil, a `multierror.Error`, or any other `error`,
+the function behaves as you would expect.
+
+```go
+var result error
+
+if err := step1(); err != nil {
+ result = multierror.Append(result, err)
+}
+if err := step2(); err != nil {
+ result = multierror.Append(result, err)
+}
+
+return result
+```
+
+**Customizing the formatting of the errors**
+
+By specifying a custom `ErrorFormat`, you can customize the format
+of the `Error() string` function:
+
+```go
+var result *multierror.Error
+
+// ... accumulate errors here, maybe using Append
+
+if result != nil {
+ result.ErrorFormat = func([]error) string {
+ return "errors!"
+ }
+}
+```
+
+**Accessing the list of errors**
+
+`multierror.Error` implements `error` so if the caller doesn't know about
+multierror, it will work just fine. But if you're aware a multierror might
+be returned, you can use type switches to access the list of errors:
+
+```go
+if err := something(); err != nil {
+ if merr, ok := err.(*multierror.Error); ok {
+ // Use merr.Errors
+ }
+}
+```
+
+You can also use the standard [`errors.Unwrap`](https://golang.org/pkg/errors/#Unwrap)
+function. This will continue to unwrap into subsequent errors until none exist.
+
+**Extracting an error**
+
+The standard library [`errors.As`](https://golang.org/pkg/errors/#As)
+function can be used directly with a multierror to extract a specific error:
+
+```go
+// Assume err is a multierror value
+err := somefunc()
+
+// We want to know if "err" has a "RichErrorType" in it and extract it.
+var errRich RichErrorType
+if errors.As(err, &errRich) {
+ // It has it, and now errRich is populated.
+}
+```
+
+**Checking for an exact error value**
+
+Some errors are returned as exact errors such as the [`ErrNotExist`](https://golang.org/pkg/os/#pkg-variables)
+error in the `os` package. You can check if this error is present by using
+the standard [`errors.Is`](https://golang.org/pkg/errors/#Is) function.
+
+```go
+// Assume err is a multierror value
+err := somefunc()
+if errors.Is(err, os.ErrNotExist) {
+ // err contains os.ErrNotExist
+}
+```
+
+**Returning a multierror only if there are errors**
+
+If you build a `multierror.Error`, you can use the `ErrorOrNil` function
+to return an `error` implementation only if there are errors to return:
+
+```go
+var result *multierror.Error
+
+// ... accumulate errors here
+
+// Return the `error` only if errors were added to the multierror, otherwise
+// return nil since there are no errors.
+return result.ErrorOrNil()
+```
diff --git a/vendor/github.com/hashicorp/go-multierror/append.go b/vendor/github.com/hashicorp/go-multierror/append.go
new file mode 100644
index 0000000..3e2589b
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-multierror/append.go
@@ -0,0 +1,43 @@
+package multierror
+
+// Append is a helper function that will append more errors
+// onto an Error in order to create a larger multi-error.
+//
+// If err is not a multierror.Error, then it will be turned into
+// one. If any of the errs are multierr.Error, they will be flattened
+// one level into err.
+// Any nil errors within errs will be ignored. If err is nil, a new
+// *Error will be returned.
+func Append(err error, errs ...error) *Error {
+ switch err := err.(type) {
+ case *Error:
+ // Typed nils can reach here, so initialize if we are nil
+ if err == nil {
+ err = new(Error)
+ }
+
+ // Go through each error and flatten
+ for _, e := range errs {
+ switch e := e.(type) {
+ case *Error:
+ if e != nil {
+ err.Errors = append(err.Errors, e.Errors...)
+ }
+ default:
+ if e != nil {
+ err.Errors = append(err.Errors, e)
+ }
+ }
+ }
+
+ return err
+ default:
+ newErrs := make([]error, 0, len(errs)+1)
+ if err != nil {
+ newErrs = append(newErrs, err)
+ }
+ newErrs = append(newErrs, errs...)
+
+ return Append(&Error{}, newErrs...)
+ }
+}
diff --git a/vendor/github.com/hashicorp/go-multierror/flatten.go b/vendor/github.com/hashicorp/go-multierror/flatten.go
new file mode 100644
index 0000000..aab8e9a
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-multierror/flatten.go
@@ -0,0 +1,26 @@
+package multierror
+
+// Flatten flattens the given error, merging any *Errors together into
+// a single *Error.
+func Flatten(err error) error {
+ // If it isn't an *Error, just return the error as-is
+ if _, ok := err.(*Error); !ok {
+ return err
+ }
+
+ // Otherwise, make the result and flatten away!
+ flatErr := new(Error)
+ flatten(err, flatErr)
+ return flatErr
+}
+
+func flatten(err error, flatErr *Error) {
+ switch err := err.(type) {
+ case *Error:
+ for _, e := range err.Errors {
+ flatten(e, flatErr)
+ }
+ default:
+ flatErr.Errors = append(flatErr.Errors, err)
+ }
+}
diff --git a/vendor/github.com/hashicorp/go-multierror/format.go b/vendor/github.com/hashicorp/go-multierror/format.go
new file mode 100644
index 0000000..47f13c4
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-multierror/format.go
@@ -0,0 +1,27 @@
+package multierror
+
+import (
+ "fmt"
+ "strings"
+)
+
+// ErrorFormatFunc is a function callback that is called by Error to
+// turn the list of errors into a string.
+type ErrorFormatFunc func([]error) string
+
+// ListFormatFunc is a basic formatter that outputs the number of errors
+// that occurred along with a bullet point list of the errors.
+func ListFormatFunc(es []error) string {
+ if len(es) == 1 {
+ return fmt.Sprintf("1 error occurred:\n\t* %s\n\n", es[0])
+ }
+
+ points := make([]string, len(es))
+ for i, err := range es {
+ points[i] = fmt.Sprintf("* %s", err)
+ }
+
+ return fmt.Sprintf(
+ "%d errors occurred:\n\t%s\n\n",
+ len(es), strings.Join(points, "\n\t"))
+}
diff --git a/vendor/github.com/hashicorp/go-multierror/group.go b/vendor/github.com/hashicorp/go-multierror/group.go
new file mode 100644
index 0000000..9c29efb
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-multierror/group.go
@@ -0,0 +1,38 @@
+package multierror
+
+import "sync"
+
+// Group is a collection of goroutines which return errors that need to be
+// coalesced.
+type Group struct {
+ mutex sync.Mutex
+ err *Error
+ wg sync.WaitGroup
+}
+
+// Go calls the given function in a new goroutine.
+//
+// If the function returns an error it is added to the group multierror which
+// is returned by Wait.
+func (g *Group) Go(f func() error) {
+ g.wg.Add(1)
+
+ go func() {
+ defer g.wg.Done()
+
+ if err := f(); err != nil {
+ g.mutex.Lock()
+ g.err = Append(g.err, err)
+ g.mutex.Unlock()
+ }
+ }()
+}
+
+// Wait blocks until all function calls from the Go method have returned, then
+// returns the multierror.
+func (g *Group) Wait() *Error {
+ g.wg.Wait()
+ g.mutex.Lock()
+ defer g.mutex.Unlock()
+ return g.err
+}
diff --git a/vendor/github.com/hashicorp/go-multierror/multierror.go b/vendor/github.com/hashicorp/go-multierror/multierror.go
new file mode 100644
index 0000000..f545743
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-multierror/multierror.go
@@ -0,0 +1,121 @@
+package multierror
+
+import (
+ "errors"
+ "fmt"
+)
+
+// Error is an error type to track multiple errors. This is used to
+// accumulate errors in cases and return them as a single "error".
+type Error struct {
+ Errors []error
+ ErrorFormat ErrorFormatFunc
+}
+
+func (e *Error) Error() string {
+ fn := e.ErrorFormat
+ if fn == nil {
+ fn = ListFormatFunc
+ }
+
+ return fn(e.Errors)
+}
+
+// ErrorOrNil returns an error interface if this Error represents
+// a list of errors, or returns nil if the list of errors is empty. This
+// function is useful at the end of accumulation to make sure that the value
+// returned represents the existence of errors.
+func (e *Error) ErrorOrNil() error {
+ if e == nil {
+ return nil
+ }
+ if len(e.Errors) == 0 {
+ return nil
+ }
+
+ return e
+}
+
+func (e *Error) GoString() string {
+ return fmt.Sprintf("*%#v", *e)
+}
+
+// WrappedErrors returns the list of errors that this Error is wrapping. It is
+// an implementation of the errwrap.Wrapper interface so that multierror.Error
+// can be used with that library.
+//
+// This method is not safe to be called concurrently. Unlike accessing the
+// Errors field directly, this function also checks if the multierror is nil to
+// prevent a null-pointer panic. It satisfies the errwrap.Wrapper interface.
+func (e *Error) WrappedErrors() []error {
+ if e == nil {
+ return nil
+ }
+ return e.Errors
+}
+
+// Unwrap returns an error from Error (or nil if there are no errors).
+// This error returned will further support Unwrap to get the next error,
+// etc. The order will match the order of Errors in the multierror.Error
+// at the time of calling.
+//
+// The resulting error supports errors.As/Is/Unwrap so you can continue
+// to use the stdlib errors package to introspect further.
+//
+// This will perform a shallow copy of the errors slice. Any errors appended
+// to this error after calling Unwrap will not be available until a new
+// Unwrap is called on the multierror.Error.
+func (e *Error) Unwrap() error {
+ // If we have no errors then we do nothing
+ if e == nil || len(e.Errors) == 0 {
+ return nil
+ }
+
+ // If we have exactly one error, we can just return that directly.
+ if len(e.Errors) == 1 {
+ return e.Errors[0]
+ }
+
+ // Shallow copy the slice
+ errs := make([]error, len(e.Errors))
+ copy(errs, e.Errors)
+ return chain(errs)
+}
+
+// chain implements the interfaces necessary for errors.Is/As/Unwrap to
+// work in a deterministic way with multierror. A chain tracks a list of
+// errors while accounting for the current represented error. This lets
+// Is/As be meaningful.
+//
+// Unwrap returns the next error. In the cleanest form, Unwrap would return
+// the wrapped error here but we can't do that if we want to properly
+// get access to all the errors. Instead, users are recommended to use
+// Is/As to get the correct error type out.
+//
+// Precondition: []error is non-empty (len > 0)
+type chain []error
+
+// Error implements the error interface
+func (e chain) Error() string {
+ return e[0].Error()
+}
+
+// Unwrap implements errors.Unwrap by returning the next error in the
+// chain or nil if there are no more errors.
+func (e chain) Unwrap() error {
+ if len(e) == 1 {
+ return nil
+ }
+
+ return e[1:]
+}
+
+// As implements errors.As by attempting to map to the current value.
+func (e chain) As(target interface{}) bool {
+ return errors.As(e[0], target)
+}
+
+// Is implements errors.Is by comparing the current value directly.
+func (e chain) Is(target error) bool {
+ return errors.Is(e[0], target)
+}
diff --git a/vendor/github.com/hashicorp/go-multierror/prefix.go b/vendor/github.com/hashicorp/go-multierror/prefix.go
new file mode 100644
index 0000000..5c477ab
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-multierror/prefix.go
@@ -0,0 +1,37 @@
+package multierror
+
+import (
+ "fmt"
+
+ "github.com/hashicorp/errwrap"
+)
+
+// Prefix is a helper function that will prefix some text
+// to the given error. If the error is a multierror.Error, then
+// it will be prefixed to each wrapped error.
+//
+// This is useful to use when appending multiple multierrors
+// together in order to give better scoping.
+func Prefix(err error, prefix string) error {
+ if err == nil {
+ return nil
+ }
+
+ format := fmt.Sprintf("%s {{err}}", prefix)
+ switch err := err.(type) {
+ case *Error:
+ // Typed nils can reach here, so initialize if we are nil
+ if err == nil {
+ err = new(Error)
+ }
+
+ // Wrap each of the errors
+ for i, e := range err.Errors {
+ err.Errors[i] = errwrap.Wrapf(format, e)
+ }
+
+ return err
+ default:
+ return errwrap.Wrapf(format, err)
+ }
+}
diff --git a/vendor/github.com/hashicorp/go-multierror/sort.go b/vendor/github.com/hashicorp/go-multierror/sort.go
new file mode 100644
index 0000000..fecb14e
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-multierror/sort.go
@@ -0,0 +1,16 @@
+package multierror
+
+// Len implements sort.Interface function for length
+func (err Error) Len() int {
+ return len(err.Errors)
+}
+
+// Swap implements sort.Interface function for swapping elements
+func (err Error) Swap(i, j int) {
+ err.Errors[i], err.Errors[j] = err.Errors[j], err.Errors[i]
+}
+
+// Less implements sort.Interface function for determining order
+func (err Error) Less(i, j int) bool {
+ return err.Errors[i].Error() < err.Errors[j].Error()
+}
diff --git a/vendor/github.com/patrickmn/go-cache/CONTRIBUTORS b/vendor/github.com/patrickmn/go-cache/CONTRIBUTORS
deleted file mode 100644
index 2b16e99..0000000
--- a/vendor/github.com/patrickmn/go-cache/CONTRIBUTORS
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a list of people who have contributed code to go-cache. They, or their
-employers, are the copyright holders of the contributed code. Contributed code
-is subject to the license restrictions listed in LICENSE (as they were when the
-code was contributed.)
-
-Dustin Sallings
-Jason Mooberry
-Sergey Shepelev
-Alex Edwards
diff --git a/vendor/github.com/patrickmn/go-cache/LICENSE b/vendor/github.com/patrickmn/go-cache/LICENSE
deleted file mode 100644
index db9903c..0000000
--- a/vendor/github.com/patrickmn/go-cache/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2012-2017 Patrick Mylund Nielsen and the go-cache contributors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/vendor/github.com/patrickmn/go-cache/README.md b/vendor/github.com/patrickmn/go-cache/README.md
deleted file mode 100644
index c5789cc..0000000
--- a/vendor/github.com/patrickmn/go-cache/README.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# go-cache
-
-go-cache is an in-memory key:value store/cache similar to memcached that is
-suitable for applications running on a single machine. Its major advantage is
-that, being essentially a thread-safe `map[string]interface{}` with expiration
-times, it doesn't need to serialize or transmit its contents over the network.
-
-Any object can be stored, for a given duration or forever, and the cache can be
-safely used by multiple goroutines.
-
-Although go-cache isn't meant to be used as a persistent datastore, the entire
-cache can be saved to and loaded from a file (using `c.Items()` to retrieve the
-items map to serialize, and `NewFrom()` to create a cache from a deserialized
-one) to recover from downtime quickly. (See the docs for `NewFrom()` for caveats.)
-
-### Installation
-
-`go get github.com/patrickmn/go-cache`
-
-### Usage
-
-```go
-import (
- "fmt"
- "github.com/patrickmn/go-cache"
- "time"
-)
-
-func main() {
- // Create a cache with a default expiration time of 5 minutes, and which
- // purges expired items every 10 minutes
- c := cache.New(5*time.Minute, 10*time.Minute)
-
- // Set the value of the key "foo" to "bar", with the default expiration time
- c.Set("foo", "bar", cache.DefaultExpiration)
-
- // Set the value of the key "baz" to 42, with no expiration time
- // (the item won't be removed until it is re-set, or removed using
- // c.Delete("baz")
- c.Set("baz", 42, cache.NoExpiration)
-
- // Get the string associated with the key "foo" from the cache
- foo, found := c.Get("foo")
- if found {
- fmt.Println(foo)
- }
-
- // Since Go is statically typed, and cache values can be anything, type
- // assertion is needed when values are being passed to functions that don't
- // take arbitrary types, (i.e. interface{}). The simplest way to do this for
- // values which will only be used once--e.g. for passing to another
- // function--is:
- foo, found := c.Get("foo")
- if found {
- MyFunction(foo.(string))
- }
-
- // This gets tedious if the value is used several times in the same function.
- // You might do either of the following instead:
- if x, found := c.Get("foo"); found {
- foo := x.(string)
- // ...
- }
- // or
- var foo string
- if x, found := c.Get("foo"); found {
- foo = x.(string)
- }
- // ...
- // foo can then be passed around freely as a string
-
- // Want performance? Store pointers!
- c.Set("foo", &MyStruct, cache.DefaultExpiration)
- if x, found := c.Get("foo"); found {
- foo := x.(*MyStruct)
- // ...
- }
-}
-```
-
-### Reference
-
-`godoc` or [http://godoc.org/github.com/patrickmn/go-cache](http://godoc.org/github.com/patrickmn/go-cache)
diff --git a/vendor/github.com/patrickmn/go-cache/cache.go b/vendor/github.com/patrickmn/go-cache/cache.go
deleted file mode 100644
index db88d2f..0000000
--- a/vendor/github.com/patrickmn/go-cache/cache.go
+++ /dev/null
@@ -1,1161 +0,0 @@
-package cache
-
-import (
- "encoding/gob"
- "fmt"
- "io"
- "os"
- "runtime"
- "sync"
- "time"
-)
-
-type Item struct {
- Object interface{}
- Expiration int64
-}
-
-// Returns true if the item has expired.
-func (item Item) Expired() bool {
- if item.Expiration == 0 {
- return false
- }
- return time.Now().UnixNano() > item.Expiration
-}
-
-const (
- // For use with functions that take an expiration time.
- NoExpiration time.Duration = -1
- // For use with functions that take an expiration time. Equivalent to
- // passing in the same expiration duration as was given to New() or
- // NewFrom() when the cache was created (e.g. 5 minutes.)
- DefaultExpiration time.Duration = 0
-)
-
-type Cache struct {
- *cache
- // If this is confusing, see the comment at the bottom of New()
-}
-
-type cache struct {
- defaultExpiration time.Duration
- items map[string]Item
- mu sync.RWMutex
- onEvicted func(string, interface{})
- janitor *janitor
-}
-
-// Add an item to the cache, replacing any existing item. If the duration is 0
-// (DefaultExpiration), the cache's default expiration time is used. If it is -1
-// (NoExpiration), the item never expires.
-func (c *cache) Set(k string, x interface{}, d time.Duration) {
- // "Inlining" of set
- var e int64
- if d == DefaultExpiration {
- d = c.defaultExpiration
- }
- if d > 0 {
- e = time.Now().Add(d).UnixNano()
- }
- c.mu.Lock()
- c.items[k] = Item{
- Object: x,
- Expiration: e,
- }
- // TODO: Calls to mu.Unlock are currently not deferred because defer
- // adds ~200 ns (as of go1.)
- c.mu.Unlock()
-}
-
-func (c *cache) set(k string, x interface{}, d time.Duration) {
- var e int64
- if d == DefaultExpiration {
- d = c.defaultExpiration
- }
- if d > 0 {
- e = time.Now().Add(d).UnixNano()
- }
- c.items[k] = Item{
- Object: x,
- Expiration: e,
- }
-}
-
-// Add an item to the cache, replacing any existing item, using the default
-// expiration.
-func (c *cache) SetDefault(k string, x interface{}) {
- c.Set(k, x, DefaultExpiration)
-}
-
-// Add an item to the cache only if an item doesn't already exist for the given
-// key, or if the existing item has expired. Returns an error otherwise.
-func (c *cache) Add(k string, x interface{}, d time.Duration) error {
- c.mu.Lock()
- _, found := c.get(k)
- if found {
- c.mu.Unlock()
- return fmt.Errorf("Item %s already exists", k)
- }
- c.set(k, x, d)
- c.mu.Unlock()
- return nil
-}
-
-// Set a new value for the cache key only if it already exists, and the existing
-// item hasn't expired. Returns an error otherwise.
-func (c *cache) Replace(k string, x interface{}, d time.Duration) error {
- c.mu.Lock()
- _, found := c.get(k)
- if !found {
- c.mu.Unlock()
- return fmt.Errorf("Item %s doesn't exist", k)
- }
- c.set(k, x, d)
- c.mu.Unlock()
- return nil
-}
-
-// Get an item from the cache. Returns the item or nil, and a bool indicating
-// whether the key was found.
-func (c *cache) Get(k string) (interface{}, bool) {
- c.mu.RLock()
- // "Inlining" of get and Expired
- item, found := c.items[k]
- if !found {
- c.mu.RUnlock()
- return nil, false
- }
- if item.Expiration > 0 {
- if time.Now().UnixNano() > item.Expiration {
- c.mu.RUnlock()
- return nil, false
- }
- }
- c.mu.RUnlock()
- return item.Object, true
-}
-
-// GetWithExpiration returns an item and its expiration time from the cache.
-// It returns the item or nil, the expiration time if one is set (if the item
-// never expires a zero value for time.Time is returned), and a bool indicating
-// whether the key was found.
-func (c *cache) GetWithExpiration(k string) (interface{}, time.Time, bool) {
- c.mu.RLock()
- // "Inlining" of get and Expired
- item, found := c.items[k]
- if !found {
- c.mu.RUnlock()
- return nil, time.Time{}, false
- }
-
- if item.Expiration > 0 {
- if time.Now().UnixNano() > item.Expiration {
- c.mu.RUnlock()
- return nil, time.Time{}, false
- }
-
- // Return the item and the expiration time
- c.mu.RUnlock()
- return item.Object, time.Unix(0, item.Expiration), true
- }
-
- // If expiration <= 0 (i.e. no expiration time set) then return the item
- // and a zeroed time.Time
- c.mu.RUnlock()
- return item.Object, time.Time{}, true
-}
-
-func (c *cache) get(k string) (interface{}, bool) {
- item, found := c.items[k]
- if !found {
- return nil, false
- }
- // "Inlining" of Expired
- if item.Expiration > 0 {
- if time.Now().UnixNano() > item.Expiration {
- return nil, false
- }
- }
- return item.Object, true
-}
-
-// Increment an item of type int, int8, int16, int32, int64, uintptr, uint,
-// uint8, uint32, or uint64, float32 or float64 by n. Returns an error if the
-// item's value is not an integer, if it was not found, or if it is not
-// possible to increment it by n. To retrieve the incremented value, use one
-// of the specialized methods, e.g. IncrementInt64.
-func (c *cache) Increment(k string, n int64) error {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return fmt.Errorf("Item %s not found", k)
- }
- switch v.Object.(type) {
- case int:
- v.Object = v.Object.(int) + int(n)
- case int8:
- v.Object = v.Object.(int8) + int8(n)
- case int16:
- v.Object = v.Object.(int16) + int16(n)
- case int32:
- v.Object = v.Object.(int32) + int32(n)
- case int64:
- v.Object = v.Object.(int64) + n
- case uint:
- v.Object = v.Object.(uint) + uint(n)
- case uintptr:
- v.Object = v.Object.(uintptr) + uintptr(n)
- case uint8:
- v.Object = v.Object.(uint8) + uint8(n)
- case uint16:
- v.Object = v.Object.(uint16) + uint16(n)
- case uint32:
- v.Object = v.Object.(uint32) + uint32(n)
- case uint64:
- v.Object = v.Object.(uint64) + uint64(n)
- case float32:
- v.Object = v.Object.(float32) + float32(n)
- case float64:
- v.Object = v.Object.(float64) + float64(n)
- default:
- c.mu.Unlock()
- return fmt.Errorf("The value for %s is not an integer", k)
- }
- c.items[k] = v
- c.mu.Unlock()
- return nil
-}
-
-// Increment an item of type float32 or float64 by n. Returns an error if the
-// item's value is not floating point, if it was not found, or if it is not
-// possible to increment it by n. Pass a negative number to decrement the
-// value. To retrieve the incremented value, use one of the specialized methods,
-// e.g. IncrementFloat64.
-func (c *cache) IncrementFloat(k string, n float64) error {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return fmt.Errorf("Item %s not found", k)
- }
- switch v.Object.(type) {
- case float32:
- v.Object = v.Object.(float32) + float32(n)
- case float64:
- v.Object = v.Object.(float64) + n
- default:
- c.mu.Unlock()
- return fmt.Errorf("The value for %s does not have type float32 or float64", k)
- }
- c.items[k] = v
- c.mu.Unlock()
- return nil
-}
-
-// Increment an item of type int by n. Returns an error if the item's value is
-// not an int, or if it was not found. If there is no error, the incremented
-// value is returned.
-func (c *cache) IncrementInt(k string, n int) (int, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(int)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an int", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type int8 by n. Returns an error if the item's value is
-// not an int8, or if it was not found. If there is no error, the incremented
-// value is returned.
-func (c *cache) IncrementInt8(k string, n int8) (int8, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(int8)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an int8", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type int16 by n. Returns an error if the item's value is
-// not an int16, or if it was not found. If there is no error, the incremented
-// value is returned.
-func (c *cache) IncrementInt16(k string, n int16) (int16, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(int16)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an int16", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type int32 by n. Returns an error if the item's value is
-// not an int32, or if it was not found. If there is no error, the incremented
-// value is returned.
-func (c *cache) IncrementInt32(k string, n int32) (int32, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(int32)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an int32", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type int64 by n. Returns an error if the item's value is
-// not an int64, or if it was not found. If there is no error, the incremented
-// value is returned.
-func (c *cache) IncrementInt64(k string, n int64) (int64, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(int64)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an int64", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type uint by n. Returns an error if the item's value is
-// not an uint, or if it was not found. If there is no error, the incremented
-// value is returned.
-func (c *cache) IncrementUint(k string, n uint) (uint, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uint)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uint", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type uintptr by n. Returns an error if the item's value
-// is not an uintptr, or if it was not found. If there is no error, the
-// incremented value is returned.
-func (c *cache) IncrementUintptr(k string, n uintptr) (uintptr, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uintptr)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uintptr", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type uint8 by n. Returns an error if the item's value
-// is not an uint8, or if it was not found. If there is no error, the
-// incremented value is returned.
-func (c *cache) IncrementUint8(k string, n uint8) (uint8, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uint8)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uint8", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type uint16 by n. Returns an error if the item's value
-// is not an uint16, or if it was not found. If there is no error, the
-// incremented value is returned.
-func (c *cache) IncrementUint16(k string, n uint16) (uint16, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uint16)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uint16", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type uint32 by n. Returns an error if the item's value
-// is not an uint32, or if it was not found. If there is no error, the
-// incremented value is returned.
-func (c *cache) IncrementUint32(k string, n uint32) (uint32, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uint32)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uint32", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type uint64 by n. Returns an error if the item's value
-// is not an uint64, or if it was not found. If there is no error, the
-// incremented value is returned.
-func (c *cache) IncrementUint64(k string, n uint64) (uint64, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uint64)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uint64", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type float32 by n. Returns an error if the item's value
-// is not an float32, or if it was not found. If there is no error, the
-// incremented value is returned.
-func (c *cache) IncrementFloat32(k string, n float32) (float32, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(float32)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an float32", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Increment an item of type float64 by n. Returns an error if the item's value
-// is not an float64, or if it was not found. If there is no error, the
-// incremented value is returned.
-func (c *cache) IncrementFloat64(k string, n float64) (float64, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(float64)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an float64", k)
- }
- nv := rv + n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type int, int8, int16, int32, int64, uintptr, uint,
-// uint8, uint32, or uint64, float32 or float64 by n. Returns an error if the
-// item's value is not an integer, if it was not found, or if it is not
-// possible to decrement it by n. To retrieve the decremented value, use one
-// of the specialized methods, e.g. DecrementInt64.
-func (c *cache) Decrement(k string, n int64) error {
- // TODO: Implement Increment and Decrement more cleanly.
- // (Cannot do Increment(k, n*-1) for uints.)
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return fmt.Errorf("Item not found")
- }
- switch v.Object.(type) {
- case int:
- v.Object = v.Object.(int) - int(n)
- case int8:
- v.Object = v.Object.(int8) - int8(n)
- case int16:
- v.Object = v.Object.(int16) - int16(n)
- case int32:
- v.Object = v.Object.(int32) - int32(n)
- case int64:
- v.Object = v.Object.(int64) - n
- case uint:
- v.Object = v.Object.(uint) - uint(n)
- case uintptr:
- v.Object = v.Object.(uintptr) - uintptr(n)
- case uint8:
- v.Object = v.Object.(uint8) - uint8(n)
- case uint16:
- v.Object = v.Object.(uint16) - uint16(n)
- case uint32:
- v.Object = v.Object.(uint32) - uint32(n)
- case uint64:
- v.Object = v.Object.(uint64) - uint64(n)
- case float32:
- v.Object = v.Object.(float32) - float32(n)
- case float64:
- v.Object = v.Object.(float64) - float64(n)
- default:
- c.mu.Unlock()
- return fmt.Errorf("The value for %s is not an integer", k)
- }
- c.items[k] = v
- c.mu.Unlock()
- return nil
-}
-
-// Decrement an item of type float32 or float64 by n. Returns an error if the
-// item's value is not floating point, if it was not found, or if it is not
-// possible to decrement it by n. Pass a negative number to decrement the
-// value. To retrieve the decremented value, use one of the specialized methods,
-// e.g. DecrementFloat64.
-func (c *cache) DecrementFloat(k string, n float64) error {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return fmt.Errorf("Item %s not found", k)
- }
- switch v.Object.(type) {
- case float32:
- v.Object = v.Object.(float32) - float32(n)
- case float64:
- v.Object = v.Object.(float64) - n
- default:
- c.mu.Unlock()
- return fmt.Errorf("The value for %s does not have type float32 or float64", k)
- }
- c.items[k] = v
- c.mu.Unlock()
- return nil
-}
-
-// Decrement an item of type int by n. Returns an error if the item's value is
-// not an int, or if it was not found. If there is no error, the decremented
-// value is returned.
-func (c *cache) DecrementInt(k string, n int) (int, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(int)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an int", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type int8 by n. Returns an error if the item's value is
-// not an int8, or if it was not found. If there is no error, the decremented
-// value is returned.
-func (c *cache) DecrementInt8(k string, n int8) (int8, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(int8)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an int8", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type int16 by n. Returns an error if the item's value is
-// not an int16, or if it was not found. If there is no error, the decremented
-// value is returned.
-func (c *cache) DecrementInt16(k string, n int16) (int16, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(int16)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an int16", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type int32 by n. Returns an error if the item's value is
-// not an int32, or if it was not found. If there is no error, the decremented
-// value is returned.
-func (c *cache) DecrementInt32(k string, n int32) (int32, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(int32)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an int32", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type int64 by n. Returns an error if the item's value is
-// not an int64, or if it was not found. If there is no error, the decremented
-// value is returned.
-func (c *cache) DecrementInt64(k string, n int64) (int64, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(int64)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an int64", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type uint by n. Returns an error if the item's value is
-// not an uint, or if it was not found. If there is no error, the decremented
-// value is returned.
-func (c *cache) DecrementUint(k string, n uint) (uint, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uint)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uint", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type uintptr by n. Returns an error if the item's value
-// is not an uintptr, or if it was not found. If there is no error, the
-// decremented value is returned.
-func (c *cache) DecrementUintptr(k string, n uintptr) (uintptr, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uintptr)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uintptr", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type uint8 by n. Returns an error if the item's value is
-// not an uint8, or if it was not found. If there is no error, the decremented
-// value is returned.
-func (c *cache) DecrementUint8(k string, n uint8) (uint8, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uint8)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uint8", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type uint16 by n. Returns an error if the item's value
-// is not an uint16, or if it was not found. If there is no error, the
-// decremented value is returned.
-func (c *cache) DecrementUint16(k string, n uint16) (uint16, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uint16)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uint16", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type uint32 by n. Returns an error if the item's value
-// is not an uint32, or if it was not found. If there is no error, the
-// decremented value is returned.
-func (c *cache) DecrementUint32(k string, n uint32) (uint32, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uint32)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uint32", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type uint64 by n. Returns an error if the item's value
-// is not an uint64, or if it was not found. If there is no error, the
-// decremented value is returned.
-func (c *cache) DecrementUint64(k string, n uint64) (uint64, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(uint64)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an uint64", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type float32 by n. Returns an error if the item's value
-// is not an float32, or if it was not found. If there is no error, the
-// decremented value is returned.
-func (c *cache) DecrementFloat32(k string, n float32) (float32, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(float32)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an float32", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Decrement an item of type float64 by n. Returns an error if the item's value
-// is not an float64, or if it was not found. If there is no error, the
-// decremented value is returned.
-func (c *cache) DecrementFloat64(k string, n float64) (float64, error) {
- c.mu.Lock()
- v, found := c.items[k]
- if !found || v.Expired() {
- c.mu.Unlock()
- return 0, fmt.Errorf("Item %s not found", k)
- }
- rv, ok := v.Object.(float64)
- if !ok {
- c.mu.Unlock()
- return 0, fmt.Errorf("The value for %s is not an float64", k)
- }
- nv := rv - n
- v.Object = nv
- c.items[k] = v
- c.mu.Unlock()
- return nv, nil
-}
-
-// Delete an item from the cache. Does nothing if the key is not in the cache.
-func (c *cache) Delete(k string) {
- c.mu.Lock()
- v, evicted := c.delete(k)
- c.mu.Unlock()
- if evicted {
- c.onEvicted(k, v)
- }
-}
-
-func (c *cache) delete(k string) (interface{}, bool) {
- if c.onEvicted != nil {
- if v, found := c.items[k]; found {
- delete(c.items, k)
- return v.Object, true
- }
- }
- delete(c.items, k)
- return nil, false
-}
-
-type keyAndValue struct {
- key string
- value interface{}
-}
-
-// Delete all expired items from the cache.
-func (c *cache) DeleteExpired() {
- var evictedItems []keyAndValue
- now := time.Now().UnixNano()
- c.mu.Lock()
- for k, v := range c.items {
- // "Inlining" of expired
- if v.Expiration > 0 && now > v.Expiration {
- ov, evicted := c.delete(k)
- if evicted {
- evictedItems = append(evictedItems, keyAndValue{k, ov})
- }
- }
- }
- c.mu.Unlock()
- for _, v := range evictedItems {
- c.onEvicted(v.key, v.value)
- }
-}
-
-// Sets an (optional) function that is called with the key and value when an
-// item is evicted from the cache. (Including when it is deleted manually, but
-// not when it is overwritten.) Set to nil to disable.
-func (c *cache) OnEvicted(f func(string, interface{})) {
- c.mu.Lock()
- c.onEvicted = f
- c.mu.Unlock()
-}
-
-// Write the cache's items (using Gob) to an io.Writer.
-//
-// NOTE: This method is deprecated in favor of c.Items() and NewFrom() (see the
-// documentation for NewFrom().)
-func (c *cache) Save(w io.Writer) (err error) {
- enc := gob.NewEncoder(w)
- defer func() {
- if x := recover(); x != nil {
- err = fmt.Errorf("Error registering item types with Gob library")
- }
- }()
- c.mu.RLock()
- defer c.mu.RUnlock()
- for _, v := range c.items {
- gob.Register(v.Object)
- }
- err = enc.Encode(&c.items)
- return
-}
-
-// Save the cache's items to the given filename, creating the file if it
-// doesn't exist, and overwriting it if it does.
-//
-// NOTE: This method is deprecated in favor of c.Items() and NewFrom() (see the
-// documentation for NewFrom().)
-func (c *cache) SaveFile(fname string) error {
- fp, err := os.Create(fname)
- if err != nil {
- return err
- }
- err = c.Save(fp)
- if err != nil {
- fp.Close()
- return err
- }
- return fp.Close()
-}
-
-// Add (Gob-serialized) cache items from an io.Reader, excluding any items with
-// keys that already exist (and haven't expired) in the current cache.
-//
-// NOTE: This method is deprecated in favor of c.Items() and NewFrom() (see the
-// documentation for NewFrom().)
-func (c *cache) Load(r io.Reader) error {
- dec := gob.NewDecoder(r)
- items := map[string]Item{}
- err := dec.Decode(&items)
- if err == nil {
- c.mu.Lock()
- defer c.mu.Unlock()
- for k, v := range items {
- ov, found := c.items[k]
- if !found || ov.Expired() {
- c.items[k] = v
- }
- }
- }
- return err
-}
-
-// Load and add cache items from the given filename, excluding any items with
-// keys that already exist in the current cache.
-//
-// NOTE: This method is deprecated in favor of c.Items() and NewFrom() (see the
-// documentation for NewFrom().)
-func (c *cache) LoadFile(fname string) error {
- fp, err := os.Open(fname)
- if err != nil {
- return err
- }
- err = c.Load(fp)
- if err != nil {
- fp.Close()
- return err
- }
- return fp.Close()
-}
-
-// Copies all unexpired items in the cache into a new map and returns it.
-func (c *cache) Items() map[string]Item {
- c.mu.RLock()
- defer c.mu.RUnlock()
- m := make(map[string]Item, len(c.items))
- now := time.Now().UnixNano()
- for k, v := range c.items {
- // "Inlining" of Expired
- if v.Expiration > 0 {
- if now > v.Expiration {
- continue
- }
- }
- m[k] = v
- }
- return m
-}
-
-// Returns the number of items in the cache. This may include items that have
-// expired, but have not yet been cleaned up.
-func (c *cache) ItemCount() int {
- c.mu.RLock()
- n := len(c.items)
- c.mu.RUnlock()
- return n
-}
-
-// Delete all items from the cache.
-func (c *cache) Flush() {
- c.mu.Lock()
- c.items = map[string]Item{}
- c.mu.Unlock()
-}
-
-type janitor struct {
- Interval time.Duration
- stop chan bool
-}
-
-func (j *janitor) Run(c *cache) {
- ticker := time.NewTicker(j.Interval)
- for {
- select {
- case <-ticker.C:
- c.DeleteExpired()
- case <-j.stop:
- ticker.Stop()
- return
- }
- }
-}
-
-func stopJanitor(c *Cache) {
- c.janitor.stop <- true
-}
-
-func runJanitor(c *cache, ci time.Duration) {
- j := &janitor{
- Interval: ci,
- stop: make(chan bool),
- }
- c.janitor = j
- go j.Run(c)
-}
-
-func newCache(de time.Duration, m map[string]Item) *cache {
- if de == 0 {
- de = -1
- }
- c := &cache{
- defaultExpiration: de,
- items: m,
- }
- return c
-}
-
-func newCacheWithJanitor(de time.Duration, ci time.Duration, m map[string]Item) *Cache {
- c := newCache(de, m)
- // This trick ensures that the janitor goroutine (which--granted it
- // was enabled--is running DeleteExpired on c forever) does not keep
- // the returned C object from being garbage collected. When it is
- // garbage collected, the finalizer stops the janitor goroutine, after
- // which c can be collected.
- C := &Cache{c}
- if ci > 0 {
- runJanitor(c, ci)
- runtime.SetFinalizer(C, stopJanitor)
- }
- return C
-}
-
-// Return a new cache with a given default expiration duration and cleanup
-// interval. If the expiration duration is less than one (or NoExpiration),
-// the items in the cache never expire (by default), and must be deleted
-// manually. If the cleanup interval is less than one, expired items are not
-// deleted from the cache before calling c.DeleteExpired().
-func New(defaultExpiration, cleanupInterval time.Duration) *Cache {
- items := make(map[string]Item)
- return newCacheWithJanitor(defaultExpiration, cleanupInterval, items)
-}
-
-// Return a new cache with a given default expiration duration and cleanup
-// interval. If the expiration duration is less than one (or NoExpiration),
-// the items in the cache never expire (by default), and must be deleted
-// manually. If the cleanup interval is less than one, expired items are not
-// deleted from the cache before calling c.DeleteExpired().
-//
-// NewFrom() also accepts an items map which will serve as the underlying map
-// for the cache. This is useful for starting from a deserialized cache
-// (serialized using e.g. gob.Encode() on c.Items()), or passing in e.g.
-// make(map[string]Item, 500) to improve startup performance when the cache
-// is expected to reach a certain minimum size.
-//
-// Only the cache's methods synchronize access to this map, so it is not
-// recommended to keep any references to the map around after creating a cache.
-// If need be, the map can be accessed at a later point using c.Items() (subject
-// to the same caveat.)
-//
-// Note regarding serialization: When using e.g. gob, make sure to
-// gob.Register() the individual types stored in the cache before encoding a
-// map retrieved with c.Items(), and to register those same types before
-// decoding a blob containing an items map.
-func NewFrom(defaultExpiration, cleanupInterval time.Duration, items map[string]Item) *Cache {
- return newCacheWithJanitor(defaultExpiration, cleanupInterval, items)
-}
diff --git a/vendor/github.com/patrickmn/go-cache/sharded.go b/vendor/github.com/patrickmn/go-cache/sharded.go
deleted file mode 100644
index bcc0538..0000000
--- a/vendor/github.com/patrickmn/go-cache/sharded.go
+++ /dev/null
@@ -1,192 +0,0 @@
-package cache
-
-import (
- "crypto/rand"
- "math"
- "math/big"
- insecurerand "math/rand"
- "os"
- "runtime"
- "time"
-)
-
-// This is an experimental and unexported (for now) attempt at making a cache
-// with better algorithmic complexity than the standard one, namely by
-// preventing write locks of the entire cache when an item is added. As of the
-// time of writing, the overhead of selecting buckets results in cache
-// operations being about twice as slow as for the standard cache with small
-// total cache sizes, and faster for larger ones.
-//
-// See cache_test.go for a few benchmarks.
-
-type unexportedShardedCache struct {
- *shardedCache
-}
-
-type shardedCache struct {
- seed uint32
- m uint32
- cs []*cache
- janitor *shardedJanitor
-}
-
-// djb2 with better shuffling. 5x faster than FNV with the hash.Hash overhead.
-func djb33(seed uint32, k string) uint32 {
- var (
- l = uint32(len(k))
- d = 5381 + seed + l
- i = uint32(0)
- )
- // Why is all this 5x faster than a for loop?
- if l >= 4 {
- for i < l-4 {
- d = (d * 33) ^ uint32(k[i])
- d = (d * 33) ^ uint32(k[i+1])
- d = (d * 33) ^ uint32(k[i+2])
- d = (d * 33) ^ uint32(k[i+3])
- i += 4
- }
- }
- switch l - i {
- case 1:
- case 2:
- d = (d * 33) ^ uint32(k[i])
- case 3:
- d = (d * 33) ^ uint32(k[i])
- d = (d * 33) ^ uint32(k[i+1])
- case 4:
- d = (d * 33) ^ uint32(k[i])
- d = (d * 33) ^ uint32(k[i+1])
- d = (d * 33) ^ uint32(k[i+2])
- }
- return d ^ (d >> 16)
-}
-
-func (sc *shardedCache) bucket(k string) *cache {
- return sc.cs[djb33(sc.seed, k)%sc.m]
-}
-
-func (sc *shardedCache) Set(k string, x interface{}, d time.Duration) {
- sc.bucket(k).Set(k, x, d)
-}
-
-func (sc *shardedCache) Add(k string, x interface{}, d time.Duration) error {
- return sc.bucket(k).Add(k, x, d)
-}
-
-func (sc *shardedCache) Replace(k string, x interface{}, d time.Duration) error {
- return sc.bucket(k).Replace(k, x, d)
-}
-
-func (sc *shardedCache) Get(k string) (interface{}, bool) {
- return sc.bucket(k).Get(k)
-}
-
-func (sc *shardedCache) Increment(k string, n int64) error {
- return sc.bucket(k).Increment(k, n)
-}
-
-func (sc *shardedCache) IncrementFloat(k string, n float64) error {
- return sc.bucket(k).IncrementFloat(k, n)
-}
-
-func (sc *shardedCache) Decrement(k string, n int64) error {
- return sc.bucket(k).Decrement(k, n)
-}
-
-func (sc *shardedCache) Delete(k string) {
- sc.bucket(k).Delete(k)
-}
-
-func (sc *shardedCache) DeleteExpired() {
- for _, v := range sc.cs {
- v.DeleteExpired()
- }
-}
-
-// Returns the items in the cache. This may include items that have expired,
-// but have not yet been cleaned up. If this is significant, the Expiration
-// fields of the items should be checked. Note that explicit synchronization
-// is needed to use a cache and its corresponding Items() return values at
-// the same time, as the maps are shared.
-func (sc *shardedCache) Items() []map[string]Item {
- res := make([]map[string]Item, len(sc.cs))
- for i, v := range sc.cs {
- res[i] = v.Items()
- }
- return res
-}
-
-func (sc *shardedCache) Flush() {
- for _, v := range sc.cs {
- v.Flush()
- }
-}
-
-type shardedJanitor struct {
- Interval time.Duration
- stop chan bool
-}
-
-func (j *shardedJanitor) Run(sc *shardedCache) {
- j.stop = make(chan bool)
- tick := time.Tick(j.Interval)
- for {
- select {
- case <-tick:
- sc.DeleteExpired()
- case <-j.stop:
- return
- }
- }
-}
-
-func stopShardedJanitor(sc *unexportedShardedCache) {
- sc.janitor.stop <- true
-}
-
-func runShardedJanitor(sc *shardedCache, ci time.Duration) {
- j := &shardedJanitor{
- Interval: ci,
- }
- sc.janitor = j
- go j.Run(sc)
-}
-
-func newShardedCache(n int, de time.Duration) *shardedCache {
- max := big.NewInt(0).SetUint64(uint64(math.MaxUint32))
- rnd, err := rand.Int(rand.Reader, max)
- var seed uint32
- if err != nil {
- os.Stderr.Write([]byte("WARNING: go-cache's newShardedCache failed to read from the system CSPRNG (/dev/urandom or equivalent.) Your system's security may be compromised. Continuing with an insecure seed.\n"))
- seed = insecurerand.Uint32()
- } else {
- seed = uint32(rnd.Uint64())
- }
- sc := &shardedCache{
- seed: seed,
- m: uint32(n),
- cs: make([]*cache, n),
- }
- for i := 0; i < n; i++ {
- c := &cache{
- defaultExpiration: de,
- items: map[string]Item{},
- }
- sc.cs[i] = c
- }
- return sc
-}
-
-func unexportedNewSharded(defaultExpiration, cleanupInterval time.Duration, shards int) *unexportedShardedCache {
- if defaultExpiration == 0 {
- defaultExpiration = -1
- }
- sc := newShardedCache(shards, defaultExpiration)
- SC := &unexportedShardedCache{sc}
- if cleanupInterval > 0 {
- runShardedJanitor(sc, cleanupInterval)
- runtime.SetFinalizer(SC, stopShardedJanitor)
- }
- return SC
-}
diff --git a/vendor/github.com/pion/dtls/v2/.editorconfig b/vendor/github.com/pion/dtls/v2/.editorconfig
index d2b3206..1dca00f 100644
--- a/vendor/github.com/pion/dtls/v2/.editorconfig
+++ b/vendor/github.com/pion/dtls/v2/.editorconfig
@@ -1,4 +1,6 @@
# http://editorconfig.org/
+# SPDX-FileCopyrightText: 2023 The Pion community
+# SPDX-License-Identifier: MIT
root = true
diff --git a/vendor/github.com/pion/dtls/v2/.gitignore b/vendor/github.com/pion/dtls/v2/.gitignore
index 0e52f2f..6e2f206 100644
--- a/vendor/github.com/pion/dtls/v2/.gitignore
+++ b/vendor/github.com/pion/dtls/v2/.gitignore
@@ -1,2 +1,28 @@
-vendor
-*-fuzz.zip
+# SPDX-FileCopyrightText: 2023 The Pion community
+# SPDX-License-Identifier: MIT
+
+### JetBrains IDE ###
+#####################
+.idea/
+
+### Emacs Temporary Files ###
+#############################
+*~
+
+### Folders ###
+###############
+bin/
+vendor/
+node_modules/
+
+### Files ###
+#############
+*.ivf
+*.ogg
+tags
+cover.out
+*.sw[poe]
+*.wasm
+examples/sfu-ws/cert.pem
+examples/sfu-ws/key.pem
+wasm_exec.js
diff --git a/vendor/github.com/pion/dtls/v2/.golangci.yml b/vendor/github.com/pion/dtls/v2/.golangci.yml
index 077186f..4e3eddf 100644
--- a/vendor/github.com/pion/dtls/v2/.golangci.yml
+++ b/vendor/github.com/pion/dtls/v2/.golangci.yml
@@ -1,36 +1,137 @@
+# SPDX-FileCopyrightText: 2023 The Pion community
+# SPDX-License-Identifier: MIT
+
linters-settings:
govet:
check-shadowing: true
misspell:
locale: US
+ exhaustive:
+ default-signifies-exhaustive: true
+ gomodguard:
+ blocked:
+ modules:
+ - github.com/pkg/errors:
+ recommendations:
+ - errors
+ forbidigo:
+ forbid:
+ - ^fmt.Print(f|ln)?$
+ - ^log.(Panic|Fatal|Print)(f|ln)?$
+ - ^os.Exit$
+ - ^panic$
+ - ^print(ln)?$
linters:
- enable-all: true
+ enable:
+ - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers
+ - bidichk # Checks for dangerous unicode character sequences
+ - bodyclose # checks whether HTTP response body is closed successfully
+ - contextcheck # check the function whether use a non-inherited context
+ - decorder # check declaration order and count of types, constants, variables and functions
+ - depguard # Go linter that checks if package imports are in a list of acceptable packages
+ - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
+ - dupl # Tool for code clone detection
+ - durationcheck # check for two durations multiplied together
+ - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases
+ - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted.
+ - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`.
+ - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
+ - exhaustive # check exhaustiveness of enum switch statements
+ - exportloopref # checks for pointers to enclosing loop variables
+ - forbidigo # Forbids identifiers
+ - forcetypeassert # finds forced type assertions
+ - gci # Gci control golang package import order and make it always deterministic.
+ - gochecknoglobals # Checks that no globals are present in Go code
+ - gochecknoinits # Checks that no init functions are present in Go code
+ - gocognit # Computes and checks the cognitive complexity of functions
+ - goconst # Finds repeated strings that could be replaced by a constant
+ - gocritic # The most opinionated Go source code linter
+ - godox # Tool for detection of FIXME, TODO and other comment keywords
+ - goerr113 # Golang linter to check the errors handling expressions
+ - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification
+ - gofumpt # Gofumpt checks whether code was gofumpt-ed.
+ - goheader # Checks is file header matches to pattern
+ - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports
+ - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod.
+ - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations.
+ - goprintffuncname # Checks that printf-like functions are named with `f` at the end
+ - gosec # Inspects source code for security problems
+ - gosimple # Linter for Go source code that specializes in simplifying a code
+ - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
+ - grouper # An analyzer to analyze expression groups.
+ - importas # Enforces consistent import aliases
+ - ineffassign # Detects when assignments to existing variables are not used
+ - misspell # Finds commonly misspelled English words in comments
+ - nakedret # Finds naked returns in functions greater than a specified function length
+ - nilerr # Finds the code that returns nil even if it checks that the error is not nil.
+ - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value.
+ - noctx # noctx finds sending http request without context.Context
+ - predeclared # find code that shadows one of Go's predeclared identifiers
+ - revive # golint replacement, finds style mistakes
+ - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks
+ - stylecheck # Stylecheck is a replacement for golint
+ - tagliatelle # Checks the struct tags.
+ - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17
+ - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes
+ - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code
+ - unconvert # Remove unnecessary type conversions
+ - unparam # Reports unused function parameters
+ - unused # Checks Go code for unused constants, variables, functions and types
+ - wastedassign # wastedassign finds wasted assignment statements
+ - whitespace # Tool for detection of leading and trailing whitespace
disable:
- - dupl
- - funlen
- - gochecknoglobals
- - gocyclo
- - godox
- - lll
- - maligned
+ - containedctx # containedctx is a linter that detects struct contained context.Context field
+ - cyclop # checks function and package cyclomatic complexity
+ - exhaustivestruct # Checks if all struct's fields are initialized
+ - funlen # Tool for detection of long functions
+ - gocyclo # Computes and checks the cyclomatic complexity of functions
+ - godot # Check if comments end in a period
+ - gomnd # An analyzer to detect magic numbers.
+ - ifshort # Checks that your code uses short syntax for if-statements whenever possible
+ - ireturn # Accept Interfaces, Return Concrete Types
+ - lll # Reports long lines
+ - maintidx # maintidx measures the maintainability index of each function.
+ - makezero # Finds slice declarations with non-zero initial length
+ - maligned # Tool to detect Go structs that would take less memory if their fields were sorted
+ - nestif # Reports deeply nested if statements
+ - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity
+ - nolintlint # Reports ill-formed or insufficient nolint directives
+ - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test
+ - prealloc # Finds slice declarations that could potentially be preallocated
+ - promlinter # Check Prometheus metrics naming via promlint
+ - rowserrcheck # checks whether Err of rows is checked successfully
+ - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed.
+ - testpackage # linter that makes you use a separate _test package
+ - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers
+ - varnamelen # checks that the length of a variable's name matches its scope
+ - wrapcheck # Checks that errors returned from external packages are wrapped
+ - wsl # Whitespace Linter - Forces you to use empty lines!
issues:
exclude-use-default: false
-
exclude-rules:
- - path: pkg/crypto/ccm
- text: "L' should not be capitalized"
+ # Allow complex tests, better to be self contained
+ - path: _test\.go
linters:
- - gocritic
- - path: cipher_suite
- text: "should not use ALL_CAPS in Go names; use CamelCase instead"
+ - gocognit
+ - forbidigo
+
+ # Allow complex main function in examples
+ - path: examples
+ text: "of func `main` is high"
linters:
- - stylecheck
- - path: cipher_suite
- text: "don't use ALL_CAPS in Go names; use CamelCase"
+ - gocognit
+
+ # Allow forbidden identifiers in examples
+ - path: examples
+ linters:
+ - forbidigo
+
+ # Allow forbidden identifiers in CLI commands
+ - path: cmd
linters:
- - golint
+ - forbidigo
run:
skip-dirs-use-default: false
diff --git a/vendor/github.com/pion/dtls/v2/.goreleaser.yml b/vendor/github.com/pion/dtls/v2/.goreleaser.yml
new file mode 100644
index 0000000..30093e9
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/.goreleaser.yml
@@ -0,0 +1,5 @@
+# SPDX-FileCopyrightText: 2023 The Pion community
+# SPDX-License-Identifier: MIT
+
+builds:
+- skip: true
diff --git a/vendor/github.com/pion/dtls/v2/.travis.yml b/vendor/github.com/pion/dtls/v2/.travis.yml
deleted file mode 100644
index e2bb205..0000000
--- a/vendor/github.com/pion/dtls/v2/.travis.yml
+++ /dev/null
@@ -1,128 +0,0 @@
-#
-# DO NOT EDIT THIS FILE DIRECTLY
-#
-# It is automatically copied from https://github.com/pion/.goassets repository.
-# If this repository should have package specific CI config,
-# remove the repository name from .goassets/.github/workflows/assets-sync.yml.
-#
-
-dist: bionic
-language: go
-
-
-branches:
- only:
- - master
-
-env:
- global:
- - GO111MODULE=on
- - GOLANGCI_LINT_VERSION=1.19.1
-
-cache:
- directories:
- - ${HOME}/.cache/go-build
- - ${GOPATH}/pkg/mod
- npm: true
- yarn: true
-
-_lint_job: &lint_job
- env: CACHE_NAME=lint
- before_script:
- - |
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh \
- | bash -s - -b $GOPATH/bin v${GOLANGCI_LINT_VERSION}
- install: skip
- script:
- - bash .github/assert-contributors.sh
- - bash .github/lint-disallowed-functions-in-library.sh
- - bash .github/lint-commit-message.sh
- - bash .github/lint-filename.sh
- - golangci-lint run ./...
-_test_job: &test_job
- env: CACHE_NAME=test
- before_install:
- - go mod download
- install:
- - go build ./...
- script:
- - coverpkgs=$(go list ./... | grep -v examples | paste -s -d ',')
- - |
- go test \
- -coverpkg=${coverpkgs} -coverprofile=cover.out -covermode=atomic \
- -tags quic \
- -v -race ./...
- after_success:
- - travis_retry bash <(curl -s https://codecov.io/bash) -c -F go
-_test_i386_job: &test_i386_job
- env: CACHE_NAME=test386
- language: bash
- services: docker
- script:
- - |
- docker run \
- -u $(id -u):$(id -g) \
- -e "GO111MODULE=on" \
- -e "CGO_ENABLED=0" \
- -v ${PWD}:/go/src/github.com/pion/$(basename ${PWD}) \
- -v ${HOME}/gopath/pkg/mod:/go/pkg/mod \
- -v ${HOME}/.cache/go-build:/.cache/go-build \
- -w /go/src/github.com/pion/$(basename ${PWD}) \
- -it i386/golang:${GO_VERSION}-alpine \
- /usr/local/go/bin/go test \
- -tags quic \
- -v ./...
-_test_wasm_job: &test_wasm_job
- env: CACHE_NAME=wasm
- language: node_js
- node_js: 12
- install:
- # Manually download and install Go instead of using gimme.
- # It looks like gimme Go causes some errors on go-test for Wasm.
- - curl -sSfL https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz | tar -C ~ -xzf -
- - export GOROOT=${HOME}/go
- - export PATH=${GOROOT}/bin:${PATH}
- - yarn install
- - export GO_JS_WASM_EXEC=${GOROOT}/misc/wasm/go_js_wasm_exec
- # If the repository has wasm_exec hook, use it.
- - |
- if [ -f test-wasm/go_js_wasm_exec ]; then
- export GO_JS_WASM_EXEC=${PWD}/test-wasm/go_js_wasm_exec
- fi
- script:
- - testpkgs=$(go list ./... | grep -v examples)
- - coverpkgs=$(go list ./... | grep -v examples | paste -s -d ',')
- - |
- GOOS=js GOARCH=wasm go test \
- -coverpkg=${coverpkgs} -coverprofile=cover.out -covermode=atomic \
- -exec="${GO_JS_WASM_EXEC}" \
- -v ${testpkgs}
- after_success:
- - travis_retry bash <(curl -s https://codecov.io/bash) -c -F wasm
-
-jobs:
- include:
- - <<: *lint_job
- name: Lint 1.14
- go: 1.14
- - <<: *test_job
- name: Test 1.13
- go: 1.13
- - <<: *test_job
- name: Test 1.14
- go: 1.14
- - <<: *test_i386_job
- name: Test i386 1.13
- env: GO_VERSION=1.13
- - <<: *test_i386_job
- name: Test i386 1.14
- env: GO_VERSION=1.14
- - <<: *test_wasm_job
- name: Test WASM 1.13
- env: GO_VERSION=1.13
- - <<: *test_wasm_job
- name: Test WASM 1.14
- env: GO_VERSION=1.14
-
-notifications:
- email: false
diff --git a/vendor/github.com/pion/dtls/v2/AUTHORS.txt b/vendor/github.com/pion/dtls/v2/AUTHORS.txt
new file mode 100644
index 0000000..fbaf977
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/AUTHORS.txt
@@ -0,0 +1,60 @@
+# Thank you to everyone that made Pion possible. If you are interested in contributing
+# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
+#
+# This file is auto generated, using git to list all individuals contributors.
+# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting
+Aleksandr Razumov
+alvarowolfx
+Arlo Breault
+Atsushi Watanabe
+backkem
+bjdgyc
+boks1971
+Bragadeesh
+Carson Hoffman
+Cecylia Bocovich
+Chris Hiszpanski
+cnderrauber
+Daniel Mangum
+Daniele Sluijters
+folbrich
+Hayden James
+Hugo Arregui
+Hugo Arregui
+igolaizola <11333576+igolaizola@users.noreply.github.com>
+Jeffrey Stoke
+Jeroen de Bruijn
+Jeroen de Bruijn
+Jim Wert
+jinleileiking
+Jozef Kralik
+Julien Salleyron
+Juliusz Chroboczek
+Kegan Dougal
+Kevin Wang
+Lander Noterman
+Len
+Lukas Lihotzki
+ManuelBk <26275612+ManuelBk@users.noreply.github.com>
+Michael Zabka
+Michiel De Backker
+Rachel Chen
+Robert Eperjesi
+Ryan Gordon
+Sam Lancia
+Sean
+Sean DuBois
+Sean DuBois
+Sean DuBois
+Sean DuBois
+Shelikhoo
+Stefan Tatschner
+Steffen Vogel
+Vadim
+Vadim Filimonov
+wmiao
+ZHENK
+吕海涛
+
+# List of contributors not appearing in Git history
+
diff --git a/vendor/github.com/pion/dtls/v2/LICENSE b/vendor/github.com/pion/dtls/v2/LICENSE
index ab60297..491caf6 100644
--- a/vendor/github.com/pion/dtls/v2/LICENSE
+++ b/vendor/github.com/pion/dtls/v2/LICENSE
@@ -1,21 +1,9 @@
MIT License
-Copyright (c) 2018
+Copyright (c) 2023 The Pion community
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/pion/dtls/v2/Makefile b/vendor/github.com/pion/dtls/v2/Makefile
deleted file mode 100644
index 1df38b2..0000000
--- a/vendor/github.com/pion/dtls/v2/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-fuzz-build-record-layer: fuzz-prepare
- go-fuzz-build -tags gofuzz -func FuzzRecordLayer
-fuzz-run-record-layer:
- go-fuzz -bin dtls-fuzz.zip -workdir fuzz
-fuzz-prepare:
- @GO111MODULE=on go mod vendor
diff --git a/vendor/github.com/pion/dtls/v2/README.md b/vendor/github.com/pion/dtls/v2/README.md
index 6ce930d..0c06595 100644
--- a/vendor/github.com/pion/dtls/v2/README.md
+++ b/vendor/github.com/pion/dtls/v2/README.md
@@ -9,24 +9,38 @@
-
-
+
+
-
-
+
Native [DTLS 1.2][rfc6347] implementation in the Go programming language.
-A long term goal is a professional security review, and maye inclusion in stdlib.
+A long term goal is a professional security review, and maybe an inclusion in stdlib.
+### RFCs
+#### Implemented
+- **RFC 6347**: [Datagram Transport Layer Security Version 1.2][rfc6347]
+- **RFC 5705**: [Keying Material Exporters for Transport Layer Security (TLS)][rfc5705]
+- **RFC 7627**: [Transport Layer Security (TLS) - Session Hash and Extended Master Secret Extension][rfc7627]
+- **RFC 7301**: [Transport Layer Security (TLS) - Application-Layer Protocol Negotiation Extension][rfc7301]
+
+[rfc5289]: https://tools.ietf.org/html/rfc5289
+[rfc5487]: https://tools.ietf.org/html/rfc5487
+[rfc5489]: https://tools.ietf.org/html/rfc5489
+[rfc5705]: https://tools.ietf.org/html/rfc5705
[rfc6347]: https://tools.ietf.org/html/rfc6347
+[rfc6655]: https://tools.ietf.org/html/rfc6655
+[rfc7301]: https://tools.ietf.org/html/rfc7301
+[rfc7627]: https://tools.ietf.org/html/rfc7627
+[rfc8422]: https://tools.ietf.org/html/rfc8422
### Goals/Progress
This will only be targeting DTLS 1.2, and the most modern/common cipher suites.
-We would love contributes that fall under the 'Planned Features' and fixing any bugs!
+We would love contributions that fall under the 'Planned Features' and any bug fixes!
#### Current features
* DTLS 1.2 Client/Server
@@ -35,29 +49,32 @@ We would love contributes that fall under the 'Planned Features' and fixing any
* Key export ([RFC 5705][rfc5705])
* Serialization and Resumption of sessions
* Extended Master Secret extension ([RFC 7627][rfc7627])
-
-[rfc5705]: https://tools.ietf.org/html/rfc5705
-[rfc7627]: https://tools.ietf.org/html/rfc7627
+* ALPN extension ([RFC 7301][rfc7301])
#### Supported ciphers
##### ECDHE
+
* TLS_ECDHE_ECDSA_WITH_AES_128_CCM ([RFC 6655][rfc6655])
* TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ([RFC 6655][rfc6655])
* TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ([RFC 5289][rfc5289])
* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ([RFC 5289][rfc5289])
+* TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ([RFC 5289][rfc5289])
+* TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ([RFC 5289][rfc5289])
* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ([RFC 8422][rfc8422])
* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ([RFC 8422][rfc8422])
##### PSK
+
* TLS_PSK_WITH_AES_128_CCM ([RFC 6655][rfc6655])
* TLS_PSK_WITH_AES_128_CCM_8 ([RFC 6655][rfc6655])
+* TLS_PSK_WITH_AES_256_CCM_8 ([RFC 6655][rfc6655])
* TLS_PSK_WITH_AES_128_GCM_SHA256 ([RFC 5487][rfc5487])
+* TLS_PSK_WITH_AES_128_CBC_SHA256 ([RFC 5487][rfc5487])
-[rfc5289]: https://tools.ietf.org/html/rfc5289
-[rfc8422]: https://tools.ietf.org/html/rfc8422
-[rfc6655]: https://tools.ietf.org/html/rfc6655
-[rfc5487]: https://tools.ietf.org/html/rfc5487
+##### ECDHE & PSK
+
+* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 ([RFC 5489][rfc5489])
#### Planned Features
* Chacha20Poly1305
@@ -101,7 +118,6 @@ Pion DTLS can connect to itself and OpenSSL.
### Using with PSK
Pion DTLS also comes with examples that do key exchange via PSK
-
#### Pion DTLS
```sh
go run examples/listen/psk/main.go
@@ -120,27 +136,16 @@ go run examples/dial/psk/main.go
openssl s_client -dtls1_2 -connect 127.0.0.1:4444 -psk abc123 -cipher PSK-AES128-CCM8
```
+### Community
+Pion has an active community on the [Slack](https://pion.ly/slack).
+
+Follow the [Pion Twitter](https://twitter.com/_pion) for project updates and important WebRTC news.
+
+We are always looking to support **your projects**. Please reach out if you have something to build!
+If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly)
+
### Contributing
-Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contributing)** to join the group of amazing people making this project possible:
-
-* [Sean DuBois](https://github.com/Sean-Der) - *Original Author*
-* [Michiel De Backker](https://github.com/backkem) - *Public API*
-* [Chris Hiszpanski](https://github.com/thinkski) - *Support Signature Algorithms Extension*
-* [Iñigo Garcia Olaizola](https://github.com/igolaizola) - *Serialization & resumption, cert verification, E2E*
-* [Daniele Sluijters](https://github.com/daenney) - *AES-CCM support*
-* [Jin Lei](https://github.com/jinleileiking) - *Logging*
-* [Hugo Arregui](https://github.com/hugoArregui)
-* [Lander Noterman](https://github.com/LanderN)
-* [Aleksandr Razumov](https://github.com/ernado) - *Fuzzing*
-* [Ryan Gordon](https://github.com/ryangordon)
-* [Stefan Tatschner](https://rumpelsepp.org/contact.html)
-* [Hayden James](https://github.com/hjames9)
-* [Jozef Kralik](https://github.com/jkralik)
-* [Robert Eperjesi](https://github.com/epes)
-* [Atsushi Watanabe](https://github.com/at-wat)
-* [Julien Salleyron](https://github.com/juliens) - *Server Name Indication*
-* [Jeroen de Bruijn](https://github.com/vidavidorra)
-* [bjdgyc](https://github.com/bjdgyc)
+Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt)
### License
MIT License - see [LICENSE](LICENSE) for full text
diff --git a/vendor/github.com/pion/dtls/v2/alert.go b/vendor/github.com/pion/dtls/v2/alert.go
deleted file mode 100644
index b747016..0000000
--- a/vendor/github.com/pion/dtls/v2/alert.go
+++ /dev/null
@@ -1,145 +0,0 @@
-package dtls
-
-import "fmt"
-
-type alertLevel byte
-
-const (
- alertLevelWarning alertLevel = 1
- alertLevelFatal alertLevel = 2
-)
-
-func (a alertLevel) String() string {
- switch a {
- case alertLevelWarning:
- return "LevelWarning"
- case alertLevelFatal:
- return "LevelFatal"
- default:
- return "Invalid alert level"
- }
-}
-
-type alertDescription byte
-
-const (
- alertCloseNotify alertDescription = 0
- alertUnexpectedMessage alertDescription = 10
- alertBadRecordMac alertDescription = 20
- alertDecryptionFailed alertDescription = 21
- alertRecordOverflow alertDescription = 22
- alertDecompressionFailure alertDescription = 30
- alertHandshakeFailure alertDescription = 40
- alertNoCertificate alertDescription = 41
- alertBadCertificate alertDescription = 42
- alertUnsupportedCertificate alertDescription = 43
- alertCertificateRevoked alertDescription = 44
- alertCertificateExpired alertDescription = 45
- alertCertificateUnknown alertDescription = 46
- alertIllegalParameter alertDescription = 47
- alertUnknownCA alertDescription = 48
- alertAccessDenied alertDescription = 49
- alertDecodeError alertDescription = 50
- alertDecryptError alertDescription = 51
- alertExportRestriction alertDescription = 60
- alertProtocolVersion alertDescription = 70
- alertInsufficientSecurity alertDescription = 71
- alertInternalError alertDescription = 80
- alertUserCanceled alertDescription = 90
- alertNoRenegotiation alertDescription = 100
- alertUnsupportedExtension alertDescription = 110
-)
-
-func (a alertDescription) String() string {
- switch a {
- case alertCloseNotify:
- return "CloseNotify"
- case alertUnexpectedMessage:
- return "UnexpectedMessage"
- case alertBadRecordMac:
- return "BadRecordMac"
- case alertDecryptionFailed:
- return "DecryptionFailed"
- case alertRecordOverflow:
- return "RecordOverflow"
- case alertDecompressionFailure:
- return "DecompressionFailure"
- case alertHandshakeFailure:
- return "HandshakeFailure"
- case alertNoCertificate:
- return "NoCertificate"
- case alertBadCertificate:
- return "BadCertificate"
- case alertUnsupportedCertificate:
- return "UnsupportedCertificate"
- case alertCertificateRevoked:
- return "CertificateRevoked"
- case alertCertificateExpired:
- return "CertificateExpired"
- case alertCertificateUnknown:
- return "CertificateUnknown"
- case alertIllegalParameter:
- return "IllegalParameter"
- case alertUnknownCA:
- return "UnknownCA"
- case alertAccessDenied:
- return "AccessDenied"
- case alertDecodeError:
- return "DecodeError"
- case alertDecryptError:
- return "DecryptError"
- case alertExportRestriction:
- return "ExportRestriction"
- case alertProtocolVersion:
- return "ProtocolVersion"
- case alertInsufficientSecurity:
- return "InsufficientSecurity"
- case alertInternalError:
- return "InternalError"
- case alertUserCanceled:
- return "UserCanceled"
- case alertNoRenegotiation:
- return "NoRenegotiation"
- case alertUnsupportedExtension:
- return "UnsupportedExtension"
- default:
- return "Invalid alert description"
- }
-}
-
-// One of the content types supported by the TLS record layer is the
-// alert type. Alert messages convey the severity of the message
-// (warning or fatal) and a description of the alert. Alert messages
-// with a level of fatal result in the immediate termination of the
-// connection. In this case, other connections corresponding to the
-// session may continue, but the session identifier MUST be invalidated,
-// preventing the failed session from being used to establish new
-// connections. Like other messages, alert messages are encrypted and
-// compressed, as specified by the current connection state.
-// https://tools.ietf.org/html/rfc5246#section-7.2
-type alert struct {
- alertLevel alertLevel
- alertDescription alertDescription
-}
-
-func (a alert) contentType() contentType {
- return contentTypeAlert
-}
-
-func (a *alert) Marshal() ([]byte, error) {
- return []byte{byte(a.alertLevel), byte(a.alertDescription)}, nil
-}
-
-func (a *alert) Unmarshal(data []byte) error {
- if len(data) != 2 {
- return errBufferTooSmall
- }
-
- a.alertLevel = alertLevel(data[0])
- a.alertDescription = alertDescription(data[1])
- return nil
-}
-
-func (a *alert) String() string {
- return fmt.Sprintf("Alert %s: %s", a.alertLevel, a.alertDescription)
-}
diff --git a/vendor/github.com/pion/dtls/v2/application_data.go b/vendor/github.com/pion/dtls/v2/application_data.go
deleted file mode 100644
index 679a103..0000000
--- a/vendor/github.com/pion/dtls/v2/application_data.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package dtls
-
-// Application data messages are carried by the record layer and are
-// fragmented, compressed, and encrypted based on the current connection
-// state. The messages are treated as transparent data to the record
-// layer.
-// https://tools.ietf.org/html/rfc5246#section-10
-type applicationData struct {
- data []byte
-}
-
-func (a applicationData) contentType() contentType {
- return contentTypeApplicationData
-}
-
-func (a *applicationData) Marshal() ([]byte, error) {
- return append([]byte{}, a.data...), nil
-}
-
-func (a *applicationData) Unmarshal(data []byte) error {
- a.data = append([]byte{}, data...)
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/certificate.go b/vendor/github.com/pion/dtls/v2/certificate.go
index c99e1c9..519fc87 100644
--- a/vendor/github.com/pion/dtls/v2/certificate.go
+++ b/vendor/github.com/pion/dtls/v2/certificate.go
@@ -1,35 +1,105 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
+ "bytes"
"crypto/tls"
"crypto/x509"
+ "fmt"
"strings"
)
-func (c *handshakeConfig) getCertificate(serverName string) (*tls.Certificate, error) {
- c.mu.Lock()
- defer c.mu.Unlock()
+// ClientHelloInfo contains information from a ClientHello message in order to
+// guide application logic in the GetCertificate.
+type ClientHelloInfo struct {
+ // ServerName indicates the name of the server requested by the client
+ // in order to support virtual hosting. ServerName is only set if the
+ // client is using SNI (see RFC 4366, Section 3.1).
+ ServerName string
- if c.nameToCertificate == nil {
- nameToCertificate := make(map[string]*tls.Certificate)
- for i := range c.localCertificates {
- cert := &c.localCertificates[i]
- x509Cert := cert.Leaf
- if x509Cert == nil {
- var parseErr error
- x509Cert, parseErr = x509.ParseCertificate(cert.Certificate[0])
- if parseErr != nil {
- continue
- }
+ // CipherSuites lists the CipherSuites supported by the client (e.g.
+ // TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).
+ CipherSuites []CipherSuiteID
+}
+
+// CertificateRequestInfo contains information from a server's
+// CertificateRequest message, which is used to demand a certificate and proof
+// of control from a client.
+type CertificateRequestInfo struct {
+ // AcceptableCAs contains zero or more, DER-encoded, X.501
+ // Distinguished Names. These are the names of root or intermediate CAs
+ // that the server wishes the returned certificate to be signed by. An
+ // empty slice indicates that the server has no preference.
+ AcceptableCAs [][]byte
+}
+
+// SupportsCertificate returns nil if the provided certificate is supported by
+// the server that sent the CertificateRequest. Otherwise, it returns an error
+// describing the reason for the incompatibility.
+// NOTE: original src: https://github.com/golang/go/blob/29b9a328d268d53833d2cc063d1d8b4bf6852675/src/crypto/tls/common.go#L1273
+func (cri *CertificateRequestInfo) SupportsCertificate(c *tls.Certificate) error {
+ if len(cri.AcceptableCAs) == 0 {
+ return nil
+ }
+
+ for j, cert := range c.Certificate {
+ x509Cert := c.Leaf
+ // Parse the certificate if this isn't the leaf node, or if
+ // chain.Leaf was nil.
+ if j != 0 || x509Cert == nil {
+ var err error
+ if x509Cert, err = x509.ParseCertificate(cert); err != nil {
+ return fmt.Errorf("failed to parse certificate #%d in the chain: %w", j, err)
}
- if len(x509Cert.Subject.CommonName) > 0 {
- nameToCertificate[strings.ToLower(x509Cert.Subject.CommonName)] = cert
+ }
+
+ for _, ca := range cri.AcceptableCAs {
+ if bytes.Equal(x509Cert.RawIssuer, ca) {
+ return nil
}
- for _, san := range x509Cert.DNSNames {
- nameToCertificate[strings.ToLower(san)] = cert
+ }
+ }
+ return errNotAcceptableCertificateChain
+}
+
+func (c *handshakeConfig) setNameToCertificateLocked() {
+ nameToCertificate := make(map[string]*tls.Certificate)
+ for i := range c.localCertificates {
+ cert := &c.localCertificates[i]
+ x509Cert := cert.Leaf
+ if x509Cert == nil {
+ var parseErr error
+ x509Cert, parseErr = x509.ParseCertificate(cert.Certificate[0])
+ if parseErr != nil {
+ continue
}
}
- c.nameToCertificate = nameToCertificate
+ if len(x509Cert.Subject.CommonName) > 0 {
+ nameToCertificate[strings.ToLower(x509Cert.Subject.CommonName)] = cert
+ }
+ for _, san := range x509Cert.DNSNames {
+ nameToCertificate[strings.ToLower(san)] = cert
+ }
+ }
+ c.nameToCertificate = nameToCertificate
+}
+
+func (c *handshakeConfig) getCertificate(clientHelloInfo *ClientHelloInfo) (*tls.Certificate, error) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
+ if c.localGetCertificate != nil &&
+ (len(c.localCertificates) == 0 || len(clientHelloInfo.ServerName) > 0) {
+ cert, err := c.localGetCertificate(clientHelloInfo)
+ if cert != nil || err != nil {
+ return cert, err
+ }
+ }
+
+ if c.nameToCertificate == nil {
+ c.setNameToCertificateLocked()
}
if len(c.localCertificates) == 0 {
@@ -41,11 +111,11 @@ func (c *handshakeConfig) getCertificate(serverName string) (*tls.Certificate, e
return &c.localCertificates[0], nil
}
- if len(serverName) == 0 {
+ if len(clientHelloInfo.ServerName) == 0 {
return &c.localCertificates[0], nil
}
- name := strings.TrimRight(strings.ToLower(serverName), ".")
+ name := strings.TrimRight(strings.ToLower(clientHelloInfo.ServerName), ".")
if cert, ok := c.nameToCertificate[name]; ok {
return cert, nil
@@ -65,3 +135,23 @@ func (c *handshakeConfig) getCertificate(serverName string) (*tls.Certificate, e
// If nothing matches, return the first certificate.
return &c.localCertificates[0], nil
}
+
+// NOTE: original src: https://github.com/golang/go/blob/29b9a328d268d53833d2cc063d1d8b4bf6852675/src/crypto/tls/handshake_client.go#L974
+func (c *handshakeConfig) getClientCertificate(cri *CertificateRequestInfo) (*tls.Certificate, error) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if c.localGetClientCertificate != nil {
+ return c.localGetClientCertificate(cri)
+ }
+
+ for i := range c.localCertificates {
+ chain := c.localCertificates[i]
+ if err := cri.SupportsCertificate(&chain); err != nil {
+ continue
+ }
+ return &chain, nil
+ }
+
+ // No acceptable certificate found. Don't send a certificate.
+ return new(tls.Certificate), nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/change_cipher_spec.go b/vendor/github.com/pion/dtls/v2/change_cipher_spec.go
deleted file mode 100644
index f072d7f..0000000
--- a/vendor/github.com/pion/dtls/v2/change_cipher_spec.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package dtls
-
-// The change cipher spec protocol exists to signal transitions in
-// ciphering strategies. The protocol consists of a single message,
-// which is encrypted and compressed under the current (not the pending)
-// connection state. The message consists of a single byte of value 1.
-// https://tools.ietf.org/html/rfc5246#section-7.1
-type changeCipherSpec struct {
-}
-
-func (c changeCipherSpec) contentType() contentType {
- return contentTypeChangeCipherSpec
-}
-
-func (c *changeCipherSpec) Marshal() ([]byte, error) {
- return []byte{0x01}, nil
-}
-
-func (c *changeCipherSpec) Unmarshal(data []byte) error {
- if len(data) == 1 && data[0] == 0x01 {
- return nil
- }
-
- return errInvalidCipherSpec
-}
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite.go b/vendor/github.com/pion/dtls/v2/cipher_suite.go
index b2017d5..6f7015c 100644
--- a/vendor/github.com/pion/dtls/v2/cipher_suite.go
+++ b/vendor/github.com/pion/dtls/v2/cipher_suite.go
@@ -1,75 +1,101 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
- "encoding/binary"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "crypto/tls"
"fmt"
"hash"
+
+ "github.com/pion/dtls/v2/internal/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
)
// CipherSuiteID is an ID for our supported CipherSuites
-type CipherSuiteID uint16
+type CipherSuiteID = ciphersuite.ID
// Supported Cipher Suites
const (
// AES-128-CCM
- TLS_ECDHE_ECDSA_WITH_AES_128_CCM CipherSuiteID = 0xc0ac
- TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 CipherSuiteID = 0xc0ae
+ TLS_ECDHE_ECDSA_WITH_AES_128_CCM CipherSuiteID = ciphersuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM //nolint:revive,stylecheck
+ TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 CipherSuiteID = ciphersuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 //nolint:revive,stylecheck
// AES-128-GCM-SHA256
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 CipherSuiteID = 0xc02b
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 CipherSuiteID = 0xc02f
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 CipherSuiteID = ciphersuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 //nolint:revive,stylecheck
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 CipherSuiteID = ciphersuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 //nolint:revive,stylecheck
+
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 CipherSuiteID = ciphersuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 //nolint:revive,stylecheck
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 CipherSuiteID = ciphersuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 //nolint:revive,stylecheck
// AES-256-CBC-SHA
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA CipherSuiteID = 0xc00a
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA CipherSuiteID = 0xc014
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA CipherSuiteID = ciphersuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA //nolint:revive,stylecheck
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA CipherSuiteID = ciphersuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA //nolint:revive,stylecheck
- TLS_PSK_WITH_AES_128_CCM CipherSuiteID = 0xc0a4
- TLS_PSK_WITH_AES_128_CCM_8 CipherSuiteID = 0xc0a8
- TLS_PSK_WITH_AES_128_GCM_SHA256 CipherSuiteID = 0x00a8
+ TLS_PSK_WITH_AES_128_CCM CipherSuiteID = ciphersuite.TLS_PSK_WITH_AES_128_CCM //nolint:revive,stylecheck
+ TLS_PSK_WITH_AES_128_CCM_8 CipherSuiteID = ciphersuite.TLS_PSK_WITH_AES_128_CCM_8 //nolint:revive,stylecheck
+ TLS_PSK_WITH_AES_256_CCM_8 CipherSuiteID = ciphersuite.TLS_PSK_WITH_AES_256_CCM_8 //nolint:revive,stylecheck
+ TLS_PSK_WITH_AES_128_GCM_SHA256 CipherSuiteID = ciphersuite.TLS_PSK_WITH_AES_128_GCM_SHA256 //nolint:revive,stylecheck
+ TLS_PSK_WITH_AES_128_CBC_SHA256 CipherSuiteID = ciphersuite.TLS_PSK_WITH_AES_128_CBC_SHA256 //nolint:revive,stylecheck
+
+ TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 CipherSuiteID = ciphersuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 //nolint:revive,stylecheck
)
-var (
- _ = allCipherSuites() // Necessary until this function isn't only used by Go 1.14
+// CipherSuiteAuthenticationType controls what authentication method is using during the handshake for a CipherSuite
+type CipherSuiteAuthenticationType = ciphersuite.AuthenticationType
+
+// AuthenticationType Enums
+const (
+ CipherSuiteAuthenticationTypeCertificate CipherSuiteAuthenticationType = ciphersuite.AuthenticationTypeCertificate
+ CipherSuiteAuthenticationTypePreSharedKey CipherSuiteAuthenticationType = ciphersuite.AuthenticationTypePreSharedKey
+ CipherSuiteAuthenticationTypeAnonymous CipherSuiteAuthenticationType = ciphersuite.AuthenticationTypeAnonymous
)
-func (c CipherSuiteID) String() string {
- switch c {
- case TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
- return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM"
- case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
- return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8"
- case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
- case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
- return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
- case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
- return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
- case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
- case TLS_PSK_WITH_AES_128_CCM:
- return "TLS_PSK_WITH_AES_128_CCM"
- case TLS_PSK_WITH_AES_128_CCM_8:
- return "TLS_PSK_WITH_AES_128_CCM_8"
- case TLS_PSK_WITH_AES_128_GCM_SHA256:
- return "TLS_PSK_WITH_AES_128_GCM_SHA256"
- default:
- return fmt.Sprintf("unknown(%v)", uint16(c))
- }
-}
+// CipherSuiteKeyExchangeAlgorithm controls what exchange algorithm is using during the handshake for a CipherSuite
+type CipherSuiteKeyExchangeAlgorithm = ciphersuite.KeyExchangeAlgorithm
+
+// CipherSuiteKeyExchangeAlgorithm Bitmask
+const (
+ CipherSuiteKeyExchangeAlgorithmNone CipherSuiteKeyExchangeAlgorithm = ciphersuite.KeyExchangeAlgorithmNone
+ CipherSuiteKeyExchangeAlgorithmPsk CipherSuiteKeyExchangeAlgorithm = ciphersuite.KeyExchangeAlgorithmPsk
+ CipherSuiteKeyExchangeAlgorithmEcdhe CipherSuiteKeyExchangeAlgorithm = ciphersuite.KeyExchangeAlgorithmEcdhe
+)
+
+var _ = allCipherSuites() // Necessary until this function isn't only used by Go 1.14
-type cipherSuite interface {
+// CipherSuite is an interface that all DTLS CipherSuites must satisfy
+type CipherSuite interface {
+ // String of CipherSuite, only used for logging
String() string
+
+ // ID of CipherSuite.
ID() CipherSuiteID
- certificateType() clientCertificateType
- hashFunc() func() hash.Hash
- isPSK() bool
- isInitialized() bool
- // Generate the internal encryption state
- init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error
+ // What type of Certificate does this CipherSuite use
+ CertificateType() clientcertificate.Type
+
+ // What Hash function is used during verification
+ HashFunc() func() hash.Hash
+
+ // AuthenticationType controls what authentication method is using during the handshake
+ AuthenticationType() CipherSuiteAuthenticationType
- encrypt(pkt *recordLayer, raw []byte) ([]byte, error)
- decrypt(in []byte) ([]byte, error)
+ // KeyExchangeAlgorithm controls what exchange algorithm is using during the handshake
+ KeyExchangeAlgorithm() CipherSuiteKeyExchangeAlgorithm
+
+ // ECC (Elliptic Curve Cryptography) determines whether ECC extesions will be send during handshake.
+ // https://datatracker.ietf.org/doc/html/rfc4492#page-10
+ ECC() bool
+
+ // Called when keying material has been generated, should initialize the internal cipher
+ Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error
+ IsInitialized() bool
+ Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error)
+ Decrypt(h recordlayer.Header, in []byte) ([]byte, error)
}
// CipherSuiteName provides the same functionality as tls.CipherSuiteName
@@ -78,7 +104,7 @@ type cipherSuite interface {
// Our implementation differs slightly in that it takes in a CiperSuiteID,
// like the rest of our library, instead of a uint16 like crypto/tls.
func CipherSuiteName(id CipherSuiteID) string {
- suite := cipherSuiteForID(id)
+ suite := cipherSuiteForID(id, nil)
if suite != nil {
return suite.String()
}
@@ -88,89 +114,93 @@ func CipherSuiteName(id CipherSuiteID) string {
// Taken from https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
// A cipherSuite is a specific combination of key agreement, cipher and MAC
// function.
-func cipherSuiteForID(id CipherSuiteID) cipherSuite {
- switch id {
+func cipherSuiteForID(id CipherSuiteID, customCiphers func() []CipherSuite) CipherSuite {
+ switch id { //nolint:exhaustive
case TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
- return newCipherSuiteTLSEcdheEcdsaWithAes128Ccm()
+ return ciphersuite.NewTLSEcdheEcdsaWithAes128Ccm()
case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
- return newCipherSuiteTLSEcdheEcdsaWithAes128Ccm8()
+ return ciphersuite.NewTLSEcdheEcdsaWithAes128Ccm8()
case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- return &cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256{}
+ return &ciphersuite.TLSEcdheEcdsaWithAes128GcmSha256{}
case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
- return &cipherSuiteTLSEcdheRsaWithAes128GcmSha256{}
+ return &ciphersuite.TLSEcdheRsaWithAes128GcmSha256{}
case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
- return &cipherSuiteTLSEcdheEcdsaWithAes256CbcSha{}
+ return &ciphersuite.TLSEcdheEcdsaWithAes256CbcSha{}
case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- return &cipherSuiteTLSEcdheRsaWithAes256CbcSha{}
+ return &ciphersuite.TLSEcdheRsaWithAes256CbcSha{}
case TLS_PSK_WITH_AES_128_CCM:
- return newCipherSuiteTLSPskWithAes128Ccm()
+ return ciphersuite.NewTLSPskWithAes128Ccm()
case TLS_PSK_WITH_AES_128_CCM_8:
- return newCipherSuiteTLSPskWithAes128Ccm8()
+ return ciphersuite.NewTLSPskWithAes128Ccm8()
+ case TLS_PSK_WITH_AES_256_CCM_8:
+ return ciphersuite.NewTLSPskWithAes256Ccm8()
case TLS_PSK_WITH_AES_128_GCM_SHA256:
- return &cipherSuiteTLSPskWithAes128GcmSha256{}
+ return &ciphersuite.TLSPskWithAes128GcmSha256{}
+ case TLS_PSK_WITH_AES_128_CBC_SHA256:
+ return &ciphersuite.TLSPskWithAes128CbcSha256{}
+ case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+ return &ciphersuite.TLSEcdheEcdsaWithAes256GcmSha384{}
+ case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ return &ciphersuite.TLSEcdheRsaWithAes256GcmSha384{}
+ case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
+ return ciphersuite.NewTLSEcdhePskWithAes128CbcSha256()
+ }
+
+ if customCiphers != nil {
+ for _, c := range customCiphers() {
+ if c.ID() == id {
+ return c
+ }
+ }
}
+
return nil
}
// CipherSuites we support in order of preference
-func defaultCipherSuites() []cipherSuite {
- return []cipherSuite{
- &cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256{},
- &cipherSuiteTLSEcdheRsaWithAes128GcmSha256{},
- &cipherSuiteTLSEcdheEcdsaWithAes256CbcSha{},
- &cipherSuiteTLSEcdheRsaWithAes256CbcSha{},
+func defaultCipherSuites() []CipherSuite {
+ return []CipherSuite{
+ &ciphersuite.TLSEcdheEcdsaWithAes128GcmSha256{},
+ &ciphersuite.TLSEcdheRsaWithAes128GcmSha256{},
+ &ciphersuite.TLSEcdheEcdsaWithAes256CbcSha{},
+ &ciphersuite.TLSEcdheRsaWithAes256CbcSha{},
+ &ciphersuite.TLSEcdheEcdsaWithAes256GcmSha384{},
+ &ciphersuite.TLSEcdheRsaWithAes256GcmSha384{},
}
}
-func allCipherSuites() []cipherSuite {
- return []cipherSuite{
- newCipherSuiteTLSEcdheEcdsaWithAes128Ccm(),
- newCipherSuiteTLSEcdheEcdsaWithAes128Ccm8(),
- &cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256{},
- &cipherSuiteTLSEcdheRsaWithAes128GcmSha256{},
- &cipherSuiteTLSEcdheEcdsaWithAes256CbcSha{},
- &cipherSuiteTLSEcdheRsaWithAes256CbcSha{},
- newCipherSuiteTLSPskWithAes128Ccm(),
- newCipherSuiteTLSPskWithAes128Ccm8(),
- &cipherSuiteTLSPskWithAes128GcmSha256{},
+func allCipherSuites() []CipherSuite {
+ return []CipherSuite{
+ ciphersuite.NewTLSEcdheEcdsaWithAes128Ccm(),
+ ciphersuite.NewTLSEcdheEcdsaWithAes128Ccm8(),
+ &ciphersuite.TLSEcdheEcdsaWithAes128GcmSha256{},
+ &ciphersuite.TLSEcdheRsaWithAes128GcmSha256{},
+ &ciphersuite.TLSEcdheEcdsaWithAes256CbcSha{},
+ &ciphersuite.TLSEcdheRsaWithAes256CbcSha{},
+ ciphersuite.NewTLSPskWithAes128Ccm(),
+ ciphersuite.NewTLSPskWithAes128Ccm8(),
+ ciphersuite.NewTLSPskWithAes256Ccm8(),
+ &ciphersuite.TLSPskWithAes128GcmSha256{},
+ &ciphersuite.TLSEcdheEcdsaWithAes256GcmSha384{},
+ &ciphersuite.TLSEcdheRsaWithAes256GcmSha384{},
}
}
-func decodeCipherSuites(buf []byte) ([]cipherSuite, error) {
- if len(buf) < 2 {
- return nil, errDTLSPacketInvalidLength
- }
- cipherSuitesCount := int(binary.BigEndian.Uint16(buf[0:])) / 2
- rtrn := []cipherSuite{}
- for i := 0; i < cipherSuitesCount; i++ {
- if len(buf) < (i*2 + 4) {
- return nil, errBufferTooSmall
- }
- id := CipherSuiteID(binary.BigEndian.Uint16(buf[(i*2)+2:]))
- if c := cipherSuiteForID(id); c != nil {
- rtrn = append(rtrn, c)
- }
- }
- return rtrn, nil
-}
-
-func encodeCipherSuites(cipherSuites []cipherSuite) []byte {
- out := []byte{0x00, 0x00}
- binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(cipherSuites)*2))
+func cipherSuiteIDs(cipherSuites []CipherSuite) []uint16 {
+ rtrn := []uint16{}
for _, c := range cipherSuites {
- out = append(out, []byte{0x00, 0x00}...)
- binary.BigEndian.PutUint16(out[len(out)-2:], uint16(c.ID()))
+ rtrn = append(rtrn, uint16(c.ID()))
}
- return out
+ return rtrn
}
-func parseCipherSuites(userSelectedSuites []CipherSuiteID, excludePSK, excludeNonPSK bool) ([]cipherSuite, error) {
- cipherSuitesForIDs := func(ids []CipherSuiteID) ([]cipherSuite, error) {
- cipherSuites := []cipherSuite{}
+func parseCipherSuites(userSelectedSuites []CipherSuiteID, customCipherSuites func() []CipherSuite, includeCertificateSuites, includePSKSuites bool) ([]CipherSuite, error) {
+ cipherSuitesForIDs := func(ids []CipherSuiteID) ([]CipherSuite, error) {
+ cipherSuites := []CipherSuite{}
for _, id := range ids {
- c := cipherSuiteForID(id)
+ c := cipherSuiteForID(id, nil)
if c == nil {
- return nil, fmt.Errorf("CipherSuite with id(%d) is not valid", id)
+ return nil, &invalidCipherSuiteError{id}
}
cipherSuites = append(cipherSuites, c)
}
@@ -178,11 +208,11 @@ func parseCipherSuites(userSelectedSuites []CipherSuiteID, excludePSK, excludeNo
}
var (
- cipherSuites []cipherSuite
+ cipherSuites []CipherSuite
err error
i int
)
- if len(userSelectedSuites) != 0 {
+ if userSelectedSuites != nil {
cipherSuites, err = cipherSuitesForIDs(userSelectedSuites)
if err != nil {
return nil, err
@@ -191,18 +221,56 @@ func parseCipherSuites(userSelectedSuites []CipherSuiteID, excludePSK, excludeNo
cipherSuites = defaultCipherSuites()
}
+ // Put CustomCipherSuites before ID selected suites
+ if customCipherSuites != nil {
+ cipherSuites = append(customCipherSuites(), cipherSuites...)
+ }
+
+ var foundCertificateSuite, foundPSKSuite, foundAnonymousSuite bool
for _, c := range cipherSuites {
- if excludePSK && c.isPSK() || excludeNonPSK && !c.isPSK() {
+ switch {
+ case includeCertificateSuites && c.AuthenticationType() == CipherSuiteAuthenticationTypeCertificate:
+ foundCertificateSuite = true
+ case includePSKSuites && c.AuthenticationType() == CipherSuiteAuthenticationTypePreSharedKey:
+ foundPSKSuite = true
+ case c.AuthenticationType() == CipherSuiteAuthenticationTypeAnonymous:
+ foundAnonymousSuite = true
+ default:
continue
}
cipherSuites[i] = c
i++
}
- cipherSuites = cipherSuites[:i]
- if len(cipherSuites) == 0 {
+ switch {
+ case includeCertificateSuites && !foundCertificateSuite && !foundAnonymousSuite:
+ return nil, errNoAvailableCertificateCipherSuite
+ case includePSKSuites && !foundPSKSuite:
+ return nil, errNoAvailablePSKCipherSuite
+ case i == 0:
return nil, errNoAvailableCipherSuites
}
- return cipherSuites, nil
+ return cipherSuites[:i], nil
+}
+
+func filterCipherSuitesForCertificate(cert *tls.Certificate, cipherSuites []CipherSuite) []CipherSuite {
+ if cert == nil || cert.PrivateKey == nil {
+ return cipherSuites
+ }
+ var certType clientcertificate.Type
+ switch cert.PrivateKey.(type) {
+ case ed25519.PrivateKey, *ecdsa.PrivateKey:
+ certType = clientcertificate.ECDSASign
+ case *rsa.PrivateKey:
+ certType = clientcertificate.RSASign
+ }
+
+ filtered := []CipherSuite{}
+ for _, c := range cipherSuites {
+ if c.AuthenticationType() != CipherSuiteAuthenticationTypeCertificate || certType == c.CertificateType() {
+ filtered = append(filtered, c)
+ }
+ }
+ return filtered
}
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_aes_128_ccm.go b/vendor/github.com/pion/dtls/v2/cipher_suite_aes_128_ccm.go
deleted file mode 100644
index cdff9b7..0000000
--- a/vendor/github.com/pion/dtls/v2/cipher_suite_aes_128_ccm.go
+++ /dev/null
@@ -1,90 +0,0 @@
-package dtls
-
-import (
- "crypto/sha256"
- "errors"
- "hash"
- "sync/atomic"
-)
-
-type cipherSuiteAes128Ccm struct {
- ccm atomic.Value // *cryptoCCM
- clientCertificateType clientCertificateType
- id CipherSuiteID
- psk bool
- cryptoCCMTagLen cryptoCCMTagLen
-}
-
-func newCipherSuiteAes128Ccm(clientCertificateType clientCertificateType, id CipherSuiteID, psk bool, cryptoCCMTagLen cryptoCCMTagLen) *cipherSuiteAes128Ccm {
- return &cipherSuiteAes128Ccm{
- clientCertificateType: clientCertificateType,
- id: id,
- psk: psk,
- cryptoCCMTagLen: cryptoCCMTagLen,
- }
-}
-
-func (c *cipherSuiteAes128Ccm) certificateType() clientCertificateType {
- return c.clientCertificateType
-}
-
-func (c *cipherSuiteAes128Ccm) ID() CipherSuiteID {
- return c.id
-}
-
-func (c *cipherSuiteAes128Ccm) String() string {
- return c.id.String()
-}
-
-func (c *cipherSuiteAes128Ccm) hashFunc() func() hash.Hash {
- return sha256.New
-}
-
-func (c *cipherSuiteAes128Ccm) isPSK() bool {
- return c.psk
-}
-
-func (c *cipherSuiteAes128Ccm) isInitialized() bool {
- return c.ccm.Load() != nil
-}
-
-func (c *cipherSuiteAes128Ccm) init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error {
- const (
- prfMacLen = 0
- prfKeyLen = 16
- prfIvLen = 4
- )
-
- keys, err := prfEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.hashFunc())
- if err != nil {
- return err
- }
-
- var ccm *cryptoCCM
- if isClient {
- ccm, err = newCryptoCCM(c.cryptoCCMTagLen, keys.clientWriteKey, keys.clientWriteIV, keys.serverWriteKey, keys.serverWriteIV)
- } else {
- ccm, err = newCryptoCCM(c.cryptoCCMTagLen, keys.serverWriteKey, keys.serverWriteIV, keys.clientWriteKey, keys.clientWriteIV)
- }
- c.ccm.Store(ccm)
-
- return err
-}
-
-func (c *cipherSuiteAes128Ccm) encrypt(pkt *recordLayer, raw []byte) ([]byte, error) {
- ccm := c.ccm.Load()
- if ccm == nil { // !c.isInitialized()
- return nil, errors.New("CipherSuite has not been initialized, unable to encrypt")
- }
-
- return ccm.(*cryptoCCM).encrypt(pkt, raw)
-}
-
-func (c *cipherSuiteAes128Ccm) decrypt(raw []byte) ([]byte, error) {
- ccm := c.ccm.Load()
- if ccm == nil { // !c.isInitialized()
- return nil, errors.New("CipherSuite has not been initialized, unable to decrypt ")
- }
-
- return ccm.(*cryptoCCM).decrypt(raw)
-}
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_go114.go b/vendor/github.com/pion/dtls/v2/cipher_suite_go114.go
index 54824db..fd46d7b 100644
--- a/vendor/github.com/pion/dtls/v2/cipher_suite_go114.go
+++ b/vendor/github.com/pion/dtls/v2/cipher_suite_go114.go
@@ -1,3 +1,7 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+//go:build go1.14
// +build go1.14
package dtls
@@ -6,8 +10,12 @@ import (
"crypto/tls"
)
+// VersionDTLS12 is the DTLS version in the same style as
+// VersionTLSXX from crypto/tls
+const VersionDTLS12 = 0xfefd
+
// Convert from our cipherSuite interface to a tls.CipherSuite struct
-func toTLSCipherSuite(c cipherSuite) *tls.CipherSuite {
+func toTLSCipherSuite(c CipherSuite) *tls.CipherSuite {
return &tls.CipherSuite{
ID: uint16(c.ID()),
Name: c.String(),
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm.go b/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm.go
deleted file mode 100644
index 4aa8f3b..0000000
--- a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package dtls
-
-func newCipherSuiteTLSEcdheEcdsaWithAes128Ccm() *cipherSuiteAes128Ccm {
- return newCipherSuiteAes128Ccm(clientCertificateTypeECDSASign, TLS_ECDHE_ECDSA_WITH_AES_128_CCM, false, cryptoCCMTagLength)
-}
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm8.go b/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm8.go
deleted file mode 100644
index 58bbe13..0000000
--- a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm8.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package dtls
-
-func newCipherSuiteTLSEcdheEcdsaWithAes128Ccm8() *cipherSuiteAes128Ccm {
- return newCipherSuiteAes128Ccm(clientCertificateTypeECDSASign, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, false, cryptoCCM8TagLength)
-}
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go
deleted file mode 100644
index d4ffd7e..0000000
--- a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package dtls
-
-import (
- "crypto/sha256"
- "errors"
- "hash"
- "sync/atomic"
-)
-
-type cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256 struct {
- gcm atomic.Value // *cryptoGCM
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256) certificateType() clientCertificateType {
- return clientCertificateTypeECDSASign
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256) ID() CipherSuiteID {
- return TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256) String() string {
- return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256) hashFunc() func() hash.Hash {
- return sha256.New
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256) isPSK() bool {
- return false
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256) isInitialized() bool {
- return c.gcm.Load() != nil
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256) init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error {
- const (
- prfMacLen = 0
- prfKeyLen = 16
- prfIvLen = 4
- )
-
- keys, err := prfEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.hashFunc())
- if err != nil {
- return err
- }
-
- var gcm *cryptoGCM
- if isClient {
- gcm, err = newCryptoGCM(keys.clientWriteKey, keys.clientWriteIV, keys.serverWriteKey, keys.serverWriteIV)
- } else {
- gcm, err = newCryptoGCM(keys.serverWriteKey, keys.serverWriteIV, keys.clientWriteKey, keys.clientWriteIV)
- }
- c.gcm.Store(gcm)
-
- return err
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256) encrypt(pkt *recordLayer, raw []byte) ([]byte, error) {
- gcm := c.gcm.Load()
- if gcm == nil { // !c.isInitialized()
- return nil, errors.New("CipherSuite has not been initialized, unable to encrypt")
- }
-
- return gcm.(*cryptoGCM).encrypt(pkt, raw)
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256) decrypt(raw []byte) ([]byte, error) {
- gcm := c.gcm.Load()
- if gcm == nil { // !c.isInitialized()
- return nil, errors.New("CipherSuite has not been initialized, unable to decrypt ")
- }
-
- return gcm.(*cryptoGCM).decrypt(raw)
-}
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go b/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go
deleted file mode 100644
index 25f2942..0000000
--- a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package dtls
-
-import (
- "crypto/sha256"
- "errors"
- "hash"
- "sync/atomic"
-)
-
-type cipherSuiteTLSEcdheEcdsaWithAes256CbcSha struct {
- cbc atomic.Value // *cryptoCBC
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes256CbcSha) certificateType() clientCertificateType {
- return clientCertificateTypeECDSASign
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes256CbcSha) ID() CipherSuiteID {
- return TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes256CbcSha) String() string {
- return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes256CbcSha) hashFunc() func() hash.Hash {
- return sha256.New
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes256CbcSha) isPSK() bool {
- return false
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes256CbcSha) isInitialized() bool {
- return c.cbc.Load() != nil
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes256CbcSha) init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error {
- const (
- prfMacLen = 20
- prfKeyLen = 32
- prfIvLen = 16
- )
-
- keys, err := prfEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.hashFunc())
- if err != nil {
- return err
- }
-
- var cbc *cryptoCBC
- if isClient {
- cbc, err = newCryptoCBC(
- keys.clientWriteKey, keys.clientWriteIV, keys.clientMACKey,
- keys.serverWriteKey, keys.serverWriteIV, keys.serverMACKey,
- )
- } else {
- cbc, err = newCryptoCBC(
- keys.serverWriteKey, keys.serverWriteIV, keys.serverMACKey,
- keys.clientWriteKey, keys.clientWriteIV, keys.clientMACKey,
- )
- }
- c.cbc.Store(cbc)
-
- return err
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes256CbcSha) encrypt(pkt *recordLayer, raw []byte) ([]byte, error) {
- cbc := c.cbc.Load()
- if cbc == nil { // !c.isInitialized()
- return nil, errors.New("CipherSuite has not been initialized, unable to encrypt")
- }
-
- return cbc.(*cryptoCBC).encrypt(pkt, raw)
-}
-
-func (c *cipherSuiteTLSEcdheEcdsaWithAes256CbcSha) decrypt(raw []byte) ([]byte, error) {
- cbc := c.cbc.Load()
- if cbc == nil { // !c.isInitialized()
- return nil, errors.New("CipherSuite has not been initialized, unable to decrypt ")
- }
-
- return cbc.(*cryptoCBC).decrypt(raw)
-}
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_rsa_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_rsa_with_aes_128_gcm_sha256.go
deleted file mode 100644
index 63402de..0000000
--- a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_rsa_with_aes_128_gcm_sha256.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package dtls
-
-type cipherSuiteTLSEcdheRsaWithAes128GcmSha256 struct {
- cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256
-}
-
-func (c *cipherSuiteTLSEcdheRsaWithAes128GcmSha256) certificateType() clientCertificateType {
- return clientCertificateTypeRSASign
-}
-
-func (c *cipherSuiteTLSEcdheRsaWithAes128GcmSha256) ID() CipherSuiteID {
- return TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
-}
-
-func (c *cipherSuiteTLSEcdheRsaWithAes128GcmSha256) String() string {
- return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
-}
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_rsa_with_aes_256_cbc_sha.go b/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_rsa_with_aes_256_cbc_sha.go
deleted file mode 100644
index 80a231f..0000000
--- a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_ecdhe_rsa_with_aes_256_cbc_sha.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package dtls
-
-type cipherSuiteTLSEcdheRsaWithAes256CbcSha struct {
- cipherSuiteTLSEcdheEcdsaWithAes256CbcSha
-}
-
-func (c *cipherSuiteTLSEcdheRsaWithAes256CbcSha) certificateType() clientCertificateType {
- return clientCertificateTypeRSASign
-}
-
-func (c *cipherSuiteTLSEcdheRsaWithAes256CbcSha) ID() CipherSuiteID {
- return TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
-}
-
-func (c *cipherSuiteTLSEcdheRsaWithAes256CbcSha) String() string {
- return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
-}
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_psk_with_aes_128_ccm.go b/vendor/github.com/pion/dtls/v2/cipher_suite_tls_psk_with_aes_128_ccm.go
deleted file mode 100644
index 7e72036..0000000
--- a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_psk_with_aes_128_ccm.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package dtls
-
-func newCipherSuiteTLSPskWithAes128Ccm() *cipherSuiteAes128Ccm {
- return newCipherSuiteAes128Ccm(clientCertificateType(0), TLS_PSK_WITH_AES_128_CCM, true, cryptoCCMTagLength)
-}
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_psk_with_aes_128_ccm8.go b/vendor/github.com/pion/dtls/v2/cipher_suite_tls_psk_with_aes_128_ccm8.go
deleted file mode 100644
index a7fd07e..0000000
--- a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_psk_with_aes_128_ccm8.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package dtls
-
-func newCipherSuiteTLSPskWithAes128Ccm8() *cipherSuiteAes128Ccm {
- return newCipherSuiteAes128Ccm(clientCertificateType(0), TLS_PSK_WITH_AES_128_CCM_8, true, cryptoCCM8TagLength)
-}
diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_psk_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v2/cipher_suite_tls_psk_with_aes_128_gcm_sha256.go
deleted file mode 100644
index 98663bd..0000000
--- a/vendor/github.com/pion/dtls/v2/cipher_suite_tls_psk_with_aes_128_gcm_sha256.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package dtls
-
-type cipherSuiteTLSPskWithAes128GcmSha256 struct {
- cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256
-}
-
-func (c *cipherSuiteTLSPskWithAes128GcmSha256) certificateType() clientCertificateType {
- return clientCertificateType(0)
-}
-
-func (c *cipherSuiteTLSPskWithAes128GcmSha256) ID() CipherSuiteID {
- return TLS_PSK_WITH_AES_128_GCM_SHA256
-}
-
-func (c *cipherSuiteTLSPskWithAes128GcmSha256) String() string {
- return "TLS_PSK_WITH_AES_128_GCM_SHA256"
-}
-
-func (c *cipherSuiteTLSPskWithAes128GcmSha256) isPSK() bool {
- return true
-}
diff --git a/vendor/github.com/pion/dtls/v2/client_certificate_type.go b/vendor/github.com/pion/dtls/v2/client_certificate_type.go
deleted file mode 100644
index 8eb3526..0000000
--- a/vendor/github.com/pion/dtls/v2/client_certificate_type.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package dtls
-
-// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-10
-type clientCertificateType byte
-
-const (
- clientCertificateTypeRSASign clientCertificateType = 1
- clientCertificateTypeECDSASign clientCertificateType = 64
-)
-
-var clientCertificateTypes = map[clientCertificateType]bool{
- clientCertificateTypeRSASign: true,
- clientCertificateTypeECDSASign: true,
-}
diff --git a/vendor/github.com/pion/dtls/v2/codecov.yml b/vendor/github.com/pion/dtls/v2/codecov.yml
index 5941e99..263e4d4 100644
--- a/vendor/github.com/pion/dtls/v2/codecov.yml
+++ b/vendor/github.com/pion/dtls/v2/codecov.yml
@@ -1,8 +1,10 @@
#
-# DO NOT EDIT THIS FILE DIRECTLY
+# DO NOT EDIT THIS FILE
#
# It is automatically copied from https://github.com/pion/.goassets repository.
#
+# SPDX-FileCopyrightText: 2023 The Pion community
+# SPDX-License-Identifier: MIT
coverage:
status:
diff --git a/vendor/github.com/pion/dtls/v2/compression_method.go b/vendor/github.com/pion/dtls/v2/compression_method.go
index 15d7aec..7e44de0 100644
--- a/vendor/github.com/pion/dtls/v2/compression_method.go
+++ b/vendor/github.com/pion/dtls/v2/compression_method.go
@@ -1,45 +1,12 @@
-package dtls
-
-type compressionMethodID byte
-
-const (
- compressionMethodNull compressionMethodID = 0
-)
-
-type compressionMethod struct {
- id compressionMethodID
-}
-
-var compressionMethods = map[compressionMethodID]*compressionMethod{
- compressionMethodNull: {id: compressionMethodNull},
-}
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
-var defaultCompressionMethods = []*compressionMethod{
- compressionMethods[compressionMethodNull],
-}
+package dtls
-func decodeCompressionMethods(buf []byte) ([]*compressionMethod, error) {
- if len(buf) < 1 {
- return nil, errDTLSPacketInvalidLength
- }
- compressionMethodsCount := int(buf[0])
- c := []*compressionMethod{}
- for i := 0; i < compressionMethodsCount; i++ {
- if len(buf) <= i+1 {
- return nil, errBufferTooSmall
- }
- id := compressionMethodID(buf[i+1])
- if compressionMethod, ok := compressionMethods[id]; ok {
- c = append(c, compressionMethod)
- }
- }
- return c, nil
-}
+import "github.com/pion/dtls/v2/pkg/protocol"
-func encodeCompressionMethods(c []*compressionMethod) []byte {
- out := []byte{byte(len(c))}
- for i := len(c); i > 0; i-- {
- out = append(out, byte(c[i-1].id))
+func defaultCompressionMethods() []*protocol.CompressionMethod {
+ return []*protocol.CompressionMethod{
+ {},
}
- return out
}
diff --git a/vendor/github.com/pion/dtls/v2/config.go b/vendor/github.com/pion/dtls/v2/config.go
index 26eb62a..604a4d5 100644
--- a/vendor/github.com/pion/dtls/v2/config.go
+++ b/vendor/github.com/pion/dtls/v2/config.go
@@ -1,16 +1,24 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
"context"
"crypto/ecdsa"
"crypto/ed25519"
+ "crypto/rsa"
"crypto/tls"
"crypto/x509"
+ "io"
"time"
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
"github.com/pion/logging"
)
+const keyLogLabelTLS12 = "CLIENT_RANDOM"
+
// Config is used to configure a DTLS client or server.
// After a Config is passed to a DTLS function it must not be modified.
type Config struct {
@@ -23,6 +31,11 @@ type Config struct {
// If CipherSuites is nil, a default list is used
CipherSuites []CipherSuiteID
+ // CustomCipherSuites is a list of CipherSuites that can be
+ // provided by the user. This allow users to user Ciphers that are reserved
+ // for private usage.
+ CustomCipherSuites func() []CipherSuite
+
// SignatureSchemes contains the signature and hash schemes that the peer requests to verify.
SignatureSchemes []tls.SignatureScheme
@@ -73,6 +86,16 @@ type Config struct {
// be considered but the verifiedChains will always be nil.
VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
+ // VerifyConnection, if not nil, is called after normal certificate
+ // verification/PSK and after VerifyPeerCertificate by either a TLS client
+ // or server. If it returns a non-nil error, the handshake is aborted
+ // and that error results.
+ //
+ // If normal verification fails then the handshake will abort before
+ // considering this callback. This callback will run for all connections
+ // regardless of InsecureSkipVerify or ClientAuth settings.
+ VerifyConnection func(*State) error
+
// RootCAs defines the set of root certificate authorities
// that one peer uses when verifying the other peer's certificates.
// If RootCAs is nil, TLS uses the host's root CA set.
@@ -107,6 +130,72 @@ type Config struct {
// Packet with sequence number older than this value compared to the latest
// accepted packet will be discarded. (default is 64)
ReplayProtectionWindow int
+
+ // KeyLogWriter optionally specifies a destination for TLS master secrets
+ // in NSS key log format that can be used to allow external programs
+ // such as Wireshark to decrypt TLS connections.
+ // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.
+ // Use of KeyLogWriter compromises security and should only be
+ // used for debugging.
+ KeyLogWriter io.Writer
+
+ // SessionStore is the container to store session for resumption.
+ SessionStore SessionStore
+
+ // List of application protocols the peer supports, for ALPN
+ SupportedProtocols []string
+
+ // List of Elliptic Curves to use
+ //
+ // If an ECC ciphersuite is configured and EllipticCurves is empty
+ // it will default to X25519, P-256, P-384 in this specific order.
+ EllipticCurves []elliptic.Curve
+
+ // GetCertificate returns a Certificate based on the given
+ // ClientHelloInfo. It will only be called if the client supplies SNI
+ // information or if Certificates is empty.
+ //
+ // If GetCertificate is nil or returns nil, then the certificate is
+ // retrieved from NameToCertificate. If NameToCertificate is nil, the
+ // best element of Certificates will be used.
+ GetCertificate func(*ClientHelloInfo) (*tls.Certificate, error)
+
+ // GetClientCertificate, if not nil, is called when a server requests a
+ // certificate from a client. If set, the contents of Certificates will
+ // be ignored.
+ //
+ // If GetClientCertificate returns an error, the handshake will be
+ // aborted and that error will be returned. Otherwise
+ // GetClientCertificate must return a non-nil Certificate. If
+ // Certificate.Certificate is empty then no certificate will be sent to
+ // the server. If this is unacceptable to the server then it may abort
+ // the handshake.
+ GetClientCertificate func(*CertificateRequestInfo) (*tls.Certificate, error)
+
+ // InsecureSkipVerifyHello, if true and when acting as server, allow client to
+ // skip hello verify phase and receive ServerHello after initial ClientHello.
+ // This have implication on DoS attack resistance.
+ InsecureSkipVerifyHello bool
+
+ // ConnectionIDGenerator generates connection identifiers that should be
+ // sent by the remote party if it supports the DTLS Connection Identifier
+ // extension, as determined during the handshake. Generated connection
+ // identifiers must always have the same length. Returning a zero-length
+ // connection identifier indicates that the local party supports sending
+ // connection identifiers but does not require the remote party to send
+ // them. A nil ConnectionIDGenerator indicates that connection identifiers
+ // are not supported.
+ // https://datatracker.ietf.org/doc/html/rfc9146
+ ConnectionIDGenerator func() []byte
+
+ // PaddingLengthGenerator generates the number of padding bytes used to
+ // inflate ciphertext size in order to obscure content size from observers.
+ // The length of the content is passed to the generator such that both
+ // deterministic and random padding schemes can be applied while not
+ // exceeding maximum record size.
+ // If no PaddingLengthGenerator is specified, padding will not be applied.
+ // https://datatracker.ietf.org/doc/html/rfc9146#section-4
+ PaddingLengthGenerator func(uint) uint
}
func defaultConnectContextMaker() (context.Context, func()) {
@@ -120,8 +209,14 @@ func (c *Config) connectContextMaker() (context.Context, func()) {
return c.ConnectContextMaker()
}
+func (c *Config) includeCertificateSuites() bool {
+ return c.PSK == nil || len(c.Certificates) > 0 || c.GetCertificate != nil || c.GetClientCertificate != nil
+}
+
const defaultMTU = 1200 // bytes
+var defaultCurves = []elliptic.Curve{elliptic.X25519, elliptic.P256, elliptic.P384} //nolint:gochecknoglobals
+
// PSKCallback is called once we have the remote's PSKIdentityHint.
// If the remote provided none it will be nil
type PSKCallback func([]byte) ([]byte, error)
@@ -154,8 +249,6 @@ func validateConfig(config *Config) error {
switch {
case config == nil:
return errNoConfigProvided
- case len(config.Certificates) > 0 && config.PSK != nil:
- return errPSKAndCertificate
case config.PSKIdentityHint != nil && config.PSK == nil:
return errIdentityNoPSK
}
@@ -168,12 +261,13 @@ func validateConfig(config *Config) error {
switch cert.PrivateKey.(type) {
case ed25519.PrivateKey:
case *ecdsa.PrivateKey:
+ case *rsa.PrivateKey:
default:
return errInvalidPrivateKey
}
}
}
- _, err := parseCipherSuites(config.CipherSuites, config.PSK == nil, config.PSK != nil)
+ _, err := parseCipherSuites(config.CipherSuites, config.CustomCipherSuites, config.includeCertificateSuites(), config.PSK != nil)
return err
}
diff --git a/vendor/github.com/pion/dtls/v2/conn.go b/vendor/github.com/pion/dtls/v2/conn.go
index 30f6fd9..9d1da84 100644
--- a/vendor/github.com/pion/dtls/v2/conn.go
+++ b/vendor/github.com/pion/dtls/v2/conn.go
@@ -1,7 +1,12 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
+ "bytes"
"context"
+ "errors"
"fmt"
"io"
"net"
@@ -10,43 +15,58 @@ import (
"time"
"github.com/pion/dtls/v2/internal/closer"
- "github.com/pion/dtls/v2/internal/net/connctx"
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+ "github.com/pion/dtls/v2/pkg/crypto/signaturehash"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
"github.com/pion/logging"
- "github.com/pion/transport/deadline"
- "github.com/pion/transport/replaydetector"
+ "github.com/pion/transport/v3/deadline"
+ "github.com/pion/transport/v3/netctx"
+ "github.com/pion/transport/v3/replaydetector"
)
const (
initialTickerInterval = time.Second
cookieLength = 20
- defaultNamedCurve = namedCurveX25519
+ sessionLength = 32
+ defaultNamedCurve = elliptic.X25519
inboundBufferSize = 8192
// Default replay protection window is specified by RFC 6347 Section 4.1.2.6
defaultReplayProtectionWindow = 64
)
-var invalidKeyingLabels = map[string]bool{
- "client finished": true,
- "server finished": true,
- "master secret": true,
- "key expansion": true,
+func invalidKeyingLabels() map[string]bool {
+ return map[string]bool{
+ "client finished": true,
+ "server finished": true,
+ "master secret": true,
+ "key expansion": true,
+ }
+}
+
+type addrPkt struct {
+ rAddr net.Addr
+ data []byte
}
// Conn represents a DTLS connection
type Conn struct {
- lock sync.RWMutex // Internal lock (must not be public)
- nextConn connctx.ConnCtx // Embedded Conn, typically a udpconn we read/write from
- fragmentBuffer *fragmentBuffer // out-of-order and missing fragment handling
- handshakeCache *handshakeCache // caching of handshake messages for verifyData generation
- decrypted chan interface{} // Decrypted Application Data or error, pull by calling `Read`
-
- state State // Internal state
+ lock sync.RWMutex // Internal lock (must not be public)
+ nextConn netctx.PacketConn // Embedded Conn, typically a udpconn we read/write from
+ fragmentBuffer *fragmentBuffer // out-of-order and missing fragment handling
+ handshakeCache *handshakeCache // caching of handshake messages for verifyData generation
+ decrypted chan interface{} // Decrypted Application Data or error, pull by calling `Read`
+ rAddr net.Addr
+ state State // Internal state
maximumTransmissionUnit int
+ paddingLengthGenerator func(uint) uint
handshakeCompletedSuccessfully atomic.Value
- encryptedPackets [][]byte
+ encryptedPackets []addrPkt
connectionClosedByUser bool
closeLock sync.Mutex
@@ -68,9 +88,8 @@ type Conn struct {
replayProtectionWindow uint
}
-func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient bool, initialState *State) (*Conn, error) {
- err := validateConfig(config)
- if err != nil {
+func createConn(ctx context.Context, nextConn net.PacketConn, rAddr net.Addr, config *Config, isClient bool, initialState *State) (*Conn, error) {
+ if err := validateConfig(config); err != nil {
return nil, err
}
@@ -78,12 +97,12 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
return nil, errNilNextConn
}
- cipherSuites, err := parseCipherSuites(config.CipherSuites, config.PSK == nil, config.PSK != nil)
+ cipherSuites, err := parseCipherSuites(config.CipherSuites, config.CustomCipherSuites, config.includeCertificateSuites(), config.PSK != nil)
if err != nil {
return nil, err
}
- signatureSchemes, err := parseSignatureSchemes(config.SignatureSchemes, config.InsecureHashes)
+ signatureSchemes, err := signaturehash.ParseSignatureSchemes(config.SignatureSchemes, config.InsecureHashes)
if err != nil {
return nil, err
}
@@ -110,11 +129,18 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
replayProtectionWindow = defaultReplayProtectionWindow
}
+ paddingLengthGenerator := config.PaddingLengthGenerator
+ if paddingLengthGenerator == nil {
+ paddingLengthGenerator = func(uint) uint { return 0 }
+ }
+
c := &Conn{
- nextConn: connctx.New(nextConn),
+ rAddr: rAddr,
+ nextConn: netctx.NewPacketConn(nextConn),
fragmentBuffer: newFragmentBuffer(),
handshakeCache: newHandshakeCache(),
maximumTransmissionUnit: mtu,
+ paddingLengthGenerator: paddingLengthGenerator,
decrypted: make(chan interface{}, 1),
log: logger,
@@ -138,16 +164,15 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
c.setLocalEpoch(0)
serverName := config.ServerName
- // Use host from conn address when serverName is not provided
- if isClient && serverName == "" && nextConn.RemoteAddr() != nil {
- remoteAddr := nextConn.RemoteAddr().String()
- var host string
- host, _, err = net.SplitHostPort(remoteAddr)
- if err != nil {
- serverName = remoteAddr
- } else {
- serverName = host
- }
+ // Do not allow the use of an IP address literal as an SNI value.
+ // See RFC 6066, Section 3.
+ if net.ParseIP(serverName) != nil {
+ serverName = ""
+ }
+
+ curves := config.EllipticCurves
+ if len(curves) == 0 {
+ curves = defaultCurves
}
hsCfg := &handshakeConfig{
@@ -158,15 +183,36 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
extendedMasterSecret: config.ExtendedMasterSecret,
localSRTPProtectionProfiles: config.SRTPProtectionProfiles,
serverName: serverName,
+ supportedProtocols: config.SupportedProtocols,
clientAuth: config.ClientAuth,
localCertificates: config.Certificates,
insecureSkipVerify: config.InsecureSkipVerify,
verifyPeerCertificate: config.VerifyPeerCertificate,
+ verifyConnection: config.VerifyConnection,
rootCAs: config.RootCAs,
clientCAs: config.ClientCAs,
+ customCipherSuites: config.CustomCipherSuites,
retransmitInterval: workerInterval,
log: logger,
initialEpoch: 0,
+ keyLogWriter: config.KeyLogWriter,
+ sessionStore: config.SessionStore,
+ ellipticCurves: curves,
+ localGetCertificate: config.GetCertificate,
+ localGetClientCertificate: config.GetClientCertificate,
+ insecureSkipHelloVerify: config.InsecureSkipVerifyHello,
+ connectionIDGenerator: config.ConnectionIDGenerator,
+ }
+
+ // rfc5246#section-7.4.3
+ // In addition, the hash and signature algorithms MUST be compatible
+ // with the key in the server's end-entity certificate.
+ if !isClient {
+ cert, err := hsCfg.getCertificate(&ClientHelloInfo{})
+ if err != nil && !errors.Is(err, errNoCertificates) {
+ return nil, err
+ }
+ hsCfg.localCipherSuites = filterCipherSuitesForCertificate(cert, cipherSuites)
}
var initialFlight flightVal
@@ -194,7 +240,7 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
return nil, err
}
- c.log.Trace(fmt.Sprintf("Handshake Completed"))
+ c.log.Trace("Handshake Completed")
return c, nil
}
@@ -202,44 +248,49 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
// Dial connects to the given network address and establishes a DTLS connection on top.
// Connection handshake will timeout using ConnectContextMaker in the Config.
// If you want to specify the timeout duration, use DialWithContext() instead.
-func Dial(network string, raddr *net.UDPAddr, config *Config) (*Conn, error) {
+func Dial(network string, rAddr *net.UDPAddr, config *Config) (*Conn, error) {
ctx, cancel := config.connectContextMaker()
defer cancel()
- return DialWithContext(ctx, network, raddr, config)
+ return DialWithContext(ctx, network, rAddr, config)
}
// Client establishes a DTLS connection over an existing connection.
// Connection handshake will timeout using ConnectContextMaker in the Config.
// If you want to specify the timeout duration, use ClientWithContext() instead.
-func Client(conn net.Conn, config *Config) (*Conn, error) {
+func Client(conn net.PacketConn, rAddr net.Addr, config *Config) (*Conn, error) {
ctx, cancel := config.connectContextMaker()
defer cancel()
- return ClientWithContext(ctx, conn, config)
+ return ClientWithContext(ctx, conn, rAddr, config)
}
// Server listens for incoming DTLS connections.
// Connection handshake will timeout using ConnectContextMaker in the Config.
// If you want to specify the timeout duration, use ServerWithContext() instead.
-func Server(conn net.Conn, config *Config) (*Conn, error) {
+func Server(conn net.PacketConn, rAddr net.Addr, config *Config) (*Conn, error) {
ctx, cancel := config.connectContextMaker()
defer cancel()
- return ServerWithContext(ctx, conn, config)
+ return ServerWithContext(ctx, conn, rAddr, config)
}
-// DialWithContext connects to the given network address and establishes a DTLS connection on top.
-func DialWithContext(ctx context.Context, network string, raddr *net.UDPAddr, config *Config) (*Conn, error) {
- pConn, err := net.DialUDP(network, nil, raddr)
+// DialWithContext connects to the given network address and establishes a DTLS
+// connection on top.
+func DialWithContext(ctx context.Context, network string, rAddr *net.UDPAddr, config *Config) (*Conn, error) {
+ // net.ListenUDP is used rather than net.DialUDP as the latter prevents the
+ // use of net.PacketConn.WriteTo.
+ // https://github.com/golang/go/blob/ce5e37ec21442c6eb13a43e68ca20129102ebac0/src/net/udpsock_posix.go#L115
+ pConn, err := net.ListenUDP(network, nil)
if err != nil {
return nil, err
}
- return ClientWithContext(ctx, pConn, config)
+
+ return ClientWithContext(ctx, pConn, rAddr, config)
}
// ClientWithContext establishes a DTLS connection over an existing connection.
-func ClientWithContext(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) {
+func ClientWithContext(ctx context.Context, conn net.PacketConn, rAddr net.Addr, config *Config) (*Conn, error) {
switch {
case config == nil:
return nil, errNoConfigProvided
@@ -247,19 +298,16 @@ func ClientWithContext(ctx context.Context, conn net.Conn, config *Config) (*Con
return nil, errPSKAndIdentityMustBeSetForClient
}
- return createConn(ctx, conn, config, true, nil)
+ return createConn(ctx, conn, rAddr, config, true, nil)
}
// ServerWithContext listens for incoming DTLS connections.
-func ServerWithContext(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) {
- switch {
- case config == nil:
+func ServerWithContext(ctx context.Context, conn net.PacketConn, rAddr net.Addr, config *Config) (*Conn, error) {
+ if config == nil {
return nil, errNoConfigProvided
- case config.PSK == nil && len(config.Certificates) == 0:
- return nil, errServerMustHaveCertificate
}
- return createConn(ctx, conn, config, false, nil)
+ return createConn(ctx, conn, rAddr, config, false, nil)
}
// Read reads data from the connection.
@@ -314,15 +362,16 @@ func (c *Conn) Write(p []byte) (int, error) {
return len(p), c.writePackets(c.writeDeadline, []*packet{
{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- epoch: c.getLocalEpoch(),
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Epoch: c.state.getLocalEpoch(),
+ Version: protocol.Version1_2,
},
- content: &applicationData{
- data: p,
+ Content: &protocol.ApplicationData{
+ Data: p,
},
},
+ shouldWrapCID: len(c.state.remoteConnectionID) > 0,
shouldEncrypt: true,
},
})
@@ -330,7 +379,7 @@ func (c *Conn) Write(p []byte) (int, error) {
// Close closes the connection.
func (c *Conn) Close() error {
- err := c.close(true)
+ err := c.close(true) //nolint:contextcheck
c.handshakeLoopsFinished.Wait()
return err
}
@@ -362,16 +411,17 @@ func (c *Conn) writePackets(ctx context.Context, pkts []*packet) error {
var rawPackets [][]byte
for _, p := range pkts {
- if h, ok := p.record.content.(*handshake); ok {
+ if h, ok := p.record.Content.(*handshake.Handshake); ok {
handshakeRaw, err := p.record.Marshal()
if err != nil {
return err
}
c.log.Tracef("[handshake:%v] -> %s (epoch: %d, seq: %d)",
- srvCliStr(c.state.isClient), h.handshakeHeader.handshakeType.String(),
- p.record.recordLayerHeader.epoch, h.handshakeHeader.messageSequence)
- c.handshakeCache.push(handshakeRaw[recordLayerHeaderSize:], p.record.recordLayerHeader.epoch, h.handshakeHeader.messageSequence, h.handshakeHeader.handshakeType, c.state.isClient)
+ srvCliStr(c.state.isClient), h.Header.Type.String(),
+ p.record.Header.Epoch, h.Header.MessageSequence)
+
+ c.handshakeCache.push(handshakeRaw[recordlayer.FixedHeaderSize:], p.record.Header.Epoch, h.Header.MessageSequence, h.Header.Type, c.state.isClient)
rawHandshakePackets, err := c.processHandshakePacket(p, h)
if err != nil {
@@ -392,7 +442,7 @@ func (c *Conn) writePackets(ctx context.Context, pkts []*packet) error {
compactedRawPackets := c.compactRawPackets(rawPackets)
for _, compactedRawPackets := range compactedRawPackets {
- if _, err := c.nextConn.Write(ctx, compactedRawPackets); err != nil {
+ if _, err := c.nextConn.WriteToContext(ctx, compactedRawPackets, c.rAddr); err != nil {
return netError(err)
}
}
@@ -401,6 +451,11 @@ func (c *Conn) writePackets(ctx context.Context, pkts []*packet) error {
}
func (c *Conn) compactRawPackets(rawPackets [][]byte) [][]byte {
+ // avoid a useless copy in the common case
+ if len(rawPackets) == 1 {
+ return rawPackets
+ }
+
combinedRawPackets := make([][]byte, 0)
currentCombinedRawPacket := make([]byte, 0)
@@ -418,27 +473,62 @@ func (c *Conn) compactRawPackets(rawPackets [][]byte) [][]byte {
}
func (c *Conn) processPacket(p *packet) ([]byte, error) {
- epoch := p.record.recordLayerHeader.epoch
+ epoch := p.record.Header.Epoch
for len(c.state.localSequenceNumber) <= int(epoch) {
c.state.localSequenceNumber = append(c.state.localSequenceNumber, uint64(0))
}
seq := atomic.AddUint64(&c.state.localSequenceNumber[epoch], 1) - 1
- if seq > maxSequenceNumber {
+ if seq > recordlayer.MaxSequenceNumber {
// RFC 6347 Section 4.1.0
// The implementation must either abandon an association or rehandshake
// prior to allowing the sequence number to wrap.
return nil, errSequenceNumberOverflow
}
- p.record.recordLayerHeader.sequenceNumber = seq
+ p.record.Header.SequenceNumber = seq
- rawPacket, err := p.record.Marshal()
- if err != nil {
- return nil, err
+ var rawPacket []byte
+ if p.shouldWrapCID {
+ // Record must be marshaled to populate fields used in inner plaintext.
+ if _, err := p.record.Marshal(); err != nil {
+ return nil, err
+ }
+ content, err := p.record.Content.Marshal()
+ if err != nil {
+ return nil, err
+ }
+ inner := &recordlayer.InnerPlaintext{
+ Content: content,
+ RealType: p.record.Header.ContentType,
+ }
+ rawInner, err := inner.Marshal() //nolint:govet
+ if err != nil {
+ return nil, err
+ }
+ cidHeader := &recordlayer.Header{
+ Version: p.record.Header.Version,
+ ContentType: protocol.ContentTypeConnectionID,
+ Epoch: p.record.Header.Epoch,
+ ContentLen: uint16(len(rawInner)),
+ ConnectionID: c.state.remoteConnectionID,
+ SequenceNumber: p.record.Header.SequenceNumber,
+ }
+ rawPacket, err = cidHeader.Marshal()
+ if err != nil {
+ return nil, err
+ }
+ p.record.Header = *cidHeader
+ rawPacket = append(rawPacket, rawInner...)
+ } else {
+ var err error
+ rawPacket, err = p.record.Marshal()
+ if err != nil {
+ return nil, err
+ }
}
if p.shouldEncrypt {
var err error
- rawPacket, err = c.state.cipherSuite.encrypt(p.record, rawPacket)
+ rawPacket, err = c.state.cipherSuite.Encrypt(p.record, rawPacket)
if err != nil {
return nil, err
}
@@ -447,43 +537,70 @@ func (c *Conn) processPacket(p *packet) ([]byte, error) {
return rawPacket, nil
}
-func (c *Conn) processHandshakePacket(p *packet, h *handshake) ([][]byte, error) {
+func (c *Conn) processHandshakePacket(p *packet, h *handshake.Handshake) ([][]byte, error) {
rawPackets := make([][]byte, 0)
handshakeFragments, err := c.fragmentHandshake(h)
if err != nil {
return nil, err
}
- epoch := p.record.recordLayerHeader.epoch
+ epoch := p.record.Header.Epoch
for len(c.state.localSequenceNumber) <= int(epoch) {
c.state.localSequenceNumber = append(c.state.localSequenceNumber, uint64(0))
}
for _, handshakeFragment := range handshakeFragments {
seq := atomic.AddUint64(&c.state.localSequenceNumber[epoch], 1) - 1
- if seq > maxSequenceNumber {
+ if seq > recordlayer.MaxSequenceNumber {
return nil, errSequenceNumberOverflow
}
- recordLayerHeader := &recordLayerHeader{
- protocolVersion: p.record.recordLayerHeader.protocolVersion,
- contentType: p.record.recordLayerHeader.contentType,
- contentLen: uint16(len(handshakeFragment)),
- epoch: p.record.recordLayerHeader.epoch,
- sequenceNumber: seq,
- }
+ var rawPacket []byte
+ if p.shouldWrapCID {
+ inner := &recordlayer.InnerPlaintext{
+ Content: handshakeFragment,
+ RealType: protocol.ContentTypeHandshake,
+ Zeros: c.paddingLengthGenerator(uint(len(handshakeFragment))),
+ }
+ rawInner, err := inner.Marshal() //nolint:govet
+ if err != nil {
+ return nil, err
+ }
+ cidHeader := &recordlayer.Header{
+ Version: p.record.Header.Version,
+ ContentType: protocol.ContentTypeConnectionID,
+ Epoch: p.record.Header.Epoch,
+ ContentLen: uint16(len(rawInner)),
+ ConnectionID: c.state.remoteConnectionID,
+ SequenceNumber: p.record.Header.SequenceNumber,
+ }
+ rawPacket, err = cidHeader.Marshal()
+ if err != nil {
+ return nil, err
+ }
+ p.record.Header = *cidHeader
+ rawPacket = append(rawPacket, rawInner...)
+ } else {
+ recordlayerHeader := &recordlayer.Header{
+ Version: p.record.Header.Version,
+ ContentType: p.record.Header.ContentType,
+ ContentLen: uint16(len(handshakeFragment)),
+ Epoch: p.record.Header.Epoch,
+ SequenceNumber: seq,
+ }
- recordLayerHeaderBytes, err := recordLayerHeader.Marshal()
- if err != nil {
- return nil, err
- }
+ rawPacket, err = recordlayerHeader.Marshal()
+ if err != nil {
+ return nil, err
+ }
- p.record.recordLayerHeader = *recordLayerHeader
+ p.record.Header = *recordlayerHeader
+ rawPacket = append(rawPacket, handshakeFragment...)
+ }
- rawPacket := append(recordLayerHeaderBytes, handshakeFragment...)
if p.shouldEncrypt {
var err error
- rawPacket, err = c.state.cipherSuite.encrypt(p.record, rawPacket)
+ rawPacket, err = c.state.cipherSuite.Encrypt(p.record, rawPacket)
if err != nil {
return nil, err
}
@@ -495,8 +612,8 @@ func (c *Conn) processHandshakePacket(p *packet, h *handshake) ([][]byte, error)
return rawPackets, nil
}
-func (c *Conn) fragmentHandshake(h *handshake) ([][]byte, error) {
- content, err := h.handshakeMessage.Marshal()
+func (c *Conn) fragmentHandshake(h *handshake.Handshake) ([][]byte, error) {
+ content, err := h.Message.Marshal()
if err != nil {
return nil, err
}
@@ -514,29 +631,29 @@ func (c *Conn) fragmentHandshake(h *handshake) ([][]byte, error) {
for _, contentFragment := range contentFragments {
contentFragmentLen := len(contentFragment)
- handshakeHeaderFragment := &handshakeHeader{
- handshakeType: h.handshakeHeader.handshakeType,
- length: h.handshakeHeader.length,
- messageSequence: h.handshakeHeader.messageSequence,
- fragmentOffset: uint32(offset),
- fragmentLength: uint32(contentFragmentLen),
+ headerFragment := &handshake.Header{
+ Type: h.Header.Type,
+ Length: h.Header.Length,
+ MessageSequence: h.Header.MessageSequence,
+ FragmentOffset: uint32(offset),
+ FragmentLength: uint32(contentFragmentLen),
}
offset += contentFragmentLen
- handshakeHeaderFragmentRaw, err := handshakeHeaderFragment.Marshal()
+ fragmentedHandshake, err := headerFragment.Marshal()
if err != nil {
return nil, err
}
- fragmentedHandshake := append(handshakeHeaderFragmentRaw, contentFragment...)
+ fragmentedHandshake = append(fragmentedHandshake, contentFragment...)
fragmentedHandshakes = append(fragmentedHandshakes, fragmentedHandshake)
}
return fragmentedHandshakes, nil
}
-var poolReadBuffer = sync.Pool{
+var poolReadBuffer = sync.Pool{ //nolint:gochecknoglobals
New: func() interface{} {
b := make([]byte, inboundBufferSize)
return &b
@@ -544,42 +661,44 @@ var poolReadBuffer = sync.Pool{
}
func (c *Conn) readAndBuffer(ctx context.Context) error {
- bufptr := poolReadBuffer.Get().(*[]byte)
+ bufptr, ok := poolReadBuffer.Get().(*[]byte)
+ if !ok {
+ return errFailedToAccessPoolReadBuffer
+ }
defer poolReadBuffer.Put(bufptr)
b := *bufptr
- i, err := c.nextConn.Read(ctx, b)
+ i, rAddr, err := c.nextConn.ReadFromContext(ctx, b)
if err != nil {
return netError(err)
}
- pkts, err := unpackDatagram(b[:i])
+ pkts, err := recordlayer.ContentAwareUnpackDatagram(b[:i], len(c.state.localConnectionID))
if err != nil {
return err
}
var hasHandshake bool
for _, p := range pkts {
- hs, alert, err := c.handleIncomingPacket(p, true)
+ hs, alert, err := c.handleIncomingPacket(ctx, p, rAddr, true)
if alert != nil {
- if alertErr := c.notify(ctx, alert.alertLevel, alert.alertDescription); alertErr != nil {
+ if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil {
if err == nil {
err = alertErr
}
}
}
+
+ var e *alertError
+ if errors.As(err, &e) && e.IsFatalOrCloseNotify() {
+ return e
+ }
+ if err != nil {
+ return err
+ }
if hs {
hasHandshake = true
}
- switch e := err.(type) {
- case nil:
- case *errAlert:
- if e.IsFatalOrCloseNotify() {
- return e
- }
- default:
- return e
- }
}
if hasHandshake {
done := make(chan struct{})
@@ -599,30 +718,32 @@ func (c *Conn) handleQueuedPackets(ctx context.Context) error {
c.encryptedPackets = nil
for _, p := range pkts {
- _, alert, err := c.handleIncomingPacket(p, false) // don't re-enqueue
+ _, alert, err := c.handleIncomingPacket(ctx, p.data, p.rAddr, false) // don't re-enqueue
if alert != nil {
- if alertErr := c.notify(ctx, alert.alertLevel, alert.alertDescription); alertErr != nil {
+ if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil {
if err == nil {
err = alertErr
}
}
}
- switch e := err.(type) {
- case nil:
- case *errAlert:
- if e.IsFatalOrCloseNotify() {
- return e
- }
- default:
+ var e *alertError
+ if errors.As(err, &e) && e.IsFatalOrCloseNotify() {
return e
}
+ if err != nil {
+ return err
+ }
}
return nil
}
-func (c *Conn) handleIncomingPacket(buf []byte, enqueue bool) (bool, *alert, error) {
- // TODO: avoid separate unmarshal
- h := &recordLayerHeader{}
+func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, rAddr net.Addr, enqueue bool) (bool, *alert.Alert, error) { //nolint:gocognit
+ h := &recordlayer.Header{}
+ // Set connection ID size so that records of content type tls12_cid will
+ // be parsed correctly.
+ if len(c.state.localConnectionID) > 0 {
+ h.ConnectionID = make([]byte, len(c.state.localConnectionID))
+ }
if err := h.Unmarshal(buf); err != nil {
// Decode error must be silently discarded
// [RFC6347 Section-4.1.2.7]
@@ -631,51 +752,95 @@ func (c *Conn) handleIncomingPacket(buf []byte, enqueue bool) (bool, *alert, err
}
// Validate epoch
- remoteEpoch := c.getRemoteEpoch()
- if h.epoch > remoteEpoch {
- if h.epoch > remoteEpoch+1 {
+ remoteEpoch := c.state.getRemoteEpoch()
+ if h.Epoch > remoteEpoch {
+ if h.Epoch > remoteEpoch+1 {
c.log.Debugf("discarded future packet (epoch: %d, seq: %d)",
- h.epoch, h.sequenceNumber,
+ h.Epoch, h.SequenceNumber,
)
return false, nil, nil
}
if enqueue {
c.log.Debug("received packet of next epoch, queuing packet")
- c.encryptedPackets = append(c.encryptedPackets, buf)
+ c.encryptedPackets = append(c.encryptedPackets, addrPkt{rAddr, buf})
}
return false, nil, nil
}
// Anti-replay protection
- for len(c.state.replayDetector) <= int(h.epoch) {
+ for len(c.state.replayDetector) <= int(h.Epoch) {
c.state.replayDetector = append(c.state.replayDetector,
- replaydetector.New(c.replayProtectionWindow, maxSequenceNumber),
+ replaydetector.New(c.replayProtectionWindow, recordlayer.MaxSequenceNumber),
)
}
- markPacketAsValid, ok := c.state.replayDetector[int(h.epoch)].Check(h.sequenceNumber)
+ markPacketAsValid, ok := c.state.replayDetector[int(h.Epoch)].Check(h.SequenceNumber)
if !ok {
c.log.Debugf("discarded duplicated packet (epoch: %d, seq: %d)",
- h.epoch, h.sequenceNumber,
+ h.Epoch, h.SequenceNumber,
)
return false, nil, nil
}
+ // originalCID indicates whether the original record had content type
+ // Connection ID.
+ originalCID := false
+
// Decrypt
- if h.epoch != 0 {
- if c.state.cipherSuite == nil || !c.state.cipherSuite.isInitialized() {
+ if h.Epoch != 0 {
+ if c.state.cipherSuite == nil || !c.state.cipherSuite.IsInitialized() {
if enqueue {
- c.encryptedPackets = append(c.encryptedPackets, buf)
+ c.encryptedPackets = append(c.encryptedPackets, addrPkt{rAddr, buf})
c.log.Debug("handshake not finished, queuing packet")
}
return false, nil, nil
}
+ // If a connection identifier had been negotiated and encryption is
+ // enabled, the connection identifier MUST be sent.
+ if len(c.state.localConnectionID) > 0 && h.ContentType != protocol.ContentTypeConnectionID {
+ c.log.Debug("discarded packet missing connection ID after value negotiated")
+ return false, nil, nil
+ }
+
var err error
- buf, err = c.state.cipherSuite.decrypt(buf)
+ var hdr recordlayer.Header
+ if h.ContentType == protocol.ContentTypeConnectionID {
+ hdr.ConnectionID = make([]byte, len(c.state.localConnectionID))
+ }
+ buf, err = c.state.cipherSuite.Decrypt(hdr, buf)
if err != nil {
c.log.Debugf("%s: decrypt failed: %s", srvCliStr(c.state.isClient), err)
return false, nil, nil
}
+ // If this is a connection ID record, make it look like a normal record for
+ // further processing.
+ if h.ContentType == protocol.ContentTypeConnectionID {
+ originalCID = true
+ ip := &recordlayer.InnerPlaintext{}
+ if err := ip.Unmarshal(buf[h.Size():]); err != nil { //nolint:govet
+ c.log.Debugf("unpacking inner plaintext failed: %s", err)
+ return false, nil, nil
+ }
+ unpacked := &recordlayer.Header{
+ ContentType: ip.RealType,
+ ContentLen: uint16(len(ip.Content)),
+ Version: h.Version,
+ Epoch: h.Epoch,
+ SequenceNumber: h.SequenceNumber,
+ }
+ buf, err = unpacked.Marshal()
+ if err != nil {
+ c.log.Debugf("converting CID record to inner plaintext failed: %s", err)
+ return false, nil, nil
+ }
+ buf = append(buf, ip.Content...)
+ }
+
+ // If connection ID does not match discard the packet.
+ if !bytes.Equal(c.state.localConnectionID, h.ConnectionID) {
+ c.log.Debug("unexpected connection ID")
+ return false, nil, nil
+ }
}
isHandshake, err := c.fragmentBuffer.push(append([]byte{}, buf...))
@@ -687,64 +852,77 @@ func (c *Conn) handleIncomingPacket(buf []byte, enqueue bool) (bool, *alert, err
} else if isHandshake {
markPacketAsValid()
for out, epoch := c.fragmentBuffer.pop(); out != nil; out, epoch = c.fragmentBuffer.pop() {
- rawHandshake := &handshake{}
- if err := rawHandshake.Unmarshal(out); err != nil {
+ header := &handshake.Header{}
+ if err := header.Unmarshal(out); err != nil {
c.log.Debugf("%s: handshake parse failed: %s", srvCliStr(c.state.isClient), err)
continue
}
-
- _ = c.handshakeCache.push(out, epoch, rawHandshake.handshakeHeader.messageSequence, rawHandshake.handshakeHeader.handshakeType, !c.state.isClient)
+ c.handshakeCache.push(out, epoch, header.MessageSequence, header.Type, !c.state.isClient)
}
return true, nil, nil
}
- r := &recordLayer{}
+ r := &recordlayer.RecordLayer{}
if err := r.Unmarshal(buf); err != nil {
- return false, &alert{alertLevelFatal, alertDecodeError}, err
+ return false, &alert.Alert{Level: alert.Fatal, Description: alert.DecodeError}, err
}
- switch content := r.content.(type) {
- case *alert:
+ isLatestSeqNum := false
+ switch content := r.Content.(type) {
+ case *alert.Alert:
c.log.Tracef("%s: <- %s", srvCliStr(c.state.isClient), content.String())
- var a *alert
- if content.alertDescription == alertCloseNotify {
+ var a *alert.Alert
+ if content.Description == alert.CloseNotify {
// Respond with a close_notify [RFC5246 Section 7.2.1]
- a = &alert{alertLevelWarning, alertCloseNotify}
+ a = &alert.Alert{Level: alert.Warning, Description: alert.CloseNotify}
}
- markPacketAsValid()
- return false, a, &errAlert{content}
- case *changeCipherSpec:
- if c.state.cipherSuite == nil || !c.state.cipherSuite.isInitialized() {
+ _ = markPacketAsValid()
+ return false, a, &alertError{content}
+ case *protocol.ChangeCipherSpec:
+ if c.state.cipherSuite == nil || !c.state.cipherSuite.IsInitialized() {
if enqueue {
- c.encryptedPackets = append(c.encryptedPackets, buf)
+ c.encryptedPackets = append(c.encryptedPackets, addrPkt{rAddr, buf})
c.log.Debugf("CipherSuite not initialized, queuing packet")
}
return false, nil, nil
}
- newRemoteEpoch := h.epoch + 1
+ newRemoteEpoch := h.Epoch + 1
c.log.Tracef("%s: <- ChangeCipherSpec (epoch: %d)", srvCliStr(c.state.isClient), newRemoteEpoch)
- if c.getRemoteEpoch()+1 == newRemoteEpoch {
+ if c.state.getRemoteEpoch()+1 == newRemoteEpoch {
c.setRemoteEpoch(newRemoteEpoch)
- markPacketAsValid()
+ isLatestSeqNum = markPacketAsValid()
}
- case *applicationData:
- if h.epoch == 0 {
- return false, &alert{alertLevelFatal, alertUnexpectedMessage}, fmt.Errorf("ApplicationData with epoch of 0")
+ case *protocol.ApplicationData:
+ if h.Epoch == 0 {
+ return false, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, errApplicationDataEpochZero
}
- markPacketAsValid()
+ isLatestSeqNum = markPacketAsValid()
select {
- case c.decrypted <- content.data:
+ case c.decrypted <- content.Data:
case <-c.closed.Done():
+ case <-ctx.Done():
}
default:
- return false, &alert{alertLevelFatal, alertUnexpectedMessage}, fmt.Errorf("unhandled contentType %d", content.contentType())
+ return false, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, fmt.Errorf("%w: %d", errUnhandledContextType, content.ContentType())
+ }
+
+ // Any valid connection ID record is a candidate for updating the remote
+ // address if it is the latest record received.
+ // https://datatracker.ietf.org/doc/html/rfc9146#peer-address-update
+ if originalCID && isLatestSeqNum {
+ if rAddr != c.RemoteAddr() {
+ c.lock.Lock()
+ c.rAddr = rAddr
+ c.lock.Unlock()
+ }
}
+
return false, nil, nil
}
@@ -752,19 +930,30 @@ func (c *Conn) recvHandshake() <-chan chan struct{} {
return c.handshakeRecv
}
-func (c *Conn) notify(ctx context.Context, level alertLevel, desc alertDescription) error {
+func (c *Conn) notify(ctx context.Context, level alert.Level, desc alert.Description) error {
+ if level == alert.Fatal && len(c.state.SessionID) > 0 {
+ // According to the RFC, we need to delete the stored session.
+ // https://datatracker.ietf.org/doc/html/rfc5246#section-7.2
+ if ss := c.fsm.cfg.sessionStore; ss != nil {
+ c.log.Tracef("clean invalid session: %s", c.state.SessionID)
+ if err := ss.Del(c.sessionKey()); err != nil {
+ return err
+ }
+ }
+ }
return c.writePackets(ctx, []*packet{
{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- epoch: c.getLocalEpoch(),
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Epoch: c.state.getLocalEpoch(),
+ Version: protocol.Version1_2,
},
- content: &alert{
- alertLevel: level,
- alertDescription: desc,
+ Content: &alert.Alert{
+ Level: level,
+ Description: desc,
},
},
+ shouldWrapCID: len(c.state.remoteConnectionID) > 0,
shouldEncrypt: c.isHandshakeCompletedSuccessfully(),
},
})
@@ -779,7 +968,7 @@ func (c *Conn) isHandshakeCompletedSuccessfully() bool {
return boolean.bool
}
-func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFlight flightVal, initialState handshakeState) error {
+func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFlight flightVal, initialState handshakeState) error { //nolint:gocognit
c.fsm = newHandshakeFSM(&c.state, c.handshakeCache, cfg, initialFlight)
done := make(chan struct{})
@@ -804,7 +993,7 @@ func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFligh
go func() {
defer c.handshakeLoopsFinished.Done()
err := c.fsm.Run(ctxHs, c, initialState)
- if err != context.Canceled {
+ if !errors.Is(err, context.Canceled) {
select {
case firstErr <- err:
default:
@@ -823,42 +1012,49 @@ func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFligh
defer c.handshakeLoopsFinished.Done()
for {
if err := c.readAndBuffer(ctxRead); err != nil {
- switch e := err.(type) {
- case *errAlert:
+ var e *alertError
+ if errors.As(err, &e) {
if !e.IsFatalOrCloseNotify() {
if c.isHandshakeCompletedSuccessfully() {
// Pass the error to Read()
select {
case c.decrypted <- err:
case <-c.closed.Done():
+ case <-ctxRead.Done():
}
}
continue // non-fatal alert must not stop read loop
}
- case error:
- switch err {
- case context.DeadlineExceeded, context.Canceled, io.EOF:
+ } else {
+ switch {
+ case errors.Is(err, context.DeadlineExceeded), errors.Is(err, context.Canceled), errors.Is(err, io.EOF), errors.Is(err, net.ErrClosed):
default:
if c.isHandshakeCompletedSuccessfully() {
// Keep read loop and pass the read error to Read()
select {
case c.decrypted <- err:
case <-c.closed.Done():
+ case <-ctxRead.Done():
}
continue // non-fatal alert must not stop read loop
}
}
}
+
select {
case firstErr <- err:
default:
}
- if e, ok := err.(*errAlert); ok {
+ if e != nil {
if e.IsFatalOrCloseNotify() {
- _ = c.close(false)
+ _ = c.close(false) //nolint:contextcheck
}
}
+ if !c.isConnectionClosed() && errors.Is(err, context.Canceled) {
+ c.log.Trace("handshake timeouts - closing underline connection")
+ _ = c.close(false) //nolint:contextcheck
+ }
return
}
}
@@ -868,10 +1064,12 @@ func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFligh
case err := <-firstErr:
cancelRead()
cancel()
+ c.handshakeLoopsFinished.Wait()
return c.translateHandshakeCtxError(err)
case <-ctx.Done():
cancelRead()
cancel()
+ c.handshakeLoopsFinished.Wait()
return c.translateHandshakeCtxError(ctx.Err())
case <-done:
return nil
@@ -879,16 +1077,13 @@ func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFligh
}
func (c *Conn) translateHandshakeCtxError(err error) error {
- switch err {
- case context.Canceled:
- if c.isHandshakeCompletedSuccessfully() {
- return nil
- }
- return err
- case context.DeadlineExceeded:
- return errHandshakeTimeout
+ if err == nil {
+ return nil
}
- return err
+ if errors.Is(err, context.Canceled) && c.isHandshakeCompletedSuccessfully() {
+ return nil
+ }
+ return &HandshakeError{Err: err}
}
func (c *Conn) close(byUser bool) error {
@@ -898,7 +1093,7 @@ func (c *Conn) close(byUser bool) error {
if c.isHandshakeCompletedSuccessfully() && byUser {
// Discard error from notify() to return non-error on the first user call of Close()
// even if the underlying connection is already closed.
- _ = c.notify(context.Background(), alertLevelWarning, alertCloseNotify)
+ _ = c.notify(context.Background(), alert.Warning, alert.CloseNotify)
}
c.closeLock.Lock()
@@ -907,6 +1102,7 @@ func (c *Conn) close(byUser bool) error {
if byUser {
c.connectionClosedByUser = true
}
+ isClosed := c.isConnectionClosed()
c.closed.Close()
c.closeLock.Unlock()
@@ -914,6 +1110,10 @@ func (c *Conn) close(byUser bool) error {
return ErrConnClosed
}
+ if isClosed {
+ return nil
+ }
+
return c.nextConn.Close()
}
@@ -930,18 +1130,10 @@ func (c *Conn) setLocalEpoch(epoch uint16) {
c.state.localEpoch.Store(epoch)
}
-func (c *Conn) getLocalEpoch() uint16 {
- return c.state.localEpoch.Load().(uint16)
-}
-
func (c *Conn) setRemoteEpoch(epoch uint16) {
c.state.remoteEpoch.Store(epoch)
}
-func (c *Conn) getRemoteEpoch() uint16 {
- return c.state.remoteEpoch.Load().(uint16)
-}
-
// LocalAddr implements net.Conn.LocalAddr
func (c *Conn) LocalAddr() net.Addr {
return c.nextConn.LocalAddr()
@@ -949,7 +1141,19 @@ func (c *Conn) LocalAddr() net.Addr {
// RemoteAddr implements net.Conn.RemoteAddr
func (c *Conn) RemoteAddr() net.Addr {
- return c.nextConn.RemoteAddr()
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+ return c.rAddr
+}
+
+func (c *Conn) sessionKey() []byte {
+ if c.state.isClient {
+ // As ServerName can be like 0.example.com, it's better to add
+ // delimiter character which is not allowed to be in
+ // neither address or domain name.
+ return []byte(c.rAddr.String() + "_" + c.fsm.cfg.serverName)
+ }
+ return c.state.SessionID
}
// SetDeadline implements net.Conn.SetDeadline
diff --git a/vendor/github.com/pion/dtls/v2/connection_id.go b/vendor/github.com/pion/dtls/v2/connection_id.go
new file mode 100644
index 0000000..b2fbbd7
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/connection_id.go
@@ -0,0 +1,101 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package dtls
+
+import (
+ "crypto/rand"
+
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/extension"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
+// RandomCIDGenerator is a random Connection ID generator where CID is the
+// specified size. Specifying a size of 0 will indicate to peers that sending a
+// Connection ID is not necessary.
+func RandomCIDGenerator(size int) func() []byte {
+ return func() []byte {
+ cid := make([]byte, size)
+ if _, err := rand.Read(cid); err != nil {
+ panic(err) //nolint -- nonrecoverable
+ }
+ return cid
+ }
+}
+
+// OnlySendCIDGenerator enables sending Connection IDs negotiated with a peer,
+// but indicates to the peer that sending Connection IDs in return is not
+// necessary.
+func OnlySendCIDGenerator() func() []byte {
+ return func() []byte {
+ return nil
+ }
+}
+
+// cidDatagramRouter extracts connection IDs from incoming datagram payloads and
+// uses them to route to the proper connection.
+// NOTE: properly routing datagrams based on connection IDs requires using
+// constant size connection IDs.
+func cidDatagramRouter(size int) func([]byte) (string, bool) {
+ return func(packet []byte) (string, bool) {
+ pkts, err := recordlayer.ContentAwareUnpackDatagram(packet, size)
+ if err != nil || len(pkts) < 1 {
+ return "", false
+ }
+ for _, pkt := range pkts {
+ h := &recordlayer.Header{
+ ConnectionID: make([]byte, size),
+ }
+ if err := h.Unmarshal(pkt); err != nil {
+ continue
+ }
+ if h.ContentType != protocol.ContentTypeConnectionID {
+ continue
+ }
+ return string(h.ConnectionID), true
+ }
+ return "", false
+ }
+}
+
+// cidConnIdentifier extracts connection IDs from outgoing ServerHello records
+// and associates them with the associated connection.
+// NOTE: a ServerHello should always be the first record in a datagram if
+// multiple are present, so we avoid iterating through all packets if the first
+// is not a ServerHello.
+func cidConnIdentifier() func([]byte) (string, bool) {
+ return func(packet []byte) (string, bool) {
+ pkts, err := recordlayer.UnpackDatagram(packet)
+ if err != nil || len(pkts) < 1 {
+ return "", false
+ }
+ var h recordlayer.Header
+ if hErr := h.Unmarshal(pkts[0]); hErr != nil {
+ return "", false
+ }
+ if h.ContentType != protocol.ContentTypeHandshake {
+ return "", false
+ }
+ var hh handshake.Header
+ var sh handshake.MessageServerHello
+ for _, pkt := range pkts {
+ if hhErr := hh.Unmarshal(pkt[recordlayer.FixedHeaderSize:]); hhErr != nil {
+ continue
+ }
+ if err = sh.Unmarshal(pkt[recordlayer.FixedHeaderSize+handshake.HeaderLength:]); err == nil {
+ break
+ }
+ }
+ if err != nil {
+ return "", false
+ }
+ for _, ext := range sh.Extensions {
+ if e, ok := ext.(*extension.ConnectionID); ok {
+ return string(e.CID), true
+ }
+ }
+ return "", false
+ }
+}
diff --git a/vendor/github.com/pion/dtls/v2/content.go b/vendor/github.com/pion/dtls/v2/content.go
deleted file mode 100644
index c938cb7..0000000
--- a/vendor/github.com/pion/dtls/v2/content.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package dtls
-
-// https://tools.ietf.org/html/rfc4346#section-6.2.1
-type contentType uint8
-
-const (
- contentTypeChangeCipherSpec contentType = 20
- contentTypeAlert contentType = 21
- contentTypeHandshake contentType = 22
- contentTypeApplicationData contentType = 23
-)
-
-type content interface {
- contentType() contentType
- Marshal() ([]byte, error)
- Unmarshal(data []byte) error
-}
diff --git a/vendor/github.com/pion/dtls/v2/crypto.go b/vendor/github.com/pion/dtls/v2/crypto.go
index d380a6f..968910c 100644
--- a/vendor/github.com/pion/dtls/v2/crypto.go
+++ b/vendor/github.com/pion/dtls/v2/crypto.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
@@ -12,13 +15,16 @@ import (
"encoding/binary"
"math/big"
"time"
+
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+ "github.com/pion/dtls/v2/pkg/crypto/hash"
)
type ecdsaSignature struct {
R, S *big.Int
}
-func valueKeyMessage(clientRandom, serverRandom, publicKey []byte, namedCurve namedCurve) []byte {
+func valueKeyMessage(clientRandom, serverRandom, publicKey []byte, namedCurve elliptic.Curve) []byte {
serverECDHParams := make([]byte, 4)
serverECDHParams[0] = 3 // named curve
binary.BigEndian.PutUint16(serverECDHParams[1:], uint16(namedCurve))
@@ -38,24 +44,24 @@ func valueKeyMessage(clientRandom, serverRandom, publicKey []byte, namedCurve na
// hash/signature algorithm pair that appears in that extension
//
// https://tools.ietf.org/html/rfc5246#section-7.4.2
-func generateKeySignature(clientRandom, serverRandom, publicKey []byte, namedCurve namedCurve, privateKey crypto.PrivateKey, hashAlgorithm hashAlgorithm) ([]byte, error) {
+func generateKeySignature(clientRandom, serverRandom, publicKey []byte, namedCurve elliptic.Curve, privateKey crypto.PrivateKey, hashAlgorithm hash.Algorithm) ([]byte, error) {
msg := valueKeyMessage(clientRandom, serverRandom, publicKey, namedCurve)
switch p := privateKey.(type) {
case ed25519.PrivateKey:
// https://crypto.stackexchange.com/a/55483
return p.Sign(rand.Reader, msg, crypto.Hash(0))
case *ecdsa.PrivateKey:
- hashed := hashAlgorithm.digest(msg)
- return p.Sign(rand.Reader, hashed, hashAlgorithm.cryptoHash())
+ hashed := hashAlgorithm.Digest(msg)
+ return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash())
case *rsa.PrivateKey:
- hashed := hashAlgorithm.digest(msg)
- return p.Sign(rand.Reader, hashed, hashAlgorithm.cryptoHash())
+ hashed := hashAlgorithm.Digest(msg)
+ return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash())
}
return nil, errKeySignatureGenerateUnimplemented
}
-func verifyKeySignature(message, remoteKeySignature []byte, hashAlgorithm hashAlgorithm, rawCertificates [][]byte) error {
+func verifyKeySignature(message, remoteKeySignature []byte, hashAlgorithm hash.Algorithm, rawCertificates [][]byte) error { //nolint:dupl
if len(rawCertificates) == 0 {
return errLengthMismatch
}
@@ -78,7 +84,7 @@ func verifyKeySignature(message, remoteKeySignature []byte, hashAlgorithm hashAl
if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
return errInvalidECDSASignature
}
- hashed := hashAlgorithm.digest(message)
+ hashed := hashAlgorithm.Digest(message)
if !ecdsa.Verify(p, hashed, ecdsaSig.R, ecdsaSig.S) {
return errKeySignatureMismatch
}
@@ -86,8 +92,10 @@ func verifyKeySignature(message, remoteKeySignature []byte, hashAlgorithm hashAl
case *rsa.PublicKey:
switch certificate.SignatureAlgorithm {
case x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA:
- hashed := hashAlgorithm.digest(message)
- return rsa.VerifyPKCS1v15(p, hashAlgorithm.cryptoHash(), hashed, remoteKeySignature)
+ hashed := hashAlgorithm.Digest(message)
+ return rsa.VerifyPKCS1v15(p, hashAlgorithm.CryptoHash(), hashed, remoteKeySignature)
+ default:
+ return errKeySignatureVerifyUnimplemented
}
}
@@ -102,7 +110,14 @@ func verifyKeySignature(message, remoteKeySignature []byte, hashAlgorithm hashAl
// CertificateVerify message is sent to explicitly verify possession of
// the private key in the certificate.
// https://tools.ietf.org/html/rfc5246#section-7.3
-func generateCertificateVerify(handshakeBodies []byte, privateKey crypto.PrivateKey, hashAlgorithm hashAlgorithm) ([]byte, error) {
+func generateCertificateVerify(handshakeBodies []byte, privateKey crypto.PrivateKey, hashAlgorithm hash.Algorithm) ([]byte, error) {
+ if p, ok := privateKey.(ed25519.PrivateKey); ok {
+ // https://pkg.go.dev/crypto/ed25519#PrivateKey.Sign
+ // Sign signs the given message with priv. Ed25519 performs two passes over
+ // messages to be signed and therefore cannot handle pre-hashed messages.
+ return p.Sign(rand.Reader, handshakeBodies, crypto.Hash(0))
+ }
+
h := sha256.New()
if _, err := h.Write(handshakeBodies); err != nil {
return nil, err
@@ -110,19 +125,16 @@ func generateCertificateVerify(handshakeBodies []byte, privateKey crypto.Private
hashed := h.Sum(nil)
switch p := privateKey.(type) {
- case ed25519.PrivateKey:
- // https://crypto.stackexchange.com/a/55483
- return p.Sign(rand.Reader, hashed, crypto.Hash(0))
case *ecdsa.PrivateKey:
- return p.Sign(rand.Reader, hashed, hashAlgorithm.cryptoHash())
+ return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash())
case *rsa.PrivateKey:
- return p.Sign(rand.Reader, hashed, hashAlgorithm.cryptoHash())
+ return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash())
}
return nil, errInvalidSignatureAlgorithm
}
-func verifyCertificateVerify(handshakeBodies []byte, hashAlgorithm hashAlgorithm, remoteKeySignature []byte, rawCertificates [][]byte) error {
+func verifyCertificateVerify(handshakeBodies []byte, hashAlgorithm hash.Algorithm, remoteKeySignature []byte, rawCertificates [][]byte) error { //nolint:dupl
if len(rawCertificates) == 0 {
return errLengthMismatch
}
@@ -145,7 +157,7 @@ func verifyCertificateVerify(handshakeBodies []byte, hashAlgorithm hashAlgorithm
if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
return errInvalidECDSASignature
}
- hash := hashAlgorithm.digest(handshakeBodies)
+ hash := hashAlgorithm.Digest(handshakeBodies)
if !ecdsa.Verify(p, hash, ecdsaSig.R, ecdsaSig.S) {
return errKeySignatureMismatch
}
@@ -153,8 +165,10 @@ func verifyCertificateVerify(handshakeBodies []byte, hashAlgorithm hashAlgorithm
case *rsa.PublicKey:
switch certificate.SignatureAlgorithm {
case x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA:
- hash := hashAlgorithm.digest(handshakeBodies)
- return rsa.VerifyPKCS1v15(p, hashAlgorithm.cryptoHash(), hash, remoteKeySignature)
+ hash := hashAlgorithm.Digest(handshakeBodies)
+ return rsa.VerifyPKCS1v15(p, hashAlgorithm.CryptoHash(), hash, remoteKeySignature)
+ default:
+ return errKeySignatureVerifyUnimplemented
}
}
@@ -212,17 +226,3 @@ func verifyServerCert(rawCertificates [][]byte, roots *x509.CertPool, serverName
}
return certificate[0].Verify(opts)
}
-
-func generateAEADAdditionalData(h *recordLayerHeader, payloadLen int) []byte {
- var additionalData [13]byte
- // SequenceNumber MUST be set first
- // we only want uint48, clobbering an extra 2 (using uint64, Golang doesn't have uint48)
- binary.BigEndian.PutUint64(additionalData[:], h.sequenceNumber)
- binary.BigEndian.PutUint16(additionalData[:], h.epoch)
- additionalData[8] = byte(h.contentType)
- additionalData[9] = h.protocolVersion.major
- additionalData[10] = h.protocolVersion.minor
- binary.BigEndian.PutUint16(additionalData[len(additionalData)-2:], uint16(payloadLen))
-
- return additionalData[:]
-}
diff --git a/vendor/github.com/pion/dtls/v2/crypto_cbc.go b/vendor/github.com/pion/dtls/v2/crypto_cbc.go
deleted file mode 100644
index 4bc2031..0000000
--- a/vendor/github.com/pion/dtls/v2/crypto_cbc.go
+++ /dev/null
@@ -1,133 +0,0 @@
-package dtls
-
-import (
- "crypto/aes"
- "crypto/cipher"
- "crypto/hmac"
- "crypto/rand"
- "crypto/sha1" // #nosec
- "encoding/binary"
-)
-
-// block ciphers using cipher block chaining.
-type cbcMode interface {
- cipher.BlockMode
- SetIV([]byte)
-}
-
-// State needed to handle encrypted input/output
-type cryptoCBC struct {
- writeCBC, readCBC cbcMode
- writeMac, readMac []byte
-}
-
-// Currently hardcoded to be SHA1 only
-var cryptoCBCMacFunc = sha1.New
-
-func newCryptoCBC(localKey, localWriteIV, localMac, remoteKey, remoteWriteIV, remoteMac []byte) (*cryptoCBC, error) {
- writeBlock, err := aes.NewCipher(localKey)
- if err != nil {
- return nil, err
- }
-
- readBlock, err := aes.NewCipher(remoteKey)
- if err != nil {
- return nil, err
- }
-
- return &cryptoCBC{
- writeCBC: cipher.NewCBCEncrypter(writeBlock, localWriteIV).(cbcMode),
- writeMac: localMac,
-
- readCBC: cipher.NewCBCDecrypter(readBlock, remoteWriteIV).(cbcMode),
- readMac: remoteMac,
- }, nil
-}
-
-func (c *cryptoCBC) encrypt(pkt *recordLayer, raw []byte) ([]byte, error) {
- payload := raw[recordLayerHeaderSize:]
- raw = raw[:recordLayerHeaderSize]
- blockSize := c.writeCBC.BlockSize()
-
- // Generate + Append MAC
- h := pkt.recordLayerHeader
-
- MAC, err := prfMac(h.epoch, h.sequenceNumber, h.contentType, h.protocolVersion, payload, c.writeMac)
- if err != nil {
- return nil, err
- }
- payload = append(payload, MAC...)
-
- // Generate + Append padding
- padding := make([]byte, blockSize-len(payload)%blockSize)
- paddingLen := len(padding)
- for i := 0; i < paddingLen; i++ {
- padding[i] = byte(paddingLen - 1)
- }
- payload = append(payload, padding...)
-
- // Generate IV
- iv := make([]byte, blockSize)
- if _, err := rand.Read(iv); err != nil {
- return nil, err
- }
-
- // Set IV + Encrypt + Prepend IV
- c.writeCBC.SetIV(iv)
- c.writeCBC.CryptBlocks(payload, payload)
- payload = append(iv, payload...)
-
- // Prepend unencrypte header with encrypted payload
- raw = append(raw, payload...)
-
- // Update recordLayer size to include IV+MAC+Padding
- binary.BigEndian.PutUint16(raw[recordLayerHeaderSize-2:], uint16(len(raw)-recordLayerHeaderSize))
-
- return raw, nil
-}
-
-func (c *cryptoCBC) decrypt(in []byte) ([]byte, error) {
- body := in[recordLayerHeaderSize:]
- blockSize := c.readCBC.BlockSize()
- mac := cryptoCBCMacFunc()
-
- var h recordLayerHeader
- err := h.Unmarshal(in)
- switch {
- case err != nil:
- return nil, err
- case h.contentType == contentTypeChangeCipherSpec:
- // Nothing to encrypt with ChangeCipherSpec
- return in, nil
- case len(body)%blockSize != 0 || len(body) < blockSize+max(mac.Size()+1, blockSize):
- return nil, errNotEnoughRoomForNonce
- }
-
- // Set + remove per record IV
- c.readCBC.SetIV(body[:blockSize])
- body = body[blockSize:]
-
- // Decrypt
- c.readCBC.CryptBlocks(body, body)
-
- // Padding+MAC needs to be checked in constant time
- // Otherwise we reveal information about the level of correctness
- paddingLen, paddingGood := examinePadding(body)
-
- macSize := mac.Size()
- if len(body) < macSize {
- return nil, errInvalidMAC
- }
-
- dataEnd := len(body) - macSize - paddingLen
-
- expectedMAC := body[dataEnd : dataEnd+macSize]
- actualMAC, err := prfMac(h.epoch, h.sequenceNumber, h.contentType, h.protocolVersion, body[:dataEnd], c.readMac)
-
- // Compute Local MAC and compare
- if paddingGood != 255 || err != nil || !hmac.Equal(actualMAC, expectedMAC) {
- return nil, errInvalidMAC
- }
-
- return append(in[:recordLayerHeaderSize], body[:dataEnd]...), nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/crypto_ccm.go b/vendor/github.com/pion/dtls/v2/crypto_ccm.go
deleted file mode 100644
index fe84cd1..0000000
--- a/vendor/github.com/pion/dtls/v2/crypto_ccm.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package dtls
-
-import (
- "crypto/aes"
- "crypto/rand"
- "encoding/binary"
- "fmt"
-
- "github.com/pion/dtls/v2/pkg/crypto/ccm"
-)
-
-type cryptoCCMTagLen int
-
-const (
- cryptoCCM8TagLength cryptoCCMTagLen = 8
- cryptoCCMTagLength cryptoCCMTagLen = 16
- cryptoCCMNonceLength = 12
-)
-
-// State needed to handle encrypted input/output
-type cryptoCCM struct {
- localCCM, remoteCCM ccm.CCM
- localWriteIV, remoteWriteIV []byte
- tagLen cryptoCCMTagLen
-}
-
-func newCryptoCCM(tagLen cryptoCCMTagLen, localKey, localWriteIV, remoteKey, remoteWriteIV []byte) (*cryptoCCM, error) {
- localBlock, err := aes.NewCipher(localKey)
- if err != nil {
- return nil, err
- }
- localCCM, err := ccm.NewCCM(localBlock, int(tagLen), cryptoCCMNonceLength)
- if err != nil {
- return nil, err
- }
-
- remoteBlock, err := aes.NewCipher(remoteKey)
- if err != nil {
- return nil, err
- }
- remoteCCM, err := ccm.NewCCM(remoteBlock, int(tagLen), cryptoCCMNonceLength)
- if err != nil {
- return nil, err
- }
-
- return &cryptoCCM{
- localCCM: localCCM,
- localWriteIV: localWriteIV,
- remoteCCM: remoteCCM,
- remoteWriteIV: remoteWriteIV,
- tagLen: tagLen,
- }, nil
-}
-
-func (c *cryptoCCM) encrypt(pkt *recordLayer, raw []byte) ([]byte, error) {
- payload := raw[recordLayerHeaderSize:]
- raw = raw[:recordLayerHeaderSize]
-
- nonce := append(append([]byte{}, c.localWriteIV[:4]...), make([]byte, 8)...)
- if _, err := rand.Read(nonce[4:]); err != nil {
- return nil, err
- }
-
- additionalData := generateAEADAdditionalData(&pkt.recordLayerHeader, len(payload))
- encryptedPayload := c.localCCM.Seal(nil, nonce, payload, additionalData)
-
- encryptedPayload = append(nonce[4:], encryptedPayload...)
- raw = append(raw, encryptedPayload...)
-
- // Update recordLayer size to include explicit nonce
- binary.BigEndian.PutUint16(raw[recordLayerHeaderSize-2:], uint16(len(raw)-recordLayerHeaderSize))
- return raw, nil
-}
-
-func (c *cryptoCCM) decrypt(in []byte) ([]byte, error) {
- var h recordLayerHeader
- err := h.Unmarshal(in)
- switch {
- case err != nil:
- return nil, err
- case h.contentType == contentTypeChangeCipherSpec:
- // Nothing to encrypt with ChangeCipherSpec
- return in, nil
- case len(in) <= (8 + recordLayerHeaderSize):
- return nil, errNotEnoughRoomForNonce
- }
-
- nonce := append(append([]byte{}, c.remoteWriteIV[:4]...), in[recordLayerHeaderSize:recordLayerHeaderSize+8]...)
- out := in[recordLayerHeaderSize+8:]
-
- additionalData := generateAEADAdditionalData(&h, len(out)-int(c.tagLen))
- out, err = c.remoteCCM.Open(out[:0], nonce, out, additionalData)
- if err != nil {
- return nil, fmt.Errorf("decryptPacket: %v", err)
- }
- return append(in[:recordLayerHeaderSize], out...), nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/crypto_gcm.go b/vendor/github.com/pion/dtls/v2/crypto_gcm.go
deleted file mode 100644
index 50a06e6..0000000
--- a/vendor/github.com/pion/dtls/v2/crypto_gcm.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package dtls
-
-import (
- "crypto/aes"
- "crypto/cipher"
- "crypto/rand"
- "encoding/binary"
- "fmt"
-)
-
-const cryptoGCMTagLength = 16
-const cryptoGCMNonceLength = 12
-
-// State needed to handle encrypted input/output
-type cryptoGCM struct {
- localGCM, remoteGCM cipher.AEAD
- localWriteIV, remoteWriteIV []byte
-}
-
-func newCryptoGCM(localKey, localWriteIV, remoteKey, remoteWriteIV []byte) (*cryptoGCM, error) {
- localBlock, err := aes.NewCipher(localKey)
- if err != nil {
- return nil, err
- }
- localGCM, err := cipher.NewGCM(localBlock)
- if err != nil {
- return nil, err
- }
-
- remoteBlock, err := aes.NewCipher(remoteKey)
- if err != nil {
- return nil, err
- }
- remoteGCM, err := cipher.NewGCM(remoteBlock)
- if err != nil {
- return nil, err
- }
-
- return &cryptoGCM{
- localGCM: localGCM,
- localWriteIV: localWriteIV,
- remoteGCM: remoteGCM,
- remoteWriteIV: remoteWriteIV,
- }, nil
-}
-
-func (c *cryptoGCM) encrypt(pkt *recordLayer, raw []byte) ([]byte, error) {
- payload := raw[recordLayerHeaderSize:]
- raw = raw[:recordLayerHeaderSize]
-
- nonce := make([]byte, cryptoGCMNonceLength)
- copy(nonce, c.localWriteIV[:4])
- if _, err := rand.Read(nonce[4:]); err != nil {
- return nil, err
- }
-
- additionalData := generateAEADAdditionalData(&pkt.recordLayerHeader, len(payload))
- encryptedPayload := c.localGCM.Seal(nil, nonce, payload, additionalData)
- r := make([]byte, len(raw)+len(nonce[4:])+len(encryptedPayload))
- copy(r, raw)
- copy(r[len(raw):], nonce[4:])
- copy(r[len(raw)+len(nonce[4:]):], encryptedPayload)
-
- // Update recordLayer size to include explicit nonce
- binary.BigEndian.PutUint16(r[recordLayerHeaderSize-2:], uint16(len(r)-recordLayerHeaderSize))
- return r, nil
-}
-
-func (c *cryptoGCM) decrypt(in []byte) ([]byte, error) {
- var h recordLayerHeader
- err := h.Unmarshal(in)
- switch {
- case err != nil:
- return nil, err
- case h.contentType == contentTypeChangeCipherSpec:
- // Nothing to encrypt with ChangeCipherSpec
- return in, nil
- case len(in) <= (8 + recordLayerHeaderSize):
- return nil, errNotEnoughRoomForNonce
- }
-
- nonce := make([]byte, 0, cryptoGCMNonceLength)
- nonce = append(append(nonce, c.remoteWriteIV[:4]...), in[recordLayerHeaderSize:recordLayerHeaderSize+8]...)
- out := in[recordLayerHeaderSize+8:]
-
- additionalData := generateAEADAdditionalData(&h, len(out)-cryptoGCMTagLength)
- out, err = c.remoteGCM.Open(out[:0], nonce, out, additionalData)
- if err != nil {
- return nil, fmt.Errorf("decryptPacket: %v", err)
- }
- return append(in[:recordLayerHeaderSize], out...), nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/curve_type.go b/vendor/github.com/pion/dtls/v2/curve_type.go
deleted file mode 100644
index 37771f6..0000000
--- a/vendor/github.com/pion/dtls/v2/curve_type.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package dtls
-
-// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-10
-type ellipticCurveType byte
-
-const (
- ellipticCurveTypeNamedCurve ellipticCurveType = 0x03
-)
-
-var ellipticCurveTypes = map[ellipticCurveType]bool{
- ellipticCurveTypeNamedCurve: true,
-}
diff --git a/vendor/github.com/pion/dtls/v2/dtls.go b/vendor/github.com/pion/dtls/v2/dtls.go
index 125b904..b799770 100644
--- a/vendor/github.com/pion/dtls/v2/dtls.go
+++ b/vendor/github.com/pion/dtls/v2/dtls.go
@@ -1,2 +1,5 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
// Package dtls implements Datagram Transport Layer Security (DTLS) 1.2
package dtls
diff --git a/vendor/github.com/pion/dtls/v2/errors.go b/vendor/github.com/pion/dtls/v2/errors.go
index ea7cbb8..025d864 100644
--- a/vendor/github.com/pion/dtls/v2/errors.go
+++ b/vendor/github.com/pion/dtls/v2/errors.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
@@ -8,174 +11,147 @@ import (
"net"
"os"
- "golang.org/x/xerrors"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
)
// Typed errors
var (
- ErrConnClosed = &FatalError{errors.New("conn is closed")}
-
- errDeadlineExceeded = &TimeoutError{xerrors.Errorf("read/write timeout: %w", context.DeadlineExceeded)}
-
- errBufferTooSmall = &TemporaryError{errors.New("buffer is too small")}
- errContextUnsupported = &TemporaryError{errors.New("context is not supported for ExportKeyingMaterial")}
- errDTLSPacketInvalidLength = &TemporaryError{errors.New("packet is too short")}
- errHandshakeInProgress = &TemporaryError{errors.New("handshake is in progress")}
- errInvalidContentType = &TemporaryError{errors.New("invalid content type")}
- errInvalidMAC = &TemporaryError{errors.New("invalid mac")}
- errInvalidPacketLength = &TemporaryError{errors.New("packet length and declared length do not match")}
- errReservedExportKeyingMaterial = &TemporaryError{errors.New("ExportKeyingMaterial can not be used with a reserved label")}
-
- errCertificateVerifyNoCertificate = &FatalError{errors.New("client sent certificate verify but we have no certificate to verify")}
- errCipherSuiteNoIntersection = &FatalError{errors.New("client+server do not support any shared cipher suites")}
- errCipherSuiteUnset = &FatalError{errors.New("server hello can not be created without a cipher suite")}
- errClientCertificateNotVerified = &FatalError{errors.New("client sent certificate but did not verify it")}
- errClientCertificateRequired = &FatalError{errors.New("server required client verification, but got none")}
- errClientNoMatchingSRTPProfile = &FatalError{errors.New("server responded with SRTP Profile we do not support")}
- errClientRequiredButNoServerEMS = &FatalError{errors.New("client required Extended Master Secret extension, but server does not support it")}
- errCompressionMethodUnset = &FatalError{errors.New("server hello can not be created without a compression method")}
- errCookieMismatch = &FatalError{errors.New("client+server cookie does not match")}
- errCookieTooLong = &FatalError{errors.New("cookie must not be longer then 255 bytes")}
- errHandshakeTimeout = &FatalError{xerrors.Errorf("the connection timed out during the handshake: %w", context.DeadlineExceeded)}
- errIdentityNoPSK = &FatalError{errors.New("PSK Identity Hint provided but PSK is nil")}
- errInvalidCertificate = &FatalError{errors.New("no certificate provided")}
- errInvalidCipherSpec = &FatalError{errors.New("cipher spec invalid")}
- errInvalidCipherSuite = &FatalError{errors.New("invalid or unknown cipher suite")}
- errInvalidClientKeyExchange = &FatalError{errors.New("unable to determine if ClientKeyExchange is a public key or PSK Identity")}
- errInvalidCompressionMethod = &FatalError{errors.New("invalid or unknown compression method")}
- errInvalidECDSASignature = &FatalError{errors.New("ECDSA signature contained zero or negative values")}
- errInvalidEllipticCurveType = &FatalError{errors.New("invalid or unknown elliptic curve type")}
- errInvalidExtensionType = &FatalError{errors.New("invalid extension type")}
- errInvalidHashAlgorithm = &FatalError{errors.New("invalid hash algorithm")}
- errInvalidNamedCurve = &FatalError{errors.New("invalid named curve")}
- errInvalidPrivateKey = &FatalError{errors.New("invalid private key type")}
- errInvalidSNIFormat = &FatalError{errors.New("invalid server name format")}
- errInvalidSignatureAlgorithm = &FatalError{errors.New("invalid signature algorithm")}
- errKeySignatureMismatch = &FatalError{errors.New("expected and actual key signature do not match")}
- errNilNextConn = &FatalError{errors.New("Conn can not be created with a nil nextConn")}
- errNoAvailableCipherSuites = &FatalError{errors.New("connection can not be created, no CipherSuites satisfy this Config")}
- errNoAvailableSignatureSchemes = &FatalError{errors.New("connection can not be created, no SignatureScheme satisfy this Config")}
- errNoCertificates = &FatalError{errors.New("no certificates configured")}
- errNoConfigProvided = &FatalError{errors.New("no config provided")}
- errNoSupportedEllipticCurves = &FatalError{errors.New("client requested zero or more elliptic curves that are not supported by the server")}
- errUnsupportedProtocolVersion = &FatalError{errors.New("unsupported protocol version")}
- errPSKAndCertificate = &FatalError{errors.New("Certificate and PSK provided")} // nolint:stylecheck
- errPSKAndIdentityMustBeSetForClient = &FatalError{errors.New("PSK and PSK Identity Hint must both be set for client")}
- errRequestedButNoSRTPExtension = &FatalError{errors.New("SRTP support was requested but server did not respond with use_srtp extension")}
- errServerMustHaveCertificate = &FatalError{errors.New("Certificate is mandatory for server")} // nolint:stylecheck
- errServerNoMatchingSRTPProfile = &FatalError{errors.New("client requested SRTP but we have no matching profiles")}
- errServerRequiredButNoClientEMS = &FatalError{errors.New("server requires the Extended Master Secret extension, but the client does not support it")}
- errVerifyDataMismatch = &FatalError{errors.New("expected and actual verify data does not match")}
-
- errHandshakeMessageUnset = &InternalError{errors.New("handshake message unset, unable to marshal")}
- errInvalidFlight = &InternalError{errors.New("invalid flight number")}
- errKeySignatureGenerateUnimplemented = &InternalError{errors.New("unable to generate key signature, unimplemented")}
- errKeySignatureVerifyUnimplemented = &InternalError{errors.New("unable to verify key signature, unimplemented")}
- errLengthMismatch = &InternalError{errors.New("data length and declared length do not match")}
- errNotEnoughRoomForNonce = &InternalError{errors.New("buffer not long enough to contain nonce")}
- errNotImplemented = &InternalError{errors.New("feature has not been implemented yet")}
- errSequenceNumberOverflow = &InternalError{errors.New("sequence number overflow")}
- errUnableToMarshalFragmented = &InternalError{errors.New("unable to marshal fragmented handshakes")}
+ ErrConnClosed = &FatalError{Err: errors.New("conn is closed")} //nolint:goerr113
+
+ errDeadlineExceeded = &TimeoutError{Err: fmt.Errorf("read/write timeout: %w", context.DeadlineExceeded)}
+ errInvalidContentType = &TemporaryError{Err: errors.New("invalid content type")} //nolint:goerr113
+
+ errBufferTooSmall = &TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113
+ errContextUnsupported = &TemporaryError{Err: errors.New("context is not supported for ExportKeyingMaterial")} //nolint:goerr113
+ errHandshakeInProgress = &TemporaryError{Err: errors.New("handshake is in progress")} //nolint:goerr113
+ errReservedExportKeyingMaterial = &TemporaryError{Err: errors.New("ExportKeyingMaterial can not be used with a reserved label")} //nolint:goerr113
+ errApplicationDataEpochZero = &TemporaryError{Err: errors.New("ApplicationData with epoch of 0")} //nolint:goerr113
+ errUnhandledContextType = &TemporaryError{Err: errors.New("unhandled contentType")} //nolint:goerr113
+
+ errCertificateVerifyNoCertificate = &FatalError{Err: errors.New("client sent certificate verify but we have no certificate to verify")} //nolint:goerr113
+ errCipherSuiteNoIntersection = &FatalError{Err: errors.New("client+server do not support any shared cipher suites")} //nolint:goerr113
+ errClientCertificateNotVerified = &FatalError{Err: errors.New("client sent certificate but did not verify it")} //nolint:goerr113
+ errClientCertificateRequired = &FatalError{Err: errors.New("server required client verification, but got none")} //nolint:goerr113
+ errClientNoMatchingSRTPProfile = &FatalError{Err: errors.New("server responded with SRTP Profile we do not support")} //nolint:goerr113
+ errClientRequiredButNoServerEMS = &FatalError{Err: errors.New("client required Extended Master Secret extension, but server does not support it")} //nolint:goerr113
+ errCookieMismatch = &FatalError{Err: errors.New("client+server cookie does not match")} //nolint:goerr113
+ errIdentityNoPSK = &FatalError{Err: errors.New("PSK Identity Hint provided but PSK is nil")} //nolint:goerr113
+ errInvalidCertificate = &FatalError{Err: errors.New("no certificate provided")} //nolint:goerr113
+ errInvalidCipherSuite = &FatalError{Err: errors.New("invalid or unknown cipher suite")} //nolint:goerr113
+ errInvalidECDSASignature = &FatalError{Err: errors.New("ECDSA signature contained zero or negative values")} //nolint:goerr113
+ errInvalidPrivateKey = &FatalError{Err: errors.New("invalid private key type")} //nolint:goerr113
+ errInvalidSignatureAlgorithm = &FatalError{Err: errors.New("invalid signature algorithm")} //nolint:goerr113
+ errKeySignatureMismatch = &FatalError{Err: errors.New("expected and actual key signature do not match")} //nolint:goerr113
+ errNilNextConn = &FatalError{Err: errors.New("Conn can not be created with a nil nextConn")} //nolint:goerr113
+ errNoAvailableCipherSuites = &FatalError{Err: errors.New("connection can not be created, no CipherSuites satisfy this Config")} //nolint:goerr113
+ errNoAvailablePSKCipherSuite = &FatalError{Err: errors.New("connection can not be created, pre-shared key present but no compatible CipherSuite")} //nolint:goerr113
+ errNoAvailableCertificateCipherSuite = &FatalError{Err: errors.New("connection can not be created, certificate present but no compatible CipherSuite")} //nolint:goerr113
+ errNoAvailableSignatureSchemes = &FatalError{Err: errors.New("connection can not be created, no SignatureScheme satisfy this Config")} //nolint:goerr113
+ errNoCertificates = &FatalError{Err: errors.New("no certificates configured")} //nolint:goerr113
+ errNoConfigProvided = &FatalError{Err: errors.New("no config provided")} //nolint:goerr113
+ errNoSupportedEllipticCurves = &FatalError{Err: errors.New("client requested zero or more elliptic curves that are not supported by the server")} //nolint:goerr113
+ errUnsupportedProtocolVersion = &FatalError{Err: errors.New("unsupported protocol version")} //nolint:goerr113
+ errPSKAndIdentityMustBeSetForClient = &FatalError{Err: errors.New("PSK and PSK Identity Hint must both be set for client")} //nolint:goerr113
+ errRequestedButNoSRTPExtension = &FatalError{Err: errors.New("SRTP support was requested but server did not respond with use_srtp extension")} //nolint:goerr113
+ errServerNoMatchingSRTPProfile = &FatalError{Err: errors.New("client requested SRTP but we have no matching profiles")} //nolint:goerr113
+ errServerRequiredButNoClientEMS = &FatalError{Err: errors.New("server requires the Extended Master Secret extension, but the client does not support it")} //nolint:goerr113
+ errVerifyDataMismatch = &FatalError{Err: errors.New("expected and actual verify data does not match")} //nolint:goerr113
+ errNotAcceptableCertificateChain = &FatalError{Err: errors.New("certificate chain is not signed by an acceptable CA")} //nolint:goerr113
+
+ errInvalidFlight = &InternalError{Err: errors.New("invalid flight number")} //nolint:goerr113
+ errKeySignatureGenerateUnimplemented = &InternalError{Err: errors.New("unable to generate key signature, unimplemented")} //nolint:goerr113
+ errKeySignatureVerifyUnimplemented = &InternalError{Err: errors.New("unable to verify key signature, unimplemented")} //nolint:goerr113
+ errLengthMismatch = &InternalError{Err: errors.New("data length and declared length do not match")} //nolint:goerr113
+ errSequenceNumberOverflow = &InternalError{Err: errors.New("sequence number overflow")} //nolint:goerr113
+ errInvalidFSMTransition = &InternalError{Err: errors.New("invalid state machine transition")} //nolint:goerr113
+ errFailedToAccessPoolReadBuffer = &InternalError{Err: errors.New("failed to access pool read buffer")} //nolint:goerr113
+ errFragmentBufferOverflow = &InternalError{Err: errors.New("fragment buffer overflow")} //nolint:goerr113
)
// FatalError indicates that the DTLS connection is no longer available.
// It is mainly caused by wrong configuration of server or client.
-type FatalError struct {
- Err error
-}
+type FatalError = protocol.FatalError
// InternalError indicates and internal error caused by the implementation, and the DTLS connection is no longer available.
// It is mainly caused by bugs or tried to use unimplemented features.
-type InternalError struct {
- Err error
-}
+type InternalError = protocol.InternalError
// TemporaryError indicates that the DTLS connection is still available, but the request was failed temporary.
-type TemporaryError struct {
- Err error
-}
+type TemporaryError = protocol.TemporaryError
// TimeoutError indicates that the request was timed out.
-type TimeoutError struct {
- Err error
-}
-
-// Timeout implements net.Error.Timeout()
-func (*FatalError) Timeout() bool { return false }
-
-// Temporary implements net.Error.Temporary()
-func (*FatalError) Temporary() bool { return false }
-
-// Unwrap implements Go1.13 error unwrapper.
-func (e *FatalError) Unwrap() error { return e.Err }
-
-func (e *FatalError) Error() string { return fmt.Sprintf("dtls fatal: %v", e.Err) }
-
-// Timeout implements net.Error.Timeout()
-func (*InternalError) Timeout() bool { return false }
-
-// Temporary implements net.Error.Temporary()
-func (*InternalError) Temporary() bool { return false }
-
-// Unwrap implements Go1.13 error unwrapper.
-func (e *InternalError) Unwrap() error { return e.Err }
-
-func (e *InternalError) Error() string { return fmt.Sprintf("dtls internal: %v", e.Err) }
-
-// Timeout implements net.Error.Timeout()
-func (*TemporaryError) Timeout() bool { return false }
-
-// Temporary implements net.Error.Temporary()
-func (*TemporaryError) Temporary() bool { return true }
+type TimeoutError = protocol.TimeoutError
-// Unwrap implements Go1.13 error unwrapper.
-func (e *TemporaryError) Unwrap() error { return e.Err }
+// HandshakeError indicates that the handshake failed.
+type HandshakeError = protocol.HandshakeError
-func (e *TemporaryError) Error() string { return fmt.Sprintf("dtls temporary: %v", e.Err) }
-
-// Timeout implements net.Error.Timeout()
-func (*TimeoutError) Timeout() bool { return true }
-
-// Temporary implements net.Error.Temporary()
-func (*TimeoutError) Temporary() bool { return true }
+// errInvalidCipherSuite indicates an attempt at using an unsupported cipher suite.
+type invalidCipherSuiteError struct {
+ id CipherSuiteID
+}
-// Unwrap implements Go1.13 error unwrapper.
-func (e *TimeoutError) Unwrap() error { return e.Err }
+func (e *invalidCipherSuiteError) Error() string {
+ return fmt.Sprintf("CipherSuite with id(%d) is not valid", e.id)
+}
-func (e *TimeoutError) Error() string { return fmt.Sprintf("dtls timeout: %v", e.Err) }
+func (e *invalidCipherSuiteError) Is(err error) bool {
+ var other *invalidCipherSuiteError
+ if errors.As(err, &other) {
+ return e.id == other.id
+ }
+ return false
+}
// errAlert wraps DTLS alert notification as an error
-type errAlert struct {
- *alert
+type alertError struct {
+ *alert.Alert
+}
+
+func (e *alertError) Error() string {
+ return fmt.Sprintf("alert: %s", e.Alert.String())
}
-func (e *errAlert) Error() string {
- return fmt.Sprintf("alert: %s", e.alert.String())
+func (e *alertError) IsFatalOrCloseNotify() bool {
+ return e.Level == alert.Fatal || e.Description == alert.CloseNotify
}
-func (e *errAlert) IsFatalOrCloseNotify() bool {
- return e.alertLevel == alertLevelFatal || e.alertDescription == alertCloseNotify
+func (e *alertError) Is(err error) bool {
+ var other *alertError
+ if errors.As(err, &other) {
+ return e.Level == other.Level && e.Description == other.Description
+ }
+ return false
}
// netError translates an error from underlying Conn to corresponding net.Error.
func netError(err error) error {
- switch err {
- case io.EOF, context.Canceled, context.DeadlineExceeded:
+ switch {
+ case errors.Is(err, io.EOF), errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):
// Return io.EOF and context errors as is.
return err
}
- switch e := err.(type) {
- case (*net.OpError):
- if se, ok := e.Err.(*os.SyscallError); ok {
+
+ var (
+ ne net.Error
+ opError *net.OpError
+ se *os.SyscallError
+ )
+
+ if errors.As(err, &opError) {
+ if errors.As(opError, &se) {
if se.Timeout() {
- return &TimeoutError{err}
+ return &TimeoutError{Err: err}
}
if isOpErrorTemporary(se) {
- return &TemporaryError{err}
+ return &TemporaryError{Err: err}
}
}
- case (net.Error):
+ }
+
+ if errors.As(err, &ne) {
return err
}
- return &FatalError{err}
+
+ return &FatalError{Err: err}
}
diff --git a/vendor/github.com/pion/dtls/v2/errors_errno.go b/vendor/github.com/pion/dtls/v2/errors_errno.go
index a9a439b..f8e424e 100644
--- a/vendor/github.com/pion/dtls/v2/errors_errno.go
+++ b/vendor/github.com/pion/dtls/v2/errors_errno.go
@@ -1,3 +1,7 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+//go:build aix || darwin || dragonfly || freebsd || linux || nacl || nacljs || netbsd || openbsd || solaris || windows
// +build aix darwin dragonfly freebsd linux nacl nacljs netbsd openbsd solaris windows
// For systems having syscall.Errno.
@@ -8,18 +12,11 @@
package dtls
import (
+ "errors"
"os"
"syscall"
)
func isOpErrorTemporary(err *os.SyscallError) bool {
- if ne, ok := err.Err.(syscall.Errno); ok {
- switch ne {
- case syscall.ECONNREFUSED:
- return true
- default:
- return false
- }
- }
- return false
+ return errors.Is(err.Err, syscall.ECONNREFUSED)
}
diff --git a/vendor/github.com/pion/dtls/v2/errors_noerrno.go b/vendor/github.com/pion/dtls/v2/errors_noerrno.go
index fcc37ce..844ff1e 100644
--- a/vendor/github.com/pion/dtls/v2/errors_noerrno.go
+++ b/vendor/github.com/pion/dtls/v2/errors_noerrno.go
@@ -1,3 +1,7 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !nacl && !nacljs && !netbsd && !openbsd && !solaris && !windows
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!nacl,!nacljs,!netbsd,!openbsd,!solaris,!windows
// For systems without syscall.Errno.
diff --git a/vendor/github.com/pion/dtls/v2/extension.go b/vendor/github.com/pion/dtls/v2/extension.go
deleted file mode 100644
index 9e4bdb4..0000000
--- a/vendor/github.com/pion/dtls/v2/extension.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
-type extensionValue uint16
-
-const (
- extensionServerNameValue extensionValue = 0
- extensionSupportedEllipticCurvesValue extensionValue = 10
- extensionSupportedPointFormatsValue extensionValue = 11
- extensionSupportedSignatureAlgorithmsValue extensionValue = 13
- extensionUseSRTPValue extensionValue = 14
- extensionUseExtendedMasterSecretValue extensionValue = 23
-)
-
-type extension interface {
- Marshal() ([]byte, error)
- Unmarshal(data []byte) error
-
- extensionValue() extensionValue
-}
-
-func decodeExtensions(buf []byte) ([]extension, error) {
- if len(buf) < 2 {
- return nil, errBufferTooSmall
- }
- declaredLen := binary.BigEndian.Uint16(buf)
- if len(buf)-2 != int(declaredLen) {
- return nil, errLengthMismatch
- }
-
- extensions := []extension{}
- unmarshalAndAppend := func(data []byte, e extension) error {
- err := e.Unmarshal(data)
- if err != nil {
- return err
- }
- extensions = append(extensions, e)
- return nil
- }
-
- for offset := 2; offset < len(buf); {
- if len(buf) < (offset + 2) {
- return nil, errBufferTooSmall
- }
- var err error
- switch extensionValue(binary.BigEndian.Uint16(buf[offset:])) {
- case extensionServerNameValue:
- err = unmarshalAndAppend(buf[offset:], &extensionServerName{})
- case extensionSupportedEllipticCurvesValue:
- err = unmarshalAndAppend(buf[offset:], &extensionSupportedEllipticCurves{})
- case extensionUseSRTPValue:
- err = unmarshalAndAppend(buf[offset:], &extensionUseSRTP{})
- case extensionUseExtendedMasterSecretValue:
- err = unmarshalAndAppend(buf[offset:], &extensionUseExtendedMasterSecret{})
- default:
- }
- if err != nil {
- return nil, err
- }
- if len(buf) < (offset + 4) {
- return nil, errBufferTooSmall
- }
- extensionLength := binary.BigEndian.Uint16(buf[offset+2:])
- offset += (4 + int(extensionLength))
- }
- return extensions, nil
-}
-
-func encodeExtensions(e []extension) ([]byte, error) {
- extensions := []byte{}
- for _, e := range e {
- raw, err := e.Marshal()
- if err != nil {
- return nil, err
- }
- extensions = append(extensions, raw...)
- }
- out := []byte{0x00, 0x00}
- binary.BigEndian.PutUint16(out, uint16(len(extensions)))
- return append(out, extensions...), nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/extension_server_name.go b/vendor/github.com/pion/dtls/v2/extension_server_name.go
deleted file mode 100644
index 07eddc2..0000000
--- a/vendor/github.com/pion/dtls/v2/extension_server_name.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package dtls
-
-import (
- "strings"
-
- "golang.org/x/crypto/cryptobyte"
-)
-
-const extensionServerNameTypeDNSHostName = 0
-
-type extensionServerName struct {
- serverName string
-}
-
-func (e extensionServerName) extensionValue() extensionValue {
- return extensionServerNameValue
-}
-
-func (e *extensionServerName) Marshal() ([]byte, error) {
- var b cryptobyte.Builder
- b.AddUint16(uint16(e.extensionValue()))
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint8(extensionServerNameTypeDNSHostName)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes([]byte(e.serverName))
- })
- })
- })
- return b.Bytes()
-}
-
-func (e *extensionServerName) Unmarshal(data []byte) error {
- s := cryptobyte.String(data)
- var extension uint16
- s.ReadUint16(&extension)
- if extensionValue(extension) != e.extensionValue() {
- return errInvalidExtensionType
- }
-
- var extData cryptobyte.String
- s.ReadUint16LengthPrefixed(&extData)
-
- var nameList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() {
- return errInvalidSNIFormat
- }
- for !nameList.Empty() {
- var nameType uint8
- var serverName cryptobyte.String
- if !nameList.ReadUint8(&nameType) ||
- !nameList.ReadUint16LengthPrefixed(&serverName) ||
- serverName.Empty() {
- return errInvalidSNIFormat
- }
- if nameType != extensionServerNameTypeDNSHostName {
- continue
- }
- if len(e.serverName) != 0 {
- // Multiple names of the same name_type are prohibited.
- return errInvalidSNIFormat
- }
- e.serverName = string(serverName)
- // An SNI value may not include a trailing dot.
- if strings.HasSuffix(e.serverName, ".") {
- return errInvalidSNIFormat
- }
- }
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/extension_supported_elliptic_curves.go b/vendor/github.com/pion/dtls/v2/extension_supported_elliptic_curves.go
deleted file mode 100644
index 3eef92c..0000000
--- a/vendor/github.com/pion/dtls/v2/extension_supported_elliptic_curves.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-const (
- extensionSupportedGroupsHeaderSize = 6
-)
-
-// https://tools.ietf.org/html/rfc8422#section-5.1.1
-type extensionSupportedEllipticCurves struct {
- ellipticCurves []namedCurve
-}
-
-func (e extensionSupportedEllipticCurves) extensionValue() extensionValue {
- return extensionSupportedEllipticCurvesValue
-}
-
-func (e *extensionSupportedEllipticCurves) Marshal() ([]byte, error) {
- out := make([]byte, extensionSupportedGroupsHeaderSize)
-
- binary.BigEndian.PutUint16(out, uint16(e.extensionValue()))
- binary.BigEndian.PutUint16(out[2:], uint16(2+(len(e.ellipticCurves)*2)))
- binary.BigEndian.PutUint16(out[4:], uint16(len(e.ellipticCurves)*2))
-
- for _, v := range e.ellipticCurves {
- out = append(out, []byte{0x00, 0x00}...)
- binary.BigEndian.PutUint16(out[len(out)-2:], uint16(v))
- }
-
- return out, nil
-}
-
-func (e *extensionSupportedEllipticCurves) Unmarshal(data []byte) error {
- if len(data) <= extensionSupportedGroupsHeaderSize {
- return errBufferTooSmall
- } else if extensionValue(binary.BigEndian.Uint16(data)) != e.extensionValue() {
- return errInvalidExtensionType
- }
-
- groupCount := int(binary.BigEndian.Uint16(data[4:]) / 2)
- if extensionSupportedGroupsHeaderSize+(groupCount*2) > len(data) {
- return errLengthMismatch
- }
-
- for i := 0; i < groupCount; i++ {
- supportedGroupID := namedCurve(binary.BigEndian.Uint16(data[(extensionSupportedGroupsHeaderSize + (i * 2)):]))
- if _, ok := namedCurves[supportedGroupID]; ok {
- e.ellipticCurves = append(e.ellipticCurves, supportedGroupID)
- }
- }
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/extension_supported_point_formats.go b/vendor/github.com/pion/dtls/v2/extension_supported_point_formats.go
deleted file mode 100644
index 5f2d968..0000000
--- a/vendor/github.com/pion/dtls/v2/extension_supported_point_formats.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package dtls
-
-import "encoding/binary"
-
-const (
- extensionSupportedPointFormatsSize = 5
-)
-
-type ellipticCurvePointFormat byte
-
-const ellipticCurvePointFormatUncompressed ellipticCurvePointFormat = 0
-
-// https://tools.ietf.org/html/rfc4492#section-5.1.2
-type extensionSupportedPointFormats struct {
- pointFormats []ellipticCurvePointFormat
-}
-
-func (e extensionSupportedPointFormats) extensionValue() extensionValue {
- return extensionSupportedPointFormatsValue
-}
-
-func (e *extensionSupportedPointFormats) Marshal() ([]byte, error) {
- out := make([]byte, extensionSupportedPointFormatsSize)
-
- binary.BigEndian.PutUint16(out, uint16(e.extensionValue()))
- binary.BigEndian.PutUint16(out[2:], uint16(1+(len(e.pointFormats))))
- out[4] = byte(len(e.pointFormats))
-
- for _, v := range e.pointFormats {
- out = append(out, byte(v))
- }
- return out, nil
-}
-
-func (e *extensionSupportedPointFormats) Unmarshal(data []byte) error {
- if len(data) <= extensionSupportedPointFormatsSize {
- return errBufferTooSmall
- } else if extensionValue(binary.BigEndian.Uint16(data)) != e.extensionValue() {
- return errInvalidExtensionType
- }
-
- pointFormatCount := int(binary.BigEndian.Uint16(data[4:]))
- if extensionSupportedGroupsHeaderSize+(pointFormatCount) > len(data) {
- return errLengthMismatch
- }
-
- for i := 0; i < pointFormatCount; i++ {
- p := ellipticCurvePointFormat(data[extensionSupportedPointFormatsSize+i])
- switch p {
- case ellipticCurvePointFormatUncompressed:
- e.pointFormats = append(e.pointFormats, p)
- default:
- }
- }
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/extension_supported_signature_algorithms.go b/vendor/github.com/pion/dtls/v2/extension_supported_signature_algorithms.go
deleted file mode 100644
index 0a8a7a0..0000000
--- a/vendor/github.com/pion/dtls/v2/extension_supported_signature_algorithms.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-const (
- extensionSupportedSignatureAlgorithmsHeaderSize = 6
-)
-
-// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
-type extensionSupportedSignatureAlgorithms struct {
- signatureHashAlgorithms []signatureHashAlgorithm
-}
-
-func (e extensionSupportedSignatureAlgorithms) extensionValue() extensionValue {
- return extensionSupportedSignatureAlgorithmsValue
-}
-
-func (e *extensionSupportedSignatureAlgorithms) Marshal() ([]byte, error) {
- out := make([]byte, extensionSupportedSignatureAlgorithmsHeaderSize)
-
- binary.BigEndian.PutUint16(out, uint16(e.extensionValue()))
- binary.BigEndian.PutUint16(out[2:], uint16(2+(len(e.signatureHashAlgorithms)*2)))
- binary.BigEndian.PutUint16(out[4:], uint16(len(e.signatureHashAlgorithms)*2))
- for _, v := range e.signatureHashAlgorithms {
- out = append(out, []byte{0x00, 0x00}...)
- out[len(out)-2] = byte(v.hash)
- out[len(out)-1] = byte(v.signature)
- }
-
- return out, nil
-}
-
-func (e *extensionSupportedSignatureAlgorithms) Unmarshal(data []byte) error {
- if len(data) <= extensionSupportedSignatureAlgorithmsHeaderSize {
- return errBufferTooSmall
- } else if extensionValue(binary.BigEndian.Uint16(data)) != e.extensionValue() {
- return errInvalidExtensionType
- }
-
- algorithmCount := int(binary.BigEndian.Uint16(data[4:]) / 2)
- if extensionSupportedSignatureAlgorithmsHeaderSize+(algorithmCount*2) > len(data) {
- return errLengthMismatch
- }
- for i := 0; i < algorithmCount; i++ {
- supportedHashAlgorithm := hashAlgorithm(data[extensionSupportedSignatureAlgorithmsHeaderSize+(i*2)])
- supportedSignatureAlgorithm := signatureAlgorithm(data[extensionSupportedSignatureAlgorithmsHeaderSize+(i*2)+1])
- if _, ok := hashAlgorithms[supportedHashAlgorithm]; ok {
- if _, ok := signatureAlgorithms[supportedSignatureAlgorithm]; ok {
- e.signatureHashAlgorithms = append(e.signatureHashAlgorithms, signatureHashAlgorithm{
- supportedHashAlgorithm,
- supportedSignatureAlgorithm,
- })
- }
- }
- }
-
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/extension_use_master_secret.go b/vendor/github.com/pion/dtls/v2/extension_use_master_secret.go
deleted file mode 100644
index 50d5413..0000000
--- a/vendor/github.com/pion/dtls/v2/extension_use_master_secret.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package dtls
-
-import "encoding/binary"
-
-const (
- extensionUseExtendedMasterSecretHeaderSize = 4
-)
-
-// https://tools.ietf.org/html/rfc8422
-type extensionUseExtendedMasterSecret struct {
- supported bool
-}
-
-func (e extensionUseExtendedMasterSecret) extensionValue() extensionValue {
- return extensionUseExtendedMasterSecretValue
-}
-
-func (e *extensionUseExtendedMasterSecret) Marshal() ([]byte, error) {
- if !e.supported {
- return []byte{}, nil
- }
-
- out := make([]byte, extensionUseExtendedMasterSecretHeaderSize)
-
- binary.BigEndian.PutUint16(out, uint16(e.extensionValue()))
- binary.BigEndian.PutUint16(out[2:], uint16(0)) // length
- return out, nil
-}
-
-func (e *extensionUseExtendedMasterSecret) Unmarshal(data []byte) error {
- if len(data) < extensionUseExtendedMasterSecretHeaderSize {
- return errBufferTooSmall
- } else if extensionValue(binary.BigEndian.Uint16(data)) != e.extensionValue() {
- return errInvalidExtensionType
- }
-
- e.supported = true
-
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/extension_use_srtp.go b/vendor/github.com/pion/dtls/v2/extension_use_srtp.go
deleted file mode 100644
index f89a671..0000000
--- a/vendor/github.com/pion/dtls/v2/extension_use_srtp.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package dtls
-
-import "encoding/binary"
-
-const (
- extensionUseSRTPHeaderSize = 6
-)
-
-// https://tools.ietf.org/html/rfc8422
-type extensionUseSRTP struct {
- protectionProfiles []SRTPProtectionProfile
-}
-
-func (e extensionUseSRTP) extensionValue() extensionValue {
- return extensionUseSRTPValue
-}
-
-func (e *extensionUseSRTP) Marshal() ([]byte, error) {
- out := make([]byte, extensionUseSRTPHeaderSize)
-
- binary.BigEndian.PutUint16(out, uint16(e.extensionValue()))
- binary.BigEndian.PutUint16(out[2:], uint16(2+(len(e.protectionProfiles)*2)+ /* MKI Length */ 1))
- binary.BigEndian.PutUint16(out[4:], uint16(len(e.protectionProfiles)*2))
-
- for _, v := range e.protectionProfiles {
- out = append(out, []byte{0x00, 0x00}...)
- binary.BigEndian.PutUint16(out[len(out)-2:], uint16(v))
- }
-
- out = append(out, 0x00) /* MKI Length */
- return out, nil
-}
-
-func (e *extensionUseSRTP) Unmarshal(data []byte) error {
- if len(data) <= extensionUseSRTPHeaderSize {
- return errBufferTooSmall
- } else if extensionValue(binary.BigEndian.Uint16(data)) != e.extensionValue() {
- return errInvalidExtensionType
- }
-
- profileCount := int(binary.BigEndian.Uint16(data[4:]) / 2)
- if extensionSupportedGroupsHeaderSize+(profileCount*2) > len(data) {
- return errLengthMismatch
- }
-
- for i := 0; i < profileCount; i++ {
- supportedProfile := SRTPProtectionProfile(binary.BigEndian.Uint16(data[(extensionUseSRTPHeaderSize + (i * 2)):]))
- if _, ok := srtpProtectionProfiles[supportedProfile]; ok {
- e.protectionProfiles = append(e.protectionProfiles, supportedProfile)
- }
- }
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/flight.go b/vendor/github.com/pion/dtls/v2/flight.go
index 580ee48..cfa58c5 100644
--- a/vendor/github.com/pion/dtls/v2/flight.go
+++ b/vendor/github.com/pion/dtls/v2/flight.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
/*
@@ -6,6 +9,9 @@ package dtls
of a number of messages, they should be viewed as monolithic for the
purpose of timeout and retransmission.
https://tools.ietf.org/html/rfc4347#section-4.2.4
+
+ Message flights for full handshake:
+
Client Server
------ ------
Waiting Flight 0
@@ -31,6 +37,23 @@ package dtls
[ChangeCipherSpec] \ Flight 6
<-------- Finished /
+ Message flights for session-resuming handshake (no cookie exchange):
+
+ Client Server
+ ------ ------
+ Waiting Flight 0
+
+ ClientHello --------> Flight 1
+
+ ServerHello \
+ [ChangeCipherSpec] Flight 4b
+ <-------- Finished /
+
+ [ChangeCipherSpec] \ Flight 5b
+ Finished --------> /
+
+ [ChangeCipherSpec] \ Flight 6
+ <-------- Finished /
*/
type flightVal uint8
@@ -41,7 +64,9 @@ const (
flight2
flight3
flight4
+ flight4b
flight5
+ flight5b
flight6
)
@@ -57,8 +82,12 @@ func (f flightVal) String() string {
return "Flight 3"
case flight4:
return "Flight 4"
+ case flight4b:
+ return "Flight 4b"
case flight5:
return "Flight 5"
+ case flight5b:
+ return "Flight 5b"
case flight6:
return "Flight 6"
default:
@@ -67,9 +96,9 @@ func (f flightVal) String() string {
}
func (f flightVal) isLastSendFlight() bool {
- return f == flight6
+ return f == flight6 || f == flight5b
}
func (f flightVal) isLastRecvFlight() bool {
- return f == flight5
+ return f == flight5 || f == flight4b
}
diff --git a/vendor/github.com/pion/dtls/v2/flight0handler.go b/vendor/github.com/pion/dtls/v2/flight0handler.go
index 3c14af4..648c528 100644
--- a/vendor/github.com/pion/dtls/v2/flight0handler.go
+++ b/vendor/github.com/pion/dtls/v2/flight0handler.go
@@ -1,83 +1,146 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
"context"
"crypto/rand"
+
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/extension"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
)
-func flight0Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert, error) {
- // HelloVerifyRequest can be skipped by the server,
- // so allow ServerHello during flight1 also
- seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence,
- handshakeCachePullRule{handshakeTypeClientHello, cfg.initialEpoch, true, false},
+func flight0Parse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) {
+ seq, msgs, ok := cache.fullPullMap(0, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
)
if !ok {
// No valid message received. Keep reading
- return flight0, nil, nil
+ return 0, nil, nil
}
+
+ // Connection Identifiers must be negotiated afresh on session resumption.
+ // https://datatracker.ietf.org/doc/html/rfc9146#name-the-connection_id-extension
+ state.localConnectionID = nil
+ state.remoteConnectionID = nil
+
state.handshakeRecvSequence = seq
- var clientHello *handshakeMessageClientHello
+ var clientHello *handshake.MessageClientHello
// Validate type
- if clientHello, ok = msgs[handshakeTypeClientHello].(*handshakeMessageClientHello); !ok {
- return 0, &alert{alertLevelFatal, alertInternalError}, nil
+ if clientHello, ok = msgs[handshake.TypeClientHello].(*handshake.MessageClientHello); !ok {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
}
- if !clientHello.version.Equal(protocolVersion1_2) {
- return 0, &alert{alertLevelFatal, alertProtocolVersion}, errUnsupportedProtocolVersion
+ if !clientHello.Version.Equal(protocol.Version1_2) {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion
}
- state.remoteRandom = clientHello.random
+ state.remoteRandom = clientHello.Random
- if _, ok := findMatchingCipherSuite(clientHello.cipherSuites, cfg.localCipherSuites); !ok {
- return 0, &alert{alertLevelFatal, alertInsufficientSecurity}, errCipherSuiteNoIntersection
+ cipherSuites := []CipherSuite{}
+ for _, id := range clientHello.CipherSuiteIDs {
+ if c := cipherSuiteForID(CipherSuiteID(id), cfg.customCipherSuites); c != nil {
+ cipherSuites = append(cipherSuites, c)
+ }
}
- state.cipherSuite = clientHello.cipherSuites[0]
+ if state.cipherSuite, ok = findMatchingCipherSuite(cipherSuites, cfg.localCipherSuites); !ok {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errCipherSuiteNoIntersection
+ }
- for _, extension := range clientHello.extensions {
- switch e := extension.(type) {
- case *extensionSupportedEllipticCurves:
- if len(e.ellipticCurves) == 0 {
- return 0, &alert{alertLevelFatal, alertInsufficientSecurity}, errNoSupportedEllipticCurves
+ for _, val := range clientHello.Extensions {
+ switch e := val.(type) {
+ case *extension.SupportedEllipticCurves:
+ if len(e.EllipticCurves) == 0 {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errNoSupportedEllipticCurves
}
- state.namedCurve = e.ellipticCurves[0]
- case *extensionUseSRTP:
- profile, ok := findMatchingSRTPProfile(e.protectionProfiles, cfg.localSRTPProtectionProfiles)
+ state.namedCurve = e.EllipticCurves[0]
+ case *extension.UseSRTP:
+ profile, ok := findMatchingSRTPProfile(e.ProtectionProfiles, cfg.localSRTPProtectionProfiles)
if !ok {
- return 0, &alert{alertLevelFatal, alertInsufficientSecurity}, errServerNoMatchingSRTPProfile
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errServerNoMatchingSRTPProfile
}
state.srtpProtectionProfile = profile
- case *extensionUseExtendedMasterSecret:
+ case *extension.UseExtendedMasterSecret:
if cfg.extendedMasterSecret != DisableExtendedMasterSecret {
state.extendedMasterSecret = true
}
- case *extensionServerName:
- state.serverName = e.serverName // remote server name
+ case *extension.ServerName:
+ state.serverName = e.ServerName // remote server name
+ case *extension.ALPN:
+ state.peerSupportedProtocols = e.ProtocolNameList
+ case *extension.ConnectionID:
+ // Only set connection ID to be sent if server supports connection
+ // IDs.
+ if cfg.connectionIDGenerator != nil {
+ state.remoteConnectionID = e.CID
+ }
}
}
+ // If the client doesn't support connection IDs, the server should not
+ // expect one to be sent.
+ if state.remoteConnectionID == nil {
+ state.localConnectionID = nil
+ }
+
if cfg.extendedMasterSecret == RequireExtendedMasterSecret && !state.extendedMasterSecret {
- return 0, &alert{alertLevelFatal, alertInsufficientSecurity}, errServerRequiredButNoClientEMS
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errServerRequiredButNoClientEMS
}
if state.localKeypair == nil {
var err error
- state.localKeypair, err = generateKeypair(state.namedCurve)
+ state.localKeypair, err = elliptic.GenerateKeypair(state.namedCurve)
if err != nil {
- return 0, &alert{alertLevelFatal, alertIllegalParameter}, err
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.IllegalParameter}, err
}
}
- return flight2, nil, nil
+ nextFlight := flight2
+
+ if cfg.insecureSkipHelloVerify {
+ nextFlight = flight4
+ }
+
+ return handleHelloResume(clientHello.SessionID, state, cfg, nextFlight)
}
-func flight0Generate(c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert, error) {
+func handleHelloResume(sessionID []byte, state *State, cfg *handshakeConfig, next flightVal) (flightVal, *alert.Alert, error) {
+ if len(sessionID) > 0 && cfg.sessionStore != nil {
+ if s, err := cfg.sessionStore.Get(sessionID); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ } else if s.ID != nil {
+ cfg.log.Tracef("[handshake] resume session: %x", sessionID)
+
+ state.SessionID = sessionID
+ state.masterSecret = s.Secret
+
+ if err := state.initCipherSuite(); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+
+ clientRandom := state.localRandom.MarshalFixed()
+ cfg.writeKeyLog(keyLogLabelTLS12, clientRandom[:], state.masterSecret)
+
+ return flight4b, nil, nil
+ }
+ }
+ return next, nil, nil
+}
+
+func flight0Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) {
// Initialize
- state.cookie = make([]byte, cookieLength)
- if _, err := rand.Read(state.cookie); err != nil {
- return nil, nil, err
+ if !cfg.insecureSkipHelloVerify {
+ state.cookie = make([]byte, cookieLength)
+ if _, err := rand.Read(state.cookie); err != nil {
+ return nil, nil, err
+ }
}
var zeroEpoch uint16
@@ -85,7 +148,7 @@ func flight0Generate(c flightConn, state *State, cache *handshakeCache, cfg *han
state.remoteEpoch.Store(zeroEpoch)
state.namedCurve = defaultNamedCurve
- if err := state.localRandom.populate(); err != nil {
+ if err := state.localRandom.Populate(); err != nil {
return nil, nil, err
}
diff --git a/vendor/github.com/pion/dtls/v2/flight1handler.go b/vendor/github.com/pion/dtls/v2/flight1handler.go
index 88e9607..48bc882 100644
--- a/vendor/github.com/pion/dtls/v2/flight1handler.go
+++ b/vendor/github.com/pion/dtls/v2/flight1handler.go
@@ -1,100 +1,155 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
"context"
+
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/extension"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
)
-func flight1Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert, error) {
+func flight1Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) {
// HelloVerifyRequest can be skipped by the server,
// so allow ServerHello during flight1 also
- seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence,
- handshakeCachePullRule{handshakeTypeHelloVerifyRequest, cfg.initialEpoch, false, true},
- handshakeCachePullRule{handshakeTypeServerHello, cfg.initialEpoch, false, true},
+ seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeHelloVerifyRequest, cfg.initialEpoch, false, true},
+ handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, true},
)
if !ok {
// No valid message received. Keep reading
return 0, nil, nil
}
- state.handshakeRecvSequence = seq
- if h, ok := msgs[handshakeTypeHelloVerifyRequest].(*handshakeMessageHelloVerifyRequest); ok {
+ if _, ok := msgs[handshake.TypeServerHello]; ok {
+ // Flight1 and flight2 were skipped.
+ // Parse as flight3.
+ return flight3Parse(ctx, c, state, cache, cfg)
+ }
+
+ if h, ok := msgs[handshake.TypeHelloVerifyRequest].(*handshake.MessageHelloVerifyRequest); ok {
// DTLS 1.2 clients must not assume that the server will use the protocol version
// specified in HelloVerifyRequest message. RFC 6347 Section 4.2.1
- if !h.version.Equal(protocolVersion1_0) && !h.version.Equal(protocolVersion1_2) {
- return 0, &alert{alertLevelFatal, alertProtocolVersion}, errUnsupportedProtocolVersion
+ if !h.Version.Equal(protocol.Version1_0) && !h.Version.Equal(protocol.Version1_2) {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion
}
- state.cookie = append([]byte{}, h.cookie...)
+ state.cookie = append([]byte{}, h.Cookie...)
+ state.handshakeRecvSequence = seq
return flight3, nil, nil
}
- if _, ok := msgs[handshakeTypeServerHello]; ok {
- // Flight1 and flight2 were skipped.
- // Parse as flight3.
- return flight3Parse(ctx, c, state, cache, cfg)
- }
-
- return 0, &alert{alertLevelFatal, alertInternalError}, nil
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
}
-func flight1Generate(c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert, error) {
+func flight1Generate(c flightConn, state *State, _ *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) {
var zeroEpoch uint16
state.localEpoch.Store(zeroEpoch)
state.remoteEpoch.Store(zeroEpoch)
state.namedCurve = defaultNamedCurve
state.cookie = nil
- if err := state.localRandom.populate(); err != nil {
+ if err := state.localRandom.Populate(); err != nil {
return nil, nil, err
}
- extensions := []extension{
- &extensionSupportedSignatureAlgorithms{
- signatureHashAlgorithms: cfg.localSignatureSchemes,
+ extensions := []extension.Extension{
+ &extension.SupportedSignatureAlgorithms{
+ SignatureHashAlgorithms: cfg.localSignatureSchemes,
+ },
+ &extension.RenegotiationInfo{
+ RenegotiatedConnection: 0,
},
}
- if cfg.localPSKCallback == nil {
- extensions = append(extensions, []extension{
- &extensionSupportedEllipticCurves{
- ellipticCurves: []namedCurve{namedCurveX25519, namedCurveP256, namedCurveP384},
+
+ var setEllipticCurveCryptographyClientHelloExtensions bool
+ for _, c := range cfg.localCipherSuites {
+ if c.ECC() {
+ setEllipticCurveCryptographyClientHelloExtensions = true
+ break
+ }
+ }
+
+ if setEllipticCurveCryptographyClientHelloExtensions {
+ extensions = append(extensions, []extension.Extension{
+ &extension.SupportedEllipticCurves{
+ EllipticCurves: cfg.ellipticCurves,
},
- &extensionSupportedPointFormats{
- pointFormats: []ellipticCurvePointFormat{ellipticCurvePointFormatUncompressed},
+ &extension.SupportedPointFormats{
+ PointFormats: []elliptic.CurvePointFormat{elliptic.CurvePointFormatUncompressed},
},
}...)
}
if len(cfg.localSRTPProtectionProfiles) > 0 {
- extensions = append(extensions, &extensionUseSRTP{
- protectionProfiles: cfg.localSRTPProtectionProfiles,
+ extensions = append(extensions, &extension.UseSRTP{
+ ProtectionProfiles: cfg.localSRTPProtectionProfiles,
})
}
if cfg.extendedMasterSecret == RequestExtendedMasterSecret ||
cfg.extendedMasterSecret == RequireExtendedMasterSecret {
- extensions = append(extensions, &extensionUseExtendedMasterSecret{
- supported: true,
+ extensions = append(extensions, &extension.UseExtendedMasterSecret{
+ Supported: true,
})
}
if len(cfg.serverName) > 0 {
- extensions = append(extensions, &extensionServerName{serverName: cfg.serverName})
+ extensions = append(extensions, &extension.ServerName{ServerName: cfg.serverName})
+ }
+
+ if len(cfg.supportedProtocols) > 0 {
+ extensions = append(extensions, &extension.ALPN{ProtocolNameList: cfg.supportedProtocols})
+ }
+
+ if cfg.sessionStore != nil {
+ cfg.log.Tracef("[handshake] try to resume session")
+ if s, err := cfg.sessionStore.Get(c.sessionKey()); err != nil {
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ } else if s.ID != nil {
+ cfg.log.Tracef("[handshake] get saved session: %x", s.ID)
+
+ state.SessionID = s.ID
+ state.masterSecret = s.Secret
+ }
+ }
+
+ // If we have a connection ID generator, use it. The CID may be zero length,
+ // in which case we are just requesting that the server send us a CID to
+ // use.
+ if cfg.connectionIDGenerator != nil {
+ state.localConnectionID = cfg.connectionIDGenerator()
+ // The presence of a generator indicates support for connection IDs. We
+ // use the presence of a non-nil local CID in flight 3 to determine
+ // whether we send a CID in the second ClientHello, so we convert any
+ // nil CID returned by a generator to []byte{}.
+ if state.localConnectionID == nil {
+ state.localConnectionID = []byte{}
+ }
+ extensions = append(extensions, &extension.ConnectionID{CID: state.localConnectionID})
}
return []*packet{
{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ },
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageClientHello{
+ Version: protocol.Version1_2,
+ SessionID: state.SessionID,
+ Cookie: state.cookie,
+ Random: state.localRandom,
+ CipherSuiteIDs: cipherSuiteIDs(cfg.localCipherSuites),
+ CompressionMethods: defaultCompressionMethods(),
+ Extensions: extensions,
+ },
},
- content: &handshake{
- handshakeMessage: &handshakeMessageClientHello{
- version: protocolVersion1_2,
- cookie: state.cookie,
- random: state.localRandom,
- cipherSuites: cfg.localCipherSuites,
- compressionMethods: defaultCompressionMethods,
- extensions: extensions,
- }},
},
},
}, nil, nil
diff --git a/vendor/github.com/pion/dtls/v2/flight2handler.go b/vendor/github.com/pion/dtls/v2/flight2handler.go
index 1b0e355..26e57d2 100644
--- a/vendor/github.com/pion/dtls/v2/flight2handler.go
+++ b/vendor/github.com/pion/dtls/v2/flight2handler.go
@@ -1,51 +1,61 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
"bytes"
"context"
+
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
)
-func flight2Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert, error) {
- seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence,
- handshakeCachePullRule{handshakeTypeClientHello, cfg.initialEpoch, true, true},
+func flight2Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) {
+ seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
)
if !ok {
- // No valid message received. Keep reading
- return 0, nil, nil
+ // Client may retransmit the first ClientHello when HelloVerifyRequest is dropped.
+ // Parse as flight 0 in this case.
+ return flight0Parse(ctx, c, state, cache, cfg)
}
state.handshakeRecvSequence = seq
- var clientHello *handshakeMessageClientHello
+ var clientHello *handshake.MessageClientHello
// Validate type
- if clientHello, ok = msgs[handshakeTypeClientHello].(*handshakeMessageClientHello); !ok {
- return 0, &alert{alertLevelFatal, alertInternalError}, nil
+ if clientHello, ok = msgs[handshake.TypeClientHello].(*handshake.MessageClientHello); !ok {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
}
- if !clientHello.version.Equal(protocolVersion1_2) {
- return 0, &alert{alertLevelFatal, alertProtocolVersion}, errUnsupportedProtocolVersion
+ if !clientHello.Version.Equal(protocol.Version1_2) {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion
}
- if len(clientHello.cookie) == 0 {
+ if len(clientHello.Cookie) == 0 {
return 0, nil, nil
}
- if !bytes.Equal(state.cookie, clientHello.cookie) {
- return 0, &alert{alertLevelFatal, alertAccessDenied}, errCookieMismatch
+ if !bytes.Equal(state.cookie, clientHello.Cookie) {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.AccessDenied}, errCookieMismatch
}
return flight4, nil, nil
}
-func flight2Generate(c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert, error) {
+func flight2Generate(_ flightConn, state *State, _ *handshakeCache, _ *handshakeConfig) ([]*packet, *alert.Alert, error) {
+ state.handshakeSendSequence = 0
return []*packet{
{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
},
- content: &handshake{
- handshakeMessage: &handshakeMessageHelloVerifyRequest{
- version: protocolVersion1_2,
- cookie: state.cookie,
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageHelloVerifyRequest{
+ Version: protocol.Version1_2,
+ Cookie: state.cookie,
},
},
},
diff --git a/vendor/github.com/pion/dtls/v2/flight3handler.go b/vendor/github.com/pion/dtls/v2/flight3handler.go
index fda824a..b17a798 100644
--- a/vendor/github.com/pion/dtls/v2/flight3handler.go
+++ b/vendor/github.com/pion/dtls/v2/flight3handler.go
@@ -1,157 +1,308 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
+ "bytes"
"context"
-)
-func flight3Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert, error) {
- var msgs map[handshakeType]handshakeMessage
- var ok bool
- var seq int
+ "github.com/pion/dtls/v2/internal/ciphersuite/types"
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/extension"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
- if cfg.localPSKCallback != nil {
- seq, msgs, ok = cache.fullPullMap(state.handshakeRecvSequence,
- handshakeCachePullRule{handshakeTypeServerHello, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerKeyExchange, cfg.initialEpoch, false, true},
- handshakeCachePullRule{handshakeTypeServerHelloDone, cfg.initialEpoch, false, false},
- )
- } else {
- seq, msgs, ok = cache.fullPullMap(state.handshakeRecvSequence,
- handshakeCachePullRule{handshakeTypeServerHello, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerKeyExchange, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificateRequest, cfg.initialEpoch, false, true},
- handshakeCachePullRule{handshakeTypeServerHelloDone, cfg.initialEpoch, false, false},
- )
+func flight3Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { //nolint:gocognit
+ // Clients may receive multiple HelloVerifyRequest messages with different cookies.
+ // Clients SHOULD handle this by sending a new ClientHello with a cookie in response
+ // to the new HelloVerifyRequest. RFC 6347 Section 4.2.1
+ seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeHelloVerifyRequest, cfg.initialEpoch, false, true},
+ )
+ if ok {
+ if h, msgOk := msgs[handshake.TypeHelloVerifyRequest].(*handshake.MessageHelloVerifyRequest); msgOk {
+ // DTLS 1.2 clients must not assume that the server will use the protocol version
+ // specified in HelloVerifyRequest message. RFC 6347 Section 4.2.1
+ if !h.Version.Equal(protocol.Version1_0) && !h.Version.Equal(protocol.Version1_2) {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion
+ }
+ state.cookie = append([]byte{}, h.Cookie...)
+ state.handshakeRecvSequence = seq
+ return flight3, nil, nil
+ }
}
+
+ _, msgs, ok = cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false},
+ )
if !ok {
// Don't have enough messages. Keep reading
return 0, nil, nil
}
- state.handshakeRecvSequence = seq
- if h, ok := msgs[handshakeTypeServerHello].(*handshakeMessageServerHello); ok {
- if !h.version.Equal(protocolVersion1_2) {
- return 0, &alert{alertLevelFatal, alertProtocolVersion}, errUnsupportedProtocolVersion
+ if h, msgOk := msgs[handshake.TypeServerHello].(*handshake.MessageServerHello); msgOk {
+ if !h.Version.Equal(protocol.Version1_2) {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion
}
- for _, extension := range h.extensions {
- switch e := extension.(type) {
- case *extensionUseSRTP:
- profile, ok := findMatchingSRTPProfile(e.protectionProfiles, cfg.localSRTPProtectionProfiles)
- if !ok {
- return 0, &alert{alertLevelFatal, alertIllegalParameter}, errClientNoMatchingSRTPProfile
+ for _, v := range h.Extensions {
+ switch e := v.(type) {
+ case *extension.UseSRTP:
+ profile, found := findMatchingSRTPProfile(e.ProtectionProfiles, cfg.localSRTPProtectionProfiles)
+ if !found {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.IllegalParameter}, errClientNoMatchingSRTPProfile
}
state.srtpProtectionProfile = profile
- case *extensionUseExtendedMasterSecret:
+ case *extension.UseExtendedMasterSecret:
if cfg.extendedMasterSecret != DisableExtendedMasterSecret {
state.extendedMasterSecret = true
}
+ case *extension.ALPN:
+ if len(e.ProtocolNameList) > 1 { // This should be exactly 1, the zero case is handle when unmarshalling
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, extension.ErrALPNInvalidFormat // Meh, internal error?
+ }
+ state.NegotiatedProtocol = e.ProtocolNameList[0]
+ case *extension.ConnectionID:
+ // Only set connection ID to be sent if client supports connection
+ // IDs.
+ if cfg.connectionIDGenerator != nil {
+ state.remoteConnectionID = e.CID
+ }
}
}
+ // If the server doesn't support connection IDs, the client should not
+ // expect one to be sent.
+ if state.remoteConnectionID == nil {
+ state.localConnectionID = nil
+ }
+
if cfg.extendedMasterSecret == RequireExtendedMasterSecret && !state.extendedMasterSecret {
- return 0, &alert{alertLevelFatal, alertInsufficientSecurity}, errClientRequiredButNoServerEMS
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errClientRequiredButNoServerEMS
}
if len(cfg.localSRTPProtectionProfiles) > 0 && state.srtpProtectionProfile == 0 {
- return 0, &alert{alertLevelFatal, alertInsufficientSecurity}, errRequestedButNoSRTPExtension
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errRequestedButNoSRTPExtension
+ }
+
+ remoteCipherSuite := cipherSuiteForID(CipherSuiteID(*h.CipherSuiteID), cfg.customCipherSuites)
+ if remoteCipherSuite == nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errCipherSuiteNoIntersection
+ }
+
+ selectedCipherSuite, found := findMatchingCipherSuite([]CipherSuite{remoteCipherSuite}, cfg.localCipherSuites)
+ if !found {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errInvalidCipherSuite
+ }
+
+ state.cipherSuite = selectedCipherSuite
+ state.remoteRandom = h.Random
+ cfg.log.Tracef("[handshake] use cipher suite: %s", selectedCipherSuite.String())
+
+ if len(h.SessionID) > 0 && bytes.Equal(state.SessionID, h.SessionID) {
+ return handleResumption(ctx, c, state, cache, cfg)
+ }
+
+ if len(state.SessionID) > 0 {
+ cfg.log.Tracef("[handshake] clean old session : %s", state.SessionID)
+ if err := cfg.sessionStore.Del(state.SessionID); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
}
- if _, ok := findMatchingCipherSuite([]cipherSuite{h.cipherSuite}, cfg.localCipherSuites); !ok {
- return 0, &alert{alertLevelFatal, alertInsufficientSecurity}, errCipherSuiteNoIntersection
+
+ if cfg.sessionStore == nil {
+ state.SessionID = []byte{}
+ } else {
+ state.SessionID = h.SessionID
}
- state.cipherSuite = h.cipherSuite
- state.remoteRandom = h.random
- cfg.log.Tracef("[handshake] use cipher suite: %s", h.cipherSuite.String())
+ state.masterSecret = []byte{}
+ }
+
+ if cfg.localPSKCallback != nil {
+ seq, msgs, ok = cache.fullPullMap(state.handshakeRecvSequence+1, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, true},
+ handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false},
+ )
+ } else {
+ seq, msgs, ok = cache.fullPullMap(state.handshakeRecvSequence+1, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, true},
+ handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, true},
+ handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false},
+ )
}
+ if !ok {
+ // Don't have enough messages. Keep reading
+ return 0, nil, nil
+ }
+ state.handshakeRecvSequence = seq
- if h, ok := msgs[handshakeTypeCertificate].(*handshakeMessageCertificate); ok {
- state.PeerCertificates = h.certificate
+ if h, ok := msgs[handshake.TypeCertificate].(*handshake.MessageCertificate); ok {
+ state.PeerCertificates = h.Certificate
+ } else if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeCertificate {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.NoCertificate}, errInvalidCertificate
}
- if h, ok := msgs[handshakeTypeServerKeyExchange].(*handshakeMessageServerKeyExchange); ok {
+ if h, ok := msgs[handshake.TypeServerKeyExchange].(*handshake.MessageServerKeyExchange); ok {
alertPtr, err := handleServerKeyExchange(c, state, cfg, h)
if err != nil {
return 0, alertPtr, err
}
}
- if _, ok := msgs[handshakeTypeCertificateRequest].(*handshakeMessageCertificateRequest); ok {
+ if _, ok := msgs[handshake.TypeCertificateRequest].(*handshake.MessageCertificateRequest); ok {
state.remoteRequestedCertificate = true
}
return flight5, nil, nil
}
-func handleServerKeyExchange(_ flightConn, state *State, cfg *handshakeConfig, h *handshakeMessageServerKeyExchange) (*alert, error) {
+func handleResumption(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) {
+ if err := state.initCipherSuite(); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+
+ // Now, encrypted packets can be handled
+ if err := c.handleQueuedPackets(ctx); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+
+ _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence+1, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, false, false},
+ )
+ if !ok {
+ // No valid message received. Keep reading
+ return 0, nil, nil
+ }
+
+ var finished *handshake.MessageFinished
+ if finished, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
+ }
+ plainText := cache.pullAndMerge(
+ handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false},
+ )
+
+ expectedVerifyData, err := prf.VerifyDataServer(state.masterSecret, plainText, state.cipherSuite.HashFunc())
+ if err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ if !bytes.Equal(expectedVerifyData, finished.VerifyData) {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errVerifyDataMismatch
+ }
+
+ clientRandom := state.localRandom.MarshalFixed()
+ cfg.writeKeyLog(keyLogLabelTLS12, clientRandom[:], state.masterSecret)
+
+ return flight5b, nil, nil
+}
+
+func handleServerKeyExchange(_ flightConn, state *State, cfg *handshakeConfig, h *handshake.MessageServerKeyExchange) (*alert.Alert, error) {
var err error
+ if state.cipherSuite == nil {
+ return &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errInvalidCipherSuite
+ }
if cfg.localPSKCallback != nil {
var psk []byte
- if psk, err = cfg.localPSKCallback(h.identityHint); err != nil {
- return &alert{alertLevelFatal, alertInternalError}, err
+ if psk, err = cfg.localPSKCallback(h.IdentityHint); err != nil {
+ return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ state.IdentityHint = h.IdentityHint
+ switch state.cipherSuite.KeyExchangeAlgorithm() {
+ case types.KeyExchangeAlgorithmPsk:
+ state.preMasterSecret = prf.PSKPreMasterSecret(psk)
+ case (types.KeyExchangeAlgorithmEcdhe | types.KeyExchangeAlgorithmPsk):
+ if state.localKeypair, err = elliptic.GenerateKeypair(h.NamedCurve); err != nil {
+ return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ state.preMasterSecret, err = prf.EcdhePSKPreMasterSecret(psk, h.PublicKey, state.localKeypair.PrivateKey, state.localKeypair.Curve)
+ if err != nil {
+ return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ default:
+ return &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errInvalidCipherSuite
}
-
- state.preMasterSecret = prfPSKPreMasterSecret(psk)
} else {
- if state.localKeypair, err = generateKeypair(h.namedCurve); err != nil {
- return &alert{alertLevelFatal, alertInternalError}, err
+ if state.localKeypair, err = elliptic.GenerateKeypair(h.NamedCurve); err != nil {
+ return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
- if state.preMasterSecret, err = prfPreMasterSecret(h.publicKey, state.localKeypair.privateKey, state.localKeypair.curve); err != nil {
- return &alert{alertLevelFatal, alertInternalError}, err
+ if state.preMasterSecret, err = prf.PreMasterSecret(h.PublicKey, state.localKeypair.PrivateKey, state.localKeypair.Curve); err != nil {
+ return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
}
- return nil, nil
+ return nil, nil //nolint:nilnil
}
-func flight3Generate(c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert, error) {
- extensions := []extension{
- &extensionSupportedSignatureAlgorithms{
- signatureHashAlgorithms: cfg.localSignatureSchemes,
+func flight3Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) {
+ extensions := []extension.Extension{
+ &extension.SupportedSignatureAlgorithms{
+ SignatureHashAlgorithms: cfg.localSignatureSchemes,
+ },
+ &extension.RenegotiationInfo{
+ RenegotiatedConnection: 0,
},
}
- if cfg.localPSKCallback == nil {
- extensions = append(extensions, []extension{
- &extensionSupportedEllipticCurves{
- ellipticCurves: []namedCurve{namedCurveX25519, namedCurveP256, namedCurveP384},
+ if state.namedCurve != 0 {
+ extensions = append(extensions, []extension.Extension{
+ &extension.SupportedEllipticCurves{
+ EllipticCurves: []elliptic.Curve{elliptic.X25519, elliptic.P256, elliptic.P384},
},
- &extensionSupportedPointFormats{
- pointFormats: []ellipticCurvePointFormat{ellipticCurvePointFormatUncompressed},
+ &extension.SupportedPointFormats{
+ PointFormats: []elliptic.CurvePointFormat{elliptic.CurvePointFormatUncompressed},
},
}...)
}
if len(cfg.localSRTPProtectionProfiles) > 0 {
- extensions = append(extensions, &extensionUseSRTP{
- protectionProfiles: cfg.localSRTPProtectionProfiles,
+ extensions = append(extensions, &extension.UseSRTP{
+ ProtectionProfiles: cfg.localSRTPProtectionProfiles,
})
}
if cfg.extendedMasterSecret == RequestExtendedMasterSecret ||
cfg.extendedMasterSecret == RequireExtendedMasterSecret {
- extensions = append(extensions, &extensionUseExtendedMasterSecret{
- supported: true,
+ extensions = append(extensions, &extension.UseExtendedMasterSecret{
+ Supported: true,
})
}
if len(cfg.serverName) > 0 {
- extensions = append(extensions, &extensionServerName{serverName: cfg.serverName})
+ extensions = append(extensions, &extension.ServerName{ServerName: cfg.serverName})
+ }
+
+ if len(cfg.supportedProtocols) > 0 {
+ extensions = append(extensions, &extension.ALPN{ProtocolNameList: cfg.supportedProtocols})
+ }
+
+ // If we sent a connection ID on the first ClientHello, send it on the
+ // second.
+ if state.localConnectionID != nil {
+ extensions = append(extensions, &extension.ConnectionID{CID: state.localConnectionID})
}
return []*packet{
{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ },
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageClientHello{
+ Version: protocol.Version1_2,
+ SessionID: state.SessionID,
+ Cookie: state.cookie,
+ Random: state.localRandom,
+ CipherSuiteIDs: cipherSuiteIDs(cfg.localCipherSuites),
+ CompressionMethods: defaultCompressionMethods(),
+ Extensions: extensions,
+ },
},
- content: &handshake{
- handshakeMessage: &handshakeMessageClientHello{
- version: protocolVersion1_2,
- cookie: state.cookie,
- random: state.localRandom,
- cipherSuites: cfg.localCipherSuites,
- compressionMethods: defaultCompressionMethods,
- extensions: extensions,
- }},
},
},
}, nil, nil
diff --git a/vendor/github.com/pion/dtls/v2/flight4bhandler.go b/vendor/github.com/pion/dtls/v2/flight4bhandler.go
new file mode 100644
index 0000000..6bbbc59
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/flight4bhandler.go
@@ -0,0 +1,144 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package dtls
+
+import (
+ "bytes"
+ "context"
+
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/extension"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
+func flight4bParse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) {
+ _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false},
+ )
+ if !ok {
+ // No valid message received. Keep reading
+ return 0, nil, nil
+ }
+
+ var finished *handshake.MessageFinished
+ if finished, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
+ }
+
+ plainText := cache.pullAndMerge(
+ handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, false, false},
+ )
+
+ expectedVerifyData, err := prf.VerifyDataClient(state.masterSecret, plainText, state.cipherSuite.HashFunc())
+ if err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ if !bytes.Equal(expectedVerifyData, finished.VerifyData) {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errVerifyDataMismatch
+ }
+
+ // Other party may re-transmit the last flight. Keep state to be flight4b.
+ return flight4b, nil, nil
+}
+
+func flight4bGenerate(_ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) {
+ var pkts []*packet
+
+ extensions := []extension.Extension{&extension.RenegotiationInfo{
+ RenegotiatedConnection: 0,
+ }}
+ if (cfg.extendedMasterSecret == RequestExtendedMasterSecret ||
+ cfg.extendedMasterSecret == RequireExtendedMasterSecret) && state.extendedMasterSecret {
+ extensions = append(extensions, &extension.UseExtendedMasterSecret{
+ Supported: true,
+ })
+ }
+ if state.srtpProtectionProfile != 0 {
+ extensions = append(extensions, &extension.UseSRTP{
+ ProtectionProfiles: []SRTPProtectionProfile{state.srtpProtectionProfile},
+ })
+ }
+
+ selectedProto, err := extension.ALPNProtocolSelection(cfg.supportedProtocols, state.peerSupportedProtocols)
+ if err != nil {
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.NoApplicationProtocol}, err
+ }
+ if selectedProto != "" {
+ extensions = append(extensions, &extension.ALPN{
+ ProtocolNameList: []string{selectedProto},
+ })
+ state.NegotiatedProtocol = selectedProto
+ }
+
+ cipherSuiteID := uint16(state.cipherSuite.ID())
+ serverHello := &handshake.Handshake{
+ Message: &handshake.MessageServerHello{
+ Version: protocol.Version1_2,
+ Random: state.localRandom,
+ SessionID: state.SessionID,
+ CipherSuiteID: &cipherSuiteID,
+ CompressionMethod: defaultCompressionMethods()[0],
+ Extensions: extensions,
+ },
+ }
+
+ serverHello.Header.MessageSequence = uint16(state.handshakeSendSequence)
+
+ if len(state.localVerifyData) == 0 {
+ plainText := cache.pullAndMerge(
+ handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
+ )
+ raw, err := serverHello.Marshal()
+ if err != nil {
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ plainText = append(plainText, raw...)
+
+ state.localVerifyData, err = prf.VerifyDataServer(state.masterSecret, plainText, state.cipherSuite.HashFunc())
+ if err != nil {
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ }
+
+ pkts = append(pkts,
+ &packet{
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ },
+ Content: serverHello,
+ },
+ },
+ &packet{
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ },
+ Content: &protocol.ChangeCipherSpec{},
+ },
+ },
+ &packet{
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ Epoch: 1,
+ },
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageFinished{
+ VerifyData: state.localVerifyData,
+ },
+ },
+ },
+ shouldEncrypt: true,
+ resetLocalSequenceNumber: true,
+ },
+ )
+
+ return pkts, nil, nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/flight4handler.go b/vendor/github.com/pion/dtls/v2/flight4handler.go
index 5149f6d..5256813 100644
--- a/vendor/github.com/pion/dtls/v2/flight4handler.go
+++ b/vendor/github.com/pion/dtls/v2/flight4handler.go
@@ -1,15 +1,30 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
"context"
+ "crypto/rand"
"crypto/x509"
+
+ "github.com/pion/dtls/v2/internal/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/crypto/signaturehash"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/extension"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
)
-func flight4Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert, error) {
- seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence,
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, true, true},
- handshakeCachePullRule{handshakeTypeClientKeyExchange, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeCertificateVerify, cfg.initialEpoch, true, true},
+func flight4Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { //nolint:gocognit
+ seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, true},
+ handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeCertificateVerify, cfg.initialEpoch, true, true},
)
if !ok {
// No valid message received. Keep reading
@@ -17,113 +32,144 @@ func flight4Parse(ctx context.Context, c flightConn, state *State, cache *handsh
}
// Validate type
- var clientKeyExchange *handshakeMessageClientKeyExchange
- if clientKeyExchange, ok = msgs[handshakeTypeClientKeyExchange].(*handshakeMessageClientKeyExchange); !ok {
- return 0, &alert{alertLevelFatal, alertInternalError}, nil
+ var clientKeyExchange *handshake.MessageClientKeyExchange
+ if clientKeyExchange, ok = msgs[handshake.TypeClientKeyExchange].(*handshake.MessageClientKeyExchange); !ok {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
}
- if h, hasCert := msgs[handshakeTypeCertificate].(*handshakeMessageCertificate); hasCert {
- state.PeerCertificates = h.certificate
+ if h, hasCert := msgs[handshake.TypeCertificate].(*handshake.MessageCertificate); hasCert {
+ state.PeerCertificates = h.Certificate
+ // If the client offer its certificate, just disable session resumption.
+ // Otherwise, we have to store the certificate identitfication and expire time.
+ // And we have to check whether this certificate expired, revoked or changed.
+ //
+ // https://curl.se/docs/CVE-2016-5419.html
+ state.SessionID = nil
}
- if h, hasCertVerify := msgs[handshakeTypeCertificateVerify].(*handshakeMessageCertificateVerify); hasCertVerify {
+ if h, hasCertVerify := msgs[handshake.TypeCertificateVerify].(*handshake.MessageCertificateVerify); hasCertVerify {
if state.PeerCertificates == nil {
- return 0, &alert{alertLevelFatal, alertNoCertificate}, errCertificateVerifyNoCertificate
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.NoCertificate}, errCertificateVerifyNoCertificate
}
plainText := cache.pullAndMerge(
- handshakeCachePullRule{handshakeTypeClientHello, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeServerHello, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerKeyExchange, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificateRequest, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerHelloDone, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeClientKeyExchange, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false},
)
// Verify that the pair of hash algorithm and signiture is listed.
var validSignatureScheme bool
for _, ss := range cfg.localSignatureSchemes {
- if ss.hash == h.hashAlgorithm && ss.signature == h.signatureAlgorithm {
+ if ss.Hash == h.HashAlgorithm && ss.Signature == h.SignatureAlgorithm {
validSignatureScheme = true
break
}
}
if !validSignatureScheme {
- return 0, &alert{alertLevelFatal, alertInsufficientSecurity}, errNoAvailableSignatureSchemes
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errNoAvailableSignatureSchemes
}
- if err := verifyCertificateVerify(plainText, h.hashAlgorithm, h.signature, state.PeerCertificates); err != nil {
- return 0, &alert{alertLevelFatal, alertBadCertificate}, err
+ if err := verifyCertificateVerify(plainText, h.HashAlgorithm, h.Signature, state.PeerCertificates); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err
}
var chains [][]*x509.Certificate
var err error
var verified bool
if cfg.clientAuth >= VerifyClientCertIfGiven {
if chains, err = verifyClientCert(state.PeerCertificates, cfg.clientCAs); err != nil {
- return 0, &alert{alertLevelFatal, alertBadCertificate}, err
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err
}
verified = true
}
if cfg.verifyPeerCertificate != nil {
if err := cfg.verifyPeerCertificate(state.PeerCertificates, chains); err != nil {
- return 0, &alert{alertLevelFatal, alertBadCertificate}, err
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err
}
}
state.peerCertificatesVerified = verified
+ } else if state.PeerCertificates != nil {
+ // A certificate was received, but we haven't seen a CertificateVerify
+ // keep reading until we receive one
+ return 0, nil, nil
}
- if !state.cipherSuite.isInitialized() {
- serverRandom := state.localRandom.marshalFixed()
- clientRandom := state.remoteRandom.marshalFixed()
+ if !state.cipherSuite.IsInitialized() {
+ serverRandom := state.localRandom.MarshalFixed()
+ clientRandom := state.remoteRandom.MarshalFixed()
var err error
var preMasterSecret []byte
- if cfg.localPSKCallback != nil {
+ if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypePreSharedKey {
var psk []byte
- if psk, err = cfg.localPSKCallback(clientKeyExchange.identityHint); err != nil {
- return 0, &alert{alertLevelFatal, alertInternalError}, err
+ if psk, err = cfg.localPSKCallback(clientKeyExchange.IdentityHint); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ state.IdentityHint = clientKeyExchange.IdentityHint
+ switch state.cipherSuite.KeyExchangeAlgorithm() {
+ case CipherSuiteKeyExchangeAlgorithmPsk:
+ preMasterSecret = prf.PSKPreMasterSecret(psk)
+ case (CipherSuiteKeyExchangeAlgorithmPsk | CipherSuiteKeyExchangeAlgorithmEcdhe):
+ if preMasterSecret, err = prf.EcdhePSKPreMasterSecret(psk, clientKeyExchange.PublicKey, state.localKeypair.PrivateKey, state.localKeypair.Curve); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ default:
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, errInvalidCipherSuite
}
-
- preMasterSecret = prfPSKPreMasterSecret(psk)
} else {
- preMasterSecret, err = prfPreMasterSecret(clientKeyExchange.publicKey, state.localKeypair.privateKey, state.localKeypair.curve)
+ preMasterSecret, err = prf.PreMasterSecret(clientKeyExchange.PublicKey, state.localKeypair.PrivateKey, state.localKeypair.Curve)
if err != nil {
- return 0, &alert{alertLevelFatal, alertIllegalParameter}, err
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.IllegalParameter}, err
}
}
if state.extendedMasterSecret {
var sessionHash []byte
- sessionHash, err = cache.sessionHash(state.cipherSuite.hashFunc(), cfg.initialEpoch)
+ sessionHash, err = cache.sessionHash(state.cipherSuite.HashFunc(), cfg.initialEpoch)
if err != nil {
- return 0, &alert{alertLevelFatal, alertInternalError}, err
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
- state.masterSecret, err = prfExtendedMasterSecret(preMasterSecret, sessionHash, state.cipherSuite.hashFunc())
+ state.masterSecret, err = prf.ExtendedMasterSecret(preMasterSecret, sessionHash, state.cipherSuite.HashFunc())
if err != nil {
- return 0, &alert{alertLevelFatal, alertInternalError}, err
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
} else {
- state.masterSecret, err = prfMasterSecret(preMasterSecret, clientRandom[:], serverRandom[:], state.cipherSuite.hashFunc())
+ state.masterSecret, err = prf.MasterSecret(preMasterSecret, clientRandom[:], serverRandom[:], state.cipherSuite.HashFunc())
if err != nil {
- return 0, &alert{alertLevelFatal, alertInternalError}, err
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
}
- if err := state.cipherSuite.init(state.masterSecret, clientRandom[:], serverRandom[:], false); err != nil {
- return 0, &alert{alertLevelFatal, alertInternalError}, err
+ if err := state.cipherSuite.Init(state.masterSecret, clientRandom[:], serverRandom[:], false); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ cfg.writeKeyLog(keyLogLabelTLS12, clientRandom[:], state.masterSecret)
+ }
+
+ if len(state.SessionID) > 0 {
+ s := Session{
+ ID: state.SessionID,
+ Secret: state.masterSecret,
+ }
+ cfg.log.Tracef("[handshake] save new session: %x", s.ID)
+ if err := cfg.sessionStore.Set(state.SessionID, s); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
}
// Now, encrypted packets can be handled
if err := c.handleQueuedPackets(ctx); err != nil {
- return 0, &alert{alertLevelFatal, alertInternalError}, err
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
- seq, msgs, ok = cache.fullPullMap(seq,
- handshakeCachePullRule{handshakeTypeFinished, cfg.initialEpoch + 1, true, false},
+ seq, msgs, ok = cache.fullPullMap(seq, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false},
)
if !ok {
// No valid message received. Keep reading
@@ -131,164 +177,232 @@ func flight4Parse(ctx context.Context, c flightConn, state *State, cache *handsh
}
state.handshakeRecvSequence = seq
- if _, ok = msgs[handshakeTypeFinished].(*handshakeMessageFinished); !ok {
- return 0, &alert{alertLevelFatal, alertInternalError}, nil
+ if _, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
+ }
+
+ if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeAnonymous {
+ if cfg.verifyConnection != nil {
+ if err := cfg.verifyConnection(state.clone()); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err
+ }
+ }
+ return flight6, nil, nil
}
switch cfg.clientAuth {
case RequireAnyClientCert:
if state.PeerCertificates == nil {
- return 0, &alert{alertLevelFatal, alertNoCertificate}, errClientCertificateRequired
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.NoCertificate}, errClientCertificateRequired
}
case VerifyClientCertIfGiven:
if state.PeerCertificates != nil && !state.peerCertificatesVerified {
- return 0, &alert{alertLevelFatal, alertBadCertificate}, errClientCertificateNotVerified
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, errClientCertificateNotVerified
}
case RequireAndVerifyClientCert:
if state.PeerCertificates == nil {
- return 0, &alert{alertLevelFatal, alertNoCertificate}, errClientCertificateRequired
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.NoCertificate}, errClientCertificateRequired
}
if !state.peerCertificatesVerified {
- return 0, &alert{alertLevelFatal, alertBadCertificate}, errClientCertificateNotVerified
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, errClientCertificateNotVerified
+ }
+ case NoClientCert, RequestClientCert:
+ // go to flight6
+ }
+ if cfg.verifyConnection != nil {
+ if err := cfg.verifyConnection(state.clone()); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err
}
}
return flight6, nil, nil
}
-func flight4Generate(c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert, error) {
- extensions := []extension{}
+func flight4Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { //nolint:gocognit
+ extensions := []extension.Extension{&extension.RenegotiationInfo{
+ RenegotiatedConnection: 0,
+ }}
if (cfg.extendedMasterSecret == RequestExtendedMasterSecret ||
cfg.extendedMasterSecret == RequireExtendedMasterSecret) && state.extendedMasterSecret {
- extensions = append(extensions, &extensionUseExtendedMasterSecret{
- supported: true,
+ extensions = append(extensions, &extension.UseExtendedMasterSecret{
+ Supported: true,
})
}
if state.srtpProtectionProfile != 0 {
- extensions = append(extensions, &extensionUseSRTP{
- protectionProfiles: []SRTPProtectionProfile{state.srtpProtectionProfile},
+ extensions = append(extensions, &extension.UseSRTP{
+ ProtectionProfiles: []SRTPProtectionProfile{state.srtpProtectionProfile},
})
}
- if cfg.localPSKCallback == nil {
- extensions = append(extensions, []extension{
- &extensionSupportedEllipticCurves{
- ellipticCurves: []namedCurve{namedCurveX25519, namedCurveP256, namedCurveP384},
- },
- &extensionSupportedPointFormats{
- pointFormats: []ellipticCurvePointFormat{ellipticCurvePointFormatUncompressed},
- },
- }...)
+ if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeCertificate {
+ extensions = append(extensions, &extension.SupportedPointFormats{
+ PointFormats: []elliptic.CurvePointFormat{elliptic.CurvePointFormatUncompressed},
+ })
+ }
+
+ selectedProto, err := extension.ALPNProtocolSelection(cfg.supportedProtocols, state.peerSupportedProtocols)
+ if err != nil {
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.NoApplicationProtocol}, err
+ }
+ if selectedProto != "" {
+ extensions = append(extensions, &extension.ALPN{
+ ProtocolNameList: []string{selectedProto},
+ })
+ state.NegotiatedProtocol = selectedProto
+ }
+
+ // If we have a connection ID generator, we are willing to use connection
+ // IDs. We already know whether the client supports connection IDs from
+ // parsing the ClientHello, so avoid setting local connection ID if the
+ // client won't send it.
+ if cfg.connectionIDGenerator != nil && state.remoteConnectionID != nil {
+ state.localConnectionID = cfg.connectionIDGenerator()
+ extensions = append(extensions, &extension.ConnectionID{CID: state.localConnectionID})
}
var pkts []*packet
+ cipherSuiteID := uint16(state.cipherSuite.ID())
+
+ if cfg.sessionStore != nil {
+ state.SessionID = make([]byte, sessionLength)
+ if _, err := rand.Read(state.SessionID); err != nil {
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ }
pkts = append(pkts, &packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ },
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageServerHello{
+ Version: protocol.Version1_2,
+ Random: state.localRandom,
+ SessionID: state.SessionID,
+ CipherSuiteID: &cipherSuiteID,
+ CompressionMethod: defaultCompressionMethods()[0],
+ Extensions: extensions,
+ },
},
- content: &handshake{
- handshakeMessage: &handshakeMessageServerHello{
- version: protocolVersion1_2,
- random: state.localRandom,
- cipherSuite: state.cipherSuite,
- compressionMethod: defaultCompressionMethods[0],
- extensions: extensions,
- }},
},
})
- if cfg.localPSKCallback == nil {
- certificate, err := cfg.getCertificate(cfg.serverName)
+ switch {
+ case state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeCertificate:
+ certificate, err := cfg.getCertificate(&ClientHelloInfo{
+ ServerName: state.serverName,
+ CipherSuites: []ciphersuite.ID{state.cipherSuite.ID()},
+ })
if err != nil {
- return nil, &alert{alertLevelFatal, alertHandshakeFailure}, err
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, err
}
pkts = append(pkts, &packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ },
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageCertificate{
+ Certificate: certificate.Certificate,
+ },
},
- content: &handshake{
- handshakeMessage: &handshakeMessageCertificate{
- certificate: certificate.Certificate,
- }},
},
})
- serverRandom := state.localRandom.marshalFixed()
- clientRandom := state.remoteRandom.marshalFixed()
+ serverRandom := state.localRandom.MarshalFixed()
+ clientRandom := state.remoteRandom.MarshalFixed()
// Find compatible signature scheme
- signatureHashAlgo, err := selectSignatureScheme(cfg.localSignatureSchemes, certificate.PrivateKey)
+ signatureHashAlgo, err := signaturehash.SelectSignatureScheme(cfg.localSignatureSchemes, certificate.PrivateKey)
if err != nil {
- return nil, &alert{alertLevelFatal, alertInsufficientSecurity}, err
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, err
}
- signature, err := generateKeySignature(clientRandom[:], serverRandom[:], state.localKeypair.publicKey, state.namedCurve, certificate.PrivateKey, signatureHashAlgo.hash)
+ signature, err := generateKeySignature(clientRandom[:], serverRandom[:], state.localKeypair.PublicKey, state.namedCurve, certificate.PrivateKey, signatureHashAlgo.Hash)
if err != nil {
- return nil, &alert{alertLevelFatal, alertInternalError}, err
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
state.localKeySignature = signature
pkts = append(pkts, &packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ },
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageServerKeyExchange{
+ EllipticCurveType: elliptic.CurveTypeNamedCurve,
+ NamedCurve: state.namedCurve,
+ PublicKey: state.localKeypair.PublicKey,
+ HashAlgorithm: signatureHashAlgo.Hash,
+ SignatureAlgorithm: signatureHashAlgo.Signature,
+ Signature: state.localKeySignature,
+ },
},
- content: &handshake{
- handshakeMessage: &handshakeMessageServerKeyExchange{
- ellipticCurveType: ellipticCurveTypeNamedCurve,
- namedCurve: state.namedCurve,
- publicKey: state.localKeypair.publicKey,
- hashAlgorithm: signatureHashAlgo.hash,
- signatureAlgorithm: signatureHashAlgo.signature,
- signature: state.localKeySignature,
- }},
},
})
if cfg.clientAuth > NoClientCert {
+ // An empty list of certificateAuthorities signals to
+ // the client that it may send any certificate in response
+ // to our request. When we know the CAs we trust, then
+ // we can send them down, so that the client can choose
+ // an appropriate certificate to give to us.
+ var certificateAuthorities [][]byte
+ if cfg.clientCAs != nil {
+ // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool and it's ok if certificate authorities is empty.
+ certificateAuthorities = cfg.clientCAs.Subjects()
+ }
pkts = append(pkts, &packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
},
- content: &handshake{
- handshakeMessage: &handshakeMessageCertificateRequest{
- certificateTypes: []clientCertificateType{clientCertificateTypeRSASign, clientCertificateTypeECDSASign},
- signatureHashAlgorithms: cfg.localSignatureSchemes,
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageCertificateRequest{
+ CertificateTypes: []clientcertificate.Type{clientcertificate.RSASign, clientcertificate.ECDSASign},
+ SignatureHashAlgorithms: cfg.localSignatureSchemes,
+ CertificateAuthoritiesNames: certificateAuthorities,
},
},
},
})
}
- } else if cfg.localPSKIdentityHint != nil {
+ case cfg.localPSKIdentityHint != nil || state.cipherSuite.KeyExchangeAlgorithm().Has(CipherSuiteKeyExchangeAlgorithmEcdhe):
// To help the client in selecting which identity to use, the server
// can provide a "PSK identity hint" in the ServerKeyExchange message.
- // If no hint is provided, the ServerKeyExchange message is omitted.
+ // If no hint is provided and cipher suite doesn't use elliptic curve,
+ // the ServerKeyExchange message is omitted.
//
// https://tools.ietf.org/html/rfc4279#section-2
+ srvExchange := &handshake.MessageServerKeyExchange{
+ IdentityHint: cfg.localPSKIdentityHint,
+ }
+ if state.cipherSuite.KeyExchangeAlgorithm().Has(CipherSuiteKeyExchangeAlgorithmEcdhe) {
+ srvExchange.EllipticCurveType = elliptic.CurveTypeNamedCurve
+ srvExchange.NamedCurve = state.namedCurve
+ srvExchange.PublicKey = state.localKeypair.PublicKey
+ }
pkts = append(pkts, &packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ },
+ Content: &handshake.Handshake{
+ Message: srvExchange,
},
- content: &handshake{
- handshakeMessage: &handshakeMessageServerKeyExchange{
- identityHint: cfg.localPSKIdentityHint,
- }},
},
})
}
pkts = append(pkts, &packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
},
- content: &handshake{
- handshakeMessage: &handshakeMessageServerHelloDone{},
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageServerHelloDone{},
},
},
})
diff --git a/vendor/github.com/pion/dtls/v2/flight5bhandler.go b/vendor/github.com/pion/dtls/v2/flight5bhandler.go
new file mode 100644
index 0000000..ddd3732
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/flight5bhandler.go
@@ -0,0 +1,78 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package dtls
+
+import (
+ "context"
+
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
+func flight5bParse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) {
+ _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence-1, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, false, false},
+ )
+ if !ok {
+ // No valid message received. Keep reading
+ return 0, nil, nil
+ }
+
+ if _, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
+ }
+
+ // Other party may re-transmit the last flight. Keep state to be flight5b.
+ return flight5b, nil, nil
+}
+
+func flight5bGenerate(_ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { //nolint:gocognit
+ var pkts []*packet
+
+ pkts = append(pkts,
+ &packet{
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ },
+ Content: &protocol.ChangeCipherSpec{},
+ },
+ })
+
+ if len(state.localVerifyData) == 0 {
+ plainText := cache.pullAndMerge(
+ handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, false, false},
+ )
+
+ var err error
+ state.localVerifyData, err = prf.VerifyDataClient(state.masterSecret, plainText, state.cipherSuite.HashFunc())
+ if err != nil {
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
+ }
+
+ pkts = append(pkts,
+ &packet{
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ Epoch: 1,
+ },
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageFinished{
+ VerifyData: state.localVerifyData,
+ },
+ },
+ },
+ shouldEncrypt: true,
+ resetLocalSequenceNumber: true,
+ })
+
+ return pkts, nil, nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/flight5handler.go b/vendor/github.com/pion/dtls/v2/flight5handler.go
index 8ee63ba..e1cca62 100644
--- a/vendor/github.com/pion/dtls/v2/flight5handler.go
+++ b/vendor/github.com/pion/dtls/v2/flight5handler.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
@@ -5,117 +8,151 @@ import (
"context"
"crypto"
"crypto/x509"
+
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/crypto/signaturehash"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
)
-func flight5Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert, error) {
- _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence,
- handshakeCachePullRule{handshakeTypeFinished, cfg.initialEpoch + 1, false, false},
+func flight5Parse(_ context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) {
+ _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, false, false},
)
if !ok {
// No valid message received. Keep reading
return 0, nil, nil
}
- var finished *handshakeMessageFinished
- if finished, ok = msgs[handshakeTypeFinished].(*handshakeMessageFinished); !ok {
- return 0, &alert{alertLevelFatal, alertInternalError}, nil
+ var finished *handshake.MessageFinished
+ if finished, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
}
plainText := cache.pullAndMerge(
- handshakeCachePullRule{handshakeTypeClientHello, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeServerHello, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerKeyExchange, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificateRequest, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerHelloDone, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeClientKeyExchange, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeCertificateVerify, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeFinished, cfg.initialEpoch + 1, true, false},
+ handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeCertificateVerify, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false},
)
- expectedVerifyData, err := prfVerifyDataServer(state.masterSecret, plainText, state.cipherSuite.hashFunc())
+ expectedVerifyData, err := prf.VerifyDataServer(state.masterSecret, plainText, state.cipherSuite.HashFunc())
if err != nil {
- return 0, &alert{alertLevelFatal, alertInternalError}, err
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
- if !bytes.Equal(expectedVerifyData, finished.verifyData) {
- return 0, &alert{alertLevelFatal, alertHandshakeFailure}, errVerifyDataMismatch
+ if !bytes.Equal(expectedVerifyData, finished.VerifyData) {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errVerifyDataMismatch
+ }
+
+ if len(state.SessionID) > 0 {
+ s := Session{
+ ID: state.SessionID,
+ Secret: state.masterSecret,
+ }
+ cfg.log.Tracef("[handshake] save new session: %x", s.ID)
+ if err := cfg.sessionStore.Set(c.sessionKey(), s); err != nil {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
+ }
}
return flight5, nil, nil
}
-func flight5Generate(c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert, error) {
- var certBytes [][]byte
+func flight5Generate(c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { //nolint:gocognit
var privateKey crypto.PrivateKey
- if len(cfg.localCertificates) > 0 {
- certificate, err := cfg.getCertificate(cfg.serverName)
- if err != nil {
- return nil, &alert{alertLevelFatal, alertHandshakeFailure}, err
- }
- certBytes = certificate.Certificate
- privateKey = certificate.PrivateKey
- }
-
var pkts []*packet
-
if state.remoteRequestedCertificate {
+ _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence-2, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false})
+ if !ok {
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errClientCertificateRequired
+ }
+ reqInfo := CertificateRequestInfo{}
+ if r, ok := msgs[handshake.TypeCertificateRequest].(*handshake.MessageCertificateRequest); ok {
+ reqInfo.AcceptableCAs = r.CertificateAuthoritiesNames
+ } else {
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errClientCertificateRequired
+ }
+ certificate, err := cfg.getClientCertificate(&reqInfo)
+ if err != nil {
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, err
+ }
+ if certificate == nil {
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errNotAcceptableCertificateChain
+ }
+ if certificate.Certificate != nil {
+ privateKey = certificate.PrivateKey
+ }
pkts = append(pkts,
&packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ },
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageCertificate{
+ Certificate: certificate.Certificate,
+ },
},
- content: &handshake{
- handshakeMessage: &handshakeMessageCertificate{
- certificate: certBytes,
- }},
},
})
}
- clientKeyExchange := &handshakeMessageClientKeyExchange{}
+ clientKeyExchange := &handshake.MessageClientKeyExchange{}
if cfg.localPSKCallback == nil {
- clientKeyExchange.publicKey = state.localKeypair.publicKey
+ clientKeyExchange.PublicKey = state.localKeypair.PublicKey
} else {
- clientKeyExchange.identityHint = cfg.localPSKIdentityHint
+ clientKeyExchange.IdentityHint = cfg.localPSKIdentityHint
+ }
+ if state != nil && state.localKeypair != nil && len(state.localKeypair.PublicKey) > 0 {
+ clientKeyExchange.PublicKey = state.localKeypair.PublicKey
}
pkts = append(pkts,
&packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
},
- content: &handshake{
- handshakeMessage: clientKeyExchange,
+ Content: &handshake.Handshake{
+ Message: clientKeyExchange,
},
},
})
serverKeyExchangeData := cache.pullAndMerge(
- handshakeCachePullRule{handshakeTypeServerKeyExchange, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false},
)
- serverKeyExchange := &handshakeMessageServerKeyExchange{}
+ serverKeyExchange := &handshake.MessageServerKeyExchange{}
// handshakeMessageServerKeyExchange is optional for PSK
if len(serverKeyExchangeData) == 0 {
- alertPtr, err := handleServerKeyExchange(c, state, cfg, &handshakeMessageServerKeyExchange{})
+ alertPtr, err := handleServerKeyExchange(c, state, cfg, &handshake.MessageServerKeyExchange{})
if err != nil {
return nil, alertPtr, err
}
} else {
- rawHandshake := &handshake{}
+ rawHandshake := &handshake.Handshake{
+ KeyExchangeAlgorithm: state.cipherSuite.KeyExchangeAlgorithm(),
+ }
err := rawHandshake.Unmarshal(serverKeyExchangeData)
if err != nil {
- return nil, &alert{alertLevelFatal, alertUnexpectedMessage}, err
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, err
}
- switch h := rawHandshake.handshakeMessage.(type) {
- case *handshakeMessageServerKeyExchange:
+ switch h := rawHandshake.Message.(type) {
+ case *handshake.MessageServerKeyExchange:
serverKeyExchange = h
default:
- return nil, &alert{alertLevelFatal, alertUnexpectedMessage}, errInvalidContentType
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, errInvalidContentType
}
}
@@ -123,121 +160,124 @@ func flight5Generate(c flightConn, state *State, cache *handshakeCache, cfg *han
merged := []byte{}
seqPred := uint16(state.handshakeSendSequence)
for _, p := range pkts {
- h, ok := p.record.content.(*handshake)
+ h, ok := p.record.Content.(*handshake.Handshake)
if !ok {
- return nil, &alert{alertLevelFatal, alertInternalError}, errInvalidContentType
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, errInvalidContentType
}
- h.handshakeHeader.messageSequence = seqPred
+ h.Header.MessageSequence = seqPred
seqPred++
raw, err := h.Marshal()
if err != nil {
- return nil, &alert{alertLevelFatal, alertInternalError}, err
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
merged = append(merged, raw...)
}
- if alertPtr, err := initalizeCipherSuite(state, cache, cfg, serverKeyExchange, merged); err != nil {
+ if alertPtr, err := initializeCipherSuite(state, cache, cfg, serverKeyExchange, merged); err != nil {
return nil, alertPtr, err
}
// If the client has sent a certificate with signing ability, a digitally-signed
// CertificateVerify message is sent to explicitly verify possession of the
// private key in the certificate.
- if state.remoteRequestedCertificate && len(cfg.localCertificates) > 0 {
+ if state.remoteRequestedCertificate && privateKey != nil {
plainText := append(cache.pullAndMerge(
- handshakeCachePullRule{handshakeTypeClientHello, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeServerHello, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerKeyExchange, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificateRequest, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerHelloDone, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeClientKeyExchange, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false},
), merged...)
// Find compatible signature scheme
- signatureHashAlgo, err := selectSignatureScheme(cfg.localSignatureSchemes, privateKey)
+ signatureHashAlgo, err := signaturehash.SelectSignatureScheme(cfg.localSignatureSchemes, privateKey)
if err != nil {
- return nil, &alert{alertLevelFatal, alertInsufficientSecurity}, err
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, err
}
- certVerify, err := generateCertificateVerify(plainText, privateKey, signatureHashAlgo.hash)
+ certVerify, err := generateCertificateVerify(plainText, privateKey, signatureHashAlgo.Hash)
if err != nil {
- return nil, &alert{alertLevelFatal, alertInternalError}, err
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
state.localCertificatesVerify = certVerify
p := &packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ },
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageCertificateVerify{
+ HashAlgorithm: signatureHashAlgo.Hash,
+ SignatureAlgorithm: signatureHashAlgo.Signature,
+ Signature: state.localCertificatesVerify,
+ },
},
- content: &handshake{
- handshakeMessage: &handshakeMessageCertificateVerify{
- hashAlgorithm: signatureHashAlgo.hash,
- signatureAlgorithm: signatureHashAlgo.signature,
- signature: state.localCertificatesVerify,
- }},
},
}
pkts = append(pkts, p)
- h, ok := p.record.content.(*handshake)
+ h, ok := p.record.Content.(*handshake.Handshake)
if !ok {
- return nil, &alert{alertLevelFatal, alertInternalError}, errInvalidContentType
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, errInvalidContentType
}
- h.handshakeHeader.messageSequence = seqPred
+ h.Header.MessageSequence = seqPred
// seqPred++ // this is the last use of seqPred
raw, err := h.Marshal()
if err != nil {
- return nil, &alert{alertLevelFatal, alertInternalError}, err
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
merged = append(merged, raw...)
}
pkts = append(pkts,
&packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
},
- content: &changeCipherSpec{},
+ Content: &protocol.ChangeCipherSpec{},
},
})
if len(state.localVerifyData) == 0 {
plainText := cache.pullAndMerge(
- handshakeCachePullRule{handshakeTypeClientHello, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeServerHello, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerKeyExchange, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificateRequest, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerHelloDone, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeClientKeyExchange, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeCertificateVerify, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeFinished, cfg.initialEpoch + 1, true, false},
+ handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeCertificateVerify, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false},
)
var err error
- state.localVerifyData, err = prfVerifyDataClient(state.masterSecret, append(plainText, merged...), state.cipherSuite.hashFunc())
+ state.localVerifyData, err = prf.VerifyDataClient(state.masterSecret, append(plainText, merged...), state.cipherSuite.HashFunc())
if err != nil {
- return nil, &alert{alertLevelFatal, alertInternalError}, err
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
}
pkts = append(pkts,
&packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
- epoch: 1,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ Epoch: 1,
+ },
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageFinished{
+ VerifyData: state.localVerifyData,
+ },
},
- content: &handshake{
- handshakeMessage: &handshakeMessageFinished{
- verifyData: state.localVerifyData,
- }},
},
+ shouldWrapCID: len(state.remoteConnectionID) > 0,
shouldEncrypt: true,
resetLocalSequenceNumber: true,
})
@@ -245,66 +285,74 @@ func flight5Generate(c flightConn, state *State, cache *handshakeCache, cfg *han
return pkts, nil, nil
}
-func initalizeCipherSuite(state *State, cache *handshakeCache, cfg *handshakeConfig, h *handshakeMessageServerKeyExchange, sendingPlainText []byte) (*alert, error) {
- if state.cipherSuite.isInitialized() {
- return nil, nil
+func initializeCipherSuite(state *State, cache *handshakeCache, cfg *handshakeConfig, h *handshake.MessageServerKeyExchange, sendingPlainText []byte) (*alert.Alert, error) { //nolint:gocognit
+ if state.cipherSuite.IsInitialized() {
+ return nil, nil //nolint
}
- clientRandom := state.localRandom.marshalFixed()
- serverRandom := state.remoteRandom.marshalFixed()
+ clientRandom := state.localRandom.MarshalFixed()
+ serverRandom := state.remoteRandom.MarshalFixed()
var err error
if state.extendedMasterSecret {
var sessionHash []byte
- sessionHash, err = cache.sessionHash(state.cipherSuite.hashFunc(), cfg.initialEpoch, sendingPlainText)
+ sessionHash, err = cache.sessionHash(state.cipherSuite.HashFunc(), cfg.initialEpoch, sendingPlainText)
if err != nil {
- return &alert{alertLevelFatal, alertInternalError}, err
+ return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
- state.masterSecret, err = prfExtendedMasterSecret(state.preMasterSecret, sessionHash, state.cipherSuite.hashFunc())
+ state.masterSecret, err = prf.ExtendedMasterSecret(state.preMasterSecret, sessionHash, state.cipherSuite.HashFunc())
if err != nil {
- return &alert{alertLevelFatal, alertIllegalParameter}, err
+ return &alert.Alert{Level: alert.Fatal, Description: alert.IllegalParameter}, err
}
} else {
- state.masterSecret, err = prfMasterSecret(state.preMasterSecret, clientRandom[:], serverRandom[:], state.cipherSuite.hashFunc())
+ state.masterSecret, err = prf.MasterSecret(state.preMasterSecret, clientRandom[:], serverRandom[:], state.cipherSuite.HashFunc())
if err != nil {
- return &alert{alertLevelFatal, alertInternalError}, err
+ return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
}
- if cfg.localPSKCallback == nil {
+ if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeCertificate {
// Verify that the pair of hash algorithm and signiture is listed.
var validSignatureScheme bool
for _, ss := range cfg.localSignatureSchemes {
- if ss.hash == h.hashAlgorithm && ss.signature == h.signatureAlgorithm {
+ if ss.Hash == h.HashAlgorithm && ss.Signature == h.SignatureAlgorithm {
validSignatureScheme = true
break
}
}
if !validSignatureScheme {
- return &alert{alertLevelFatal, alertInsufficientSecurity}, errNoAvailableSignatureSchemes
+ return &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errNoAvailableSignatureSchemes
}
- expectedMsg := valueKeyMessage(clientRandom[:], serverRandom[:], h.publicKey, h.namedCurve)
- if err = verifyKeySignature(expectedMsg, h.signature, h.hashAlgorithm, state.PeerCertificates); err != nil {
- return &alert{alertLevelFatal, alertBadCertificate}, err
+ expectedMsg := valueKeyMessage(clientRandom[:], serverRandom[:], h.PublicKey, h.NamedCurve)
+ if err = verifyKeySignature(expectedMsg, h.Signature, h.HashAlgorithm, state.PeerCertificates); err != nil {
+ return &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err
}
var chains [][]*x509.Certificate
if !cfg.insecureSkipVerify {
if chains, err = verifyServerCert(state.PeerCertificates, cfg.rootCAs, cfg.serverName); err != nil {
- return &alert{alertLevelFatal, alertBadCertificate}, err
+ return &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err
}
}
if cfg.verifyPeerCertificate != nil {
if err = cfg.verifyPeerCertificate(state.PeerCertificates, chains); err != nil {
- return &alert{alertLevelFatal, alertBadCertificate}, err
+ return &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err
}
}
}
+ if cfg.verifyConnection != nil {
+ if err = cfg.verifyConnection(state.clone()); err != nil {
+ return &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err
+ }
+ }
- if err = state.cipherSuite.init(state.masterSecret, clientRandom[:], serverRandom[:], true); err != nil {
- return &alert{alertLevelFatal, alertInternalError}, err
+ if err = state.cipherSuite.Init(state.masterSecret, clientRandom[:], serverRandom[:], true); err != nil {
+ return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
- return nil, nil
+
+ cfg.writeKeyLog(keyLogLabelTLS12, clientRandom[:], state.masterSecret)
+
+ return nil, nil //nolint
}
diff --git a/vendor/github.com/pion/dtls/v2/flight6handler.go b/vendor/github.com/pion/dtls/v2/flight6handler.go
index 4f3a864..c038904 100644
--- a/vendor/github.com/pion/dtls/v2/flight6handler.go
+++ b/vendor/github.com/pion/dtls/v2/flight6handler.go
@@ -1,72 +1,83 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
"context"
+
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
)
-func flight6Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert, error) {
- _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence-1,
- handshakeCachePullRule{handshakeTypeFinished, cfg.initialEpoch + 1, true, false},
+func flight6Parse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) {
+ _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence-1, state.cipherSuite,
+ handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false},
)
if !ok {
// No valid message received. Keep reading
return 0, nil, nil
}
- if _, ok = msgs[handshakeTypeFinished].(*handshakeMessageFinished); !ok {
- return 0, &alert{alertLevelFatal, alertInternalError}, nil
+ if _, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok {
+ return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
}
- // Other party retransmitted the last flight.
+ // Other party may re-transmit the last flight. Keep state to be flight6.
return flight6, nil, nil
}
-func flight6Generate(c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert, error) {
+func flight6Generate(_ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) {
var pkts []*packet
pkts = append(pkts,
&packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
},
- content: &changeCipherSpec{},
+ Content: &protocol.ChangeCipherSpec{},
},
})
if len(state.localVerifyData) == 0 {
plainText := cache.pullAndMerge(
- handshakeCachePullRule{handshakeTypeClientHello, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeServerHello, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerKeyExchange, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificateRequest, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeServerHelloDone, cfg.initialEpoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeClientKeyExchange, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeCertificateVerify, cfg.initialEpoch, true, false},
- handshakeCachePullRule{handshakeTypeFinished, cfg.initialEpoch + 1, true, false},
+ handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeCertificateVerify, cfg.initialEpoch, true, false},
+ handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false},
)
var err error
- state.localVerifyData, err = prfVerifyDataServer(state.masterSecret, plainText, state.cipherSuite.hashFunc())
+ state.localVerifyData, err = prf.VerifyDataServer(state.masterSecret, plainText, state.cipherSuite.HashFunc())
if err != nil {
- return nil, &alert{alertLevelFatal, alertInternalError}, err
+ return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err
}
}
pkts = append(pkts,
&packet{
- record: &recordLayer{
- recordLayerHeader: recordLayerHeader{
- protocolVersion: protocolVersion1_2,
- epoch: 1,
+ record: &recordlayer.RecordLayer{
+ Header: recordlayer.Header{
+ Version: protocol.Version1_2,
+ Epoch: 1,
+ },
+ Content: &handshake.Handshake{
+ Message: &handshake.MessageFinished{
+ VerifyData: state.localVerifyData,
+ },
},
- content: &handshake{
- handshakeMessage: &handshakeMessageFinished{
- verifyData: state.localVerifyData,
- }},
},
+ shouldWrapCID: len(state.remoteConnectionID) > 0,
shouldEncrypt: true,
resetLocalSequenceNumber: true,
},
diff --git a/vendor/github.com/pion/dtls/v2/flighthandler.go b/vendor/github.com/pion/dtls/v2/flighthandler.go
index 0df09be..ceb4a99 100644
--- a/vendor/github.com/pion/dtls/v2/flighthandler.go
+++ b/vendor/github.com/pion/dtls/v2/flighthandler.go
@@ -1,14 +1,19 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
"context"
+
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
)
// Parse received handshakes and return next flightVal
-type flightParser func(context.Context, flightConn, *State, *handshakeCache, *handshakeConfig) (flightVal, *alert, error)
+type flightParser func(context.Context, flightConn, *State, *handshakeCache, *handshakeConfig) (flightVal, *alert.Alert, error)
// Generate flights
-type flightGenerator func(flightConn, *State, *handshakeCache, *handshakeConfig) ([]*packet, *alert, error)
+type flightGenerator func(flightConn, *State, *handshakeCache, *handshakeConfig) ([]*packet, *alert.Alert, error)
func (f flightVal) getFlightParser() (flightParser, error) {
switch f {
@@ -22,8 +27,12 @@ func (f flightVal) getFlightParser() (flightParser, error) {
return flight3Parse, nil
case flight4:
return flight4Parse, nil
+ case flight4b:
+ return flight4bParse, nil
case flight5:
return flight5Parse, nil
+ case flight5b:
+ return flight5bParse, nil
case flight6:
return flight6Parse, nil
default:
@@ -31,23 +40,29 @@ func (f flightVal) getFlightParser() (flightParser, error) {
}
}
-func (f flightVal) getFlightGenerator() (flightGenerator, error) {
+func (f flightVal) getFlightGenerator() (gen flightGenerator, retransmit bool, err error) {
switch f {
case flight0:
- return flight0Generate, nil
+ return flight0Generate, true, nil
case flight1:
- return flight1Generate, nil
+ return flight1Generate, true, nil
case flight2:
- return flight2Generate, nil
+ // https://tools.ietf.org/html/rfc6347#section-3.2.1
+ // HelloVerifyRequests must not be retransmitted.
+ return flight2Generate, false, nil
case flight3:
- return flight3Generate, nil
+ return flight3Generate, true, nil
case flight4:
- return flight4Generate, nil
+ return flight4Generate, true, nil
+ case flight4b:
+ return flight4bGenerate, true, nil
case flight5:
- return flight5Generate, nil
+ return flight5Generate, true, nil
+ case flight5b:
+ return flight5bGenerate, true, nil
case flight6:
- return flight6Generate, nil
+ return flight6Generate, true, nil
default:
- return nil, errInvalidFlight
+ return nil, false, errInvalidFlight
}
}
diff --git a/vendor/github.com/pion/dtls/v2/fragment_buffer.go b/vendor/github.com/pion/dtls/v2/fragment_buffer.go
index 95f9d47..fb5af6c 100644
--- a/vendor/github.com/pion/dtls/v2/fragment_buffer.go
+++ b/vendor/github.com/pion/dtls/v2/fragment_buffer.go
@@ -1,8 +1,20 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
+import (
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
+// 2 megabytes
+const fragmentBufferMaxSize = 2000000
+
type fragment struct {
- recordLayerHeader recordLayerHeader
- handshakeHeader handshakeHeader
+ recordLayerHeader recordlayer.Header
+ handshakeHeader handshake.Header
data []byte
}
@@ -17,31 +29,56 @@ func newFragmentBuffer() *fragmentBuffer {
return &fragmentBuffer{cache: map[uint16][]*fragment{}}
}
+// current total size of buffer
+func (f *fragmentBuffer) size() int {
+ size := 0
+ for i := range f.cache {
+ for j := range f.cache[i] {
+ size += len(f.cache[i][j].data)
+ }
+ }
+ return size
+}
+
// Attempts to push a DTLS packet to the fragmentBuffer
// when it returns true it means the fragmentBuffer has inserted and the buffer shouldn't be handled
// when an error returns it is fatal, and the DTLS connection should be stopped
func (f *fragmentBuffer) push(buf []byte) (bool, error) {
+ if f.size()+len(buf) >= fragmentBufferMaxSize {
+ return false, errFragmentBufferOverflow
+ }
+
frag := new(fragment)
if err := frag.recordLayerHeader.Unmarshal(buf); err != nil {
return false, err
}
// fragment isn't a handshake, we don't need to handle it
- if frag.recordLayerHeader.contentType != contentTypeHandshake {
+ if frag.recordLayerHeader.ContentType != protocol.ContentTypeHandshake {
return false, nil
}
- if err := frag.handshakeHeader.Unmarshal(buf[recordLayerHeaderSize:]); err != nil {
- return false, err
- }
+ for buf = buf[recordlayer.FixedHeaderSize:]; len(buf) != 0; frag = new(fragment) {
+ if err := frag.handshakeHeader.Unmarshal(buf); err != nil {
+ return false, err
+ }
- if _, ok := f.cache[frag.handshakeHeader.messageSequence]; !ok {
- f.cache[frag.handshakeHeader.messageSequence] = []*fragment{}
- }
+ if _, ok := f.cache[frag.handshakeHeader.MessageSequence]; !ok {
+ f.cache[frag.handshakeHeader.MessageSequence] = []*fragment{}
+ }
+
+ // end index should be the length of handshake header but if the handshake
+ // was fragmented, we should keep them all
+ end := int(handshake.HeaderLength + frag.handshakeHeader.Length)
+ if size := len(buf); end > size {
+ end = size
+ }
- // Discard all headers, when rebuilding the packet we will re-build
- frag.data = append([]byte{}, buf[recordLayerHeaderSize+handshakeHeaderLength:]...)
- f.cache[frag.handshakeHeader.messageSequence] = append(f.cache[frag.handshakeHeader.messageSequence], frag)
+ // Discard all headers, when rebuilding the packet we will re-build
+ frag.data = append([]byte{}, buf[handshake.HeaderLength:end]...)
+ f.cache[frag.handshakeHeader.MessageSequence] = append(f.cache[frag.handshakeHeader.MessageSequence], frag)
+ buf = buf[end:]
+ }
return true, nil
}
@@ -58,9 +95,9 @@ func (f *fragmentBuffer) pop() (content []byte, epoch uint16) {
rawMessage := []byte{}
appendMessage = func(targetOffset uint32) bool {
for _, f := range frags {
- if f.handshakeHeader.fragmentOffset == targetOffset {
- fragmentEnd := (f.handshakeHeader.fragmentOffset + f.handshakeHeader.fragmentLength)
- if fragmentEnd != f.handshakeHeader.length {
+ if f.handshakeHeader.FragmentOffset == targetOffset {
+ fragmentEnd := (f.handshakeHeader.FragmentOffset + f.handshakeHeader.FragmentLength)
+ if fragmentEnd != f.handshakeHeader.Length && f.handshakeHeader.FragmentLength != 0 {
if !appendMessage(fragmentEnd) {
return false
}
@@ -79,15 +116,15 @@ func (f *fragmentBuffer) pop() (content []byte, epoch uint16) {
}
firstHeader := frags[0].handshakeHeader
- firstHeader.fragmentOffset = 0
- firstHeader.fragmentLength = firstHeader.length
+ firstHeader.FragmentOffset = 0
+ firstHeader.FragmentLength = firstHeader.Length
rawHeader, err := firstHeader.Marshal()
if err != nil {
return nil, 0
}
- messageEpoch := frags[0].recordLayerHeader.epoch
+ messageEpoch := frags[0].recordLayerHeader.Epoch
delete(f.cache, f.currentMessageSequenceNumber)
f.currentMessageSequenceNumber++
diff --git a/vendor/github.com/pion/dtls/v2/fuzz.go b/vendor/github.com/pion/dtls/v2/fuzz.go
deleted file mode 100644
index 8dfa9d5..0000000
--- a/vendor/github.com/pion/dtls/v2/fuzz.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// +build gofuzz
-
-package dtls
-
-import "fmt"
-
-func partialHeaderMismatch(a, b recordLayerHeader) bool {
- // Ignoring content length for now.
- a.contentLen = b.contentLen
- return a != b
-}
-
-func FuzzRecordLayer(data []byte) int {
- var r recordLayer
- if err := r.Unmarshal(data); err != nil {
- return 0
- }
- buf, err := r.Marshal()
- if err != nil {
- return 1
- }
- if len(buf) == 0 {
- panic("zero buff") // nolint
- }
- var nr recordLayer
- if err = nr.Unmarshal(data); err != nil {
- panic(err) // nolint
- }
- if partialHeaderMismatch(nr.recordLayerHeader, r.recordLayerHeader) {
- panic( // nolint
- fmt.Sprintf("header mismatch: %+v != %+v",
- nr.recordLayerHeader, r.recordLayerHeader,
- ),
- )
- }
-
- return 1
-}
diff --git a/vendor/github.com/pion/dtls/v2/go.mod b/vendor/github.com/pion/dtls/v2/go.mod
deleted file mode 100644
index a02393f..0000000
--- a/vendor/github.com/pion/dtls/v2/go.mod
+++ /dev/null
@@ -1,11 +0,0 @@
-module github.com/pion/dtls/v2
-
-require (
- github.com/pion/logging v0.2.2
- github.com/pion/transport v0.10.0
- golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59
- golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5
- golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
-)
-
-go 1.13
diff --git a/vendor/github.com/pion/dtls/v2/go.sum b/vendor/github.com/pion/dtls/v2/go.sum
deleted file mode 100644
index ed40f25..0000000
--- a/vendor/github.com/pion/dtls/v2/go.sum
+++ /dev/null
@@ -1,30 +0,0 @@
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-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 v0.10.0 h1:9M12BSneJm6ggGhJyWpDveFOstJsTiQjkLf4M44rm80=
-github.com/pion/transport v0.10.0/go.mod h1:BnHnUipd0rZQyTVB2SBGojFHT9CBt5C5TcsJSQGkvSE=
-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/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
-golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
-golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-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.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/pion/dtls/v2/handshake.go b/vendor/github.com/pion/dtls/v2/handshake.go
deleted file mode 100644
index 5a95da7..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake.go
+++ /dev/null
@@ -1,136 +0,0 @@
-package dtls
-
-// https://tools.ietf.org/html/rfc5246#section-7.4
-type handshakeType uint8
-
-const (
- handshakeTypeHelloRequest handshakeType = 0
- handshakeTypeClientHello handshakeType = 1
- handshakeTypeServerHello handshakeType = 2
- handshakeTypeHelloVerifyRequest handshakeType = 3
- handshakeTypeCertificate handshakeType = 11
- handshakeTypeServerKeyExchange handshakeType = 12
- handshakeTypeCertificateRequest handshakeType = 13
- handshakeTypeServerHelloDone handshakeType = 14
- handshakeTypeCertificateVerify handshakeType = 15
- handshakeTypeClientKeyExchange handshakeType = 16
- handshakeTypeFinished handshakeType = 20
-
- // msg_len for Handshake messages assumes an extra 12 bytes for
- // sequence, fragment and version information
- handshakeMessageHeaderLength = 12
-)
-
-type handshakeMessage interface {
- Marshal() ([]byte, error)
- Unmarshal(data []byte) error
-
- handshakeType() handshakeType
-}
-
-func (h handshakeType) String() string {
- switch h {
- case handshakeTypeHelloRequest:
- return "HelloRequest"
- case handshakeTypeClientHello:
- return "ClientHello"
- case handshakeTypeServerHello:
- return "ServerHello"
- case handshakeTypeHelloVerifyRequest:
- return "HelloVerifyRequest"
- case handshakeTypeCertificate:
- return "TypeCertificate"
- case handshakeTypeServerKeyExchange:
- return "ServerKeyExchange"
- case handshakeTypeCertificateRequest:
- return "CertificateRequest"
- case handshakeTypeServerHelloDone:
- return "ServerHelloDone"
- case handshakeTypeCertificateVerify:
- return "CertificateVerify"
- case handshakeTypeClientKeyExchange:
- return "ClientKeyExchange"
- case handshakeTypeFinished:
- return "Finished"
- }
- return ""
-}
-
-// The handshake protocol is responsible for selecting a cipher spec and
-// generating a master secret, which together comprise the primary
-// cryptographic parameters associated with a secure session. The
-// handshake protocol can also optionally authenticate parties who have
-// certificates signed by a trusted certificate authority.
-// https://tools.ietf.org/html/rfc5246#section-7.3
-type handshake struct {
- handshakeHeader handshakeHeader
- handshakeMessage handshakeMessage
-}
-
-func (h handshake) contentType() contentType {
- return contentTypeHandshake
-}
-
-func (h *handshake) Marshal() ([]byte, error) {
- if h.handshakeMessage == nil {
- return nil, errHandshakeMessageUnset
- } else if h.handshakeHeader.fragmentOffset != 0 {
- return nil, errUnableToMarshalFragmented
- }
-
- msg, err := h.handshakeMessage.Marshal()
- if err != nil {
- return nil, err
- }
-
- h.handshakeHeader.length = uint32(len(msg))
- h.handshakeHeader.fragmentLength = h.handshakeHeader.length
- h.handshakeHeader.handshakeType = h.handshakeMessage.handshakeType()
- header, err := h.handshakeHeader.Marshal()
- if err != nil {
- return nil, err
- }
-
- return append(header, msg...), nil
-}
-
-func (h *handshake) Unmarshal(data []byte) error {
- if err := h.handshakeHeader.Unmarshal(data); err != nil {
- return err
- }
-
- reportedLen := bigEndianUint24(data[1:])
- if uint32(len(data)-handshakeMessageHeaderLength) != reportedLen {
- return errLengthMismatch
- } else if reportedLen != h.handshakeHeader.fragmentLength {
- return errLengthMismatch
- }
-
- switch handshakeType(data[0]) {
- case handshakeTypeHelloRequest:
- return errNotImplemented
- case handshakeTypeClientHello:
- h.handshakeMessage = &handshakeMessageClientHello{}
- case handshakeTypeHelloVerifyRequest:
- h.handshakeMessage = &handshakeMessageHelloVerifyRequest{}
- case handshakeTypeServerHello:
- h.handshakeMessage = &handshakeMessageServerHello{}
- case handshakeTypeCertificate:
- h.handshakeMessage = &handshakeMessageCertificate{}
- case handshakeTypeServerKeyExchange:
- h.handshakeMessage = &handshakeMessageServerKeyExchange{}
- case handshakeTypeCertificateRequest:
- h.handshakeMessage = &handshakeMessageCertificateRequest{}
- case handshakeTypeServerHelloDone:
- h.handshakeMessage = &handshakeMessageServerHelloDone{}
- case handshakeTypeClientKeyExchange:
- h.handshakeMessage = &handshakeMessageClientKeyExchange{}
- case handshakeTypeFinished:
- h.handshakeMessage = &handshakeMessageFinished{}
- case handshakeTypeCertificateVerify:
- h.handshakeMessage = &handshakeMessageCertificateVerify{}
- default:
- return errNotImplemented
- }
- return h.handshakeMessage.Unmarshal(data[handshakeMessageHeaderLength:])
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_cache.go b/vendor/github.com/pion/dtls/v2/handshake_cache.go
index 90da29e..8d59605 100644
--- a/vendor/github.com/pion/dtls/v2/handshake_cache.go
+++ b/vendor/github.com/pion/dtls/v2/handshake_cache.go
@@ -1,11 +1,17 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
"sync"
+
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
)
type handshakeCacheItem struct {
- typ handshakeType
+ typ handshake.Type
isClient bool
epoch uint16
messageSequence uint16
@@ -13,7 +19,7 @@ type handshakeCacheItem struct {
}
type handshakeCachePullRule struct {
- typ handshakeType
+ typ handshake.Type
epoch uint16
isClient bool
optional bool
@@ -28,17 +34,10 @@ func newHandshakeCache() *handshakeCache {
return &handshakeCache{}
}
-func (h *handshakeCache) push(data []byte, epoch, messageSequence uint16, typ handshakeType, isClient bool) bool {
+func (h *handshakeCache) push(data []byte, epoch, messageSequence uint16, typ handshake.Type, isClient bool) {
h.mu.Lock()
defer h.mu.Unlock()
- for _, i := range h.cache {
- if i.messageSequence == messageSequence &&
- i.isClient == isClient {
- return false
- }
- }
-
h.cache = append(h.cache, &handshakeCacheItem{
data: append([]byte{}, data...),
epoch: epoch,
@@ -46,7 +45,6 @@ func (h *handshakeCache) push(data []byte, epoch, messageSequence uint16, typ ha
typ: typ,
isClient: isClient,
})
- return true
}
// returns a list handshakes that match the requested rules
@@ -74,11 +72,11 @@ func (h *handshakeCache) pull(rules ...handshakeCachePullRule) []*handshakeCache
}
// fullPullMap pulls all handshakes between rules[0] to rules[len(rules)-1] as map.
-func (h *handshakeCache) fullPullMap(startSeq int, rules ...handshakeCachePullRule) (int, map[handshakeType]handshakeMessage, bool) {
+func (h *handshakeCache) fullPullMap(startSeq int, cipherSuite CipherSuite, rules ...handshakeCachePullRule) (int, map[handshake.Type]handshake.Message, bool) {
h.mu.Lock()
defer h.mu.Unlock()
- ci := make(map[handshakeType]*handshakeCacheItem)
+ ci := make(map[handshake.Type]*handshakeCacheItem)
for _, r := range rules {
var item *handshakeCacheItem
for _, c := range h.cache {
@@ -97,7 +95,7 @@ func (h *handshakeCache) fullPullMap(startSeq int, rules ...handshakeCachePullRu
}
ci[r.typ] = item
}
- out := make(map[handshakeType]handshakeMessage)
+ out := make(map[handshake.Type]handshake.Message)
seq := startSeq
for _, r := range rules {
t := r.typ
@@ -105,16 +103,22 @@ func (h *handshakeCache) fullPullMap(startSeq int, rules ...handshakeCachePullRu
if i == nil {
continue
}
- rawHandshake := &handshake{}
+ var keyExchangeAlgorithm CipherSuiteKeyExchangeAlgorithm
+ if cipherSuite != nil {
+ keyExchangeAlgorithm = cipherSuite.KeyExchangeAlgorithm()
+ }
+ rawHandshake := &handshake.Handshake{
+ KeyExchangeAlgorithm: keyExchangeAlgorithm,
+ }
if err := rawHandshake.Unmarshal(i.data); err != nil {
return startSeq, nil, false
}
- if uint16(seq) != rawHandshake.handshakeHeader.messageSequence {
+ if uint16(seq) != rawHandshake.Header.MessageSequence {
// There is a gap. Some messages are not arrived.
return startSeq, nil, false
}
seq++
- out[t] = rawHandshake.handshakeMessage
+ out[t] = rawHandshake.Message
}
return seq, out, true
}
@@ -133,19 +137,19 @@ func (h *handshakeCache) pullAndMerge(rules ...handshakeCachePullRule) []byte {
// sessionHash returns the session hash for Extended Master Secret support
// https://tools.ietf.org/html/draft-ietf-tls-session-hash-06#section-4
-func (h *handshakeCache) sessionHash(hf hashFunc, epoch uint16, additional ...[]byte) ([]byte, error) {
+func (h *handshakeCache) sessionHash(hf prf.HashFunc, epoch uint16, additional ...[]byte) ([]byte, error) {
merged := []byte{}
// Order defined by https://tools.ietf.org/html/rfc5246#section-7.3
handshakeBuffer := h.pull(
- handshakeCachePullRule{handshakeTypeClientHello, epoch, true, false},
- handshakeCachePullRule{handshakeTypeServerHello, epoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, epoch, false, false},
- handshakeCachePullRule{handshakeTypeServerKeyExchange, epoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificateRequest, epoch, false, false},
- handshakeCachePullRule{handshakeTypeServerHelloDone, epoch, false, false},
- handshakeCachePullRule{handshakeTypeCertificate, epoch, true, false},
- handshakeCachePullRule{handshakeTypeClientKeyExchange, epoch, true, false},
+ handshakeCachePullRule{handshake.TypeClientHello, epoch, true, false},
+ handshakeCachePullRule{handshake.TypeServerHello, epoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, epoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerKeyExchange, epoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificateRequest, epoch, false, false},
+ handshakeCachePullRule{handshake.TypeServerHelloDone, epoch, false, false},
+ handshakeCachePullRule{handshake.TypeCertificate, epoch, true, false},
+ handshakeCachePullRule{handshake.TypeClientKeyExchange, epoch, true, false},
)
for _, p := range handshakeBuffer {
diff --git a/vendor/github.com/pion/dtls/v2/handshake_header.go b/vendor/github.com/pion/dtls/v2/handshake_header.go
deleted file mode 100644
index 8198294..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_header.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-// msg_len for Handshake messages assumes an extra 12 bytes for
-// sequence, fragment and version information
-const handshakeHeaderLength = 12
-
-type handshakeHeader struct {
- handshakeType handshakeType
- length uint32 // uint24 in spec
- messageSequence uint16
- fragmentOffset uint32 // uint24 in spec
- fragmentLength uint32 // uint24 in spec
-}
-
-func (h *handshakeHeader) Marshal() ([]byte, error) {
- out := make([]byte, handshakeMessageHeaderLength)
-
- out[0] = byte(h.handshakeType)
- putBigEndianUint24(out[1:], h.length)
- binary.BigEndian.PutUint16(out[4:], h.messageSequence)
- putBigEndianUint24(out[6:], h.fragmentOffset)
- putBigEndianUint24(out[9:], h.fragmentLength)
- return out, nil
-}
-
-func (h *handshakeHeader) Unmarshal(data []byte) error {
- if len(data) < handshakeHeaderLength {
- return errBufferTooSmall
- }
-
- h.handshakeType = handshakeType(data[0])
- h.length = bigEndianUint24(data[1:])
- h.messageSequence = binary.BigEndian.Uint16(data[4:])
- h.fragmentOffset = bigEndianUint24(data[6:])
- h.fragmentLength = bigEndianUint24(data[9:])
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_message_certificate.go b/vendor/github.com/pion/dtls/v2/handshake_message_certificate.go
deleted file mode 100644
index c968cfe..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_message_certificate.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package dtls
-
-type handshakeMessageCertificate struct {
- certificate [][]byte
-}
-
-func (h handshakeMessageCertificate) handshakeType() handshakeType {
- return handshakeTypeCertificate
-}
-
-const (
- handshakeMessageCertificateLengthFieldSize = 3
-)
-
-func (h *handshakeMessageCertificate) Marshal() ([]byte, error) {
- out := make([]byte, handshakeMessageCertificateLengthFieldSize)
-
- for _, r := range h.certificate {
- // Certificate Length
- out = append(out, make([]byte, handshakeMessageCertificateLengthFieldSize)...)
- putBigEndianUint24(out[len(out)-handshakeMessageCertificateLengthFieldSize:], uint32(len(r)))
-
- // Certificate body
- out = append(out, append([]byte{}, r...)...)
- }
-
- // Total Payload Size
- putBigEndianUint24(out[0:], uint32(len(out[handshakeMessageCertificateLengthFieldSize:])))
- return out, nil
-}
-
-func (h *handshakeMessageCertificate) Unmarshal(data []byte) error {
- if len(data) < handshakeMessageCertificateLengthFieldSize {
- return errBufferTooSmall
- }
-
- if certificateBodyLen := int(bigEndianUint24(data)); certificateBodyLen+handshakeMessageCertificateLengthFieldSize != len(data) {
- return errLengthMismatch
- }
-
- offset := handshakeMessageCertificateLengthFieldSize
- for offset < len(data) {
- certificateLen := int(bigEndianUint24(data[offset:]))
- offset += handshakeMessageCertificateLengthFieldSize
-
- if offset+certificateLen > len(data) {
- return errLengthMismatch
- }
-
- h.certificate = append(h.certificate, append([]byte{}, data[offset:offset+certificateLen]...))
- offset += certificateLen
- }
-
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_message_certificate_request.go b/vendor/github.com/pion/dtls/v2/handshake_message_certificate_request.go
deleted file mode 100644
index eafe174..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_message_certificate_request.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-/*
-A non-anonymous server can optionally request a certificate from
-the client, if appropriate for the selected cipher suite. This
-message, if sent, will immediately follow the ServerKeyExchange
-message (if it is sent; otherwise, this message follows the
-server's Certificate message).
-*/
-
-type handshakeMessageCertificateRequest struct {
- certificateTypes []clientCertificateType
- signatureHashAlgorithms []signatureHashAlgorithm
-}
-
-const (
- handshakeMessageCertificateRequestMinLength = 5
-)
-
-func (h handshakeMessageCertificateRequest) handshakeType() handshakeType {
- return handshakeTypeCertificateRequest
-}
-
-func (h *handshakeMessageCertificateRequest) Marshal() ([]byte, error) {
- out := []byte{byte(len(h.certificateTypes))}
- for _, v := range h.certificateTypes {
- out = append(out, byte(v))
- }
-
- out = append(out, []byte{0x00, 0x00}...)
- binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(h.signatureHashAlgorithms)*2))
- for _, v := range h.signatureHashAlgorithms {
- out = append(out, byte(v.hash))
- out = append(out, byte(v.signature))
- }
-
- out = append(out, []byte{0x00, 0x00}...) // Distinguished Names Length
- return out, nil
-}
-
-func (h *handshakeMessageCertificateRequest) Unmarshal(data []byte) error {
- if len(data) < handshakeMessageCertificateRequestMinLength {
- return errBufferTooSmall
- }
-
- offset := 0
- certificateTypesLength := int(data[0])
- offset++
-
- if (offset + certificateTypesLength) > len(data) {
- return errBufferTooSmall
- }
-
- for i := 0; i < certificateTypesLength; i++ {
- certType := clientCertificateType(data[offset+i])
- if _, ok := clientCertificateTypes[certType]; ok {
- h.certificateTypes = append(h.certificateTypes, certType)
- }
- }
- offset += certificateTypesLength
- if len(data) < offset+2 {
- return errBufferTooSmall
- }
- signatureHashAlgorithmsLength := int(binary.BigEndian.Uint16(data[offset:]))
- offset += 2
-
- if (offset + signatureHashAlgorithmsLength) > len(data) {
- return errBufferTooSmall
- }
-
- for i := 0; i < signatureHashAlgorithmsLength; i += 2 {
- if len(data) < (offset + i + 2) {
- return errBufferTooSmall
- }
- hash := hashAlgorithm(data[offset+i])
- signature := signatureAlgorithm(data[offset+i+1])
-
- if _, ok := hashAlgorithms[hash]; !ok {
- continue
- } else if _, ok := signatureAlgorithms[signature]; !ok {
- continue
- }
- h.signatureHashAlgorithms = append(h.signatureHashAlgorithms, signatureHashAlgorithm{signature: signature, hash: hash})
- }
-
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_message_certificate_verify.go b/vendor/github.com/pion/dtls/v2/handshake_message_certificate_verify.go
deleted file mode 100644
index 2a45eb4..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_message_certificate_verify.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-type handshakeMessageCertificateVerify struct {
- hashAlgorithm hashAlgorithm
- signatureAlgorithm signatureAlgorithm
- signature []byte
-}
-
-const handshakeMessageCertificateVerifyMinLength = 4
-
-func (h handshakeMessageCertificateVerify) handshakeType() handshakeType {
- return handshakeTypeCertificateVerify
-}
-
-func (h *handshakeMessageCertificateVerify) Marshal() ([]byte, error) {
- out := make([]byte, 1+1+2+len(h.signature))
-
- out[0] = byte(h.hashAlgorithm)
- out[1] = byte(h.signatureAlgorithm)
- binary.BigEndian.PutUint16(out[2:], uint16(len(h.signature)))
- copy(out[4:], h.signature)
- return out, nil
-}
-
-func (h *handshakeMessageCertificateVerify) Unmarshal(data []byte) error {
- if len(data) < handshakeMessageCertificateVerifyMinLength {
- return errBufferTooSmall
- }
-
- h.hashAlgorithm = hashAlgorithm(data[0])
- if _, ok := hashAlgorithms[h.hashAlgorithm]; !ok {
- return errInvalidHashAlgorithm
- }
-
- h.signatureAlgorithm = signatureAlgorithm(data[1])
- if _, ok := signatureAlgorithms[h.signatureAlgorithm]; !ok {
- return errInvalidSignatureAlgorithm
- }
-
- signatureLength := int(binary.BigEndian.Uint16(data[2:]))
- if (signatureLength + 4) != len(data) {
- return errBufferTooSmall
- }
-
- h.signature = append([]byte{}, data[4:]...)
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_message_client_hello.go b/vendor/github.com/pion/dtls/v2/handshake_message_client_hello.go
deleted file mode 100644
index f61adb9..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_message_client_hello.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-/*
-When a client first connects to a server it is required to send
-the client hello as its first message. The client can also send a
-client hello in response to a hello request or on its own
-initiative in order to renegotiate the security parameters in an
-existing connection.
-*/
-type handshakeMessageClientHello struct {
- version protocolVersion
- random handshakeRandom
- cookie []byte
-
- cipherSuites []cipherSuite
- compressionMethods []*compressionMethod
- extensions []extension
-}
-
-const handshakeMessageClientHelloVariableWidthStart = 34
-
-func (h handshakeMessageClientHello) handshakeType() handshakeType {
- return handshakeTypeClientHello
-}
-
-func (h *handshakeMessageClientHello) Marshal() ([]byte, error) {
- if len(h.cookie) > 255 {
- return nil, errCookieTooLong
- }
-
- out := make([]byte, handshakeMessageClientHelloVariableWidthStart)
- out[0] = h.version.major
- out[1] = h.version.minor
-
- rand := h.random.marshalFixed()
- copy(out[2:], rand[:])
-
- out = append(out, 0x00) // SessionID
-
- out = append(out, byte(len(h.cookie)))
- out = append(out, h.cookie...)
- out = append(out, encodeCipherSuites(h.cipherSuites)...)
- out = append(out, encodeCompressionMethods(h.compressionMethods)...)
-
- extensions, err := encodeExtensions(h.extensions)
- if err != nil {
- return nil, err
- }
-
- return append(out, extensions...), nil
-}
-
-func (h *handshakeMessageClientHello) Unmarshal(data []byte) error {
- if len(data) < 2+handshakeRandomLength {
- return errBufferTooSmall
- }
-
- h.version.major = data[0]
- h.version.minor = data[1]
-
- var random [handshakeRandomLength]byte
- copy(random[:], data[2:])
- h.random.unmarshalFixed(random)
-
- // rest of packet has variable width sections
- currOffset := handshakeMessageClientHelloVariableWidthStart
- currOffset += int(data[currOffset]) + 1 // SessionID
-
- currOffset++
- if len(data) <= currOffset {
- return errBufferTooSmall
- }
- n := int(data[currOffset-1])
- if len(data) <= currOffset+n {
- return errBufferTooSmall
- }
- h.cookie = append([]byte{}, data[currOffset:currOffset+n]...)
- currOffset += len(h.cookie)
-
- // Cipher Suites
- if len(data) < currOffset {
- return errBufferTooSmall
- }
- cipherSuites, err := decodeCipherSuites(data[currOffset:])
- if err != nil {
- return err
- }
- h.cipherSuites = cipherSuites
- if len(data) < currOffset+2 {
- return errBufferTooSmall
- }
- currOffset += int(binary.BigEndian.Uint16(data[currOffset:])) + 2
-
- // Compression Methods
- if len(data) < currOffset {
- return errBufferTooSmall
- }
- compressionMethods, err := decodeCompressionMethods(data[currOffset:])
- if err != nil {
- return err
- }
- h.compressionMethods = compressionMethods
- if len(data) < currOffset {
- return errBufferTooSmall
- }
- currOffset += int(data[currOffset]) + 1
-
- // Extensions
- extensions, err := decodeExtensions(data[currOffset:])
- if err != nil {
- return err
- }
- h.extensions = extensions
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_message_client_key_exchange.go b/vendor/github.com/pion/dtls/v2/handshake_message_client_key_exchange.go
deleted file mode 100644
index b2ab209..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_message_client_key_exchange.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-type handshakeMessageClientKeyExchange struct {
- identityHint []byte
- publicKey []byte
-}
-
-func (h handshakeMessageClientKeyExchange) handshakeType() handshakeType {
- return handshakeTypeClientKeyExchange
-}
-
-func (h *handshakeMessageClientKeyExchange) Marshal() ([]byte, error) {
- switch {
- case (h.identityHint != nil && h.publicKey != nil) || (h.identityHint == nil && h.publicKey == nil):
- return nil, errInvalidClientKeyExchange
- case h.publicKey != nil:
- return append([]byte{byte(len(h.publicKey))}, h.publicKey...), nil
- default:
- out := append([]byte{0x00, 0x00}, h.identityHint...)
- binary.BigEndian.PutUint16(out, uint16(len(out)-2))
- return out, nil
- }
-}
-
-func (h *handshakeMessageClientKeyExchange) Unmarshal(data []byte) error {
- if len(data) < 2 {
- return errBufferTooSmall
- }
-
- // If parsed as PSK return early and only populate PSK Identity Hint
- if pskLength := binary.BigEndian.Uint16(data); len(data) == int(pskLength+2) {
- h.identityHint = append([]byte{}, data[2:]...)
- return nil
- }
-
- if publicKeyLength := int(data[0]); len(data) != publicKeyLength+1 {
- return errBufferTooSmall
- }
-
- h.publicKey = append([]byte{}, data[1:]...)
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_message_finished.go b/vendor/github.com/pion/dtls/v2/handshake_message_finished.go
deleted file mode 100644
index 9149150..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_message_finished.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package dtls
-
-type handshakeMessageFinished struct {
- verifyData []byte
-}
-
-func (h handshakeMessageFinished) handshakeType() handshakeType {
- return handshakeTypeFinished
-}
-
-func (h *handshakeMessageFinished) Marshal() ([]byte, error) {
- return append([]byte{}, h.verifyData...), nil
-}
-
-func (h *handshakeMessageFinished) Unmarshal(data []byte) error {
- h.verifyData = append([]byte{}, data...)
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_message_hello_verify_request.go b/vendor/github.com/pion/dtls/v2/handshake_message_hello_verify_request.go
deleted file mode 100644
index 453947f..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_message_hello_verify_request.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package dtls
-
-/*
- The definition of HelloVerifyRequest is as follows:
-
- struct {
- ProtocolVersion server_version;
- opaque cookie<0..2^8-1>;
- } HelloVerifyRequest;
-
- The HelloVerifyRequest message type is hello_verify_request(3).
-
- When the client sends its ClientHello message to the server, the server
- MAY respond with a HelloVerifyRequest message. This message contains
- a stateless cookie generated using the technique of [PHOTURIS]. The
- client MUST retransmit the ClientHello with the cookie added.
-
- https://tools.ietf.org/html/rfc6347#section-4.2.1
-*/
-type handshakeMessageHelloVerifyRequest struct {
- version protocolVersion
- cookie []byte
-}
-
-func (h handshakeMessageHelloVerifyRequest) handshakeType() handshakeType {
- return handshakeTypeHelloVerifyRequest
-}
-
-func (h *handshakeMessageHelloVerifyRequest) Marshal() ([]byte, error) {
- if len(h.cookie) > 255 {
- return nil, errCookieTooLong
- }
-
- out := make([]byte, 3+len(h.cookie))
- out[0] = h.version.major
- out[1] = h.version.minor
- out[2] = byte(len(h.cookie))
- copy(out[3:], h.cookie)
-
- return out, nil
-}
-
-func (h *handshakeMessageHelloVerifyRequest) Unmarshal(data []byte) error {
- if len(data) < 3 {
- return errBufferTooSmall
- }
- h.version.major = data[0]
- h.version.minor = data[1]
- cookieLength := data[2]
- if len(data) < (int(cookieLength) + 3) {
- return errBufferTooSmall
- }
- h.cookie = make([]byte, cookieLength)
-
- copy(h.cookie, data[3:3+cookieLength])
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_message_server_hello.go b/vendor/github.com/pion/dtls/v2/handshake_message_server_hello.go
deleted file mode 100644
index 5be0159..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_message_server_hello.go
+++ /dev/null
@@ -1,102 +0,0 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-/*
-The server will send this message in response to a ClientHello
-message when it was able to find an acceptable set of algorithms.
-If it cannot find such a match, it will respond with a handshake
-failure alert.
-https://tools.ietf.org/html/rfc5246#section-7.4.1.3
-*/
-type handshakeMessageServerHello struct {
- version protocolVersion
- random handshakeRandom
-
- cipherSuite cipherSuite
- compressionMethod *compressionMethod
- extensions []extension
-}
-
-const handshakeMessageServerHelloVariableWidthStart = 2 + handshakeRandomLength
-
-func (h handshakeMessageServerHello) handshakeType() handshakeType {
- return handshakeTypeServerHello
-}
-
-func (h *handshakeMessageServerHello) Marshal() ([]byte, error) {
- if h.cipherSuite == nil {
- return nil, errCipherSuiteUnset
- } else if h.compressionMethod == nil {
- return nil, errCompressionMethodUnset
- }
-
- out := make([]byte, handshakeMessageServerHelloVariableWidthStart)
- out[0] = h.version.major
- out[1] = h.version.minor
-
- rand := h.random.marshalFixed()
- copy(out[2:], rand[:])
-
- out = append(out, 0x00) // SessionID
-
- out = append(out, []byte{0x00, 0x00}...)
- binary.BigEndian.PutUint16(out[len(out)-2:], uint16(h.cipherSuite.ID()))
-
- out = append(out, byte(h.compressionMethod.id))
-
- extensions, err := encodeExtensions(h.extensions)
- if err != nil {
- return nil, err
- }
-
- return append(out, extensions...), nil
-}
-
-func (h *handshakeMessageServerHello) Unmarshal(data []byte) error {
- if len(data) < 2+handshakeRandomLength {
- return errBufferTooSmall
- }
-
- h.version.major = data[0]
- h.version.minor = data[1]
-
- var random [handshakeRandomLength]byte
- copy(random[:], data[2:])
- h.random.unmarshalFixed(random)
-
- currOffset := handshakeMessageServerHelloVariableWidthStart
- currOffset += int(data[currOffset]) + 1 // SessionID
- if len(data) < (currOffset + 2) {
- return errBufferTooSmall
- }
- if c := cipherSuiteForID(CipherSuiteID(binary.BigEndian.Uint16(data[currOffset:]))); c != nil {
- h.cipherSuite = c
- currOffset += 2
- } else {
- return errInvalidCipherSuite
- }
- if len(data) < currOffset {
- return errBufferTooSmall
- }
- if compressionMethod, ok := compressionMethods[compressionMethodID(data[currOffset])]; ok {
- h.compressionMethod = compressionMethod
- currOffset++
- } else {
- return errInvalidCompressionMethod
- }
-
- if len(data) <= currOffset {
- h.extensions = []extension{}
- return nil
- }
-
- extensions, err := decodeExtensions(data[currOffset:])
- if err != nil {
- return err
- }
- h.extensions = extensions
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_message_server_hello_done.go b/vendor/github.com/pion/dtls/v2/handshake_message_server_hello_done.go
deleted file mode 100644
index 0d591d6..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_message_server_hello_done.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package dtls
-
-type handshakeMessageServerHelloDone struct {
-}
-
-func (h handshakeMessageServerHelloDone) handshakeType() handshakeType {
- return handshakeTypeServerHelloDone
-}
-
-func (h *handshakeMessageServerHelloDone) Marshal() ([]byte, error) {
- return []byte{}, nil
-}
-
-func (h *handshakeMessageServerHelloDone) Unmarshal(data []byte) error {
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_message_server_key_exchange.go b/vendor/github.com/pion/dtls/v2/handshake_message_server_key_exchange.go
deleted file mode 100644
index 6d01158..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_message_server_key_exchange.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-// Structure supports ECDH and PSK
-type handshakeMessageServerKeyExchange struct {
- identityHint []byte
-
- ellipticCurveType ellipticCurveType
- namedCurve namedCurve
- publicKey []byte
- hashAlgorithm hashAlgorithm
- signatureAlgorithm signatureAlgorithm
- signature []byte
-}
-
-func (h handshakeMessageServerKeyExchange) handshakeType() handshakeType {
- return handshakeTypeServerKeyExchange
-}
-
-func (h *handshakeMessageServerKeyExchange) Marshal() ([]byte, error) {
- if h.identityHint != nil {
- out := append([]byte{0x00, 0x00}, h.identityHint...)
- binary.BigEndian.PutUint16(out, uint16(len(out)-2))
- return out, nil
- }
-
- out := []byte{byte(h.ellipticCurveType), 0x00, 0x00}
- binary.BigEndian.PutUint16(out[1:], uint16(h.namedCurve))
-
- out = append(out, byte(len(h.publicKey)))
- out = append(out, h.publicKey...)
-
- out = append(out, []byte{byte(h.hashAlgorithm), byte(h.signatureAlgorithm), 0x00, 0x00}...)
-
- binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(h.signature)))
- out = append(out, h.signature...)
-
- return out, nil
-}
-
-func (h *handshakeMessageServerKeyExchange) Unmarshal(data []byte) error {
- if len(data) < 2 {
- return errBufferTooSmall
- }
-
- // If parsed as PSK return early and only populate PSK Identity Hint
- if pskLength := binary.BigEndian.Uint16(data); len(data) == int(pskLength+2) {
- h.identityHint = append([]byte{}, data[2:]...)
- return nil
- }
-
- if _, ok := ellipticCurveTypes[ellipticCurveType(data[0])]; ok {
- h.ellipticCurveType = ellipticCurveType(data[0])
- } else {
- return errInvalidEllipticCurveType
- }
-
- if len(data[1:]) < 2 {
- return errBufferTooSmall
- }
- h.namedCurve = namedCurve(binary.BigEndian.Uint16(data[1:3]))
- if _, ok := namedCurves[h.namedCurve]; !ok {
- return errInvalidNamedCurve
- }
- if len(data) < 4 {
- return errBufferTooSmall
- }
-
- publicKeyLength := int(data[3])
- offset := 4 + publicKeyLength
- if len(data) < offset {
- return errBufferTooSmall
- }
- h.publicKey = append([]byte{}, data[4:offset]...)
- if len(data) <= offset {
- return errBufferTooSmall
- }
- h.hashAlgorithm = hashAlgorithm(data[offset])
- if _, ok := hashAlgorithms[h.hashAlgorithm]; !ok {
- return errInvalidHashAlgorithm
- }
- offset++
- if len(data) <= offset {
- return errBufferTooSmall
- }
- h.signatureAlgorithm = signatureAlgorithm(data[offset])
- if _, ok := signatureAlgorithms[h.signatureAlgorithm]; !ok {
- return errInvalidSignatureAlgorithm
- }
- offset++
- if len(data) < offset+2 {
- return errBufferTooSmall
- }
- signatureLength := int(binary.BigEndian.Uint16(data[offset:]))
- offset += 2
- if len(data) < offset+signatureLength {
- return errBufferTooSmall
- }
- h.signature = append([]byte{}, data[offset:offset+signatureLength]...)
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshake_random.go b/vendor/github.com/pion/dtls/v2/handshake_random.go
deleted file mode 100644
index 479132e..0000000
--- a/vendor/github.com/pion/dtls/v2/handshake_random.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package dtls
-
-import (
- "crypto/rand"
- "encoding/binary"
- "time"
-)
-
-const randomBytesLength = 28
-const handshakeRandomLength = randomBytesLength + 4
-
-// https://tools.ietf.org/html/rfc4346#section-7.4.1.2
-type handshakeRandom struct {
- gmtUnixTime time.Time
- randomBytes [randomBytesLength]byte
-}
-
-func (h *handshakeRandom) marshalFixed() [handshakeRandomLength]byte {
- var out [handshakeRandomLength]byte
-
- binary.BigEndian.PutUint32(out[0:], uint32(h.gmtUnixTime.Unix()))
- copy(out[4:], h.randomBytes[:])
-
- return out
-}
-
-func (h *handshakeRandom) unmarshalFixed(data [handshakeRandomLength]byte) {
- h.gmtUnixTime = time.Unix(int64(binary.BigEndian.Uint32(data[0:])), 0)
- copy(h.randomBytes[:], data[4:])
-}
-
-// populate fills the handshakeRandom with random values
-// may be called multiple times
-func (h *handshakeRandom) populate() error {
- h.gmtUnixTime = time.Now()
-
- tmp := make([]byte, randomBytesLength)
- _, err := rand.Read(tmp)
- copy(h.randomBytes[:], tmp)
-
- return err
-}
diff --git a/vendor/github.com/pion/dtls/v2/handshaker.go b/vendor/github.com/pion/dtls/v2/handshaker.go
index a479377..46fbd38 100644
--- a/vendor/github.com/pion/dtls/v2/handshaker.go
+++ b/vendor/github.com/pion/dtls/v2/handshaker.go
@@ -1,13 +1,21 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
"context"
"crypto/tls"
"crypto/x509"
- "errors"
+ "fmt"
+ "io"
"sync"
"time"
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+ "github.com/pion/dtls/v2/pkg/crypto/signaturehash"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
"github.com/pion/logging"
)
@@ -46,8 +54,6 @@ import (
// Read retransmit
// Retransmit last flight
-var errInvalidFSMTransition = errors.New("invalid state machine transition")
-
type handshakeState uint8
const (
@@ -78,6 +84,7 @@ func (s handshakeState) String() string {
type handshakeFSM struct {
currentFlight flightVal
flights []*packet
+ retransmit bool
state *State
cache *handshakeCache
cfg *handshakeConfig
@@ -87,22 +94,33 @@ type handshakeFSM struct {
type handshakeConfig struct {
localPSKCallback PSKCallback
localPSKIdentityHint []byte
- localCipherSuites []cipherSuite // Available CipherSuites
- localSignatureSchemes []signatureHashAlgorithm // Available signature schemes
- extendedMasterSecret ExtendedMasterSecretType // Policy for the Extended Master Support extension
- localSRTPProtectionProfiles []SRTPProtectionProfile // Available SRTPProtectionProfiles, if empty no SRTP support
+ localCipherSuites []CipherSuite // Available CipherSuites
+ localSignatureSchemes []signaturehash.Algorithm // Available signature schemes
+ extendedMasterSecret ExtendedMasterSecretType // Policy for the Extended Master Support extension
+ localSRTPProtectionProfiles []SRTPProtectionProfile // Available SRTPProtectionProfiles, if empty no SRTP support
serverName string
+ supportedProtocols []string
clientAuth ClientAuthType // If we are a client should we request a client certificate
localCertificates []tls.Certificate
nameToCertificate map[string]*tls.Certificate
insecureSkipVerify bool
verifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
+ verifyConnection func(*State) error
+ sessionStore SessionStore
rootCAs *x509.CertPool
clientCAs *x509.CertPool
retransmitInterval time.Duration
+ customCipherSuites func() []CipherSuite
+ ellipticCurves []elliptic.Curve
+ insecureSkipHelloVerify bool
+ connectionIDGenerator func() []byte
onFlightState func(flightVal, handshakeState)
log logging.LeveledLogger
+ keyLogWriter io.Writer
+
+ localGetCertificate func(*ClientHelloInfo) (*tls.Certificate, error)
+ localGetClientCertificate func(*CertificateRequestInfo) (*tls.Certificate, error)
initialEpoch uint16
@@ -110,11 +128,24 @@ type handshakeConfig struct {
}
type flightConn interface {
- notify(ctx context.Context, level alertLevel, desc alertDescription) error
+ notify(ctx context.Context, level alert.Level, desc alert.Description) error
writePackets(context.Context, []*packet) error
recvHandshake() <-chan chan struct{}
setLocalEpoch(epoch uint16)
handleQueuedPackets(context.Context) error
+ sessionKey() []byte
+}
+
+func (c *handshakeConfig) writeKeyLog(label string, clientRandom, secret []byte) {
+ if c.keyLogWriter == nil {
+ return
+ }
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ _, err := c.keyLogWriter.Write([]byte(fmt.Sprintf("%s %x %x\n", label, clientRandom, secret)))
+ if err != nil {
+ c.log.Debugf("failed to write key log file: %s", err)
+ }
}
func srvCliStr(isClient bool) string {
@@ -174,19 +205,20 @@ func (s *handshakeFSM) prepare(ctx context.Context, c flightConn) (handshakeStat
s.flights = nil
// Prepare flights
var (
- a *alert
+ a *alert.Alert
err error
pkts []*packet
)
- gen, errFlight := s.currentFlight.getFlightGenerator()
+ gen, retransmit, errFlight := s.currentFlight.getFlightGenerator()
if errFlight != nil {
err = errFlight
- a = &alert{alertLevelFatal, alertInternalError}
+ a = &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}
} else {
pkts, a, err = gen(c, s.state, s.cache, s.cfg)
+ s.retransmit = retransmit
}
if a != nil {
- if alertErr := c.notify(ctx, a.alertLevel, a.alertDescription); alertErr != nil {
+ if alertErr := c.notify(ctx, a.Level, a.Description); alertErr != nil {
if err != nil {
err = alertErr
}
@@ -200,12 +232,12 @@ func (s *handshakeFSM) prepare(ctx context.Context, c flightConn) (handshakeStat
epoch := s.cfg.initialEpoch
nextEpoch := epoch
for _, p := range s.flights {
- p.record.recordLayerHeader.epoch += epoch
- if p.record.recordLayerHeader.epoch > nextEpoch {
- nextEpoch = p.record.recordLayerHeader.epoch
+ p.record.Header.Epoch += epoch
+ if p.record.Header.Epoch > nextEpoch {
+ nextEpoch = p.record.Header.Epoch
}
- if h, ok := p.record.content.(*handshake); ok {
- h.handshakeHeader.messageSequence = uint16(s.state.handshakeSendSequence)
+ if h, ok := p.record.Content.(*handshake.Handshake); ok {
+ h.Header.MessageSequence = uint16(s.state.handshakeSendSequence)
s.state.handshakeSendSequence++
}
}
@@ -228,13 +260,11 @@ func (s *handshakeFSM) send(ctx context.Context, c flightConn) (handshakeState,
return handshakeWaiting, nil
}
-func (s *handshakeFSM) wait(ctx context.Context, c flightConn) (handshakeState, error) {
+func (s *handshakeFSM) wait(ctx context.Context, c flightConn) (handshakeState, error) { //nolint:gocognit
parse, errFlight := s.currentFlight.getFlightParser()
if errFlight != nil {
- if alertErr := c.notify(ctx, alertLevelFatal, alertInternalError); alertErr != nil {
- if errFlight != nil {
- return handshakeErrored, alertErr
- }
+ if alertErr := c.notify(ctx, alert.Fatal, alert.InternalError); alertErr != nil {
+ return handshakeErrored, alertErr
}
return handshakeErrored, errFlight
}
@@ -246,7 +276,7 @@ func (s *handshakeFSM) wait(ctx context.Context, c flightConn) (handshakeState,
nextFlight, alert, err := parse(ctx, c, s.state, s.cache, s.cfg)
close(done)
if alert != nil {
- if alertErr := c.notify(ctx, alert.alertLevel, alert.alertDescription); alertErr != nil {
+ if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil {
if err != nil {
err = alertErr
}
@@ -266,6 +296,9 @@ func (s *handshakeFSM) wait(ctx context.Context, c flightConn) (handshakeState,
return handshakePreparing, nil
case <-retransmitTimer.C:
+ if !s.retransmit {
+ return handshakeWaiting, nil
+ }
return handshakeSending, nil
case <-ctx.Done():
return handshakeErrored, ctx.Err()
@@ -276,10 +309,8 @@ func (s *handshakeFSM) wait(ctx context.Context, c flightConn) (handshakeState,
func (s *handshakeFSM) finish(ctx context.Context, c flightConn) (handshakeState, error) {
parse, errFlight := s.currentFlight.getFlightParser()
if errFlight != nil {
- if alertErr := c.notify(ctx, alertLevelFatal, alertInternalError); alertErr != nil {
- if errFlight != nil {
- return handshakeErrored, alertErr
- }
+ if alertErr := c.notify(ctx, alert.Fatal, alert.InternalError); alertErr != nil {
+ return handshakeErrored, alertErr
}
return handshakeErrored, errFlight
}
@@ -290,7 +321,7 @@ func (s *handshakeFSM) finish(ctx context.Context, c flightConn) (handshakeState
nextFlight, alert, err := parse(ctx, c, s.state, s.cache, s.cfg)
close(done)
if alert != nil {
- if alertErr := c.notify(ctx, alert.alertLevel, alert.alertDescription); alertErr != nil {
+ if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil {
if err != nil {
err = alertErr
}
@@ -302,6 +333,9 @@ func (s *handshakeFSM) finish(ctx context.Context, c flightConn) (handshakeState
if nextFlight == 0 {
break
}
+ if nextFlight.isLastRecvFlight() && s.currentFlight == nextFlight {
+ return handshakeFinished, nil
+ }
<-retransmitTimer.C
// Retransmit last flight
return handshakeSending, nil
diff --git a/vendor/github.com/pion/dtls/v2/hash_algorithm.go b/vendor/github.com/pion/dtls/v2/hash_algorithm.go
deleted file mode 100644
index 29ac2da..0000000
--- a/vendor/github.com/pion/dtls/v2/hash_algorithm.go
+++ /dev/null
@@ -1,114 +0,0 @@
-package dtls
-
-import (
- "crypto"
- "crypto/md5" // #nosec
- "crypto/sha1" // #nosec
- "crypto/sha256"
- "crypto/sha512"
-)
-
-// hashAlgorithm is used to indicate the hash algorithm used
-// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18
-type hashAlgorithm uint16
-
-// Supported hash hash algorithms
-const (
- hashAlgorithmMD2 hashAlgorithm = 0 // Blacklisted
- hashAlgorithmMD5 hashAlgorithm = 1 // Blacklisted
- hashAlgorithmSHA1 hashAlgorithm = 2 // Blacklisted
- hashAlgorithmSHA224 hashAlgorithm = 3
- hashAlgorithmSHA256 hashAlgorithm = 4
- hashAlgorithmSHA384 hashAlgorithm = 5
- hashAlgorithmSHA512 hashAlgorithm = 6
- hashAlgorithmEd25519 hashAlgorithm = 8
-)
-
-// String makes hashAlgorithm printable
-func (h hashAlgorithm) String() string {
- switch h {
- case hashAlgorithmMD2:
- return "md2"
- case hashAlgorithmMD5:
- return "md5" // [RFC3279]
- case hashAlgorithmSHA1:
- return "sha-1" // [RFC3279]
- case hashAlgorithmSHA224:
- return "sha-224" // [RFC4055]
- case hashAlgorithmSHA256:
- return "sha-256" // [RFC4055]
- case hashAlgorithmSHA384:
- return "sha-384" // [RFC4055]
- case hashAlgorithmSHA512:
- return "sha-512" // [RFC4055]
- case hashAlgorithmEd25519:
- return "null"
- default:
- return "unknown or unsupported hash algorithm"
- }
-}
-
-func (h hashAlgorithm) digest(b []byte) []byte {
- switch h {
- case hashAlgorithmMD5:
- hash := md5.Sum(b) // #nosec
- return hash[:]
- case hashAlgorithmSHA1:
- hash := sha1.Sum(b) // #nosec
- return hash[:]
- case hashAlgorithmSHA224:
- hash := sha256.Sum224(b)
- return hash[:]
- case hashAlgorithmSHA256:
- hash := sha256.Sum256(b)
- return hash[:]
- case hashAlgorithmSHA384:
- hash := sha512.Sum384(b)
- return hash[:]
- case hashAlgorithmSHA512:
- hash := sha512.Sum512(b)
- return hash[:]
- default:
- return nil
- }
-}
-
-func (h hashAlgorithm) insecure() bool {
- switch h {
- case hashAlgorithmMD2, hashAlgorithmMD5, hashAlgorithmSHA1:
- return true
- default:
- return false
- }
-}
-
-func (h hashAlgorithm) cryptoHash() crypto.Hash {
- switch h {
- case hashAlgorithmMD5:
- return crypto.MD5
- case hashAlgorithmSHA1:
- return crypto.SHA1
- case hashAlgorithmSHA224:
- return crypto.SHA224
- case hashAlgorithmSHA256:
- return crypto.SHA256
- case hashAlgorithmSHA384:
- return crypto.SHA384
- case hashAlgorithmSHA512:
- return crypto.SHA512
- case hashAlgorithmEd25519:
- return crypto.Hash(0)
- default:
- return crypto.Hash(0)
- }
-}
-
-var hashAlgorithms = map[hashAlgorithm]struct{}{
- hashAlgorithmMD5: {},
- hashAlgorithmSHA1: {},
- hashAlgorithmSHA224: {},
- hashAlgorithmSHA256: {},
- hashAlgorithmSHA384: {},
- hashAlgorithmSHA512: {},
- hashAlgorithmEd25519: {},
-}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go
new file mode 100644
index 0000000..f78b6dc
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go
@@ -0,0 +1,33 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+)
+
+// Aes128Ccm is a base class used by multiple AES-CCM Ciphers
+type Aes128Ccm struct {
+ AesCcm
+}
+
+func newAes128Ccm(clientCertificateType clientcertificate.Type, id ID, psk bool, cryptoCCMTagLen ciphersuite.CCMTagLen, keyExchangeAlgorithm KeyExchangeAlgorithm, ecc bool) *Aes128Ccm {
+ return &Aes128Ccm{
+ AesCcm: AesCcm{
+ clientCertificateType: clientCertificateType,
+ id: id,
+ psk: psk,
+ cryptoCCMTagLen: cryptoCCMTagLen,
+ keyExchangeAlgorithm: keyExchangeAlgorithm,
+ ecc: ecc,
+ },
+ }
+}
+
+// Init initializes the internal Cipher with keying material
+func (c *Aes128Ccm) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error {
+ const prfKeyLen = 16
+ return c.AesCcm.Init(masterSecret, clientRandom, serverRandom, isClient, prfKeyLen)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_256_ccm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_256_ccm.go
new file mode 100644
index 0000000..bb81286
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_256_ccm.go
@@ -0,0 +1,33 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+)
+
+// Aes256Ccm is a base class used by multiple AES-CCM Ciphers
+type Aes256Ccm struct {
+ AesCcm
+}
+
+func newAes256Ccm(clientCertificateType clientcertificate.Type, id ID, psk bool, cryptoCCMTagLen ciphersuite.CCMTagLen, keyExchangeAlgorithm KeyExchangeAlgorithm, ecc bool) *Aes256Ccm {
+ return &Aes256Ccm{
+ AesCcm: AesCcm{
+ clientCertificateType: clientCertificateType,
+ id: id,
+ psk: psk,
+ cryptoCCMTagLen: cryptoCCMTagLen,
+ keyExchangeAlgorithm: keyExchangeAlgorithm,
+ ecc: ecc,
+ },
+ }
+}
+
+// Init initializes the internal Cipher with keying material
+func (c *Aes256Ccm) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error {
+ const prfKeyLen = 32
+ return c.AesCcm.Init(masterSecret, clientRandom, serverRandom, isClient, prfKeyLen)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_ccm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_ccm.go
new file mode 100644
index 0000000..ee3cca9
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_ccm.go
@@ -0,0 +1,113 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "crypto/sha256"
+ "fmt"
+ "hash"
+ "sync/atomic"
+
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
+// AesCcm is a base class used by multiple AES-CCM Ciphers
+type AesCcm struct {
+ ccm atomic.Value // *cryptoCCM
+ clientCertificateType clientcertificate.Type
+ id ID
+ psk bool
+ keyExchangeAlgorithm KeyExchangeAlgorithm
+ cryptoCCMTagLen ciphersuite.CCMTagLen
+ ecc bool
+}
+
+// CertificateType returns what type of certificate this CipherSuite exchanges
+func (c *AesCcm) CertificateType() clientcertificate.Type {
+ return c.clientCertificateType
+}
+
+// ID returns the ID of the CipherSuite
+func (c *AesCcm) ID() ID {
+ return c.id
+}
+
+func (c *AesCcm) String() string {
+ return c.id.String()
+}
+
+// ECC uses Elliptic Curve Cryptography
+func (c *AesCcm) ECC() bool {
+ return c.ecc
+}
+
+// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake
+func (c *AesCcm) KeyExchangeAlgorithm() KeyExchangeAlgorithm {
+ return c.keyExchangeAlgorithm
+}
+
+// HashFunc returns the hashing func for this CipherSuite
+func (c *AesCcm) HashFunc() func() hash.Hash {
+ return sha256.New
+}
+
+// AuthenticationType controls what authentication method is using during the handshake
+func (c *AesCcm) AuthenticationType() AuthenticationType {
+ if c.psk {
+ return AuthenticationTypePreSharedKey
+ }
+ return AuthenticationTypeCertificate
+}
+
+// IsInitialized returns if the CipherSuite has keying material and can
+// encrypt/decrypt packets
+func (c *AesCcm) IsInitialized() bool {
+ return c.ccm.Load() != nil
+}
+
+// Init initializes the internal Cipher with keying material
+func (c *AesCcm) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool, prfKeyLen int) error {
+ const (
+ prfMacLen = 0
+ prfIvLen = 4
+ )
+
+ keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc())
+ if err != nil {
+ return err
+ }
+
+ var ccm *ciphersuite.CCM
+ if isClient {
+ ccm, err = ciphersuite.NewCCM(c.cryptoCCMTagLen, keys.ClientWriteKey, keys.ClientWriteIV, keys.ServerWriteKey, keys.ServerWriteIV)
+ } else {
+ ccm, err = ciphersuite.NewCCM(c.cryptoCCMTagLen, keys.ServerWriteKey, keys.ServerWriteIV, keys.ClientWriteKey, keys.ClientWriteIV)
+ }
+ c.ccm.Store(ccm)
+
+ return err
+}
+
+// Encrypt encrypts a single TLS RecordLayer
+func (c *AesCcm) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) {
+ cipherSuite, ok := c.ccm.Load().(*ciphersuite.CCM)
+ if !ok {
+ return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit)
+ }
+
+ return cipherSuite.Encrypt(pkt, raw)
+}
+
+// Decrypt decrypts a single TLS RecordLayer
+func (c *AesCcm) Decrypt(h recordlayer.Header, raw []byte) ([]byte, error) {
+ cipherSuite, ok := c.ccm.Load().(*ciphersuite.CCM)
+ if !ok {
+ return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit)
+ }
+
+ return cipherSuite.Decrypt(h, raw)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/ciphersuite.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/ciphersuite.go
new file mode 100644
index 0000000..f44f29f
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/ciphersuite.go
@@ -0,0 +1,98 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package ciphersuite provides TLS Ciphers as registered with the IANA https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4
+package ciphersuite
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/pion/dtls/v2/internal/ciphersuite/types"
+ "github.com/pion/dtls/v2/pkg/protocol"
+)
+
+var errCipherSuiteNotInit = &protocol.TemporaryError{Err: errors.New("CipherSuite has not been initialized")} //nolint:goerr113
+
+// ID is an ID for our supported CipherSuites
+type ID uint16
+
+func (i ID) String() string {
+ switch i {
+ case TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
+ return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM"
+ case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
+ return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8"
+ case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+ return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
+ case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+ return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
+ case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+ return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
+ case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+ return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
+ case TLS_PSK_WITH_AES_128_CCM:
+ return "TLS_PSK_WITH_AES_128_CCM"
+ case TLS_PSK_WITH_AES_128_CCM_8:
+ return "TLS_PSK_WITH_AES_128_CCM_8"
+ case TLS_PSK_WITH_AES_256_CCM_8:
+ return "TLS_PSK_WITH_AES_256_CCM_8"
+ case TLS_PSK_WITH_AES_128_GCM_SHA256:
+ return "TLS_PSK_WITH_AES_128_GCM_SHA256"
+ case TLS_PSK_WITH_AES_128_CBC_SHA256:
+ return "TLS_PSK_WITH_AES_128_CBC_SHA256"
+ case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+ return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
+ case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
+ case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
+ return "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256"
+ default:
+ return fmt.Sprintf("unknown(%v)", uint16(i))
+ }
+}
+
+// Supported Cipher Suites
+const (
+ // AES-128-CCM
+ TLS_ECDHE_ECDSA_WITH_AES_128_CCM ID = 0xc0ac //nolint:revive,stylecheck
+ TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ID = 0xc0ae //nolint:revive,stylecheck
+
+ // AES-128-GCM-SHA256
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ID = 0xc02b //nolint:revive,stylecheck
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ID = 0xc02f //nolint:revive,stylecheck
+
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ID = 0xc02c //nolint:revive,stylecheck
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ID = 0xc030 //nolint:revive,stylecheck
+ // AES-256-CBC-SHA
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ID = 0xc00a //nolint:revive,stylecheck
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ID = 0xc014 //nolint:revive,stylecheck
+
+ TLS_PSK_WITH_AES_128_CCM ID = 0xc0a4 //nolint:revive,stylecheck
+ TLS_PSK_WITH_AES_128_CCM_8 ID = 0xc0a8 //nolint:revive,stylecheck
+ TLS_PSK_WITH_AES_256_CCM_8 ID = 0xc0a9 //nolint:revive,stylecheck
+ TLS_PSK_WITH_AES_128_GCM_SHA256 ID = 0x00a8 //nolint:revive,stylecheck
+ TLS_PSK_WITH_AES_128_CBC_SHA256 ID = 0x00ae //nolint:revive,stylecheck
+
+ TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 ID = 0xC037 //nolint:revive,stylecheck
+)
+
+// AuthenticationType controls what authentication method is using during the handshake
+type AuthenticationType = types.AuthenticationType
+
+// AuthenticationType Enums
+const (
+ AuthenticationTypeCertificate AuthenticationType = types.AuthenticationTypeCertificate
+ AuthenticationTypePreSharedKey AuthenticationType = types.AuthenticationTypePreSharedKey
+ AuthenticationTypeAnonymous AuthenticationType = types.AuthenticationTypeAnonymous
+)
+
+// KeyExchangeAlgorithm controls what exchange algorithm was chosen.
+type KeyExchangeAlgorithm = types.KeyExchangeAlgorithm
+
+// KeyExchangeAlgorithm Bitmask
+const (
+ KeyExchangeAlgorithmNone KeyExchangeAlgorithm = types.KeyExchangeAlgorithmNone
+ KeyExchangeAlgorithmPsk KeyExchangeAlgorithm = types.KeyExchangeAlgorithmPsk
+ KeyExchangeAlgorithmEcdhe KeyExchangeAlgorithm = types.KeyExchangeAlgorithmEcdhe
+)
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go
new file mode 100644
index 0000000..8367b2c
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+)
+
+// NewTLSEcdheEcdsaWithAes128Ccm constructs a TLS_ECDHE_ECDSA_WITH_AES_128_CCM Cipher
+func NewTLSEcdheEcdsaWithAes128Ccm() *Aes128Ccm {
+ return newAes128Ccm(clientcertificate.ECDSASign, TLS_ECDHE_ECDSA_WITH_AES_128_CCM, false, ciphersuite.CCMTagLength, KeyExchangeAlgorithmEcdhe, true)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go
new file mode 100644
index 0000000..11b6873
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+)
+
+// NewTLSEcdheEcdsaWithAes128Ccm8 creates a new TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 CipherSuite
+func NewTLSEcdheEcdsaWithAes128Ccm8() *Aes128Ccm {
+ return newAes128Ccm(clientcertificate.ECDSASign, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, false, ciphersuite.CCMTagLength8, KeyExchangeAlgorithmEcdhe, true)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go
new file mode 100644
index 0000000..362370b
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go
@@ -0,0 +1,108 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "crypto/sha256"
+ "fmt"
+ "hash"
+ "sync/atomic"
+
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
+// TLSEcdheEcdsaWithAes128GcmSha256 represents a TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 CipherSuite
+type TLSEcdheEcdsaWithAes128GcmSha256 struct {
+ gcm atomic.Value // *cryptoGCM
+}
+
+// CertificateType returns what type of certficate this CipherSuite exchanges
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) CertificateType() clientcertificate.Type {
+ return clientcertificate.ECDSASign
+}
+
+// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) KeyExchangeAlgorithm() KeyExchangeAlgorithm {
+ return KeyExchangeAlgorithmEcdhe
+}
+
+// ECC uses Elliptic Curve Cryptography
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) ECC() bool {
+ return true
+}
+
+// ID returns the ID of the CipherSuite
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) ID() ID {
+ return TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+}
+
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) String() string {
+ return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
+}
+
+// HashFunc returns the hashing func for this CipherSuite
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) HashFunc() func() hash.Hash {
+ return sha256.New
+}
+
+// AuthenticationType controls what authentication method is using during the handshake
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) AuthenticationType() AuthenticationType {
+ return AuthenticationTypeCertificate
+}
+
+// IsInitialized returns if the CipherSuite has keying material and can
+// encrypt/decrypt packets
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) IsInitialized() bool {
+ return c.gcm.Load() != nil
+}
+
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) init(masterSecret, clientRandom, serverRandom []byte, isClient bool, prfMacLen, prfKeyLen, prfIvLen int, hashFunc func() hash.Hash) error {
+ keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, hashFunc)
+ if err != nil {
+ return err
+ }
+
+ var gcm *ciphersuite.GCM
+ if isClient {
+ gcm, err = ciphersuite.NewGCM(keys.ClientWriteKey, keys.ClientWriteIV, keys.ServerWriteKey, keys.ServerWriteIV)
+ } else {
+ gcm, err = ciphersuite.NewGCM(keys.ServerWriteKey, keys.ServerWriteIV, keys.ClientWriteKey, keys.ClientWriteIV)
+ }
+ c.gcm.Store(gcm)
+ return err
+}
+
+// Init initializes the internal Cipher with keying material
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error {
+ const (
+ prfMacLen = 0
+ prfKeyLen = 16
+ prfIvLen = 4
+ )
+
+ return c.init(masterSecret, clientRandom, serverRandom, isClient, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc())
+}
+
+// Encrypt encrypts a single TLS RecordLayer
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) {
+ cipherSuite, ok := c.gcm.Load().(*ciphersuite.GCM)
+ if !ok {
+ return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit)
+ }
+
+ return cipherSuite.Encrypt(pkt, raw)
+}
+
+// Decrypt decrypts a single TLS RecordLayer
+func (c *TLSEcdheEcdsaWithAes128GcmSha256) Decrypt(h recordlayer.Header, raw []byte) ([]byte, error) {
+ cipherSuite, ok := c.gcm.Load().(*ciphersuite.GCM)
+ if !ok {
+ return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit)
+ }
+
+ return cipherSuite.Decrypt(h, raw)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go
new file mode 100644
index 0000000..07ad66f
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go
@@ -0,0 +1,114 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "crypto/sha1" //nolint: gosec,gci
+ "crypto/sha256"
+ "fmt"
+ "hash"
+ "sync/atomic"
+
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
+// TLSEcdheEcdsaWithAes256CbcSha represents a TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA CipherSuite
+type TLSEcdheEcdsaWithAes256CbcSha struct {
+ cbc atomic.Value // *cryptoCBC
+}
+
+// CertificateType returns what type of certficate this CipherSuite exchanges
+func (c *TLSEcdheEcdsaWithAes256CbcSha) CertificateType() clientcertificate.Type {
+ return clientcertificate.ECDSASign
+}
+
+// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake
+func (c *TLSEcdheEcdsaWithAes256CbcSha) KeyExchangeAlgorithm() KeyExchangeAlgorithm {
+ return KeyExchangeAlgorithmEcdhe
+}
+
+// ECC uses Elliptic Curve Cryptography
+func (c *TLSEcdheEcdsaWithAes256CbcSha) ECC() bool {
+ return true
+}
+
+// ID returns the ID of the CipherSuite
+func (c *TLSEcdheEcdsaWithAes256CbcSha) ID() ID {
+ return TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+}
+
+func (c *TLSEcdheEcdsaWithAes256CbcSha) String() string {
+ return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
+}
+
+// HashFunc returns the hashing func for this CipherSuite
+func (c *TLSEcdheEcdsaWithAes256CbcSha) HashFunc() func() hash.Hash {
+ return sha256.New
+}
+
+// AuthenticationType controls what authentication method is using during the handshake
+func (c *TLSEcdheEcdsaWithAes256CbcSha) AuthenticationType() AuthenticationType {
+ return AuthenticationTypeCertificate
+}
+
+// IsInitialized returns if the CipherSuite has keying material and can
+// encrypt/decrypt packets
+func (c *TLSEcdheEcdsaWithAes256CbcSha) IsInitialized() bool {
+ return c.cbc.Load() != nil
+}
+
+// Init initializes the internal Cipher with keying material
+func (c *TLSEcdheEcdsaWithAes256CbcSha) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error {
+ const (
+ prfMacLen = 20
+ prfKeyLen = 32
+ prfIvLen = 16
+ )
+
+ keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc())
+ if err != nil {
+ return err
+ }
+
+ var cbc *ciphersuite.CBC
+ if isClient {
+ cbc, err = ciphersuite.NewCBC(
+ keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey,
+ keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey,
+ sha1.New,
+ )
+ } else {
+ cbc, err = ciphersuite.NewCBC(
+ keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey,
+ keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey,
+ sha1.New,
+ )
+ }
+ c.cbc.Store(cbc)
+
+ return err
+}
+
+// Encrypt encrypts a single TLS RecordLayer
+func (c *TLSEcdheEcdsaWithAes256CbcSha) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) {
+ cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC)
+ if !ok {
+ return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit)
+ }
+
+ return cipherSuite.Encrypt(pkt, raw)
+}
+
+// Decrypt decrypts a single TLS RecordLayer
+func (c *TLSEcdheEcdsaWithAes256CbcSha) Decrypt(h recordlayer.Header, raw []byte) ([]byte, error) {
+ cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC)
+ if !ok {
+ return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit)
+ }
+
+ return cipherSuite.Decrypt(h, raw)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_gcm_sha384.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_gcm_sha384.go
new file mode 100644
index 0000000..2a3cfa4
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_gcm_sha384.go
@@ -0,0 +1,39 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "crypto/sha512"
+ "hash"
+)
+
+// TLSEcdheEcdsaWithAes256GcmSha384 represents a TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 CipherSuite
+type TLSEcdheEcdsaWithAes256GcmSha384 struct {
+ TLSEcdheEcdsaWithAes128GcmSha256
+}
+
+// ID returns the ID of the CipherSuite
+func (c *TLSEcdheEcdsaWithAes256GcmSha384) ID() ID {
+ return TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+}
+
+func (c *TLSEcdheEcdsaWithAes256GcmSha384) String() string {
+ return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
+}
+
+// HashFunc returns the hashing func for this CipherSuite
+func (c *TLSEcdheEcdsaWithAes256GcmSha384) HashFunc() func() hash.Hash {
+ return sha512.New384
+}
+
+// Init initializes the internal Cipher with keying material
+func (c *TLSEcdheEcdsaWithAes256GcmSha384) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error {
+ const (
+ prfMacLen = 0
+ prfKeyLen = 32
+ prfIvLen = 4
+ )
+
+ return c.init(masterSecret, clientRandom, serverRandom, isClient, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc())
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go
new file mode 100644
index 0000000..10cc58c
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go
@@ -0,0 +1,118 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "crypto/sha256"
+ "fmt"
+ "hash"
+ "sync/atomic"
+
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
+// TLSEcdhePskWithAes128CbcSha256 implements the TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 CipherSuite
+type TLSEcdhePskWithAes128CbcSha256 struct {
+ cbc atomic.Value // *cryptoCBC
+}
+
+// NewTLSEcdhePskWithAes128CbcSha256 creates TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 cipher.
+func NewTLSEcdhePskWithAes128CbcSha256() *TLSEcdhePskWithAes128CbcSha256 {
+ return &TLSEcdhePskWithAes128CbcSha256{}
+}
+
+// CertificateType returns what type of certificate this CipherSuite exchanges
+func (c *TLSEcdhePskWithAes128CbcSha256) CertificateType() clientcertificate.Type {
+ return clientcertificate.Type(0)
+}
+
+// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake
+func (c *TLSEcdhePskWithAes128CbcSha256) KeyExchangeAlgorithm() KeyExchangeAlgorithm {
+ return (KeyExchangeAlgorithmPsk | KeyExchangeAlgorithmEcdhe)
+}
+
+// ECC uses Elliptic Curve Cryptography
+func (c *TLSEcdhePskWithAes128CbcSha256) ECC() bool {
+ return true
+}
+
+// ID returns the ID of the CipherSuite
+func (c *TLSEcdhePskWithAes128CbcSha256) ID() ID {
+ return TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+}
+
+func (c *TLSEcdhePskWithAes128CbcSha256) String() string {
+ return "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256"
+}
+
+// HashFunc returns the hashing func for this CipherSuite
+func (c *TLSEcdhePskWithAes128CbcSha256) HashFunc() func() hash.Hash {
+ return sha256.New
+}
+
+// AuthenticationType controls what authentication method is using during the handshake
+func (c *TLSEcdhePskWithAes128CbcSha256) AuthenticationType() AuthenticationType {
+ return AuthenticationTypePreSharedKey
+}
+
+// IsInitialized returns if the CipherSuite has keying material and can
+// encrypt/decrypt packets
+func (c *TLSEcdhePskWithAes128CbcSha256) IsInitialized() bool {
+ return c.cbc.Load() != nil
+}
+
+// Init initializes the internal Cipher with keying material
+func (c *TLSEcdhePskWithAes128CbcSha256) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error {
+ const (
+ prfMacLen = 32
+ prfKeyLen = 16
+ prfIvLen = 16
+ )
+
+ keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc())
+ if err != nil {
+ return err
+ }
+
+ var cbc *ciphersuite.CBC
+ if isClient {
+ cbc, err = ciphersuite.NewCBC(
+ keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey,
+ keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey,
+ c.HashFunc(),
+ )
+ } else {
+ cbc, err = ciphersuite.NewCBC(
+ keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey,
+ keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey,
+ c.HashFunc(),
+ )
+ }
+ c.cbc.Store(cbc)
+
+ return err
+}
+
+// Encrypt encrypts a single TLS RecordLayer
+func (c *TLSEcdhePskWithAes128CbcSha256) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) {
+ cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC)
+ if !ok { // !c.isInitialized()
+ return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit)
+ }
+
+ return cipherSuite.Encrypt(pkt, raw)
+}
+
+// Decrypt decrypts a single TLS RecordLayer
+func (c *TLSEcdhePskWithAes128CbcSha256) Decrypt(h recordlayer.Header, raw []byte) ([]byte, error) {
+ cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC)
+ if !ok { // !c.isInitialized()
+ return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit)
+ }
+
+ return cipherSuite.Decrypt(h, raw)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go
new file mode 100644
index 0000000..478a2e0
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go
@@ -0,0 +1,25 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+
+// TLSEcdheRsaWithAes128GcmSha256 implements the TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 CipherSuite
+type TLSEcdheRsaWithAes128GcmSha256 struct {
+ TLSEcdheEcdsaWithAes128GcmSha256
+}
+
+// CertificateType returns what type of certificate this CipherSuite exchanges
+func (c *TLSEcdheRsaWithAes128GcmSha256) CertificateType() clientcertificate.Type {
+ return clientcertificate.RSASign
+}
+
+// ID returns the ID of the CipherSuite
+func (c *TLSEcdheRsaWithAes128GcmSha256) ID() ID {
+ return TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+}
+
+func (c *TLSEcdheRsaWithAes128GcmSha256) String() string {
+ return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go
new file mode 100644
index 0000000..8e88ee6
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go
@@ -0,0 +1,25 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+
+// TLSEcdheRsaWithAes256CbcSha implements the TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA CipherSuite
+type TLSEcdheRsaWithAes256CbcSha struct {
+ TLSEcdheEcdsaWithAes256CbcSha
+}
+
+// CertificateType returns what type of certificate this CipherSuite exchanges
+func (c *TLSEcdheRsaWithAes256CbcSha) CertificateType() clientcertificate.Type {
+ return clientcertificate.RSASign
+}
+
+// ID returns the ID of the CipherSuite
+func (c *TLSEcdheRsaWithAes256CbcSha) ID() ID {
+ return TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+}
+
+func (c *TLSEcdheRsaWithAes256CbcSha) String() string {
+ return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go
new file mode 100644
index 0000000..752fb52
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go
@@ -0,0 +1,25 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+
+// TLSEcdheRsaWithAes256GcmSha384 implements the TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 CipherSuite
+type TLSEcdheRsaWithAes256GcmSha384 struct {
+ TLSEcdheEcdsaWithAes256GcmSha384
+}
+
+// CertificateType returns what type of certificate this CipherSuite exchanges
+func (c *TLSEcdheRsaWithAes256GcmSha384) CertificateType() clientcertificate.Type {
+ return clientcertificate.RSASign
+}
+
+// ID returns the ID of the CipherSuite
+func (c *TLSEcdheRsaWithAes256GcmSha384) ID() ID {
+ return TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+}
+
+func (c *TLSEcdheRsaWithAes256GcmSha384) String() string {
+ return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go
new file mode 100644
index 0000000..dea0dfc
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go
@@ -0,0 +1,113 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "crypto/sha256"
+ "fmt"
+ "hash"
+ "sync/atomic"
+
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
+// TLSPskWithAes128CbcSha256 implements the TLS_PSK_WITH_AES_128_CBC_SHA256 CipherSuite
+type TLSPskWithAes128CbcSha256 struct {
+ cbc atomic.Value // *cryptoCBC
+}
+
+// CertificateType returns what type of certificate this CipherSuite exchanges
+func (c *TLSPskWithAes128CbcSha256) CertificateType() clientcertificate.Type {
+ return clientcertificate.Type(0)
+}
+
+// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake
+func (c *TLSPskWithAes128CbcSha256) KeyExchangeAlgorithm() KeyExchangeAlgorithm {
+ return KeyExchangeAlgorithmPsk
+}
+
+// ECC uses Elliptic Curve Cryptography
+func (c *TLSPskWithAes128CbcSha256) ECC() bool {
+ return false
+}
+
+// ID returns the ID of the CipherSuite
+func (c *TLSPskWithAes128CbcSha256) ID() ID {
+ return TLS_PSK_WITH_AES_128_CBC_SHA256
+}
+
+func (c *TLSPskWithAes128CbcSha256) String() string {
+ return "TLS_PSK_WITH_AES_128_CBC_SHA256"
+}
+
+// HashFunc returns the hashing func for this CipherSuite
+func (c *TLSPskWithAes128CbcSha256) HashFunc() func() hash.Hash {
+ return sha256.New
+}
+
+// AuthenticationType controls what authentication method is using during the handshake
+func (c *TLSPskWithAes128CbcSha256) AuthenticationType() AuthenticationType {
+ return AuthenticationTypePreSharedKey
+}
+
+// IsInitialized returns if the CipherSuite has keying material and can
+// encrypt/decrypt packets
+func (c *TLSPskWithAes128CbcSha256) IsInitialized() bool {
+ return c.cbc.Load() != nil
+}
+
+// Init initializes the internal Cipher with keying material
+func (c *TLSPskWithAes128CbcSha256) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error {
+ const (
+ prfMacLen = 32
+ prfKeyLen = 16
+ prfIvLen = 16
+ )
+
+ keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc())
+ if err != nil {
+ return err
+ }
+
+ var cbc *ciphersuite.CBC
+ if isClient {
+ cbc, err = ciphersuite.NewCBC(
+ keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey,
+ keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey,
+ c.HashFunc(),
+ )
+ } else {
+ cbc, err = ciphersuite.NewCBC(
+ keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey,
+ keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey,
+ c.HashFunc(),
+ )
+ }
+ c.cbc.Store(cbc)
+
+ return err
+}
+
+// Encrypt encrypts a single TLS RecordLayer
+func (c *TLSPskWithAes128CbcSha256) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) {
+ cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC)
+ if !ok {
+ return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit)
+ }
+
+ return cipherSuite.Encrypt(pkt, raw)
+}
+
+// Decrypt decrypts a single TLS RecordLayer
+func (c *TLSPskWithAes128CbcSha256) Decrypt(h recordlayer.Header, raw []byte) ([]byte, error) {
+ cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC)
+ if !ok {
+ return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit)
+ }
+
+ return cipherSuite.Decrypt(h, raw)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm.go
new file mode 100644
index 0000000..1ded09b
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm.go
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+)
+
+// NewTLSPskWithAes128Ccm returns the TLS_PSK_WITH_AES_128_CCM CipherSuite
+func NewTLSPskWithAes128Ccm() *Aes128Ccm {
+ return newAes128Ccm(clientcertificate.Type(0), TLS_PSK_WITH_AES_128_CCM, true, ciphersuite.CCMTagLength, KeyExchangeAlgorithmPsk, false)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go
new file mode 100644
index 0000000..4781970
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+)
+
+// NewTLSPskWithAes128Ccm8 returns the TLS_PSK_WITH_AES_128_CCM_8 CipherSuite
+func NewTLSPskWithAes128Ccm8() *Aes128Ccm {
+ return newAes128Ccm(clientcertificate.Type(0), TLS_PSK_WITH_AES_128_CCM_8, true, ciphersuite.CCMTagLength8, KeyExchangeAlgorithmPsk, false)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go
new file mode 100644
index 0000000..8ab5b89
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go
@@ -0,0 +1,35 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+
+// TLSPskWithAes128GcmSha256 implements the TLS_PSK_WITH_AES_128_GCM_SHA256 CipherSuite
+type TLSPskWithAes128GcmSha256 struct {
+ TLSEcdheEcdsaWithAes128GcmSha256
+}
+
+// CertificateType returns what type of certificate this CipherSuite exchanges
+func (c *TLSPskWithAes128GcmSha256) CertificateType() clientcertificate.Type {
+ return clientcertificate.Type(0)
+}
+
+// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake
+func (c *TLSPskWithAes128GcmSha256) KeyExchangeAlgorithm() KeyExchangeAlgorithm {
+ return KeyExchangeAlgorithmPsk
+}
+
+// ID returns the ID of the CipherSuite
+func (c *TLSPskWithAes128GcmSha256) ID() ID {
+ return TLS_PSK_WITH_AES_128_GCM_SHA256
+}
+
+func (c *TLSPskWithAes128GcmSha256) String() string {
+ return "TLS_PSK_WITH_AES_128_GCM_SHA256"
+}
+
+// AuthenticationType controls what authentication method is using during the handshake
+func (c *TLSPskWithAes128GcmSha256) AuthenticationType() AuthenticationType {
+ return AuthenticationTypePreSharedKey
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go
new file mode 100644
index 0000000..32d5030
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "github.com/pion/dtls/v2/pkg/crypto/ciphersuite"
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+)
+
+// NewTLSPskWithAes256Ccm8 returns the TLS_PSK_WITH_AES_256_CCM_8 CipherSuite
+func NewTLSPskWithAes256Ccm8() *Aes256Ccm {
+ return newAes256Ccm(clientcertificate.Type(0), TLS_PSK_WITH_AES_256_CCM_8, true, ciphersuite.CCMTagLength8, KeyExchangeAlgorithmPsk, false)
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/authentication_type.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/authentication_type.go
new file mode 100644
index 0000000..2da21e6
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/authentication_type.go
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package types
+
+// AuthenticationType controls what authentication method is using during the handshake
+type AuthenticationType int
+
+// AuthenticationType Enums
+const (
+ AuthenticationTypeCertificate AuthenticationType = iota + 1
+ AuthenticationTypePreSharedKey
+ AuthenticationTypeAnonymous
+)
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/key_exchange_algorithm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/key_exchange_algorithm.go
new file mode 100644
index 0000000..c2c3911
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/key_exchange_algorithm.go
@@ -0,0 +1,20 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package types provides types for TLS Ciphers
+package types
+
+// KeyExchangeAlgorithm controls what exchange algorithm was chosen.
+type KeyExchangeAlgorithm int
+
+// KeyExchangeAlgorithm Bitmask
+const (
+ KeyExchangeAlgorithmNone KeyExchangeAlgorithm = 0
+ KeyExchangeAlgorithmPsk KeyExchangeAlgorithm = iota << 1
+ KeyExchangeAlgorithmEcdhe
+)
+
+// Has check if keyExchangeAlgorithm is supported.
+func (a KeyExchangeAlgorithm) Has(v KeyExchangeAlgorithm) bool {
+ return (a & v) == v
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/closer/closer.go b/vendor/github.com/pion/dtls/v2/internal/closer/closer.go
index b99e13e..bfa171c 100644
--- a/vendor/github.com/pion/dtls/v2/internal/closer/closer.go
+++ b/vendor/github.com/pion/dtls/v2/internal/closer/closer.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
// Package closer provides signaling channel for shutdown
package closer
diff --git a/vendor/github.com/pion/dtls/v2/internal/net/buffer.go b/vendor/github.com/pion/dtls/v2/internal/net/buffer.go
new file mode 100644
index 0000000..9ab290e
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/net/buffer.go
@@ -0,0 +1,235 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package net implements DTLS specific networking primitives.
+// NOTE: this package is an adaption of pion/transport/packetio that allows for
+// storing a remote address alongside each packet in the buffer and implements
+// relevant methods of net.PacketConn. If possible, the updates made in this
+// repository will be reflected back upstream. If not, it is likely that this
+// will be moved to a public package in this repository.
+//
+// This package was migrated from pion/transport/packetio at
+// https://github.com/pion/transport/commit/6890c795c807a617c054149eee40a69d7fdfbfdb
+package net
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "net"
+ "sync"
+ "time"
+
+ "github.com/pion/transport/v3/deadline"
+)
+
+// ErrTimeout indicates that deadline was reached before operation could be
+// completed.
+var ErrTimeout = errors.New("buffer: i/o timeout")
+
+// AddrPacket is a packet payload and the associated remote address from which
+// it was received.
+type AddrPacket struct {
+ addr net.Addr
+ data bytes.Buffer
+}
+
+// PacketBuffer is a circular buffer for network packets. Each slot in the
+// buffer contains the remote address from which the packet was received, as
+// well as the packet data.
+type PacketBuffer struct {
+ mutex sync.Mutex
+
+ packets []AddrPacket
+ write, read int
+
+ // full indicates whether the buffer is full, which is needed to distinguish
+ // when the write pointer and read pointer are at the same index.
+ full bool
+
+ notify chan struct{}
+ closed bool
+
+ readDeadline *deadline.Deadline
+}
+
+// NewPacketBuffer creates a new PacketBuffer.
+func NewPacketBuffer() *PacketBuffer {
+ return &PacketBuffer{
+ readDeadline: deadline.New(),
+ // In the narrow context in which this package is currently used, there
+ // will always be at least one packet written to the buffer. Therefore,
+ // we opt to allocate with size of 1 during construction, rather than
+ // waiting until that first packet is written.
+ packets: make([]AddrPacket, 1),
+ full: false,
+ }
+}
+
+// WriteTo writes a single packet to the buffer. The supplied address will
+// remain associated with the packet.
+func (b *PacketBuffer) WriteTo(p []byte, addr net.Addr) (int, error) {
+ b.mutex.Lock()
+
+ if b.closed {
+ b.mutex.Unlock()
+ return 0, io.ErrClosedPipe
+ }
+
+ var notify chan struct{}
+ if b.notify != nil {
+ notify = b.notify
+ b.notify = nil
+ }
+
+ // Check to see if we are full.
+ if b.full {
+ // If so, grow AddrPacket buffer.
+ var newSize int
+ if len(b.packets) < 128 {
+ // Double the number of packets.
+ newSize = len(b.packets) * 2
+ } else {
+ // Increase the number of packets by 25%.
+ newSize = 5 * len(b.packets) / 4
+ }
+ newBuf := make([]AddrPacket, newSize)
+ var n int
+ if b.read < b.write {
+ n = copy(newBuf, b.packets[b.read:b.write])
+ } else {
+ n = copy(newBuf, b.packets[b.read:])
+ n += copy(newBuf[n:], b.packets[:b.write])
+ }
+
+ b.packets = newBuf
+
+ // Update write pointer to point to new location and mark buffer as not
+ // full.
+ b.write = n
+ b.full = false
+ }
+
+ // Store the packet at the write pointer.
+ packet := &b.packets[b.write]
+ packet.data.Reset()
+ n, err := packet.data.Write(p)
+ if err != nil {
+ b.mutex.Unlock()
+ return n, err
+ }
+ packet.addr = addr
+
+ // Increment write pointer.
+ b.write++
+
+ // If the write pointer is equal to the length of the buffer, wrap around.
+ if len(b.packets) == b.write {
+ b.write = 0
+ }
+
+ // If a write resulted in making write and read pointers equivalent, then we
+ // are full.
+ if b.write == b.read {
+ b.full = true
+ }
+
+ b.mutex.Unlock()
+
+ if notify != nil {
+ close(notify)
+ }
+
+ return n, nil
+}
+
+// ReadFrom reads a single packet from the buffer, or blocks until one is
+// available.
+func (b *PacketBuffer) ReadFrom(packet []byte) (n int, addr net.Addr, err error) {
+ select {
+ case <-b.readDeadline.Done():
+ return 0, nil, ErrTimeout
+ default:
+ }
+
+ for {
+ b.mutex.Lock()
+
+ if b.read != b.write || b.full {
+ ap := b.packets[b.read]
+ if len(packet) < ap.data.Len() {
+ b.mutex.Unlock()
+ return 0, nil, io.ErrShortBuffer
+ }
+
+ // Copy packet data from buffer.
+ n, err := ap.data.Read(packet)
+ if err != nil {
+ b.mutex.Unlock()
+ return n, nil, err
+ }
+
+ // Advance read pointer.
+ b.read++
+ if len(b.packets) == b.read {
+ b.read = 0
+ }
+
+ // If we were full before reading and have successfully read, we are
+ // no longer full.
+ if b.full {
+ b.full = false
+ }
+
+ b.mutex.Unlock()
+
+ return n, ap.addr, nil
+ }
+
+ if b.closed {
+ b.mutex.Unlock()
+ return 0, nil, io.EOF
+ }
+
+ if b.notify == nil {
+ b.notify = make(chan struct{})
+ }
+ notify := b.notify
+ b.mutex.Unlock()
+
+ select {
+ case <-b.readDeadline.Done():
+ return 0, nil, ErrTimeout
+ case <-notify:
+ }
+ }
+}
+
+// Close closes the buffer, allowing unread packets to be read, but erroring on
+// any new writes.
+func (b *PacketBuffer) Close() (err error) {
+ b.mutex.Lock()
+
+ if b.closed {
+ b.mutex.Unlock()
+ return nil
+ }
+
+ notify := b.notify
+ b.notify = nil
+ b.closed = true
+
+ b.mutex.Unlock()
+
+ if notify != nil {
+ close(notify)
+ }
+
+ return nil
+}
+
+// SetReadDeadline sets the read deadline for the buffer.
+func (b *PacketBuffer) SetReadDeadline(t time.Time) error {
+ b.readDeadline.Set(t)
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/net/udp/packet_conn.go b/vendor/github.com/pion/dtls/v2/internal/net/udp/packet_conn.go
new file mode 100644
index 0000000..7dafbe2
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/net/udp/packet_conn.go
@@ -0,0 +1,407 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package udp implements DTLS specific UDP networking primitives.
+// NOTE: this package is an adaption of pion/transport/udp that allows for
+// routing datagrams based on identifiers other than the remote address. The
+// primary use case for this functionality is routing based on DTLS connection
+// IDs. In order to allow for consumers of this package to treat connections as
+// generic net.PackageConn, routing and identitier establishment is based on
+// custom introspecion of datagrams, rather than direct intervention by
+// consumers. If possible, the updates made in this repository will be reflected
+// back upstream. If not, it is likely that this will be moved to a public
+// package in this repository.
+//
+// This package was migrated from pion/transport/udp at
+// https://github.com/pion/transport/commit/6890c795c807a617c054149eee40a69d7fdfbfdb
+package udp
+
+import (
+ "context"
+ "errors"
+ "net"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ idtlsnet "github.com/pion/dtls/v2/internal/net"
+ dtlsnet "github.com/pion/dtls/v2/pkg/net"
+ "github.com/pion/transport/v3/deadline"
+)
+
+const (
+ receiveMTU = 8192
+ defaultListenBacklog = 128 // same as Linux default
+)
+
+// Typed errors
+var (
+ ErrClosedListener = errors.New("udp: listener closed")
+ ErrListenQueueExceeded = errors.New("udp: listen queue exceeded")
+)
+
+// listener augments a connection-oriented Listener over a UDP PacketConn
+type listener struct {
+ pConn *net.UDPConn
+
+ accepting atomic.Value // bool
+ acceptCh chan *PacketConn
+ doneCh chan struct{}
+ doneOnce sync.Once
+ acceptFilter func([]byte) bool
+ datagramRouter func([]byte) (string, bool)
+ connIdentifier func([]byte) (string, bool)
+
+ connLock sync.Mutex
+ conns map[string]*PacketConn
+ connWG sync.WaitGroup
+
+ readWG sync.WaitGroup
+ errClose atomic.Value // error
+
+ readDoneCh chan struct{}
+ errRead atomic.Value // error
+}
+
+// Accept waits for and returns the next connection to the listener.
+func (l *listener) Accept() (net.PacketConn, net.Addr, error) {
+ select {
+ case c := <-l.acceptCh:
+ l.connWG.Add(1)
+ return c, c.raddr, nil
+
+ case <-l.readDoneCh:
+ err, _ := l.errRead.Load().(error)
+ return nil, nil, err
+
+ case <-l.doneCh:
+ return nil, nil, ErrClosedListener
+ }
+}
+
+// Close closes the listener.
+// Any blocked Accept operations will be unblocked and return errors.
+func (l *listener) Close() error {
+ var err error
+ l.doneOnce.Do(func() {
+ l.accepting.Store(false)
+ close(l.doneCh)
+
+ l.connLock.Lock()
+ // Close unaccepted connections
+ lclose:
+ for {
+ select {
+ case c := <-l.acceptCh:
+ close(c.doneCh)
+ // If we have an alternate identifier, remove it from the connection
+ // map.
+ if id := c.id.Load(); id != nil {
+ delete(l.conns, id.(string)) //nolint:forcetypeassert
+ }
+ // If we haven't already removed the remote address, remove it
+ // from the connection map.
+ if c.rmraddr.Load() == nil {
+ delete(l.conns, c.raddr.String())
+ c.rmraddr.Store(true)
+ }
+ default:
+ break lclose
+ }
+ }
+ nConns := len(l.conns)
+ l.connLock.Unlock()
+
+ l.connWG.Done()
+
+ if nConns == 0 {
+ // Wait if this is the final connection.
+ l.readWG.Wait()
+ if errClose, ok := l.errClose.Load().(error); ok {
+ err = errClose
+ }
+ } else {
+ err = nil
+ }
+ })
+
+ return err
+}
+
+// Addr returns the listener's network address.
+func (l *listener) Addr() net.Addr {
+ return l.pConn.LocalAddr()
+}
+
+// ListenConfig stores options for listening to an address.
+type ListenConfig struct {
+ // Backlog defines the maximum length of the queue of pending
+ // connections. It is equivalent of the backlog argument of
+ // POSIX listen function.
+ // If a connection request arrives when the queue is full,
+ // the request will be silently discarded, unlike TCP.
+ // Set zero to use default value 128 which is same as Linux default.
+ Backlog int
+
+ // AcceptFilter determines whether the new conn should be made for
+ // the incoming packet. If not set, any packet creates new conn.
+ AcceptFilter func([]byte) bool
+
+ // DatagramRouter routes an incoming datagram to a connection by extracting
+ // an identifier from the its paylod
+ DatagramRouter func([]byte) (string, bool)
+
+ // ConnectionIdentifier extracts an identifier from an outgoing packet. If
+ // the identifier is not already associated with the connection, it will be
+ // added.
+ ConnectionIdentifier func([]byte) (string, bool)
+}
+
+// Listen creates a new listener based on the ListenConfig.
+func (lc *ListenConfig) Listen(network string, laddr *net.UDPAddr) (dtlsnet.PacketListener, error) {
+ if lc.Backlog == 0 {
+ lc.Backlog = defaultListenBacklog
+ }
+
+ conn, err := net.ListenUDP(network, laddr)
+ if err != nil {
+ return nil, err
+ }
+
+ l := &listener{
+ pConn: conn,
+ acceptCh: make(chan *PacketConn, lc.Backlog),
+ conns: make(map[string]*PacketConn),
+ doneCh: make(chan struct{}),
+ acceptFilter: lc.AcceptFilter,
+ datagramRouter: lc.DatagramRouter,
+ connIdentifier: lc.ConnectionIdentifier,
+ readDoneCh: make(chan struct{}),
+ }
+
+ l.accepting.Store(true)
+ l.connWG.Add(1)
+ l.readWG.Add(2) // wait readLoop and Close execution routine
+
+ go l.readLoop()
+ go func() {
+ l.connWG.Wait()
+ if err := l.pConn.Close(); err != nil {
+ l.errClose.Store(err)
+ }
+ l.readWG.Done()
+ }()
+
+ return l, nil
+}
+
+// Listen creates a new listener using default ListenConfig.
+func Listen(network string, laddr *net.UDPAddr) (dtlsnet.PacketListener, error) {
+ return (&ListenConfig{}).Listen(network, laddr)
+}
+
+// readLoop dispatches packets to the proper connection, creating a new one if
+// necessary, until all connections are closed.
+func (l *listener) readLoop() {
+ defer l.readWG.Done()
+ defer close(l.readDoneCh)
+
+ buf := make([]byte, receiveMTU)
+
+ for {
+ n, raddr, err := l.pConn.ReadFrom(buf)
+ if err != nil {
+ l.errRead.Store(err)
+ return
+ }
+ conn, ok, err := l.getConn(raddr, buf[:n])
+ if err != nil {
+ continue
+ }
+ if ok {
+ _, _ = conn.buffer.WriteTo(buf[:n], raddr)
+ }
+ }
+}
+
+// getConn gets an existing connection or creates a new one.
+func (l *listener) getConn(raddr net.Addr, buf []byte) (*PacketConn, bool, error) {
+ l.connLock.Lock()
+ defer l.connLock.Unlock()
+ // If we have a custom resolver, use it.
+ if l.datagramRouter != nil {
+ if id, ok := l.datagramRouter(buf); ok {
+ if conn, ok := l.conns[id]; ok {
+ return conn, true, nil
+ }
+ }
+ }
+
+ // If we don't have a custom resolver, or we were unable to find an
+ // associated connection, fall back to remote address.
+ conn, ok := l.conns[raddr.String()]
+ if !ok {
+ if isAccepting, ok := l.accepting.Load().(bool); !isAccepting || !ok {
+ return nil, false, ErrClosedListener
+ }
+ if l.acceptFilter != nil {
+ if !l.acceptFilter(buf) {
+ return nil, false, nil
+ }
+ }
+ conn = l.newPacketConn(raddr)
+ select {
+ case l.acceptCh <- conn:
+ l.conns[raddr.String()] = conn
+ default:
+ return nil, false, ErrListenQueueExceeded
+ }
+ }
+ return conn, true, nil
+}
+
+// PacketConn is a net.PacketConn implementation that is able to dictate its
+// routing ID via an alternate identifier from its remote address. Internal
+// buffering is performed for reads, and writes are passed through to the
+// underlying net.PacketConn.
+type PacketConn struct {
+ listener *listener
+
+ raddr net.Addr
+ rmraddr atomic.Value // bool
+ id atomic.Value // string
+
+ buffer *idtlsnet.PacketBuffer
+
+ doneCh chan struct{}
+ doneOnce sync.Once
+
+ writeDeadline *deadline.Deadline
+}
+
+// newPacketConn constructs a new PacketConn.
+func (l *listener) newPacketConn(raddr net.Addr) *PacketConn {
+ return &PacketConn{
+ listener: l,
+ raddr: raddr,
+ buffer: idtlsnet.NewPacketBuffer(),
+ doneCh: make(chan struct{}),
+ writeDeadline: deadline.New(),
+ }
+}
+
+// ReadFrom reads a single packet payload and its associated remote address from
+// the underlying buffer.
+func (c *PacketConn) ReadFrom(p []byte) (int, net.Addr, error) {
+ return c.buffer.ReadFrom(p)
+}
+
+// WriteTo writes len(p) bytes from p to the specified address.
+func (c *PacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
+ // If we have a connection identifier, check to see if the outgoing packet
+ // sets it.
+ if c.listener.connIdentifier != nil {
+ id := c.id.Load()
+ // Only update establish identifier if we haven't already done so.
+ if id == nil {
+ candidate, ok := c.listener.connIdentifier(p)
+ // If we have an identifier, add entry to connection map.
+ if ok {
+ c.listener.connLock.Lock()
+ c.listener.conns[candidate] = c
+ c.listener.connLock.Unlock()
+ c.id.Store(candidate)
+ }
+ }
+ // If we are writing to a remote address that differs from the initial,
+ // we have an alternate identifier established, and we haven't already
+ // freed the remote address, free the remote address to be used by
+ // another connection.
+ // Note: this strategy results in holding onto a remote address after it
+ // is potentially no longer in use by the client. However, releasing
+ // earlier means that we could miss some packets that should have been
+ // routed to this connection. Ideally, we would drop the connection
+ // entry for the remote address as soon as the client starts sending
+ // using an alternate identifier, but in practice this proves
+ // challenging because any client could spoof a connection identifier,
+ // resulting in the remote address entry being dropped prior to the
+ // "real" client transitioning to sending using the alternate
+ // identifier.
+ if id != nil && c.rmraddr.Load() == nil && addr.String() != c.raddr.String() {
+ c.listener.connLock.Lock()
+ delete(c.listener.conns, c.raddr.String())
+ c.rmraddr.Store(true)
+ c.listener.connLock.Unlock()
+ }
+ }
+
+ select {
+ case <-c.writeDeadline.Done():
+ return 0, context.DeadlineExceeded
+ default:
+ }
+ return c.listener.pConn.WriteTo(p, addr)
+}
+
+// Close closes the conn and releases any Read calls
+func (c *PacketConn) Close() error {
+ var err error
+ c.doneOnce.Do(func() {
+ c.listener.connWG.Done()
+ close(c.doneCh)
+ c.listener.connLock.Lock()
+ // If we have an alternate identifier, remove it from the connection
+ // map.
+ if id := c.id.Load(); id != nil {
+ delete(c.listener.conns, id.(string)) //nolint:forcetypeassert
+ }
+ // If we haven't already removed the remote address, remove it from the
+ // connection map.
+ if c.rmraddr.Load() == nil {
+ delete(c.listener.conns, c.raddr.String())
+ c.rmraddr.Store(true)
+ }
+ nConns := len(c.listener.conns)
+ c.listener.connLock.Unlock()
+
+ if isAccepting, ok := c.listener.accepting.Load().(bool); nConns == 0 && !isAccepting && ok {
+ // Wait if this is the final connection
+ c.listener.readWG.Wait()
+ if errClose, ok := c.listener.errClose.Load().(error); ok {
+ err = errClose
+ }
+ } else {
+ err = nil
+ }
+
+ if errBuf := c.buffer.Close(); errBuf != nil && err == nil {
+ err = errBuf
+ }
+ })
+
+ return err
+}
+
+// LocalAddr implements net.PacketConn.LocalAddr.
+func (c *PacketConn) LocalAddr() net.Addr {
+ return c.listener.pConn.LocalAddr()
+}
+
+// SetDeadline implements net.PacketConn.SetDeadline.
+func (c *PacketConn) SetDeadline(t time.Time) error {
+ c.writeDeadline.Set(t)
+ return c.SetReadDeadline(t)
+}
+
+// SetReadDeadline implements net.PacketConn.SetReadDeadline.
+func (c *PacketConn) SetReadDeadline(t time.Time) error {
+ return c.buffer.SetReadDeadline(t)
+}
+
+// SetWriteDeadline implements net.PacketConn.SetWriteDeadline.
+func (c *PacketConn) SetWriteDeadline(t time.Time) error {
+ c.writeDeadline.Set(t)
+ // Write deadline of underlying connection should not be changed
+ // since the connection can be shared.
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/util/util.go b/vendor/github.com/pion/dtls/v2/internal/util/util.go
new file mode 100644
index 0000000..382a0e1
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/internal/util/util.go
@@ -0,0 +1,51 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package util contains small helpers used across the repo
+package util
+
+import (
+ "encoding/binary"
+
+ "golang.org/x/crypto/cryptobyte"
+)
+
+// BigEndianUint24 returns the value of a big endian uint24
+func BigEndianUint24(raw []byte) uint32 {
+ if len(raw) < 3 {
+ return 0
+ }
+
+ rawCopy := make([]byte, 4)
+ copy(rawCopy[1:], raw)
+ return binary.BigEndian.Uint32(rawCopy)
+}
+
+// PutBigEndianUint24 encodes a uint24 and places into out
+func PutBigEndianUint24(out []byte, in uint32) {
+ tmp := make([]byte, 4)
+ binary.BigEndian.PutUint32(tmp, in)
+ copy(out, tmp[1:])
+}
+
+// PutBigEndianUint48 encodes a uint64 and places into out
+func PutBigEndianUint48(out []byte, in uint64) {
+ tmp := make([]byte, 8)
+ binary.BigEndian.PutUint64(tmp, in)
+ copy(out, tmp[2:])
+}
+
+// Max returns the larger value
+func Max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+
+// AddUint48 appends a big-endian, 48-bit value to the byte string.
+// Remove if / when https://github.com/golang/crypto/pull/265 is merged
+// upstream.
+func AddUint48(b *cryptobyte.Builder, v uint64) {
+ b.AddBytes([]byte{byte(v >> 40), byte(v >> 32), byte(v >> 24), byte(v >> 16), byte(v >> 8), byte(v)})
+}
diff --git a/vendor/github.com/pion/dtls/v2/listener.go b/vendor/github.com/pion/dtls/v2/listener.go
index 1fe3632..90dbbb4 100644
--- a/vendor/github.com/pion/dtls/v2/listener.go
+++ b/vendor/github.com/pion/dtls/v2/listener.go
@@ -1,9 +1,15 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
"net"
"github.com/pion/dtls/v2/internal/net/udp"
+ dtlsnet "github.com/pion/dtls/v2/pkg/net"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
)
// Listen creates a DTLS listener
@@ -12,7 +18,26 @@ func Listen(network string, laddr *net.UDPAddr, config *Config) (net.Listener, e
return nil, err
}
- parent, err := udp.Listen(network, laddr)
+ lc := udp.ListenConfig{
+ AcceptFilter: func(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
+ },
+ }
+ // If connection ID support is enabled, then they must be supported in
+ // routing.
+ if config.ConnectionIDGenerator != nil {
+ lc.DatagramRouter = cidDatagramRouter(len(config.ConnectionIDGenerator()))
+ lc.ConnectionIdentifier = cidConnIdentifier()
+ }
+ parent, err := lc.Listen(network, laddr)
if err != nil {
return nil, err
}
@@ -23,7 +48,7 @@ func Listen(network string, laddr *net.UDPAddr, config *Config) (net.Listener, e
}
// NewListener creates a DTLS listener which accepts connections from an inner Listener.
-func NewListener(inner net.Listener, config *Config) (net.Listener, error) {
+func NewListener(inner dtlsnet.PacketListener, config *Config) (net.Listener, error) {
if err := validateConfig(config); err != nil {
return nil, err
}
@@ -37,7 +62,7 @@ func NewListener(inner net.Listener, config *Config) (net.Listener, error) {
// listener represents a DTLS listener
type listener struct {
config *Config
- parent net.Listener
+ parent dtlsnet.PacketListener
}
// Accept waits for and returns the next connection to the listener.
@@ -45,11 +70,11 @@ type listener struct {
// Connection handshake will timeout using ConnectContextMaker in the Config.
// If you want to specify the timeout duration, set ConnectContextMaker.
func (l *listener) Accept() (net.Conn, error) {
- c, err := l.parent.Accept()
+ c, raddr, err := l.parent.Accept()
if err != nil {
return nil, err
}
- return Server(c, l.config)
+ return Server(c, raddr, l.config)
}
// Close closes the listener.
diff --git a/vendor/github.com/pion/dtls/v2/named_curve.go b/vendor/github.com/pion/dtls/v2/named_curve.go
deleted file mode 100644
index e14257f..0000000
--- a/vendor/github.com/pion/dtls/v2/named_curve.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package dtls
-
-import (
- "crypto/elliptic"
- "crypto/rand"
-
- "golang.org/x/crypto/curve25519"
-)
-
-// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
-type namedCurve uint16
-
-type namedCurveKeypair struct {
- curve namedCurve
- publicKey []byte
- privateKey []byte
-}
-
-const (
- namedCurveP256 namedCurve = 0x0017
- namedCurveP384 namedCurve = 0x0018
- namedCurveX25519 namedCurve = 0x001d
-)
-
-var namedCurves = map[namedCurve]bool{
- namedCurveX25519: true,
- namedCurveP256: true,
- namedCurveP384: true,
-}
-
-func generateKeypair(c namedCurve) (*namedCurveKeypair, error) {
- switch c {
- case namedCurveX25519:
- tmp := make([]byte, 32)
- if _, err := rand.Read(tmp); err != nil {
- return nil, err
- }
-
- var public, private [32]byte
- copy(private[:], tmp)
-
- curve25519.ScalarBaseMult(&public, &private)
- return &namedCurveKeypair{namedCurveX25519, public[:], private[:]}, nil
- case namedCurveP256:
- return ellipticCurveKeypair(namedCurveP256, elliptic.P256(), elliptic.P256())
- case namedCurveP384:
- return ellipticCurveKeypair(namedCurveP384, elliptic.P384(), elliptic.P384())
- }
- return nil, errInvalidNamedCurve
-}
-
-func ellipticCurveKeypair(nc namedCurve, c1, c2 elliptic.Curve) (*namedCurveKeypair, error) {
- privateKey, x, y, err := elliptic.GenerateKey(c1, rand.Reader)
- if err != nil {
- return nil, err
- }
-
- return &namedCurveKeypair{nc, elliptic.Marshal(c2, x, y), privateKey}, nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/packet.go b/vendor/github.com/pion/dtls/v2/packet.go
index 685f2e0..052c33a 100644
--- a/vendor/github.com/pion/dtls/v2/packet.go
+++ b/vendor/github.com/pion/dtls/v2/packet.go
@@ -1,7 +1,15 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
+import (
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
type packet struct {
- record *recordLayer
+ record *recordlayer.RecordLayer
shouldEncrypt bool
+ shouldWrapCID bool
resetLocalSequenceNumber bool
}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ccm/ccm.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/ccm/ccm.go
index 252e632..d6e6fc4 100644
--- a/vendor/github.com/pion/dtls/v2/pkg/crypto/ccm/ccm.go
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/ccm/ccm.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
// Package ccm implements a CCM, Counter with CBC-MAC
// as per RFC 3610.
//
@@ -70,9 +73,9 @@ func (c *ccm) NonceSize() int { return 15 - int(c.L) }
func (c *ccm) Overhead() int { return int(c.M) }
func (c *ccm) MaxLength() int { return maxlen(c.L, c.Overhead()) }
-func maxlen(L uint8, tagsize int) int {
- max := (uint64(1) << (8 * L)) - 1
- if m64 := uint64(math.MaxInt64) - uint64(tagsize); L > 8 || max > m64 {
+func maxlen(l uint8, tagsize int) int {
+ max := (uint64(1) << (8 * l)) - 1
+ if m64 := uint64(math.MaxInt64) - uint64(tagsize); l > 8 || max > m64 {
max = m64 // The maximum lentgh on a 64bit arch
}
if max != uint64(int(max)) {
@@ -113,9 +116,7 @@ func (c *ccm) cbcData(mac, data []byte) {
}
}
-var (
- errPlaintextTooLong = errors.New("ccm: plaintext too large")
-)
+var errPlaintextTooLong = errors.New("ccm: plaintext too large")
func (c *ccm) tag(nonce, plaintext, adata []byte) ([]byte, error) {
var mac [ccmBlockSize]byte
@@ -223,7 +224,7 @@ func (c *ccm) Open(dst, nonce, ciphertext, adata []byte) ([]byte, error) {
return nil, errCiphertextTooLong
}
- var tag = make([]byte, int(c.M))
+ tag := make([]byte, int(c.M))
copy(tag, ciphertext[len(ciphertext)-int(c.M):])
ciphertextWithoutTag := ciphertext[:len(ciphertext)-int(c.M)]
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/cbc.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/cbc.go
new file mode 100644
index 0000000..008a836
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/cbc.go
@@ -0,0 +1,227 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import ( //nolint:gci
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/hmac"
+ "crypto/rand"
+ "encoding/binary"
+ "hash"
+
+ "github.com/pion/dtls/v2/internal/util"
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+ "golang.org/x/crypto/cryptobyte"
+)
+
+// block ciphers using cipher block chaining.
+type cbcMode interface {
+ cipher.BlockMode
+ SetIV([]byte)
+}
+
+// CBC Provides an API to Encrypt/Decrypt DTLS 1.2 Packets
+type CBC struct {
+ writeCBC, readCBC cbcMode
+ writeMac, readMac []byte
+ h prf.HashFunc
+}
+
+// NewCBC creates a DTLS CBC Cipher
+func NewCBC(localKey, localWriteIV, localMac, remoteKey, remoteWriteIV, remoteMac []byte, h prf.HashFunc) (*CBC, error) {
+ writeBlock, err := aes.NewCipher(localKey)
+ if err != nil {
+ return nil, err
+ }
+
+ readBlock, err := aes.NewCipher(remoteKey)
+ if err != nil {
+ return nil, err
+ }
+
+ writeCBC, ok := cipher.NewCBCEncrypter(writeBlock, localWriteIV).(cbcMode)
+ if !ok {
+ return nil, errFailedToCast
+ }
+
+ readCBC, ok := cipher.NewCBCDecrypter(readBlock, remoteWriteIV).(cbcMode)
+ if !ok {
+ return nil, errFailedToCast
+ }
+
+ return &CBC{
+ writeCBC: writeCBC,
+ writeMac: localMac,
+
+ readCBC: readCBC,
+ readMac: remoteMac,
+ h: h,
+ }, nil
+}
+
+// Encrypt encrypt a DTLS RecordLayer message
+func (c *CBC) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) {
+ payload := raw[pkt.Header.Size():]
+ raw = raw[:pkt.Header.Size()]
+ blockSize := c.writeCBC.BlockSize()
+
+ // Generate + Append MAC
+ h := pkt.Header
+
+ var err error
+ var mac []byte
+ if h.ContentType == protocol.ContentTypeConnectionID {
+ mac, err = c.hmacCID(h.Epoch, h.SequenceNumber, h.Version, payload, c.writeMac, c.h, h.ConnectionID)
+ } else {
+ mac, err = c.hmac(h.Epoch, h.SequenceNumber, h.ContentType, h.Version, payload, c.writeMac, c.h)
+ }
+ if err != nil {
+ return nil, err
+ }
+ payload = append(payload, mac...)
+
+ // Generate + Append padding
+ padding := make([]byte, blockSize-len(payload)%blockSize)
+ paddingLen := len(padding)
+ for i := 0; i < paddingLen; i++ {
+ padding[i] = byte(paddingLen - 1)
+ }
+ payload = append(payload, padding...)
+
+ // Generate IV
+ iv := make([]byte, blockSize)
+ if _, err := rand.Read(iv); err != nil {
+ return nil, err
+ }
+
+ // Set IV + Encrypt + Prepend IV
+ c.writeCBC.SetIV(iv)
+ c.writeCBC.CryptBlocks(payload, payload)
+ payload = append(iv, payload...)
+
+ // Prepend unencrypted header with encrypted payload
+ raw = append(raw, payload...)
+
+ // Update recordLayer size to include IV+MAC+Padding
+ binary.BigEndian.PutUint16(raw[pkt.Header.Size()-2:], uint16(len(raw)-pkt.Header.Size()))
+
+ return raw, nil
+}
+
+// Decrypt decrypts a DTLS RecordLayer message
+func (c *CBC) Decrypt(h recordlayer.Header, in []byte) ([]byte, error) {
+ blockSize := c.readCBC.BlockSize()
+ mac := c.h()
+
+ if err := h.Unmarshal(in); err != nil {
+ return nil, err
+ }
+ body := in[h.Size():]
+
+ switch {
+ case h.ContentType == protocol.ContentTypeChangeCipherSpec:
+ // Nothing to encrypt with ChangeCipherSpec
+ return in, nil
+ case len(body)%blockSize != 0 || len(body) < blockSize+util.Max(mac.Size()+1, blockSize):
+ return nil, errNotEnoughRoomForNonce
+ }
+
+ // Set + remove per record IV
+ c.readCBC.SetIV(body[:blockSize])
+ body = body[blockSize:]
+
+ // Decrypt
+ c.readCBC.CryptBlocks(body, body)
+
+ // Padding+MAC needs to be checked in constant time
+ // Otherwise we reveal information about the level of correctness
+ paddingLen, paddingGood := examinePadding(body)
+ if paddingGood != 255 {
+ return nil, errInvalidMAC
+ }
+
+ macSize := mac.Size()
+ if len(body) < macSize {
+ return nil, errInvalidMAC
+ }
+
+ dataEnd := len(body) - macSize - paddingLen
+
+ expectedMAC := body[dataEnd : dataEnd+macSize]
+ var err error
+ var actualMAC []byte
+ if h.ContentType == protocol.ContentTypeConnectionID {
+ actualMAC, err = c.hmacCID(h.Epoch, h.SequenceNumber, h.Version, body[:dataEnd], c.readMac, c.h, h.ConnectionID)
+ } else {
+ actualMAC, err = c.hmac(h.Epoch, h.SequenceNumber, h.ContentType, h.Version, body[:dataEnd], c.readMac, c.h)
+ }
+ // Compute Local MAC and compare
+ if err != nil || !hmac.Equal(actualMAC, expectedMAC) {
+ return nil, errInvalidMAC
+ }
+
+ return append(in[:h.Size()], body[:dataEnd]...), nil
+}
+
+func (c *CBC) hmac(epoch uint16, sequenceNumber uint64, contentType protocol.ContentType, protocolVersion protocol.Version, payload []byte, key []byte, hf func() hash.Hash) ([]byte, error) {
+ h := hmac.New(hf, key)
+
+ msg := make([]byte, 13)
+
+ binary.BigEndian.PutUint16(msg, epoch)
+ util.PutBigEndianUint48(msg[2:], sequenceNumber)
+ msg[8] = byte(contentType)
+ msg[9] = protocolVersion.Major
+ msg[10] = protocolVersion.Minor
+ binary.BigEndian.PutUint16(msg[11:], uint16(len(payload)))
+
+ if _, err := h.Write(msg); err != nil {
+ return nil, err
+ }
+ if _, err := h.Write(payload); err != nil {
+ return nil, err
+ }
+
+ return h.Sum(nil), nil
+}
+
+// hmacCID calculates a MAC according to
+// https://datatracker.ietf.org/doc/html/rfc9146#section-5.1
+func (c *CBC) hmacCID(epoch uint16, sequenceNumber uint64, protocolVersion protocol.Version, payload []byte, key []byte, hf func() hash.Hash, cid []byte) ([]byte, error) {
+ // Must unmarshal inner plaintext in orde to perform MAC.
+ ip := &recordlayer.InnerPlaintext{}
+ if err := ip.Unmarshal(payload); err != nil {
+ return nil, err
+ }
+
+ h := hmac.New(hf, key)
+
+ var msg cryptobyte.Builder
+
+ msg.AddUint64(seqNumPlaceholder)
+ msg.AddUint8(uint8(protocol.ContentTypeConnectionID))
+ msg.AddUint8(uint8(len(cid)))
+ msg.AddUint8(uint8(protocol.ContentTypeConnectionID))
+ msg.AddUint8(protocolVersion.Major)
+ msg.AddUint8(protocolVersion.Minor)
+ msg.AddUint16(epoch)
+ util.AddUint48(&msg, sequenceNumber)
+ msg.AddBytes(cid)
+ msg.AddUint16(uint16(len(payload)))
+ msg.AddBytes(ip.Content)
+ msg.AddUint8(uint8(ip.RealType))
+ msg.AddBytes(make([]byte, ip.Zeros))
+
+ if _, err := h.Write(msg.BytesOrPanic()); err != nil {
+ return nil, err
+ }
+ if _, err := h.Write(payload); err != nil {
+ return nil, err
+ }
+
+ return h.Sum(nil), nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ccm.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ccm.go
new file mode 100644
index 0000000..6fb185d
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ccm.go
@@ -0,0 +1,117 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "crypto/aes"
+ "crypto/rand"
+ "encoding/binary"
+ "fmt"
+
+ "github.com/pion/dtls/v2/pkg/crypto/ccm"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
+// CCMTagLen is the length of Authentication Tag
+type CCMTagLen int
+
+// CCM Enums
+const (
+ CCMTagLength8 CCMTagLen = 8
+ CCMTagLength CCMTagLen = 16
+ ccmNonceLength = 12
+)
+
+// CCM Provides an API to Encrypt/Decrypt DTLS 1.2 Packets
+type CCM struct {
+ localCCM, remoteCCM ccm.CCM
+ localWriteIV, remoteWriteIV []byte
+ tagLen CCMTagLen
+}
+
+// NewCCM creates a DTLS GCM Cipher
+func NewCCM(tagLen CCMTagLen, localKey, localWriteIV, remoteKey, remoteWriteIV []byte) (*CCM, error) {
+ localBlock, err := aes.NewCipher(localKey)
+ if err != nil {
+ return nil, err
+ }
+ localCCM, err := ccm.NewCCM(localBlock, int(tagLen), ccmNonceLength)
+ if err != nil {
+ return nil, err
+ }
+
+ remoteBlock, err := aes.NewCipher(remoteKey)
+ if err != nil {
+ return nil, err
+ }
+ remoteCCM, err := ccm.NewCCM(remoteBlock, int(tagLen), ccmNonceLength)
+ if err != nil {
+ return nil, err
+ }
+
+ return &CCM{
+ localCCM: localCCM,
+ localWriteIV: localWriteIV,
+ remoteCCM: remoteCCM,
+ remoteWriteIV: remoteWriteIV,
+ tagLen: tagLen,
+ }, nil
+}
+
+// Encrypt encrypt a DTLS RecordLayer message
+func (c *CCM) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) {
+ payload := raw[pkt.Header.Size():]
+ raw = raw[:pkt.Header.Size()]
+
+ nonce := append(append([]byte{}, c.localWriteIV[:4]...), make([]byte, 8)...)
+ if _, err := rand.Read(nonce[4:]); err != nil {
+ return nil, err
+ }
+
+ var additionalData []byte
+ if pkt.Header.ContentType == protocol.ContentTypeConnectionID {
+ additionalData = generateAEADAdditionalDataCID(&pkt.Header, len(payload))
+ } else {
+ additionalData = generateAEADAdditionalData(&pkt.Header, len(payload))
+ }
+ encryptedPayload := c.localCCM.Seal(nil, nonce, payload, additionalData)
+
+ encryptedPayload = append(nonce[4:], encryptedPayload...)
+ raw = append(raw, encryptedPayload...)
+
+ // Update recordLayer size to include explicit nonce
+ binary.BigEndian.PutUint16(raw[pkt.Header.Size()-2:], uint16(len(raw)-pkt.Header.Size()))
+ return raw, nil
+}
+
+// Decrypt decrypts a DTLS RecordLayer message
+func (c *CCM) Decrypt(h recordlayer.Header, in []byte) ([]byte, error) {
+ if err := h.Unmarshal(in); err != nil {
+ return nil, err
+ }
+ switch {
+ case h.ContentType == protocol.ContentTypeChangeCipherSpec:
+ // Nothing to encrypt with ChangeCipherSpec
+ return in, nil
+ case len(in) <= (8 + h.Size()):
+ return nil, errNotEnoughRoomForNonce
+ }
+
+ nonce := append(append([]byte{}, c.remoteWriteIV[:4]...), in[h.Size():h.Size()+8]...)
+ out := in[h.Size()+8:]
+
+ var additionalData []byte
+ if h.ContentType == protocol.ContentTypeConnectionID {
+ additionalData = generateAEADAdditionalDataCID(&h, len(out)-int(c.tagLen))
+ } else {
+ additionalData = generateAEADAdditionalData(&h, len(out)-int(c.tagLen))
+ }
+ var err error
+ out, err = c.remoteCCM.Open(out[:0], nonce, out, additionalData)
+ if err != nil {
+ return nil, fmt.Errorf("%w: %v", errDecryptPacket, err) //nolint:errorlint
+ }
+ return append(in[:h.Size()], out...), nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ciphersuite.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ciphersuite.go
new file mode 100644
index 0000000..a3130be
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ciphersuite.go
@@ -0,0 +1,104 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package ciphersuite provides the crypto operations needed for a DTLS CipherSuite
+package ciphersuite
+
+import (
+ "encoding/binary"
+ "errors"
+
+ "github.com/pion/dtls/v2/internal/util"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+ "golang.org/x/crypto/cryptobyte"
+)
+
+const (
+ // 8 bytes of 0xff.
+ // https://datatracker.ietf.org/doc/html/rfc9146#name-record-payload-protection
+ seqNumPlaceholder = 0xffffffffffffffff
+)
+
+var (
+ errNotEnoughRoomForNonce = &protocol.InternalError{Err: errors.New("buffer not long enough to contain nonce")} //nolint:goerr113
+ errDecryptPacket = &protocol.TemporaryError{Err: errors.New("failed to decrypt packet")} //nolint:goerr113
+ errInvalidMAC = &protocol.TemporaryError{Err: errors.New("invalid mac")} //nolint:goerr113
+ errFailedToCast = &protocol.FatalError{Err: errors.New("failed to cast")} //nolint:goerr113
+)
+
+func generateAEADAdditionalData(h *recordlayer.Header, payloadLen int) []byte {
+ var additionalData [13]byte
+
+ // SequenceNumber MUST be set first
+ // we only want uint48, clobbering an extra 2 (using uint64, Golang doesn't have uint48)
+ binary.BigEndian.PutUint64(additionalData[:], h.SequenceNumber)
+ binary.BigEndian.PutUint16(additionalData[:], h.Epoch)
+ additionalData[8] = byte(h.ContentType)
+ additionalData[9] = h.Version.Major
+ additionalData[10] = h.Version.Minor
+ binary.BigEndian.PutUint16(additionalData[len(additionalData)-2:], uint16(payloadLen))
+
+ return additionalData[:]
+}
+
+// generateAEADAdditionalDataCID generates additional data for AEAD ciphers
+// according to https://datatracker.ietf.org/doc/html/rfc9146#name-aead-ciphers
+func generateAEADAdditionalDataCID(h *recordlayer.Header, payloadLen int) []byte {
+ var b cryptobyte.Builder
+
+ b.AddUint64(seqNumPlaceholder)
+ b.AddUint8(uint8(protocol.ContentTypeConnectionID))
+ b.AddUint8(uint8(len(h.ConnectionID)))
+ b.AddUint8(uint8(protocol.ContentTypeConnectionID))
+ b.AddUint8(h.Version.Major)
+ b.AddUint8(h.Version.Minor)
+ b.AddUint16(h.Epoch)
+ util.AddUint48(&b, h.SequenceNumber)
+ b.AddBytes(h.ConnectionID)
+ b.AddUint16(uint16(payloadLen))
+
+ return b.BytesOrPanic()
+}
+
+// examinePadding returns, in constant time, the length of the padding to remove
+// from the end of payload. It also returns a byte which is equal to 255 if the
+// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2.
+//
+// https://github.com/golang/go/blob/039c2081d1178f90a8fa2f4e6958693129f8de33/src/crypto/tls/conn.go#L245
+func examinePadding(payload []byte) (toRemove int, good byte) {
+ if len(payload) < 1 {
+ return 0, 0
+ }
+
+ paddingLen := payload[len(payload)-1]
+ t := uint(len(payload)-1) - uint(paddingLen)
+ // if len(payload) >= (paddingLen - 1) then the MSB of t is zero
+ good = byte(int32(^t) >> 31)
+
+ // The maximum possible padding length plus the actual length field
+ toCheck := 256
+ // The length of the padded data is public, so we can use an if here
+ if toCheck > len(payload) {
+ toCheck = len(payload)
+ }
+
+ for i := 0; i < toCheck; i++ {
+ t := uint(paddingLen) - uint(i)
+ // if i <= paddingLen then the MSB of t is zero
+ mask := byte(int32(^t) >> 31)
+ b := payload[len(payload)-1-i]
+ good &^= mask&paddingLen ^ mask&b
+ }
+
+ // We AND together the bits of good and replicate the result across
+ // all the bits.
+ good &= good << 4
+ good &= good << 2
+ good &= good << 1
+ good = uint8(int8(good) >> 7)
+
+ toRemove = int(paddingLen) + 1
+
+ return toRemove, good
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/gcm.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/gcm.go
new file mode 100644
index 0000000..1d09c8e
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/gcm.go
@@ -0,0 +1,112 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package ciphersuite
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/rand"
+ "encoding/binary"
+ "fmt"
+
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/recordlayer"
+)
+
+const (
+ gcmTagLength = 16
+ gcmNonceLength = 12
+)
+
+// GCM Provides an API to Encrypt/Decrypt DTLS 1.2 Packets
+type GCM struct {
+ localGCM, remoteGCM cipher.AEAD
+ localWriteIV, remoteWriteIV []byte
+}
+
+// NewGCM creates a DTLS GCM Cipher
+func NewGCM(localKey, localWriteIV, remoteKey, remoteWriteIV []byte) (*GCM, error) {
+ localBlock, err := aes.NewCipher(localKey)
+ if err != nil {
+ return nil, err
+ }
+ localGCM, err := cipher.NewGCM(localBlock)
+ if err != nil {
+ return nil, err
+ }
+
+ remoteBlock, err := aes.NewCipher(remoteKey)
+ if err != nil {
+ return nil, err
+ }
+ remoteGCM, err := cipher.NewGCM(remoteBlock)
+ if err != nil {
+ return nil, err
+ }
+
+ return &GCM{
+ localGCM: localGCM,
+ localWriteIV: localWriteIV,
+ remoteGCM: remoteGCM,
+ remoteWriteIV: remoteWriteIV,
+ }, nil
+}
+
+// Encrypt encrypt a DTLS RecordLayer message
+func (g *GCM) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) {
+ payload := raw[pkt.Header.Size():]
+ raw = raw[:pkt.Header.Size()]
+
+ nonce := make([]byte, gcmNonceLength)
+ copy(nonce, g.localWriteIV[:4])
+ if _, err := rand.Read(nonce[4:]); err != nil {
+ return nil, err
+ }
+
+ var additionalData []byte
+ if pkt.Header.ContentType == protocol.ContentTypeConnectionID {
+ additionalData = generateAEADAdditionalDataCID(&pkt.Header, len(payload))
+ } else {
+ additionalData = generateAEADAdditionalData(&pkt.Header, len(payload))
+ }
+ encryptedPayload := g.localGCM.Seal(nil, nonce, payload, additionalData)
+ r := make([]byte, len(raw)+len(nonce[4:])+len(encryptedPayload))
+ copy(r, raw)
+ copy(r[len(raw):], nonce[4:])
+ copy(r[len(raw)+len(nonce[4:]):], encryptedPayload)
+
+ // Update recordLayer size to include explicit nonce
+ binary.BigEndian.PutUint16(r[pkt.Header.Size()-2:], uint16(len(r)-pkt.Header.Size()))
+ return r, nil
+}
+
+// Decrypt decrypts a DTLS RecordLayer message
+func (g *GCM) Decrypt(h recordlayer.Header, in []byte) ([]byte, error) {
+ err := h.Unmarshal(in)
+ switch {
+ case err != nil:
+ return nil, err
+ case h.ContentType == protocol.ContentTypeChangeCipherSpec:
+ // Nothing to encrypt with ChangeCipherSpec
+ return in, nil
+ case len(in) <= (8 + h.Size()):
+ return nil, errNotEnoughRoomForNonce
+ }
+
+ nonce := make([]byte, 0, gcmNonceLength)
+ nonce = append(append(nonce, g.remoteWriteIV[:4]...), in[h.Size():h.Size()+8]...)
+ out := in[h.Size()+8:]
+
+ var additionalData []byte
+ if h.ContentType == protocol.ContentTypeConnectionID {
+ additionalData = generateAEADAdditionalDataCID(&h, len(out)-gcmTagLength)
+ } else {
+ additionalData = generateAEADAdditionalData(&h, len(out)-gcmTagLength)
+ }
+ out, err = g.remoteGCM.Open(out[:0], nonce, out, additionalData)
+ if err != nil {
+ return nil, fmt.Errorf("%w: %v", errDecryptPacket, err) //nolint:errorlint
+ }
+ return append(in[:h.Size()], out...), nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/clientcertificate/client_certificate.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/clientcertificate/client_certificate.go
new file mode 100644
index 0000000..ddfa39e
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/clientcertificate/client_certificate.go
@@ -0,0 +1,25 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package clientcertificate provides all the support Client Certificate types
+package clientcertificate
+
+// Type is used to communicate what
+// type of certificate is being transported
+//
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-2
+type Type byte
+
+// ClientCertificateType enums
+const (
+ RSASign Type = 1
+ ECDSASign Type = 64
+)
+
+// Types returns all valid ClientCertificate Types
+func Types() map[Type]bool {
+ return map[Type]bool{
+ RSASign: true,
+ ECDSASign: true,
+ }
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/elliptic/elliptic.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/elliptic/elliptic.go
new file mode 100644
index 0000000..1265238
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/elliptic/elliptic.go
@@ -0,0 +1,115 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package elliptic provides elliptic curve cryptography for DTLS
+package elliptic
+
+import (
+ "crypto/elliptic"
+ "crypto/rand"
+ "errors"
+ "fmt"
+
+ "golang.org/x/crypto/curve25519"
+)
+
+var errInvalidNamedCurve = errors.New("invalid named curve")
+
+// CurvePointFormat is used to represent the IANA registered curve points
+//
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
+type CurvePointFormat byte
+
+// CurvePointFormat enums
+const (
+ CurvePointFormatUncompressed CurvePointFormat = 0
+)
+
+// Keypair is a Curve with a Private/Public Keypair
+type Keypair struct {
+ Curve Curve
+ PublicKey []byte
+ PrivateKey []byte
+}
+
+// CurveType is used to represent the IANA registered curve types for TLS
+//
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-10
+type CurveType byte
+
+// CurveType enums
+const (
+ CurveTypeNamedCurve CurveType = 0x03
+)
+
+// CurveTypes returns all known curves
+func CurveTypes() map[CurveType]struct{} {
+ return map[CurveType]struct{}{
+ CurveTypeNamedCurve: {},
+ }
+}
+
+// Curve is used to represent the IANA registered curves for TLS
+//
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
+type Curve uint16
+
+// Curve enums
+const (
+ P256 Curve = 0x0017
+ P384 Curve = 0x0018
+ X25519 Curve = 0x001d
+)
+
+func (c Curve) String() string {
+ switch c {
+ case P256:
+ return "P-256"
+ case P384:
+ return "P-384"
+ case X25519:
+ return "X25519"
+ }
+ return fmt.Sprintf("%#x", uint16(c))
+}
+
+// Curves returns all curves we implement
+func Curves() map[Curve]bool {
+ return map[Curve]bool{
+ X25519: true,
+ P256: true,
+ P384: true,
+ }
+}
+
+// GenerateKeypair generates a keypair for the given Curve
+func GenerateKeypair(c Curve) (*Keypair, error) {
+ switch c { //nolint:revive
+ case X25519:
+ tmp := make([]byte, 32)
+ if _, err := rand.Read(tmp); err != nil {
+ return nil, err
+ }
+
+ var public, private [32]byte
+ copy(private[:], tmp)
+
+ curve25519.ScalarBaseMult(&public, &private)
+ return &Keypair{X25519, public[:], private[:]}, nil
+ case P256:
+ return ellipticCurveKeypair(P256, elliptic.P256(), elliptic.P256())
+ case P384:
+ return ellipticCurveKeypair(P384, elliptic.P384(), elliptic.P384())
+ default:
+ return nil, errInvalidNamedCurve
+ }
+}
+
+func ellipticCurveKeypair(nc Curve, c1, c2 elliptic.Curve) (*Keypair, error) {
+ privateKey, x, y, err := elliptic.GenerateKey(c1, rand.Reader)
+ if err != nil {
+ return nil, err
+ }
+
+ return &Keypair{nc, elliptic.Marshal(c2, x, y), privateKey}, nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/hash/hash.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/hash/hash.go
new file mode 100644
index 0000000..9966626
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/hash/hash.go
@@ -0,0 +1,129 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package hash provides TLS HashAlgorithm as defined in TLS 1.2
+package hash
+
+import ( //nolint:gci
+ "crypto"
+ "crypto/md5" //nolint:gosec
+ "crypto/sha1" //nolint:gosec
+ "crypto/sha256"
+ "crypto/sha512"
+)
+
+// Algorithm is used to indicate the hash algorithm used
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18
+type Algorithm uint16
+
+// Supported hash algorithms
+const (
+ None Algorithm = 0 // Blacklisted
+ MD5 Algorithm = 1 // Blacklisted
+ SHA1 Algorithm = 2 // Blacklisted
+ SHA224 Algorithm = 3
+ SHA256 Algorithm = 4
+ SHA384 Algorithm = 5
+ SHA512 Algorithm = 6
+ Ed25519 Algorithm = 8
+)
+
+// String makes hashAlgorithm printable
+func (a Algorithm) String() string {
+ switch a {
+ case None:
+ return "none"
+ case MD5:
+ return "md5" // [RFC3279]
+ case SHA1:
+ return "sha-1" // [RFC3279]
+ case SHA224:
+ return "sha-224" // [RFC4055]
+ case SHA256:
+ return "sha-256" // [RFC4055]
+ case SHA384:
+ return "sha-384" // [RFC4055]
+ case SHA512:
+ return "sha-512" // [RFC4055]
+ case Ed25519:
+ return "null"
+ default:
+ return "unknown or unsupported hash algorithm"
+ }
+}
+
+// Digest performs a digest on the passed value
+func (a Algorithm) Digest(b []byte) []byte {
+ switch a {
+ case None:
+ return nil
+ case MD5:
+ hash := md5.Sum(b) // #nosec
+ return hash[:]
+ case SHA1:
+ hash := sha1.Sum(b) // #nosec
+ return hash[:]
+ case SHA224:
+ hash := sha256.Sum224(b)
+ return hash[:]
+ case SHA256:
+ hash := sha256.Sum256(b)
+ return hash[:]
+ case SHA384:
+ hash := sha512.Sum384(b)
+ return hash[:]
+ case SHA512:
+ hash := sha512.Sum512(b)
+ return hash[:]
+ default:
+ return nil
+ }
+}
+
+// Insecure returns if the given HashAlgorithm is considered secure in DTLS 1.2
+func (a Algorithm) Insecure() bool {
+ switch a {
+ case None, MD5, SHA1:
+ return true
+ default:
+ return false
+ }
+}
+
+// CryptoHash returns the crypto.Hash implementation for the given HashAlgorithm
+func (a Algorithm) CryptoHash() crypto.Hash {
+ switch a {
+ case None:
+ return crypto.Hash(0)
+ case MD5:
+ return crypto.MD5
+ case SHA1:
+ return crypto.SHA1
+ case SHA224:
+ return crypto.SHA224
+ case SHA256:
+ return crypto.SHA256
+ case SHA384:
+ return crypto.SHA384
+ case SHA512:
+ return crypto.SHA512
+ case Ed25519:
+ return crypto.Hash(0)
+ default:
+ return crypto.Hash(0)
+ }
+}
+
+// Algorithms returns all the supported Hash Algorithms
+func Algorithms() map[Algorithm]struct{} {
+ return map[Algorithm]struct{}{
+ None: {},
+ MD5: {},
+ SHA1: {},
+ SHA224: {},
+ SHA256: {},
+ SHA384: {},
+ SHA512: {},
+ Ed25519: {},
+ }
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/prf/prf.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/prf/prf.go
new file mode 100644
index 0000000..6e7b3ec
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/prf/prf.go
@@ -0,0 +1,255 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package prf implements TLS 1.2 Pseudorandom functions
+package prf
+
+import ( //nolint:gci
+ ellipticStdlib "crypto/elliptic"
+ "crypto/hmac"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "hash"
+ "math"
+
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "golang.org/x/crypto/curve25519"
+)
+
+const (
+ masterSecretLabel = "master secret"
+ extendedMasterSecretLabel = "extended master secret"
+ keyExpansionLabel = "key expansion"
+ verifyDataClientLabel = "client finished"
+ verifyDataServerLabel = "server finished"
+)
+
+// HashFunc allows callers to decide what hash is used in PRF
+type HashFunc func() hash.Hash
+
+// EncryptionKeys is all the state needed for a TLS CipherSuite
+type EncryptionKeys struct {
+ MasterSecret []byte
+ ClientMACKey []byte
+ ServerMACKey []byte
+ ClientWriteKey []byte
+ ServerWriteKey []byte
+ ClientWriteIV []byte
+ ServerWriteIV []byte
+}
+
+var errInvalidNamedCurve = &protocol.FatalError{Err: errors.New("invalid named curve")} //nolint:goerr113
+
+func (e *EncryptionKeys) String() string {
+ return fmt.Sprintf(`encryptionKeys:
+- masterSecret: %#v
+- clientMACKey: %#v
+- serverMACKey: %#v
+- clientWriteKey: %#v
+- serverWriteKey: %#v
+- clientWriteIV: %#v
+- serverWriteIV: %#v
+`,
+ e.MasterSecret,
+ e.ClientMACKey,
+ e.ServerMACKey,
+ e.ClientWriteKey,
+ e.ServerWriteKey,
+ e.ClientWriteIV,
+ e.ServerWriteIV)
+}
+
+// PSKPreMasterSecret generates the PSK Premaster Secret
+// The premaster secret is formed as follows: if the PSK is N octets
+// long, concatenate a uint16 with the value N, N zero octets, a second
+// uint16 with the value N, and the PSK itself.
+//
+// https://tools.ietf.org/html/rfc4279#section-2
+func PSKPreMasterSecret(psk []byte) []byte {
+ pskLen := uint16(len(psk))
+
+ out := append(make([]byte, 2+pskLen+2), psk...)
+ binary.BigEndian.PutUint16(out, pskLen)
+ binary.BigEndian.PutUint16(out[2+pskLen:], pskLen)
+
+ return out
+}
+
+// EcdhePSKPreMasterSecret implements TLS 1.2 Premaster Secret generation given a psk, a keypair and a curve
+//
+// https://datatracker.ietf.org/doc/html/rfc5489#section-2
+func EcdhePSKPreMasterSecret(psk, publicKey, privateKey []byte, curve elliptic.Curve) ([]byte, error) {
+ preMasterSecret, err := PreMasterSecret(publicKey, privateKey, curve)
+ if err != nil {
+ return nil, err
+ }
+ out := make([]byte, 2+len(preMasterSecret)+2+len(psk))
+
+ // write preMasterSecret length
+ offset := 0
+ binary.BigEndian.PutUint16(out[offset:], uint16(len(preMasterSecret)))
+ offset += 2
+
+ // write preMasterSecret
+ copy(out[offset:], preMasterSecret)
+ offset += len(preMasterSecret)
+
+ // write psk length
+ binary.BigEndian.PutUint16(out[offset:], uint16(len(psk)))
+ offset += 2
+
+ // write psk
+ copy(out[offset:], psk)
+ return out, nil
+}
+
+// PreMasterSecret implements TLS 1.2 Premaster Secret generation given a keypair and a curve
+func PreMasterSecret(publicKey, privateKey []byte, curve elliptic.Curve) ([]byte, error) {
+ switch curve {
+ case elliptic.X25519:
+ return curve25519.X25519(privateKey, publicKey)
+ case elliptic.P256:
+ return ellipticCurvePreMasterSecret(publicKey, privateKey, ellipticStdlib.P256(), ellipticStdlib.P256())
+ case elliptic.P384:
+ return ellipticCurvePreMasterSecret(publicKey, privateKey, ellipticStdlib.P384(), ellipticStdlib.P384())
+ default:
+ return nil, errInvalidNamedCurve
+ }
+}
+
+func ellipticCurvePreMasterSecret(publicKey, privateKey []byte, c1, c2 ellipticStdlib.Curve) ([]byte, error) {
+ x, y := ellipticStdlib.Unmarshal(c1, publicKey)
+ if x == nil || y == nil {
+ return nil, errInvalidNamedCurve
+ }
+
+ result, _ := c2.ScalarMult(x, y, privateKey)
+ preMasterSecret := make([]byte, (c2.Params().BitSize+7)>>3)
+ resultBytes := result.Bytes()
+ copy(preMasterSecret[len(preMasterSecret)-len(resultBytes):], resultBytes)
+ return preMasterSecret, nil
+}
+
+// PHash is PRF is the SHA-256 hash function is used for all cipher suites
+// defined in this TLS 1.2 document and in TLS documents published prior to this
+// document when TLS 1.2 is negotiated. New cipher suites MUST explicitly
+// specify a PRF and, in general, SHOULD use the TLS PRF with SHA-256 or a
+// stronger standard hash function.
+//
+// P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
+// HMAC_hash(secret, A(2) + seed) +
+// HMAC_hash(secret, A(3) + seed) + ...
+//
+// A() is defined as:
+//
+// A(0) = seed
+// A(i) = HMAC_hash(secret, A(i-1))
+//
+// P_hash can be iterated as many times as necessary to produce the
+// required quantity of data. For example, if P_SHA256 is being used to
+// create 80 bytes of data, it will have to be iterated three times
+// (through A(3)), creating 96 bytes of output data; the last 16 bytes
+// of the final iteration will then be discarded, leaving 80 bytes of
+// output data.
+//
+// https://tools.ietf.org/html/rfc4346w
+func PHash(secret, seed []byte, requestedLength int, h HashFunc) ([]byte, error) {
+ hmacSHA256 := func(key, data []byte) ([]byte, error) {
+ mac := hmac.New(h, key)
+ if _, err := mac.Write(data); err != nil {
+ return nil, err
+ }
+ return mac.Sum(nil), nil
+ }
+
+ var err error
+ lastRound := seed
+ out := []byte{}
+
+ iterations := int(math.Ceil(float64(requestedLength) / float64(h().Size())))
+ for i := 0; i < iterations; i++ {
+ lastRound, err = hmacSHA256(secret, lastRound)
+ if err != nil {
+ return nil, err
+ }
+ withSecret, err := hmacSHA256(secret, append(lastRound, seed...))
+ if err != nil {
+ return nil, err
+ }
+ out = append(out, withSecret...)
+ }
+
+ return out[:requestedLength], nil
+}
+
+// ExtendedMasterSecret generates a Extended MasterSecret as defined in
+// https://tools.ietf.org/html/rfc7627
+func ExtendedMasterSecret(preMasterSecret, sessionHash []byte, h HashFunc) ([]byte, error) {
+ seed := append([]byte(extendedMasterSecretLabel), sessionHash...)
+ return PHash(preMasterSecret, seed, 48, h)
+}
+
+// MasterSecret generates a TLS 1.2 MasterSecret
+func MasterSecret(preMasterSecret, clientRandom, serverRandom []byte, h HashFunc) ([]byte, error) {
+ seed := append(append([]byte(masterSecretLabel), clientRandom...), serverRandom...)
+ return PHash(preMasterSecret, seed, 48, h)
+}
+
+// GenerateEncryptionKeys is the final step TLS 1.2 PRF. Given all state generated so far generates
+// the final keys need for encryption
+func GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int, h HashFunc) (*EncryptionKeys, error) {
+ seed := append(append([]byte(keyExpansionLabel), serverRandom...), clientRandom...)
+ keyMaterial, err := PHash(masterSecret, seed, (2*macLen)+(2*keyLen)+(2*ivLen), h)
+ if err != nil {
+ return nil, err
+ }
+
+ clientMACKey := keyMaterial[:macLen]
+ keyMaterial = keyMaterial[macLen:]
+
+ serverMACKey := keyMaterial[:macLen]
+ keyMaterial = keyMaterial[macLen:]
+
+ clientWriteKey := keyMaterial[:keyLen]
+ keyMaterial = keyMaterial[keyLen:]
+
+ serverWriteKey := keyMaterial[:keyLen]
+ keyMaterial = keyMaterial[keyLen:]
+
+ clientWriteIV := keyMaterial[:ivLen]
+ keyMaterial = keyMaterial[ivLen:]
+
+ serverWriteIV := keyMaterial[:ivLen]
+
+ return &EncryptionKeys{
+ MasterSecret: masterSecret,
+ ClientMACKey: clientMACKey,
+ ServerMACKey: serverMACKey,
+ ClientWriteKey: clientWriteKey,
+ ServerWriteKey: serverWriteKey,
+ ClientWriteIV: clientWriteIV,
+ ServerWriteIV: serverWriteIV,
+ }, nil
+}
+
+func prfVerifyData(masterSecret, handshakeBodies []byte, label string, hashFunc HashFunc) ([]byte, error) {
+ h := hashFunc()
+ if _, err := h.Write(handshakeBodies); err != nil {
+ return nil, err
+ }
+
+ seed := append([]byte(label), h.Sum(nil)...)
+ return PHash(masterSecret, seed, 12, hashFunc)
+}
+
+// VerifyDataClient is caled on the Client Side to either verify or generate the VerifyData message
+func VerifyDataClient(masterSecret, handshakeBodies []byte, h HashFunc) ([]byte, error) {
+ return prfVerifyData(masterSecret, handshakeBodies, verifyDataClientLabel, h)
+}
+
+// VerifyDataServer is caled on the Server Side to either verify or generate the VerifyData message
+func VerifyDataServer(masterSecret, handshakeBodies []byte, h HashFunc) ([]byte, error) {
+ return prfVerifyData(masterSecret, handshakeBodies, verifyDataServerLabel, h)
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/signature/signature.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/signature/signature.go
new file mode 100644
index 0000000..fec7fba
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/signature/signature.go
@@ -0,0 +1,27 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package signature provides our implemented Signature Algorithms
+package signature
+
+// Algorithm as defined in TLS 1.2
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-16
+type Algorithm uint16
+
+// SignatureAlgorithm enums
+const (
+ Anonymous Algorithm = 0
+ RSA Algorithm = 1
+ ECDSA Algorithm = 3
+ Ed25519 Algorithm = 7
+)
+
+// Algorithms returns all implemented Signature Algorithms
+func Algorithms() map[Algorithm]struct{} {
+ return map[Algorithm]struct{}{
+ Anonymous: {},
+ RSA: {},
+ ECDSA: {},
+ Ed25519: {},
+ }
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/errors.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/errors.go
new file mode 100644
index 0000000..4aeb3e4
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/errors.go
@@ -0,0 +1,12 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package signaturehash
+
+import "errors"
+
+var (
+ errNoAvailableSignatureSchemes = errors.New("connection can not be created, no SignatureScheme satisfy this Config")
+ errInvalidSignatureAlgorithm = errors.New("invalid signature algorithm")
+ errInvalidHashAlgorithm = errors.New("invalid hash algorithm")
+)
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go
new file mode 100644
index 0000000..2561acc
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go
@@ -0,0 +1,96 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package signaturehash provides the SignatureHashAlgorithm as defined in TLS 1.2
+package signaturehash
+
+import (
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "crypto/tls"
+ "fmt"
+
+ "github.com/pion/dtls/v2/pkg/crypto/hash"
+ "github.com/pion/dtls/v2/pkg/crypto/signature"
+)
+
+// Algorithm is a signature/hash algorithm pairs which may be used in
+// digital signatures.
+//
+// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
+type Algorithm struct {
+ Hash hash.Algorithm
+ Signature signature.Algorithm
+}
+
+// Algorithms are all the know SignatureHash Algorithms
+func Algorithms() []Algorithm {
+ return []Algorithm{
+ {hash.SHA256, signature.ECDSA},
+ {hash.SHA384, signature.ECDSA},
+ {hash.SHA512, signature.ECDSA},
+ {hash.SHA256, signature.RSA},
+ {hash.SHA384, signature.RSA},
+ {hash.SHA512, signature.RSA},
+ {hash.Ed25519, signature.Ed25519},
+ }
+}
+
+// SelectSignatureScheme returns most preferred and compatible scheme.
+func SelectSignatureScheme(sigs []Algorithm, privateKey crypto.PrivateKey) (Algorithm, error) {
+ for _, ss := range sigs {
+ if ss.isCompatible(privateKey) {
+ return ss, nil
+ }
+ }
+ return Algorithm{}, errNoAvailableSignatureSchemes
+}
+
+// isCompatible checks that given private key is compatible with the signature scheme.
+func (a *Algorithm) isCompatible(privateKey crypto.PrivateKey) bool {
+ switch privateKey.(type) {
+ case ed25519.PrivateKey:
+ return a.Signature == signature.Ed25519
+ case *ecdsa.PrivateKey:
+ return a.Signature == signature.ECDSA
+ case *rsa.PrivateKey:
+ return a.Signature == signature.RSA
+ default:
+ return false
+ }
+}
+
+// ParseSignatureSchemes translates []tls.SignatureScheme to []signatureHashAlgorithm.
+// It returns default signature scheme list if no SignatureScheme is passed.
+func ParseSignatureSchemes(sigs []tls.SignatureScheme, insecureHashes bool) ([]Algorithm, error) {
+ if len(sigs) == 0 {
+ return Algorithms(), nil
+ }
+ out := []Algorithm{}
+ for _, ss := range sigs {
+ sig := signature.Algorithm(ss & 0xFF)
+ if _, ok := signature.Algorithms()[sig]; !ok {
+ return nil,
+ fmt.Errorf("SignatureScheme %04x: %w", ss, errInvalidSignatureAlgorithm)
+ }
+ h := hash.Algorithm(ss >> 8)
+ if _, ok := hash.Algorithms()[h]; !ok || (ok && h == hash.None) {
+ return nil, fmt.Errorf("SignatureScheme %04x: %w", ss, errInvalidHashAlgorithm)
+ }
+ if h.Insecure() && !insecureHashes {
+ continue
+ }
+ out = append(out, Algorithm{
+ Hash: h,
+ Signature: sig,
+ })
+ }
+
+ if len(out) == 0 {
+ return nil, errNoAvailableSignatureSchemes
+ }
+
+ return out, nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/net/net.go b/vendor/github.com/pion/dtls/v2/pkg/net/net.go
new file mode 100644
index 0000000..e76daf5
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/net/net.go
@@ -0,0 +1,108 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package net defines packet-oriented primitives that are compatible with net
+// in the standard library.
+package net
+
+import (
+ "net"
+ "time"
+)
+
+// A PacketListener is the same as net.Listener but returns a net.PacketConn on
+// Accept() rather than a net.Conn.
+//
+// Multiple goroutines may invoke methods on a PacketListener simultaneously.
+type PacketListener interface {
+ // Accept waits for and returns the next connection to the listener.
+ Accept() (net.PacketConn, net.Addr, error)
+
+ // Close closes the listener.
+ // Any blocked Accept operations will be unblocked and return errors.
+ Close() error
+
+ // Addr returns the listener's network address.
+ Addr() net.Addr
+}
+
+// PacketListenerFromListener converts a net.Listener into a
+// dtlsnet.PacketListener.
+func PacketListenerFromListener(l net.Listener) PacketListener {
+ return &packetListenerWrapper{
+ l: l,
+ }
+}
+
+// packetListenerWrapper wraps a net.Listener and implements
+// dtlsnet.PacketListener.
+type packetListenerWrapper struct {
+ l net.Listener
+}
+
+// Accept calls Accept on the underlying net.Listener and converts the returned
+// net.Conn into a net.PacketConn.
+func (p *packetListenerWrapper) Accept() (net.PacketConn, net.Addr, error) {
+ c, err := p.l.Accept()
+ if err != nil {
+ return PacketConnFromConn(c), nil, err
+ }
+ return PacketConnFromConn(c), c.RemoteAddr(), nil
+}
+
+// Close closes the underlying net.Listener.
+func (p *packetListenerWrapper) Close() error {
+ return p.l.Close()
+}
+
+// Addr returns the address of the underlying net.Listener.
+func (p *packetListenerWrapper) Addr() net.Addr {
+ return p.l.Addr()
+}
+
+// PacketConnFromConn converts a net.Conn into a net.PacketConn.
+func PacketConnFromConn(conn net.Conn) net.PacketConn {
+ return &packetConnWrapper{conn}
+}
+
+// packetConnWrapper wraps a net.Conn and implements net.PacketConn.
+type packetConnWrapper struct {
+ conn net.Conn
+}
+
+// ReadFrom reads from the underlying net.Conn and returns its remote address.
+func (p *packetConnWrapper) ReadFrom(b []byte) (int, net.Addr, error) {
+ n, err := p.conn.Read(b)
+ return n, p.conn.RemoteAddr(), err
+}
+
+// WriteTo writes to the underlying net.Conn.
+func (p *packetConnWrapper) WriteTo(b []byte, _ net.Addr) (int, error) {
+ n, err := p.conn.Write(b)
+ return n, err
+}
+
+// Close closes the underlying net.Conn.
+func (p *packetConnWrapper) Close() error {
+ return p.conn.Close()
+}
+
+// LocalAddr returns the local address of the underlying net.Conn.
+func (p *packetConnWrapper) LocalAddr() net.Addr {
+ return p.conn.LocalAddr()
+}
+
+// SetDeadline sets the deadline on the underlying net.Conn.
+func (p *packetConnWrapper) SetDeadline(t time.Time) error {
+ return p.conn.SetDeadline(t)
+}
+
+// SetReadDeadline sets the read deadline on the underlying net.Conn.
+func (p *packetConnWrapper) SetReadDeadline(t time.Time) error {
+ return p.conn.SetReadDeadline(t)
+}
+
+// SetWriteDeadline sets the write deadline on the underlying net.Conn.
+func (p *packetConnWrapper) SetWriteDeadline(t time.Time) error {
+ return p.conn.SetWriteDeadline(t)
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/alert/alert.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/alert/alert.go
new file mode 100644
index 0000000..91e9f4d
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/alert/alert.go
@@ -0,0 +1,166 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package alert implements TLS alert protocol https://tools.ietf.org/html/rfc5246#section-7.2
+package alert
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/pion/dtls/v2/pkg/protocol"
+)
+
+var errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113
+
+// Level is the level of the TLS Alert
+type Level byte
+
+// Level enums
+const (
+ Warning Level = 1
+ Fatal Level = 2
+)
+
+func (l Level) String() string {
+ switch l {
+ case Warning:
+ return "Warning"
+ case Fatal:
+ return "Fatal"
+ default:
+ return "Invalid alert level"
+ }
+}
+
+// Description is the extended info of the TLS Alert
+type Description byte
+
+// Description enums
+const (
+ CloseNotify Description = 0
+ UnexpectedMessage Description = 10
+ BadRecordMac Description = 20
+ DecryptionFailed Description = 21
+ RecordOverflow Description = 22
+ DecompressionFailure Description = 30
+ HandshakeFailure Description = 40
+ NoCertificate Description = 41
+ BadCertificate Description = 42
+ UnsupportedCertificate Description = 43
+ CertificateRevoked Description = 44
+ CertificateExpired Description = 45
+ CertificateUnknown Description = 46
+ IllegalParameter Description = 47
+ UnknownCA Description = 48
+ AccessDenied Description = 49
+ DecodeError Description = 50
+ DecryptError Description = 51
+ ExportRestriction Description = 60
+ ProtocolVersion Description = 70
+ InsufficientSecurity Description = 71
+ InternalError Description = 80
+ UserCanceled Description = 90
+ NoRenegotiation Description = 100
+ UnsupportedExtension Description = 110
+ NoApplicationProtocol Description = 120
+)
+
+func (d Description) String() string {
+ switch d {
+ case CloseNotify:
+ return "CloseNotify"
+ case UnexpectedMessage:
+ return "UnexpectedMessage"
+ case BadRecordMac:
+ return "BadRecordMac"
+ case DecryptionFailed:
+ return "DecryptionFailed"
+ case RecordOverflow:
+ return "RecordOverflow"
+ case DecompressionFailure:
+ return "DecompressionFailure"
+ case HandshakeFailure:
+ return "HandshakeFailure"
+ case NoCertificate:
+ return "NoCertificate"
+ case BadCertificate:
+ return "BadCertificate"
+ case UnsupportedCertificate:
+ return "UnsupportedCertificate"
+ case CertificateRevoked:
+ return "CertificateRevoked"
+ case CertificateExpired:
+ return "CertificateExpired"
+ case CertificateUnknown:
+ return "CertificateUnknown"
+ case IllegalParameter:
+ return "IllegalParameter"
+ case UnknownCA:
+ return "UnknownCA"
+ case AccessDenied:
+ return "AccessDenied"
+ case DecodeError:
+ return "DecodeError"
+ case DecryptError:
+ return "DecryptError"
+ case ExportRestriction:
+ return "ExportRestriction"
+ case ProtocolVersion:
+ return "ProtocolVersion"
+ case InsufficientSecurity:
+ return "InsufficientSecurity"
+ case InternalError:
+ return "InternalError"
+ case UserCanceled:
+ return "UserCanceled"
+ case NoRenegotiation:
+ return "NoRenegotiation"
+ case UnsupportedExtension:
+ return "UnsupportedExtension"
+ case NoApplicationProtocol:
+ return "NoApplicationProtocol"
+ default:
+ return "Invalid alert description"
+ }
+}
+
+// Alert is one of the content types supported by the TLS record layer.
+// Alert messages convey the severity of the message
+// (warning or fatal) and a description of the alert. Alert messages
+// with a level of fatal result in the immediate termination of the
+// connection. In this case, other connections corresponding to the
+// session may continue, but the session identifier MUST be invalidated,
+// preventing the failed session from being used to establish new
+// connections. Like other messages, alert messages are encrypted and
+// compressed, as specified by the current connection state.
+// https://tools.ietf.org/html/rfc5246#section-7.2
+type Alert struct {
+ Level Level
+ Description Description
+}
+
+// ContentType returns the ContentType of this Content
+func (a Alert) ContentType() protocol.ContentType {
+ return protocol.ContentTypeAlert
+}
+
+// Marshal returns the encoded alert
+func (a *Alert) Marshal() ([]byte, error) {
+ return []byte{byte(a.Level), byte(a.Description)}, nil
+}
+
+// Unmarshal populates the alert from binary data
+func (a *Alert) Unmarshal(data []byte) error {
+ if len(data) != 2 {
+ return errBufferTooSmall
+ }
+
+ a.Level = Level(data[0])
+ a.Description = Description(data[1])
+ return nil
+}
+
+func (a *Alert) String() string {
+ return fmt.Sprintf("Alert %s: %s", a.Level, a.Description)
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/application_data.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/application_data.go
new file mode 100644
index 0000000..f422115
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/application_data.go
@@ -0,0 +1,29 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package protocol
+
+// ApplicationData messages are carried by the record layer and are
+// fragmented, compressed, and encrypted based on the current connection
+// state. The messages are treated as transparent data to the record
+// layer.
+// https://tools.ietf.org/html/rfc5246#section-10
+type ApplicationData struct {
+ Data []byte
+}
+
+// ContentType returns the ContentType of this content
+func (a ApplicationData) ContentType() ContentType {
+ return ContentTypeApplicationData
+}
+
+// Marshal encodes the ApplicationData to binary
+func (a *ApplicationData) Marshal() ([]byte, error) {
+ return append([]byte{}, a.Data...), nil
+}
+
+// Unmarshal populates the ApplicationData from binary
+func (a *ApplicationData) Unmarshal(data []byte) error {
+ a.Data = append([]byte{}, data...)
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/change_cipher_spec.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/change_cipher_spec.go
new file mode 100644
index 0000000..87f28bc
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/change_cipher_spec.go
@@ -0,0 +1,30 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package protocol
+
+// ChangeCipherSpec protocol exists to signal transitions in
+// ciphering strategies. The protocol consists of a single message,
+// which is encrypted and compressed under the current (not the pending)
+// connection state. The message consists of a single byte of value 1.
+// https://tools.ietf.org/html/rfc5246#section-7.1
+type ChangeCipherSpec struct{}
+
+// ContentType returns the ContentType of this content
+func (c ChangeCipherSpec) ContentType() ContentType {
+ return ContentTypeChangeCipherSpec
+}
+
+// Marshal encodes the ChangeCipherSpec to binary
+func (c *ChangeCipherSpec) Marshal() ([]byte, error) {
+ return []byte{0x01}, nil
+}
+
+// Unmarshal populates the ChangeCipherSpec from binary
+func (c *ChangeCipherSpec) Unmarshal(data []byte) error {
+ if len(data) == 1 && data[0] == 0x01 {
+ return nil
+ }
+
+ return errInvalidCipherSpec
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/compression_method.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/compression_method.go
new file mode 100644
index 0000000..3478ee3
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/compression_method.go
@@ -0,0 +1,51 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package protocol
+
+// CompressionMethodID is the ID for a CompressionMethod
+type CompressionMethodID byte
+
+const (
+ compressionMethodNull CompressionMethodID = 0
+)
+
+// CompressionMethod represents a TLS Compression Method
+type CompressionMethod struct {
+ ID CompressionMethodID
+}
+
+// CompressionMethods returns all supported CompressionMethods
+func CompressionMethods() map[CompressionMethodID]*CompressionMethod {
+ return map[CompressionMethodID]*CompressionMethod{
+ compressionMethodNull: {ID: compressionMethodNull},
+ }
+}
+
+// DecodeCompressionMethods the given compression methods
+func DecodeCompressionMethods(buf []byte) ([]*CompressionMethod, error) {
+ if len(buf) < 1 {
+ return nil, errBufferTooSmall
+ }
+ compressionMethodsCount := int(buf[0])
+ c := []*CompressionMethod{}
+ for i := 0; i < compressionMethodsCount; i++ {
+ if len(buf) <= i+1 {
+ return nil, errBufferTooSmall
+ }
+ id := CompressionMethodID(buf[i+1])
+ if compressionMethod, ok := CompressionMethods()[id]; ok {
+ c = append(c, compressionMethod)
+ }
+ }
+ return c, nil
+}
+
+// EncodeCompressionMethods the given compression methods
+func EncodeCompressionMethods(c []*CompressionMethod) []byte {
+ out := []byte{byte(len(c))}
+ for i := len(c); i > 0; i-- {
+ out = append(out, byte(c[i-1].ID))
+ }
+ return out
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/content.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/content.go
new file mode 100644
index 0000000..154005e
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/content.go
@@ -0,0 +1,25 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package protocol
+
+// ContentType represents the IANA Registered ContentTypes
+//
+// https://tools.ietf.org/html/rfc4346#section-6.2.1
+type ContentType uint8
+
+// ContentType enums
+const (
+ ContentTypeChangeCipherSpec ContentType = 20
+ ContentTypeAlert ContentType = 21
+ ContentTypeHandshake ContentType = 22
+ ContentTypeApplicationData ContentType = 23
+ ContentTypeConnectionID ContentType = 25
+)
+
+// Content is the top level distinguisher for a DTLS Datagram
+type Content interface {
+ ContentType() ContentType
+ Marshal() ([]byte, error)
+ Unmarshal(data []byte) error
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/errors.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/errors.go
new file mode 100644
index 0000000..d87aff7
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/errors.go
@@ -0,0 +1,109 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package protocol
+
+import (
+ "errors"
+ "fmt"
+ "net"
+)
+
+var (
+ errBufferTooSmall = &TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113
+ errInvalidCipherSpec = &FatalError{Err: errors.New("cipher spec invalid")} //nolint:goerr113
+)
+
+// FatalError indicates that the DTLS connection is no longer available.
+// It is mainly caused by wrong configuration of server or client.
+type FatalError struct {
+ Err error
+}
+
+// InternalError indicates and internal error caused by the implementation, and the DTLS connection is no longer available.
+// It is mainly caused by bugs or tried to use unimplemented features.
+type InternalError struct {
+ Err error
+}
+
+// TemporaryError indicates that the DTLS connection is still available, but the request was failed temporary.
+type TemporaryError struct {
+ Err error
+}
+
+// TimeoutError indicates that the request was timed out.
+type TimeoutError struct {
+ Err error
+}
+
+// HandshakeError indicates that the handshake failed.
+type HandshakeError struct {
+ Err error
+}
+
+// Timeout implements net.Error.Timeout()
+func (*FatalError) Timeout() bool { return false }
+
+// Temporary implements net.Error.Temporary()
+func (*FatalError) Temporary() bool { return false }
+
+// Unwrap implements Go1.13 error unwrapper.
+func (e *FatalError) Unwrap() error { return e.Err }
+
+func (e *FatalError) Error() string { return fmt.Sprintf("dtls fatal: %v", e.Err) }
+
+// Timeout implements net.Error.Timeout()
+func (*InternalError) Timeout() bool { return false }
+
+// Temporary implements net.Error.Temporary()
+func (*InternalError) Temporary() bool { return false }
+
+// Unwrap implements Go1.13 error unwrapper.
+func (e *InternalError) Unwrap() error { return e.Err }
+
+func (e *InternalError) Error() string { return fmt.Sprintf("dtls internal: %v", e.Err) }
+
+// Timeout implements net.Error.Timeout()
+func (*TemporaryError) Timeout() bool { return false }
+
+// Temporary implements net.Error.Temporary()
+func (*TemporaryError) Temporary() bool { return true }
+
+// Unwrap implements Go1.13 error unwrapper.
+func (e *TemporaryError) Unwrap() error { return e.Err }
+
+func (e *TemporaryError) Error() string { return fmt.Sprintf("dtls temporary: %v", e.Err) }
+
+// Timeout implements net.Error.Timeout()
+func (*TimeoutError) Timeout() bool { return true }
+
+// Temporary implements net.Error.Temporary()
+func (*TimeoutError) Temporary() bool { return true }
+
+// Unwrap implements Go1.13 error unwrapper.
+func (e *TimeoutError) Unwrap() error { return e.Err }
+
+func (e *TimeoutError) Error() string { return fmt.Sprintf("dtls timeout: %v", e.Err) }
+
+// Timeout implements net.Error.Timeout()
+func (e *HandshakeError) Timeout() bool {
+ var netErr net.Error
+ if errors.As(e.Err, &netErr) {
+ return netErr.Timeout()
+ }
+ return false
+}
+
+// Temporary implements net.Error.Temporary()
+func (e *HandshakeError) Temporary() bool {
+ var netErr net.Error
+ if errors.As(e.Err, &netErr) {
+ return netErr.Temporary() //nolint
+ }
+ return false
+}
+
+// Unwrap implements Go1.13 error unwrapper.
+func (e *HandshakeError) Unwrap() error { return e.Err }
+
+func (e *HandshakeError) Error() string { return fmt.Sprintf("handshake error: %v", e.Err) }
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/alpn.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/alpn.go
new file mode 100644
index 0000000..e780dc9
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/alpn.go
@@ -0,0 +1,80 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package extension
+
+import (
+ "golang.org/x/crypto/cryptobyte"
+)
+
+// ALPN is a TLS extension for application-layer protocol negotiation within
+// the TLS handshake.
+//
+// https://tools.ietf.org/html/rfc7301
+type ALPN struct {
+ ProtocolNameList []string
+}
+
+// TypeValue returns the extension TypeValue
+func (a ALPN) TypeValue() TypeValue {
+ return ALPNTypeValue
+}
+
+// Marshal encodes the extension
+func (a *ALPN) Marshal() ([]byte, error) {
+ var b cryptobyte.Builder
+ b.AddUint16(uint16(a.TypeValue()))
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, proto := range a.ProtocolNameList {
+ p := proto // Satisfy range scope lint
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes([]byte(p))
+ })
+ }
+ })
+ })
+ return b.Bytes()
+}
+
+// Unmarshal populates the extension from encoded data
+func (a *ALPN) Unmarshal(data []byte) error {
+ val := cryptobyte.String(data)
+
+ var extension uint16
+ val.ReadUint16(&extension)
+ if TypeValue(extension) != a.TypeValue() {
+ return errInvalidExtensionType
+ }
+
+ var extData cryptobyte.String
+ val.ReadUint16LengthPrefixed(&extData)
+
+ var protoList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
+ return ErrALPNInvalidFormat
+ }
+ for !protoList.Empty() {
+ var proto cryptobyte.String
+ if !protoList.ReadUint8LengthPrefixed(&proto) || proto.Empty() {
+ return ErrALPNInvalidFormat
+ }
+ a.ProtocolNameList = append(a.ProtocolNameList, string(proto))
+ }
+ return nil
+}
+
+// ALPNProtocolSelection negotiates a shared protocol according to #3.2 of rfc7301
+func ALPNProtocolSelection(supportedProtocols, peerSupportedProtocols []string) (string, error) {
+ if len(supportedProtocols) == 0 || len(peerSupportedProtocols) == 0 {
+ return "", nil
+ }
+ for _, s := range supportedProtocols {
+ for _, c := range peerSupportedProtocols {
+ if s == c {
+ return s, nil
+ }
+ }
+ }
+ return "", errALPNNoAppProto
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/connection_id.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/connection_id.go
new file mode 100644
index 0000000..b3fe164
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/connection_id.go
@@ -0,0 +1,59 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package extension
+
+import (
+ "golang.org/x/crypto/cryptobyte"
+)
+
+// ConnectionID is a DTLS extension that provides an alternative to IP address
+// and port for session association.
+//
+// https://tools.ietf.org/html/rfc9146
+type ConnectionID struct {
+ // A zero-length connection ID indicates for a client or server that
+ // negotiated connection IDs from the peer will be sent but there is no need
+ // to respond with one
+ CID []byte // variable length
+}
+
+// TypeValue returns the extension TypeValue
+func (c ConnectionID) TypeValue() TypeValue {
+ return ConnectionIDTypeValue
+}
+
+// Marshal encodes the extension
+func (c *ConnectionID) Marshal() ([]byte, error) {
+ var b cryptobyte.Builder
+ b.AddUint16(uint16(c.TypeValue()))
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(c.CID)
+ })
+ })
+ return b.Bytes()
+}
+
+// Unmarshal populates the extension from encoded data
+func (c *ConnectionID) Unmarshal(data []byte) error {
+ val := cryptobyte.String(data)
+ var extension uint16
+ val.ReadUint16(&extension)
+ if TypeValue(extension) != c.TypeValue() {
+ return errInvalidExtensionType
+ }
+
+ var extData cryptobyte.String
+ val.ReadUint16LengthPrefixed(&extData)
+
+ var cid cryptobyte.String
+ if !extData.ReadUint8LengthPrefixed(&cid) {
+ return errInvalidCIDFormat
+ }
+ c.CID = make([]byte, len(cid))
+ if !cid.CopyBytes(c.CID) {
+ return errInvalidCIDFormat
+ }
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/errors.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/errors.go
new file mode 100644
index 0000000..3943120
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/errors.go
@@ -0,0 +1,21 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package extension
+
+import (
+ "errors"
+
+ "github.com/pion/dtls/v2/pkg/protocol"
+)
+
+var (
+ // ErrALPNInvalidFormat is raised when the ALPN format is invalid
+ ErrALPNInvalidFormat = &protocol.FatalError{Err: errors.New("invalid alpn format")} //nolint:goerr113
+ errALPNNoAppProto = &protocol.FatalError{Err: errors.New("no application protocol")} //nolint:goerr113
+ errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113
+ errInvalidExtensionType = &protocol.FatalError{Err: errors.New("invalid extension type")} //nolint:goerr113
+ errInvalidSNIFormat = &protocol.FatalError{Err: errors.New("invalid server name format")} //nolint:goerr113
+ errInvalidCIDFormat = &protocol.FatalError{Err: errors.New("invalid connection ID format")} //nolint:goerr113
+ errLengthMismatch = &protocol.InternalError{Err: errors.New("data length and declared length do not match")} //nolint:goerr113
+)
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/extension.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/extension.go
new file mode 100644
index 0000000..e4df859
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/extension.go
@@ -0,0 +1,109 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package extension implements the extension values in the ClientHello/ServerHello
+package extension
+
+import "encoding/binary"
+
+// TypeValue is the 2 byte value for a TLS Extension as registered in the IANA
+//
+// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
+type TypeValue uint16
+
+// TypeValue constants
+const (
+ ServerNameTypeValue TypeValue = 0
+ SupportedEllipticCurvesTypeValue TypeValue = 10
+ SupportedPointFormatsTypeValue TypeValue = 11
+ SupportedSignatureAlgorithmsTypeValue TypeValue = 13
+ UseSRTPTypeValue TypeValue = 14
+ ALPNTypeValue TypeValue = 16
+ UseExtendedMasterSecretTypeValue TypeValue = 23
+ ConnectionIDTypeValue TypeValue = 54
+ RenegotiationInfoTypeValue TypeValue = 65281
+)
+
+// Extension represents a single TLS extension
+type Extension interface {
+ Marshal() ([]byte, error)
+ Unmarshal(data []byte) error
+ TypeValue() TypeValue
+}
+
+// Unmarshal many extensions at once
+func Unmarshal(buf []byte) ([]Extension, error) {
+ switch {
+ case len(buf) == 0:
+ return []Extension{}, nil
+ case len(buf) < 2:
+ return nil, errBufferTooSmall
+ }
+
+ declaredLen := binary.BigEndian.Uint16(buf)
+ if len(buf)-2 != int(declaredLen) {
+ return nil, errLengthMismatch
+ }
+
+ extensions := []Extension{}
+ unmarshalAndAppend := func(data []byte, e Extension) error {
+ err := e.Unmarshal(data)
+ if err != nil {
+ return err
+ }
+ extensions = append(extensions, e)
+ return nil
+ }
+
+ for offset := 2; offset < len(buf); {
+ if len(buf) < (offset + 2) {
+ return nil, errBufferTooSmall
+ }
+ var err error
+ switch TypeValue(binary.BigEndian.Uint16(buf[offset:])) {
+ case ServerNameTypeValue:
+ err = unmarshalAndAppend(buf[offset:], &ServerName{})
+ case SupportedEllipticCurvesTypeValue:
+ err = unmarshalAndAppend(buf[offset:], &SupportedEllipticCurves{})
+ case SupportedPointFormatsTypeValue:
+ err = unmarshalAndAppend(buf[offset:], &SupportedPointFormats{})
+ case SupportedSignatureAlgorithmsTypeValue:
+ err = unmarshalAndAppend(buf[offset:], &SupportedSignatureAlgorithms{})
+ case UseSRTPTypeValue:
+ err = unmarshalAndAppend(buf[offset:], &UseSRTP{})
+ case ALPNTypeValue:
+ err = unmarshalAndAppend(buf[offset:], &ALPN{})
+ case UseExtendedMasterSecretTypeValue:
+ err = unmarshalAndAppend(buf[offset:], &UseExtendedMasterSecret{})
+ case RenegotiationInfoTypeValue:
+ err = unmarshalAndAppend(buf[offset:], &RenegotiationInfo{})
+ case ConnectionIDTypeValue:
+ err = unmarshalAndAppend(buf[offset:], &ConnectionID{})
+ default:
+ }
+ if err != nil {
+ return nil, err
+ }
+ if len(buf) < (offset + 4) {
+ return nil, errBufferTooSmall
+ }
+ extensionLength := binary.BigEndian.Uint16(buf[offset+2:])
+ offset += (4 + int(extensionLength))
+ }
+ return extensions, nil
+}
+
+// Marshal many extensions at once
+func Marshal(e []Extension) ([]byte, error) {
+ extensions := []byte{}
+ for _, e := range e {
+ raw, err := e.Marshal()
+ if err != nil {
+ return nil, err
+ }
+ extensions = append(extensions, raw...)
+ }
+ out := []byte{0x00, 0x00}
+ binary.BigEndian.PutUint16(out, uint16(len(extensions)))
+ return append(out, extensions...), nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/renegotiation_info.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/renegotiation_info.go
new file mode 100644
index 0000000..c5092a7
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/renegotiation_info.go
@@ -0,0 +1,46 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package extension
+
+import "encoding/binary"
+
+const (
+ renegotiationInfoHeaderSize = 5
+)
+
+// RenegotiationInfo allows a Client/Server to
+// communicate their renegotation support
+//
+// https://tools.ietf.org/html/rfc5746
+type RenegotiationInfo struct {
+ RenegotiatedConnection uint8
+}
+
+// TypeValue returns the extension TypeValue
+func (r RenegotiationInfo) TypeValue() TypeValue {
+ return RenegotiationInfoTypeValue
+}
+
+// Marshal encodes the extension
+func (r *RenegotiationInfo) Marshal() ([]byte, error) {
+ out := make([]byte, renegotiationInfoHeaderSize)
+
+ binary.BigEndian.PutUint16(out, uint16(r.TypeValue()))
+ binary.BigEndian.PutUint16(out[2:], uint16(1)) // length
+ out[4] = r.RenegotiatedConnection
+ return out, nil
+}
+
+// Unmarshal populates the extension from encoded data
+func (r *RenegotiationInfo) Unmarshal(data []byte) error {
+ if len(data) < renegotiationInfoHeaderSize {
+ return errBufferTooSmall
+ } else if TypeValue(binary.BigEndian.Uint16(data)) != r.TypeValue() {
+ return errInvalidExtensionType
+ }
+
+ r.RenegotiatedConnection = data[4]
+
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go
new file mode 100644
index 0000000..183e08e
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go
@@ -0,0 +1,81 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package extension
+
+import (
+ "strings"
+
+ "golang.org/x/crypto/cryptobyte"
+)
+
+const serverNameTypeDNSHostName = 0
+
+// ServerName allows the client to inform the server the specific
+// name it wishes to contact. Useful if multiple DNS names resolve
+// to one IP
+//
+// https://tools.ietf.org/html/rfc6066#section-3
+type ServerName struct {
+ ServerName string
+}
+
+// TypeValue returns the extension TypeValue
+func (s ServerName) TypeValue() TypeValue {
+ return ServerNameTypeValue
+}
+
+// Marshal encodes the extension
+func (s *ServerName) Marshal() ([]byte, error) {
+ var b cryptobyte.Builder
+ b.AddUint16(uint16(s.TypeValue()))
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint8(serverNameTypeDNSHostName)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes([]byte(s.ServerName))
+ })
+ })
+ })
+ return b.Bytes()
+}
+
+// Unmarshal populates the extension from encoded data
+func (s *ServerName) Unmarshal(data []byte) error {
+ val := cryptobyte.String(data)
+ var extension uint16
+ val.ReadUint16(&extension)
+ if TypeValue(extension) != s.TypeValue() {
+ return errInvalidExtensionType
+ }
+
+ var extData cryptobyte.String
+ val.ReadUint16LengthPrefixed(&extData)
+
+ var nameList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() {
+ return errInvalidSNIFormat
+ }
+ for !nameList.Empty() {
+ var nameType uint8
+ var serverName cryptobyte.String
+ if !nameList.ReadUint8(&nameType) ||
+ !nameList.ReadUint16LengthPrefixed(&serverName) ||
+ serverName.Empty() {
+ return errInvalidSNIFormat
+ }
+ if nameType != serverNameTypeDNSHostName {
+ continue
+ }
+ if len(s.ServerName) != 0 {
+ // Multiple names of the same name_type are prohibited.
+ return errInvalidSNIFormat
+ }
+ s.ServerName = string(serverName)
+ // An SNI value may not include a trailing dot.
+ if strings.HasSuffix(s.ServerName, ".") {
+ return errInvalidSNIFormat
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/srtp_protection_profile.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/srtp_protection_profile.go
new file mode 100644
index 0000000..2966966
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/srtp_protection_profile.go
@@ -0,0 +1,24 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package extension
+
+// SRTPProtectionProfile defines the parameters and options that are in effect for the SRTP processing
+// https://tools.ietf.org/html/rfc5764#section-4.1.2
+type SRTPProtectionProfile uint16
+
+const (
+ SRTP_AES128_CM_HMAC_SHA1_80 SRTPProtectionProfile = 0x0001 // nolint
+ SRTP_AES128_CM_HMAC_SHA1_32 SRTPProtectionProfile = 0x0002 // nolint
+ SRTP_AEAD_AES_128_GCM SRTPProtectionProfile = 0x0007 // nolint
+ SRTP_AEAD_AES_256_GCM SRTPProtectionProfile = 0x0008 // nolint
+)
+
+func srtpProtectionProfiles() map[SRTPProtectionProfile]bool {
+ return map[SRTPProtectionProfile]bool{
+ SRTP_AES128_CM_HMAC_SHA1_80: true,
+ SRTP_AES128_CM_HMAC_SHA1_32: true,
+ SRTP_AEAD_AES_128_GCM: true,
+ SRTP_AEAD_AES_256_GCM: true,
+ }
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_elliptic_curves.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_elliptic_curves.go
new file mode 100644
index 0000000..dd9b54f
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_elliptic_curves.go
@@ -0,0 +1,65 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package extension
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+)
+
+const (
+ supportedGroupsHeaderSize = 6
+)
+
+// SupportedEllipticCurves allows a Client/Server to communicate
+// what curves they both support
+//
+// https://tools.ietf.org/html/rfc8422#section-5.1.1
+type SupportedEllipticCurves struct {
+ EllipticCurves []elliptic.Curve
+}
+
+// TypeValue returns the extension TypeValue
+func (s SupportedEllipticCurves) TypeValue() TypeValue {
+ return SupportedEllipticCurvesTypeValue
+}
+
+// Marshal encodes the extension
+func (s *SupportedEllipticCurves) Marshal() ([]byte, error) {
+ out := make([]byte, supportedGroupsHeaderSize)
+
+ binary.BigEndian.PutUint16(out, uint16(s.TypeValue()))
+ binary.BigEndian.PutUint16(out[2:], uint16(2+(len(s.EllipticCurves)*2)))
+ binary.BigEndian.PutUint16(out[4:], uint16(len(s.EllipticCurves)*2))
+
+ for _, v := range s.EllipticCurves {
+ out = append(out, []byte{0x00, 0x00}...)
+ binary.BigEndian.PutUint16(out[len(out)-2:], uint16(v))
+ }
+
+ return out, nil
+}
+
+// Unmarshal populates the extension from encoded data
+func (s *SupportedEllipticCurves) Unmarshal(data []byte) error {
+ if len(data) <= supportedGroupsHeaderSize {
+ return errBufferTooSmall
+ } else if TypeValue(binary.BigEndian.Uint16(data)) != s.TypeValue() {
+ return errInvalidExtensionType
+ }
+
+ groupCount := int(binary.BigEndian.Uint16(data[4:]) / 2)
+ if supportedGroupsHeaderSize+(groupCount*2) > len(data) {
+ return errLengthMismatch
+ }
+
+ for i := 0; i < groupCount; i++ {
+ supportedGroupID := elliptic.Curve(binary.BigEndian.Uint16(data[(supportedGroupsHeaderSize + (i * 2)):]))
+ if _, ok := elliptic.Curves()[supportedGroupID]; ok {
+ s.EllipticCurves = append(s.EllipticCurves, supportedGroupID)
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_point_formats.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_point_formats.go
new file mode 100644
index 0000000..5ed0f34
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_point_formats.go
@@ -0,0 +1,67 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package extension
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+)
+
+const (
+ supportedPointFormatsSize = 5
+)
+
+// SupportedPointFormats allows a Client/Server to negotiate
+// the EllipticCurvePointFormats
+//
+// https://tools.ietf.org/html/rfc4492#section-5.1.2
+type SupportedPointFormats struct {
+ PointFormats []elliptic.CurvePointFormat
+}
+
+// TypeValue returns the extension TypeValue
+func (s SupportedPointFormats) TypeValue() TypeValue {
+ return SupportedPointFormatsTypeValue
+}
+
+// Marshal encodes the extension
+func (s *SupportedPointFormats) Marshal() ([]byte, error) {
+ out := make([]byte, supportedPointFormatsSize)
+
+ binary.BigEndian.PutUint16(out, uint16(s.TypeValue()))
+ binary.BigEndian.PutUint16(out[2:], uint16(1+(len(s.PointFormats))))
+ out[4] = byte(len(s.PointFormats))
+
+ for _, v := range s.PointFormats {
+ out = append(out, byte(v))
+ }
+ return out, nil
+}
+
+// Unmarshal populates the extension from encoded data
+func (s *SupportedPointFormats) Unmarshal(data []byte) error {
+ if len(data) <= supportedPointFormatsSize {
+ return errBufferTooSmall
+ }
+
+ if TypeValue(binary.BigEndian.Uint16(data)) != s.TypeValue() {
+ return errInvalidExtensionType
+ }
+
+ pointFormatCount := int(data[4])
+ if supportedPointFormatsSize+pointFormatCount > len(data) {
+ return errLengthMismatch
+ }
+
+ for i := 0; i < pointFormatCount; i++ {
+ p := elliptic.CurvePointFormat(data[supportedPointFormatsSize+i])
+ switch p {
+ case elliptic.CurvePointFormatUncompressed:
+ s.PointFormats = append(s.PointFormats, p)
+ default:
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_signature_algorithms.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_signature_algorithms.go
new file mode 100644
index 0000000..2ff4b90
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_signature_algorithms.go
@@ -0,0 +1,73 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package extension
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/pkg/crypto/hash"
+ "github.com/pion/dtls/v2/pkg/crypto/signature"
+ "github.com/pion/dtls/v2/pkg/crypto/signaturehash"
+)
+
+const (
+ supportedSignatureAlgorithmsHeaderSize = 6
+)
+
+// SupportedSignatureAlgorithms allows a Client/Server to
+// negotiate what SignatureHash Algorithms they both support
+//
+// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
+type SupportedSignatureAlgorithms struct {
+ SignatureHashAlgorithms []signaturehash.Algorithm
+}
+
+// TypeValue returns the extension TypeValue
+func (s SupportedSignatureAlgorithms) TypeValue() TypeValue {
+ return SupportedSignatureAlgorithmsTypeValue
+}
+
+// Marshal encodes the extension
+func (s *SupportedSignatureAlgorithms) Marshal() ([]byte, error) {
+ out := make([]byte, supportedSignatureAlgorithmsHeaderSize)
+
+ binary.BigEndian.PutUint16(out, uint16(s.TypeValue()))
+ binary.BigEndian.PutUint16(out[2:], uint16(2+(len(s.SignatureHashAlgorithms)*2)))
+ binary.BigEndian.PutUint16(out[4:], uint16(len(s.SignatureHashAlgorithms)*2))
+ for _, v := range s.SignatureHashAlgorithms {
+ out = append(out, []byte{0x00, 0x00}...)
+ out[len(out)-2] = byte(v.Hash)
+ out[len(out)-1] = byte(v.Signature)
+ }
+
+ return out, nil
+}
+
+// Unmarshal populates the extension from encoded data
+func (s *SupportedSignatureAlgorithms) Unmarshal(data []byte) error {
+ if len(data) <= supportedSignatureAlgorithmsHeaderSize {
+ return errBufferTooSmall
+ } else if TypeValue(binary.BigEndian.Uint16(data)) != s.TypeValue() {
+ return errInvalidExtensionType
+ }
+
+ algorithmCount := int(binary.BigEndian.Uint16(data[4:]) / 2)
+ if supportedSignatureAlgorithmsHeaderSize+(algorithmCount*2) > len(data) {
+ return errLengthMismatch
+ }
+ for i := 0; i < algorithmCount; i++ {
+ supportedHashAlgorithm := hash.Algorithm(data[supportedSignatureAlgorithmsHeaderSize+(i*2)])
+ supportedSignatureAlgorithm := signature.Algorithm(data[supportedSignatureAlgorithmsHeaderSize+(i*2)+1])
+ if _, ok := hash.Algorithms()[supportedHashAlgorithm]; ok {
+ if _, ok := signature.Algorithms()[supportedSignatureAlgorithm]; ok {
+ s.SignatureHashAlgorithms = append(s.SignatureHashAlgorithms, signaturehash.Algorithm{
+ Hash: supportedHashAlgorithm,
+ Signature: supportedSignatureAlgorithm,
+ })
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_master_secret.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_master_secret.go
new file mode 100644
index 0000000..d0b70ca
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_master_secret.go
@@ -0,0 +1,48 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package extension
+
+import "encoding/binary"
+
+const (
+ useExtendedMasterSecretHeaderSize = 4
+)
+
+// UseExtendedMasterSecret defines a TLS extension that contextually binds the
+// master secret to a log of the full handshake that computes it, thus
+// preventing MITM attacks.
+type UseExtendedMasterSecret struct {
+ Supported bool
+}
+
+// TypeValue returns the extension TypeValue
+func (u UseExtendedMasterSecret) TypeValue() TypeValue {
+ return UseExtendedMasterSecretTypeValue
+}
+
+// Marshal encodes the extension
+func (u *UseExtendedMasterSecret) Marshal() ([]byte, error) {
+ if !u.Supported {
+ return []byte{}, nil
+ }
+
+ out := make([]byte, useExtendedMasterSecretHeaderSize)
+
+ binary.BigEndian.PutUint16(out, uint16(u.TypeValue()))
+ binary.BigEndian.PutUint16(out[2:], uint16(0)) // length
+ return out, nil
+}
+
+// Unmarshal populates the extension from encoded data
+func (u *UseExtendedMasterSecret) Unmarshal(data []byte) error {
+ if len(data) < useExtendedMasterSecretHeaderSize {
+ return errBufferTooSmall
+ } else if TypeValue(binary.BigEndian.Uint16(data)) != u.TypeValue() {
+ return errInvalidExtensionType
+ }
+
+ u.Supported = true
+
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_srtp.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_srtp.go
new file mode 100644
index 0000000..ea9f108
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_srtp.go
@@ -0,0 +1,62 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package extension
+
+import "encoding/binary"
+
+const (
+ useSRTPHeaderSize = 6
+)
+
+// UseSRTP allows a Client/Server to negotiate what SRTPProtectionProfiles
+// they both support
+//
+// https://tools.ietf.org/html/rfc8422
+type UseSRTP struct {
+ ProtectionProfiles []SRTPProtectionProfile
+}
+
+// TypeValue returns the extension TypeValue
+func (u UseSRTP) TypeValue() TypeValue {
+ return UseSRTPTypeValue
+}
+
+// Marshal encodes the extension
+func (u *UseSRTP) Marshal() ([]byte, error) {
+ out := make([]byte, useSRTPHeaderSize)
+
+ binary.BigEndian.PutUint16(out, uint16(u.TypeValue()))
+ binary.BigEndian.PutUint16(out[2:], uint16(2+(len(u.ProtectionProfiles)*2)+ /* MKI Length */ 1))
+ binary.BigEndian.PutUint16(out[4:], uint16(len(u.ProtectionProfiles)*2))
+
+ for _, v := range u.ProtectionProfiles {
+ out = append(out, []byte{0x00, 0x00}...)
+ binary.BigEndian.PutUint16(out[len(out)-2:], uint16(v))
+ }
+
+ out = append(out, 0x00) /* MKI Length */
+ return out, nil
+}
+
+// Unmarshal populates the extension from encoded data
+func (u *UseSRTP) Unmarshal(data []byte) error {
+ if len(data) <= useSRTPHeaderSize {
+ return errBufferTooSmall
+ } else if TypeValue(binary.BigEndian.Uint16(data)) != u.TypeValue() {
+ return errInvalidExtensionType
+ }
+
+ profileCount := int(binary.BigEndian.Uint16(data[4:]) / 2)
+ if supportedGroupsHeaderSize+(profileCount*2) > len(data) {
+ return errLengthMismatch
+ }
+
+ for i := 0; i < profileCount; i++ {
+ supportedProfile := SRTPProtectionProfile(binary.BigEndian.Uint16(data[(useSRTPHeaderSize + (i * 2)):]))
+ if _, ok := srtpProtectionProfiles()[supportedProfile]; ok {
+ u.ProtectionProfiles = append(u.ProtectionProfiles, supportedProfile)
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/cipher_suite.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/cipher_suite.go
new file mode 100644
index 0000000..b296297
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/cipher_suite.go
@@ -0,0 +1,32 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import "encoding/binary"
+
+func decodeCipherSuiteIDs(buf []byte) ([]uint16, error) {
+ if len(buf) < 2 {
+ return nil, errBufferTooSmall
+ }
+ cipherSuitesCount := int(binary.BigEndian.Uint16(buf[0:])) / 2
+ rtrn := make([]uint16, cipherSuitesCount)
+ for i := 0; i < cipherSuitesCount; i++ {
+ if len(buf) < (i*2 + 4) {
+ return nil, errBufferTooSmall
+ }
+
+ rtrn[i] = binary.BigEndian.Uint16(buf[(i*2)+2:])
+ }
+ return rtrn, nil
+}
+
+func encodeCipherSuiteIDs(cipherSuiteIDs []uint16) []byte {
+ out := []byte{0x00, 0x00}
+ binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(cipherSuiteIDs)*2))
+ for _, id := range cipherSuiteIDs {
+ out = append(out, []byte{0x00, 0x00}...)
+ binary.BigEndian.PutUint16(out[len(out)-2:], id)
+ }
+ return out
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/errors.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/errors.go
new file mode 100644
index 0000000..1354300
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/errors.go
@@ -0,0 +1,28 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import (
+ "errors"
+
+ "github.com/pion/dtls/v2/pkg/protocol"
+)
+
+// Typed errors
+var (
+ errUnableToMarshalFragmented = &protocol.InternalError{Err: errors.New("unable to marshal fragmented handshakes")} //nolint:goerr113
+ errHandshakeMessageUnset = &protocol.InternalError{Err: errors.New("handshake message unset, unable to marshal")} //nolint:goerr113
+ errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113
+ errLengthMismatch = &protocol.InternalError{Err: errors.New("data length and declared length do not match")} //nolint:goerr113
+ errInvalidClientKeyExchange = &protocol.FatalError{Err: errors.New("unable to determine if ClientKeyExchange is a public key or PSK Identity")} //nolint:goerr113
+ errInvalidHashAlgorithm = &protocol.FatalError{Err: errors.New("invalid hash algorithm")} //nolint:goerr113
+ errInvalidSignatureAlgorithm = &protocol.FatalError{Err: errors.New("invalid signature algorithm")} //nolint:goerr113
+ errCookieTooLong = &protocol.FatalError{Err: errors.New("cookie must not be longer then 255 bytes")} //nolint:goerr113
+ errInvalidEllipticCurveType = &protocol.FatalError{Err: errors.New("invalid or unknown elliptic curve type")} //nolint:goerr113
+ errInvalidNamedCurve = &protocol.FatalError{Err: errors.New("invalid named curve")} //nolint:goerr113
+ errCipherSuiteUnset = &protocol.FatalError{Err: errors.New("server hello can not be created without a cipher suite")} //nolint:goerr113
+ errCompressionMethodUnset = &protocol.FatalError{Err: errors.New("server hello can not be created without a compression method")} //nolint:goerr113
+ errInvalidCompressionMethod = &protocol.FatalError{Err: errors.New("invalid or unknown compression method")} //nolint:goerr113
+ errNotImplemented = &protocol.InternalError{Err: errors.New("feature has not been implemented yet")} //nolint:goerr113
+)
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go
new file mode 100644
index 0000000..b1f682b
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go
@@ -0,0 +1,150 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package handshake provides the DTLS wire protocol for handshakes
+package handshake
+
+import (
+ "github.com/pion/dtls/v2/internal/ciphersuite/types"
+ "github.com/pion/dtls/v2/internal/util"
+ "github.com/pion/dtls/v2/pkg/protocol"
+)
+
+// Type is the unique identifier for each handshake message
+// https://tools.ietf.org/html/rfc5246#section-7.4
+type Type uint8
+
+// Types of DTLS Handshake messages we know about
+const (
+ TypeHelloRequest Type = 0
+ TypeClientHello Type = 1
+ TypeServerHello Type = 2
+ TypeHelloVerifyRequest Type = 3
+ TypeCertificate Type = 11
+ TypeServerKeyExchange Type = 12
+ TypeCertificateRequest Type = 13
+ TypeServerHelloDone Type = 14
+ TypeCertificateVerify Type = 15
+ TypeClientKeyExchange Type = 16
+ TypeFinished Type = 20
+)
+
+// String returns the string representation of this type
+func (t Type) String() string {
+ switch t {
+ case TypeHelloRequest:
+ return "HelloRequest"
+ case TypeClientHello:
+ return "ClientHello"
+ case TypeServerHello:
+ return "ServerHello"
+ case TypeHelloVerifyRequest:
+ return "HelloVerifyRequest"
+ case TypeCertificate:
+ return "TypeCertificate"
+ case TypeServerKeyExchange:
+ return "ServerKeyExchange"
+ case TypeCertificateRequest:
+ return "CertificateRequest"
+ case TypeServerHelloDone:
+ return "ServerHelloDone"
+ case TypeCertificateVerify:
+ return "CertificateVerify"
+ case TypeClientKeyExchange:
+ return "ClientKeyExchange"
+ case TypeFinished:
+ return "Finished"
+ }
+ return ""
+}
+
+// Message is the body of a Handshake datagram
+type Message interface {
+ Marshal() ([]byte, error)
+ Unmarshal(data []byte) error
+ Type() Type
+}
+
+// Handshake protocol is responsible for selecting a cipher spec and
+// generating a master secret, which together comprise the primary
+// cryptographic parameters associated with a secure session. The
+// handshake protocol can also optionally authenticate parties who have
+// certificates signed by a trusted certificate authority.
+// https://tools.ietf.org/html/rfc5246#section-7.3
+type Handshake struct {
+ Header Header
+ Message Message
+
+ KeyExchangeAlgorithm types.KeyExchangeAlgorithm
+}
+
+// ContentType returns what kind of content this message is carying
+func (h Handshake) ContentType() protocol.ContentType {
+ return protocol.ContentTypeHandshake
+}
+
+// Marshal encodes a handshake into a binary message
+func (h *Handshake) Marshal() ([]byte, error) {
+ if h.Message == nil {
+ return nil, errHandshakeMessageUnset
+ } else if h.Header.FragmentOffset != 0 {
+ return nil, errUnableToMarshalFragmented
+ }
+
+ msg, err := h.Message.Marshal()
+ if err != nil {
+ return nil, err
+ }
+
+ h.Header.Length = uint32(len(msg))
+ h.Header.FragmentLength = h.Header.Length
+ h.Header.Type = h.Message.Type()
+ header, err := h.Header.Marshal()
+ if err != nil {
+ return nil, err
+ }
+
+ return append(header, msg...), nil
+}
+
+// Unmarshal decodes a handshake from a binary message
+func (h *Handshake) Unmarshal(data []byte) error {
+ if err := h.Header.Unmarshal(data); err != nil {
+ return err
+ }
+
+ reportedLen := util.BigEndianUint24(data[1:])
+ if uint32(len(data)-HeaderLength) != reportedLen {
+ return errLengthMismatch
+ } else if reportedLen != h.Header.FragmentLength {
+ return errLengthMismatch
+ }
+
+ switch Type(data[0]) {
+ case TypeHelloRequest:
+ return errNotImplemented
+ case TypeClientHello:
+ h.Message = &MessageClientHello{}
+ case TypeHelloVerifyRequest:
+ h.Message = &MessageHelloVerifyRequest{}
+ case TypeServerHello:
+ h.Message = &MessageServerHello{}
+ case TypeCertificate:
+ h.Message = &MessageCertificate{}
+ case TypeServerKeyExchange:
+ h.Message = &MessageServerKeyExchange{KeyExchangeAlgorithm: h.KeyExchangeAlgorithm}
+ case TypeCertificateRequest:
+ h.Message = &MessageCertificateRequest{}
+ case TypeServerHelloDone:
+ h.Message = &MessageServerHelloDone{}
+ case TypeClientKeyExchange:
+ h.Message = &MessageClientKeyExchange{KeyExchangeAlgorithm: h.KeyExchangeAlgorithm}
+ case TypeFinished:
+ h.Message = &MessageFinished{}
+ case TypeCertificateVerify:
+ h.Message = &MessageCertificateVerify{}
+ default:
+ return errNotImplemented
+ }
+ return h.Message.Unmarshal(data[HeaderLength:])
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/header.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/header.go
new file mode 100644
index 0000000..4f9a962
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/header.go
@@ -0,0 +1,53 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/internal/util"
+)
+
+// HeaderLength msg_len for Handshake messages assumes an extra
+// 12 bytes for sequence, fragment and version information vs TLS
+const HeaderLength = 12
+
+// Header is the static first 12 bytes of each RecordLayer
+// of type Handshake. These fields allow us to support message loss, reordering, and
+// message fragmentation,
+//
+// https://tools.ietf.org/html/rfc6347#section-4.2.2
+type Header struct {
+ Type Type
+ Length uint32 // uint24 in spec
+ MessageSequence uint16
+ FragmentOffset uint32 // uint24 in spec
+ FragmentLength uint32 // uint24 in spec
+}
+
+// Marshal encodes the Header
+func (h *Header) Marshal() ([]byte, error) {
+ out := make([]byte, HeaderLength)
+
+ out[0] = byte(h.Type)
+ util.PutBigEndianUint24(out[1:], h.Length)
+ binary.BigEndian.PutUint16(out[4:], h.MessageSequence)
+ util.PutBigEndianUint24(out[6:], h.FragmentOffset)
+ util.PutBigEndianUint24(out[9:], h.FragmentLength)
+ return out, nil
+}
+
+// Unmarshal populates the header from encoded data
+func (h *Header) Unmarshal(data []byte) error {
+ if len(data) < HeaderLength {
+ return errBufferTooSmall
+ }
+
+ h.Type = Type(data[0])
+ h.Length = util.BigEndianUint24(data[1:])
+ h.MessageSequence = binary.BigEndian.Uint16(data[4:])
+ h.FragmentOffset = util.BigEndianUint24(data[6:])
+ h.FragmentLength = util.BigEndianUint24(data[9:])
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate.go
new file mode 100644
index 0000000..d5c861d
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate.go
@@ -0,0 +1,69 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import (
+ "github.com/pion/dtls/v2/internal/util"
+)
+
+// MessageCertificate is a DTLS Handshake Message
+// it can contain either a Client or Server Certificate
+//
+// https://tools.ietf.org/html/rfc5246#section-7.4.2
+type MessageCertificate struct {
+ Certificate [][]byte
+}
+
+// Type returns the Handshake Type
+func (m MessageCertificate) Type() Type {
+ return TypeCertificate
+}
+
+const (
+ handshakeMessageCertificateLengthFieldSize = 3
+)
+
+// Marshal encodes the Handshake
+func (m *MessageCertificate) Marshal() ([]byte, error) {
+ out := make([]byte, handshakeMessageCertificateLengthFieldSize)
+
+ for _, r := range m.Certificate {
+ // Certificate Length
+ out = append(out, make([]byte, handshakeMessageCertificateLengthFieldSize)...)
+ util.PutBigEndianUint24(out[len(out)-handshakeMessageCertificateLengthFieldSize:], uint32(len(r)))
+
+ // Certificate body
+ out = append(out, append([]byte{}, r...)...)
+ }
+
+ // Total Payload Size
+ util.PutBigEndianUint24(out[0:], uint32(len(out[handshakeMessageCertificateLengthFieldSize:])))
+ return out, nil
+}
+
+// Unmarshal populates the message from encoded data
+func (m *MessageCertificate) Unmarshal(data []byte) error {
+ if len(data) < handshakeMessageCertificateLengthFieldSize {
+ return errBufferTooSmall
+ }
+
+ if certificateBodyLen := int(util.BigEndianUint24(data)); certificateBodyLen+handshakeMessageCertificateLengthFieldSize != len(data) {
+ return errLengthMismatch
+ }
+
+ offset := handshakeMessageCertificateLengthFieldSize
+ for offset < len(data) {
+ certificateLen := int(util.BigEndianUint24(data[offset:]))
+ offset += handshakeMessageCertificateLengthFieldSize
+
+ if offset+certificateLen > len(data) {
+ return errLengthMismatch
+ }
+
+ m.Certificate = append(m.Certificate, append([]byte{}, data[offset:offset+certificateLen]...))
+ offset += certificateLen
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_request.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_request.go
new file mode 100644
index 0000000..11a44d4
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_request.go
@@ -0,0 +1,144 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
+ "github.com/pion/dtls/v2/pkg/crypto/hash"
+ "github.com/pion/dtls/v2/pkg/crypto/signature"
+ "github.com/pion/dtls/v2/pkg/crypto/signaturehash"
+)
+
+/*
+MessageCertificateRequest is so a non-anonymous server can optionally
+request a certificate from the client, if appropriate for the selected cipher
+suite. This message, if sent, will immediately follow the ServerKeyExchange
+message (if it is sent; otherwise, this message follows the
+server's Certificate message).
+
+https://tools.ietf.org/html/rfc5246#section-7.4.4
+*/
+type MessageCertificateRequest struct {
+ CertificateTypes []clientcertificate.Type
+ SignatureHashAlgorithms []signaturehash.Algorithm
+ CertificateAuthoritiesNames [][]byte
+}
+
+const (
+ messageCertificateRequestMinLength = 5
+)
+
+// Type returns the Handshake Type
+func (m MessageCertificateRequest) Type() Type {
+ return TypeCertificateRequest
+}
+
+// Marshal encodes the Handshake
+func (m *MessageCertificateRequest) Marshal() ([]byte, error) {
+ out := []byte{byte(len(m.CertificateTypes))}
+ for _, v := range m.CertificateTypes {
+ out = append(out, byte(v))
+ }
+
+ out = append(out, []byte{0x00, 0x00}...)
+ binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(m.SignatureHashAlgorithms)*2))
+ for _, v := range m.SignatureHashAlgorithms {
+ out = append(out, byte(v.Hash))
+ out = append(out, byte(v.Signature))
+ }
+
+ // Distinguished Names
+ casLength := 0
+ for _, ca := range m.CertificateAuthoritiesNames {
+ casLength += len(ca) + 2
+ }
+ out = append(out, []byte{0x00, 0x00}...)
+ binary.BigEndian.PutUint16(out[len(out)-2:], uint16(casLength))
+ if casLength > 0 {
+ for _, ca := range m.CertificateAuthoritiesNames {
+ out = append(out, []byte{0x00, 0x00}...)
+ binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(ca)))
+ out = append(out, ca...)
+ }
+ }
+ return out, nil
+}
+
+// Unmarshal populates the message from encoded data
+func (m *MessageCertificateRequest) Unmarshal(data []byte) error {
+ if len(data) < messageCertificateRequestMinLength {
+ return errBufferTooSmall
+ }
+
+ offset := 0
+ certificateTypesLength := int(data[0])
+ offset++
+
+ if (offset + certificateTypesLength) > len(data) {
+ return errBufferTooSmall
+ }
+
+ for i := 0; i < certificateTypesLength; i++ {
+ certType := clientcertificate.Type(data[offset+i])
+ if _, ok := clientcertificate.Types()[certType]; ok {
+ m.CertificateTypes = append(m.CertificateTypes, certType)
+ }
+ }
+ offset += certificateTypesLength
+ if len(data) < offset+2 {
+ return errBufferTooSmall
+ }
+ signatureHashAlgorithmsLength := int(binary.BigEndian.Uint16(data[offset:]))
+ offset += 2
+
+ if (offset + signatureHashAlgorithmsLength) > len(data) {
+ return errBufferTooSmall
+ }
+
+ for i := 0; i < signatureHashAlgorithmsLength; i += 2 {
+ if len(data) < (offset + i + 2) {
+ return errBufferTooSmall
+ }
+ h := hash.Algorithm(data[offset+i])
+ s := signature.Algorithm(data[offset+i+1])
+
+ if _, ok := hash.Algorithms()[h]; !ok {
+ continue
+ } else if _, ok := signature.Algorithms()[s]; !ok {
+ continue
+ }
+ m.SignatureHashAlgorithms = append(m.SignatureHashAlgorithms, signaturehash.Algorithm{Signature: s, Hash: h})
+ }
+
+ offset += signatureHashAlgorithmsLength
+ if len(data) < offset+2 {
+ return errBufferTooSmall
+ }
+ casLength := int(binary.BigEndian.Uint16(data[offset:]))
+ offset += 2
+ if (offset + casLength) > len(data) {
+ return errBufferTooSmall
+ }
+ cas := make([]byte, casLength)
+ copy(cas, data[offset:offset+casLength])
+ m.CertificateAuthoritiesNames = nil
+ for len(cas) > 0 {
+ if len(cas) < 2 {
+ return errBufferTooSmall
+ }
+ caLen := binary.BigEndian.Uint16(cas)
+ cas = cas[2:]
+
+ if len(cas) < int(caLen) {
+ return errBufferTooSmall
+ }
+
+ m.CertificateAuthoritiesNames = append(m.CertificateAuthoritiesNames, cas[:caLen])
+ cas = cas[caLen:]
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_verify.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_verify.go
new file mode 100644
index 0000000..9e02a9c
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_verify.go
@@ -0,0 +1,64 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/pkg/crypto/hash"
+ "github.com/pion/dtls/v2/pkg/crypto/signature"
+)
+
+// MessageCertificateVerify provide explicit verification of a
+// client certificate.
+//
+// https://tools.ietf.org/html/rfc5246#section-7.4.8
+type MessageCertificateVerify struct {
+ HashAlgorithm hash.Algorithm
+ SignatureAlgorithm signature.Algorithm
+ Signature []byte
+}
+
+const handshakeMessageCertificateVerifyMinLength = 4
+
+// Type returns the Handshake Type
+func (m MessageCertificateVerify) Type() Type {
+ return TypeCertificateVerify
+}
+
+// Marshal encodes the Handshake
+func (m *MessageCertificateVerify) Marshal() ([]byte, error) {
+ out := make([]byte, 1+1+2+len(m.Signature))
+
+ out[0] = byte(m.HashAlgorithm)
+ out[1] = byte(m.SignatureAlgorithm)
+ binary.BigEndian.PutUint16(out[2:], uint16(len(m.Signature)))
+ copy(out[4:], m.Signature)
+ return out, nil
+}
+
+// Unmarshal populates the message from encoded data
+func (m *MessageCertificateVerify) Unmarshal(data []byte) error {
+ if len(data) < handshakeMessageCertificateVerifyMinLength {
+ return errBufferTooSmall
+ }
+
+ m.HashAlgorithm = hash.Algorithm(data[0])
+ if _, ok := hash.Algorithms()[m.HashAlgorithm]; !ok {
+ return errInvalidHashAlgorithm
+ }
+
+ m.SignatureAlgorithm = signature.Algorithm(data[1])
+ if _, ok := signature.Algorithms()[m.SignatureAlgorithm]; !ok {
+ return errInvalidSignatureAlgorithm
+ }
+
+ signatureLength := int(binary.BigEndian.Uint16(data[2:]))
+ if (signatureLength + 4) != len(data) {
+ return errBufferTooSmall
+ }
+
+ m.Signature = append([]byte{}, data[4:]...)
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_hello.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_hello.go
new file mode 100644
index 0000000..bea6dd9
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_hello.go
@@ -0,0 +1,141 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/extension"
+)
+
+/*
+MessageClientHello is for when a client first connects to a server it is
+required to send the client hello as its first message. The client can also send a
+client hello in response to a hello request or on its own
+initiative in order to renegotiate the security parameters in an
+existing connection.
+*/
+type MessageClientHello struct {
+ Version protocol.Version
+ Random Random
+ Cookie []byte
+
+ SessionID []byte
+
+ CipherSuiteIDs []uint16
+ CompressionMethods []*protocol.CompressionMethod
+ Extensions []extension.Extension
+}
+
+const handshakeMessageClientHelloVariableWidthStart = 34
+
+// Type returns the Handshake Type
+func (m MessageClientHello) Type() Type {
+ return TypeClientHello
+}
+
+// Marshal encodes the Handshake
+func (m *MessageClientHello) Marshal() ([]byte, error) {
+ if len(m.Cookie) > 255 {
+ return nil, errCookieTooLong
+ }
+
+ out := make([]byte, handshakeMessageClientHelloVariableWidthStart)
+ out[0] = m.Version.Major
+ out[1] = m.Version.Minor
+
+ rand := m.Random.MarshalFixed()
+ copy(out[2:], rand[:])
+
+ out = append(out, byte(len(m.SessionID)))
+ out = append(out, m.SessionID...)
+
+ out = append(out, byte(len(m.Cookie)))
+ out = append(out, m.Cookie...)
+ out = append(out, encodeCipherSuiteIDs(m.CipherSuiteIDs)...)
+ out = append(out, protocol.EncodeCompressionMethods(m.CompressionMethods)...)
+
+ extensions, err := extension.Marshal(m.Extensions)
+ if err != nil {
+ return nil, err
+ }
+
+ return append(out, extensions...), nil
+}
+
+// Unmarshal populates the message from encoded data
+func (m *MessageClientHello) Unmarshal(data []byte) error {
+ if len(data) < 2+RandomLength {
+ return errBufferTooSmall
+ }
+
+ m.Version.Major = data[0]
+ m.Version.Minor = data[1]
+
+ var random [RandomLength]byte
+ copy(random[:], data[2:])
+ m.Random.UnmarshalFixed(random)
+
+ // rest of packet has variable width sections
+ currOffset := handshakeMessageClientHelloVariableWidthStart
+
+ currOffset++
+ if len(data) <= currOffset {
+ return errBufferTooSmall
+ }
+ n := int(data[currOffset-1])
+ if len(data) <= currOffset+n {
+ return errBufferTooSmall
+ }
+ m.SessionID = append([]byte{}, data[currOffset:currOffset+n]...)
+ currOffset += len(m.SessionID)
+
+ currOffset++
+ if len(data) <= currOffset {
+ return errBufferTooSmall
+ }
+ n = int(data[currOffset-1])
+ if len(data) <= currOffset+n {
+ return errBufferTooSmall
+ }
+ m.Cookie = append([]byte{}, data[currOffset:currOffset+n]...)
+ currOffset += len(m.Cookie)
+
+ // Cipher Suites
+ if len(data) < currOffset {
+ return errBufferTooSmall
+ }
+ cipherSuiteIDs, err := decodeCipherSuiteIDs(data[currOffset:])
+ if err != nil {
+ return err
+ }
+ m.CipherSuiteIDs = cipherSuiteIDs
+ if len(data) < currOffset+2 {
+ return errBufferTooSmall
+ }
+ currOffset += int(binary.BigEndian.Uint16(data[currOffset:])) + 2
+
+ // Compression Methods
+ if len(data) < currOffset {
+ return errBufferTooSmall
+ }
+ compressionMethods, err := protocol.DecodeCompressionMethods(data[currOffset:])
+ if err != nil {
+ return err
+ }
+ m.CompressionMethods = compressionMethods
+ if len(data) < currOffset {
+ return errBufferTooSmall
+ }
+ currOffset += int(data[currOffset]) + 1
+
+ // Extensions
+ extensions, err := extension.Unmarshal(data[currOffset:])
+ if err != nil {
+ return err
+ }
+ m.Extensions = extensions
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_key_exchange.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_key_exchange.go
new file mode 100644
index 0000000..2abcd5b
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_key_exchange.go
@@ -0,0 +1,81 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/internal/ciphersuite/types"
+)
+
+// MessageClientKeyExchange is a DTLS Handshake Message
+// With this message, the premaster secret is set, either by direct
+// transmission of the RSA-encrypted secret or by the transmission of
+// Diffie-Hellman parameters that will allow each side to agree upon
+// the same premaster secret.
+//
+// https://tools.ietf.org/html/rfc5246#section-7.4.7
+type MessageClientKeyExchange struct {
+ IdentityHint []byte
+ PublicKey []byte
+
+ // for unmarshaling
+ KeyExchangeAlgorithm types.KeyExchangeAlgorithm
+}
+
+// Type returns the Handshake Type
+func (m MessageClientKeyExchange) Type() Type {
+ return TypeClientKeyExchange
+}
+
+// Marshal encodes the Handshake
+func (m *MessageClientKeyExchange) Marshal() (out []byte, err error) {
+ if m.IdentityHint == nil && m.PublicKey == nil {
+ return nil, errInvalidClientKeyExchange
+ }
+
+ if m.IdentityHint != nil {
+ out = append([]byte{0x00, 0x00}, m.IdentityHint...)
+ binary.BigEndian.PutUint16(out, uint16(len(out)-2))
+ }
+
+ if m.PublicKey != nil {
+ out = append(out, byte(len(m.PublicKey)))
+ out = append(out, m.PublicKey...)
+ }
+
+ return out, nil
+}
+
+// Unmarshal populates the message from encoded data
+func (m *MessageClientKeyExchange) Unmarshal(data []byte) error {
+ switch {
+ case len(data) < 2:
+ return errBufferTooSmall
+ case m.KeyExchangeAlgorithm == types.KeyExchangeAlgorithmNone:
+ return errCipherSuiteUnset
+ }
+
+ offset := 0
+ if m.KeyExchangeAlgorithm.Has(types.KeyExchangeAlgorithmPsk) {
+ pskLength := int(binary.BigEndian.Uint16(data))
+ if pskLength > len(data)-2 {
+ return errBufferTooSmall
+ }
+
+ m.IdentityHint = append([]byte{}, data[2:pskLength+2]...)
+ offset += pskLength + 2
+ }
+
+ if m.KeyExchangeAlgorithm.Has(types.KeyExchangeAlgorithmEcdhe) {
+ publicKeyLength := int(data[offset])
+ if publicKeyLength > len(data)-1-offset {
+ return errBufferTooSmall
+ }
+
+ m.PublicKey = append([]byte{}, data[offset+1:]...)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_finished.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_finished.go
new file mode 100644
index 0000000..255aedd
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_finished.go
@@ -0,0 +1,30 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+// MessageFinished is a DTLS Handshake Message
+// this message is the first one protected with the just
+// negotiated algorithms, keys, and secrets. Recipients of Finished
+// messages MUST verify that the contents are correct.
+//
+// https://tools.ietf.org/html/rfc5246#section-7.4.9
+type MessageFinished struct {
+ VerifyData []byte
+}
+
+// Type returns the Handshake Type
+func (m MessageFinished) Type() Type {
+ return TypeFinished
+}
+
+// Marshal encodes the Handshake
+func (m *MessageFinished) Marshal() ([]byte, error) {
+ return append([]byte{}, m.VerifyData...), nil
+}
+
+// Unmarshal populates the message from encoded data
+func (m *MessageFinished) Unmarshal(data []byte) error {
+ m.VerifyData = append([]byte{}, data...)
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_hello_verify_request.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_hello_verify_request.go
new file mode 100644
index 0000000..398e59c
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_hello_verify_request.go
@@ -0,0 +1,65 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import (
+ "github.com/pion/dtls/v2/pkg/protocol"
+)
+
+// MessageHelloVerifyRequest is as follows:
+//
+// struct {
+// ProtocolVersion server_version;
+// opaque cookie<0..2^8-1>;
+// } HelloVerifyRequest;
+//
+// The HelloVerifyRequest message type is hello_verify_request(3).
+//
+// When the client sends its ClientHello message to the server, the server
+// MAY respond with a HelloVerifyRequest message. This message contains
+// a stateless cookie generated using the technique of [PHOTURIS]. The
+// client MUST retransmit the ClientHello with the cookie added.
+//
+// https://tools.ietf.org/html/rfc6347#section-4.2.1
+type MessageHelloVerifyRequest struct {
+ Version protocol.Version
+ Cookie []byte
+}
+
+// Type returns the Handshake Type
+func (m MessageHelloVerifyRequest) Type() Type {
+ return TypeHelloVerifyRequest
+}
+
+// Marshal encodes the Handshake
+func (m *MessageHelloVerifyRequest) Marshal() ([]byte, error) {
+ if len(m.Cookie) > 255 {
+ return nil, errCookieTooLong
+ }
+
+ out := make([]byte, 3+len(m.Cookie))
+ out[0] = m.Version.Major
+ out[1] = m.Version.Minor
+ out[2] = byte(len(m.Cookie))
+ copy(out[3:], m.Cookie)
+
+ return out, nil
+}
+
+// Unmarshal populates the message from encoded data
+func (m *MessageHelloVerifyRequest) Unmarshal(data []byte) error {
+ if len(data) < 3 {
+ return errBufferTooSmall
+ }
+ m.Version.Major = data[0]
+ m.Version.Minor = data[1]
+ cookieLength := int(data[2])
+ if len(data) < cookieLength+3 {
+ return errBufferTooSmall
+ }
+ m.Cookie = make([]byte, cookieLength)
+
+ copy(m.Cookie, data[3:3+cookieLength])
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello.go
new file mode 100644
index 0000000..caf186d
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello.go
@@ -0,0 +1,122 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/extension"
+)
+
+// MessageServerHello is sent in response to a ClientHello
+// message when it was able to find an acceptable set of algorithms.
+// If it cannot find such a match, it will respond with a handshake
+// failure alert.
+//
+// https://tools.ietf.org/html/rfc5246#section-7.4.1.3
+type MessageServerHello struct {
+ Version protocol.Version
+ Random Random
+
+ SessionID []byte
+
+ CipherSuiteID *uint16
+ CompressionMethod *protocol.CompressionMethod
+ Extensions []extension.Extension
+}
+
+const messageServerHelloVariableWidthStart = 2 + RandomLength
+
+// Type returns the Handshake Type
+func (m MessageServerHello) Type() Type {
+ return TypeServerHello
+}
+
+// Marshal encodes the Handshake
+func (m *MessageServerHello) Marshal() ([]byte, error) {
+ if m.CipherSuiteID == nil {
+ return nil, errCipherSuiteUnset
+ } else if m.CompressionMethod == nil {
+ return nil, errCompressionMethodUnset
+ }
+
+ out := make([]byte, messageServerHelloVariableWidthStart)
+ out[0] = m.Version.Major
+ out[1] = m.Version.Minor
+
+ rand := m.Random.MarshalFixed()
+ copy(out[2:], rand[:])
+
+ out = append(out, byte(len(m.SessionID)))
+ out = append(out, m.SessionID...)
+
+ out = append(out, []byte{0x00, 0x00}...)
+ binary.BigEndian.PutUint16(out[len(out)-2:], *m.CipherSuiteID)
+
+ out = append(out, byte(m.CompressionMethod.ID))
+
+ extensions, err := extension.Marshal(m.Extensions)
+ if err != nil {
+ return nil, err
+ }
+
+ return append(out, extensions...), nil
+}
+
+// Unmarshal populates the message from encoded data
+func (m *MessageServerHello) Unmarshal(data []byte) error {
+ if len(data) < 2+RandomLength {
+ return errBufferTooSmall
+ }
+
+ m.Version.Major = data[0]
+ m.Version.Minor = data[1]
+
+ var random [RandomLength]byte
+ copy(random[:], data[2:])
+ m.Random.UnmarshalFixed(random)
+
+ currOffset := messageServerHelloVariableWidthStart
+ currOffset++
+ if len(data) <= currOffset {
+ return errBufferTooSmall
+ }
+
+ n := int(data[currOffset-1])
+ if len(data) <= currOffset+n {
+ return errBufferTooSmall
+ }
+ m.SessionID = append([]byte{}, data[currOffset:currOffset+n]...)
+ currOffset += len(m.SessionID)
+
+ if len(data) < currOffset+2 {
+ return errBufferTooSmall
+ }
+ m.CipherSuiteID = new(uint16)
+ *m.CipherSuiteID = binary.BigEndian.Uint16(data[currOffset:])
+ currOffset += 2
+
+ if len(data) <= currOffset {
+ return errBufferTooSmall
+ }
+ if compressionMethod, ok := protocol.CompressionMethods()[protocol.CompressionMethodID(data[currOffset])]; ok {
+ m.CompressionMethod = compressionMethod
+ currOffset++
+ } else {
+ return errInvalidCompressionMethod
+ }
+
+ if len(data) <= currOffset {
+ m.Extensions = []extension.Extension{}
+ return nil
+ }
+
+ extensions, err := extension.Unmarshal(data[currOffset:])
+ if err != nil {
+ return err
+ }
+ m.Extensions = extensions
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello_done.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello_done.go
new file mode 100644
index 0000000..b187dd4
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello_done.go
@@ -0,0 +1,24 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+// MessageServerHelloDone is final non-encrypted message from server
+// this communicates server has sent all its handshake messages and next
+// should be MessageFinished
+type MessageServerHelloDone struct{}
+
+// Type returns the Handshake Type
+func (m MessageServerHelloDone) Type() Type {
+ return TypeServerHelloDone
+}
+
+// Marshal encodes the Handshake
+func (m *MessageServerHelloDone) Marshal() ([]byte, error) {
+ return []byte{}, nil
+}
+
+// Unmarshal populates the message from encoded data
+func (m *MessageServerHelloDone) Unmarshal([]byte) error {
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_key_exchange.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_key_exchange.go
new file mode 100644
index 0000000..82abbe0
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_key_exchange.go
@@ -0,0 +1,148 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/internal/ciphersuite/types"
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+ "github.com/pion/dtls/v2/pkg/crypto/hash"
+ "github.com/pion/dtls/v2/pkg/crypto/signature"
+)
+
+// MessageServerKeyExchange supports ECDH and PSK
+type MessageServerKeyExchange struct {
+ IdentityHint []byte
+
+ EllipticCurveType elliptic.CurveType
+ NamedCurve elliptic.Curve
+ PublicKey []byte
+ HashAlgorithm hash.Algorithm
+ SignatureAlgorithm signature.Algorithm
+ Signature []byte
+
+ // for unmarshaling
+ KeyExchangeAlgorithm types.KeyExchangeAlgorithm
+}
+
+// Type returns the Handshake Type
+func (m MessageServerKeyExchange) Type() Type {
+ return TypeServerKeyExchange
+}
+
+// Marshal encodes the Handshake
+func (m *MessageServerKeyExchange) Marshal() ([]byte, error) {
+ var out []byte
+ if m.IdentityHint != nil {
+ out = append([]byte{0x00, 0x00}, m.IdentityHint...)
+ binary.BigEndian.PutUint16(out, uint16(len(out)-2))
+ }
+
+ if m.EllipticCurveType == 0 || len(m.PublicKey) == 0 {
+ return out, nil
+ }
+ out = append(out, byte(m.EllipticCurveType), 0x00, 0x00)
+ binary.BigEndian.PutUint16(out[len(out)-2:], uint16(m.NamedCurve))
+
+ out = append(out, byte(len(m.PublicKey)))
+ out = append(out, m.PublicKey...)
+ switch {
+ case m.HashAlgorithm != hash.None && len(m.Signature) == 0:
+ return nil, errInvalidHashAlgorithm
+ case m.HashAlgorithm == hash.None && len(m.Signature) > 0:
+ return nil, errInvalidHashAlgorithm
+ case m.SignatureAlgorithm == signature.Anonymous && (m.HashAlgorithm != hash.None || len(m.Signature) > 0):
+ return nil, errInvalidSignatureAlgorithm
+ case m.SignatureAlgorithm == signature.Anonymous:
+ return out, nil
+ }
+
+ out = append(out, []byte{byte(m.HashAlgorithm), byte(m.SignatureAlgorithm), 0x00, 0x00}...)
+ binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(m.Signature)))
+ out = append(out, m.Signature...)
+
+ return out, nil
+}
+
+// Unmarshal populates the message from encoded data
+func (m *MessageServerKeyExchange) Unmarshal(data []byte) error {
+ switch {
+ case len(data) < 2:
+ return errBufferTooSmall
+ case m.KeyExchangeAlgorithm == types.KeyExchangeAlgorithmNone:
+ return errCipherSuiteUnset
+ }
+
+ hintLength := binary.BigEndian.Uint16(data)
+ if int(hintLength) <= len(data)-2 && m.KeyExchangeAlgorithm.Has(types.KeyExchangeAlgorithmPsk) {
+ m.IdentityHint = append([]byte{}, data[2:2+hintLength]...)
+ data = data[2+hintLength:]
+ }
+ if m.KeyExchangeAlgorithm == types.KeyExchangeAlgorithmPsk {
+ if len(data) == 0 {
+ return nil
+ }
+ return errLengthMismatch
+ }
+
+ if !m.KeyExchangeAlgorithm.Has(types.KeyExchangeAlgorithmEcdhe) {
+ return errLengthMismatch
+ }
+
+ if _, ok := elliptic.CurveTypes()[elliptic.CurveType(data[0])]; ok {
+ m.EllipticCurveType = elliptic.CurveType(data[0])
+ } else {
+ return errInvalidEllipticCurveType
+ }
+
+ if len(data[1:]) < 2 {
+ return errBufferTooSmall
+ }
+ m.NamedCurve = elliptic.Curve(binary.BigEndian.Uint16(data[1:3]))
+ if _, ok := elliptic.Curves()[m.NamedCurve]; !ok {
+ return errInvalidNamedCurve
+ }
+ if len(data) < 4 {
+ return errBufferTooSmall
+ }
+
+ publicKeyLength := int(data[3])
+ offset := 4 + publicKeyLength
+ if len(data) < offset {
+ return errBufferTooSmall
+ }
+ m.PublicKey = append([]byte{}, data[4:offset]...)
+
+ // Anon connection doesn't contains hashAlgorithm, signatureAlgorithm, signature
+ if len(data) == offset {
+ return nil
+ } else if len(data) <= offset {
+ return errBufferTooSmall
+ }
+
+ m.HashAlgorithm = hash.Algorithm(data[offset])
+ if _, ok := hash.Algorithms()[m.HashAlgorithm]; !ok {
+ return errInvalidHashAlgorithm
+ }
+ offset++
+ if len(data) <= offset {
+ return errBufferTooSmall
+ }
+ m.SignatureAlgorithm = signature.Algorithm(data[offset])
+ if _, ok := signature.Algorithms()[m.SignatureAlgorithm]; !ok {
+ return errInvalidSignatureAlgorithm
+ }
+ offset++
+ if len(data) < offset+2 {
+ return errBufferTooSmall
+ }
+ signatureLength := int(binary.BigEndian.Uint16(data[offset:]))
+ offset += 2
+ if len(data) < offset+signatureLength {
+ return errBufferTooSmall
+ }
+ m.Signature = append([]byte{}, data[offset:offset+signatureLength]...)
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/random.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/random.go
new file mode 100644
index 0000000..56f3756
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/random.go
@@ -0,0 +1,52 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package handshake
+
+import (
+ "crypto/rand"
+ "encoding/binary"
+ "time"
+)
+
+// Consts for Random in Handshake
+const (
+ RandomBytesLength = 28
+ RandomLength = RandomBytesLength + 4
+)
+
+// Random value that is used in ClientHello and ServerHello
+//
+// https://tools.ietf.org/html/rfc4346#section-7.4.1.2
+type Random struct {
+ GMTUnixTime time.Time
+ RandomBytes [RandomBytesLength]byte
+}
+
+// MarshalFixed encodes the Handshake
+func (r *Random) MarshalFixed() [RandomLength]byte {
+ var out [RandomLength]byte
+
+ binary.BigEndian.PutUint32(out[0:], uint32(r.GMTUnixTime.Unix()))
+ copy(out[4:], r.RandomBytes[:])
+
+ return out
+}
+
+// UnmarshalFixed populates the message from encoded data
+func (r *Random) UnmarshalFixed(data [RandomLength]byte) {
+ r.GMTUnixTime = time.Unix(int64(binary.BigEndian.Uint32(data[0:])), 0)
+ copy(r.RandomBytes[:], data[4:])
+}
+
+// Populate fills the handshakeRandom with random values
+// may be called multiple times
+func (r *Random) Populate() error {
+ r.GMTUnixTime = time.Now()
+
+ tmp := make([]byte, RandomBytesLength)
+ _, err := rand.Read(tmp)
+ copy(r.RandomBytes[:], tmp)
+
+ return err
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/errors.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/errors.go
new file mode 100644
index 0000000..cd4cb60
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/errors.go
@@ -0,0 +1,19 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package recordlayer implements the TLS Record Layer https://tools.ietf.org/html/rfc5246#section-6
+package recordlayer
+
+import (
+ "errors"
+
+ "github.com/pion/dtls/v2/pkg/protocol"
+)
+
+var (
+ errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113
+ errInvalidPacketLength = &protocol.TemporaryError{Err: errors.New("packet length and declared length do not match")} //nolint:goerr113
+ errSequenceNumberOverflow = &protocol.InternalError{Err: errors.New("sequence number overflow")} //nolint:goerr113
+ errUnsupportedProtocolVersion = &protocol.FatalError{Err: errors.New("unsupported protocol version")} //nolint:goerr113
+ errInvalidContentType = &protocol.TemporaryError{Err: errors.New("invalid content type")} //nolint:goerr113
+)
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/header.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/header.go
new file mode 100644
index 0000000..66a1be8
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/header.go
@@ -0,0 +1,85 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package recordlayer
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/internal/util"
+ "github.com/pion/dtls/v2/pkg/protocol"
+)
+
+// Header implements a TLS RecordLayer header
+type Header struct {
+ ContentType protocol.ContentType
+ ContentLen uint16
+ Version protocol.Version
+ Epoch uint16
+ SequenceNumber uint64 // uint48 in spec
+
+ // Optional Fields
+ ConnectionID []byte
+}
+
+// RecordLayer enums
+const (
+ // FixedHeaderSize is the size of a DTLS record header when connection IDs
+ // are not in use.
+ FixedHeaderSize = 13
+ MaxSequenceNumber = 0x0000FFFFFFFFFFFF
+)
+
+// Marshal encodes a TLS RecordLayer Header to binary
+func (h *Header) Marshal() ([]byte, error) {
+ if h.SequenceNumber > MaxSequenceNumber {
+ return nil, errSequenceNumberOverflow
+ }
+
+ hs := FixedHeaderSize + len(h.ConnectionID)
+
+ out := make([]byte, hs)
+ out[0] = byte(h.ContentType)
+ out[1] = h.Version.Major
+ out[2] = h.Version.Minor
+ binary.BigEndian.PutUint16(out[3:], h.Epoch)
+ util.PutBigEndianUint48(out[5:], h.SequenceNumber)
+ copy(out[11:11+len(h.ConnectionID)], h.ConnectionID)
+ binary.BigEndian.PutUint16(out[hs-2:], h.ContentLen)
+ return out, nil
+}
+
+// Unmarshal populates a TLS RecordLayer Header from binary
+func (h *Header) Unmarshal(data []byte) error {
+ if len(data) < FixedHeaderSize {
+ return errBufferTooSmall
+ }
+ h.ContentType = protocol.ContentType(data[0])
+ if h.ContentType == protocol.ContentTypeConnectionID {
+ // If a CID was expected the ConnectionID should have been initialized.
+ if len(data) < FixedHeaderSize+len(h.ConnectionID) {
+ return errBufferTooSmall
+ }
+ h.ConnectionID = data[11 : 11+len(h.ConnectionID)]
+ }
+
+ h.Version.Major = data[1]
+ h.Version.Minor = data[2]
+ h.Epoch = binary.BigEndian.Uint16(data[3:])
+
+ // SequenceNumber is stored as uint48, make into uint64
+ seqCopy := make([]byte, 8)
+ copy(seqCopy[2:], data[5:11])
+ h.SequenceNumber = binary.BigEndian.Uint64(seqCopy)
+
+ if !h.Version.Equal(protocol.Version1_0) && !h.Version.Equal(protocol.Version1_2) {
+ return errUnsupportedProtocolVersion
+ }
+
+ return nil
+}
+
+// Size returns the total size of the header.
+func (h *Header) Size() int {
+ return FixedHeaderSize + len(h.ConnectionID)
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/inner_plaintext.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/inner_plaintext.go
new file mode 100644
index 0000000..bbc94dd
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/inner_plaintext.go
@@ -0,0 +1,47 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package recordlayer
+
+import (
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "golang.org/x/crypto/cryptobyte"
+)
+
+// InnerPlaintext implements DTLSInnerPlaintext
+//
+// https://datatracker.ietf.org/doc/html/rfc9146#name-record-layer-extensions
+type InnerPlaintext struct {
+ Content []byte
+ RealType protocol.ContentType
+ Zeros uint
+}
+
+// Marshal encodes a DTLS InnerPlaintext to binary
+func (p *InnerPlaintext) Marshal() ([]byte, error) {
+ var out cryptobyte.Builder
+ out.AddBytes(p.Content)
+ out.AddUint8(uint8(p.RealType))
+ out.AddBytes(make([]byte, p.Zeros))
+ return out.Bytes()
+}
+
+// Unmarshal populates a DTLS InnerPlaintext from binary
+func (p *InnerPlaintext) Unmarshal(data []byte) error {
+ // Process in reverse
+ i := len(data) - 1
+ for i >= 0 {
+ if data[i] != 0 {
+ p.Zeros = uint(len(data) - 1 - i)
+ break
+ }
+ i--
+ }
+ if i == 0 {
+ return errBufferTooSmall
+ }
+ p.RealType = protocol.ContentType(data[i])
+ p.Content = append([]byte{}, data[:i]...)
+
+ return nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/recordlayer.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/recordlayer.go
new file mode 100644
index 0000000..213a797
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/recordlayer.go
@@ -0,0 +1,145 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package recordlayer
+
+import (
+ "encoding/binary"
+
+ "github.com/pion/dtls/v2/pkg/protocol"
+ "github.com/pion/dtls/v2/pkg/protocol/alert"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+)
+
+// DTLS fixed size record layer header when Connection IDs are not in-use.
+
+// ---------------------------------
+// | Type | Version | Epoch |
+// ---------------------------------
+// | Epoch | Sequence Number |
+// ---------------------------------
+// | Sequence Number | Length |
+// ---------------------------------
+// | Length | Fragment... |
+// ---------------------------------
+
+// fixedHeaderLenIdx is the index at which the record layer content length is
+// specified in a fixed length header (i.e. one that does not include a
+// Connection ID).
+const fixedHeaderLenIdx = 11
+
+// RecordLayer which handles all data transport.
+// The record layer is assumed to sit directly on top of some
+// reliable transport such as TCP. The record layer can carry four types of content:
+//
+// 1. Handshake messages—used for algorithm negotiation and key establishment.
+// 2. ChangeCipherSpec messages—really part of the handshake but technically a separate kind of message.
+// 3. Alert messages—used to signal that errors have occurred
+// 4. Application layer data
+//
+// The DTLS record layer is extremely similar to that of TLS 1.1. The
+// only change is the inclusion of an explicit sequence number in the
+// record. This sequence number allows the recipient to correctly
+// verify the TLS MAC.
+//
+// https://tools.ietf.org/html/rfc4347#section-4.1
+type RecordLayer struct {
+ Header Header
+ Content protocol.Content
+}
+
+// Marshal encodes the RecordLayer to binary
+func (r *RecordLayer) Marshal() ([]byte, error) {
+ contentRaw, err := r.Content.Marshal()
+ if err != nil {
+ return nil, err
+ }
+
+ r.Header.ContentLen = uint16(len(contentRaw))
+ r.Header.ContentType = r.Content.ContentType()
+
+ headerRaw, err := r.Header.Marshal()
+ if err != nil {
+ return nil, err
+ }
+
+ return append(headerRaw, contentRaw...), nil
+}
+
+// Unmarshal populates the RecordLayer from binary
+func (r *RecordLayer) Unmarshal(data []byte) error {
+ if err := r.Header.Unmarshal(data); err != nil {
+ return err
+ }
+
+ switch r.Header.ContentType {
+ case protocol.ContentTypeChangeCipherSpec:
+ r.Content = &protocol.ChangeCipherSpec{}
+ case protocol.ContentTypeAlert:
+ r.Content = &alert.Alert{}
+ case protocol.ContentTypeHandshake:
+ r.Content = &handshake.Handshake{}
+ case protocol.ContentTypeApplicationData:
+ r.Content = &protocol.ApplicationData{}
+ default:
+ return errInvalidContentType
+ }
+
+ return r.Content.Unmarshal(data[r.Header.Size()+len(r.Header.ConnectionID):])
+}
+
+// UnpackDatagram extracts all RecordLayer messages from a single datagram.
+// Note that as with TLS, multiple handshake messages may be placed in
+// the same DTLS record, provided that there is room and that they are
+// part of the same flight. Thus, there are two acceptable ways to pack
+// two DTLS messages into the same datagram: in the same record or in
+// separate records.
+// https://tools.ietf.org/html/rfc6347#section-4.2.3
+func UnpackDatagram(buf []byte) ([][]byte, error) {
+ out := [][]byte{}
+
+ for offset := 0; len(buf) != offset; {
+ if len(buf)-offset <= FixedHeaderSize {
+ return nil, errInvalidPacketLength
+ }
+
+ pktLen := (FixedHeaderSize + int(binary.BigEndian.Uint16(buf[offset+11:])))
+ if offset+pktLen > len(buf) {
+ return nil, errInvalidPacketLength
+ }
+
+ out = append(out, buf[offset:offset+pktLen])
+ offset += pktLen
+ }
+
+ return out, nil
+}
+
+// ContentAwareUnpackDatagram is the same as UnpackDatagram but considers the
+// presence of a connection identifier if the record is of content type
+// tls12_cid.
+func ContentAwareUnpackDatagram(buf []byte, cidLength int) ([][]byte, error) {
+ out := [][]byte{}
+
+ for offset := 0; len(buf) != offset; {
+ headerSize := FixedHeaderSize
+ lenIdx := fixedHeaderLenIdx
+ if protocol.ContentType(buf[offset]) == protocol.ContentTypeConnectionID {
+ headerSize += cidLength
+ lenIdx += cidLength
+ }
+ if len(buf)-offset <= headerSize {
+ return nil, errInvalidPacketLength
+ }
+
+ pktLen := (headerSize + int(binary.BigEndian.Uint16(buf[offset+lenIdx:])))
+ if offset+pktLen > len(buf) {
+ return nil, errInvalidPacketLength
+ }
+
+ out = append(out, buf[offset:offset+pktLen])
+ offset += pktLen
+ }
+
+ return out, nil
+}
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/version.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/version.go
new file mode 100644
index 0000000..c4d94ac
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/version.go
@@ -0,0 +1,24 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package protocol provides the DTLS wire format
+package protocol
+
+// Version enums
+var (
+ Version1_0 = Version{Major: 0xfe, Minor: 0xff} //nolint:gochecknoglobals
+ Version1_2 = Version{Major: 0xfe, Minor: 0xfd} //nolint:gochecknoglobals
+)
+
+// Version is the minor/major value in the RecordLayer
+// and ClientHello/ServerHello
+//
+// https://tools.ietf.org/html/rfc4346#section-6.2.1
+type Version struct {
+ Major, Minor uint8
+}
+
+// Equal determines if two protocol versions are equal
+func (v Version) Equal(x Version) bool {
+ return v.Major == x.Major && v.Minor == x.Minor
+}
diff --git a/vendor/github.com/pion/dtls/v2/prf.go b/vendor/github.com/pion/dtls/v2/prf.go
deleted file mode 100644
index c83d94b..0000000
--- a/vendor/github.com/pion/dtls/v2/prf.go
+++ /dev/null
@@ -1,230 +0,0 @@
-package dtls
-
-import (
- "crypto/elliptic"
- "crypto/hmac"
- "crypto/sha1" // #nosec
- "encoding/binary"
- "fmt"
- "hash"
- "math"
-
- "golang.org/x/crypto/curve25519"
-)
-
-const (
- prfMasterSecretLabel = "master secret"
- prfExtendedMasterSecretLabel = "extended master secret"
- prfKeyExpansionLabel = "key expansion"
- prfVerifyDataClientLabel = "client finished"
- prfVerifyDataServerLabel = "server finished"
-)
-
-type hashFunc func() hash.Hash
-
-type encryptionKeys struct {
- masterSecret []byte
- clientMACKey []byte
- serverMACKey []byte
- clientWriteKey []byte
- serverWriteKey []byte
- clientWriteIV []byte
- serverWriteIV []byte
-}
-
-func (e *encryptionKeys) String() string {
- return fmt.Sprintf(`encryptionKeys:
-- masterSecret: %#v
-- clientMACKey: %#v
-- serverMACKey: %#v
-- clientWriteKey: %#v
-- serverWriteKey: %#v
-- clientWriteIV: %#v
-- serverWriteIV: %#v
-`,
- e.masterSecret,
- e.clientMACKey,
- e.serverMACKey,
- e.clientWriteKey,
- e.serverWriteKey,
- e.clientWriteIV,
- e.serverWriteIV)
-}
-
-// The premaster secret is formed as follows: if the PSK is N octets
-// long, concatenate a uint16 with the value N, N zero octets, a second
-// uint16 with the value N, and the PSK itself.
-//
-// https://tools.ietf.org/html/rfc4279#section-2
-func prfPSKPreMasterSecret(psk []byte) []byte {
- pskLen := uint16(len(psk))
-
- out := append(make([]byte, 2+pskLen+2), psk...)
- binary.BigEndian.PutUint16(out, pskLen)
- binary.BigEndian.PutUint16(out[2+pskLen:], pskLen)
-
- return out
-}
-
-func prfPreMasterSecret(publicKey, privateKey []byte, curve namedCurve) ([]byte, error) {
- switch curve {
- case namedCurveX25519:
- return curve25519.X25519(privateKey, publicKey)
- case namedCurveP256:
- return ellipticCurvePreMasterSecret(publicKey, privateKey, elliptic.P256(), elliptic.P256())
- case namedCurveP384:
- return ellipticCurvePreMasterSecret(publicKey, privateKey, elliptic.P384(), elliptic.P384())
- }
-
- return nil, errInvalidNamedCurve
-}
-
-func ellipticCurvePreMasterSecret(publicKey, privateKey []byte, c1, c2 elliptic.Curve) ([]byte, error) {
- x, y := elliptic.Unmarshal(c1, publicKey)
- if x == nil || y == nil {
- return nil, errInvalidNamedCurve
- }
-
- result, _ := c2.ScalarMult(x, y, privateKey)
- preMasterSecret := make([]byte, (c2.Params().BitSize+7)>>3)
- resultBytes := result.Bytes()
- copy(preMasterSecret[len(preMasterSecret)-len(resultBytes):], resultBytes)
- return preMasterSecret, nil
-}
-
-// This PRF with the SHA-256 hash function is used for all cipher suites
-// defined in this document and in TLS documents published prior to this
-// document when TLS 1.2 is negotiated. New cipher suites MUST explicitly
-// specify a PRF and, in general, SHOULD use the TLS PRF with SHA-256 or a
-// stronger standard hash function.
-//
-// P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
-// HMAC_hash(secret, A(2) + seed) +
-// HMAC_hash(secret, A(3) + seed) + ...
-//
-// A() is defined as:
-//
-// A(0) = seed
-// A(i) = HMAC_hash(secret, A(i-1))
-//
-// P_hash can be iterated as many times as necessary to produce the
-// required quantity of data. For example, if P_SHA256 is being used to
-// create 80 bytes of data, it will have to be iterated three times
-// (through A(3)), creating 96 bytes of output data; the last 16 bytes
-// of the final iteration will then be discarded, leaving 80 bytes of
-// output data.
-//
-// https://tools.ietf.org/html/rfc4346w
-func prfPHash(secret, seed []byte, requestedLength int, h hashFunc) ([]byte, error) {
- hmacSHA256 := func(key, data []byte) ([]byte, error) {
- mac := hmac.New(h, key)
- if _, err := mac.Write(data); err != nil {
- return nil, err
- }
- return mac.Sum(nil), nil
- }
-
- var err error
- lastRound := seed
- out := []byte{}
-
- iterations := int(math.Ceil(float64(requestedLength) / float64(h().Size())))
- for i := 0; i < iterations; i++ {
- lastRound, err = hmacSHA256(secret, lastRound)
- if err != nil {
- return nil, err
- }
- withSecret, err := hmacSHA256(secret, append(lastRound, seed...))
- if err != nil {
- return nil, err
- }
- out = append(out, withSecret...)
- }
-
- return out[:requestedLength], nil
-}
-
-func prfExtendedMasterSecret(preMasterSecret, sessionHash []byte, h hashFunc) ([]byte, error) {
- seed := append([]byte(prfExtendedMasterSecretLabel), sessionHash...)
- return prfPHash(preMasterSecret, seed, 48, h)
-}
-
-func prfMasterSecret(preMasterSecret, clientRandom, serverRandom []byte, h hashFunc) ([]byte, error) {
- seed := append(append([]byte(prfMasterSecretLabel), clientRandom...), serverRandom...)
- return prfPHash(preMasterSecret, seed, 48, h)
-}
-
-func prfEncryptionKeys(masterSecret, clientRandom, serverRandom []byte, prfMacLen, prfKeyLen, prfIvLen int, h hashFunc) (*encryptionKeys, error) {
- seed := append(append([]byte(prfKeyExpansionLabel), serverRandom...), clientRandom...)
- keyMaterial, err := prfPHash(masterSecret, seed, (2*prfMacLen)+(2*prfKeyLen)+(2*prfIvLen), h)
- if err != nil {
- return nil, err
- }
-
- clientMACKey := keyMaterial[:prfMacLen]
- keyMaterial = keyMaterial[prfMacLen:]
-
- serverMACKey := keyMaterial[:prfMacLen]
- keyMaterial = keyMaterial[prfMacLen:]
-
- clientWriteKey := keyMaterial[:prfKeyLen]
- keyMaterial = keyMaterial[prfKeyLen:]
-
- serverWriteKey := keyMaterial[:prfKeyLen]
- keyMaterial = keyMaterial[prfKeyLen:]
-
- clientWriteIV := keyMaterial[:prfIvLen]
- keyMaterial = keyMaterial[prfIvLen:]
-
- serverWriteIV := keyMaterial[:prfIvLen]
-
- return &encryptionKeys{
- masterSecret: masterSecret,
- clientMACKey: clientMACKey,
- serverMACKey: serverMACKey,
- clientWriteKey: clientWriteKey,
- serverWriteKey: serverWriteKey,
- clientWriteIV: clientWriteIV,
- serverWriteIV: serverWriteIV,
- }, nil
-}
-
-func prfVerifyData(masterSecret, handshakeBodies []byte, label string, hashFunc hashFunc) ([]byte, error) {
- h := hashFunc()
- if _, err := h.Write(handshakeBodies); err != nil {
- return nil, err
- }
-
- seed := append([]byte(label), h.Sum(nil)...)
- return prfPHash(masterSecret, seed, 12, hashFunc)
-}
-
-func prfVerifyDataClient(masterSecret, handshakeBodies []byte, h hashFunc) ([]byte, error) {
- return prfVerifyData(masterSecret, handshakeBodies, prfVerifyDataClientLabel, h)
-}
-
-func prfVerifyDataServer(masterSecret, handshakeBodies []byte, h hashFunc) ([]byte, error) {
- return prfVerifyData(masterSecret, handshakeBodies, prfVerifyDataServerLabel, h)
-}
-
-// compute the MAC using HMAC-SHA1
-func prfMac(epoch uint16, sequenceNumber uint64, contentType contentType, protocolVersion protocolVersion, payload []byte, key []byte) ([]byte, error) {
- h := hmac.New(sha1.New, key)
-
- msg := make([]byte, 13)
-
- binary.BigEndian.PutUint16(msg, epoch)
- putBigEndianUint48(msg[2:], sequenceNumber)
- msg[8] = byte(contentType)
- msg[9] = protocolVersion.major
- msg[10] = protocolVersion.minor
- binary.BigEndian.PutUint16(msg[11:], uint16(len(payload)))
-
- if _, err := h.Write(msg); err != nil {
- return nil, err
- } else if _, err := h.Write(payload); err != nil {
- return nil, err
- }
-
- return h.Sum(nil), nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/record_layer.go b/vendor/github.com/pion/dtls/v2/record_layer.go
deleted file mode 100644
index 11f32da..0000000
--- a/vendor/github.com/pion/dtls/v2/record_layer.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-/*
- The TLS Record Layer which handles all data transport.
- The record layer is assumed to sit directly on top of some
- reliable transport such as TCP. The record layer can carry four types of content:
-
- 1. Handshake messages—used for algorithm negotiation and key establishment.
- 2. ChangeCipherSpec messages—really part of the handshake but technically a separate kind of message.
- 3. Alert messages—used to signal that errors have occurred
- 4. Application layer data
-
- The DTLS record layer is extremely similar to that of TLS 1.1. The
- only change is the inclusion of an explicit sequence number in the
- record. This sequence number allows the recipient to correctly
- verify the TLS MAC.
- https://tools.ietf.org/html/rfc4347#section-4.1
-*/
-type recordLayer struct {
- recordLayerHeader recordLayerHeader
- content content
-}
-
-func (r *recordLayer) Marshal() ([]byte, error) {
- contentRaw, err := r.content.Marshal()
- if err != nil {
- return nil, err
- }
-
- r.recordLayerHeader.contentLen = uint16(len(contentRaw))
- r.recordLayerHeader.contentType = r.content.contentType()
-
- headerRaw, err := r.recordLayerHeader.Marshal()
- if err != nil {
- return nil, err
- }
-
- return append(headerRaw, contentRaw...), nil
-}
-
-func (r *recordLayer) Unmarshal(data []byte) error {
- if len(data) < recordLayerHeaderSize {
- return errBufferTooSmall
- }
- if err := r.recordLayerHeader.Unmarshal(data); err != nil {
- return err
- }
-
- switch contentType(data[0]) {
- case contentTypeChangeCipherSpec:
- r.content = &changeCipherSpec{}
- case contentTypeAlert:
- r.content = &alert{}
- case contentTypeHandshake:
- r.content = &handshake{}
- case contentTypeApplicationData:
- r.content = &applicationData{}
- default:
- return errInvalidContentType
- }
-
- return r.content.Unmarshal(data[recordLayerHeaderSize:])
-}
-
-// Note that as with TLS, multiple handshake messages may be placed in
-// the same DTLS record, provided that there is room and that they are
-// part of the same flight. Thus, there are two acceptable ways to pack
-// two DTLS messages into the same datagram: in the same record or in
-// separate records.
-// https://tools.ietf.org/html/rfc6347#section-4.2.3
-func unpackDatagram(buf []byte) ([][]byte, error) {
- out := [][]byte{}
-
- for offset := 0; len(buf) != offset; {
- if len(buf)-offset <= recordLayerHeaderSize {
- return nil, errInvalidPacketLength
- }
-
- pktLen := (recordLayerHeaderSize + int(binary.BigEndian.Uint16(buf[offset+11:])))
- if offset+pktLen > len(buf) {
- return nil, errInvalidPacketLength
- }
-
- out = append(out, buf[offset:offset+pktLen])
- offset += pktLen
- }
-
- return out, nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/record_layer_header.go b/vendor/github.com/pion/dtls/v2/record_layer_header.go
deleted file mode 100644
index 09e9e14..0000000
--- a/vendor/github.com/pion/dtls/v2/record_layer_header.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package dtls
-
-import "encoding/binary"
-
-type recordLayerHeader struct {
- contentType contentType
- contentLen uint16
- protocolVersion protocolVersion
- epoch uint16
- sequenceNumber uint64 // uint48 in spec
-}
-
-const (
- recordLayerHeaderSize = 13
- maxSequenceNumber = 0x0000FFFFFFFFFFFF
-
- dtls1_2Major = 0xfe
- dtls1_2Minor = 0xfd
-
- dtls1_0Major = 0xfe
- dtls1_0Minor = 0xff
-
- // VersionDTLS12 is the DTLS version in the same style as
- // VersionTLSXX from crypto/tls
- VersionDTLS12 = 0xfefd
-)
-
-var protocolVersion1_0 = protocolVersion{dtls1_0Major, dtls1_0Minor}
-var protocolVersion1_2 = protocolVersion{dtls1_2Major, dtls1_2Minor}
-
-// https://tools.ietf.org/html/rfc4346#section-6.2.1
-type protocolVersion struct {
- major, minor uint8
-}
-
-func (v protocolVersion) Equal(x protocolVersion) bool {
- return v.major == x.major && v.minor == x.minor
-}
-
-func (r *recordLayerHeader) Marshal() ([]byte, error) {
- if r.sequenceNumber > maxSequenceNumber {
- return nil, errSequenceNumberOverflow
- }
-
- out := make([]byte, recordLayerHeaderSize)
- out[0] = byte(r.contentType)
- out[1] = r.protocolVersion.major
- out[2] = r.protocolVersion.minor
- binary.BigEndian.PutUint16(out[3:], r.epoch)
- putBigEndianUint48(out[5:], r.sequenceNumber)
- binary.BigEndian.PutUint16(out[recordLayerHeaderSize-2:], r.contentLen)
- return out, nil
-}
-
-func (r *recordLayerHeader) Unmarshal(data []byte) error {
- if len(data) < recordLayerHeaderSize {
- return errBufferTooSmall
- }
- r.contentType = contentType(data[0])
- r.protocolVersion.major = data[1]
- r.protocolVersion.minor = data[2]
- r.epoch = binary.BigEndian.Uint16(data[3:])
-
- // SequenceNumber is stored as uint48, make into uint64
- seqCopy := make([]byte, 8)
- copy(seqCopy[2:], data[5:11])
- r.sequenceNumber = binary.BigEndian.Uint64(seqCopy)
-
- if !r.protocolVersion.Equal(protocolVersion1_0) && !r.protocolVersion.Equal(protocolVersion1_2) {
- return errUnsupportedProtocolVersion
- }
-
- return nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/renovate.json b/vendor/github.com/pion/dtls/v2/renovate.json
index 4400fd9..f1bb98c 100644
--- a/vendor/github.com/pion/dtls/v2/renovate.json
+++ b/vendor/github.com/pion/dtls/v2/renovate.json
@@ -1,15 +1,6 @@
{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
- "config:base"
- ],
- "postUpdateOptions": [
- "gomodTidy"
- ],
- "commitBody": "Generated by renovateBot",
- "packageRules": [
- {
- "packagePatterns": ["^golang.org/x/"],
- "schedule": ["on the first day of the month"]
- }
+ "github>pion/renovate-config"
]
}
diff --git a/vendor/github.com/pion/dtls/v2/resume.go b/vendor/github.com/pion/dtls/v2/resume.go
index 40e55e4..9e8a2ae 100644
--- a/vendor/github.com/pion/dtls/v2/resume.go
+++ b/vendor/github.com/pion/dtls/v2/resume.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
@@ -6,11 +9,11 @@ import (
)
// Resume imports an already established dtls connection using a specific dtls state
-func Resume(state *State, conn net.Conn, config *Config) (*Conn, error) {
+func Resume(state *State, conn net.PacketConn, rAddr net.Addr, config *Config) (*Conn, error) {
if err := state.initCipherSuite(); err != nil {
return nil, err
}
- c, err := createConn(context.Background(), conn, config, state.isClient, state)
+ c, err := createConn(context.Background(), conn, rAddr, config, state.isClient, state)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/pion/dtls/v2/session.go b/vendor/github.com/pion/dtls/v2/session.go
new file mode 100644
index 0000000..99bf5a4
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/session.go
@@ -0,0 +1,24 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package dtls
+
+// Session store data needed in resumption
+type Session struct {
+ // ID store session id
+ ID []byte
+ // Secret store session master secret
+ Secret []byte
+}
+
+// SessionStore defines methods needed for session resumption.
+type SessionStore interface {
+ // Set save a session.
+ // For client, use server name as key.
+ // For server, use session id.
+ Set(key []byte, s Session) error
+ // Get fetch a session.
+ Get(key []byte) (Session, error)
+ // Del clean saved session.
+ Del(key []byte) error
+}
diff --git a/vendor/github.com/pion/dtls/v2/signature_algorithm.go b/vendor/github.com/pion/dtls/v2/signature_algorithm.go
deleted file mode 100644
index f215cfc..0000000
--- a/vendor/github.com/pion/dtls/v2/signature_algorithm.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package dtls
-
-// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-16
-type signatureAlgorithm uint16
-
-const (
- signatureAlgorithmRSA signatureAlgorithm = 1
- signatureAlgorithmECDSA signatureAlgorithm = 3
- signatureAlgorithmEd25519 signatureAlgorithm = 7
-)
-
-var signatureAlgorithms = map[signatureAlgorithm]bool{
- signatureAlgorithmRSA: true,
- signatureAlgorithmECDSA: true,
- signatureAlgorithmEd25519: true,
-}
diff --git a/vendor/github.com/pion/dtls/v2/signature_hash_algorithm.go b/vendor/github.com/pion/dtls/v2/signature_hash_algorithm.go
deleted file mode 100644
index c01caed..0000000
--- a/vendor/github.com/pion/dtls/v2/signature_hash_algorithm.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package dtls
-
-import (
- "crypto"
- "crypto/ecdsa"
- "crypto/ed25519"
- "crypto/rsa"
- "crypto/tls"
-
- "golang.org/x/xerrors"
-)
-
-type signatureHashAlgorithm struct {
- hash hashAlgorithm
- signature signatureAlgorithm
-}
-
-func defaultSignatureSchemes() []signatureHashAlgorithm {
- return []signatureHashAlgorithm{
- {hashAlgorithmSHA256, signatureAlgorithmECDSA},
- {hashAlgorithmSHA384, signatureAlgorithmECDSA},
- {hashAlgorithmSHA512, signatureAlgorithmECDSA},
- {hashAlgorithmSHA256, signatureAlgorithmRSA},
- {hashAlgorithmSHA384, signatureAlgorithmRSA},
- {hashAlgorithmSHA512, signatureAlgorithmRSA},
- {hashAlgorithmEd25519, signatureAlgorithmEd25519},
- }
-}
-
-// select Signature Scheme returns most preferred and compatible scheme.
-func selectSignatureScheme(sigs []signatureHashAlgorithm, privateKey crypto.PrivateKey) (signatureHashAlgorithm, error) {
- for _, ss := range sigs {
- if ss.isCompatible(privateKey) {
- return ss, nil
- }
- }
- return signatureHashAlgorithm{}, errNoAvailableSignatureSchemes
-}
-
-// isCompatible checks that given private key is compatible with the signature scheme.
-func (s *signatureHashAlgorithm) isCompatible(privateKey crypto.PrivateKey) bool {
- switch privateKey.(type) {
- case ed25519.PrivateKey:
- return s.signature == signatureAlgorithmEd25519
- case *ecdsa.PrivateKey:
- return s.signature == signatureAlgorithmECDSA
- case *rsa.PrivateKey:
- return s.signature == signatureAlgorithmRSA
- default:
- return false
- }
-}
-
-// parseSignatureSchemes translates []tls.SignatureScheme to []signatureHashAlgorithm.
-// It returns default signature scheme list if no SignatureScheme is passed.
-func parseSignatureSchemes(sigs []tls.SignatureScheme, insecureHashes bool) ([]signatureHashAlgorithm, error) {
- if len(sigs) == 0 {
- return defaultSignatureSchemes(), nil
- }
- out := []signatureHashAlgorithm{}
- for _, ss := range sigs {
- sig := signatureAlgorithm(ss & 0xFF)
- if _, ok := signatureAlgorithms[sig]; !ok {
- return nil, &FatalError{
- xerrors.Errorf("SignatureScheme %04x: %w", ss, errInvalidSignatureAlgorithm),
- }
- }
- h := hashAlgorithm(ss >> 8)
- if _, ok := hashAlgorithms[h]; !ok {
- return nil, &FatalError{
- xerrors.Errorf("SignatureScheme %04x: %w", ss, errInvalidHashAlgorithm),
- }
- }
- if h.insecure() && !insecureHashes {
- continue
- }
- out = append(out, signatureHashAlgorithm{
- hash: h,
- signature: sig,
- })
- }
-
- if len(out) == 0 {
- return nil, errNoAvailableSignatureSchemes
- }
-
- return out, nil
-}
diff --git a/vendor/github.com/pion/dtls/v2/srtp_protection_profile.go b/vendor/github.com/pion/dtls/v2/srtp_protection_profile.go
index 3ae3c28..e306e9e 100644
--- a/vendor/github.com/pion/dtls/v2/srtp_protection_profile.go
+++ b/vendor/github.com/pion/dtls/v2/srtp_protection_profile.go
@@ -1,13 +1,17 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
+import "github.com/pion/dtls/v2/pkg/protocol/extension"
+
// SRTPProtectionProfile defines the parameters and options that are in effect for the SRTP processing
// https://tools.ietf.org/html/rfc5764#section-4.1.2
-type SRTPProtectionProfile uint16
+type SRTPProtectionProfile = extension.SRTPProtectionProfile
const (
- SRTP_AES128_CM_HMAC_SHA1_80 SRTPProtectionProfile = 0x0001 // nolint
+ SRTP_AES128_CM_HMAC_SHA1_80 SRTPProtectionProfile = extension.SRTP_AES128_CM_HMAC_SHA1_80 // nolint:revive,stylecheck
+ SRTP_AES128_CM_HMAC_SHA1_32 SRTPProtectionProfile = extension.SRTP_AES128_CM_HMAC_SHA1_32 // nolint:revive,stylecheck
+ SRTP_AEAD_AES_128_GCM SRTPProtectionProfile = extension.SRTP_AEAD_AES_128_GCM // nolint:revive,stylecheck
+ SRTP_AEAD_AES_256_GCM SRTPProtectionProfile = extension.SRTP_AEAD_AES_256_GCM // nolint:revive,stylecheck
)
-
-var srtpProtectionProfiles = map[SRTPProtectionProfile]bool{
- SRTP_AES128_CM_HMAC_SHA1_80: true,
-}
diff --git a/vendor/github.com/pion/dtls/v2/state.go b/vendor/github.com/pion/dtls/v2/state.go
index 7c15dcc..cd69455 100644
--- a/vendor/github.com/pion/dtls/v2/state.go
+++ b/vendor/github.com/pion/dtls/v2/state.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package dtls
import (
@@ -5,27 +8,46 @@ import (
"encoding/gob"
"sync/atomic"
- "github.com/pion/transport/replaydetector"
+ "github.com/pion/dtls/v2/pkg/crypto/elliptic"
+ "github.com/pion/dtls/v2/pkg/crypto/prf"
+ "github.com/pion/dtls/v2/pkg/protocol/handshake"
+ "github.com/pion/transport/v3/replaydetector"
)
// State holds the dtls connection state and implements both encoding.BinaryMarshaler and encoding.BinaryUnmarshaler
type State struct {
localEpoch, remoteEpoch atomic.Value
localSequenceNumber []uint64 // uint48
- localRandom, remoteRandom handshakeRandom
+ localRandom, remoteRandom handshake.Random
masterSecret []byte
- cipherSuite cipherSuite // nil if a cipherSuite hasn't been chosen
+ cipherSuite CipherSuite // nil if a cipherSuite hasn't been chosen
srtpProtectionProfile SRTPProtectionProfile // Negotiated SRTPProtectionProfile
PeerCertificates [][]byte
+ IdentityHint []byte
+ SessionID []byte
+
+ // Connection Identifiers must be negotiated afresh on session resumption.
+ // https://datatracker.ietf.org/doc/html/rfc9146#name-the-connection_id-extension
+
+ // localConnectionID is the locally generated connection ID that is expected
+ // to be received from the remote endpoint.
+ // For a server, this is the connection ID sent in ServerHello.
+ // For a client, this is the connection ID sent in the ClientHello.
+ localConnectionID []byte
+ // remoteConnectionID is the connection ID that the remote endpoint
+ // specifies should be sent.
+ // For a server, this is the connection ID received in the ClientHello.
+ // For a client, this is the connection ID received in the ServerHello.
+ remoteConnectionID []byte
isClient bool
preMasterSecret []byte
extendedMasterSecret bool
- namedCurve namedCurve
- localKeypair *namedCurveKeypair
+ namedCurve elliptic.Curve
+ localKeypair *elliptic.Keypair
cookie []byte
handshakeSendSequence int
handshakeRecvSequence int
@@ -37,18 +59,25 @@ type State struct {
peerCertificatesVerified bool
replayDetector []replaydetector.ReplayDetector
+
+ peerSupportedProtocols []string
+ NegotiatedProtocol string
}
type serializedState struct {
LocalEpoch uint16
RemoteEpoch uint16
- LocalRandom [handshakeRandomLength]byte
- RemoteRandom [handshakeRandomLength]byte
+ LocalRandom [handshake.RandomLength]byte
+ RemoteRandom [handshake.RandomLength]byte
CipherSuiteID uint16
MasterSecret []byte
SequenceNumber uint64
SRTPProtectionProfile uint16
PeerCertificates [][]byte
+ IdentityHint []byte
+ SessionID []byte
+ LocalConnectionID []byte
+ RemoteConnectionID []byte
IsClient bool
}
@@ -62,13 +91,13 @@ func (s *State) clone() *State {
func (s *State) serialize() *serializedState {
// Marshal random values
- localRnd := s.localRandom.marshalFixed()
- remoteRnd := s.remoteRandom.marshalFixed()
+ localRnd := s.localRandom.MarshalFixed()
+ remoteRnd := s.remoteRandom.MarshalFixed()
- epoch := s.localEpoch.Load().(uint16)
+ epoch := s.getLocalEpoch()
return &serializedState{
- LocalEpoch: epoch,
- RemoteEpoch: s.remoteEpoch.Load().(uint16),
+ LocalEpoch: s.getLocalEpoch(),
+ RemoteEpoch: s.getRemoteEpoch(),
CipherSuiteID: uint16(s.cipherSuite.ID()),
MasterSecret: s.masterSecret,
SequenceNumber: atomic.LoadUint64(&s.localSequenceNumber[epoch]),
@@ -76,6 +105,10 @@ func (s *State) serialize() *serializedState {
RemoteRandom: remoteRnd,
SRTPProtectionProfile: uint16(s.srtpProtectionProfile),
PeerCertificates: s.PeerCertificates,
+ IdentityHint: s.IdentityHint,
+ SessionID: s.SessionID,
+ LocalConnectionID: s.localConnectionID,
+ RemoteConnectionID: s.remoteConnectionID,
IsClient: s.isClient,
}
}
@@ -91,12 +124,12 @@ func (s *State) deserialize(serialized serializedState) {
}
// Set random values
- localRandom := &handshakeRandom{}
- localRandom.unmarshalFixed(serialized.LocalRandom)
+ localRandom := &handshake.Random{}
+ localRandom.UnmarshalFixed(serialized.LocalRandom)
s.localRandom = *localRandom
- remoteRandom := &handshakeRandom{}
- remoteRandom.unmarshalFixed(serialized.RemoteRandom)
+ remoteRandom := &handshake.Random{}
+ remoteRandom.UnmarshalFixed(serialized.RemoteRandom)
s.remoteRandom = *remoteRandom
s.isClient = serialized.IsClient
@@ -105,28 +138,36 @@ func (s *State) deserialize(serialized serializedState) {
s.masterSecret = serialized.MasterSecret
// Set cipher suite
- s.cipherSuite = cipherSuiteForID(CipherSuiteID(serialized.CipherSuiteID))
+ s.cipherSuite = cipherSuiteForID(CipherSuiteID(serialized.CipherSuiteID), nil)
atomic.StoreUint64(&s.localSequenceNumber[epoch], serialized.SequenceNumber)
s.srtpProtectionProfile = SRTPProtectionProfile(serialized.SRTPProtectionProfile)
// Set remote certificate
s.PeerCertificates = serialized.PeerCertificates
+
+ s.IdentityHint = serialized.IdentityHint
+
+ // Set local and remote connection IDs
+ s.localConnectionID = serialized.LocalConnectionID
+ s.remoteConnectionID = serialized.RemoteConnectionID
+
+ s.SessionID = serialized.SessionID
}
func (s *State) initCipherSuite() error {
- if s.cipherSuite.isInitialized() {
+ if s.cipherSuite.IsInitialized() {
return nil
}
- localRandom := s.localRandom.marshalFixed()
- remoteRandom := s.remoteRandom.marshalFixed()
+ localRandom := s.localRandom.MarshalFixed()
+ remoteRandom := s.remoteRandom.MarshalFixed()
var err error
if s.isClient {
- err = s.cipherSuite.init(s.masterSecret, localRandom[:], remoteRandom[:], true)
+ err = s.cipherSuite.Init(s.masterSecret, localRandom[:], remoteRandom[:], true)
} else {
- err = s.cipherSuite.init(s.masterSecret, remoteRandom[:], localRandom[:], false)
+ err = s.cipherSuite.Init(s.masterSecret, remoteRandom[:], localRandom[:], false)
}
if err != nil {
return err
@@ -155,10 +196,8 @@ func (s *State) UnmarshalBinary(data []byte) error {
}
s.deserialize(serialized)
- if err := s.initCipherSuite(); err != nil {
- return err
- }
- return nil
+
+ return s.initCipherSuite()
}
// ExportKeyingMaterial returns length bytes of exported key material in a new
@@ -166,16 +205,16 @@ func (s *State) UnmarshalBinary(data []byte) error {
// This allows protocols to use DTLS for key establishment, but
// then use some of the keying material for their own purposes
func (s *State) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
- if s.localEpoch.Load().(uint16) == 0 {
+ if s.getLocalEpoch() == 0 {
return nil, errHandshakeInProgress
} else if len(context) != 0 {
return nil, errContextUnsupported
- } else if _, ok := invalidKeyingLabels[label]; ok {
+ } else if _, ok := invalidKeyingLabels()[label]; ok {
return nil, errReservedExportKeyingMaterial
}
- localRandom := s.localRandom.marshalFixed()
- remoteRandom := s.remoteRandom.marshalFixed()
+ localRandom := s.localRandom.MarshalFixed()
+ remoteRandom := s.remoteRandom.MarshalFixed()
seed := []byte(label)
if s.isClient {
@@ -183,5 +222,19 @@ func (s *State) ExportKeyingMaterial(label string, context []byte, length int) (
} else {
seed = append(append(seed, remoteRandom[:]...), localRandom[:]...)
}
- return prfPHash(s.masterSecret, seed, length, s.cipherSuite.hashFunc())
+ return prf.PHash(s.masterSecret, seed, length, s.cipherSuite.HashFunc())
+}
+
+func (s *State) getRemoteEpoch() uint16 {
+ if remoteEpoch, ok := s.remoteEpoch.Load().(uint16); ok {
+ return remoteEpoch
+ }
+ return 0
+}
+
+func (s *State) getLocalEpoch() uint16 {
+ if localEpoch, ok := s.localEpoch.Load().(uint16); ok {
+ return localEpoch
+ }
+ return 0
}
diff --git a/vendor/github.com/pion/dtls/v2/util.go b/vendor/github.com/pion/dtls/v2/util.go
index 09de441..663c443 100644
--- a/vendor/github.com/pion/dtls/v2/util.go
+++ b/vendor/github.com/pion/dtls/v2/util.go
@@ -1,80 +1,7 @@
-package dtls
-
-import (
- "encoding/binary"
-)
-
-// Parse a big endian uint24
-func bigEndianUint24(raw []byte) uint32 {
- if len(raw) < 3 {
- return 0
- }
-
- rawCopy := make([]byte, 4)
- copy(rawCopy[1:], raw)
- return binary.BigEndian.Uint32(rawCopy)
-}
-
-func putBigEndianUint24(out []byte, in uint32) {
- tmp := make([]byte, 4)
- binary.BigEndian.PutUint32(tmp, in)
- copy(out, tmp[1:])
-}
-
-func putBigEndianUint48(out []byte, in uint64) {
- tmp := make([]byte, 8)
- binary.BigEndian.PutUint64(tmp, in)
- copy(out, tmp[2:])
-}
-
-func max(a, b int) int {
- if a > b {
- return a
- }
- return b
-}
-
-// examinePadding returns, in constant time, the length of the padding to remove
-// from the end of payload. It also returns a byte which is equal to 255 if the
-// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2.
-//
-// https://github.com/golang/go/blob/039c2081d1178f90a8fa2f4e6958693129f8de33/src/crypto/tls/conn.go#L245
-func examinePadding(payload []byte) (toRemove int, good byte) {
- if len(payload) < 1 {
- return 0, 0
- }
-
- paddingLen := payload[len(payload)-1]
- t := uint(len(payload)-1) - uint(paddingLen)
- // if len(payload) >= (paddingLen - 1) then the MSB of t is zero
- good = byte(int32(^t) >> 31)
-
- // The maximum possible padding length plus the actual length field
- toCheck := 256
- // The length of the padded data is public, so we can use an if here
- if toCheck > len(payload) {
- toCheck = len(payload)
- }
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
- for i := 0; i < toCheck; i++ {
- t := uint(paddingLen) - uint(i)
- // if i <= paddingLen then the MSB of t is zero
- mask := byte(int32(^t) >> 31)
- b := payload[len(payload)-1-i]
- good &^= mask&paddingLen ^ mask&b
- }
-
- // We AND together the bits of good and replicate the result across
- // all the bits.
- good &= good << 4
- good &= good << 2
- good &= good << 1
- good = uint8(int8(good) >> 7)
-
- toRemove = int(paddingLen) + 1
-
- return toRemove, good
-}
+package dtls
func findMatchingSRTPProfile(a, b []SRTPProtectionProfile) (SRTPProtectionProfile, bool) {
for _, aProfile := range a {
@@ -87,7 +14,7 @@ func findMatchingSRTPProfile(a, b []SRTPProtectionProfile) (SRTPProtectionProfil
return 0, false
}
-func findMatchingCipherSuite(a, b []cipherSuite) (cipherSuite, bool) {
+func findMatchingCipherSuite(a, b []CipherSuite) (CipherSuite, bool) {
for _, aSuite := range a {
for _, bSuite := range b {
if aSuite.ID() == bSuite.ID() {
diff --git a/vendor/github.com/pion/logging/go.mod b/vendor/github.com/pion/logging/go.mod
deleted file mode 100644
index a1b849b..0000000
--- a/vendor/github.com/pion/logging/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module github.com/pion/logging
-
-go 1.12
diff --git a/vendor/github.com/pion/logging/go.sum b/vendor/github.com/pion/logging/go.sum
deleted file mode 100644
index e69de29..0000000
diff --git a/vendor/github.com/pion/transport/LICENSE b/vendor/github.com/pion/transport/LICENSE
deleted file mode 100644
index ab60297..0000000
--- a/vendor/github.com/pion/transport/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2018
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/vendor/github.com/pion/transport/packetio/buffer.go b/vendor/github.com/pion/transport/packetio/buffer.go
deleted file mode 100644
index 4acd0cd..0000000
--- a/vendor/github.com/pion/transport/packetio/buffer.go
+++ /dev/null
@@ -1,217 +0,0 @@
-// Package packetio provides packet buffer
-package packetio
-
-import (
- "io"
- "sync"
- "time"
-
- "github.com/pion/transport/deadline"
-)
-
-// Buffer allows writing packets to an intermediate buffer, which can then be read form.
-// This is verify similar to bytes.Buffer but avoids combining multiple writes into a single read.
-type Buffer struct {
- mutex sync.Mutex
- packets [][]byte
-
- notify chan struct{}
- subs bool
- closed bool
-
- // The number of buffered packets in bytes.
- size int
-
- // The limit on Write in packet count and total size.
- limitCount int
- limitSize int
-
- // Read deadline timer.
- readDeadline *deadline.Deadline
-}
-
-// NewBuffer creates a new Buffer object.
-func NewBuffer() *Buffer {
- return &Buffer{
- notify: make(chan struct{}),
- readDeadline: deadline.New(),
- }
-}
-
-// Write appends a copy of the packet data to the buffer.
-// If any defined limits are hit, returns ErrFull.
-func (b *Buffer) Write(packet []byte) (n int, err error) {
- // Copy the packet before adding it.
- packet = append([]byte{}, packet...)
-
- b.mutex.Lock()
-
- // Make sure we're not closed.
- if b.closed {
- b.mutex.Unlock()
- return 0, io.ErrClosedPipe
- }
-
- // Check if there is available capacity
- if b.limitCount != 0 && len(b.packets)+1 > b.limitCount {
- b.mutex.Unlock()
- return 0, ErrFull
- }
-
- // Check if there is available capacity
- if b.limitSize != 0 && b.size+len(packet) > b.limitSize {
- b.mutex.Unlock()
- return 0, ErrFull
- }
-
- var notify chan struct{}
-
- // Decide if we need to wake up any readers.
- if b.subs {
- // If so, close the notify channel and make a new one.
- // This effectively behaves like a broadcast, waking up any blocked goroutines.
- // We close after we release the lock to reduce contention.
- notify = b.notify
- b.notify = make(chan struct{})
-
- // Reset the subs marker.
- b.subs = false
- }
-
- // Add the packet to the queue.
- b.packets = append(b.packets, packet)
- b.size += len(packet)
- b.mutex.Unlock()
-
- // Actually close the notify channel down here.
- if notify != nil {
- close(notify)
- }
-
- return len(packet), nil
-}
-
-// Read populates the given byte slice, returning the number of bytes read.
-// Blocks until data is available or the buffer is closed.
-// Returns io.ErrShortBuffer is the packet is too small to copy the Write.
-// Returns io.EOF if the buffer is closed.
-func (b *Buffer) Read(packet []byte) (n int, err error) {
- // Return immediately if the deadline is already exceeded.
- select {
- case <-b.readDeadline.Done():
- return 0, &netError{errTimeout, true, true}
- default:
- }
-
- for {
- b.mutex.Lock()
-
- // See if there are any packets in the queue.
- if len(b.packets) > 0 {
- first := b.packets[0]
-
- // This is a packet-based reader/writer so we can't truncate.
- if len(first) > len(packet) {
- b.mutex.Unlock()
- return 0, io.ErrShortBuffer
- }
-
- // Remove our packet and continue.
- b.packets = b.packets[1:]
- b.size -= len(first)
-
- b.mutex.Unlock()
-
- // Actually transfer the data.
- n := copy(packet, first)
- return n, nil
- }
-
- // Make sure the reader isn't actually closed.
- // This is done after checking packets to fully read the buffer.
- if b.closed {
- b.mutex.Unlock()
- return 0, io.EOF
- }
-
- // Get the current notify channel.
- // This will be closed when there is new data available, waking us up.
- notify := b.notify
-
- // Set the subs marker, telling the writer we're waiting.
- b.subs = true
- b.mutex.Unlock()
-
- // Wake for the broadcast.
- select {
- case <-b.readDeadline.Done():
- return 0, &netError{errTimeout, true, true}
- case <-notify:
- }
- }
-}
-
-// Close will unblock any readers and prevent future writes.
-// Data in the buffer can still be read, returning io.EOF when fully depleted.
-func (b *Buffer) Close() (err error) {
- // note: We don't use defer so we can close the notify channel after unlocking.
- // This will unblock goroutines that can grab the lock immediately, instead of blocking again.
- b.mutex.Lock()
-
- if b.closed {
- b.mutex.Unlock()
- return nil
- }
-
- notify := b.notify
-
- b.closed = true
- b.mutex.Unlock()
-
- close(notify)
-
- return nil
-}
-
-// Count returns the number of packets in the buffer.
-func (b *Buffer) Count() int {
- b.mutex.Lock()
- defer b.mutex.Unlock()
-
- return len(b.packets)
-}
-
-// SetLimitCount controls the maximum number of packets that can be buffered.
-// Causes Write to return ErrFull when this limit is reached.
-// A zero value will disable this limit.
-func (b *Buffer) SetLimitCount(limit int) {
- b.mutex.Lock()
- defer b.mutex.Unlock()
-
- b.limitCount = limit
-}
-
-// Size returns the total byte size of packets in the buffer.
-func (b *Buffer) Size() int {
- b.mutex.Lock()
- defer b.mutex.Unlock()
-
- return b.size
-}
-
-// SetLimitSize controls the maximum number of bytes that can be buffered.
-// Causes Write to return ErrFull when this limit is reached.
-// A zero value will disable this limit.
-func (b *Buffer) SetLimitSize(limit int) {
- b.mutex.Lock()
- defer b.mutex.Unlock()
-
- b.limitSize = limit
-}
-
-// SetReadDeadline sets deadline of Read operation.
-// Setting zero means no deadline.
-func (b *Buffer) SetReadDeadline(t time.Time) error {
- b.readDeadline.Set(t)
- return nil
-}
diff --git a/vendor/github.com/pion/transport/packetio/errors.go b/vendor/github.com/pion/transport/packetio/errors.go
deleted file mode 100644
index a61bbb2..0000000
--- a/vendor/github.com/pion/transport/packetio/errors.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package packetio
-
-import (
- "errors"
-)
-
-// netError implements net.Error
-type netError struct {
- error
- timeout, temporary bool
-}
-
-func (e *netError) Timeout() bool {
- return e.timeout
-}
-
-func (e *netError) Temporary() bool {
- return e.temporary
-}
-
-// ErrFull is returned when the buffer has hit the configured limits.
-var ErrFull = errors.New("packetio.Buffer is full, discarding write")
-
-var errTimeout = errors.New("i/o timeout")
diff --git a/vendor/github.com/pion/transport/v3/AUTHORS.txt b/vendor/github.com/pion/transport/v3/AUTHORS.txt
new file mode 100644
index 0000000..278ce64
--- /dev/null
+++ b/vendor/github.com/pion/transport/v3/AUTHORS.txt
@@ -0,0 +1,31 @@
+# Thank you to everyone that made Pion possible. If you are interested in contributing
+# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
+#
+# This file is auto generated, using git to list all individuals contributors.
+# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting
+Adrian Cable
+Atsushi Watanabe
+backkem
+cnderrauber
+Daniel
+Daniel Mangum
+Hugo Arregui
+Jeremiah Millay
+Jozef Kralik
+Juliusz Chroboczek
+Luke Curley
+Mathis Engelbart
+OrlandoCo
+Sean DuBois
+Sean DuBois
+Sean DuBois
+Sean DuBois
+Sean DuBois
+Steffen Vogel
+Winlin
+Woodrow Douglass
+Yutaka Takeda
+ZHENK
+
+# List of contributors not appearing in Git history
+
diff --git a/vendor/github.com/pion/transport/v3/LICENSE b/vendor/github.com/pion/transport/v3/LICENSE
new file mode 100644
index 0000000..491caf6
--- /dev/null
+++ b/vendor/github.com/pion/transport/v3/LICENSE
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) 2023 The Pion community
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/pion/transport/deadline/deadline.go b/vendor/github.com/pion/transport/v3/deadline/deadline.go
similarity index 90%
rename from vendor/github.com/pion/transport/deadline/deadline.go
rename to vendor/github.com/pion/transport/v3/deadline/deadline.go
index 6f97386..abd39f0 100644
--- a/vendor/github.com/pion/transport/deadline/deadline.go
+++ b/vendor/github.com/pion/transport/v3/deadline/deadline.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
// Package deadline provides deadline timer used to implement
// net.Conn compatible connection
package deadline
@@ -59,11 +62,15 @@ func (d *Deadline) Set(t time.Time) {
exceeded := d.exceeded
stopped := d.stopped
go func() {
+ timer := time.NewTimer(dur)
select {
- case <-time.After(dur):
+ case <-timer.C:
close(exceeded)
stopped <- false
case <-d.stop:
+ if !timer.Stop() {
+ <-timer.C
+ }
stopped <- true
}
}()
diff --git a/vendor/github.com/pion/dtls/v2/internal/net/connctx/connctx.go b/vendor/github.com/pion/transport/v3/netctx/conn.go
similarity index 50%
rename from vendor/github.com/pion/dtls/v2/internal/net/connctx/connctx.go
rename to vendor/github.com/pion/transport/v3/netctx/conn.go
index 3948994..823107c 100644
--- a/vendor/github.com/pion/dtls/v2/internal/net/connctx/connctx.go
+++ b/vendor/github.com/pion/transport/v3/netctx/conn.go
@@ -1,5 +1,8 @@
-// Package connctx wraps net.Conn using context.Context.
-package connctx
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package netctx wraps common net interfaces using context.Context.
+package netctx
import (
"context"
@@ -14,17 +17,33 @@ import (
// ErrClosing is returned on Write to closed connection.
var ErrClosing = errors.New("use of closed network connection")
-// ConnCtx is a wrapper of net.Conn using context.Context.
-type ConnCtx interface {
- Read(context.Context, []byte) (int, error)
- Write(context.Context, []byte) (int, error)
- Close() error
+// Reader is an interface for context controlled reader.
+type Reader interface {
+ ReadContext(context.Context, []byte) (int, error)
+}
+
+// Writer is an interface for context controlled writer.
+type Writer interface {
+ WriteContext(context.Context, []byte) (int, error)
+}
+
+// ReadWriter is a composite of ReadWriter.
+type ReadWriter interface {
+ Reader
+ Writer
+}
+
+// Conn is a wrapper of net.Conn using context.Context.
+type Conn interface {
+ Reader
+ Writer
+ io.Closer
LocalAddr() net.Addr
RemoteAddr() net.Addr
Conn() net.Conn
}
-type connCtx struct {
+type conn struct {
nextConn net.Conn
closed chan struct{}
closeOnce sync.Once
@@ -32,24 +51,26 @@ type connCtx struct {
writeMu sync.Mutex
}
-var veryOld = time.Unix(0, 1)
+var veryOld = time.Unix(0, 1) //nolint:gochecknoglobals
-// New creates a new ConnCtx wrapping given net.Conn.
-func New(conn net.Conn) ConnCtx {
- c := &connCtx{
- nextConn: conn,
+// NewConn creates a new Conn wrapping given net.Conn.
+func NewConn(netConn net.Conn) Conn {
+ c := &conn{
+ nextConn: netConn,
closed: make(chan struct{}),
}
return c
}
-func (c *connCtx) Read(ctx context.Context, b []byte) (int, error) {
+// ReadContext reads data from the connection.
+// Unlike net.Conn.Read(), the provided context is used to control timeout.
+func (c *conn) ReadContext(ctx context.Context, b []byte) (int, error) {
c.readMu.Lock()
defer c.readMu.Unlock()
select {
case <-c.closed:
- return 0, io.EOF
+ return 0, net.ErrClosed
default:
}
@@ -81,13 +102,15 @@ func (c *connCtx) Read(ctx context.Context, b []byte) (int, error) {
if e := ctx.Err(); e != nil && n == 0 {
err = e
}
- if err2 := errSetDeadline.Load(); err == nil && err2 != nil {
- err = err2.(error)
+ if err2, ok := errSetDeadline.Load().(error); ok && err == nil && err2 != nil {
+ err = err2
}
return n, err
}
-func (c *connCtx) Write(ctx context.Context, b []byte) (int, error) {
+// WriteContext writes data to the connection.
+// Unlike net.Conn.Write(), the provided context is used to control timeout.
+func (c *conn) WriteContext(ctx context.Context, b []byte) (int, error) {
c.writeMu.Lock()
defer c.writeMu.Unlock()
@@ -102,6 +125,7 @@ func (c *connCtx) Write(ctx context.Context, b []byte) (int, error) {
var errSetDeadline atomic.Value
wg.Add(1)
go func() {
+ defer wg.Done()
select {
case <-ctx.Done():
// context canceled
@@ -115,7 +139,6 @@ func (c *connCtx) Write(ctx context.Context, b []byte) (int, error) {
}
case <-done:
}
- wg.Done()
}()
n, err := c.nextConn.Write(b)
@@ -125,13 +148,16 @@ func (c *connCtx) Write(ctx context.Context, b []byte) (int, error) {
if e := ctx.Err(); e != nil && n == 0 {
err = e
}
- if err2 := errSetDeadline.Load(); err == nil && err2 != nil {
- err = err2.(error)
+ if err2, ok := errSetDeadline.Load().(error); ok && err == nil && err2 != nil {
+ err = err2
}
return n, err
}
-func (c *connCtx) Close() error {
+// Close closes the connection.
+// Any blocked ReadContext or WriteContext operations will be unblocked and
+// return errors.
+func (c *conn) Close() error {
err := c.nextConn.Close()
c.closeOnce.Do(func() {
c.writeMu.Lock()
@@ -143,14 +169,17 @@ func (c *connCtx) Close() error {
return err
}
-func (c *connCtx) LocalAddr() net.Addr {
+// LocalAddr returns the local network address, if known.
+func (c *conn) LocalAddr() net.Addr {
return c.nextConn.LocalAddr()
}
-func (c *connCtx) RemoteAddr() net.Addr {
+// LocalAddr returns the local network address, if known.
+func (c *conn) RemoteAddr() net.Addr {
return c.nextConn.RemoteAddr()
}
-func (c *connCtx) Conn() net.Conn {
+// Conn returns the underlying net.Conn.
+func (c *conn) Conn() net.Conn {
return c.nextConn
}
diff --git a/vendor/github.com/pion/transport/v3/netctx/packetconn.go b/vendor/github.com/pion/transport/v3/netctx/packetconn.go
new file mode 100644
index 0000000..a4ce22d
--- /dev/null
+++ b/vendor/github.com/pion/transport/v3/netctx/packetconn.go
@@ -0,0 +1,175 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package netctx
+
+import (
+ "context"
+ "io"
+ "net"
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+// ReaderFrom is an interface for context controlled packet reader.
+type ReaderFrom interface {
+ ReadFromContext(context.Context, []byte) (int, net.Addr, error)
+}
+
+// WriterTo is an interface for context controlled packet writer.
+type WriterTo interface {
+ WriteToContext(context.Context, []byte, net.Addr) (int, error)
+}
+
+// PacketConn is a wrapper of net.PacketConn using context.Context.
+type PacketConn interface {
+ ReaderFrom
+ WriterTo
+ io.Closer
+ LocalAddr() net.Addr
+ Conn() net.PacketConn
+}
+
+type packetConn struct {
+ nextConn net.PacketConn
+ closed chan struct{}
+ closeOnce sync.Once
+ readMu sync.Mutex
+ writeMu sync.Mutex
+}
+
+// NewPacketConn creates a new PacketConn wrapping the given net.PacketConn.
+func NewPacketConn(pconn net.PacketConn) PacketConn {
+ p := &packetConn{
+ nextConn: pconn,
+ closed: make(chan struct{}),
+ }
+ return p
+}
+
+// ReadFromContext reads a packet from the connection,
+// copying the payload into p. It returns the number of
+// bytes copied into p and the return address that
+// was on the packet.
+// It returns the number of bytes read (0 <= n <= len(p))
+// and any error encountered. Callers should always process
+// the n > 0 bytes returned before considering the error err.
+// Unlike net.PacketConn.ReadFrom(), the provided context is
+// used to control timeout.
+func (p *packetConn) ReadFromContext(ctx context.Context, b []byte) (int, net.Addr, error) {
+ p.readMu.Lock()
+ defer p.readMu.Unlock()
+
+ select {
+ case <-p.closed:
+ return 0, nil, net.ErrClosed
+ default:
+ }
+
+ done := make(chan struct{})
+ var wg sync.WaitGroup
+ var errSetDeadline atomic.Value
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ select {
+ case <-ctx.Done():
+ // context canceled
+ if err := p.nextConn.SetReadDeadline(veryOld); err != nil {
+ errSetDeadline.Store(err)
+ return
+ }
+ <-done
+ if err := p.nextConn.SetReadDeadline(time.Time{}); err != nil {
+ errSetDeadline.Store(err)
+ }
+ case <-done:
+ }
+ }()
+
+ n, raddr, err := p.nextConn.ReadFrom(b)
+
+ close(done)
+ wg.Wait()
+ if e := ctx.Err(); e != nil && n == 0 {
+ err = e
+ }
+ if err2, ok := errSetDeadline.Load().(error); ok && err == nil && err2 != nil {
+ err = err2
+ }
+ return n, raddr, err
+}
+
+// WriteToContext writes a packet with payload p to addr.
+// Unlike net.PacketConn.WriteTo(), the provided context
+// is used to control timeout.
+// On packet-oriented connections, write timeouts are rare.
+func (p *packetConn) WriteToContext(ctx context.Context, b []byte, raddr net.Addr) (int, error) {
+ p.writeMu.Lock()
+ defer p.writeMu.Unlock()
+
+ select {
+ case <-p.closed:
+ return 0, ErrClosing
+ default:
+ }
+
+ done := make(chan struct{})
+ var wg sync.WaitGroup
+ var errSetDeadline atomic.Value
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ select {
+ case <-ctx.Done():
+ // context canceled
+ if err := p.nextConn.SetWriteDeadline(veryOld); err != nil {
+ errSetDeadline.Store(err)
+ return
+ }
+ <-done
+ if err := p.nextConn.SetWriteDeadline(time.Time{}); err != nil {
+ errSetDeadline.Store(err)
+ }
+ case <-done:
+ }
+ }()
+
+ n, err := p.nextConn.WriteTo(b, raddr)
+
+ close(done)
+ wg.Wait()
+ if e := ctx.Err(); e != nil && n == 0 {
+ err = e
+ }
+ if err2, ok := errSetDeadline.Load().(error); ok && err == nil && err2 != nil {
+ err = err2
+ }
+ return n, err
+}
+
+// Close closes the connection.
+// Any blocked ReadFromContext or WriteToContext operations will be unblocked
+// and return errors.
+func (p *packetConn) Close() error {
+ err := p.nextConn.Close()
+ p.closeOnce.Do(func() {
+ p.writeMu.Lock()
+ p.readMu.Lock()
+ close(p.closed)
+ p.readMu.Unlock()
+ p.writeMu.Unlock()
+ })
+ return err
+}
+
+// LocalAddr returns the local network address, if known.
+func (p *packetConn) LocalAddr() net.Addr {
+ return p.nextConn.LocalAddr()
+}
+
+// Conn returns the underlying net.PacketConn.
+func (p *packetConn) Conn() net.PacketConn {
+ return p.nextConn
+}
diff --git a/vendor/github.com/pion/transport/v3/netctx/pipe.go b/vendor/github.com/pion/transport/v3/netctx/pipe.go
new file mode 100644
index 0000000..7deae66
--- /dev/null
+++ b/vendor/github.com/pion/transport/v3/netctx/pipe.go
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package netctx
+
+import (
+ "net"
+)
+
+// Pipe creates piped pair of Conn.
+func Pipe() (Conn, Conn) {
+ ca, cb := net.Pipe()
+ return NewConn(ca), NewConn(cb)
+}
diff --git a/vendor/github.com/pion/transport/v3/packetio/buffer.go b/vendor/github.com/pion/transport/v3/packetio/buffer.go
new file mode 100644
index 0000000..76c7273
--- /dev/null
+++ b/vendor/github.com/pion/transport/v3/packetio/buffer.go
@@ -0,0 +1,351 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+// Package packetio provides packet buffer
+package packetio
+
+import (
+ "errors"
+ "io"
+ "sync"
+ "time"
+
+ "github.com/pion/transport/v3/deadline"
+)
+
+var errPacketTooBig = errors.New("packet too big")
+
+// BufferPacketType allow the Buffer to know which packet protocol is writing.
+type BufferPacketType int
+
+const (
+ // RTPBufferPacket indicates the Buffer that is handling RTP packets
+ RTPBufferPacket BufferPacketType = 1
+ // RTCPBufferPacket indicates the Buffer that is handling RTCP packets
+ RTCPBufferPacket BufferPacketType = 2
+)
+
+// Buffer allows writing packets to an intermediate buffer, which can then be read form.
+// This is verify similar to bytes.Buffer but avoids combining multiple writes into a single read.
+type Buffer struct {
+ mutex sync.Mutex
+
+ // this is a circular buffer. If head <= tail, then the useful
+ // data is in the interval [head, tail[. If tail < head, then
+ // the useful data is the union of [head, len[ and [0, tail[.
+ // In order to avoid ambiguity when head = tail, we always leave
+ // an unused byte in the buffer.
+ data []byte
+ head, tail int
+
+ notify chan struct{} // non-nil when we have blocked readers
+ closed bool
+
+ count int
+ limitCount, limitSize int
+
+ readDeadline *deadline.Deadline
+}
+
+const (
+ minSize = 2048
+ cutoffSize = 128 * 1024
+ maxSize = 4 * 1024 * 1024
+)
+
+// NewBuffer creates a new Buffer.
+func NewBuffer() *Buffer {
+ return &Buffer{
+ readDeadline: deadline.New(),
+ }
+}
+
+// available returns true if the buffer is large enough to fit a packet
+// of the given size, taking overhead into account.
+func (b *Buffer) available(size int) bool {
+ available := b.head - b.tail
+ if available <= 0 {
+ available += len(b.data)
+ }
+ // we interpret head=tail as empty, so always keep a byte free
+ if size+2+1 > available {
+ return false
+ }
+
+ return true
+}
+
+// grow increases the size of the buffer. If it returns nil, then the
+// buffer has been grown. It returns ErrFull if hits a limit.
+func (b *Buffer) grow() error {
+ var newSize int
+ if len(b.data) < cutoffSize {
+ newSize = 2 * len(b.data)
+ } else {
+ newSize = 5 * len(b.data) / 4
+ }
+ if newSize < minSize {
+ newSize = minSize
+ }
+ if (b.limitSize <= 0 || sizeHardLimit) && newSize > maxSize {
+ newSize = maxSize
+ }
+
+ // one byte slack
+ if b.limitSize > 0 && newSize > b.limitSize+1 {
+ newSize = b.limitSize + 1
+ }
+
+ if newSize <= len(b.data) {
+ return ErrFull
+ }
+
+ newData := make([]byte, newSize)
+
+ var n int
+ if b.head <= b.tail {
+ // data was contiguous
+ n = copy(newData, b.data[b.head:b.tail])
+ } else {
+ // data was discontinuous
+ n = copy(newData, b.data[b.head:])
+ n += copy(newData[n:], b.data[:b.tail])
+ }
+ b.head = 0
+ b.tail = n
+ b.data = newData
+
+ return nil
+}
+
+// Write appends a copy of the packet data to the buffer.
+// Returns ErrFull if the packet doesn't fit.
+//
+// Note that the packet size is limited to 65536 bytes since v0.11.0 due to the internal data structure.
+func (b *Buffer) Write(packet []byte) (int, error) {
+ if len(packet) >= 0x10000 {
+ return 0, errPacketTooBig
+ }
+
+ b.mutex.Lock()
+
+ if b.closed {
+ b.mutex.Unlock()
+ return 0, io.ErrClosedPipe
+ }
+
+ if (b.limitCount > 0 && b.count >= b.limitCount) ||
+ (b.limitSize > 0 && b.size()+2+len(packet) > b.limitSize) {
+ b.mutex.Unlock()
+ return 0, ErrFull
+ }
+
+ // grow the buffer until the packet fits
+ for !b.available(len(packet)) {
+ err := b.grow()
+ if err != nil {
+ b.mutex.Unlock()
+ return 0, err
+ }
+ }
+
+ var notify chan struct{}
+ if b.notify != nil {
+ // Prepare to notify readers, but only
+ // actually do it after we release the lock.
+ notify = b.notify
+ b.notify = nil
+ }
+
+ // store the length of the packet
+ b.data[b.tail] = uint8(len(packet) >> 8)
+ b.tail++
+ if b.tail >= len(b.data) {
+ b.tail = 0
+ }
+ b.data[b.tail] = uint8(len(packet))
+ b.tail++
+ if b.tail >= len(b.data) {
+ b.tail = 0
+ }
+
+ // store the packet
+ n := copy(b.data[b.tail:], packet)
+ b.tail += n
+ if b.tail >= len(b.data) {
+ // we reached the end, wrap around
+ m := copy(b.data, packet[n:])
+ b.tail = m
+ }
+ b.count++
+ b.mutex.Unlock()
+
+ if notify != nil {
+ close(notify)
+ }
+
+ return len(packet), nil
+}
+
+// Read populates the given byte slice, returning the number of bytes read.
+// Blocks until data is available or the buffer is closed.
+// Returns io.ErrShortBuffer is the packet is too small to copy the Write.
+// Returns io.EOF if the buffer is closed.
+func (b *Buffer) Read(packet []byte) (n int, err error) { //nolint:gocognit
+ // Return immediately if the deadline is already exceeded.
+ select {
+ case <-b.readDeadline.Done():
+ return 0, &netError{ErrTimeout, true, true}
+ default:
+ }
+
+ for {
+ b.mutex.Lock()
+
+ if b.head != b.tail {
+ // decode the packet size
+ n1 := b.data[b.head]
+ b.head++
+ if b.head >= len(b.data) {
+ b.head = 0
+ }
+ n2 := b.data[b.head]
+ b.head++
+ if b.head >= len(b.data) {
+ b.head = 0
+ }
+ count := int((uint16(n1) << 8) | uint16(n2))
+
+ // determine the number of bytes we'll actually copy
+ copied := count
+ if copied > len(packet) {
+ copied = len(packet)
+ }
+
+ // copy the data
+ if b.head+copied < len(b.data) {
+ copy(packet, b.data[b.head:b.head+copied])
+ } else {
+ k := copy(packet, b.data[b.head:])
+ copy(packet[k:], b.data[:copied-k])
+ }
+
+ // advance head, discarding any data that wasn't copied
+ b.head += count
+ if b.head >= len(b.data) {
+ b.head -= len(b.data)
+ }
+
+ if b.head == b.tail {
+ // the buffer is empty, reset to beginning
+ // in order to improve cache locality.
+ b.head = 0
+ b.tail = 0
+ }
+
+ b.count--
+
+ b.mutex.Unlock()
+
+ if copied < count {
+ return copied, io.ErrShortBuffer
+ }
+ return copied, nil
+ }
+
+ if b.closed {
+ b.mutex.Unlock()
+ return 0, io.EOF
+ }
+
+ if b.notify == nil {
+ b.notify = make(chan struct{})
+ }
+ notify := b.notify
+ b.mutex.Unlock()
+
+ select {
+ case <-b.readDeadline.Done():
+ return 0, &netError{ErrTimeout, true, true}
+ case <-notify:
+ }
+ }
+}
+
+// Close the buffer, unblocking any pending reads.
+// Data in the buffer can still be read, Read will return io.EOF only when empty.
+func (b *Buffer) Close() (err error) {
+ b.mutex.Lock()
+
+ if b.closed {
+ b.mutex.Unlock()
+ return nil
+ }
+
+ notify := b.notify
+ b.notify = nil
+ b.closed = true
+
+ b.mutex.Unlock()
+
+ if notify != nil {
+ close(notify)
+ }
+
+ return nil
+}
+
+// Count returns the number of packets in the buffer.
+func (b *Buffer) Count() int {
+ b.mutex.Lock()
+ defer b.mutex.Unlock()
+ return b.count
+}
+
+// SetLimitCount controls the maximum number of packets that can be buffered.
+// Causes Write to return ErrFull when this limit is reached.
+// A zero value will disable this limit.
+func (b *Buffer) SetLimitCount(limit int) {
+ b.mutex.Lock()
+ defer b.mutex.Unlock()
+
+ b.limitCount = limit
+}
+
+// Size returns the total byte size of packets in the buffer, including
+// a small amount of administrative overhead.
+func (b *Buffer) Size() int {
+ b.mutex.Lock()
+ defer b.mutex.Unlock()
+
+ return b.size()
+}
+
+func (b *Buffer) size() int {
+ size := b.tail - b.head
+ if size < 0 {
+ size += len(b.data)
+ }
+ return size
+}
+
+// SetLimitSize controls the maximum number of bytes that can be buffered.
+// Causes Write to return ErrFull when this limit is reached.
+// A zero value means 4MB since v0.11.0.
+//
+// User can set packetioSizeHardLimit build tag to enable 4MB hard limit.
+// When packetioSizeHardLimit build tag is set, SetLimitSize exceeding
+// the hard limit will be silently discarded.
+func (b *Buffer) SetLimitSize(limit int) {
+ b.mutex.Lock()
+ defer b.mutex.Unlock()
+
+ b.limitSize = limit
+}
+
+// SetReadDeadline sets the deadline for the Read operation.
+// Setting to zero means no deadline.
+func (b *Buffer) SetReadDeadline(t time.Time) error {
+ b.readDeadline.Set(t)
+ return nil
+}
diff --git a/vendor/github.com/pion/transport/v3/packetio/errors.go b/vendor/github.com/pion/transport/v3/packetio/errors.go
new file mode 100644
index 0000000..4974a10
--- /dev/null
+++ b/vendor/github.com/pion/transport/v3/packetio/errors.go
@@ -0,0 +1,30 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package packetio
+
+import (
+ "errors"
+)
+
+// netError implements net.Error
+type netError struct {
+ error
+ timeout, temporary bool
+}
+
+func (e *netError) Timeout() bool {
+ return e.timeout
+}
+
+func (e *netError) Temporary() bool {
+ return e.temporary
+}
+
+var (
+ // ErrFull is returned when the buffer has hit the configured limits.
+ ErrFull = errors.New("packetio.Buffer is full, discarding write")
+
+ // ErrTimeout is returned when a deadline has expired
+ ErrTimeout = errors.New("i/o timeout")
+)
diff --git a/vendor/github.com/pion/transport/v3/packetio/hardlimit.go b/vendor/github.com/pion/transport/v3/packetio/hardlimit.go
new file mode 100644
index 0000000..8058e47
--- /dev/null
+++ b/vendor/github.com/pion/transport/v3/packetio/hardlimit.go
@@ -0,0 +1,9 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+//go:build packetioSizeHardlimit
+// +build packetioSizeHardlimit
+
+package packetio
+
+const sizeHardLimit = true
diff --git a/vendor/github.com/pion/transport/v3/packetio/no_hardlimit.go b/vendor/github.com/pion/transport/v3/packetio/no_hardlimit.go
new file mode 100644
index 0000000..a59e259
--- /dev/null
+++ b/vendor/github.com/pion/transport/v3/packetio/no_hardlimit.go
@@ -0,0 +1,9 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+//go:build !packetioSizeHardlimit
+// +build !packetioSizeHardlimit
+
+package packetio
+
+const sizeHardLimit = false
diff --git a/vendor/github.com/pion/transport/replaydetector/fixedbig.go b/vendor/github.com/pion/transport/v3/replaydetector/fixedbig.go
similarity index 93%
rename from vendor/github.com/pion/transport/replaydetector/fixedbig.go
rename to vendor/github.com/pion/transport/v3/replaydetector/fixedbig.go
index a571a1a..80cb6b3 100644
--- a/vendor/github.com/pion/transport/replaydetector/fixedbig.go
+++ b/vendor/github.com/pion/transport/v3/replaydetector/fixedbig.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
package replaydetector
import (
diff --git a/vendor/github.com/pion/transport/replaydetector/replaydetector.go b/vendor/github.com/pion/transport/v3/replaydetector/replaydetector.go
similarity index 72%
rename from vendor/github.com/pion/transport/replaydetector/replaydetector.go
rename to vendor/github.com/pion/transport/v3/replaydetector/replaydetector.go
index d942002..d407995 100644
--- a/vendor/github.com/pion/transport/replaydetector/replaydetector.go
+++ b/vendor/github.com/pion/transport/v3/replaydetector/replaydetector.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
// Package replaydetector provides packet replay detection algorithm.
package replaydetector
@@ -5,7 +8,14 @@ package replaydetector
type ReplayDetector interface {
// Check returns true if given sequence number is not replayed.
// Call accept() to mark the packet is received properly.
- Check(seq uint64) (accept func(), ok bool)
+ // The return value of accept() indicates whether the accepted packet is
+ // has the latest observed sequence number.
+ Check(seq uint64) (accept func() bool, ok bool)
+}
+
+// nop is a no-op func that is returned in the case that Check() fails.
+func nop() bool {
+ return false
}
type slidingWindowDetector struct {
@@ -27,35 +37,38 @@ func New(windowSize uint, maxSeq uint64) ReplayDetector {
}
}
-func (d *slidingWindowDetector) Check(seq uint64) (accept func(), ok bool) {
+func (d *slidingWindowDetector) Check(seq uint64) (func() bool, bool) {
if seq > d.maxSeq {
// Exceeded upper limit.
- return func() {}, false
+ return nop, false
}
if seq <= d.latestSeq {
if d.latestSeq >= uint64(d.windowSize)+seq {
- return func() {}, false
+ return nop, false
}
if d.mask.Bit(uint(d.latestSeq-seq)) != 0 {
// The sequence number is duplicated.
- return func() {}, false
+ return nop, false
}
}
- return func() {
+ return func() bool {
+ latest := seq == 0
if seq > d.latestSeq {
// Update the head of the window.
d.mask.Lsh(uint(seq - d.latestSeq))
d.latestSeq = seq
+ latest = true
}
diff := (d.latestSeq - seq) % d.maxSeq
d.mask.SetBit(uint(diff))
+ return latest
}, true
}
// WithWrap creates ReplayDetector allowing sequence wrapping.
-// This is suitable for short bitwidth counter like SRTP and SRTCP.
+// This is suitable for short bit width counter like SRTP and SRTCP.
func WithWrap(windowSize uint, maxSeq uint64) ReplayDetector {
return &wrappedSlidingWindowDetector{
maxSeq: maxSeq,
@@ -72,10 +85,10 @@ type wrappedSlidingWindowDetector struct {
init bool
}
-func (d *wrappedSlidingWindowDetector) Check(seq uint64) (accept func(), ok bool) {
+func (d *wrappedSlidingWindowDetector) Check(seq uint64) (func() bool, bool) {
if seq > d.maxSeq {
// Exceeded upper limit.
- return func() {}, false
+ return nop, false
}
if !d.init {
if seq != 0 {
@@ -96,21 +109,24 @@ func (d *wrappedSlidingWindowDetector) Check(seq uint64) (accept func(), ok bool
if diff >= int64(d.windowSize) {
// Too old.
- return func() {}, false
+ return nop, false
}
if diff >= 0 {
if d.mask.Bit(uint(diff)) != 0 {
// The sequence number is duplicated.
- return func() {}, false
+ return nop, false
}
}
- return func() {
+ return func() bool {
+ latest := false
if diff < 0 {
// Update the head of the window.
d.mask.Lsh(uint(-diff))
d.latestSeq = seq
+ latest = true
}
d.mask.SetBit(uint(d.latestSeq - seq))
+ return latest
}, true
}
diff --git a/vendor/github.com/pion/transport/v3/udp/batchconn.go b/vendor/github.com/pion/transport/v3/udp/batchconn.go
new file mode 100644
index 0000000..54bdab6
--- /dev/null
+++ b/vendor/github.com/pion/transport/v3/udp/batchconn.go
@@ -0,0 +1,170 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
+package udp
+
+import (
+ "io"
+ "net"
+ "runtime"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
+)
+
+// BatchWriter represents conn can write messages in batch
+type BatchWriter interface {
+ WriteBatch(ms []ipv4.Message, flags int) (int, error)
+}
+
+// BatchReader represents conn can read messages in batch
+type BatchReader interface {
+ ReadBatch(msg []ipv4.Message, flags int) (int, error)
+}
+
+// BatchPacketConn represents conn can read/write messages in batch
+type BatchPacketConn interface {
+ BatchWriter
+ BatchReader
+ io.Closer
+}
+
+// BatchConn uses ipv4/v6.NewPacketConn to wrap a net.PacketConn to write/read messages in batch,
+// only available in linux. In other platform, it will use single Write/Read as same as net.Conn.
+type BatchConn struct {
+ net.PacketConn
+
+ batchConn BatchPacketConn
+
+ batchWriteMutex sync.Mutex
+ batchWriteMessages []ipv4.Message
+ batchWritePos int
+ batchWriteLast time.Time
+
+ batchWriteSize int
+ batchWriteInterval time.Duration
+
+ closed int32
+}
+
+// NewBatchConn creates a *BatchConn from net.PacketConn with batch configs.
+func NewBatchConn(conn net.PacketConn, batchWriteSize int, batchWriteInterval time.Duration) *BatchConn {
+ bc := &BatchConn{
+ PacketConn: conn,
+ batchWriteLast: time.Now(),
+ batchWriteInterval: batchWriteInterval,
+ batchWriteSize: batchWriteSize,
+ batchWriteMessages: make([]ipv4.Message, batchWriteSize),
+ }
+ for i := range bc.batchWriteMessages {
+ bc.batchWriteMessages[i].Buffers = [][]byte{make([]byte, sendMTU)}
+ }
+
+ // batch write only supports linux
+ if runtime.GOOS == "linux" {
+ if pc4 := ipv4.NewPacketConn(conn); pc4 != nil {
+ bc.batchConn = pc4
+ } else if pc6 := ipv6.NewPacketConn(conn); pc6 != nil {
+ bc.batchConn = pc6
+ }
+ }
+
+ if bc.batchConn != nil {
+ go func() {
+ writeTicker := time.NewTicker(batchWriteInterval / 2)
+ defer writeTicker.Stop()
+ for atomic.LoadInt32(&bc.closed) != 1 {
+ <-writeTicker.C
+ bc.batchWriteMutex.Lock()
+ if bc.batchWritePos > 0 && time.Since(bc.batchWriteLast) >= bc.batchWriteInterval {
+ _ = bc.flush()
+ }
+ bc.batchWriteMutex.Unlock()
+ }
+ }()
+ }
+
+ return bc
+}
+
+// Close batchConn and the underlying PacketConn
+func (c *BatchConn) Close() error {
+ atomic.StoreInt32(&c.closed, 1)
+ c.batchWriteMutex.Lock()
+ if c.batchWritePos > 0 {
+ _ = c.flush()
+ }
+ c.batchWriteMutex.Unlock()
+ if c.batchConn != nil {
+ return c.batchConn.Close()
+ }
+ return c.PacketConn.Close()
+}
+
+// WriteTo write message to an UDPAddr, addr should be nil if it is a connected socket.
+func (c *BatchConn) WriteTo(b []byte, addr net.Addr) (int, error) {
+ if c.batchConn == nil {
+ return c.PacketConn.WriteTo(b, addr)
+ }
+ return c.enqueueMessage(b, addr)
+}
+
+func (c *BatchConn) enqueueMessage(buf []byte, raddr net.Addr) (int, error) {
+ var err error
+ c.batchWriteMutex.Lock()
+ defer c.batchWriteMutex.Unlock()
+
+ msg := &c.batchWriteMessages[c.batchWritePos]
+ // reset buffers
+ msg.Buffers = msg.Buffers[:1]
+ msg.Buffers[0] = msg.Buffers[0][:cap(msg.Buffers[0])]
+
+ c.batchWritePos++
+ if raddr != nil {
+ msg.Addr = raddr
+ }
+ if n := copy(msg.Buffers[0], buf); n < len(buf) {
+ extraBuffer := make([]byte, len(buf)-n)
+ copy(extraBuffer, buf[n:])
+ msg.Buffers = append(msg.Buffers, extraBuffer)
+ } else {
+ msg.Buffers[0] = msg.Buffers[0][:n]
+ }
+ if c.batchWritePos == c.batchWriteSize {
+ err = c.flush()
+ }
+ return len(buf), err
+}
+
+// ReadBatch reads messages in batch, return length of message readed and error.
+func (c *BatchConn) ReadBatch(msgs []ipv4.Message, flags int) (int, error) {
+ if c.batchConn == nil {
+ n, addr, err := c.PacketConn.ReadFrom(msgs[0].Buffers[0])
+ if err == nil {
+ msgs[0].N = n
+ msgs[0].Addr = addr
+ return 1, nil
+ }
+ return 0, err
+ }
+ return c.batchConn.ReadBatch(msgs, flags)
+}
+
+func (c *BatchConn) flush() error {
+ var writeErr error
+ var txN int
+ for txN < c.batchWritePos {
+ n, err := c.batchConn.WriteBatch(c.batchWriteMessages[txN:c.batchWritePos], 0)
+ if err != nil {
+ writeErr = err
+ break
+ }
+ txN += n
+ }
+ c.batchWritePos = 0
+ c.batchWriteLast = time.Now()
+ return writeErr
+}
diff --git a/vendor/github.com/pion/dtls/v2/internal/net/udp/conn.go b/vendor/github.com/pion/transport/v3/udp/conn.go
similarity index 54%
rename from vendor/github.com/pion/dtls/v2/internal/net/udp/conn.go
rename to vendor/github.com/pion/transport/v3/udp/conn.go
index 7e3ab40..071b30e 100644
--- a/vendor/github.com/pion/dtls/v2/internal/net/udp/conn.go
+++ b/vendor/github.com/pion/transport/v3/udp/conn.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community
+// SPDX-License-Identifier: MIT
+
// Package udp provides a connection-oriented listener over a UDP PacketConn
package udp
@@ -9,31 +12,45 @@ import (
"sync/atomic"
"time"
- "github.com/pion/transport/deadline"
- "github.com/pion/transport/packetio"
+ "github.com/pion/transport/v3/deadline"
+ "github.com/pion/transport/v3/packetio"
+ "golang.org/x/net/ipv4"
)
-const receiveMTU = 8192
-const defaultListenBacklog = 128 // same as Linux default
+const (
+ receiveMTU = 8192
+ sendMTU = 1500
+ defaultListenBacklog = 128 // same as Linux default
+)
-var errClosedListener = errors.New("udp: listener closed")
-var errListenQueueExceeded = errors.New("udp: listen queue exceeded")
+// Typed errors
+var (
+ ErrClosedListener = errors.New("udp: listener closed")
+ ErrListenQueueExceeded = errors.New("udp: listen queue exceeded")
+ ErrInvalidBatchConfig = errors.New("udp: invalid batch config")
+)
// listener augments a connection-oriented Listener over a UDP PacketConn
type listener struct {
- pConn *net.UDPConn
+ pConn net.PacketConn
- accepting atomic.Value // bool
- acceptCh chan *Conn
- doneCh chan struct{}
- doneOnce sync.Once
+ readBatchSize int
+
+ accepting atomic.Value // bool
+ acceptCh chan *Conn
+ doneCh chan struct{}
+ doneOnce sync.Once
+ acceptFilter func([]byte) bool
connLock sync.Mutex
conns map[string]*Conn
- connWG sync.WaitGroup
+ connWG *sync.WaitGroup
readWG sync.WaitGroup
errClose atomic.Value // error
+
+ readDoneCh chan struct{}
+ errRead atomic.Value // error
}
// Accept waits for and returns the next connection to the listener.
@@ -43,8 +60,12 @@ func (l *listener) Accept() (net.Conn, error) {
l.connWG.Add(1)
return c, nil
+ case <-l.readDoneCh:
+ err, _ := l.errRead.Load().(error)
+ return nil, err
+
case <-l.doneCh:
- return nil, errClosedListener
+ return nil, ErrClosedListener
}
}
@@ -58,7 +79,7 @@ func (l *listener) Close() error {
l.connLock.Lock()
// Close unaccepted connections
- L_CLOSE:
+ lclose:
for {
select {
case c := <-l.acceptCh:
@@ -66,7 +87,7 @@ func (l *listener) Close() error {
delete(l.conns, c.rAddr.String())
default:
- break L_CLOSE
+ break lclose
}
}
nConns := len(l.conns)
@@ -93,6 +114,20 @@ func (l *listener) Addr() net.Addr {
return l.pConn.LocalAddr()
}
+// BatchIOConfig indicates config to batch read/write packets,
+// it will use ReadBatch/WriteBatch to improve throughput for UDP.
+type BatchIOConfig struct {
+ Enable bool
+ // ReadBatchSize indicates the maximum number of packets to be read in one batch, a batch size less than 2 means
+ // disable read batch.
+ ReadBatchSize int
+ // WriteBatchSize indicates the maximum number of packets to be written in one batch
+ WriteBatchSize int
+ // WriteBatchInterval indicates the maximum interval to wait before writing packets in one batch
+ // small interval will reduce latency/jitter, but increase the io count.
+ WriteBatchInterval time.Duration
+}
+
// ListenConfig stores options for listening to an address.
type ListenConfig struct {
// Backlog defines the maximum length of the queue of pending
@@ -102,6 +137,20 @@ type ListenConfig struct {
// the request will be silently discarded, unlike TCP.
// Set zero to use default value 128 which is same as Linux default.
Backlog int
+
+ // AcceptFilter determines whether the new conn should be made for
+ // the incoming packet. If not set, any packet creates new conn.
+ AcceptFilter func([]byte) bool
+
+ // ReadBufferSize sets the size of the operating system's
+ // receive buffer associated with the listener.
+ ReadBufferSize int
+
+ // WriteBufferSize sets the size of the operating system's
+ // send buffer associated with the connection.
+ WriteBufferSize int
+
+ Batch BatchIOConfig
}
// Listen creates a new listener based on the ListenConfig.
@@ -110,17 +159,37 @@ func (lc *ListenConfig) Listen(network string, laddr *net.UDPAddr) (net.Listener
lc.Backlog = defaultListenBacklog
}
+ if lc.Batch.Enable && (lc.Batch.WriteBatchSize <= 0 || lc.Batch.WriteBatchInterval <= 0) {
+ return nil, ErrInvalidBatchConfig
+ }
+
conn, err := net.ListenUDP(network, laddr)
if err != nil {
return nil, err
}
+ if lc.ReadBufferSize > 0 {
+ _ = conn.SetReadBuffer(lc.ReadBufferSize)
+ }
+ if lc.WriteBufferSize > 0 {
+ _ = conn.SetWriteBuffer(lc.WriteBufferSize)
+ }
+
l := &listener{
- pConn: conn,
- acceptCh: make(chan *Conn, lc.Backlog),
- conns: make(map[string]*Conn),
- doneCh: make(chan struct{}),
+ pConn: conn,
+ acceptCh: make(chan *Conn, lc.Backlog),
+ conns: make(map[string]*Conn),
+ doneCh: make(chan struct{}),
+ acceptFilter: lc.AcceptFilter,
+ connWG: &sync.WaitGroup{},
+ readDoneCh: make(chan struct{}),
+ }
+
+ if lc.Batch.Enable {
+ l.pConn = NewBatchConn(conn, lc.Batch.WriteBatchSize, lc.Batch.WriteBatchInterval)
+ l.readBatchSize = lc.Batch.ReadBatchSize
}
+
l.accepting.Store(true)
l.connWG.Add(1)
l.readWG.Add(2) // wait readLoop and Close execution routine
@@ -142,51 +211,84 @@ func Listen(network string, laddr *net.UDPAddr) (net.Listener, error) {
return (&ListenConfig{}).Listen(network, laddr)
}
-var readBufferPool = &sync.Pool{
- New: func() interface{} {
- buf := make([]byte, receiveMTU)
- return &buf
- },
-}
-
// readLoop has to tasks:
-// 1. Dispatching incoming packets to the correct Conn.
-// It can therefore not be ended until all Conns are closed.
-// 2. Creating a new Conn when receiving from a new remote.
+// 1. Dispatching incoming packets to the correct Conn.
+// It can therefore not be ended until all Conns are closed.
+// 2. Creating a new Conn when receiving from a new remote.
func (l *listener) readLoop() {
defer l.readWG.Done()
+ defer close(l.readDoneCh)
+
+ if br, ok := l.pConn.(BatchReader); ok && l.readBatchSize > 1 {
+ l.readBatch(br)
+ } else {
+ l.read()
+ }
+}
+func (l *listener) readBatch(br BatchReader) {
+ msgs := make([]ipv4.Message, l.readBatchSize)
+ for i := range msgs {
+ msg := &msgs[i]
+ msg.Buffers = [][]byte{make([]byte, receiveMTU)}
+ msg.OOB = make([]byte, 40)
+ }
for {
- buf := *(readBufferPool.Get().(*[]byte))
- n, raddr, err := l.pConn.ReadFrom(buf)
+ n, err := br.ReadBatch(msgs, 0)
if err != nil {
+ l.errRead.Store(err)
return
}
- conn, err := l.getConn(raddr)
+ for i := 0; i < n; i++ {
+ l.dispatchMsg(msgs[i].Addr, msgs[i].Buffers[0][:msgs[i].N])
+ }
+ }
+}
+
+func (l *listener) read() {
+ buf := make([]byte, receiveMTU)
+ for {
+ n, raddr, err := l.pConn.ReadFrom(buf)
if err != nil {
- continue
+ l.errRead.Store(err)
+ return
}
- _, _ = conn.buffer.Write(buf[:n])
+ l.dispatchMsg(raddr, buf[:n])
}
}
-func (l *listener) getConn(raddr net.Addr) (*Conn, error) {
+func (l *listener) dispatchMsg(addr net.Addr, buf []byte) {
+ conn, ok, err := l.getConn(addr, buf)
+ if err != nil {
+ return
+ }
+ if ok {
+ _, _ = conn.buffer.Write(buf)
+ }
+}
+
+func (l *listener) getConn(raddr net.Addr, buf []byte) (*Conn, bool, error) {
l.connLock.Lock()
defer l.connLock.Unlock()
conn, ok := l.conns[raddr.String()]
if !ok {
- if !l.accepting.Load().(bool) {
- return nil, errClosedListener
+ if isAccepting, ok := l.accepting.Load().(bool); !isAccepting || !ok {
+ return nil, false, ErrClosedListener
+ }
+ if l.acceptFilter != nil {
+ if !l.acceptFilter(buf) {
+ return nil, false, nil
+ }
}
conn = l.newConn(raddr)
select {
case l.acceptCh <- conn:
l.conns[raddr.String()] = conn
default:
- return nil, errListenQueueExceeded
+ return nil, false, ErrListenQueueExceeded
}
}
- return conn, nil
+ return conn, true, nil
}
// Conn augments a connection-oriented connection over a UDP PacketConn
@@ -213,7 +315,7 @@ func (l *listener) newConn(rAddr net.Addr) *Conn {
}
}
-// Read
+// Read reads from c into p
func (c *Conn) Read(p []byte) (int, error) {
return c.buffer.Read(p)
}
@@ -239,7 +341,7 @@ func (c *Conn) Close() error {
nConns := len(c.listener.conns)
c.listener.connLock.Unlock()
- if nConns == 0 && !c.listener.accepting.Load().(bool) {
+ if isAccepting, ok := c.listener.accepting.Load().(bool); nConns == 0 && !isAccepting && ok {
// Wait if this is the final connection
c.listener.readWG.Wait()
if errClose, ok := c.listener.errClose.Load().(error); ok {
@@ -248,6 +350,10 @@ func (c *Conn) Close() error {
} else {
err = nil
}
+
+ if errBuf := c.buffer.Close(); errBuf != nil && err == nil {
+ err = errBuf
+ }
})
return err
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/message.go b/vendor/github.com/plgd-dev/go-coap/v2/message/message.go
deleted file mode 100644
index cf9db01..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/message/message.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package message
-
-import (
- "context"
- "fmt"
- "io"
-
- "github.com/plgd-dev/go-coap/v2/message/codes"
-)
-
-// MaxTokenSize maximum of token size that can be used in message
-const MaxTokenSize = 8
-
-type Message struct {
- // Context context of request.
- Context context.Context
- Token Token
- Code codes.Code
- Options Options
- // Body of message. It is nil for message without body.
- Body io.ReadSeeker
-}
-
-func (r *Message) String() string {
- buf := fmt.Sprintf("Code: %v, Token: %v", r.Code, r.Token)
- path, err := r.Options.Path()
- if err == nil {
- buf = fmt.Sprintf("%s, Path: %v", buf, path)
- }
- cf, err := r.Options.ContentFormat()
- if err == nil {
- mt := MediaType(cf)
- buf = fmt.Sprintf("%s, ContentFormat: %v", buf, mt)
- }
- queries, err := r.Options.Queries()
- if err == nil {
- buf = fmt.Sprintf("%s, Queries: %+v", buf, queries)
- }
- return buf
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/pool/message.go b/vendor/github.com/plgd-dev/go-coap/v2/message/pool/message.go
deleted file mode 100644
index 361fc35..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/message/pool/message.go
+++ /dev/null
@@ -1,316 +0,0 @@
-package pool
-
-import (
- "io"
- "sync"
- "sync/atomic"
-
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/message/codes"
-)
-
-var (
- messagePool sync.Pool
-)
-
-type Message struct {
- msg message.Message
- valueBuffer []byte
- origValueBuffer []byte
-
- payload io.ReadSeeker
- sequence uint64
- hijacked uint32
- isModified bool
-}
-
-func NewMessage() *Message {
- valueBuffer := make([]byte, 256)
- return &Message{
- msg: message.Message{
- Options: make(message.Options, 0, 16),
- },
- valueBuffer: valueBuffer,
- origValueBuffer: valueBuffer,
- }
-}
-
-// Reset clear message for next reuse
-func (r *Message) Reset() {
- r.msg.Token = nil
- r.msg.Code = codes.Empty
- r.msg.Options = r.msg.Options[:0]
- r.valueBuffer = r.origValueBuffer
- r.payload = nil
- r.isModified = false
-}
-
-func (r *Message) Remove(opt message.OptionID) {
- r.msg.Options = r.msg.Options.Remove(opt)
- r.isModified = true
-}
-
-func (r *Message) Token() message.Token {
- if r.msg.Token == nil {
- return nil
- }
- token := make(message.Token, 0, 8)
- token = append(token, r.msg.Token...)
- return token
-}
-
-func (r *Message) SetToken(token message.Token) {
- if token == nil {
- r.msg.Token = nil
- return
- }
- r.msg.Token = append(r.msg.Token[:0], token...)
-}
-
-func (r *Message) ResetOptionsTo(in message.Options) {
- opts, used, err := r.msg.Options.ResetOptionsTo(r.valueBuffer, in)
- if err == message.ErrTooSmall {
- r.valueBuffer = append(r.valueBuffer, make([]byte, used)...)
- opts, used, err = r.msg.Options.ResetOptionsTo(r.valueBuffer, in)
- }
- r.msg.Options = opts
- r.valueBuffer = r.valueBuffer[used:]
- if len(in) > 0 {
- r.isModified = true
- }
-}
-
-func (r *Message) Options() message.Options {
- return r.msg.Options
-}
-
-func (r *Message) SetPath(p string) {
- opts, used, err := r.msg.Options.SetPath(r.valueBuffer, p)
-
- if err == message.ErrTooSmall {
- r.valueBuffer = append(r.valueBuffer, make([]byte, used)...)
- opts, used, err = r.msg.Options.SetPath(r.valueBuffer, p)
- }
- r.msg.Options = opts
- r.valueBuffer = r.valueBuffer[used:]
- r.isModified = true
-}
-
-func (r *Message) Code() codes.Code {
- return r.msg.Code
-}
-
-func (r *Message) SetCode(code codes.Code) {
- r.msg.Code = code
- r.isModified = true
-}
-
-func (r *Message) SetETag(value []byte) {
- r.SetOptionBytes(message.ETag, value)
-}
-
-func (r *Message) GetETag() ([]byte, error) {
- return r.GetOptionBytes(message.ETag)
-}
-
-func (r *Message) AddQuery(query string) {
- r.AddOptionString(message.URIQuery, query)
-}
-
-func (r *Message) GetOptionUint32(id message.OptionID) (uint32, error) {
- return r.msg.Options.GetUint32(id)
-}
-
-func (r *Message) SetOptionString(opt message.OptionID, value string) {
- opts, used, err := r.msg.Options.SetString(r.valueBuffer, opt, value)
- if err == message.ErrTooSmall {
- r.valueBuffer = append(r.valueBuffer, make([]byte, used)...)
- opts, used, err = r.msg.Options.SetString(r.valueBuffer, opt, value)
- }
- r.msg.Options = opts
- r.valueBuffer = r.valueBuffer[used:]
- r.isModified = true
-}
-
-func (r *Message) AddOptionString(opt message.OptionID, value string) {
- opts, used, err := r.msg.Options.AddString(r.valueBuffer, opt, value)
- if err == message.ErrTooSmall {
- r.valueBuffer = append(r.valueBuffer, make([]byte, used)...)
- opts, used, err = r.msg.Options.AddString(r.valueBuffer, opt, value)
- }
- r.msg.Options = opts
- r.valueBuffer = r.valueBuffer[used:]
- r.isModified = true
-}
-
-func (r *Message) AddOptionBytes(opt message.OptionID, value []byte) {
- if len(r.valueBuffer) < len(value) {
- r.valueBuffer = append(r.valueBuffer, make([]byte, len(value)-len(r.valueBuffer))...)
- }
- n := copy(r.valueBuffer, value)
- v := r.valueBuffer[:n]
- r.msg.Options = r.msg.Options.Add(message.Option{opt, v})
- r.valueBuffer = r.valueBuffer[n:]
- r.isModified = true
-}
-
-func (r *Message) SetOptionBytes(opt message.OptionID, value []byte) {
- if len(r.valueBuffer) < len(value) {
- r.valueBuffer = append(r.valueBuffer, make([]byte, len(value)-len(r.valueBuffer))...)
- }
- n := copy(r.valueBuffer, value)
- v := r.valueBuffer[:n]
- r.msg.Options = r.msg.Options.Set(message.Option{opt, v})
- r.valueBuffer = r.valueBuffer[n:]
- r.isModified = true
-}
-
-func (r *Message) GetOptionBytes(id message.OptionID) ([]byte, error) {
- return r.msg.Options.GetBytes(id)
-}
-
-func (r *Message) SetOptionUint32(opt message.OptionID, value uint32) {
- opts, used, err := r.msg.Options.SetUint32(r.valueBuffer, opt, value)
- if err == message.ErrTooSmall {
- r.valueBuffer = append(r.valueBuffer, make([]byte, used)...)
- opts, used, err = r.msg.Options.SetUint32(r.valueBuffer, opt, value)
- }
- r.msg.Options = opts
- r.valueBuffer = r.valueBuffer[used:]
- r.isModified = true
-}
-
-func (r *Message) AddOptionUint32(opt message.OptionID, value uint32) {
- opts, used, err := r.msg.Options.AddUint32(r.valueBuffer, opt, value)
- if err == message.ErrTooSmall {
- r.valueBuffer = append(r.valueBuffer, make([]byte, used)...)
- opts, used, err = r.msg.Options.AddUint32(r.valueBuffer, opt, value)
- }
- r.msg.Options = opts
- r.valueBuffer = r.valueBuffer[used:]
- r.isModified = true
-}
-
-func (r *Message) ContentFormat() (message.MediaType, error) {
- v, err := r.GetOptionUint32(message.ContentFormat)
- return message.MediaType(v), err
-}
-
-func (r *Message) HasOption(id message.OptionID) bool {
- return r.msg.Options.HasOption(id)
-}
-
-func (r *Message) SetContentFormat(contentFormat message.MediaType) {
- r.SetOptionUint32(message.ContentFormat, uint32(contentFormat))
-}
-
-func (r *Message) SetObserve(observe uint32) {
- r.SetOptionUint32(message.Observe, observe)
-}
-
-func (r *Message) Observe() (uint32, error) {
- return r.GetOptionUint32(message.Observe)
-}
-
-// SetAccept set's accept option.
-func (r *Message) SetAccept(contentFormat message.MediaType) {
- r.SetOptionUint32(message.Accept, uint32(contentFormat))
-}
-
-// Accept get's accept option.
-func (r *Message) Accept() (message.MediaType, error) {
- v, err := r.GetOptionUint32(message.Accept)
- return message.MediaType(v), err
-}
-
-func (r *Message) ETag() ([]byte, error) {
- return r.GetOptionBytes(message.ETag)
-}
-
-func (r *Message) BodySize() (int64, error) {
- if r.payload == nil {
- return 0, nil
- }
- orig, err := r.payload.Seek(0, io.SeekCurrent)
- if err != nil {
- return 0, err
- }
- _, err = r.payload.Seek(0, io.SeekStart)
- if err != nil {
- return 0, err
- }
- size, err := r.payload.Seek(0, io.SeekEnd)
- if err != nil {
- return 0, err
- }
- _, err = r.payload.Seek(orig, io.SeekStart)
- if err != nil {
- return 0, err
- }
- return size, nil
-}
-
-func (r *Message) SetBody(s io.ReadSeeker) {
- r.payload = s
- r.isModified = true
-}
-
-func (r *Message) Body() io.ReadSeeker {
- return r.payload
-}
-
-func (r *Message) SetSequence(seq uint64) {
- r.sequence = seq
-}
-
-func (r *Message) Sequence() uint64 {
- return r.sequence
-}
-
-func (r *Message) Hijack() {
- atomic.StoreUint32(&r.hijacked, 1)
-}
-
-func (r *Message) IsHijacked() bool {
- return atomic.LoadUint32(&r.hijacked) == 1
-}
-
-func (r *Message) IsModified() bool {
- return r.isModified
-}
-
-func (r *Message) SetModified(b bool) {
- r.isModified = b
-}
-
-func (r *Message) String() string {
- return r.msg.String()
-}
-
-func (r *Message) ReadBody() ([]byte, error) {
- if r.Body() == nil {
- return nil, nil
- }
- size, err := r.BodySize()
- if err != nil {
- return nil, err
- }
- if size == 0 {
- return nil, nil
- }
- _, err = r.Body().Seek(0, io.SeekStart)
- if err != nil {
- return nil, err
- }
- payload := make([]byte, 1024)
- if int64(len(payload)) < size {
- payload = make([]byte, size)
- }
- n, err := io.ReadFull(r.Body(), payload)
- if (err == io.ErrUnexpectedEOF || err == io.EOF) && int64(n) == size {
- err = nil
- } else if err != nil {
- return nil, err
- }
- return payload[:n], nil
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/mux/client.go b/vendor/github.com/plgd-dev/go-coap/v2/mux/client.go
deleted file mode 100644
index faf235b..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/mux/client.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package mux
-
-import (
- "context"
- "io"
- "net"
-
- "github.com/plgd-dev/go-coap/v2/message"
-)
-
-type Observation = interface {
- Cancel(ctx context.Context) error
-}
-
-type Client interface {
- Ping(ctx context.Context) error
- Get(ctx context.Context, path string, opts ...message.Option) (*message.Message, error)
- Delete(ctx context.Context, path string, opts ...message.Option) (*message.Message, error)
- Post(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*message.Message, error)
- Put(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*message.Message, error)
- Observe(ctx context.Context, path string, observeFunc func(notification *message.Message), opts ...message.Option) (Observation, error)
- ClientConn() interface{}
-
- RemoteAddr() net.Addr
- Context() context.Context
- SetContextValue(key interface{}, val interface{})
- WriteMessage(req *message.Message) error
- Do(req *message.Message) (*message.Message, error)
- Close() error
- Sequence() uint64
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/mux/message.go b/vendor/github.com/plgd-dev/go-coap/v2/mux/message.go
deleted file mode 100644
index b831c43..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/mux/message.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package mux
-
-import "github.com/plgd-dev/go-coap/v2/message"
-
-// Message contains message with sequence number.
-type Message struct {
- *message.Message
- // SequenceNumber identifies the order of the message from a TCP connection. For UDP it is just for debugging.
- SequenceNumber uint64
- // IsConfirmable indicates that a UDP message is confirmable. For TCP the value has no semantic.
- // When a handler blocks a confirmable message, the client might decide to issue a re-transmission.
- // Long running handlers can be handled in a go routine and send the response via w.Client().
- // The ACK is sent as soon as the handler returns.
- IsConfirmable bool
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/blockwise/blockwise.go b/vendor/github.com/plgd-dev/go-coap/v2/net/blockwise/blockwise.go
deleted file mode 100644
index 2d6f529..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/blockwise/blockwise.go
+++ /dev/null
@@ -1,823 +0,0 @@
-package blockwise
-
-import (
- "bytes"
- "context"
- "fmt"
- "io"
- "sync"
- "time"
-
- kitSync "github.com/plgd-dev/kit/sync"
-
- "github.com/dsnet/golib/memfile"
- "github.com/patrickmn/go-cache"
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/message/codes"
- udpMessage "github.com/plgd-dev/go-coap/v2/udp/message"
-)
-
-// Block Opion value is represented: https://tools.ietf.org/html/rfc7959#section-2.2
-// 0
-// 0 1 2 3 4 5 6 7
-// +-+-+-+-+-+-+-+-+
-// | NUM |M| SZX |
-// +-+-+-+-+-+-+-+-+
-// 0 1
-// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | NUM |M| SZX |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// 0 1 2
-// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | NUM |M| SZX |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-const (
- // max block size is 3bytes: https://tools.ietf.org/html/rfc7959#section-2.1
- maxBlockValue = 0xffffff
- // maxBlockNumber is 20bits (NUM)
- maxBlockNumber = 0xffff7
- // moreBlocksFollowingMask is represented by one bit (M)
- moreBlocksFollowingMask = 0x8
- // szxMask last 3bits represents SZX (SZX)
- szxMask = 0x7
-)
-
-// SZX enum representation for the size of the block: https://tools.ietf.org/html/rfc7959#section-2.2
-type SZX uint8
-
-const (
- //SZX16 block of size 16bytes
- SZX16 SZX = 0
- //SZX32 block of size 32bytes
- SZX32 SZX = 1
- //SZX64 block of size 64bytes
- SZX64 SZX = 2
- //SZX128 block of size 128bytes
- SZX128 SZX = 3
- //SZX256 block of size 256bytes
- SZX256 SZX = 4
- //SZX512 block of size 512bytes
- SZX512 SZX = 5
- //SZX1024 block of size 1024bytes
- SZX1024 SZX = 6
- //SZXBERT block of size n*1024bytes
- SZXBERT SZX = 7
-)
-
-var szxToSize = map[SZX]int64{
- SZX16: 16,
- SZX32: 32,
- SZX64: 64,
- SZX128: 128,
- SZX256: 256,
- SZX512: 512,
- SZX1024: 1024,
- SZXBERT: 1024,
-}
-
-// Size number of bytes.
-func (s SZX) Size() int64 {
- val, ok := szxToSize[s]
- if ok {
- return val
- }
- return -1
-}
-
-// ResponseWriter defines response interface for blockwise transfer.
-type ResponseWriter interface {
- Message() Message
- SetMessage(Message)
-}
-
-// Message defines message interface for blockwise transfer.
-type Message interface {
- // getters
- Context() context.Context
- Code() codes.Code
- Token() message.Token
- GetOptionUint32(id message.OptionID) (uint32, error)
- GetOptionBytes(id message.OptionID) ([]byte, error)
- Options() message.Options
- Body() io.ReadSeeker
- BodySize() (int64, error)
- Sequence() uint64
- // setters
- SetCode(codes.Code)
- SetToken(message.Token)
- SetOptionUint32(id message.OptionID, value uint32)
- Remove(id message.OptionID)
- ResetOptionsTo(message.Options)
- SetBody(r io.ReadSeeker)
- SetSequence(uint64)
- String() string
-}
-
-// hasType enables access to message.Type for supported messages
-// Since only UDP messages have a type
-type hasType interface {
- Type() udpMessage.Type
- SetType(t udpMessage.Type)
-}
-
-// EncodeBlockOption encodes block values to coap option.
-func EncodeBlockOption(szx SZX, blockNumber int64, moreBlocksFollowing bool) (uint32, error) {
- if szx > SZXBERT {
- return 0, ErrInvalidSZX
- }
- if blockNumber < 0 {
- return 0, ErrBlockNumberExceedLimit
- }
- if blockNumber > maxBlockNumber {
- return 0, ErrBlockNumberExceedLimit
- }
- blockVal := uint32(blockNumber << 4)
- m := uint32(0)
- if moreBlocksFollowing {
- m = 1
- }
- blockVal += m << 3
- blockVal += uint32(szx)
- return blockVal, nil
-}
-
-// DecodeBlockOption decodes coap block option to block values.
-func DecodeBlockOption(blockVal uint32) (szx SZX, blockNumber int64, moreBlocksFollowing bool, err error) {
- if blockVal > maxBlockValue {
- err = ErrBlockInvalidSize
- return
- }
-
- szx = SZX(blockVal & szxMask) //masking for the SZX
- if (blockVal & moreBlocksFollowingMask) != 0 { //masking for the "M"
- moreBlocksFollowing = true
- }
- blockNumber = int64(blockVal) >> 4 //shifting out the SZX and M vals. leaving the block number behind
- if blockNumber > maxBlockNumber {
- err = ErrBlockNumberExceedLimit
- }
- return
-}
-
-type BlockWise struct {
- acquireMessage func(ctx context.Context) Message
- releaseMessage func(Message)
- receivingMessagesCache *cache.Cache
- sendingMessagesCache *cache.Cache
- errors func(error)
- autoCleanUpResponseCache bool
- getSendedRequestFromOutside func(token message.Token) (Message, bool)
-
- bwSendedRequest *kitSync.Map
-}
-
-type messageGuard struct {
- sync.Mutex
- request Message
-}
-
-func newRequestGuard(request Message) *messageGuard {
- return &messageGuard{
- request: request,
- }
-}
-
-// NewBlockWise provides blockwise.
-// getSendedRequestFromOutside must returns a copy of request which will be released by function releaseMessage after use.
-func NewBlockWise(
- acquireMessage func(ctx context.Context) Message,
- releaseMessage func(Message),
- expiration time.Duration,
- errors func(error),
- autoCleanUpResponseCache bool,
- getSendedRequestFromOutside func(token message.Token) (Message, bool),
-) *BlockWise {
- receivingMessagesCache := cache.New(expiration, expiration)
- bwSendedRequest := kitSync.NewMap()
- receivingMessagesCache.OnEvicted(func(tokenstr string, _ interface{}) {
- bwSendedRequest.Delete(tokenstr)
- })
- if getSendedRequestFromOutside == nil {
- getSendedRequestFromOutside = func(token message.Token) (Message, bool) { return nil, false }
- }
- return &BlockWise{
- acquireMessage: acquireMessage,
- releaseMessage: releaseMessage,
- receivingMessagesCache: receivingMessagesCache,
- sendingMessagesCache: cache.New(expiration, expiration),
- errors: errors,
- autoCleanUpResponseCache: autoCleanUpResponseCache,
- getSendedRequestFromOutside: getSendedRequestFromOutside,
- bwSendedRequest: bwSendedRequest,
- }
-}
-
-func bufferSize(szx SZX, maxMessageSize int) int64 {
- if szx < SZXBERT {
- return szx.Size()
- }
- return (int64(maxMessageSize) / szx.Size()) * szx.Size()
-}
-
-func setTypeFrom(to Message, from Message) {
- if udpTo, ok := to.(hasType); ok {
- if udpFrom, ok := from.(hasType); ok {
- udpTo.SetType(udpFrom.Type())
- }
- }
-}
-
-func (b *BlockWise) newSendRequestMessage(r Message) Message {
- req := b.acquireMessage(r.Context())
- req.SetCode(r.Code())
- req.SetToken(r.Token())
- req.ResetOptionsTo(r.Options())
- setTypeFrom(req, r)
-
- return req
-}
-
-// Do sends an coap message and returns an coap response via blockwise transfer.
-func (b *BlockWise) Do(r Message, maxSzx SZX, maxMessageSize int, do func(req Message) (Message, error)) (Message, error) {
- if maxSzx > SZXBERT {
- return nil, fmt.Errorf("invalid szx")
- }
- if len(r.Token()) == 0 {
- return nil, fmt.Errorf("invalid token")
- }
-
- req := b.newSendRequestMessage(r)
- defer b.releaseMessage(req)
-
- tokenStr := r.Token().String()
- b.bwSendedRequest.Store(tokenStr, req)
- defer b.bwSendedRequest.Delete(tokenStr)
- if r.Body() == nil {
- return do(r)
- }
- payloadSize, err := r.BodySize()
- if err != nil {
- return nil, fmt.Errorf("cannot get size of payload: %w", err)
- }
- if payloadSize <= int64(maxSzx.Size()) {
- return do(r)
- }
-
- switch r.Code() {
- case codes.POST, codes.PUT:
- break
- default:
- return nil, fmt.Errorf("unsupported command(%v)", r.Code())
- }
- req.SetOptionUint32(message.Size1, uint32(payloadSize))
-
- num := int64(0)
- buf := make([]byte, 1024)
- szx := maxSzx
- for {
- newBufLen := bufferSize(szx, maxMessageSize)
- if int64(cap(buf)) < newBufLen {
- buf = make([]byte, newBufLen)
- }
- buf = buf[:newBufLen]
-
- off := int64(num * szx.Size())
- newOff, err := r.Body().Seek(off, io.SeekStart)
- if err != nil {
- return nil, fmt.Errorf("cannot seek in payload: %w", err)
- }
- readed, err := io.ReadFull(r.Body(), buf)
- if err == io.ErrUnexpectedEOF {
- if newOff+int64(readed) == payloadSize {
- err = nil
- }
- }
- if err != nil {
- return nil, fmt.Errorf("cannot read payload: %w", err)
- }
- buf = buf[:readed]
- req.SetBody(bytes.NewReader(buf))
- more := true
- if newOff+int64(readed) == payloadSize {
- more = false
- }
- block, err := EncodeBlockOption(szx, num, more)
- if err != nil {
- return nil, fmt.Errorf("cannot encode block option(%v, %v, %v) to bw request: %w", szx, num, more, err)
- }
-
- req.SetOptionUint32(message.Block1, block)
- resp, err := do(req)
- if err != nil {
- return nil, fmt.Errorf("cannot do bw request: %w", err)
- }
- block, err = resp.GetOptionUint32(message.Block1)
- if err != nil {
- return resp, nil
- }
- switch resp.Code() {
- case codes.Continue:
- case codes.Created, codes.Changed:
- if !more {
- return resp, nil
- }
- default:
- return resp, nil
- }
-
- var newSzx SZX
- var newNum int64
- newSzx, newNum, _, err = DecodeBlockOption(block)
- if err != nil {
- return resp, fmt.Errorf("cannot decode block option of bw response: %w", err)
- }
- if num != newNum {
- return resp, fmt.Errorf("unexpected of acknowleged seqencenumber(%v != %v)", num, newNum)
- }
-
- num = num + newSzx.Size()/szx.Size()
- szx = newSzx
- }
-}
-
-type writeMessageResponse struct {
- request Message
- releaseMessage func(Message)
-}
-
-func NewWriteRequestResponse(request Message, acquireMessage func(context.Context) Message, releaseMessage func(Message)) *writeMessageResponse {
- req := acquireMessage(request.Context())
- req.SetCode(request.Code())
- req.SetToken(request.Token())
- req.ResetOptionsTo(request.Options())
- req.SetBody(request.Body())
- return &writeMessageResponse{
- request: req,
- releaseMessage: releaseMessage,
- }
-}
-
-func (w *writeMessageResponse) SetMessage(r Message) {
- w.releaseMessage(w.request)
- w.request = r
-}
-
-func (w *writeMessageResponse) Message() Message {
- return w.request
-}
-
-// WriteMessage sends an coap message via blockwise transfer.
-func (b *BlockWise) WriteMessage(request Message, maxSZX SZX, maxMessageSize int, writeMessage func(r Message) error) error {
- req := b.newSendRequestMessage(request)
- tokenStr := req.Token().String()
- b.bwSendedRequest.Store(tokenStr, req)
- startSendingMessageBlock, err := EncodeBlockOption(maxSZX, 0, true)
- if err != nil {
- return fmt.Errorf("cannot encode start sending message block option(%v,%v,%v): %w", maxSZX, 0, true, err)
- }
-
- w := NewWriteRequestResponse(request, b.acquireMessage, b.releaseMessage)
- err = b.startSendingMessage(w, maxSZX, maxMessageSize, startSendingMessageBlock)
- if err != nil {
- return fmt.Errorf("cannot start writing request: %w", err)
- }
- return writeMessage(w.Message())
-}
-
-func fitSZX(r Message, blockType message.OptionID, maxSZX SZX) SZX {
- block, err := r.GetOptionUint32(blockType)
- if err == nil {
- szx, _, _, err := DecodeBlockOption(block)
- if err != nil {
- if maxSZX > szx {
- return szx
- }
- }
- }
- return maxSZX
-}
-
-func (b *BlockWise) handleSendingMessage(w ResponseWriter, sendingMessage Message, maxSZX SZX, maxMessageSize int, token []byte, block uint32) (bool, error) {
- blockType := message.Block2
- sizeType := message.Size2
- switch sendingMessage.Code() {
- case codes.POST, codes.PUT:
- blockType = message.Block1
- sizeType = message.Size1
- }
-
- szx, num, _, err := DecodeBlockOption(block)
- if err != nil {
- return false, fmt.Errorf("cannot decode %v option: %w", blockType, err)
- }
- off := int64(num * szx.Size())
- if szx > maxSZX {
- szx = maxSZX
- }
- sendMessage := b.acquireMessage(sendingMessage.Context())
- sendMessage.SetCode(sendingMessage.Code())
- sendMessage.ResetOptionsTo(sendingMessage.Options())
- sendMessage.SetToken(token)
- payloadSize, err := sendingMessage.BodySize()
- if err != nil {
- return false, fmt.Errorf("cannot get size of payload: %w", err)
- }
- offSeek, err := sendingMessage.Body().Seek(off, io.SeekStart)
- if err != nil {
- return false, fmt.Errorf("cannot seek in response: %w", err)
- }
- if off != offSeek {
- return false, fmt.Errorf("cannot seek to requested offset(%v != %v)", off, offSeek)
- }
- buf := make([]byte, 1024)
- newBufLen := bufferSize(szx, maxMessageSize)
- if int64(len(buf)) < newBufLen {
- buf = make([]byte, newBufLen)
- }
- buf = buf[:newBufLen]
-
- readed, err := io.ReadFull(sendingMessage.Body(), buf)
- if err == io.ErrUnexpectedEOF {
- if offSeek+int64(readed) == payloadSize {
- err = nil
- }
- }
-
- buf = buf[:readed]
- sendMessage.SetBody(bytes.NewReader(buf))
- more := true
- if offSeek+int64(readed) == payloadSize {
- more = false
- }
- sendMessage.SetOptionUint32(sizeType, uint32(payloadSize))
- num = (offSeek+int64(readed))/szx.Size() - (int64(readed) / szx.Size())
- block, err = EncodeBlockOption(szx, num, more)
- if err != nil {
- return false, fmt.Errorf("cannot encode block option(%v,%v,%v): %w", szx, num, more, err)
- }
- sendMessage.SetOptionUint32(blockType, block)
- w.SetMessage(sendMessage)
- return more, nil
-}
-
-// RemoveFromResponseCache removes response from cache. It need's tu be used for udp coap.
-func (b *BlockWise) RemoveFromResponseCache(token message.Token) {
- if len(token) == 0 {
- return
- }
- b.sendingMessagesCache.Delete(token.String())
-}
-
-func (b *BlockWise) sendEntityIncomplete(w ResponseWriter, token message.Token) {
- sendMessage := b.acquireMessage(w.Message().Context())
- sendMessage.SetCode(codes.RequestEntityIncomplete)
- sendMessage.SetToken(token)
- w.SetMessage(sendMessage)
-}
-
-// Handle middleware which constructs COAP request from blockwise transfer and send COAP response via blockwise.
-func (b *BlockWise) Handle(w ResponseWriter, r Message, maxSZX SZX, maxMessageSize int, next func(w ResponseWriter, r Message)) {
- if maxSZX > SZXBERT {
- panic("invalid maxSZX")
- }
- token := r.Token()
-
- if len(token) == 0 {
- err := b.handleReceivedMessage(w, r, maxSZX, maxMessageSize, next)
- if err != nil {
- b.sendEntityIncomplete(w, token)
- b.errors(fmt.Errorf("handleReceivedMessage(%v): %w", r, err))
- }
- return
- }
- tokenStr := token.String()
- v, ok := b.sendingMessagesCache.Get(tokenStr)
-
- if !ok {
- err := b.handleReceivedMessage(w, r, maxSZX, maxMessageSize, next)
- if err != nil {
- b.sendEntityIncomplete(w, token)
- b.errors(fmt.Errorf("handleReceivedMessage(%v): %w", r, err))
- }
- return
- }
- more, err := b.continueSendingMessage(w, r, maxSZX, maxMessageSize, v.(*messageGuard))
- if err != nil {
- b.sendingMessagesCache.Delete(tokenStr)
- b.errors(fmt.Errorf("continueSendingMessage(%v): %w", r, err))
- return
- }
- if b.autoCleanUpResponseCache && more == false {
- b.RemoveFromResponseCache(token)
- }
-}
-
-func (b *BlockWise) handleReceivedMessage(w ResponseWriter, r Message, maxSZX SZX, maxMessageSize int, next func(w ResponseWriter, r Message)) error {
- startSendingMessageBlock, err := EncodeBlockOption(maxSZX, 0, true)
- if err != nil {
- return fmt.Errorf("cannot encode start sending message block option(%v,%v,%v): %w", maxSZX, 0, true, err)
- }
- switch r.Code() {
- case codes.Empty:
- next(w, r)
- return nil
- case codes.CSM, codes.Ping, codes.Pong, codes.Release, codes.Abort, codes.Continue:
- next(w, r)
- return nil
- case codes.GET, codes.DELETE:
- maxSZX = fitSZX(r, message.Block2, maxSZX)
- block, err := r.GetOptionUint32(message.Block2)
- if err == nil {
- r.Remove(message.Block2)
- }
- next(w, r)
- if w.Message().Code() == codes.Content && err == nil {
- startSendingMessageBlock = block
- }
- case codes.POST, codes.PUT:
- maxSZX = fitSZX(r, message.Block1, maxSZX)
- err := b.processReceivedMessage(w, r, maxSZX, next, message.Block1, message.Size1)
- if err != nil {
- return err
- }
- default:
- maxSZX = fitSZX(r, message.Block2, maxSZX)
- err = b.processReceivedMessage(w, r, maxSZX, next, message.Block2, message.Size2)
- if err != nil {
- return err
- }
-
- }
- return b.startSendingMessage(w, maxSZX, maxMessageSize, startSendingMessageBlock)
-}
-
-func (b *BlockWise) continueSendingMessage(w ResponseWriter, r Message, maxSZX SZX, maxMessageSize int, messageGuard *messageGuard) (bool, error) {
- messageGuard.Lock()
- defer messageGuard.Unlock()
- resp := messageGuard.request
- blockType := message.Block2
- switch resp.Code() {
- case codes.POST, codes.PUT:
- blockType = message.Block1
- }
-
- block, err := r.GetOptionUint32(blockType)
- if err != nil {
- return false, fmt.Errorf("cannot get %v option: %w", blockType, err)
- }
- if blockType == message.Block1 {
- // num just acknowlege position we need to set block to next block.
- szx, num, more, err := DecodeBlockOption(block)
- if err != nil {
- return false, fmt.Errorf("cannot decode %v(%v) option: %w", blockType, block, err)
- }
- off, err := resp.Body().Seek(0, io.SeekCurrent)
- if err != nil {
- return false, fmt.Errorf("cannot get current position of seek: %w", err)
- }
- num = off / szx.Size()
- block, err = EncodeBlockOption(szx, num, more)
- if err != nil {
- return false, fmt.Errorf("cannot encode %v(%v, %v, %v) option: %w", blockType, szx, num, more, err)
- }
- }
- more, err := b.handleSendingMessage(w, resp, maxSZX, maxMessageSize, r.Token(), block)
-
- if err != nil {
- return false, fmt.Errorf("handleSendingMessage: %w", err)
- }
- return more, err
-}
-
-func isObserveResponse(msg Message) bool {
- _, err := msg.GetOptionUint32(message.Observe)
- if err != nil {
- return false
- }
- if msg.Code() == codes.Content {
- return true
- }
- return false
-}
-
-func (b *BlockWise) startSendingMessage(w ResponseWriter, maxSZX SZX, maxMessageSize int, block uint32) error {
- payloadSize, err := w.Message().BodySize()
- if err != nil {
- return fmt.Errorf("cannot get size of payload: %w", err)
- }
-
- if payloadSize < int64(maxSZX.Size()) {
- return nil
- }
- sendingMessage := b.acquireMessage(w.Message().Context())
- sendingMessage.ResetOptionsTo(w.Message().Options())
- sendingMessage.SetBody(w.Message().Body())
- sendingMessage.SetCode(w.Message().Code())
- sendingMessage.SetToken(w.Message().Token())
-
- _, err = b.handleSendingMessage(w, sendingMessage, maxSZX, maxMessageSize, sendingMessage.Token(), block)
- if err != nil {
- return fmt.Errorf("handleSendingMessage: %w", err)
- }
- if isObserveResponse(w.Message()) {
- // https://tools.ietf.org/html/rfc7959#section-2.6 - we don't need store it because client will be get values via GET.
- return nil
- }
- err = b.sendingMessagesCache.Add(sendingMessage.Token().String(), newRequestGuard(sendingMessage), cache.DefaultExpiration)
- if err != nil {
- return fmt.Errorf("cannot add to response cachce: %w", err)
- }
- return nil
-}
-
-func (b *BlockWise) getSendedRequest(token message.Token) Message {
- v, ok := b.bwSendedRequest.LoadWithFunc(token.String(), func(v interface{}) interface{} {
- r := v.(Message)
- return b.newSendRequestMessage(r)
- })
- if ok {
- return v.(Message)
- }
- globalRequest, ok := b.getSendedRequestFromOutside(token)
- if ok {
- return globalRequest
- }
- return nil
-}
-
-func (b *BlockWise) processReceivedMessage(w ResponseWriter, r Message, maxSzx SZX, next func(w ResponseWriter, r Message), blockType message.OptionID, sizeType message.OptionID) error {
- token := r.Token()
- if len(token) == 0 {
- next(w, r)
- return nil
- }
- if r.Code() == codes.GET || r.Code() == codes.DELETE {
- next(w, r)
- return nil
- }
-
- block, err := r.GetOptionUint32(blockType)
- if err != nil {
-
- next(w, r)
- return nil
- }
- szx, num, more, err := DecodeBlockOption(block)
- if err != nil {
- return fmt.Errorf("cannot decode block option: %w", err)
- }
- sendedRequest := b.getSendedRequest(token)
- if sendedRequest != nil {
- defer b.releaseMessage(sendedRequest)
- }
- if blockType == message.Block2 && sendedRequest == nil {
- return fmt.Errorf("cannot request body without paired request")
- }
- if isObserveResponse(r) {
- // https://tools.ietf.org/html/rfc7959#section-2.6 - performs GET with new token.
- if sendedRequest == nil {
- return fmt.Errorf("observation is not registered")
- }
- token, err = message.GetToken()
- if err != nil {
- return fmt.Errorf("cannot get token for create GET request: %w", err)
- }
- bwSendedRequest := b.acquireMessage(sendedRequest.Context())
- bwSendedRequest.SetCode(sendedRequest.Code())
- bwSendedRequest.SetToken(token)
- bwSendedRequest.ResetOptionsTo(sendedRequest.Options())
- b.bwSendedRequest.Store(token.String(), bwSendedRequest)
- }
-
- tokenStr := token.String()
- cachedReceivedMessageGuard, ok := b.receivingMessagesCache.Get(tokenStr)
- var msgGuard *messageGuard
- if !ok {
- if szx > maxSzx {
- szx = maxSzx
- }
- // first request must have 0
- if num != 0 {
- return fmt.Errorf("token %v, invalid %v(%v), expected 0", []byte(token), blockType, num)
- }
- // if there is no more then just forward req to next handler
- if more == false {
- next(w, r)
- return nil
- }
- cachedReceivedMessage := b.acquireMessage(r.Context())
- cachedReceivedMessage.ResetOptionsTo(r.Options())
- cachedReceivedMessage.SetToken(r.Token())
- cachedReceivedMessage.SetSequence(r.Sequence())
- cachedReceivedMessage.SetBody(memfile.New(make([]byte, 0, 1024)))
- msgGuard = newRequestGuard(cachedReceivedMessage)
- msgGuard.Lock()
- defer msgGuard.Unlock()
- err := b.receivingMessagesCache.Add(tokenStr, msgGuard, cache.DefaultExpiration)
- // request was already stored in cache, silently
- if err != nil {
- return fmt.Errorf("request was already stored in cache")
- }
- } else {
- msgGuard = cachedReceivedMessageGuard.(*messageGuard)
- msgGuard.Lock()
- defer msgGuard.Unlock()
- }
- defer func(err *error) {
- if *err != nil {
- b.receivingMessagesCache.Delete(tokenStr)
- }
- }(&err)
- cachedReceivedMessage := msgGuard.request
- rETAG, errETAG := r.GetOptionBytes(message.ETag)
- cachedReceivedMessageETAG, errCachedReceivedMessageETAG := cachedReceivedMessage.GetOptionBytes(message.ETag)
- switch {
- case errETAG == nil && errCachedReceivedMessageETAG != nil:
- if len(cachedReceivedMessageETAG) > 0 { // make sure there is an etag there
- return fmt.Errorf("received message doesn't contains ETAG but cached received message contains it(%v)", cachedReceivedMessageETAG)
- }
- case errETAG != nil && errCachedReceivedMessageETAG == nil:
- if len(rETAG) > 0 { // make sure there is an etag there
- return fmt.Errorf("received message contains ETAG(%v) but cached received message doesn't", rETAG)
- }
- case !bytes.Equal(rETAG, cachedReceivedMessageETAG):
- return fmt.Errorf("received message ETAG(%v) is not equal to cached received message ETAG(%v)", rETAG, cachedReceivedMessageETAG)
- }
-
- payloadFile, ok := cachedReceivedMessage.Body().(*memfile.File)
- if !ok {
- return fmt.Errorf("invalid body type(%T) stored in receivingMessagesCache", cachedReceivedMessage.Body())
- }
-
- off := num * szx.Size()
- payloadSize, err := cachedReceivedMessage.BodySize()
- if err != nil {
- return fmt.Errorf("cannot get size of payload: %w", err)
- }
-
- if int64(off) <= payloadSize {
- copyn, err := payloadFile.Seek(int64(off), io.SeekStart)
- if err != nil {
- return fmt.Errorf("cannot seek to off(%v) of cached request: %w", off, err)
- }
- if r.Body() != nil {
- _, err = r.Body().Seek(0, io.SeekStart)
- if err != nil {
- return fmt.Errorf("cannot seek to start of request: %w", err)
- }
- written, err := io.Copy(payloadFile, r.Body())
- if err != nil {
- return fmt.Errorf("cannot copy to cached request: %w", err)
- }
- payloadSize = copyn + written
- } else {
- payloadSize = copyn
- }
- err = payloadFile.Truncate(payloadSize)
- if err != nil {
- return fmt.Errorf("cannot truncate cached request: %w", err)
- }
- }
- if !more {
- b.receivingMessagesCache.Delete(tokenStr)
- cachedReceivedMessage.Remove(blockType)
- cachedReceivedMessage.Remove(sizeType)
- cachedReceivedMessage.SetCode(r.Code())
- setTypeFrom(cachedReceivedMessage, r)
- if !bytes.Equal(cachedReceivedMessage.Token(), token) {
- b.bwSendedRequest.Delete(tokenStr)
- }
- _, err := cachedReceivedMessage.Body().Seek(0, io.SeekStart)
- if err != nil {
- return fmt.Errorf("cannot seek to start of cachedReceivedMessage request: %w", err)
- }
- next(w, cachedReceivedMessage)
-
- return nil
- }
- if szx > maxSzx {
- szx = maxSzx
- }
-
- sendMessage := b.acquireMessage(r.Context())
- sendMessage.SetToken(token)
- if blockType == message.Block2 {
- num = payloadSize / szx.Size()
- sendMessage.ResetOptionsTo(sendedRequest.Options())
- sendMessage.SetCode(sendedRequest.Code())
- sendMessage.Remove(message.Observe)
- } else {
- sendMessage.SetCode(codes.Continue)
- }
- respBlock, err := EncodeBlockOption(szx, num, more)
- if err != nil {
- b.releaseMessage(sendMessage)
- return fmt.Errorf("cannot encode block option(%v,%v,%v): %w", szx, num, more, err)
- }
- sendMessage.SetOptionUint32(blockType, respBlock)
- w.SetMessage(sendMessage)
- return nil
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/conn.go b/vendor/github.com/plgd-dev/go-coap/v2/net/conn.go
deleted file mode 100644
index 264e287..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/conn.go
+++ /dev/null
@@ -1,159 +0,0 @@
-package net
-
-import (
- "bufio"
- "context"
- "fmt"
- "net"
- "sync"
- "time"
-)
-
-// Conn is a generic stream-oriented network connection that provides Read/Write with context.
-//
-// Multiple goroutines may invoke methods on a Conn simultaneously.
-type Conn struct {
- heartBeat time.Duration
- connection net.Conn
- onReadTimeout func() error
- onWriteTimeout func() error
-
- readBuffer *bufio.Reader
- lock sync.Mutex
-}
-
-var defaultConnOptions = connOptions{
- heartBeat: time.Millisecond * 200,
-}
-
-type connOptions struct {
- heartBeat time.Duration
- onReadTimeout func() error
- onWriteTimeout func() error
-}
-
-// A ConnOption sets options such as heartBeat, errors parameters, etc.
-type ConnOption interface {
- applyConn(*connOptions)
-}
-
-// NewConn creates connection over net.Conn.
-func NewConn(c net.Conn, opts ...ConnOption) *Conn {
- cfg := defaultConnOptions
- for _, o := range opts {
- o.applyConn(&cfg)
- }
- connection := Conn{
- connection: c,
- heartBeat: cfg.heartBeat,
- readBuffer: bufio.NewReaderSize(c, 2048),
- onReadTimeout: cfg.onReadTimeout,
- onWriteTimeout: cfg.onWriteTimeout,
- }
- return &connection
-}
-
-// LocalAddr returns the local network address. The Addr returned is shared by all invocations of LocalAddr, so do not modify it.
-func (c *Conn) LocalAddr() net.Addr {
- return c.connection.LocalAddr()
-}
-
-// Connection returns the network connection. The Conn returned is shared by all invocations of Connection, so do not modify it.
-func (c *Conn) Connection() net.Conn {
- return c.connection
-}
-
-// RemoteAddr returns the remote network address. The Addr returned is shared by all invocations of RemoteAddr, so do not modify it.
-func (c *Conn) RemoteAddr() net.Addr {
- return c.connection.RemoteAddr()
-}
-
-// Close closes the connection.
-func (c *Conn) Close() error {
- return c.connection.Close()
-}
-
-// WriteWithContext writes data with context.
-func (c *Conn) WriteWithContext(ctx context.Context, data []byte) error {
- written := 0
- c.lock.Lock()
- defer c.lock.Unlock()
- for written < len(data) {
- select {
- case <-ctx.Done():
- return ctx.Err()
- default:
- }
- deadline := time.Now().Add(c.heartBeat)
- err := c.connection.SetWriteDeadline(deadline)
- if err != nil {
- return fmt.Errorf("cannot set write deadline for connection: %w", err)
- }
- n, err := c.connection.Write(data[written:])
-
- if err != nil {
- if isTemporary(err, deadline) {
- if n > 0 {
- written += n
- }
- if c.onWriteTimeout != nil {
- err := c.onWriteTimeout()
- if err != nil {
- return fmt.Errorf("cannot write to connection: on timeout returns error: %w", err)
- }
- }
- continue
- }
- return fmt.Errorf("cannot write to connection: %w", err)
- }
- written += n
- }
- return nil
-}
-
-// ReadFullWithContext reads stream with context until whole buffer is satisfied.
-func (c *Conn) ReadFullWithContext(ctx context.Context, buffer []byte) error {
- offset := 0
- for offset < len(buffer) {
- n, err := c.ReadWithContext(ctx, buffer[offset:])
- if err != nil {
- return fmt.Errorf("cannot read full from connection: %w", err)
- }
- offset += n
- }
- return nil
-}
-
-// ReadWithContext reads stream with context.
-func (c *Conn) ReadWithContext(ctx context.Context, buffer []byte) (int, error) {
- for {
- select {
- case <-ctx.Done():
- if ctx.Err() != nil {
- return -1, fmt.Errorf("cannot read from connection: %v", ctx.Err())
- }
- return -1, fmt.Errorf("cannot read from connection")
- default:
- }
-
- deadline := time.Now().Add(c.heartBeat)
- err := c.connection.SetReadDeadline(deadline)
- if err != nil {
- return -1, fmt.Errorf("cannot set read deadline for connection: %w", err)
- }
- n, err := c.readBuffer.Read(buffer)
- if err != nil {
- if isTemporary(err, deadline) {
- if c.onReadTimeout != nil {
- err := c.onReadTimeout()
- if err != nil {
- return -1, fmt.Errorf("cannot read from connection: on timeout returns error: %w", err)
- }
- }
- continue
- }
- return -1, fmt.Errorf("cannot read from connection: %w", err)
- }
- return n, err
- }
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/dtlslistener.go b/vendor/github.com/plgd-dev/go-coap/v2/net/dtlslistener.go
deleted file mode 100644
index f705a09..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/dtlslistener.go
+++ /dev/null
@@ -1,211 +0,0 @@
-package net
-
-import (
- "context"
- "fmt"
- "net"
- "sync"
- "sync/atomic"
- "time"
-
- dtls "github.com/pion/dtls/v2"
-)
-
-type connData struct {
- conn net.Conn
- err error
-}
-
-// DTLSListener is a DTLS listener that provides accept with context.
-type DTLSListener struct {
- listener net.Listener
- heartBeat time.Duration
- wg sync.WaitGroup
- doneCh chan struct{}
- connCh chan connData
- onTimeout func() error
-
- cancel context.CancelFunc
- mutex sync.Mutex
-
- closed uint32
- deadline atomic.Value
-}
-
-func (l *DTLSListener) acceptLoop() {
- defer l.wg.Done()
- for {
- conn, err := l.listener.Accept()
- if err != nil {
- select {
- case <-l.doneCh:
- return
- case l.connCh <- connData{conn: conn, err: err}:
- }
- } else {
- select {
- case l.connCh <- connData{conn: conn, err: err}:
- case <-l.doneCh:
- return
- }
- }
- }
-}
-
-var defaultDTLSListenerOptions = dtlsListenerOptions{
- heartBeat: time.Millisecond * 200,
-}
-
-type dtlsListenerOptions struct {
- heartBeat time.Duration
- onTimeout func() error
-}
-
-// A DTLSListenerOption sets options such as heartBeat parameters, etc.
-type DTLSListenerOption interface {
- applyDTLSListener(*dtlsListenerOptions)
-}
-
-// 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) {
- cfg := defaultDTLSListenerOptions
- for _, o := range opts {
- o.applyDTLSListener(&cfg)
- }
-
- a, err := net.ResolveUDPAddr(network, addr)
- if err != nil {
- return nil, fmt.Errorf("cannot resolve address: %w", err)
- }
- l := DTLSListener{
- heartBeat: cfg.heartBeat,
- connCh: make(chan connData),
- doneCh: 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()
- l.mutex.Lock()
- defer l.mutex.Unlock()
- if l.closed > 0 {
- cancel()
- }
- l.cancel = cancel
- return ctx, cancel
- }
-
- listener, err := dtls.Listen(network, a, dtlsCfg)
- if err != nil {
- return nil, fmt.Errorf("cannot create new dtls listener: %w", err)
- }
- l.listener = listener
- l.wg.Add(1)
-
- go l.acceptLoop()
-
- return &l, nil
-}
-
-// AcceptWithContext waits with context for a generic Conn.
-func (l *DTLSListener) AcceptWithContext(ctx context.Context) (net.Conn, error) {
- for {
- select {
- case <-ctx.Done():
- return nil, ctx.Err()
- default:
- }
- if atomic.LoadUint32(&l.closed) == 1 {
- return nil, ErrListenerIsClosed
- }
- deadline := time.Now().Add(l.heartBeat)
- err := l.SetDeadline(deadline)
- if err != nil {
- return nil, fmt.Errorf("cannot set deadline to accept connection: %w", err)
- }
- rw, err := l.Accept()
- if err != nil {
- // check context in regular intervals and then resume listening
- if isTemporary(err, deadline) {
- if l.onTimeout != nil {
- err := l.onTimeout()
- if err != nil {
- return nil, fmt.Errorf("cannot accept connection : on timeout returns error: %w", err)
- }
- }
- continue
- }
- return nil, fmt.Errorf("cannot accept connection: %w", err)
- }
- return rw, nil
- }
-}
-
-// SetDeadline sets deadline for accept operation.
-func (l *DTLSListener) SetDeadline(t time.Time) error {
- l.deadline.Store(t)
- return nil
-}
-
-// Accept waits for a generic Conn.
-func (l *DTLSListener) Accept() (net.Conn, error) {
- var deadline time.Time
- v := l.deadline.Load()
- if v != nil {
- deadline = v.(time.Time)
- }
-
- if deadline.IsZero() {
- select {
- case d := <-l.connCh:
- if d.err != nil {
- return nil, d.err
- }
- return d.conn, nil
- }
- }
-
- select {
- case d := <-l.connCh:
- if d.err != nil {
- return nil, d.err
- }
- return d.conn, nil
- case <-time.After(deadline.Sub(time.Now())):
- return nil, fmt.Errorf(ioTimeout)
- }
-}
-
-func (l *DTLSListener) close() (bool, error) {
- l.mutex.Lock()
- defer l.mutex.Unlock()
- if l.closed > 0 {
- return false, nil
- }
- close(l.doneCh)
- err := l.listener.Close()
- if l.cancel != nil {
- l.cancel()
- }
- return true, err
-}
-
-// Close closes the connection.
-func (l *DTLSListener) Close() error {
- wait, err := l.close()
- if wait {
- l.wg.Wait()
- }
- return err
-}
-
-// Addr represents a network end point address.
-func (l *DTLSListener) Addr() net.Addr {
- return l.listener.Addr()
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/error.go b/vendor/github.com/plgd-dev/go-coap/v2/net/error.go
deleted file mode 100644
index de11bc9..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/error.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package net
-
-import "errors"
-
-var ErrListenerIsClosed = errors.New("listen socket was closed")
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/isTemporary.go b/vendor/github.com/plgd-dev/go-coap/v2/net/isTemporary.go
deleted file mode 100644
index aee561f..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/isTemporary.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package net
-
-import (
- "net"
- "strings"
- "time"
-)
-
-// https://github.com/golang/go/blob/958e212db799e609b2a8df51cdd85c9341e7a404/src/internal/poll/fd.go#L43
-const ioTimeout = "i/o timeout"
-
-func isTemporary(err error, deadline time.Time) bool {
- netErr, ok := err.(net.Error)
- if ok {
- if netErr.Timeout() {
- // when connection is closed during TLS handshake, it returns i/o timeout
- // so we need to validate if timeout real occurs by set deadline otherwise infinite loop occurs.
- return deadline.Before(time.Now())
- }
- if netErr.Temporary() {
- return true
- }
- }
-
- if strings.Contains(err.Error(), ioTimeout) {
- // when connection is closed during TLS handshake, it returns i/o timeout
- // so we need to validate if timeout real occurs by set deadline otherwise infinite loop occurs.
- return deadline.Before(time.Now())
- }
- return false
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/monitor/inactivity/inactivitymonitor.go b/vendor/github.com/plgd-dev/go-coap/v2/net/monitor/inactivity/inactivitymonitor.go
deleted file mode 100644
index c58392c..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/monitor/inactivity/inactivitymonitor.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package inactivity
-
-import (
- "context"
- "sync/atomic"
- "time"
-)
-
-type Monitor = interface {
- CheckInactivity(cc ClientConn)
- Notify()
-}
-
-type OnInactiveFunc = func(cc ClientConn)
-
-type ClientConn = interface {
- Context() context.Context
- Close() error
-}
-
-type inactivityMonitor struct {
- duration time.Duration
- onInactive OnInactiveFunc
- // lastActivity stores time.Time
- lastActivity atomic.Value
-}
-
-func (m *inactivityMonitor) Notify() {
- m.lastActivity.Store(time.Now())
-}
-
-func (m *inactivityMonitor) LastActivity() time.Time {
- if t, ok := m.lastActivity.Load().(time.Time); ok {
- return t
- }
- return time.Time{}
-}
-
-func CloseClientConn(cc ClientConn) {
- cc.Close()
-}
-
-func NewInactivityMonitor(duration time.Duration, onInactive OnInactiveFunc) Monitor {
- m := &inactivityMonitor{
- duration: duration,
- onInactive: onInactive,
- }
- m.Notify()
- return m
-}
-
-func (m *inactivityMonitor) CheckInactivity(cc ClientConn) {
- if m.onInactive == nil || m.duration == time.Duration(0) {
- return
- }
- if time.Until(m.LastActivity().Add(m.duration)) <= 0 {
- m.onInactive(cc)
- }
-}
-
-type nilMonitor struct {
-}
-
-func (m *nilMonitor) CheckInactivity(cc ClientConn) {
-}
-
-func (m *nilMonitor) Notify() {
-}
-
-func NewNilMonitor() Monitor {
- return &nilMonitor{}
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/monitor/inactivity/keepalive.go b/vendor/github.com/plgd-dev/go-coap/v2/net/monitor/inactivity/keepalive.go
deleted file mode 100644
index 113d426..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/monitor/inactivity/keepalive.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package inactivity
-
-import (
- "sync/atomic"
-)
-
-type KeepAlive struct {
- pongToken uint64
- sendToken uint64
- numFails uint32
-
- maxRetries uint32
- onInactive OnInactiveFunc
-
- sendPing func(cc ClientConn, receivePong func()) (func(), error)
- cancelPing func()
-}
-
-func NewKeepAlive(maxRetries uint32, onInactive OnInactiveFunc, sendPing func(cc ClientConn, receivePong func()) (func(), error)) *KeepAlive {
- return &KeepAlive{
- maxRetries: maxRetries,
- sendPing: sendPing,
- onInactive: onInactive,
- }
-}
-
-func (m *KeepAlive) OnInactive(cc ClientConn) {
- v := m.incrementFails()
- if m.cancelPing != nil {
- m.cancelPing()
- m.cancelPing = nil
- }
- if v >= m.maxRetries {
- m.onInactive(cc)
- return
- }
- pongToken := atomic.AddUint64(&m.pongToken, 1)
- cancel, err := m.sendPing(cc, func() {
- if atomic.LoadUint64(&m.pongToken) == pongToken {
- m.resetFails()
- }
- })
- if err != nil {
- return
- }
- m.cancelPing = cancel
-}
-
-func (m *KeepAlive) incrementFails() uint32 {
- return atomic.AddUint32(&m.numFails, 1)
-}
-
-func (m *KeepAlive) resetFails() {
- atomic.StoreUint32(&m.numFails, 0)
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/options.go b/vendor/github.com/plgd-dev/go-coap/v2/net/options.go
deleted file mode 100644
index a618456..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/options.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package net
-
-import "time"
-
-// A UDPOption sets options such as heartBeat, errors parameters, etc.
-type UDPOption interface {
- applyUDP(*udpConnOptions)
-}
-
-type HeartBeatOpt struct {
- heartBeat time.Duration
-}
-
-func (h HeartBeatOpt) applyUDP(o *udpConnOptions) {
- o.heartBeat = h.heartBeat
-}
-
-func (h HeartBeatOpt) applyConn(o *connOptions) {
- o.heartBeat = h.heartBeat
-}
-
-func (h HeartBeatOpt) applyTCPListener(o *tcpListenerOptions) {
- o.heartBeat = h.heartBeat
-}
-
-func (h HeartBeatOpt) applyTLSListener(o *tlsListenerOptions) {
- o.heartBeat = h.heartBeat
-}
-
-func (h HeartBeatOpt) applyDTLSListener(o *dtlsListenerOptions) {
- o.heartBeat = h.heartBeat
-}
-
-func WithHeartBeat(v time.Duration) HeartBeatOpt {
- return HeartBeatOpt{
- heartBeat: v,
- }
-}
-
-type ErrorsOpt struct {
- errors func(err error)
-}
-
-func (h ErrorsOpt) applyUDP(o *udpConnOptions) {
- o.errors = h.errors
-}
-
-func WithErrors(v func(err error)) ErrorsOpt {
- return ErrorsOpt{
- errors: v,
- }
-}
-
-type OnTimeoutOpt struct {
- onTimeout func() error
-}
-
-func WithOnTimeout(onTimeout func() error) OnTimeoutOpt {
- return OnTimeoutOpt{
- onTimeout: onTimeout,
- }
-}
-
-func (h OnTimeoutOpt) applyConn(o *connOptions) {
- o.onReadTimeout = h.onTimeout
- o.onWriteTimeout = h.onTimeout
-}
-
-func (h OnTimeoutOpt) applyUDP(o *udpConnOptions) {
- o.onReadTimeout = h.onTimeout
- o.onWriteTimeout = h.onTimeout
-}
-
-func (h OnTimeoutOpt) applyTCPListener(o *tcpListenerOptions) {
- o.onTimeout = h.onTimeout
-}
-
-func (h OnTimeoutOpt) applyTLSListener(o *tlsListenerOptions) {
- o.onTimeout = h.onTimeout
-}
-
-func (h OnTimeoutOpt) applyDTLSListener(o *dtlsListenerOptions) {
- o.onTimeout = h.onTimeout
-}
-
-type OnReadTimeoutOpt struct {
- onReadTimeout func() error
-}
-
-func WithOnReadTimeout(onReadTimeout func() error) OnReadTimeoutOpt {
- return OnReadTimeoutOpt{
- onReadTimeout: onReadTimeout,
- }
-}
-
-func (h OnReadTimeoutOpt) applyConn(o *connOptions) {
- o.onReadTimeout = h.onReadTimeout
-}
-
-func (h OnReadTimeoutOpt) applyUDP(o *udpConnOptions) {
- o.onReadTimeout = h.onReadTimeout
-}
-
-type OnWriteTimeoutOpt struct {
- onWriteTimeout func() error
-}
-
-func WithOnWriteTimeout(onWriteTimeout func() error) OnWriteTimeoutOpt {
- return OnWriteTimeoutOpt{
- onWriteTimeout: onWriteTimeout,
- }
-}
-
-func (h OnWriteTimeoutOpt) applyConn(o *connOptions) {
- o.onWriteTimeout = h.onWriteTimeout
-}
-
-func (h OnWriteTimeoutOpt) applyUDP(o *udpConnOptions) {
- o.onWriteTimeout = h.onWriteTimeout
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/tcplistener.go b/vendor/github.com/plgd-dev/go-coap/v2/net/tcplistener.go
deleted file mode 100644
index c921276..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/tcplistener.go
+++ /dev/null
@@ -1,115 +0,0 @@
-package net
-
-import (
- "context"
- "fmt"
- "net"
- "sync/atomic"
- "time"
-)
-
-// TCPListener is a TCP network listener that provides accept with context.
-type TCPListener struct {
- listener *net.TCPListener
- heartBeat time.Duration
- closed uint32
- onTimeout func() error
-}
-
-func newNetTCPListen(network string, addr string) (*net.TCPListener, error) {
- a, err := net.ResolveTCPAddr(network, addr)
- if err != nil {
- return nil, fmt.Errorf("cannot create new net tcp listener: %w", err)
- }
-
- tcp, err := net.ListenTCP(network, a)
- if err != nil {
- return nil, fmt.Errorf("cannot create new net tcp listener: %w", err)
- }
- return tcp, nil
-}
-
-var defaultTCPListenerOptions = tcpListenerOptions{
- heartBeat: time.Millisecond * 200,
-}
-
-type tcpListenerOptions struct {
- heartBeat time.Duration
- onTimeout func() error
-}
-
-// A TCPListenerOption sets options such as heartBeat parameters, etc.
-type TCPListenerOption interface {
- applyTCPListener(*tcpListenerOptions)
-}
-
-// NewTCPListener creates tcp listener.
-// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only).
-func NewTCPListener(network string, addr string, opts ...TCPListenerOption) (*TCPListener, error) {
- cfg := defaultTCPListenerOptions
- for _, o := range opts {
- o.applyTCPListener(&cfg)
- }
- tcp, err := newNetTCPListen(network, addr)
- if err != nil {
- return nil, fmt.Errorf("cannot create new tcp listener: %w", err)
- }
- return &TCPListener{listener: tcp, heartBeat: cfg.heartBeat, onTimeout: cfg.onTimeout}, nil
-}
-
-// AcceptWithContext waits with context for a generic Conn.
-func (l *TCPListener) AcceptWithContext(ctx context.Context) (net.Conn, error) {
- for {
- select {
- case <-ctx.Done():
- return nil, ctx.Err()
- default:
- }
- if atomic.LoadUint32(&l.closed) == 1 {
- return nil, ErrListenerIsClosed
- }
- deadline := time.Now().Add(l.heartBeat)
- err := l.SetDeadline(deadline)
- if err != nil {
- return nil, fmt.Errorf("cannot set deadline to accept connection: %w", err)
- }
- rw, err := l.listener.Accept()
- if err != nil {
- // check context in regular intervals and then resume listening
- if isTemporary(err, deadline) {
- if l.onTimeout != nil {
- err := l.onTimeout()
- if err != nil {
- return nil, fmt.Errorf("cannot accept connection : on timeout returns error: %w", err)
- }
- }
- continue
- }
- return nil, fmt.Errorf("cannot accept connection: %w", err)
- }
- return rw, nil
- }
-}
-
-// SetDeadline sets deadline for accept operation.
-func (l *TCPListener) SetDeadline(t time.Time) error {
- return l.listener.SetDeadline(t)
-}
-
-// Accept waits for a generic Conn.
-func (l *TCPListener) Accept() (net.Conn, error) {
- return l.AcceptWithContext(context.Background())
-}
-
-// Close closes the connection.
-func (l *TCPListener) Close() error {
- if !atomic.CompareAndSwapUint32(&l.closed, 0, 1) {
- return nil
- }
- return l.listener.Close()
-}
-
-// Addr represents a network end point address.
-func (l *TCPListener) Addr() net.Addr {
- return l.listener.Addr()
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/tlslistener.go b/vendor/github.com/plgd-dev/go-coap/v2/net/tlslistener.go
deleted file mode 100644
index 609f2b7..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/tlslistener.go
+++ /dev/null
@@ -1,108 +0,0 @@
-package net
-
-import (
- "context"
- "crypto/tls"
- "fmt"
- "net"
- "sync/atomic"
- "time"
-)
-
-// TLSListener is a TLS listener that provides accept with context.
-type TLSListener struct {
- tcp *net.TCPListener
- listener net.Listener
- heartBeat time.Duration
- closed uint32
- onTimeout func() error
-}
-
-var defaultTLSListenerOptions = tlsListenerOptions{
- heartBeat: time.Millisecond * 200,
-}
-
-type tlsListenerOptions struct {
- heartBeat time.Duration
- onTimeout func() error
-}
-
-// A TLSListenerOption sets options such as heartBeat parameters, etc.
-type TLSListenerOption interface {
- applyTLSListener(*tlsListenerOptions)
-}
-
-// NewTLSListener creates tcp listener.
-// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only).
-func NewTLSListener(network string, addr string, tlsCfg *tls.Config, opts ...TLSListenerOption) (*TLSListener, error) {
- cfg := defaultTLSListenerOptions
- for _, o := range opts {
- o.applyTLSListener(&cfg)
- }
- tcp, err := newNetTCPListen(network, addr)
- if err != nil {
- return nil, fmt.Errorf("cannot create new tls listener: %w", err)
- }
- tls := tls.NewListener(tcp, tlsCfg)
- return &TLSListener{
- tcp: tcp,
- listener: tls,
- heartBeat: cfg.heartBeat,
- }, nil
-}
-
-// AcceptWithContext waits with context for a generic Conn.
-func (l *TLSListener) AcceptWithContext(ctx context.Context) (net.Conn, error) {
- for {
- select {
- case <-ctx.Done():
- return nil, ctx.Err()
- default:
- }
- if atomic.LoadUint32(&l.closed) == 1 {
- return nil, ErrListenerIsClosed
- }
- deadline := time.Now().Add(l.heartBeat)
- err := l.SetDeadline(deadline)
- if err != nil {
- return nil, fmt.Errorf("cannot set deadline to accept connection: %w", err)
- }
- rw, err := l.listener.Accept()
- if err != nil {
- if isTemporary(err, deadline) {
- if l.onTimeout != nil {
- err := l.onTimeout()
- if err != nil {
- return nil, fmt.Errorf("cannot accept connection : on timeout returns error: %w", err)
- }
- }
- continue
- }
- return nil, fmt.Errorf("cannot accept connection: %w", err)
- }
- return rw, nil
- }
-}
-
-// SetDeadline sets deadline for accept operation.
-func (l *TLSListener) SetDeadline(t time.Time) error {
- return l.tcp.SetDeadline(t)
-}
-
-// Accept waits for a generic Conn.
-func (l *TLSListener) Accept() (net.Conn, error) {
- return l.AcceptWithContext(context.Background())
-}
-
-// Close closes the connection.
-func (l *TLSListener) Close() error {
- if !atomic.CompareAndSwapUint32(&l.closed, 0, 1) {
- return nil
- }
- return l.listener.Close()
-}
-
-// Addr represents a network end point address.
-func (l *TLSListener) Addr() net.Addr {
- return l.listener.Addr()
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/client.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/client.go
deleted file mode 100644
index c8e61eb..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/client.go
+++ /dev/null
@@ -1,191 +0,0 @@
-package udp
-
-import (
- "context"
- "fmt"
- "net"
- "time"
-
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/net/blockwise"
- "github.com/plgd-dev/go-coap/v2/net/monitor/inactivity"
- kitSync "github.com/plgd-dev/kit/sync"
-
- "github.com/plgd-dev/go-coap/v2/message/codes"
- coapNet "github.com/plgd-dev/go-coap/v2/net"
- "github.com/plgd-dev/go-coap/v2/udp/client"
- udpMessage "github.com/plgd-dev/go-coap/v2/udp/message"
- "github.com/plgd-dev/go-coap/v2/udp/message/pool"
-)
-
-var defaultDialOptions = dialOptions{
- ctx: context.Background(),
- maxMessageSize: 64 * 1024,
- heartBeat: time.Millisecond * 100,
- handler: func(w *client.ResponseWriter, r *pool.Message) {
- switch r.Code() {
- case codes.POST, codes.PUT, codes.GET, codes.DELETE:
- w.SetResponse(codes.NotFound, message.TextPlain, nil)
- }
- },
- errors: func(err error) {
- fmt.Println(err)
- },
- goPool: func(f func()) error {
- go func() {
- f()
- }()
- return nil
- },
- dialer: &net.Dialer{Timeout: time.Second * 3},
- net: "udp",
- blockwiseSZX: blockwise.SZX1024,
- blockwiseEnable: true,
- blockwiseTransferTimeout: time.Second * 3,
- transmissionNStart: time.Second,
- transmissionAcknowledgeTimeout: time.Second * 2,
- transmissionMaxRetransmit: 4,
- getMID: udpMessage.GetMID,
- createInactivityMonitor: func() inactivity.Monitor {
- return inactivity.NewNilMonitor()
- },
-}
-
-type dialOptions struct {
- ctx context.Context
- maxMessageSize int
- heartBeat time.Duration
- handler HandlerFunc
- errors ErrorFunc
- goPool GoPoolFunc
- dialer *net.Dialer
- net string
- blockwiseSZX blockwise.SZX
- blockwiseEnable bool
- blockwiseTransferTimeout time.Duration
- transmissionNStart time.Duration
- transmissionAcknowledgeTimeout time.Duration
- transmissionMaxRetransmit int
- getMID GetMIDFunc
- closeSocket bool
- createInactivityMonitor func() inactivity.Monitor
-}
-
-// A DialOption sets options such as credentials, keepalive parameters, etc.
-type DialOption interface {
- applyDial(*dialOptions)
-}
-
-// Dial creates a client connection to the given target.
-func Dial(target string, opts ...DialOption) (*client.ClientConn, error) {
- cfg := defaultDialOptions
- for _, o := range opts {
- o.applyDial(&cfg)
- }
-
- c, err := cfg.dialer.DialContext(cfg.ctx, cfg.net, target)
- if err != nil {
- return nil, err
- }
- conn, ok := c.(*net.UDPConn)
- if !ok {
- return nil, fmt.Errorf("unsupported connection type: %T", c)
- }
- opts = append(opts, WithCloseSocket())
- return Client(conn, opts...), nil
-}
-
-func bwAcquireMessage(ctx context.Context) blockwise.Message {
- return pool.AcquireMessage(ctx)
-}
-
-func bwReleaseMessage(m blockwise.Message) {
- pool.ReleaseMessage(m.(*pool.Message))
-}
-
-func bwCreateHandlerFunc(observatioRequests *kitSync.Map) func(token message.Token) (blockwise.Message, bool) {
- return func(token message.Token) (blockwise.Message, bool) {
- msg, ok := observatioRequests.LoadWithFunc(token.String(), func(v interface{}) interface{} {
- r := v.(*pool.Message)
- d := pool.AcquireMessage(r.Context())
- d.ResetOptionsTo(r.Options())
- d.SetCode(r.Code())
- d.SetToken(r.Token())
- d.SetMessageID(r.MessageID())
- return d
- })
- if !ok {
- return nil, ok
- }
- bwMessage := msg.(blockwise.Message)
- return bwMessage, ok
- }
-}
-
-// Client creates client over udp connection.
-func Client(conn *net.UDPConn, opts ...DialOption) *client.ClientConn {
- cfg := defaultDialOptions
- for _, o := range opts {
- o.applyDial(&cfg)
- }
- if cfg.errors == nil {
- cfg.errors = func(error) {}
- }
- if cfg.createInactivityMonitor == nil {
- cfg.createInactivityMonitor = func() inactivity.Monitor {
- return inactivity.NewNilMonitor()
- }
- }
-
- errors := cfg.errors
- cfg.errors = func(err error) {
- errors(fmt.Errorf("udp: %v: %w", conn.RemoteAddr(), err))
- }
-
- addr, _ := conn.RemoteAddr().(*net.UDPAddr)
- observatioRequests := kitSync.NewMap()
- var blockWise *blockwise.BlockWise
- if cfg.blockwiseEnable {
- blockWise = blockwise.NewBlockWise(
- bwAcquireMessage,
- bwReleaseMessage,
- cfg.blockwiseTransferTimeout,
- cfg.errors,
- false,
- bwCreateHandlerFunc(observatioRequests),
- )
- }
-
- observationTokenHandler := client.NewHandlerContainer()
- monitor := cfg.createInactivityMonitor()
- var cc *client.ClientConn
- l := coapNet.NewUDPConn(cfg.net, conn, coapNet.WithHeartBeat(cfg.heartBeat), coapNet.WithErrors(cfg.errors), coapNet.WithOnReadTimeout(func() error {
- monitor.CheckInactivity(cc)
- return nil
- }))
- session := NewSession(cfg.ctx,
- l,
- addr,
- cfg.maxMessageSize,
- cfg.closeSocket,
- )
- cc = client.NewClientConn(session,
- observationTokenHandler, observatioRequests, cfg.transmissionNStart, cfg.transmissionAcknowledgeTimeout, cfg.transmissionMaxRetransmit,
- client.NewObservationHandler(observationTokenHandler, cfg.handler),
- cfg.blockwiseSZX,
- blockWise,
- cfg.goPool,
- cfg.errors,
- cfg.getMID,
- monitor,
- )
-
- go func() {
- err := cc.Run()
- if err != nil {
- cfg.errors(err)
- }
- }()
-
- return cc
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/client.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/client/client.go
deleted file mode 100644
index 390011f..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/client.go
+++ /dev/null
@@ -1,124 +0,0 @@
-package client
-
-import (
- "context"
- "io"
- "net"
-
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/mux"
- "github.com/plgd-dev/go-coap/v2/udp/message/pool"
-)
-
-type Client struct {
- cc *ClientConn
-}
-
-func NewClient(cc *ClientConn) *Client {
- return &Client{
- cc: cc,
- }
-}
-
-func (c *Client) Ping(ctx context.Context) error {
- return c.cc.Ping(ctx)
-}
-
-func (c *Client) Delete(ctx context.Context, path string, opts ...message.Option) (*message.Message, error) {
- resp, err := c.cc.Delete(ctx, path, opts...)
- if err != nil {
- return nil, err
- }
- defer pool.ReleaseMessage(resp)
- return pool.ConvertTo(resp)
-}
-
-func (c *Client) Put(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*message.Message, error) {
- resp, err := c.cc.Put(ctx, path, contentFormat, payload, opts...)
- if err != nil {
- return nil, err
- }
- defer pool.ReleaseMessage(resp)
- return pool.ConvertTo(resp)
-}
-
-func (c *Client) Post(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*message.Message, error) {
- resp, err := c.cc.Post(ctx, path, contentFormat, payload, opts...)
- if err != nil {
- return nil, err
- }
- defer pool.ReleaseMessage(resp)
- return pool.ConvertTo(resp)
-}
-
-func (c *Client) Get(ctx context.Context, path string, opts ...message.Option) (*message.Message, error) {
- resp, err := c.cc.Get(ctx, path, opts...)
- if err != nil {
- return nil, err
- }
- defer pool.ReleaseMessage(resp)
- return pool.ConvertTo(resp)
-}
-
-func (c *Client) Close() error {
- return c.cc.Close()
-}
-
-func (c *Client) RemoteAddr() net.Addr {
- return c.cc.RemoteAddr()
-}
-
-func (c *Client) Context() context.Context {
- return c.cc.Context()
-}
-
-func (c *Client) SetContextValue(key interface{}, val interface{}) {
- c.cc.Session().SetContextValue(key, val)
-}
-
-func (c *Client) WriteMessage(req *message.Message) error {
- r, err := pool.ConvertFrom(req)
- if err != nil {
- return err
- }
- defer pool.ReleaseMessage(r)
- return c.cc.WriteMessage(r)
-}
-
-func (c *Client) Do(req *message.Message) (*message.Message, error) {
- r, err := pool.ConvertFrom(req)
- if err != nil {
- return nil, err
- }
- defer pool.ReleaseMessage(r)
- resp, err := c.cc.Do(r)
- if err != nil {
- return nil, err
- }
- defer pool.ReleaseMessage(resp)
- return pool.ConvertTo(resp)
-}
-
-func createClientConnObserveHandler(observeFunc func(notification *message.Message)) func(n *pool.Message) {
- return func(n *pool.Message) {
- muxn, err := pool.ConvertTo(n)
- if err != nil {
- return
- }
- observeFunc(muxn)
- }
-}
-
-func (c *Client) Observe(ctx context.Context, path string, observeFunc func(notification *message.Message), opts ...message.Option) (mux.Observation, error) {
- return c.cc.Observe(ctx, path, createClientConnObserveHandler(observeFunc), opts...)
-}
-
-// Sequence acquires sequence number.
-func (c *Client) Sequence() uint64 {
- return c.cc.Sequence()
-}
-
-// ClientConn get's underlaying client connection.
-func (c *Client) ClientConn() interface{} {
- return c.cc
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/clientconn.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/client/clientconn.go
deleted file mode 100644
index b123746..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/clientconn.go
+++ /dev/null
@@ -1,681 +0,0 @@
-package client
-
-import (
- "context"
- "fmt"
- "io"
- "net"
- "sync/atomic"
- "time"
-
- atomicTypes "go.uber.org/atomic"
-
- "github.com/patrickmn/go-cache"
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/net/blockwise"
-
- "github.com/plgd-dev/go-coap/v2/message/codes"
- udpMessage "github.com/plgd-dev/go-coap/v2/udp/message"
- "github.com/plgd-dev/go-coap/v2/udp/message/pool"
- kitSync "github.com/plgd-dev/kit/sync"
-)
-
-type HandlerFunc = func(*ResponseWriter, *pool.Message)
-type ErrorFunc = func(error)
-type GoPoolFunc = func(func()) error
-type EventFunc = func()
-type GetMIDFunc = func() uint16
-
-type Session interface {
- Context() context.Context
- Close() error
- MaxMessageSize() int
- RemoteAddr() net.Addr
- WriteMessage(req *pool.Message) error
- Run(cc *ClientConn) error
- AddOnClose(f EventFunc)
- SetContextValue(key interface{}, val interface{})
-}
-
-type Notifier interface {
- Notify()
-}
-
-// ClientConn represents a virtual connection to a conceptual endpoint, to perform COAPs commands.
-type ClientConn struct {
- // This field needs to be the first in the struct to ensure proper word alignment on 32-bit platforms.
- // See: https://golang.org/pkg/sync/atomic/#pkg-note-BUG
- sequence uint64
- session Session
- handler HandlerFunc
- observationTokenHandler *HandlerContainer
- observationRequests *kitSync.Map
- transmission *Transmission
- blockwiseSZX blockwise.SZX
- blockWise *blockwise.BlockWise
- goPool GoPoolFunc
- errors ErrorFunc
- getMID GetMIDFunc
- responseMsgCache *cache.Cache
- msgIdMutex *MutexMap
- activityMonitor Notifier
-
- tokenHandlerContainer *HandlerContainer
- midHandlerContainer *HandlerContainer
-}
-
-// Transmission is a threadsafe container for transmission related parameters
-type Transmission struct {
- nStart *atomicTypes.Duration
- acknowledgeTimeout *atomicTypes.Duration
- maxRetransmit *atomicTypes.Int32
-}
-
-func (t *Transmission) SetTransmissionNStart(d time.Duration) {
- t.nStart.Store(d)
-}
-
-func (t *Transmission) SetTransmissionAcknowledgeTimeout(d time.Duration) {
- t.acknowledgeTimeout.Store(d)
-}
-
-func (t *Transmission) SetTransmissionMaxRetransmit(d int32) {
- t.maxRetransmit.Store(d)
-}
-
-func (cc *ClientConn) Transmission() *Transmission {
- return cc.transmission
-}
-
-// NewClientConn creates connection over session and observation.
-func NewClientConn(
- session Session,
- observationTokenHandler *HandlerContainer,
- observationRequests *kitSync.Map,
- transmissionNStart time.Duration,
- transmissionAcknowledgeTimeout time.Duration,
- transmissionMaxRetransmit int,
- handler HandlerFunc,
- blockwiseSZX blockwise.SZX,
- blockWise *blockwise.BlockWise,
- goPool GoPoolFunc,
- errors ErrorFunc,
- getMID GetMIDFunc,
- activityMonitor Notifier,
-) *ClientConn {
- if errors == nil {
- errors = func(error) {}
- }
- if getMID == nil {
- getMID = udpMessage.GetMID
- }
- if activityMonitor == nil {
- activityMonitor = &nilNotifier{}
- }
-
- return &ClientConn{
- session: session,
- observationTokenHandler: observationTokenHandler,
- observationRequests: observationRequests,
- transmission: &Transmission{
- atomicTypes.NewDuration(transmissionNStart),
- atomicTypes.NewDuration(transmissionAcknowledgeTimeout),
- atomicTypes.NewInt32(int32(transmissionMaxRetransmit)),
- },
- handler: handler,
- blockwiseSZX: blockwiseSZX,
- blockWise: blockWise,
-
- tokenHandlerContainer: NewHandlerContainer(),
- midHandlerContainer: NewHandlerContainer(),
- goPool: goPool,
- errors: errors,
- getMID: getMID,
- // EXCHANGE_LIFETIME = 247
- responseMsgCache: cache.New(247*time.Second, 60*time.Second),
- msgIdMutex: NewMutexMap(),
- activityMonitor: activityMonitor,
- }
-}
-
-func (cc *ClientConn) Session() Session {
- return cc.session
-}
-
-// Close closes connection without wait of ends Run function.
-func (cc *ClientConn) Close() error {
- return cc.session.Close()
-}
-
-func (cc *ClientConn) do(req *pool.Message) (*pool.Message, error) {
- token := req.Token()
- if token == nil {
- return nil, fmt.Errorf("invalid token")
- }
-
- respChan := make(chan *pool.Message, 1)
- err := cc.tokenHandlerContainer.Insert(token, func(w *ResponseWriter, r *pool.Message) {
- r.Hijack()
- select {
- case respChan <- r:
- default:
- }
- })
- if err != nil {
- return nil, fmt.Errorf("cannot add token handler: %w", err)
- }
- defer cc.tokenHandlerContainer.Pop(token)
- err = cc.writeMessage(req)
- if err != nil {
- return nil, fmt.Errorf("cannot write request: %w", err)
- }
- select {
- case <-req.Context().Done():
- return nil, req.Context().Err()
- case <-cc.session.Context().Done():
- return nil, fmt.Errorf("connection was closed: %w", cc.session.Context().Err())
- case resp := <-respChan:
- return resp, nil
- }
-}
-
-// Do sends an coap message and returns an coap response.
-//
-// An error is returned if by failure to speak COAP (such as a network connectivity problem).
-// Any status code doesn't cause an error.
-//
-// Caller is responsible to release request and response.
-func (cc *ClientConn) Do(req *pool.Message) (*pool.Message, error) {
- if cc.blockWise == nil {
- return cc.do(req)
- }
- bwresp, err := cc.blockWise.Do(req, cc.blockwiseSZX, cc.session.MaxMessageSize(), func(bwreq blockwise.Message) (blockwise.Message, error) {
- return cc.do(bwreq.(*pool.Message))
- })
- if err != nil {
- return nil, err
- }
- return bwresp.(*pool.Message), nil
-}
-
-func (cc *ClientConn) writeMessage(req *pool.Message) error {
- req.SetMessageID(cc.getMID())
- respChan := make(chan struct{})
-
- // Only confirmable messages ever match an message ID
- if req.Type() == udpMessage.Confirmable {
- err := cc.midHandlerContainer.Insert(req.MessageID(), func(w *ResponseWriter, r *pool.Message) {
- close(respChan)
- if r.IsSeparate() {
- // separate message - just accept
- return
- }
- cc.handleBW(w, r)
- })
- if err != nil {
- return fmt.Errorf("cannot insert mid handler: %w", err)
- }
- defer cc.midHandlerContainer.Pop(req.MessageID())
- }
-
- err := cc.session.WriteMessage(req)
- if err != nil {
- return fmt.Errorf("cannot write request: %w", err)
- }
- if req.Type() != udpMessage.Confirmable {
- // If the request is not confirmable, we do not need to wait for a response
- // and skip retransmissions
- close(respChan)
- }
-
- maxRetransmit := cc.transmission.maxRetransmit.Load()
- for i := int32(0); i < maxRetransmit; i++ {
- select {
- case <-respChan:
- return nil
- case <-req.Context().Done():
- return req.Context().Err()
- case <-cc.Context().Done():
- return fmt.Errorf("connection was closed: %w", cc.Context().Err())
- case <-time.After(cc.transmission.acknowledgeTimeout.Load()):
- select {
- case <-req.Context().Done():
- return req.Context().Err()
- case <-cc.session.Context().Done():
- return fmt.Errorf("connection was closed: %w", cc.Context().Err())
- case <-time.After(cc.transmission.nStart.Load()):
- err = cc.session.WriteMessage(req)
- if err != nil {
- return fmt.Errorf("cannot write request: %w", err)
- }
- }
- }
- }
- return fmt.Errorf("timeout: retransmision(%v) was exhausted", cc.transmission.maxRetransmit.Load())
-}
-
-// WriteMessage sends an coap message.
-func (cc *ClientConn) WriteMessage(req *pool.Message) error {
- if cc.blockWise == nil {
- return cc.writeMessage(req)
- }
- return cc.blockWise.WriteMessage(req, cc.blockwiseSZX, cc.session.MaxMessageSize(), func(bwreq blockwise.Message) error {
- return cc.writeMessage(bwreq.(*pool.Message))
- })
-}
-
-func (cc *ClientConn) doWithMID(req *pool.Message) (*pool.Message, error) {
- respChan := make(chan *pool.Message, 1)
- err := cc.midHandlerContainer.Insert(req.MessageID(), func(w *ResponseWriter, r *pool.Message) {
- r.Hijack()
- select {
- case respChan <- r:
- default:
- }
- })
- if err != nil {
- return nil, fmt.Errorf("cannot insert mid handler: %w", err)
- }
- defer cc.midHandlerContainer.Pop(req.MessageID())
- err = cc.session.WriteMessage(req)
- if err != nil {
- return nil, fmt.Errorf("cannot write request: %w", err)
- }
-
- select {
- case <-req.Context().Done():
- return nil, req.Context().Err()
- case <-cc.session.Context().Done():
- return nil, fmt.Errorf("connection was closed: %w", cc.session.Context().Err())
- case resp := <-respChan:
- return resp, nil
- }
-}
-
-func newCommonRequest(ctx context.Context, code codes.Code, path string, opts ...message.Option) (*pool.Message, error) {
- token, err := message.GetToken()
- if err != nil {
- return nil, fmt.Errorf("cannot get token: %w", err)
- }
- req := pool.AcquireMessage(ctx)
- req.SetCode(code)
- req.SetToken(token)
- req.ResetOptionsTo(opts)
- req.SetPath(path)
- req.SetType(udpMessage.Confirmable)
- return req, nil
-}
-
-// NewGetRequest creates get request.
-//
-// Use ctx to set timeout.
-func NewGetRequest(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error) {
- return newCommonRequest(ctx, codes.GET, path, opts...)
-}
-
-// Get issues a GET to the specified path.
-//
-// Use ctx to set timeout.
-//
-// An error is returned if by failure to speak COAP (such as a network connectivity problem).
-// Any status code doesn't cause an error.
-func (cc *ClientConn) Get(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error) {
- req, err := NewGetRequest(ctx, path, opts...)
- if err != nil {
- return nil, fmt.Errorf("cannot create get request: %w", err)
- }
- defer pool.ReleaseMessage(req)
- return cc.Do(req)
-}
-
-// NewPostRequest creates post request.
-//
-// Use ctx to set timeout.
-//
-// An error is returned if by failure to speak COAP (such as a network connectivity problem).
-// Any status code doesn't cause an error.
-//
-// If payload is nil then content format is not used.
-func NewPostRequest(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error) {
- req, err := newCommonRequest(ctx, codes.POST, path, opts...)
- if err != nil {
- return nil, err
- }
- if payload != nil {
- req.SetContentFormat(contentFormat)
- req.SetBody(payload)
- }
- return req, nil
-}
-
-// Post issues a POST to the specified path.
-//
-// Use ctx to set timeout.
-//
-// An error is returned if by failure to speak COAP (such as a network connectivity problem).
-// Any status code doesn't cause an error.
-//
-// If payload is nil then content format is not used.
-func (cc *ClientConn) Post(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error) {
- req, err := NewPostRequest(ctx, path, contentFormat, payload, opts...)
- if err != nil {
- return nil, fmt.Errorf("cannot create post request: %w", err)
- }
- defer pool.ReleaseMessage(req)
- return cc.Do(req)
-}
-
-// NewPutRequest creates put request.
-//
-// Use ctx to set timeout.
-//
-// If payload is nil then content format is not used.
-func NewPutRequest(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error) {
- req, err := newCommonRequest(ctx, codes.PUT, path, opts...)
- if err != nil {
- return nil, err
- }
- if payload != nil {
- req.SetContentFormat(contentFormat)
- req.SetBody(payload)
- }
- return req, nil
-}
-
-// Put issues a PUT to the specified path.
-//
-// Use ctx to set timeout.
-//
-// An error is returned if by failure to speak COAP (such as a network connectivity problem).
-// Any status code doesn't cause an error.
-//
-// If payload is nil then content format is not used.
-func (cc *ClientConn) Put(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error) {
- req, err := NewPutRequest(ctx, path, contentFormat, payload, opts...)
- if err != nil {
- return nil, fmt.Errorf("cannot create put request: %w", err)
- }
- defer pool.ReleaseMessage(req)
- return cc.Do(req)
-}
-
-// NewDeleteRequest creates delete request.
-//
-// Use ctx to set timeout.
-func NewDeleteRequest(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error) {
- return newCommonRequest(ctx, codes.DELETE, path, opts...)
-}
-
-// Delete deletes the resource identified by the request path.
-//
-// Use ctx to set timeout.
-func (cc *ClientConn) Delete(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error) {
- req, err := NewDeleteRequest(ctx, path, opts...)
- if err != nil {
- return nil, fmt.Errorf("cannot create delete request: %w", err)
- }
- defer pool.ReleaseMessage(req)
- return cc.Do(req)
-}
-
-// Context returns the client's context.
-//
-// If connections was closed context is cancelled.
-func (cc *ClientConn) Context() context.Context {
- return cc.session.Context()
-}
-
-// Ping issues a PING to the client and waits for PONG reponse.
-//
-// Use ctx to set timeout.
-func (cc *ClientConn) Ping(ctx context.Context) error {
- resp := make(chan bool, 1)
- receivedPong := func() {
- select {
- case resp <- true:
- default:
- }
- }
- cancel, err := cc.AsyncPing(receivedPong)
- if err != nil {
- return err
- }
- defer cancel()
- select {
- case <-resp:
- return nil
- case <-ctx.Done():
- return ctx.Err()
- }
-}
-
-// AsyncPing sends ping and receivedPong will be called when pong arrives. It returns cancellation of ping operation.
-func (cc *ClientConn) AsyncPing(receivedPong func()) (func(), error) {
- req := pool.AcquireMessage(cc.Context())
- defer pool.ReleaseMessage(req)
- req.SetType(udpMessage.Confirmable)
- req.SetCode(codes.Empty)
- mid := cc.getMID()
- req.SetMessageID(mid)
- err := cc.midHandlerContainer.Insert(mid, func(w *ResponseWriter, r *pool.Message) {
- if r.Type() == udpMessage.Reset || r.Type() == udpMessage.Acknowledgement {
- receivedPong()
- }
- })
- if err != nil {
- return nil, fmt.Errorf("cannot insert mid handler: %w", err)
- }
- err = cc.session.WriteMessage(req)
- if err != nil {
- cc.midHandlerContainer.Pop(mid)
- return nil, fmt.Errorf("cannot write request: %w", err)
- }
- return func() {
- cc.midHandlerContainer.Pop(mid)
- }, nil
-}
-
-// Run reads and process requests from a connection, until the connection is closed.
-func (cc *ClientConn) Run() error {
- return cc.session.Run(cc)
-}
-
-// AddOnClose calls function on close connection event.
-func (cc *ClientConn) AddOnClose(f EventFunc) {
- cc.session.AddOnClose(f)
-}
-
-func (cc *ClientConn) RemoteAddr() net.Addr {
- return cc.session.RemoteAddr()
-}
-
-func (cc *ClientConn) sendPong(w *ResponseWriter, r *pool.Message) {
- w.SetResponse(codes.Empty, message.TextPlain, nil)
-}
-
-type bwResponseWriter struct {
- w *ResponseWriter
-}
-
-func (b *bwResponseWriter) Message() blockwise.Message {
- return b.w.response
-}
-
-func (b *bwResponseWriter) SetMessage(m blockwise.Message) {
- pool.ReleaseMessage(b.w.response)
- b.w.response = m.(*pool.Message)
-}
-
-func (cc *ClientConn) handleBW(w *ResponseWriter, r *pool.Message) {
- if cc.blockWise != nil {
- bwr := bwResponseWriter{
- w: w,
- }
- cc.blockWise.Handle(&bwr, r, cc.blockwiseSZX, cc.session.MaxMessageSize(), func(bw blockwise.ResponseWriter, br blockwise.Message) {
- h, err := cc.tokenHandlerContainer.Pop(r.Token())
- w := bw.(*bwResponseWriter).w
- r := br.(*pool.Message)
- if err == nil {
- h(w, r)
- return
- }
- cc.handler(w, r)
- })
- return
- }
- h, err := cc.tokenHandlerContainer.Pop(r.Token())
- if err == nil {
- h(w, r)
- return
- }
- cc.handler(w, r)
-}
-
-func (cc *ClientConn) handle(w *ResponseWriter, r *pool.Message) {
- if r.Code() == codes.Empty && r.Type() == udpMessage.Confirmable && len(r.Token()) == 0 && len(r.Options()) == 0 && r.Body() == nil {
- cc.sendPong(w, r)
- return
- }
- h, err := cc.midHandlerContainer.Pop(r.MessageID())
- if err == nil {
- h(w, r)
- return
- }
- if r.IsSeparate() {
- // msg was processed by token handler - just drop it.
- return
- }
- cc.handleBW(w, r)
-}
-
-// Sequence acquires sequence number.
-func (cc *ClientConn) Sequence() uint64 {
- return atomic.AddUint64(&cc.sequence, 1)
-}
-
-func (cc *ClientConn) addResponseToCache(resp *pool.Message) error {
- marshaledResp, err := resp.Marshal()
- if err != nil {
- return err
- }
- cacheMsg := make([]byte, len(marshaledResp))
- copy(cacheMsg, marshaledResp)
- cc.responseMsgCache.SetDefault(fmt.Sprintf("%d", resp.MessageID()), cacheMsg)
- return nil
-}
-
-func (cc *ClientConn) getResponseFromCache(mid uint16, resp *pool.Message) (bool, error) {
- cachedResp, _ := cc.responseMsgCache.Get(fmt.Sprintf("%d", mid))
- if rawMsg, ok := cachedResp.([]byte); ok {
- _, err := resp.Unmarshal(rawMsg)
- if err != nil {
- return false, err
- }
- return true, nil
- }
- return false, nil
-}
-
-func (cc *ClientConn) Process(datagram []byte) error {
- if cc.session.MaxMessageSize() >= 0 && len(datagram) > cc.session.MaxMessageSize() {
- return fmt.Errorf("max message size(%v) was exceeded %v", cc.session.MaxMessageSize(), len(datagram))
- }
- req := pool.AcquireMessage(cc.Context())
- _, err := req.Unmarshal(datagram)
- if err != nil {
- pool.ReleaseMessage(req)
- return err
- }
- req.SetSequence(cc.Sequence())
- cc.activityMonitor.Notify()
- cc.goPool(func() {
- defer cc.activityMonitor.Notify()
- reqMid := req.MessageID()
-
- // The same message ID can not be handled concurrently
- // for deduplication to work
- l := cc.msgIdMutex.Lock(reqMid)
- defer l.Unlock()
-
- origResp := pool.AcquireMessage(cc.Context())
- origResp.SetToken(req.Token())
- // If a request is sent in a Non-confirmable message, then the response
- // is sent using a new Non-confirmable message, although the server may
- // instead send a Confirmable message.
- origResp.SetType(req.Type())
- w := NewResponseWriter(origResp, cc, req.Options())
-
- if ok, err := cc.getResponseFromCache(req.MessageID(), w.response); ok {
- defer pool.ReleaseMessage(w.response)
- if !req.IsHijacked() {
- pool.ReleaseMessage(req)
- }
- err = cc.session.WriteMessage(w.response)
- if err != nil {
- cc.Close()
- cc.errors(fmt.Errorf("cannot write response: %w", err))
- return
- }
- return
- } else if err != nil {
- cc.Close()
- cc.errors(fmt.Errorf("cannot unmarshal response from cache: %w", err))
- return
- }
-
- reqType := req.Type()
- origResp.SetModified(false)
- cc.handle(w, req)
-
- defer pool.ReleaseMessage(w.response)
- if !req.IsHijacked() {
- pool.ReleaseMessage(req)
- }
- if w.response.IsModified() {
- switch {
- case w.response.Type() == udpMessage.Reset:
- w.response.SetMessageID(reqMid)
- case reqType == udpMessage.Confirmable:
- w.response.SetType(udpMessage.Acknowledgement)
- w.response.SetMessageID(reqMid)
- default:
- w.response.SetType(udpMessage.NonConfirmable)
- w.response.SetMessageID(cc.getMID())
- }
- err := cc.session.WriteMessage(w.response)
- if err != nil {
- cc.Close()
- cc.errors(fmt.Errorf("cannot write response: %w", err))
- return
- }
- } else if reqType == udpMessage.Confirmable {
- w.response.Reset()
- w.response.SetCode(codes.Empty)
- w.response.SetType(udpMessage.Acknowledgement)
- w.response.SetMessageID(reqMid)
- err := cc.session.WriteMessage(w.response)
- if err != nil {
- cc.Close()
- cc.errors(fmt.Errorf("cannot write ack reponse: %w", err))
- return
- }
- }
-
- err = cc.addResponseToCache(w.response)
- if err != nil {
- cc.Close()
- cc.errors(fmt.Errorf("cannot cache response: %w", err))
- return
- }
- })
- return nil
-}
-
-func (cc *ClientConn) Client() *Client {
- return NewClient(cc)
-}
-
-// SetContextValue stores the value associated with key to context of connection.
-func (cc *ClientConn) SetContextValue(key interface{}, val interface{}) {
- cc.session.SetContextValue(key, val)
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/clientobserve.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/client/clientobserve.go
deleted file mode 100644
index 4302591..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/clientobserve.go
+++ /dev/null
@@ -1,162 +0,0 @@
-package client
-
-import (
- "context"
- "fmt"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/message/codes"
- "github.com/plgd-dev/go-coap/v2/net/observation"
- "github.com/plgd-dev/go-coap/v2/udp/message/pool"
-)
-
-func NewObservationHandler(obsertionTokenHandler *HandlerContainer, next HandlerFunc) HandlerFunc {
- return func(w *ResponseWriter, r *pool.Message) {
- v, err := obsertionTokenHandler.Get(r.Token())
- if err == nil {
- v(w, r)
- return
- }
- obs, err := r.Observe()
- if err == nil && obs > 1 {
- w.SendReset()
- return
- }
- next(w, r)
- }
-}
-
-//Observation represents subscription to resource on the server
-type Observation struct {
- token message.Token
- path string
- cc *ClientConn
- observeFunc func(req *pool.Message)
- respCodeChan chan codes.Code
-
- obsSequence uint32
- etag []byte
- lastEvent time.Time
- mutex sync.Mutex
-
- waitForReponse uint32
-}
-
-func newObservation(token message.Token, path string, cc *ClientConn, observeFunc func(req *pool.Message), respCodeChan chan codes.Code) *Observation {
- return &Observation{
- token: token,
- path: path,
- obsSequence: 0,
- cc: cc,
- waitForReponse: 1,
- respCodeChan: respCodeChan,
- observeFunc: observeFunc,
- }
-}
-
-func (o *Observation) cleanUp() {
- o.cc.observationTokenHandler.Pop(o.token)
- registeredRequest, ok := o.cc.observationRequests.PullOut(o.token.String())
- if ok {
- pool.ReleaseMessage(registeredRequest.(*pool.Message))
- }
-}
-
-func (o *Observation) handler(w *ResponseWriter, r *pool.Message) {
- code := r.Code()
- if atomic.CompareAndSwapUint32(&o.waitForReponse, 1, 0) {
- select {
- case o.respCodeChan <- code:
- default:
- }
- o.respCodeChan = nil
- }
- if o.wantBeNotified(r) {
- o.observeFunc(r)
- }
-}
-
-// Cancel remove observation from server. For recreate observation use Observe.
-func (o *Observation) Cancel(ctx context.Context) error {
- o.cleanUp()
- req, err := NewGetRequest(ctx, o.path)
- if err != nil {
- return fmt.Errorf("cannot cancel observation request: %w", err)
- }
- defer pool.ReleaseMessage(req)
- req.SetObserve(1)
- req.SetToken(o.token)
- resp, err := o.cc.Do(req)
- if err != nil {
- return err
- }
- defer pool.ReleaseMessage(resp)
- if resp.Code() != codes.Content {
- return fmt.Errorf("unexpected return code(%v)", resp.Code())
- }
- return err
-}
-
-func (o *Observation) wantBeNotified(r *pool.Message) bool {
- obsSequence, err := r.Observe()
- if err != nil {
- return true
- }
- now := time.Now()
-
- o.mutex.Lock()
- defer o.mutex.Unlock()
-
- if observation.ValidSequenceNumber(o.obsSequence, obsSequence, o.lastEvent, now) {
- o.obsSequence = obsSequence
- o.lastEvent = now
- return true
- }
-
- return false
-}
-
-// Observe subscribes for every change of resource on path.
-func (cc *ClientConn) Observe(ctx context.Context, path string, observeFunc func(req *pool.Message), opts ...message.Option) (*Observation, error) {
- req, err := NewGetRequest(ctx, path, opts...)
- if err != nil {
- return nil, fmt.Errorf("cannot create observe request: %w", err)
- }
- token := req.Token()
- req.SetObserve(0)
- respCodeChan := make(chan codes.Code, 1)
- o := newObservation(token, path, cc, observeFunc, respCodeChan)
-
- cc.observationRequests.Store(token.String(), req)
- err = o.cc.observationTokenHandler.Insert(token.String(), o.handler)
- defer func(err *error) {
- if *err != nil {
- o.cleanUp()
- }
- }(&err)
- if err != nil {
- return nil, err
- }
-
- err = cc.WriteMessage(req)
- if err != nil {
- return nil, err
- }
- select {
- case <-req.Context().Done():
- err = req.Context().Err()
- return nil, err
- case <-cc.Context().Done():
- err = fmt.Errorf("connection was closed: %w", cc.Context().Err())
- return nil, err
- case respCode := <-respCodeChan:
- if respCode != codes.Content {
- err = fmt.Errorf("unexpected return code(%v)", respCode)
- return nil, err
- }
- return o, nil
- }
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/container.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/client/container.go
deleted file mode 100644
index 4f761f5..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/container.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package client
-
-import (
- "fmt"
- "sync"
-
- "github.com/plgd-dev/go-coap/v2/message"
-)
-
-// HandlerContainer for regirstration handlers by key
-type HandlerContainer struct {
- datas map[interface{}]HandlerFunc
- mutex sync.Mutex
-}
-
-// NewHandlerContainer factory
-func NewHandlerContainer() *HandlerContainer {
- return &HandlerContainer{
- datas: make(map[interface{}]HandlerFunc),
- }
-}
-
-// Insert handler for key.
-func (s *HandlerContainer) Insert(key interface{}, handler HandlerFunc) error {
- if v, ok := key.(message.Token); ok {
- key = v.String()
- }
- s.mutex.Lock()
- defer s.mutex.Unlock()
- if s.datas[key] != nil {
- return fmt.Errorf("key already exist")
- }
- s.datas[key] = handler
- return nil
-}
-
-// Get returns handler for key
-func (s *HandlerContainer) Get(key interface{}) (HandlerFunc, error) {
- if v, ok := key.(message.Token); ok {
- key = v.String()
- }
- s.mutex.Lock()
- defer s.mutex.Unlock()
- v := s.datas[key]
- if v == nil {
- return nil, fmt.Errorf("key not exist")
- }
- return v, nil
-}
-
-// Pop pops handler for key
-func (s *HandlerContainer) Pop(key interface{}) (HandlerFunc, error) {
- if v, ok := key.(message.Token); ok {
- key = v.String()
- }
- s.mutex.Lock()
- defer s.mutex.Unlock()
- v := s.datas[key]
- if v == nil {
- return nil, fmt.Errorf("key not exist")
- }
- delete(s.datas, key)
- return v, nil
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/inactivitymonitor.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/client/inactivitymonitor.go
deleted file mode 100644
index f7f82c7..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/inactivitymonitor.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package client
-
-// nilNotifier implements a Notify method that does nothing
-type nilNotifier struct {
-}
-
-func (n *nilNotifier) Notify() {
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/mux.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/client/mux.go
deleted file mode 100644
index 5e14a8a..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/mux.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package client
-
-import (
- "io"
-
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/message/codes"
- "github.com/plgd-dev/go-coap/v2/mux"
- udpMessage "github.com/plgd-dev/go-coap/v2/udp/message"
- "github.com/plgd-dev/go-coap/v2/udp/message/pool"
-)
-
-func HandlerFuncToMux(m mux.Handler) HandlerFunc {
- h := func(w *ResponseWriter, r *pool.Message) {
- muxw := &muxResponseWriter{
- w: w,
- }
- muxr, err := pool.ConvertTo(r)
- if err != nil {
- return
- }
- m.ServeCOAP(muxw, &mux.Message{
- Message: muxr,
- SequenceNumber: r.Sequence(),
- IsConfirmable: r.Type() == udpMessage.Confirmable,
- })
- }
- return h
-}
-
-type muxResponseWriter struct {
- w *ResponseWriter
-}
-
-func (w *muxResponseWriter) SetResponse(code codes.Code, contentFormat message.MediaType, d io.ReadSeeker, opts ...message.Option) error {
- return w.w.SetResponse(code, contentFormat, d, opts...)
-}
-
-func (w *muxResponseWriter) Client() mux.Client {
- return w.w.ClientConn().Client()
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/responsewriter.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/client/responsewriter.go
deleted file mode 100644
index cb90aad..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/responsewriter.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package client
-
-import (
- "io"
-
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/message/codes"
- "github.com/plgd-dev/go-coap/v2/message/noresponse"
- udpMessage "github.com/plgd-dev/go-coap/v2/udp/message"
- "github.com/plgd-dev/go-coap/v2/udp/message/pool"
-)
-
-// A ResponseWriter interface is used by an COAP handler to construct an COAP response.
-type ResponseWriter struct {
- noResponseValue *uint32
- response *pool.Message
- cc *ClientConn
-}
-
-func NewResponseWriter(response *pool.Message, cc *ClientConn, requestOptions message.Options) *ResponseWriter {
- var noResponseValue *uint32
- v, err := requestOptions.GetUint32(message.NoResponse)
- if err == nil {
- noResponseValue = &v
- }
-
- return &ResponseWriter{
- response: response,
- cc: cc,
- noResponseValue: noResponseValue,
- }
-}
-
-func (r *ResponseWriter) SetResponse(code codes.Code, contentFormat message.MediaType, d io.ReadSeeker, opts ...message.Option) error {
- if r.noResponseValue != nil {
- err := noresponse.IsNoResponseCode(code, *r.noResponseValue)
- if err != nil {
- return err
- }
- }
-
- r.response.SetCode(code)
- r.response.ResetOptionsTo(opts)
- if d != nil {
- r.response.SetContentFormat(contentFormat)
- r.response.SetBody(d)
- if !r.response.HasOption(message.ETag) {
- etag, err := message.GetETag(d)
- if err != nil {
- return err
- }
- r.response.SetOptionBytes(message.ETag, etag)
- }
- }
- return nil
-}
-
-func (r *ResponseWriter) ClientConn() *ClientConn {
- return r.cc
-}
-
-func (r *ResponseWriter) SendReset() {
- r.response.Reset()
- r.response.SetCode(codes.Empty)
- r.response.SetType(udpMessage.Reset)
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/discover.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/discover.go
deleted file mode 100644
index 6c3664f..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/discover.go
+++ /dev/null
@@ -1,81 +0,0 @@
-package udp
-
-import (
- "context"
- "fmt"
- "net"
-
- "github.com/plgd-dev/go-coap/v2/udp/client"
- "github.com/plgd-dev/go-coap/v2/udp/message/pool"
-)
-
-var defaultMulticastOptions = multicastOptions{
- hopLimit: 2,
-}
-
-type multicastOptions struct {
- hopLimit int
-}
-
-// A MulticastOption sets options such as hop limit, etc.
-type MulticastOption interface {
- apply(*multicastOptions)
-}
-
-// Discover sends GET to multicast address and wait for responses until context timeouts or server shutdown.
-func (s *Server) Discover(ctx context.Context, multicastAddr, path string, receiverFunc func(cc *client.ClientConn, resp *pool.Message), opts ...MulticastOption) error {
- req, err := client.NewGetRequest(ctx, path)
- if err != nil {
- return fmt.Errorf("cannot create discover request: %w", err)
- }
- req.SetMessageID(s.getMID())
- defer pool.ReleaseMessage(req)
- return s.DiscoveryRequest(req, multicastAddr, receiverFunc, opts...)
-}
-
-// DiscoveryRequest sends request to multicast addressand wait for responses until request timeouts or server shutdown.
-func (s *Server) DiscoveryRequest(req *pool.Message, multicastAddr string, receiverFunc func(cc *client.ClientConn, resp *pool.Message), opts ...MulticastOption) error {
- token := req.Token()
- if len(token) == 0 {
- return fmt.Errorf("invalid token")
- }
- cfg := defaultMulticastOptions
- for _, o := range opts {
- o.apply(&cfg)
- }
- c := s.conn()
- if c == nil {
- return fmt.Errorf("server doesn't serve connection")
- }
- addr, err := net.ResolveUDPAddr(c.Network(), multicastAddr)
- if err != nil {
- return fmt.Errorf("cannot resolve address: %w", err)
- }
- if !addr.IP.IsMulticast() {
- return fmt.Errorf("invalid multicast address")
- }
- data, err := req.Marshal()
- if err != nil {
- return fmt.Errorf("cannot marshal req: %w", err)
- }
- s.multicastRequests.Store(token.String(), req)
- defer s.multicastRequests.Delete(token.String())
- err = s.multicastHandler.Insert(token, func(w *client.ResponseWriter, r *pool.Message) {
- receiverFunc(w.ClientConn(), r)
- })
- if err != nil {
- return err
- }
- defer s.multicastHandler.Pop(token)
-
- err = c.WriteMulticast(req.Context(), addr, cfg.hopLimit, data)
- if err != nil {
- return err
- }
- select {
- case <-req.Context().Done():
- return nil
- case <-s.ctx.Done():
- return fmt.Errorf("server was closed: %w", s.ctx.Err())
- }
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/message/getmid.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/message/getmid.go
deleted file mode 100644
index 84ded5b..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/message/getmid.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package message
-
-import (
- "crypto/rand"
- "encoding/binary"
- "sync/atomic"
-)
-
-var msgID uint32
-
-func init() {
- b := make([]byte, 4)
- rand.Read(b)
- msgID = binary.BigEndian.Uint32(b)
-}
-
-// GetMID generates a message id for UDP-coap
-func GetMID() uint16 {
- return uint16(atomic.AddUint32(&msgID, 1))
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/message/pool/message.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/message/pool/message.go
deleted file mode 100644
index 8a79efb..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/message/pool/message.go
+++ /dev/null
@@ -1,200 +0,0 @@
-package pool
-
-import (
- "bytes"
- "context"
- "fmt"
- "io"
- "sync"
-
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/message/codes"
- "github.com/plgd-dev/go-coap/v2/message/pool"
- udp "github.com/plgd-dev/go-coap/v2/udp/message"
-)
-
-var (
- messagePool sync.Pool
-)
-
-type Message struct {
- *pool.Message
- messageID uint16
- typ udp.Type
-
- //local vars
- rawData []byte
- rawMarshalData []byte
-
- ctx context.Context
- isModified bool
-}
-
-// Reset clear message for next reuse
-func (r *Message) Reset() {
- r.Message.Reset()
- r.messageID = 0
- r.typ = udp.NonConfirmable
- r.rawData = r.rawData[:0]
- r.rawMarshalData = r.rawMarshalData[:0]
- r.isModified = false
-}
-
-func (r *Message) Context() context.Context {
- return r.ctx
-}
-
-func (r *Message) SetMessageID(mid uint16) {
- r.messageID = mid
- r.isModified = true
-}
-
-func (r *Message) MessageID() uint16 {
- return r.messageID
-}
-
-func (r *Message) SetType(typ udp.Type) {
- r.typ = typ
- r.isModified = true
-}
-
-func (r *Message) Type() udp.Type {
- return r.typ
-}
-
-func (r *Message) IsModified() bool {
- return r.isModified || r.Message.IsModified()
-}
-
-func (r *Message) SetModified(b bool) {
- r.isModified = b
- r.Message.SetModified(b)
-}
-
-func (r *Message) Unmarshal(data []byte) (int, error) {
- r.Reset()
- if len(r.rawData) < len(data) {
- r.rawData = append(r.rawData, make([]byte, len(data)-len(r.rawData))...)
- }
- copy(r.rawData, data)
- r.rawData = r.rawData[:len(data)]
- m := &udp.Message{
- Options: make(message.Options, 0, 16),
- }
-
- n, err := m.Unmarshal(r.rawData)
- if err != nil {
- return n, err
- }
- r.Message.SetCode(m.Code)
- r.Message.SetToken(m.Token)
- r.Message.ResetOptionsTo(m.Options)
- r.typ = m.Type
- r.messageID = m.MessageID
- if len(m.Payload) > 0 {
- r.Message.SetBody(bytes.NewReader(m.Payload))
- }
- return n, err
-}
-
-func (r *Message) Marshal() ([]byte, error) {
- m := udp.Message{
- Code: r.Code(),
- Token: r.Message.Token(),
- Options: r.Message.Options(),
- MessageID: r.messageID,
- Type: r.typ,
- }
- payload, err := r.ReadBody()
- if err != nil {
- return nil, err
- }
- m.Payload = payload
- size, err := m.Size()
- if err != nil {
- return nil, err
- }
- if len(r.rawMarshalData) < size {
- r.rawMarshalData = append(r.rawMarshalData, make([]byte, size-len(r.rawMarshalData))...)
- }
- n, err := m.MarshalTo(r.rawMarshalData)
- if err != nil {
- return nil, err
- }
- r.rawMarshalData = r.rawMarshalData[:n]
- return r.rawMarshalData, nil
-}
-
-func (r *Message) IsSeparate() bool {
- return r.Code() == codes.Empty && r.Token() == nil && r.Type() == udp.Acknowledgement && len(r.Options()) == 0 && r.Body() == nil
-}
-
-func (r *Message) String() string {
- return fmt.Sprintf("Type: %v, MID: %v, %s", r.Type(), r.MessageID(), r.Message.String())
-}
-
-// AcquireMessage returns an empty Message instance from Message pool.
-//
-// The returned Message instance may be passed to ReleaseMessage when it is
-// no longer needed. This allows Message recycling, reduces GC pressure
-// and usually improves performance.
-func AcquireMessage(ctx context.Context) *Message {
- v := messagePool.Get()
- if v == nil {
- return &Message{
- Message: pool.NewMessage(),
- rawData: make([]byte, 256),
- rawMarshalData: make([]byte, 256),
- ctx: ctx,
- }
- }
- r := v.(*Message)
- r.Reset()
- r.ctx = ctx
- return r
-}
-
-// ReleaseMessage returns req acquired via AcquireMessage to Message pool.
-//
-// It is forbidden accessing req and/or its' members after returning
-// it to Message pool.
-func ReleaseMessage(req *Message) {
- req.Reset()
- messagePool.Put(req)
-}
-
-// ConvertFrom converts common message to pool message.
-func ConvertFrom(m *message.Message) (*Message, error) {
- if m.Context == nil {
- return nil, fmt.Errorf("invalid context")
- }
- r := AcquireMessage(m.Context)
- r.SetCode(m.Code)
- r.ResetOptionsTo(m.Options)
- r.SetBody(m.Body)
- r.SetToken(m.Token)
- return r, nil
-}
-
-// ConvertTo converts pool message to common message.
-func ConvertTo(m *Message) (*message.Message, error) {
- opts, err := m.Options().Clone()
- if err != nil {
- return nil, err
- }
- var body io.ReadSeeker
- if m.Body() != nil {
- payload, err := m.ReadBody()
- if err != nil {
- return nil, err
- }
- body = bytes.NewReader(payload)
- }
- return &message.Message{
- Context: m.Context(),
- Code: m.Code(),
- Token: m.Token(),
- Body: body,
- Options: opts,
- }, nil
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/nocopy.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/nocopy.go
deleted file mode 100644
index a737fe4..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/nocopy.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package udp
-
-// Embed this type into a struct, which mustn't be copied,
-// so `go vet` gives a warning if this struct is copied.
-//
-// See https://github.com/golang/go/issues/8005#issuecomment-190753527 for details.
-// and also: https://stackoverflow.com/questions/52494458/nocopy-minimal-example
-
-type noCopy struct{}
-
-func (*noCopy) Lock() {}
-func (*noCopy) Unlock() {}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/optionmux.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/optionmux.go
deleted file mode 100644
index 04c1d3a..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/optionmux.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package udp
-
-import (
- "github.com/plgd-dev/go-coap/v2/mux"
- "github.com/plgd-dev/go-coap/v2/udp/client"
-)
-
-// WithMux set's multiplexer for handle requests.
-func WithMux(m mux.Handler) HandlerFuncOpt {
- return WithHandlerFunc(client.HandlerFuncToMux(m))
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/options.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/options.go
deleted file mode 100644
index cea2c07..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/options.go
+++ /dev/null
@@ -1,314 +0,0 @@
-package udp
-
-import (
- "context"
- "net"
- "time"
-
- "github.com/plgd-dev/go-coap/v2/net/blockwise"
- "github.com/plgd-dev/go-coap/v2/net/monitor/inactivity"
- "github.com/plgd-dev/go-coap/v2/udp/client"
-)
-
-// HandlerFuncOpt handler function option.
-type HandlerFuncOpt struct {
- h HandlerFunc
-}
-
-func (o HandlerFuncOpt) apply(opts *serverOptions) {
- opts.handler = o.h
-}
-
-func (o HandlerFuncOpt) applyDial(opts *dialOptions) {
- opts.handler = o.h
-}
-
-// WithHandlerFunc set handle for handling request's.
-func WithHandlerFunc(h HandlerFunc) HandlerFuncOpt {
- return HandlerFuncOpt{h: h}
-}
-
-// ContextOpt handler function option.
-type ContextOpt struct {
- ctx context.Context
-}
-
-func (o ContextOpt) apply(opts *serverOptions) {
- opts.ctx = o.ctx
-}
-
-func (o ContextOpt) applyDial(opts *dialOptions) {
- opts.ctx = o.ctx
-}
-
-// WithContext set's parent context of server.
-func WithContext(ctx context.Context) ContextOpt {
- return ContextOpt{ctx: ctx}
-}
-
-// MaxMessageSizeOpt handler function option.
-type MaxMessageSizeOpt struct {
- maxMessageSize int
-}
-
-func (o MaxMessageSizeOpt) apply(opts *serverOptions) {
- opts.maxMessageSize = o.maxMessageSize
-}
-
-func (o MaxMessageSizeOpt) applyDial(opts *dialOptions) {
- opts.maxMessageSize = o.maxMessageSize
-}
-
-// WithMaxMessageSize limit size of processed message.
-func WithMaxMessageSize(maxMessageSize int) MaxMessageSizeOpt {
- return MaxMessageSizeOpt{maxMessageSize: maxMessageSize}
-}
-
-// ErrorsOpt errors option.
-type ErrorsOpt struct {
- errors ErrorFunc
-}
-
-func (o ErrorsOpt) apply(opts *serverOptions) {
- opts.errors = o.errors
-}
-
-func (o ErrorsOpt) applyDial(opts *dialOptions) {
- opts.errors = o.errors
-}
-
-// WithErrors set function for logging error.
-func WithErrors(errors ErrorFunc) ErrorsOpt {
- return ErrorsOpt{errors: errors}
-}
-
-// GoPoolOpt gopool option.
-type GoPoolOpt struct {
- goPool GoPoolFunc
-}
-
-func (o GoPoolOpt) apply(opts *serverOptions) {
- opts.goPool = o.goPool
-}
-
-func (o GoPoolOpt) applyDial(opts *dialOptions) {
- opts.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}
-}
-
-// KeepAliveOpt keepalive option.
-type KeepAliveOpt struct {
- maxRetries uint32
- timeout time.Duration
- onInactive inactivity.OnInactiveFunc
-}
-
-func (o KeepAliveOpt) apply(opts *serverOptions) {
- opts.createInactivityMonitor = func() inactivity.Monitor {
- keepalive := inactivity.NewKeepAlive(o.maxRetries, o.onInactive, func(cc inactivity.ClientConn, receivePong func()) (func(), error) {
- return cc.(*client.ClientConn).AsyncPing(receivePong)
- })
- return inactivity.NewInactivityMonitor(o.timeout, keepalive.OnInactive)
- }
-}
-
-func (o KeepAliveOpt) applyDial(opts *dialOptions) {
- opts.createInactivityMonitor = func() inactivity.Monitor {
- keepalive := inactivity.NewKeepAlive(o.maxRetries, o.onInactive, func(cc inactivity.ClientConn, receivePong func()) (func(), error) {
- return cc.(*client.ClientConn).AsyncPing(receivePong)
- })
- return inactivity.NewInactivityMonitor(o.timeout, keepalive.OnInactive)
- }
-}
-
-// WithKeepAlive monitoring's client connection's.
-func WithKeepAlive(maxRetries uint32, timeout time.Duration, onInactive inactivity.OnInactiveFunc) KeepAliveOpt {
- return KeepAliveOpt{
- maxRetries: maxRetries,
- timeout: timeout,
- onInactive: onInactive,
- }
-}
-
-// InactivityMonitorOpt notifies when a connection was inactive for a given duration.
-type InactivityMonitorOpt struct {
- duration time.Duration
- onInactive inactivity.OnInactiveFunc
-}
-
-func (o InactivityMonitorOpt) apply(opts *serverOptions) {
- opts.createInactivityMonitor = func() inactivity.Monitor {
- return inactivity.NewInactivityMonitor(o.duration, o.onInactive)
- }
-}
-
-func (o InactivityMonitorOpt) applyDial(opts *dialOptions) {
- opts.createInactivityMonitor = func() inactivity.Monitor {
- return inactivity.NewInactivityMonitor(o.duration, o.onInactive)
- }
-}
-
-// WithInactivityMonitor set deadline's for read operations over client connection.
-func WithInactivityMonitor(duration time.Duration, onInactive inactivity.OnInactiveFunc) InactivityMonitorOpt {
- return InactivityMonitorOpt{
- duration: duration,
- onInactive: onInactive,
- }
-}
-
-// NetOpt network option.
-type NetOpt struct {
- net string
-}
-
-func (o NetOpt) applyDial(opts *dialOptions) {
- opts.net = o.net
-}
-
-// WithNetwork define's udp version (udp4, udp6, udp) for client.
-func WithNetwork(net string) NetOpt {
- return NetOpt{net: net}
-}
-
-// HeartBeatOpt heatbeat of read/write operations over connection.
-type HeartBeatOpt struct {
- heartbeat time.Duration
-}
-
-func (o HeartBeatOpt) applyDial(opts *dialOptions) {
- opts.heartBeat = o.heartbeat
-}
-
-// WithHeartBeat set deadline's for read/write operations over client connection.
-func WithHeartBeat(heartbeat time.Duration) HeartBeatOpt {
- return HeartBeatOpt{heartbeat: heartbeat}
-}
-
-// BlockwiseOpt network option.
-type BlockwiseOpt struct {
- enable bool
- szx blockwise.SZX
- transferTimeout time.Duration
-}
-
-func (o BlockwiseOpt) apply(opts *serverOptions) {
- opts.blockwiseEnable = o.enable
- opts.blockwiseSZX = o.szx
- opts.blockwiseTransferTimeout = o.transferTimeout
-}
-
-func (o BlockwiseOpt) applyDial(opts *dialOptions) {
- opts.blockwiseEnable = o.enable
- opts.blockwiseSZX = o.szx
- opts.blockwiseTransferTimeout = o.transferTimeout
-}
-
-// WithBlockwise configure's blockwise transfer.
-func WithBlockwise(enable bool, szx blockwise.SZX, transferTimeout time.Duration) BlockwiseOpt {
- return BlockwiseOpt{
- enable: enable,
- szx: szx,
- transferTimeout: transferTimeout,
- }
-}
-
-// OnNewClientConnOpt network option.
-type OnNewClientConnOpt struct {
- onNewClientConn OnNewClientConnFunc
-}
-
-func (o OnNewClientConnOpt) apply(opts *serverOptions) {
- opts.onNewClientConn = o.onNewClientConn
-}
-
-// WithOnNewClientConn server's notify about new client connection.
-func WithOnNewClientConn(onNewClientConn OnNewClientConnFunc) OnNewClientConnOpt {
- return OnNewClientConnOpt{
- onNewClientConn: onNewClientConn,
- }
-}
-
-// TransmissionOpt transmission options.
-type TransmissionOpt struct {
- transmissionNStart time.Duration
- transmissionAcknowledgeTimeout time.Duration
- transmissionMaxRetransmit int
-}
-
-func (o TransmissionOpt) apply(opts *serverOptions) {
- opts.transmissionNStart = o.transmissionNStart
- opts.transmissionAcknowledgeTimeout = o.transmissionAcknowledgeTimeout
- opts.transmissionMaxRetransmit = o.transmissionMaxRetransmit
-}
-
-func (o TransmissionOpt) applyDial(opts *dialOptions) {
- opts.transmissionNStart = o.transmissionNStart
- opts.transmissionAcknowledgeTimeout = o.transmissionAcknowledgeTimeout
- opts.transmissionMaxRetransmit = o.transmissionMaxRetransmit
-}
-
-// WithTransmission set options for (re)transmission for Confirmable message-s.
-func WithTransmission(transmissionNStart time.Duration,
- transmissionAcknowledgeTimeout time.Duration,
- transmissionMaxRetransmit int) TransmissionOpt {
- return TransmissionOpt{
- transmissionNStart: transmissionNStart,
- transmissionAcknowledgeTimeout: transmissionAcknowledgeTimeout,
- transmissionMaxRetransmit: transmissionMaxRetransmit,
- }
-}
-
-// GetMIDOpt get message ID option.
-type GetMIDOpt struct {
- getMID GetMIDFunc
-}
-
-func (o GetMIDOpt) apply(opts *serverOptions) {
- opts.getMID = o.getMID
-}
-
-func (o GetMIDOpt) applyDial(opts *dialOptions) {
- opts.getMID = o.getMID
-}
-
-// WithGetMID allows to set own getMID function to server/client.
-func WithGetMID(getMID GetMIDFunc) GetMIDOpt {
- return GetMIDOpt{getMID: getMID}
-}
-
-// CloseSocketOpt close socket option.
-type CloseSocketOpt struct {
-}
-
-func (o CloseSocketOpt) applyDial(opts *dialOptions) {
- opts.closeSocket = true
-}
-
-// WithCloseSocket closes socket at the close connection.
-func WithCloseSocket() CloseSocketOpt {
- return CloseSocketOpt{}
-}
-
-// DialerOpt dialer option.
-type DialerOpt struct {
- dialer *net.Dialer
-}
-
-func (o DialerOpt) applyDial(opts *dialOptions) {
- if o.dialer != nil {
- opts.dialer = o.dialer
- }
-}
-
-// WithDialer set dialer for dial.
-func WithDialer(dialer *net.Dialer) DialerOpt {
- return DialerOpt{
- dialer: dialer,
- }
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/server.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/server.go
deleted file mode 100644
index 283d22d..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/server.go
+++ /dev/null
@@ -1,378 +0,0 @@
-package udp
-
-import (
- "context"
- "fmt"
- "net"
- "sync"
- "time"
-
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/message/codes"
- coapNet "github.com/plgd-dev/go-coap/v2/net"
- "github.com/plgd-dev/go-coap/v2/net/blockwise"
- "github.com/plgd-dev/go-coap/v2/net/monitor/inactivity"
- "github.com/plgd-dev/go-coap/v2/udp/client"
- udpMessage "github.com/plgd-dev/go-coap/v2/udp/message"
- "github.com/plgd-dev/go-coap/v2/udp/message/pool"
- kitSync "github.com/plgd-dev/kit/sync"
-)
-
-// A ServerOption sets options such as credentials, codec and keepalive parameters, etc.
-type ServerOption interface {
- apply(*serverOptions)
-}
-
-// The HandlerFunc type is an adapter to allow the use of
-// ordinary functions as COAP handlers.
-type HandlerFunc = func(*client.ResponseWriter, *pool.Message)
-
-type ErrorFunc = func(error)
-
-type GoPoolFunc = func(func()) error
-
-type BlockwiseFactoryFunc = func(getSendedRequest func(token message.Token) (blockwise.Message, bool)) *blockwise.BlockWise
-
-type OnNewClientConnFunc = func(cc *client.ClientConn)
-
-type GetMIDFunc = func() uint16
-
-var defaultServerOptions = serverOptions{
- ctx: context.Background(),
- maxMessageSize: 64 * 1024,
- handler: func(w *client.ResponseWriter, r *pool.Message) {
- w.SetResponse(codes.NotFound, message.TextPlain, nil)
- },
- errors: func(err error) {
- fmt.Println(err)
- },
- goPool: func(f func()) error {
- go func() {
- f()
- }()
- return nil
- },
- createInactivityMonitor: func() inactivity.Monitor {
- return inactivity.NewNilMonitor()
- },
- blockwiseEnable: true,
- blockwiseSZX: blockwise.SZX1024,
- blockwiseTransferTimeout: time.Second * 3,
- onNewClientConn: func(cc *client.ClientConn) {},
- transmissionNStart: time.Second,
- transmissionAcknowledgeTimeout: time.Second * 2,
- transmissionMaxRetransmit: 4,
- getMID: udpMessage.GetMID,
-}
-
-type serverOptions struct {
- ctx context.Context
- maxMessageSize int
- handler HandlerFunc
- errors ErrorFunc
- goPool GoPoolFunc
- createInactivityMonitor func() inactivity.Monitor
- net string
- blockwiseSZX blockwise.SZX
- blockwiseEnable bool
- blockwiseTransferTimeout time.Duration
- onNewClientConn OnNewClientConnFunc
- transmissionNStart time.Duration
- transmissionAcknowledgeTimeout time.Duration
- transmissionMaxRetransmit int
- getMID GetMIDFunc
-}
-
-type Server struct {
- maxMessageSize int
- handler HandlerFunc
- errors ErrorFunc
- goPool GoPoolFunc
- createInactivityMonitor func() inactivity.Monitor
- blockwiseSZX blockwise.SZX
- blockwiseEnable bool
- blockwiseTransferTimeout time.Duration
- onNewClientConn OnNewClientConnFunc
- transmissionNStart time.Duration
- transmissionAcknowledgeTimeout time.Duration
- transmissionMaxRetransmit int
- getMID GetMIDFunc
-
- conns map[string]*client.ClientConn
- connsMutex sync.Mutex
- ctx context.Context
- cancel context.CancelFunc
- serverStartedChan chan struct{}
-
- multicastRequests *kitSync.Map
- multicastHandler *client.HandlerContainer
-
- listen *coapNet.UDPConn
- listenMutex sync.Mutex
-}
-
-func NewServer(opt ...ServerOption) *Server {
- opts := defaultServerOptions
- for _, o := range opt {
- o.apply(&opts)
- }
-
- if opts.errors == nil {
- opts.errors = func(error) {}
- }
-
- if opts.getMID == nil {
- opts.getMID = udpMessage.GetMID
- }
-
- if opts.createInactivityMonitor == nil {
- opts.createInactivityMonitor = func() inactivity.Monitor {
- return inactivity.NewNilMonitor()
- }
- }
-
- ctx, cancel := context.WithCancel(opts.ctx)
- serverStartedChan := make(chan struct{})
-
- return &Server{
- ctx: ctx,
- cancel: cancel,
- handler: opts.handler,
- maxMessageSize: opts.maxMessageSize,
- errors: func(err error) {
- opts.errors(fmt.Errorf("udp: %w", err))
- },
- goPool: opts.goPool,
- createInactivityMonitor: opts.createInactivityMonitor,
- blockwiseSZX: opts.blockwiseSZX,
- blockwiseEnable: opts.blockwiseEnable,
- blockwiseTransferTimeout: opts.blockwiseTransferTimeout,
- multicastHandler: client.NewHandlerContainer(),
- multicastRequests: kitSync.NewMap(),
- serverStartedChan: serverStartedChan,
- onNewClientConn: opts.onNewClientConn,
- transmissionNStart: opts.transmissionNStart,
- transmissionAcknowledgeTimeout: opts.transmissionAcknowledgeTimeout,
- transmissionMaxRetransmit: opts.transmissionMaxRetransmit,
- getMID: opts.getMID,
-
- conns: make(map[string]*client.ClientConn),
- }
-}
-
-func (s *Server) checkAndSetListener(l *coapNet.UDPConn) error {
- s.listenMutex.Lock()
- defer s.listenMutex.Unlock()
- if s.listen != nil {
- return fmt.Errorf("server already serve: %v", s.listen.LocalAddr().String())
- }
- s.listen = l
- close(s.serverStartedChan)
- return nil
-}
-
-func (s *Server) Serve(l *coapNet.UDPConn) error {
- if s.blockwiseSZX > blockwise.SZX1024 {
- return fmt.Errorf("invalid blockwiseSZX")
- }
-
- err := s.checkAndSetListener(l)
- if err != nil {
- return err
- }
-
- defer func() {
- s.closeSessions()
- s.listenMutex.Lock()
- defer s.listenMutex.Unlock()
- s.listen = nil
- s.serverStartedChan = make(chan struct{}, 1)
- }()
-
- m := make([]byte, s.maxMessageSize)
- var wg sync.WaitGroup
-
- wg.Add(1)
- go func() {
- defer wg.Done()
- s.handleInactivityMonitors()
- }()
-
- for {
- buf := m
- n, raddr, err := l.ReadWithContext(s.ctx, buf)
- if err != nil {
- wg.Wait()
-
- select {
- case <-s.ctx.Done():
- return nil
- default:
- return err
- }
- }
- buf = buf[:n]
- cc, created := s.getOrCreateClientConn(l, raddr)
- if created {
- if s.onNewClientConn != nil {
- s.onNewClientConn(cc)
- }
- }
- err = cc.Process(buf)
- if err != nil {
- cc.Close()
- s.errors(fmt.Errorf("%v: %w", cc.RemoteAddr(), err))
- }
- }
-}
-
-// Stop stops server without wait of ends Serve function.
-func (s *Server) Stop() {
- s.cancel()
- s.closeSessions()
-}
-
-func (s *Server) closeSessions() {
- s.connsMutex.Lock()
- conns := s.conns
- s.conns = make(map[string]*client.ClientConn)
- s.connsMutex.Unlock()
- for _, cc := range conns {
- cc.Close()
- close := getClose(cc)
- if close != nil {
- close()
- }
- }
-}
-
-func (s *Server) conn() *coapNet.UDPConn {
- s.listenMutex.Lock()
- serverStartedChan := s.serverStartedChan
- s.listenMutex.Unlock()
- select {
- case <-serverStartedChan:
- case <-s.ctx.Done():
- }
- s.listenMutex.Lock()
- defer s.listenMutex.Unlock()
- return s.listen
-}
-
-const inactivityMonitorKey = "gocoapInactivityMonitor"
-const closeKey = "gocoapCloseConnection"
-
-func (s *Server) getClientConns() []*client.ClientConn {
- s.connsMutex.Lock()
- defer s.connsMutex.Unlock()
- conns := make([]*client.ClientConn, 0, 32)
- for _, c := range s.conns {
- conns = append(conns, c)
- }
- return conns
-}
-
-func (s *Server) handleInactivityMonitors() {
- ticker := time.NewTicker(time.Second)
- defer ticker.Stop()
-
- for {
- select {
- case <-ticker.C:
- for _, cc := range s.getClientConns() {
- select {
- case <-cc.Context().Done():
- close := getClose(cc)
- if close != nil {
- close()
- }
- continue
- default:
- monitor := getInactivityMonitor(cc)
- monitor.CheckInactivity(cc)
- }
- }
- case <-s.ctx.Done():
- return
- }
- }
-}
-
-func getInactivityMonitor(cc *client.ClientConn) inactivity.Monitor {
- v := cc.Context().Value(inactivityMonitorKey)
- if v == nil {
- return nil
- }
- return v.(inactivity.Monitor)
-}
-
-func getClose(cc *client.ClientConn) func() {
- v := cc.Context().Value(closeKey)
- if v == nil {
- return nil
- }
- return v.(func())
-}
-
-func (s *Server) getOrCreateClientConn(UDPConn *coapNet.UDPConn, raddr *net.UDPAddr) (cc *client.ClientConn, created bool) {
- s.connsMutex.Lock()
- defer s.connsMutex.Unlock()
- key := raddr.String()
- cc = s.conns[key]
- if cc == nil {
- created = true
- var blockWise *blockwise.BlockWise
- if s.blockwiseEnable {
- blockWise = blockwise.NewBlockWise(
- bwAcquireMessage,
- bwReleaseMessage,
- s.blockwiseTransferTimeout,
- s.errors,
- false,
- bwCreateHandlerFunc(s.multicastRequests),
- )
- }
- obsHandler := client.NewHandlerContainer()
- session := NewSession(
- s.ctx,
- UDPConn,
- raddr,
- s.maxMessageSize,
- false,
- )
- monitor := s.createInactivityMonitor()
- cc = client.NewClientConn(
- session,
- obsHandler,
- s.multicastRequests,
- s.transmissionNStart,
- s.transmissionAcknowledgeTimeout,
- s.transmissionMaxRetransmit,
- client.NewObservationHandler(obsHandler, func(w *client.ResponseWriter, r *pool.Message) {
- h, err := s.multicastHandler.Get(r.Token())
- if err == nil {
- h(w, r)
- return
- }
- s.handler(w, r)
- }),
- s.blockwiseSZX,
- blockWise,
- s.goPool,
- s.errors,
- s.getMID,
- monitor,
- )
- cc.SetContextValue(inactivityMonitorKey, monitor)
- cc.SetContextValue(closeKey, func() {
- session.close()
- })
- cc.AddOnClose(func() {
- s.connsMutex.Lock()
- defer s.connsMutex.Unlock()
- delete(s.conns, key)
- })
- s.conns[key] = cc
- }
- return cc, created
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/session.go b/vendor/github.com/plgd-dev/go-coap/v2/udp/session.go
deleted file mode 100644
index bede4ea..0000000
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/session.go
+++ /dev/null
@@ -1,134 +0,0 @@
-package udp
-
-import (
- "context"
- "fmt"
- "net"
- "sync"
- "sync/atomic"
-
- coapNet "github.com/plgd-dev/go-coap/v2/net"
- "github.com/plgd-dev/go-coap/v2/udp/client"
- "github.com/plgd-dev/go-coap/v2/udp/message/pool"
-)
-
-type EventFunc = func()
-
-type Session struct {
- connection *coapNet.UDPConn
- raddr *net.UDPAddr
- maxMessageSize int
- closeSocket bool
-
- mutex sync.Mutex
- onClose []EventFunc
-
- cancel context.CancelFunc
- ctx atomic.Value
-}
-
-func NewSession(
- ctx context.Context,
- connection *coapNet.UDPConn,
- raddr *net.UDPAddr,
- maxMessageSize int,
- closeSocket bool,
-) *Session {
- ctx, cancel := context.WithCancel(ctx)
- s := &Session{
- cancel: cancel,
- connection: connection,
- raddr: raddr,
- maxMessageSize: maxMessageSize,
- closeSocket: closeSocket,
- }
- s.ctx.Store(&ctx)
- return s
-}
-
-// SetContextValue stores the value associated with key to context of connection.
-func (s *Session) SetContextValue(key interface{}, val interface{}) {
- s.mutex.Lock()
- defer s.mutex.Unlock()
- ctx := context.WithValue(s.Context(), key, val)
- s.ctx.Store(&ctx)
-}
-
-func (s *Session) Done() <-chan struct{} {
- return s.Context().Done()
-}
-
-func (s *Session) AddOnClose(f EventFunc) {
- s.mutex.Lock()
- defer s.mutex.Unlock()
- s.onClose = append(s.onClose, f)
-}
-
-func (s *Session) popOnClose() []EventFunc {
- s.mutex.Lock()
- defer s.mutex.Unlock()
- tmp := s.onClose
- s.onClose = nil
- return tmp
-}
-
-func (s *Session) close() error {
- for _, f := range s.popOnClose() {
- f()
- }
- if s.closeSocket {
- return s.connection.Close()
- }
- return nil
-}
-
-func (s *Session) Close() error {
- s.cancel()
- return nil
-}
-
-func (s *Session) Context() context.Context {
- return *s.ctx.Load().(*context.Context)
-}
-
-func (s *Session) WriteMessage(req *pool.Message) error {
- data, err := req.Marshal()
- if err != nil {
- return fmt.Errorf("cannot marshal: %w", err)
- }
- return s.connection.WriteWithContext(req.Context(), s.raddr, data)
-}
-
-func (s *Session) Run(cc *client.ClientConn) (err error) {
- defer func() {
- err1 := s.Close()
- if err == nil {
- err = err1
- }
- err1 = s.close()
- if err == nil {
- err = err1
- }
- }()
- m := make([]byte, s.maxMessageSize)
- for {
- buf := m
- n, _, err := s.connection.ReadWithContext(s.Context(), buf)
- if err != nil {
- return err
- }
- buf = buf[:n]
- err = cc.Process(buf)
- if err != nil {
- return err
- }
- }
-}
-
-func (s *Session) MaxMessageSize() int {
- return s.maxMessageSize
-}
-
-func (s *Session) RemoteAddr() net.Addr {
- return s.raddr
-}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/LICENSE b/vendor/github.com/plgd-dev/go-coap/v3/LICENSE
similarity index 100%
rename from vendor/github.com/plgd-dev/go-coap/v2/LICENSE
rename to vendor/github.com/plgd-dev/go-coap/v3/LICENSE
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/dtls/client.go b/vendor/github.com/plgd-dev/go-coap/v3/dtls/client.go
new file mode 100644
index 0000000..e2075f3
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/dtls/client.go
@@ -0,0 +1,127 @@
+package dtls
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/pion/dtls/v2"
+ dtlsnet "github.com/pion/dtls/v2/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"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ coapNet "github.com/plgd-dev/go-coap/v3/net"
+ "github.com/plgd-dev/go-coap/v3/net/blockwise"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/options"
+ "github.com/plgd-dev/go-coap/v3/udp"
+ udpClient "github.com/plgd-dev/go-coap/v3/udp/client"
+)
+
+var DefaultConfig = func() udpClient.Config {
+ cfg := udpClient.DefaultConfig
+ cfg.Handler = func(w *responsewriter.ResponseWriter[*udpClient.Conn], r *pool.Message) {
+ switch r.Code() {
+ case codes.POST, codes.PUT, codes.GET, codes.DELETE:
+ if err := w.SetResponse(codes.NotFound, message.TextPlain, nil); err != nil {
+ cfg.Errors(fmt.Errorf("dtls client: cannot set response: %w", err))
+ }
+ }
+ }
+ return cfg
+}()
+
+// Dial creates a client connection to the given target.
+func Dial(target string, dtlsCfg *dtls.Config, opts ...udp.Option) (*udpClient.Conn, error) {
+ cfg := DefaultConfig
+ for _, o := range opts {
+ o.UDPClientApply(&cfg)
+ }
+
+ c, err := cfg.Dialer.DialContext(cfg.Ctx, cfg.Net, target)
+ if err != nil {
+ return nil, err
+ }
+
+ conn, err := dtls.Client(dtlsnet.PacketConnFromConn(c), c.RemoteAddr(), dtlsCfg)
+ if err != nil {
+ return nil, err
+ }
+ opts = append(opts, options.WithCloseSocket())
+ return Client(conn, opts...), nil
+}
+
+// Client creates client over dtls connection.
+func Client(conn *dtls.Conn, opts ...udp.Option) *udpClient.Conn {
+ cfg := DefaultConfig
+ for _, o := range opts {
+ o.UDPClientApply(&cfg)
+ }
+ if cfg.Errors == nil {
+ cfg.Errors = func(error) {
+ // default no-op
+ }
+ }
+ if cfg.CreateInactivityMonitor == nil {
+ cfg.CreateInactivityMonitor = func() udpClient.InactivityMonitor {
+ return inactivity.NewNilMonitor[*udpClient.Conn]()
+ }
+ }
+ if cfg.MessagePool == nil {
+ cfg.MessagePool = pool.New(0, 0)
+ }
+ errorsFunc := cfg.Errors
+ cfg.Errors = func(err error) {
+ if coapNet.IsCancelOrCloseError(err) {
+ // this error was produced by cancellation context or closing connection.
+ return
+ }
+ errorsFunc(fmt.Errorf("dtls: %v: %w", conn.RemoteAddr(), err))
+ }
+
+ createBlockWise := func(cc *udpClient.Conn) *blockwise.BlockWise[*udpClient.Conn] {
+ return nil
+ }
+ if cfg.BlockwiseEnable {
+ createBlockWise = func(cc *udpClient.Conn) *blockwise.BlockWise[*udpClient.Conn] {
+ v := cc
+ return blockwise.New(
+ v,
+ cfg.BlockwiseTransferTimeout,
+ cfg.Errors,
+ func(token message.Token) (*pool.Message, bool) {
+ return v.GetObservationRequest(token)
+ },
+ )
+ }
+ }
+
+ monitor := cfg.CreateInactivityMonitor()
+ l := coapNet.NewConn(conn)
+ session := server.NewSession(cfg.Ctx,
+ l,
+ cfg.MaxMessageSize,
+ cfg.MTU,
+ cfg.CloseSocket,
+ )
+ cc := udpClient.NewConn(session,
+ createBlockWise,
+ monitor,
+ &cfg,
+ )
+
+ cfg.PeriodicRunner(func(now time.Time) bool {
+ cc.CheckExpirations(now)
+ return cc.Context().Err() == nil
+ })
+
+ go func() {
+ err := cc.Run()
+ if err != nil {
+ cfg.Errors(err)
+ }
+ }()
+
+ return cc
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/dtls/server.go b/vendor/github.com/plgd-dev/go-coap/v3/dtls/server.go
new file mode 100644
index 0000000..881c844
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/dtls/server.go
@@ -0,0 +1,7 @@
+package dtls
+
+import "github.com/plgd-dev/go-coap/v3/dtls/server"
+
+func NewServer(opt ...server.Option) *server.Server {
+ return server.New(opt...)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/dtls/server/config.go b/vendor/github.com/plgd-dev/go-coap/v3/dtls/server/config.go
new file mode 100644
index 0000000..dba7297
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/dtls/server/config.go
@@ -0,0 +1,64 @@
+package server
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/options/config"
+ udpClient "github.com/plgd-dev/go-coap/v3/udp/client"
+)
+
+// The HandlerFunc type is an adapter to allow the use of
+// ordinary functions as COAP handlers.
+type HandlerFunc = func(*responsewriter.ResponseWriter[*udpClient.Conn], *pool.Message)
+
+type ErrorFunc = func(error)
+
+// OnNewConnFunc is the callback for new connections.
+type OnNewConnFunc = func(cc *udpClient.Conn)
+
+type GetMIDFunc = func() int32
+
+var DefaultConfig = func() Config {
+ opts := Config{
+ Common: config.NewCommon[*udpClient.Conn](),
+ CreateInactivityMonitor: func() udpClient.InactivityMonitor {
+ timeout := time.Second * 16
+ onInactive := func(cc *udpClient.Conn) {
+ _ = cc.Close()
+ }
+ return inactivity.New(timeout, onInactive)
+ },
+ OnNewConn: func(cc *udpClient.Conn) {
+ // do nothing by default
+ },
+ TransmissionNStart: 1,
+ TransmissionAcknowledgeTimeout: time.Second * 2,
+ TransmissionMaxRetransmit: 4,
+ GetMID: message.GetMID,
+ MTU: udpClient.DefaultMTU,
+ }
+ opts.Handler = func(w *responsewriter.ResponseWriter[*udpClient.Conn], r *pool.Message) {
+ if err := w.SetResponse(codes.NotFound, message.TextPlain, nil); err != nil {
+ opts.Errors(fmt.Errorf("dtls server: cannot set response: %w", err))
+ }
+ }
+ return opts
+}()
+
+type Config struct {
+ config.Common[*udpClient.Conn]
+ CreateInactivityMonitor func() udpClient.InactivityMonitor
+ GetMID GetMIDFunc
+ Handler HandlerFunc
+ OnNewConn OnNewConnFunc
+ TransmissionNStart uint32
+ TransmissionAcknowledgeTimeout time.Duration
+ TransmissionMaxRetransmit uint32
+ MTU uint16
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/dtls/server/server.go b/vendor/github.com/plgd-dev/go-coap/v3/dtls/server/server.go
new file mode 100644
index 0000000..01587f8
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/dtls/server/server.go
@@ -0,0 +1,231 @@
+package server
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net"
+ "sync"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ coapNet "github.com/plgd-dev/go-coap/v3/net"
+ "github.com/plgd-dev/go-coap/v3/net/blockwise"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/pkg/connections"
+ udpClient "github.com/plgd-dev/go-coap/v3/udp/client"
+)
+
+// Listener defined used by coap
+type Listener interface {
+ Close() error
+ AcceptWithContext(ctx context.Context) (net.Conn, error)
+}
+
+type Server struct {
+ ctx context.Context
+ cancel context.CancelFunc
+ cfg *Config
+
+ listenMutex sync.Mutex
+ listen Listener
+}
+
+// A Option sets options such as credentials, codec and keepalive parameters, etc.
+type Option interface {
+ DTLSServerApply(cfg *Config)
+}
+
+func New(opt ...Option) *Server {
+ cfg := DefaultConfig
+ for _, o := range opt {
+ o.DTLSServerApply(&cfg)
+ }
+
+ ctx, cancel := context.WithCancel(cfg.Ctx)
+ if cfg.Errors == nil {
+ cfg.Errors = func(error) {
+ // default no-op
+ }
+ }
+
+ if cfg.GetMID == nil {
+ cfg.GetMID = message.GetMID
+ }
+
+ if cfg.GetToken == nil {
+ cfg.GetToken = message.GetToken
+ }
+
+ if cfg.CreateInactivityMonitor == nil {
+ cfg.CreateInactivityMonitor = func() udpClient.InactivityMonitor {
+ return inactivity.NewNilMonitor[*udpClient.Conn]()
+ }
+ }
+ if cfg.MessagePool == nil {
+ cfg.MessagePool = pool.New(0, 0)
+ }
+
+ errorsFunc := cfg.Errors
+ // assign updated func to cfg.errors so cfg.handler also uses the updated error handler
+ cfg.Errors = func(err error) {
+ if coapNet.IsCancelOrCloseError(err) {
+ // this error was produced by cancellation context or closing connection.
+ return
+ }
+ errorsFunc(fmt.Errorf("dtls: %w", err))
+ }
+
+ return &Server{
+ ctx: ctx,
+ cancel: cancel,
+ cfg: &cfg,
+ }
+}
+
+func (s *Server) checkAndSetListener(l Listener) error {
+ s.listenMutex.Lock()
+ defer s.listenMutex.Unlock()
+ if s.listen != nil {
+ return fmt.Errorf("server already serve listener")
+ }
+ s.listen = l
+ return nil
+}
+
+func (s *Server) checkAcceptError(err error) bool {
+ if err == nil {
+ return true
+ }
+ switch {
+ case errors.Is(err, coapNet.ErrListenerIsClosed):
+ s.Stop()
+ return false
+ case errors.Is(err, context.DeadlineExceeded), errors.Is(err, context.Canceled):
+ select {
+ case <-s.ctx.Done():
+ default:
+ s.cfg.Errors(fmt.Errorf("cannot accept connection: %w", err))
+ return true
+ }
+ return false
+ default:
+ return true
+ }
+}
+
+func (s *Server) serveConnection(connections *connections.Connections, cc *udpClient.Conn) {
+ connections.Store(cc)
+ defer connections.Delete(cc)
+
+ if err := cc.Run(); err != nil {
+ s.cfg.Errors(fmt.Errorf("%v: %w", cc.RemoteAddr(), err))
+ }
+}
+
+func (s *Server) Serve(l Listener) error {
+ if s.cfg.BlockwiseSZX > blockwise.SZX1024 {
+ return fmt.Errorf("invalid blockwiseSZX")
+ }
+ err := s.checkAndSetListener(l)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ s.listenMutex.Lock()
+ defer s.listenMutex.Unlock()
+ s.listen = nil
+ }()
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ connections := connections.New()
+ s.cfg.PeriodicRunner(func(now time.Time) bool {
+ connections.CheckExpirations(now)
+ return s.ctx.Err() == nil
+ })
+ defer connections.Close()
+
+ for {
+ rw, err := l.AcceptWithContext(s.ctx)
+ if ok := s.checkAcceptError(err); !ok {
+ return nil
+ }
+ if rw == nil {
+ continue
+ }
+ wg.Add(1)
+ var cc *udpClient.Conn
+ monitor := s.cfg.CreateInactivityMonitor()
+ cc = s.createConn(coapNet.NewConn(rw), monitor)
+ if s.cfg.OnNewConn != nil {
+ s.cfg.OnNewConn(cc)
+ }
+ go func() {
+ defer wg.Done()
+ s.serveConnection(connections, cc)
+ }()
+ }
+}
+
+// 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))
+ }
+ }
+}
+
+func (s *Server) createConn(connection *coapNet.Conn, monitor udpClient.InactivityMonitor) *udpClient.Conn {
+ createBlockWise := func(cc *udpClient.Conn) *blockwise.BlockWise[*udpClient.Conn] {
+ return nil
+ }
+ if s.cfg.BlockwiseEnable {
+ createBlockWise = func(cc *udpClient.Conn) *blockwise.BlockWise[*udpClient.Conn] {
+ v := cc
+ return blockwise.New(
+ v,
+ s.cfg.BlockwiseTransferTimeout,
+ s.cfg.Errors,
+ func(token message.Token) (*pool.Message, bool) {
+ return v.GetObservationRequest(token)
+ },
+ )
+ }
+ }
+ session := NewSession(
+ s.ctx,
+ connection,
+ s.cfg.MaxMessageSize,
+ s.cfg.MTU,
+ true,
+ )
+ cfg := udpClient.DefaultConfig
+ cfg.TransmissionNStart = s.cfg.TransmissionNStart
+ cfg.TransmissionAcknowledgeTimeout = s.cfg.TransmissionAcknowledgeTimeout
+ cfg.TransmissionMaxRetransmit = s.cfg.TransmissionMaxRetransmit
+ cfg.Handler = s.cfg.Handler
+ cfg.BlockwiseSZX = s.cfg.BlockwiseSZX
+ cfg.Errors = s.cfg.Errors
+ cfg.GetMID = s.cfg.GetMID
+ cfg.GetToken = s.cfg.GetToken
+ cfg.MessagePool = s.cfg.MessagePool
+ cfg.ReceivedMessageQueueSize = s.cfg.ReceivedMessageQueueSize
+ cfg.ProcessReceivedMessage = s.cfg.ProcessReceivedMessage
+ cc := udpClient.NewConn(
+ session,
+ createBlockWise,
+ monitor,
+ &cfg,
+ )
+
+ return cc
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/dtls/server/session.go b/vendor/github.com/plgd-dev/go-coap/v3/dtls/server/session.go
new file mode 100644
index 0000000..9eb2d00
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/dtls/server/session.go
@@ -0,0 +1,159 @@
+package server
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net"
+ "sync"
+ "sync/atomic"
+
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ coapNet "github.com/plgd-dev/go-coap/v3/net"
+ "github.com/plgd-dev/go-coap/v3/udp/client"
+ "github.com/plgd-dev/go-coap/v3/udp/coder"
+)
+
+type EventFunc = func()
+
+type Session struct {
+ onClose []EventFunc
+
+ ctx atomic.Value // TODO: change to atomic.Pointer[context.Context] for go1.19
+
+ cancel context.CancelFunc
+ connection *coapNet.Conn
+
+ done chan struct{}
+
+ mutex sync.Mutex
+
+ maxMessageSize uint32
+
+ mtu uint16
+
+ closeSocket bool
+}
+
+func NewSession(
+ ctx context.Context,
+ connection *coapNet.Conn,
+ maxMessageSize uint32,
+ mtu uint16,
+ closeSocket bool,
+) *Session {
+ ctx, cancel := context.WithCancel(ctx)
+ s := &Session{
+ cancel: cancel,
+ connection: connection,
+ maxMessageSize: maxMessageSize,
+ closeSocket: closeSocket,
+ mtu: mtu,
+ done: make(chan struct{}),
+ }
+ s.ctx.Store(&ctx)
+ return s
+}
+
+// Done signalizes that connection is not more processed.
+func (s *Session) Done() <-chan struct{} {
+ return s.done
+}
+
+func (s *Session) AddOnClose(f EventFunc) {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ s.onClose = append(s.onClose, f)
+}
+
+func (s *Session) popOnClose() []EventFunc {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ tmp := s.onClose
+ s.onClose = nil
+ return tmp
+}
+
+func (s *Session) shutdown() {
+ defer close(s.done)
+ for _, f := range s.popOnClose() {
+ f()
+ }
+}
+
+func (s *Session) Close() error {
+ s.cancel()
+ if s.closeSocket {
+ return s.connection.Close()
+ }
+ return nil
+}
+
+func (s *Session) Context() context.Context {
+ return *s.ctx.Load().(*context.Context) //nolint:forcetypeassert
+}
+
+// SetContextValue stores the value associated with key to context of connection.
+func (s *Session) SetContextValue(key interface{}, val interface{}) {
+ ctx := context.WithValue(s.Context(), key, val)
+ s.ctx.Store(&ctx)
+}
+
+func (s *Session) WriteMessage(req *pool.Message) error {
+ data, err := req.MarshalWithEncoder(coder.DefaultCoder)
+ if err != nil {
+ return fmt.Errorf("cannot marshal: %w", err)
+ }
+ err = s.connection.WriteWithContext(req.Context(), data)
+ if err != nil {
+ return fmt.Errorf("cannot write to connection: %w", err)
+ }
+ return err
+}
+
+// WriteMulticastMessage sends multicast to the remote multicast address.
+// Currently it is not implemented - is is just satisfy golang udp/client/Session interface.
+func (s *Session) WriteMulticastMessage(*pool.Message, *net.UDPAddr, ...coapNet.MulticastOption) error {
+ return errors.New("multicast messages not implemented for DTLS")
+}
+
+func (s *Session) MaxMessageSize() uint32 {
+ return s.maxMessageSize
+}
+
+func (s *Session) RemoteAddr() net.Addr {
+ return s.connection.RemoteAddr()
+}
+
+func (s *Session) LocalAddr() net.Addr {
+ return s.connection.LocalAddr()
+}
+
+// Run reads and process requests from a connection, until the connection is not closed.
+func (s *Session) Run(cc *client.Conn) (err error) {
+ defer func() {
+ err1 := s.Close()
+ if err == nil {
+ err = err1
+ }
+ s.shutdown()
+ }()
+ m := make([]byte, s.mtu)
+ for {
+ readBuf := m
+ readLen, err := s.connection.ReadWithContext(s.Context(), readBuf)
+ if err != nil {
+ return fmt.Errorf("cannot read from connection: %w", err)
+ }
+ readBuf = readBuf[:readLen]
+ err = cc.Process(readBuf)
+ if err != nil {
+ return err
+ }
+ }
+}
+
+// NetConn returns the underlying connection that is wrapped by s. The Conn returned is shared by all invocations of NetConn, so do not modify it.
+func (s *Session) NetConn() net.Conn {
+ return s.connection.NetConn()
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/codes/code_string.go b/vendor/github.com/plgd-dev/go-coap/v3/message/codes/code_string.go
similarity index 97%
rename from vendor/github.com/plgd-dev/go-coap/v2/message/codes/code_string.go
rename to vendor/github.com/plgd-dev/go-coap/v3/message/codes/code_string.go
index 1ef9f30..79f248a 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/message/codes/code_string.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/codes/code_string.go
@@ -26,6 +26,7 @@ var codeToString = map[Code]string{
PreconditionFailed: "PreconditionFailed",
RequestEntityTooLarge: "RequestEntityTooLarge",
UnsupportedMediaType: "UnsupportedMediaType",
+ TooManyRequests: "TooManyRequests",
InternalServerError: "InternalServerError",
NotImplemented: "NotImplemented",
BadGateway: "BadGateway",
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/codes/codes.go b/vendor/github.com/plgd-dev/go-coap/v3/message/codes/codes.go
similarity index 96%
rename from vendor/github.com/plgd-dev/go-coap/v2/message/codes/codes.go
rename to vendor/github.com/plgd-dev/go-coap/v3/message/codes/codes.go
index a97842f..62e3d8c 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/message/codes/codes.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/codes/codes.go
@@ -36,6 +36,7 @@ const (
PreconditionFailed Code = 140
RequestEntityTooLarge Code = 141
UnsupportedMediaType Code = 143
+ TooManyRequests Code = 157
InternalServerError Code = 160
NotImplemented Code = 161
BadGateway Code = 162
@@ -44,7 +45,7 @@ const (
ProxyingNotSupported Code = 165
)
-//Signaling Codes for TCP
+// Signaling Codes for TCP
const (
CSM Code = 225
Ping Code = 226
@@ -75,6 +76,7 @@ var strToCode = map[string]Code{
`"PreconditionFailed"`: PreconditionFailed,
`"RequestEntityTooLarge"`: RequestEntityTooLarge,
`"UnsupportedMediaType"`: UnsupportedMediaType,
+ `"TooManyRequests"`: TooManyRequests,
`"InternalServerError"`: InternalServerError,
`"NotImplemented"`: NotImplemented,
`"BadGateway"`: BadGateway,
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/encodeDecodeUint32.go b/vendor/github.com/plgd-dev/go-coap/v3/message/encodeDecodeUint32.go
similarity index 95%
rename from vendor/github.com/plgd-dev/go-coap/v2/message/encodeDecodeUint32.go
rename to vendor/github.com/plgd-dev/go-coap/v3/message/encodeDecodeUint32.go
index 0d23de2..51355c3 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/message/encodeDecodeUint32.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/encodeDecodeUint32.go
@@ -25,7 +25,7 @@ func EncodeUint32(buf []byte, value uint32) (int, error) {
return 3, ErrTooSmall
}
rv := make([]byte, 4)
- binary.BigEndian.PutUint32(rv[:], value)
+ binary.BigEndian.PutUint32(rv, value)
copy(buf, rv[1:])
return 3, nil
default:
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/error.go b/vendor/github.com/plgd-dev/go-coap/v3/message/error.go
similarity index 91%
rename from vendor/github.com/plgd-dev/go-coap/v2/message/error.go
rename to vendor/github.com/plgd-dev/go-coap/v3/message/error.go
index 24f433a..267cdb0 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/message/error.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/error.go
@@ -7,7 +7,7 @@ var (
ErrInvalidOptionHeaderExt = errors.New("invalid option header ext")
ErrInvalidTokenLen = errors.New("invalid token length")
ErrInvalidValueLength = errors.New("invalid value length")
- ErrShortRead = errors.New("invalid shor read")
+ ErrShortRead = errors.New("invalid short read")
ErrOptionTruncated = errors.New("option truncated")
ErrOptionUnexpectedExtendMarker = errors.New("option unexpected extend marker")
ErrOptionsTooSmall = errors.New("too small options buffer")
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/getETag.go b/vendor/github.com/plgd-dev/go-coap/v3/message/getETag.go
similarity index 74%
rename from vendor/github.com/plgd-dev/go-coap/v2/message/getETag.go
rename to vendor/github.com/plgd-dev/go-coap/v3/message/getETag.go
index 266275a..0b09623 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/message/getETag.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/getETag.go
@@ -2,11 +2,12 @@ package message
import (
"encoding/binary"
+ "errors"
"hash/crc64"
"io"
)
-// GetETag calculate ETag from payload via CRC64
+// GetETag calculates ETag from payload via CRC64
func GetETag(r io.ReadSeeker) ([]byte, error) {
if r == nil {
return make([]byte, 8), nil
@@ -23,12 +24,12 @@ func GetETag(r io.ReadSeeker) ([]byte, error) {
buf := make([]byte, 4096)
for {
bufR := buf
- n, err := r.Read(bufR)
- if err == io.EOF {
+ n, errR := r.Read(bufR)
+ if errors.Is(errR, io.EOF) {
break
}
- if err != nil {
- return nil, err
+ if errR != nil {
+ return nil, errR
}
bufR = bufR[:n]
c64.Write(bufR)
@@ -38,6 +39,6 @@ func GetETag(r io.ReadSeeker) ([]byte, error) {
return nil, err
}
b := make([]byte, 8)
- binary.LittleEndian.PutUint64(b, c64.Sum64())
+ binary.BigEndian.PutUint64(b, c64.Sum64())
return b, nil
}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/getToken.go b/vendor/github.com/plgd-dev/go-coap/v3/message/getToken.go
similarity index 79%
rename from vendor/github.com/plgd-dev/go-coap/v2/message/getToken.go
rename to vendor/github.com/plgd-dev/go-coap/v3/message/getToken.go
index 2565dc1..4ceedde 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/message/getToken.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/getToken.go
@@ -3,6 +3,7 @@ package message
import (
"crypto/rand"
"encoding/hex"
+ "hash/crc64"
)
type Token []byte
@@ -11,6 +12,10 @@ func (t Token) String() string {
return hex.EncodeToString(t)
}
+func (t Token) Hash() uint64 {
+ return crc64.Checksum(t, crc64.MakeTable(crc64.ISO))
+}
+
// GetToken generates a random token by a given length
func GetToken() (Token, error) {
b := make(Token, 8)
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/message/getmid.go b/vendor/github.com/plgd-dev/go-coap/v3/message/getmid.go
new file mode 100644
index 0000000..e049381
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/getmid.go
@@ -0,0 +1,35 @@
+package message
+
+import (
+ "crypto/rand"
+ "encoding/binary"
+ "math"
+ "sync/atomic"
+ "time"
+
+ pkgRand "github.com/plgd-dev/go-coap/v3/pkg/rand"
+)
+
+var weakRng = pkgRand.NewRand(time.Now().UnixNano())
+
+var msgID = uint32(RandMID())
+
+// GetMID generates a message id for UDP. (0 <= mid <= 65535)
+func GetMID() int32 {
+ return int32(uint16(atomic.AddUint32(&msgID, 1)))
+}
+
+func RandMID() int32 {
+ b := make([]byte, 4)
+ _, err := rand.Read(b)
+ if err != nil {
+ // fallback to cryptographically insecure pseudo-random generator
+ return int32(uint16(weakRng.Uint32() >> 16))
+ }
+ return int32(uint16(binary.BigEndian.Uint32(b)))
+}
+
+// ValidateMID validates a message id for UDP. (0 <= mid <= 65535)
+func ValidateMID(mid int32) bool {
+ return mid >= 0 && mid <= math.MaxUint16
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/message/message.go b/vendor/github.com/plgd-dev/go-coap/v3/message/message.go
new file mode 100644
index 0000000..c68ce5f
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/message.go
@@ -0,0 +1,50 @@
+package message
+
+import (
+ "fmt"
+
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+)
+
+// MaxTokenSize maximum of token size that can be used in message
+const MaxTokenSize = 8
+
+type Message struct {
+ Token Token
+ Options Options
+ Code codes.Code
+ Payload []byte
+
+ // For DTLS and UDP messages
+ MessageID int32 // uint16 is valid, all other values are invalid, -1 is used for unset
+ Type Type // uint8 is valid, all other values are invalid, -1 is used for unset
+}
+
+func (r *Message) String() string {
+ if r == nil {
+ return "nil"
+ }
+ buf := fmt.Sprintf("Code: %v, Token: %v", r.Code, r.Token)
+ path, err := r.Options.Path()
+ if err == nil {
+ buf = fmt.Sprintf("%s, Path: %v", buf, path)
+ }
+ cf, err := r.Options.ContentFormat()
+ if err == nil {
+ buf = fmt.Sprintf("%s, ContentFormat: %v", buf, cf)
+ }
+ queries, err := r.Options.Queries()
+ if err == nil {
+ buf = fmt.Sprintf("%s, Queries: %+v", buf, queries)
+ }
+ if ValidateType(r.Type) {
+ buf = fmt.Sprintf("%s, Type: %v", buf, r.Type)
+ }
+ if ValidateMID(r.MessageID) {
+ buf = fmt.Sprintf("%s, MessageID: %v", buf, r.MessageID)
+ }
+ if len(r.Payload) > 0 {
+ buf = fmt.Sprintf("%s, PayloadLen: %v", buf, len(r.Payload))
+ }
+ return buf
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/noresponse/error.go b/vendor/github.com/plgd-dev/go-coap/v3/message/noresponse/error.go
similarity index 100%
rename from vendor/github.com/plgd-dev/go-coap/v2/message/noresponse/error.go
rename to vendor/github.com/plgd-dev/go-coap/v3/message/noresponse/error.go
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/noresponse/noresponse.go b/vendor/github.com/plgd-dev/go-coap/v3/message/noresponse/noresponse.go
similarity index 92%
rename from vendor/github.com/plgd-dev/go-coap/v2/message/noresponse/noresponse.go
rename to vendor/github.com/plgd-dev/go-coap/v3/message/noresponse/noresponse.go
index 28bdc56..8bd0e52 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/message/noresponse/noresponse.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/noresponse/noresponse.go
@@ -1,7 +1,7 @@
package noresponse
import (
- "github.com/plgd-dev/go-coap/v2/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
)
var (
@@ -38,7 +38,7 @@ func decodeNoResponseOption(v uint32) []codes.Code {
return codes
}
-// IsNoResponseCode validates response code againts NoResponse option from request.
+// IsNoResponseCode validates response code against NoResponse option from request.
// https://www.rfc-editor.org/rfc/rfc7967.txt
func IsNoResponseCode(code codes.Code, noRespValue uint32) error {
suppressedCodes := decodeNoResponseOption(noRespValue)
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/option.go b/vendor/github.com/plgd-dev/go-coap/v3/message/option.go
similarity index 82%
rename from vendor/github.com/plgd-dev/go-coap/v2/message/option.go
rename to vendor/github.com/plgd-dev/go-coap/v3/message/option.go
index 3e4a2ed..1a692f1 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/message/option.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/option.go
@@ -2,6 +2,7 @@ package message
import (
"encoding/binary"
+ "errors"
"fmt"
"strconv"
)
@@ -127,9 +128,9 @@ const (
)
type OptionDef struct {
+ MinLen uint32
+ MaxLen uint32
ValueFormat ValueFormat
- MinLen int
- MaxLen int
}
var CoapOptionDefs = map[OptionID]OptionDef{
@@ -160,7 +161,7 @@ type MediaType uint16
// Content formats.
var (
- TextPlain MediaType = 0 // text/plain;charset=utf-8
+ TextPlain MediaType // text/plain;charset=utf-8
AppCoseEncrypt0 MediaType = 16 // application/cose; cose-type="cose-encrypt0" (RFC 8152)
AppCoseMac0 MediaType = 17 // application/cose; cose-type="cose-mac0" (RFC 8152)
AppCoseSign1 MediaType = 18 // application/cose; cose-type="cose-sign1" (RFC 8152)
@@ -169,19 +170,24 @@ var (
AppOctets MediaType = 42 // application/octet-stream
AppExi MediaType = 47 // application/exi
AppJSON MediaType = 50 // application/json
- AppJSONPatch MediaType = 51 //application/json-patch+json (RFC6902)
- AppJSONMergePatch MediaType = 52 //application/merge-patch+json (RFC7396)
- AppCBOR MediaType = 60 //application/cbor (RFC 7049)
- AppCWT MediaType = 61 //application/cwt
- AppCoseEncrypt MediaType = 96 //application/cose; cose-type="cose-encrypt" (RFC 8152)
- AppCoseMac MediaType = 97 //application/cose; cose-type="cose-mac" (RFC 8152)
- AppCoseSign MediaType = 98 //application/cose; cose-type="cose-sign" (RFC 8152)
- AppCoseKey MediaType = 101 //application/cose-key (RFC 8152)
- AppCoseKeySet MediaType = 102 //application/cose-key-set (RFC 8152)
- AppCoapGroup MediaType = 256 //coap-group+json (RFC 7390)
- AppOcfCbor MediaType = 10000 //application/vnd.ocf+cbor
- AppLwm2mTLV MediaType = 11542 //application/vnd.oma.lwm2m+tlv
- AppLwm2mJSON MediaType = 11543 //application/vnd.oma.lwm2m+json
+ AppJSONPatch MediaType = 51 // application/json-patch+json (RFC6902)
+ AppJSONMergePatch MediaType = 52 // application/merge-patch+json (RFC7396)
+ AppCBOR MediaType = 60 // application/cbor (RFC 7049)
+ AppCWT MediaType = 61 // application/cwt
+ AppCoseEncrypt MediaType = 96 // application/cose; cose-type="cose-encrypt" (RFC 8152)
+ AppCoseMac MediaType = 97 // application/cose; cose-type="cose-mac" (RFC 8152)
+ AppCoseSign MediaType = 98 // application/cose; cose-type="cose-sign" (RFC 8152)
+ AppCoseKey MediaType = 101 // application/cose-key (RFC 8152)
+ AppCoseKeySet MediaType = 102 // application/cose-key-set (RFC 8152)
+ AppSenmlJSON MediaType = 110 // application/senml+json
+ AppSenmlCbor MediaType = 112 // application/senml+cbor
+ AppCoapGroup MediaType = 256 // coap-group+json (RFC 7390)
+ AppSenmlEtchJSON MediaType = 320 // application/senml-etch+json
+ AppSenmlEtchCbor MediaType = 322 // application/senml-etch+cbor
+ AppOcfCbor MediaType = 10000 // application/vnd.ocf+cbor
+ AppLwm2mTLV MediaType = 11542 // application/vnd.oma.lwm2m+tlv
+ AppLwm2mJSON MediaType = 11543 // application/vnd.oma.lwm2m+json
+ AppLwm2mCbor MediaType = 11544 // application/vnd.oma.lwm2m+cbor
)
var mediaTypeToString = map[MediaType]string{
@@ -203,10 +209,15 @@ var mediaTypeToString = map[MediaType]string{
AppCoseSign: "application/cose; cose-type=\"cose-sign\" (RFC 8152)",
AppCoseKey: "application/cose-key (RFC 8152)",
AppCoseKeySet: "application/cose-key-set (RFC 8152)",
+ AppSenmlJSON: "application/senml+json",
+ AppSenmlCbor: "application/senml+cbor",
AppCoapGroup: "coap-group+json (RFC 7390)",
+ AppSenmlEtchJSON: "application/senml-etch+json",
+ AppSenmlEtchCbor: "application/senml-etch+cbor",
AppOcfCbor: "application/vnd.ocf+cbor",
AppLwm2mTLV: "application/vnd.oma.lwm2m+tlv",
AppLwm2mJSON: "application/vnd.oma.lwm2m+json",
+ AppLwm2mCbor: "application/vnd.oma.lwm2m+cbor",
}
func (c MediaType) String() string {
@@ -240,16 +251,25 @@ func extendOpt(opt int) (int, int) {
return opt, ext
}
+// VerifyOptLen checks whether valueLen is within (min, max) length limits for given option.
+func VerifyOptLen(optID OptionID, valueLen int) bool {
+ def := CoapOptionDefs[optID]
+ if valueLen < int(def.MinLen) || valueLen > int(def.MaxLen) {
+ return false
+ }
+ return true
+}
+
func marshalOptionHeaderExt(buf []byte, opt, ext int) (int, error) {
switch opt {
case ExtendOptionByteCode:
- if buf != nil && len(buf) > 0 {
+ if len(buf) > 0 {
buf[0] = byte(ext)
return 1, nil
}
return 1, ErrTooSmall
case ExtendOptionWordCode:
- if buf != nil && len(buf) > 1 {
+ if len(buf) > 1 {
binary.BigEndian.PutUint16(buf, uint16(ext))
return 2, nil
}
@@ -264,7 +284,7 @@ func marshalOptionHeader(buf []byte, delta, length int) (int, error) {
d, dx := extendOpt(delta)
l, lx := extendOpt(length)
- if buf != nil && len(buf) > 0 {
+ if len(buf) > 0 {
buf[0] = byte(d<<4) | byte(l)
size++
} else {
@@ -279,9 +299,9 @@ func marshalOptionHeader(buf []byte, delta, length int) (int, error) {
lenBuf, err = marshalOptionHeaderExt(buf[size:], d, dx)
}
- switch err {
- case nil:
- case ErrTooSmall:
+ switch {
+ case err == nil:
+ case errors.Is(err, ErrTooSmall):
buf = nil
default:
return -1, err
@@ -293,9 +313,9 @@ func marshalOptionHeader(buf []byte, delta, length int) (int, error) {
} else {
lenBuf, err = marshalOptionHeaderExt(buf[size:], l, lx)
}
- switch err {
- case nil:
- case ErrTooSmall:
+ switch {
+ case err == nil:
+ case errors.Is(err, ErrTooSmall):
buf = nil
default:
return -1, err
@@ -308,8 +328,8 @@ func marshalOptionHeader(buf []byte, delta, length int) (int, error) {
}
type Option struct {
- ID OptionID
Value []byte
+ ID OptionID
}
func (o Option) MarshalValue(buf []byte) (int, error) {
@@ -353,17 +373,17 @@ func (o Option) Marshal(buf []byte, previousID OptionID) (int, error) {
delta := int(o.ID) - int(previousID)
lenBuf, err := o.MarshalValue(nil)
- switch err {
- case ErrTooSmall, nil:
+ switch {
+ case err == nil, errors.Is(err, ErrTooSmall):
default:
return -1, err
}
- //header marshal
+ // header marshal
lenBuf, err = marshalOptionHeader(buf, delta, lenBuf)
- switch err {
- case nil:
- case ErrTooSmall:
+ switch {
+ case err == nil:
+ case errors.Is(err, ErrTooSmall):
buf = nil
default:
return -1, err
@@ -376,14 +396,14 @@ func (o Option) Marshal(buf []byte, previousID OptionID) (int, error) {
lenBuf, err = o.MarshalValue(buf[length:])
}
- switch err {
- case nil:
- case ErrTooSmall:
+ switch {
+ case err == nil:
+ case errors.Is(err, ErrTooSmall):
buf = nil
default:
return -1, err
}
- length = length + lenBuf
+ length += lenBuf
if buf == nil {
return length, ErrTooSmall
@@ -410,18 +430,18 @@ func parseExtOpt(data []byte, opt int) (int, int, error) {
return processed, opt, nil
}
-func (o *Option) Unmarshal(data []byte, optionDefs map[OptionID]OptionDef, OptionID OptionID) (int, error) {
- if def, ok := optionDefs[OptionID]; ok {
+func (o *Option) Unmarshal(data []byte, optionDefs map[OptionID]OptionDef, optionID OptionID) (int, error) {
+ if def, ok := optionDefs[optionID]; ok {
if def.ValueFormat == ValueUnknown {
// Skip unrecognized options (RFC7252 section 5.4.1)
return len(data), nil
}
- if len(data) < def.MinLen || len(data) > def.MaxLen {
+ if uint32(len(data)) < def.MinLen || uint32(len(data)) > def.MaxLen {
// Skip options with illegal value length (RFC7252 section 5.4.3)
return len(data), nil
}
}
- o.ID = OptionID
+ o.ID = optionID
proc, err := o.UnmarshalValue(data)
if err != nil {
return -1, err
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/message/options.go b/vendor/github.com/plgd-dev/go-coap/v3/message/options.go
similarity index 65%
rename from vendor/github.com/plgd-dev/go-coap/v2/message/options.go
rename to vendor/github.com/plgd-dev/go-coap/v3/message/options.go
index 557e82e..b162f9a 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/message/options.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/options.go
@@ -1,6 +1,7 @@
package message
import (
+ "errors"
"strings"
)
@@ -9,39 +10,91 @@ type Options []Option
const maxPathValue = 255
-// SetPath splits path by '/' to URIPath options and copy it to buffer.
+// GetPathBufferSize gets the size of the buffer required to store path in URI-Path options.
//
-// Return's modified options, number of used buf bytes and error if occurs.
-func (options Options) SetPath(buf []byte, path string) (Options, int, error) {
+// If the path cannot be stored an error is returned.
+func GetPathBufferSize(path string) (int, error) {
+ size := 0
+ for start := 0; start < len(path); {
+ subPath := path[start:]
+ segmentSize := strings.Index(subPath, "/")
+ if segmentSize == 0 {
+ start++
+ continue
+ }
+ if segmentSize < 0 {
+ segmentSize = len(subPath)
+ }
+ if segmentSize > maxPathValue {
+ return -1, ErrInvalidValueLength
+ }
+ size += segmentSize
+ start += segmentSize + 1
+ }
+ return size, nil
+}
+
+func setPath(options Options, optionID OptionID, buf []byte, path string) (Options, int, error) {
if len(path) == 0 {
return options, 0, nil
}
- o := options.Remove(URIPath)
+ o := options.Remove(optionID)
if path[0] == '/' {
path = path[1:]
}
+ requiredSize, err := GetPathBufferSize(path)
+ if err != nil {
+ return options, -1, err
+ }
+ if requiredSize > len(buf) {
+ return options, -1, ErrTooSmall
+ }
encoded := 0
for start := 0; start < len(path); {
subPath := path[start:]
end := strings.Index(subPath, "/")
- if end <= 0 {
+ if end == 0 {
+ start++
+ continue
+ }
+ if end < 0 {
end = len(subPath)
}
data := buf[encoded:]
var enc int
var err error
- o, enc, err = o.AddString(data, URIPath, subPath[:end])
+ o, enc, err = o.AddString(data, optionID, subPath[:end])
if err != nil {
return o, -1, err
}
encoded += enc
- start = start + end + 1
+ start += end + 1
}
return o, encoded, nil
}
-func (options Options) path(buf []byte) (int, error) {
- firstIdx, lastIdx, err := options.Find(URIPath)
+// SetPath splits path by '/' to URIPath options and copies it to buffer.
+//
+// Returns modified options, number of used buf bytes and error if occurs.
+//
+// @note the url encoded into URIHost, URIPort, URIPath is expected to be
+// absolute (https://www.rfc-editor.org/rfc/rfc7252.txt)
+func (options Options) SetPath(buf []byte, path string) (Options, int, error) {
+ return setPath(options, URIPath, buf, path)
+}
+
+// SetLocationPath splits path by '/' to LocationPath options and copies it to buffer.
+//
+// Returns modified options, number of used buf bytes and error if occurs.
+//
+// @note the url encoded into LocationPath is expected to be
+// absolute (https://www.rfc-editor.org/rfc/rfc7252.txt)
+func (options Options) SetLocationPath(buf []byte, path string) (Options, int, error) {
+ return setPath(options, LocationPath, buf, path)
+}
+
+func (options Options) path(buf []byte, id OptionID) (int, error) {
+ firstIdx, lastIdx, err := options.Find(id)
if err != nil {
return -1, err
}
@@ -50,15 +103,14 @@ func (options Options) path(buf []byte) (int, error) {
needed += len(options[i].Value)
needed++
}
- needed--
+
if len(buf) < needed {
return needed, ErrTooSmall
}
for i := firstIdx; i < lastIdx; i++ {
- if i != firstIdx {
- buf[0] = '/'
- buf = buf[1:]
- }
+ buf[0] = '/'
+ buf = buf[1:]
+
copy(buf, options[i].Value)
buf = buf[len(options[i].Value):]
}
@@ -67,13 +119,30 @@ func (options Options) path(buf []byte) (int, error) {
// Path joins URIPath options by '/' to the buf.
//
-// Return's number of used buf bytes or error when occurs.
+// Returns number of used buf bytes or error when occurs.
func (options Options) Path() (string, error) {
buf := make([]byte, 32)
- m, err := options.path(buf)
- if err == ErrTooSmall {
+ m, err := options.path(buf, URIPath)
+ if errors.Is(err, ErrTooSmall) {
+ buf = append(buf, make([]byte, m)...)
+ m, err = options.path(buf, URIPath)
+ }
+ if err != nil {
+ return "", err
+ }
+ buf = buf[:m]
+ return string(buf), nil
+}
+
+// LocationPath joins Location-Path options by '/' to the buf.
+//
+// Returns number of used buf bytes or error when occurs.
+func (options Options) LocationPath() (string, error) {
+ buf := make([]byte, 32)
+ m, err := options.path(buf, LocationPath)
+ if errors.Is(err, ErrTooSmall) {
buf = append(buf, make([]byte, m)...)
- m, err = options.path(buf)
+ m, err = options.path(buf, LocationPath)
}
if err != nil {
return "", err
@@ -82,29 +151,29 @@ func (options Options) Path() (string, error) {
return string(buf), nil
}
-// SetString replace's/store's string option to options.
+// SetString replaces/stores string option to options.
//
-// Return's modified options, number of used buf bytes and error if occurs.
+// Returns modified options, number of used buf bytes and error if occurs.
func (options Options) SetString(buf []byte, id OptionID, str string) (Options, int, error) {
data := []byte(str)
return options.SetBytes(buf, id, data)
}
-// AddString append's string option to options.
+// AddString appends string option to options.
//
-// Return's modified options, number of used buf bytes and error if occurs.
+// Returns modified options, number of used buf bytes and error if occurs.
func (options Options) AddString(buf []byte, id OptionID, str string) (Options, int, error) {
data := []byte(str)
return options.AddBytes(buf, id, data)
}
-// HasOption return's true is option exist in options.
+// HasOption returns true is option exist in options.
func (options Options) HasOption(id OptionID) bool {
_, _, err := options.Find(id)
return err == nil
}
-// GetUint32s get's all options with same id.
+// GetUint32s gets all options with same id.
func (options Options) GetUint32s(id OptionID, r []uint32) (int, error) {
firstIdx, lastIdx, err := options.Find(id)
if err != nil {
@@ -125,7 +194,7 @@ func (options Options) GetUint32s(id OptionID, r []uint32) (int, error) {
return idx, nil
}
-// GetUint32 get's first option with id of type uint32.
+// GetUint32 gets the uin32 value of the first option with the given ID.
func (options Options) GetUint32(id OptionID) (uint32, error) {
firstIdx, _, err := options.Find(id)
if err != nil {
@@ -135,13 +204,13 @@ func (options Options) GetUint32(id OptionID) (uint32, error) {
return val, err
}
-// ContentFormat get's content format of body.
+// ContentFormat gets the content format of body.
func (options Options) ContentFormat() (MediaType, error) {
v, err := options.GetUint32(ContentFormat)
return MediaType(v), err
}
-// GetString get's first option with id of type string.
+// GetString gets the string value of the first option with the given ID.
func (options Options) GetString(id OptionID) (string, error) {
firstIdx, _, err := options.Find(id)
if err != nil {
@@ -150,9 +219,41 @@ func (options Options) GetString(id OptionID) (string, error) {
return string(options[firstIdx].Value), nil
}
-// SetBytes replace's/store's byte's option to options.
+// GetStrings gets string array of all options with the given id.
+func (options Options) GetStrings(id OptionID, r []string) (int, error) {
+ firstIdx, lastIdx, err := options.Find(id)
+ if err != nil {
+ return 0, err
+ }
+ if len(r) < lastIdx-firstIdx {
+ return lastIdx - firstIdx, ErrTooSmall
+ }
+ var idx int
+ for i := firstIdx; i < lastIdx; i++ {
+ r[idx] = string(options[i].Value)
+ idx++
+ }
+
+ return idx, nil
+}
+
+// Queries gets URIQuery parameters.
+func (options Options) Queries() ([]string, error) {
+ q := make([]string, 4)
+ n, err := options.GetStrings(URIQuery, q)
+ if errors.Is(err, ErrTooSmall) {
+ q = append(q, make([]string, n-len(q))...)
+ n, err = options.GetStrings(URIQuery, q)
+ }
+ if err != nil {
+ return nil, err
+ }
+ return q[:n], nil
+}
+
+// SetBytes replaces/stores bytes of a option to options.
//
-// Return's modified options, number of used buf bytes and error if occurs.
+// Returns modified options, number of used buf bytes and error if occurs.
func (options Options) SetBytes(buf []byte, id OptionID, data []byte) (Options, int, error) {
if len(buf) < len(data) {
return options, len(data), ErrTooSmall
@@ -164,9 +265,9 @@ func (options Options) SetBytes(buf []byte, id OptionID, data []byte) (Options,
return options.Set(Option{ID: id, Value: buf[:len(data)]}), len(data), nil
}
-// AddBytes append's byte's option to options.
+// AddBytes appends bytes of a option option to options.
//
-// Return's modified options, number of used buf bytes and error if occurs.
+// Returns modified options, number of used buf bytes and error if occurs.
func (options Options) AddBytes(buf []byte, id OptionID, data []byte) (Options, int, error) {
if len(buf) < len(data) {
return options, len(data), ErrTooSmall
@@ -178,7 +279,7 @@ func (options Options) AddBytes(buf []byte, id OptionID, data []byte) (Options,
return options.Add(Option{ID: id, Value: buf[:len(data)]}), len(data), nil
}
-// GetBytes get's first option with id of type byte's.
+// GetBytes gets bytes of the first option with given id.
func (options Options) GetBytes(id OptionID) ([]byte, error) {
firstIdx, _, err := options.Find(id)
if err != nil {
@@ -187,39 +288,7 @@ func (options Options) GetBytes(id OptionID) ([]byte, error) {
return options[firstIdx].Value, nil
}
-// GetStrings get's all options with same id.
-func (options Options) GetStrings(id OptionID, r []string) (int, error) {
- firstIdx, lastIdx, err := options.Find(id)
- if err != nil {
- return 0, err
- }
- if len(r) < lastIdx-firstIdx {
- return lastIdx - firstIdx, ErrTooSmall
- }
- var idx int
- for i := firstIdx; i < lastIdx; i++ {
- r[idx] = string(options[i].Value)
- idx++
- }
-
- return idx, nil
-}
-
-// Queries get's URIQuery parameters.
-func (options Options) Queries() ([]string, error) {
- q := make([]string, 4)
- n, err := options.GetStrings(URIQuery, q)
- if err == ErrTooSmall {
- q = append(q, make([]string, n-len(q))...)
- n, err = options.GetStrings(URIQuery, q)
- }
- if err != nil {
- return nil, err
- }
- return q[:n], nil
-}
-
-// GetBytess get's all options with same id.
+// GetBytess gets array of bytes of all options with the same id.
func (options Options) GetBytess(id OptionID, r [][]byte) (int, error) {
firstIdx, lastIdx, err := options.Find(id)
if err != nil {
@@ -237,11 +306,11 @@ func (options Options) GetBytess(id OptionID, r [][]byte) (int, error) {
return idx, nil
}
-// AddUint32 append's uint32 option to options.
+// AddUint32 appends uint32 option to options.
//
-// Return's modified options, number of used buf bytes and error if occurs.
+// Returns modified options, number of used buf bytes and error if occurs.
func (options Options) AddUint32(buf []byte, id OptionID, value uint32) (Options, int, error) {
- enc, err := EncodeUint32(buf, uint32(value))
+ enc, err := EncodeUint32(buf, value)
if err != nil {
return options, enc, err
}
@@ -249,11 +318,11 @@ func (options Options) AddUint32(buf []byte, id OptionID, value uint32) (Options
return o, enc, err
}
-// SetUint32 replace's/store's uint32 option to options.
+// SetUint32 replaces/stores uint32 option to options.
//
-// Return's modified options, number of used buf bytes and error if occurs.
+// Returns modified options, number of used buf bytes and error if occurs.
func (options Options) SetUint32(buf []byte, id OptionID, value uint32) (Options, int, error) {
- enc, err := EncodeUint32(buf, uint32(value))
+ enc, err := EncodeUint32(buf, value)
if err != nil {
return options, enc, err
}
@@ -261,35 +330,35 @@ func (options Options) SetUint32(buf []byte, id OptionID, value uint32) (Options
return o, enc, err
}
-// SetContentFormat set's ContentFormat option.
+// SetContentFormat sets ContentFormat option.
func (options Options) SetContentFormat(buf []byte, contentFormat MediaType) (Options, int, error) {
return options.SetUint32(buf, ContentFormat, uint32(contentFormat))
}
-// SetObserve set's ContentFormat option.
+// SetObserve sets Observe option.
func (options Options) SetObserve(buf []byte, observe uint32) (Options, int, error) {
return options.SetUint32(buf, Observe, observe)
}
-// Observe get's observe option.
+// Observe gets Observe option.
func (options Options) Observe() (uint32, error) {
return options.GetUint32(Observe)
}
-// SetAccept set's accept option.
+// SetAccept sets accept option.
func (options Options) SetAccept(buf []byte, contentFormat MediaType) (Options, int, error) {
return options.SetUint32(buf, Accept, uint32(contentFormat))
}
-// Accept get's accept option.
+// Accept gets accept option.
func (options Options) Accept() (MediaType, error) {
v, err := options.GetUint32(Accept)
return MediaType(v), err
}
-// Find return's range of type options. First number is index and second number is index of next option type.
-func (options Options) Find(ID OptionID) (int, int, error) {
- idxPre, idxPost := options.findPositon(ID)
+// Find returns range of type options. First number is index and second number is index of next option type.
+func (options Options) Find(id OptionID) (int, int, error) {
+ idxPre, idxPost := options.findPosition(id)
if idxPre == -1 && idxPost == 0 {
return -1, -1, ErrOptionNotFound
}
@@ -299,15 +368,15 @@ func (options Options) Find(ID OptionID) (int, int, error) {
if idxPre < idxPost && idxPost-idxPre == 1 {
return -1, -1, ErrOptionNotFound
}
- idxPre = idxPre + 1
+ idxPre++
if idxPost < 0 {
idxPost = len(options)
}
return idxPre, idxPost, nil
}
-// findPositon returns opened interval, -1 at means minIdx insert at 0, -1 maxIdx at maxIdx means append.
-func (options Options) findPositon(ID OptionID) (minIdx int, maxIdx int) {
+// findPosition returns opened interval, -1 at means minIdx insert at 0, -1 maxIdx at maxIdx means append.
+func (options Options) findPosition(id OptionID) (minIdx int, maxIdx int) {
if len(options) == 0 {
return -1, 0
}
@@ -316,32 +385,34 @@ func (options Options) findPositon(ID OptionID) (minIdx int, maxIdx int) {
minIdx = 0
for {
switch {
- case ID == options[pivot].ID || (maxIdx-minIdx)/2 == 0:
- for maxIdx = pivot; maxIdx < len(options) && options[maxIdx].ID <= ID; maxIdx++ {
+ case id == options[pivot].ID || (maxIdx-minIdx)/2 == 0:
+ for maxIdx = pivot; maxIdx < len(options) && options[maxIdx].ID <= id; {
+ maxIdx++
}
if maxIdx == len(options) {
maxIdx = -1
}
- for minIdx = pivot; minIdx >= 0 && options[minIdx].ID >= ID; minIdx-- {
+ for minIdx = pivot; minIdx >= 0 && options[minIdx].ID >= id; {
+ minIdx--
}
return minIdx, maxIdx
- case ID < options[pivot].ID:
+ case id < options[pivot].ID:
maxIdx = pivot
pivot = maxIdx - (maxIdx-minIdx)/2
- case ID > options[pivot].ID:
+ case id > options[pivot].ID:
minIdx = pivot
pivot = minIdx + (maxIdx-minIdx)/2
}
}
}
-// Set replace's/store's option at options.
+// Set replaces/stores option at options.
//
-// Return's modified options.
+// Returns modified options.
func (options Options) Set(opt Option) Options {
- idxPre, idxPost := options.findPositon(opt.ID)
+ idxPre, idxPost := options.findPosition(opt.ID)
if idxPre == -1 && idxPost == -1 {
- //append
+ // append
options = append(options[:0], opt)
return options
}
@@ -375,7 +446,7 @@ func (options Options) Set(opt Option) Options {
} else {
options = options[:len(options)+1]
}
- //replace + move
+ // replace + move
updateIdx := updateTo
if updateFrom < updateTo {
for i := optsLength; i > updateFrom; i-- {
@@ -394,9 +465,9 @@ func (options Options) Set(opt Option) Options {
return options
}
-// Add append's option to options.
+// Add appends option to options.
func (options Options) Add(opt Option) Options {
- _, idxPost := options.findPositon(opt.ID)
+ _, idxPost := options.findPosition(opt.ID)
if idxPost == -1 {
idxPost = len(options)
}
@@ -412,9 +483,9 @@ func (options Options) Add(opt Option) Options {
return options
}
-// Remove remove's all options with ID.
-func (options Options) Remove(ID OptionID) Options {
- idxPre, idxPost, err := options.Find(ID)
+// Remove removes all options with ID.
+func (options Options) Remove(id OptionID) Options {
+ idxPre, idxPost, err := options.Find(id)
if err != nil {
return options
}
@@ -429,16 +500,15 @@ func (options Options) Remove(ID OptionID) Options {
return options
}
-// Marshal marshal's options to buf.
+// Marshal marshals options to buf.
//
-// Return's number of used buf byte's.
+// Returns the number of used buf bytes.
func (options Options) Marshal(buf []byte) (int, error) {
previousID := OptionID(0)
length := 0
for _, o := range options {
-
- //return coap.error but calculate length
+ // return coap.error but calculate length
if length > len(buf) {
buf = nil
}
@@ -453,14 +523,14 @@ func (options Options) Marshal(buf []byte) (int, error) {
}
previousID = o.ID
- switch err {
- case nil:
- case ErrTooSmall:
+ switch {
+ case err == nil:
+ case errors.Is(err, ErrTooSmall):
buf = nil
default:
return -1, err
}
- length = length + optionLength
+ length += optionLength
}
if buf == nil {
return length, ErrTooSmall
@@ -468,7 +538,7 @@ func (options Options) Marshal(buf []byte) (int, error) {
return length, nil
}
-// Unmarshal unmarshal's data bytes to options and returns number of consumned byte's.
+// Unmarshal unmarshals data bytes to options and returns the number of consumed bytes.
func (options *Options) Unmarshal(data []byte, optionDefs map[OptionID]OptionDef) (int, error) {
prev := 0
processed := 0
@@ -527,9 +597,9 @@ func (options *Options) Unmarshal(data []byte, optionDefs map[OptionID]OptionDef
return processed, nil
}
-// ResetOptionsTo reset's options to in options.
+// ResetOptionsTo resets options to in options.
//
-// Return's modified options, number of used buf bytes and error if occurs.
+// Returns modified options, number of used buf bytes and error if occurs.
func (options Options) ResetOptionsTo(buf []byte, in Options) (Options, int, error) {
opts := options[:0]
used := 0
@@ -556,9 +626,9 @@ func (options Options) Clone() (Options, error) {
opts := make(Options, 0, len(options))
buf := make([]byte, 64)
opts, used, err := opts.ResetOptionsTo(buf, options)
- if err == ErrTooSmall {
+ if errors.Is(err, ErrTooSmall) {
buf = append(buf, make([]byte, used-len(buf))...)
- opts, used, err = opts.ResetOptionsTo(buf, options)
+ opts, _, err = opts.ResetOptionsTo(buf, options)
}
if err != nil {
return nil, err
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/message/pool/message.go b/vendor/github.com/plgd-dev/go-coap/v3/message/pool/message.go
new file mode 100644
index 0000000..22cf886
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/pool/message.go
@@ -0,0 +1,600 @@
+package pool
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+
+ multierror "github.com/hashicorp/go-multierror"
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "go.uber.org/atomic"
+)
+
+type Encoder interface {
+ Size(m message.Message) (int, error)
+ Encode(m message.Message, buf []byte) (int, error)
+}
+
+type Decoder interface {
+ Decode(buf []byte, m *message.Message) (int, error)
+}
+
+type Message struct {
+ // Context context of request.
+ ctx context.Context
+ msg message.Message
+ hijacked atomic.Bool
+ isModified bool
+ valueBuffer []byte
+ origValueBuffer []byte
+ body io.ReadSeeker
+ sequence uint64
+
+ // local vars
+ bufferUnmarshal []byte
+ bufferMarshal []byte
+}
+
+const valueBufferSize = 256
+
+func NewMessage(ctx context.Context) *Message {
+ valueBuffer := make([]byte, valueBufferSize)
+ return &Message{
+ ctx: ctx,
+ msg: message.Message{
+ Options: make(message.Options, 0, 16),
+ MessageID: -1,
+ Type: message.Unset,
+ },
+ valueBuffer: valueBuffer,
+ origValueBuffer: valueBuffer,
+ bufferUnmarshal: make([]byte, 256),
+ bufferMarshal: make([]byte, 256),
+ }
+}
+
+func (r *Message) Context() context.Context {
+ return r.ctx
+}
+
+func (r *Message) SetContext(ctx context.Context) {
+ r.ctx = ctx
+}
+
+func (r *Message) SetMessage(message message.Message) {
+ r.Reset()
+ r.msg = message
+ if len(message.Payload) > 0 {
+ r.body = bytes.NewReader(message.Payload)
+ }
+ r.isModified = true
+}
+
+// SetMessageID only 0 to 2^16-1 are valid.
+func (r *Message) SetMessageID(mid int32) {
+ r.msg.MessageID = mid
+ r.isModified = true
+}
+
+// UpsertMessageID set value only when origin value is invalid. Only 0 to 2^16-1 values are valid.
+func (r *Message) UpsertMessageID(mid int32) {
+ if message.ValidateMID(r.msg.MessageID) {
+ return
+ }
+ r.SetMessageID(mid)
+}
+
+// MessageID returns 0 to 2^16-1 otherwise it contains invalid value.
+func (r *Message) MessageID() int32 {
+ return r.msg.MessageID
+}
+
+func (r *Message) SetType(typ message.Type) {
+ r.msg.Type = typ
+ r.isModified = true
+}
+
+// UpsertType set value only when origin value is invalid. Only 0 to 2^8-1 values are valid.
+func (r *Message) UpsertType(typ message.Type) {
+ if message.ValidateType(r.msg.Type) {
+ return
+ }
+ r.SetType(typ)
+}
+
+func (r *Message) Type() message.Type {
+ return r.msg.Type
+}
+
+// Reset clear message for next reuse
+func (r *Message) Reset() {
+ r.msg.Token = nil
+ r.msg.Code = codes.Empty
+ r.msg.Options = r.msg.Options[:0]
+ r.msg.MessageID = -1
+ r.msg.Type = message.Unset
+ r.msg.Payload = nil
+ r.valueBuffer = r.origValueBuffer
+ r.body = nil
+ r.isModified = false
+ if cap(r.bufferMarshal) > 1024 {
+ r.bufferMarshal = make([]byte, 256)
+ }
+ if cap(r.bufferUnmarshal) > 1024 {
+ r.bufferUnmarshal = make([]byte, 256)
+ }
+ r.isModified = false
+}
+
+func (r *Message) Path() (string, error) {
+ return r.msg.Options.Path()
+}
+
+func (r *Message) Queries() ([]string, error) {
+ return r.msg.Options.Queries()
+}
+
+func (r *Message) Remove(opt message.OptionID) {
+ r.msg.Options = r.msg.Options.Remove(opt)
+ r.isModified = true
+}
+
+func (r *Message) Token() message.Token {
+ if r.msg.Token == nil {
+ return nil
+ }
+ token := make(message.Token, 0, 8)
+ token = append(token, r.msg.Token...)
+ return token
+}
+
+func (r *Message) SetToken(token message.Token) {
+ if token == nil {
+ r.msg.Token = nil
+ return
+ }
+ r.msg.Token = append(r.msg.Token[:0], token...)
+}
+
+func (r *Message) ResetOptionsTo(in message.Options) {
+ opts, used, err := r.msg.Options.ResetOptionsTo(r.valueBuffer, in)
+ if errors.Is(err, message.ErrTooSmall) {
+ r.valueBuffer = append(r.valueBuffer, make([]byte, used)...)
+ opts, used, err = r.msg.Options.ResetOptionsTo(r.valueBuffer, in)
+ }
+ if err != nil {
+ panic(fmt.Errorf("cannot reset options to: %w", err))
+ }
+ r.msg.Options = opts
+ r.valueBuffer = r.valueBuffer[used:]
+ if len(in) > 0 {
+ r.isModified = true
+ }
+}
+
+func (r *Message) Options() message.Options {
+ return r.msg.Options
+}
+
+// SetPath stores the given path within URI-Path options.
+//
+// The value is stored by the algorithm described in RFC7252 and
+// using the internal buffer. If the path is too long, but valid
+// (URI-Path segments must have maximal length of 255) the internal
+// buffer is expanded.
+// If the path is too long, but not valid then the function returns
+// ErrInvalidValueLength error.
+func (r *Message) SetPath(p string) error {
+ opts, used, err := r.msg.Options.SetPath(r.valueBuffer, p)
+ if errors.Is(err, message.ErrTooSmall) {
+ expandBy, errSize := message.GetPathBufferSize(p)
+ if errSize != nil {
+ return fmt.Errorf("cannot calculate buffer size for path: %w", errSize)
+ }
+ r.valueBuffer = append(r.valueBuffer, make([]byte, expandBy)...)
+ opts, used, err = r.msg.Options.SetPath(r.valueBuffer, p)
+ }
+ if err != nil {
+ return fmt.Errorf("cannot set path: %w", err)
+ }
+ r.msg.Options = opts
+ r.valueBuffer = r.valueBuffer[used:]
+ r.isModified = true
+ return nil
+}
+
+// MustSetPath calls SetPath and panics if it returns an error.
+func (r *Message) MustSetPath(p string) {
+ if err := r.SetPath(p); err != nil {
+ panic(err)
+ }
+}
+
+func (r *Message) Code() codes.Code {
+ return r.msg.Code
+}
+
+func (r *Message) SetCode(code codes.Code) {
+ r.msg.Code = code
+ r.isModified = true
+}
+
+// AddETag appends value to existing ETags.
+//
+// Option definition:
+// - format: opaque, length: 1-8, repeatable
+func (r *Message) AddETag(value []byte) error {
+ if !message.VerifyOptLen(message.ETag, len(value)) {
+ return message.ErrInvalidValueLength
+ }
+ r.AddOptionBytes(message.ETag, value)
+ return nil
+}
+
+// SetETag inserts/replaces ETag option(s).
+//
+// After a successful call only a single ETag value will remain.
+func (r *Message) SetETag(value []byte) error {
+ if !message.VerifyOptLen(message.ETag, len(value)) {
+ return message.ErrInvalidValueLength
+ }
+ r.SetOptionBytes(message.ETag, value)
+ return nil
+}
+
+// ETag returns first ETag value
+func (r *Message) ETag() ([]byte, error) {
+ return r.GetOptionBytes(message.ETag)
+}
+
+// ETags returns all ETag values
+//
+// Writes ETag values to output array, returns number of written values or error.
+func (r *Message) ETags(b [][]byte) (int, error) {
+ return r.GetOptionAllBytes(message.ETag, b)
+}
+
+func (r *Message) AddQuery(query string) {
+ r.AddOptionString(message.URIQuery, query)
+}
+
+func (r *Message) GetOptionUint32(id message.OptionID) (uint32, error) {
+ return r.msg.Options.GetUint32(id)
+}
+
+func (r *Message) SetOptionString(opt message.OptionID, value string) {
+ opts, used, err := r.msg.Options.SetString(r.valueBuffer, opt, value)
+ if errors.Is(err, message.ErrTooSmall) {
+ r.valueBuffer = append(r.valueBuffer, make([]byte, used)...)
+ opts, used, err = r.msg.Options.SetString(r.valueBuffer, opt, value)
+ }
+ if err != nil {
+ panic(fmt.Errorf("cannot set string option: %w", err))
+ }
+ r.msg.Options = opts
+ r.valueBuffer = r.valueBuffer[used:]
+ r.isModified = true
+}
+
+func (r *Message) AddOptionString(opt message.OptionID, value string) {
+ opts, used, err := r.msg.Options.AddString(r.valueBuffer, opt, value)
+ if errors.Is(err, message.ErrTooSmall) {
+ r.valueBuffer = append(r.valueBuffer, make([]byte, used)...)
+ opts, used, err = r.msg.Options.AddString(r.valueBuffer, opt, value)
+ }
+ if err != nil {
+ panic(fmt.Errorf("cannot add string option: %w", err))
+ }
+ r.msg.Options = opts
+ r.valueBuffer = r.valueBuffer[used:]
+ r.isModified = true
+}
+
+func (r *Message) AddOptionBytes(opt message.OptionID, value []byte) {
+ if len(r.valueBuffer) < len(value) {
+ r.valueBuffer = append(r.valueBuffer, make([]byte, len(value)-len(r.valueBuffer))...)
+ }
+ n := copy(r.valueBuffer, value)
+ v := r.valueBuffer[:n]
+ r.msg.Options = r.msg.Options.Add(message.Option{ID: opt, Value: v})
+ r.valueBuffer = r.valueBuffer[n:]
+ r.isModified = true
+}
+
+func (r *Message) SetOptionBytes(opt message.OptionID, value []byte) {
+ if len(r.valueBuffer) < len(value) {
+ r.valueBuffer = append(r.valueBuffer, make([]byte, len(value)-len(r.valueBuffer))...)
+ }
+ n := copy(r.valueBuffer, value)
+ v := r.valueBuffer[:n]
+ r.msg.Options = r.msg.Options.Set(message.Option{ID: opt, Value: v})
+ r.valueBuffer = r.valueBuffer[n:]
+ r.isModified = true
+}
+
+// GetOptionBytes gets bytes of the first option with given ID.
+func (r *Message) GetOptionBytes(id message.OptionID) ([]byte, error) {
+ return r.msg.Options.GetBytes(id)
+}
+
+// GetOptionAllBytes gets array of bytes of all options with given ID.
+func (r *Message) GetOptionAllBytes(id message.OptionID, b [][]byte) (int, error) {
+ return r.msg.Options.GetBytess(id, b)
+}
+
+func (r *Message) SetOptionUint32(opt message.OptionID, value uint32) {
+ opts, used, err := r.msg.Options.SetUint32(r.valueBuffer, opt, value)
+ if errors.Is(err, message.ErrTooSmall) {
+ r.valueBuffer = append(r.valueBuffer, make([]byte, used)...)
+ opts, used, err = r.msg.Options.SetUint32(r.valueBuffer, opt, value)
+ }
+ if err != nil {
+ panic(fmt.Errorf("cannot set uint32 option: %w", err))
+ }
+ r.msg.Options = opts
+ r.valueBuffer = r.valueBuffer[used:]
+ r.isModified = true
+}
+
+func (r *Message) AddOptionUint32(opt message.OptionID, value uint32) {
+ opts, used, err := r.msg.Options.AddUint32(r.valueBuffer, opt, value)
+ if errors.Is(err, message.ErrTooSmall) {
+ r.valueBuffer = append(r.valueBuffer, make([]byte, used)...)
+ opts, used, err = r.msg.Options.AddUint32(r.valueBuffer, opt, value)
+ }
+ if err != nil {
+ panic(fmt.Errorf("cannot add uint32 option: %w", err))
+ }
+ r.msg.Options = opts
+ r.valueBuffer = r.valueBuffer[used:]
+ r.isModified = true
+}
+
+func (r *Message) ContentFormat() (message.MediaType, error) {
+ v, err := r.GetOptionUint32(message.ContentFormat)
+ return message.MediaType(v), err
+}
+
+func (r *Message) HasOption(id message.OptionID) bool {
+ return r.msg.Options.HasOption(id)
+}
+
+func (r *Message) SetContentFormat(contentFormat message.MediaType) {
+ r.SetOptionUint32(message.ContentFormat, uint32(contentFormat))
+}
+
+func (r *Message) SetObserve(observe uint32) {
+ r.SetOptionUint32(message.Observe, observe)
+}
+
+func (r *Message) Observe() (uint32, error) {
+ return r.GetOptionUint32(message.Observe)
+}
+
+// SetAccept set's accept option.
+func (r *Message) SetAccept(contentFormat message.MediaType) {
+ r.SetOptionUint32(message.Accept, uint32(contentFormat))
+}
+
+// Accept get's accept option.
+func (r *Message) Accept() (message.MediaType, error) {
+ v, err := r.GetOptionUint32(message.Accept)
+ return message.MediaType(v), err
+}
+
+func (r *Message) BodySize() (int64, error) {
+ if r.body == nil {
+ return 0, nil
+ }
+ orig, err := r.body.Seek(0, io.SeekCurrent)
+ if err != nil {
+ return 0, err
+ }
+ _, err = r.body.Seek(0, io.SeekStart)
+ if err != nil {
+ return 0, err
+ }
+ size, err := r.body.Seek(0, io.SeekEnd)
+ if err != nil {
+ return 0, err
+ }
+ _, err = r.body.Seek(orig, io.SeekStart)
+ if err != nil {
+ return 0, err
+ }
+ return size, nil
+}
+
+func (r *Message) SetBody(s io.ReadSeeker) {
+ r.body = s
+ r.isModified = true
+}
+
+func (r *Message) Body() io.ReadSeeker {
+ return r.body
+}
+
+func (r *Message) SetSequence(seq uint64) {
+ r.sequence = seq
+}
+
+func (r *Message) Sequence() uint64 {
+ return r.sequence
+}
+
+func (r *Message) Hijack() {
+ r.hijacked.Store(true)
+}
+
+func (r *Message) IsHijacked() bool {
+ return r.hijacked.Load()
+}
+
+func (r *Message) IsModified() bool {
+ return r.isModified
+}
+
+func (r *Message) SetModified(b bool) {
+ r.isModified = b
+}
+
+func (r *Message) String() string {
+ return r.msg.String()
+}
+
+func (r *Message) ReadBody() ([]byte, error) {
+ if r.Body() == nil {
+ return nil, nil
+ }
+ size, err := r.BodySize()
+ if err != nil {
+ return nil, err
+ }
+ if size == 0 {
+ return nil, nil
+ }
+ _, err = r.Body().Seek(0, io.SeekStart)
+ if err != nil {
+ return nil, err
+ }
+ payload := make([]byte, 1024)
+ if int64(len(payload)) < size {
+ payload = make([]byte, size)
+ }
+ n, err := io.ReadFull(r.Body(), payload)
+ if (errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF)) && int64(n) == size {
+ err = nil
+ }
+ if err != nil {
+ return nil, err
+ }
+ return payload[:n], nil
+}
+
+func (r *Message) toMessage() (message.Message, error) {
+ payload, err := r.ReadBody()
+ if err != nil {
+ return message.Message{}, err
+ }
+ m := r.msg
+ m.Payload = payload
+ return m, nil
+}
+
+func (r *Message) MarshalWithEncoder(encoder Encoder) ([]byte, error) {
+ msg, err := r.toMessage()
+ if err != nil {
+ return nil, err
+ }
+ size, err := encoder.Size(msg)
+ if err != nil {
+ return nil, err
+ }
+ if len(r.bufferMarshal) < size {
+ r.bufferMarshal = append(r.bufferMarshal, make([]byte, size-len(r.bufferMarshal))...)
+ }
+ n, err := encoder.Encode(msg, r.bufferMarshal)
+ if err != nil {
+ return nil, err
+ }
+ r.bufferMarshal = r.bufferMarshal[:n]
+ return r.bufferMarshal, nil
+}
+
+func (r *Message) UnmarshalWithDecoder(decoder Decoder, data []byte) (int, error) {
+ if len(r.bufferUnmarshal) < len(data) {
+ r.bufferUnmarshal = append(r.bufferUnmarshal, make([]byte, len(data)-len(r.bufferUnmarshal))...)
+ }
+ copy(r.bufferUnmarshal, data)
+ r.body = nil
+ r.bufferUnmarshal = r.bufferUnmarshal[:len(data)]
+ n, err := decoder.Decode(r.bufferUnmarshal, &r.msg)
+ if err != nil {
+ return n, err
+ }
+ if len(r.msg.Payload) > 0 {
+ r.body = bytes.NewReader(r.msg.Payload)
+ }
+ return n, err
+}
+
+func (r *Message) IsSeparateMessage() bool {
+ return r.Code() == codes.Empty && r.Token() == nil && r.Type() == message.Acknowledgement && len(r.Options()) == 0 && r.Body() == nil
+}
+
+func (r *Message) setupCommon(code codes.Code, path string, token message.Token, opts ...message.Option) error {
+ r.SetCode(code)
+ r.SetToken(token)
+ r.ResetOptionsTo(opts)
+ return r.SetPath(path)
+}
+
+func (r *Message) SetupGet(path string, token message.Token, opts ...message.Option) error {
+ return r.setupCommon(codes.GET, path, token, opts...)
+}
+
+func (r *Message) SetupPost(path string, token message.Token, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) error {
+ if err := r.setupCommon(codes.POST, path, token, opts...); err != nil {
+ return err
+ }
+ if payload != nil {
+ r.SetContentFormat(contentFormat)
+ r.SetBody(payload)
+ }
+ return nil
+}
+
+func (r *Message) SetupPut(path string, token message.Token, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) error {
+ if err := r.setupCommon(codes.PUT, path, token, opts...); err != nil {
+ return err
+ }
+ if payload != nil {
+ r.SetContentFormat(contentFormat)
+ r.SetBody(payload)
+ }
+ return nil
+}
+
+func (r *Message) SetupDelete(path string, token message.Token, opts ...message.Option) error {
+ return r.setupCommon(codes.DELETE, path, token, opts...)
+}
+
+func (r *Message) Clone(msg *Message) error {
+ msg.SetCode(r.Code())
+ msg.SetToken(r.Token())
+ msg.ResetOptionsTo(r.Options())
+ msg.SetType(r.Type())
+ msg.SetMessageID(r.MessageID())
+
+ if r.Body() != nil {
+ buf := bytes.NewBuffer(nil)
+ n, err := r.Body().Seek(0, io.SeekCurrent)
+ if err != nil {
+ return err
+ }
+ _, err = r.body.Seek(0, io.SeekStart)
+ if err != nil {
+ return err
+ }
+ _, err = io.Copy(buf, r.Body())
+ if err != nil {
+ var errs *multierror.Error
+ errs = multierror.Append(errs, err)
+ _, errS := r.Body().Seek(n, io.SeekStart)
+ if errS != nil {
+ errs = multierror.Append(errs, errS)
+ }
+ return errs.ErrorOrNil()
+ }
+ _, err = r.Body().Seek(n, io.SeekStart)
+ if err != nil {
+ return err
+ }
+ r := bytes.NewReader(buf.Bytes())
+ msg.SetBody(r)
+ }
+ return nil
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/message/pool/pool.go b/vendor/github.com/plgd-dev/go-coap/v3/message/pool/pool.go
new file mode 100644
index 0000000..e9c91a2
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/pool/pool.go
@@ -0,0 +1,64 @@
+package pool
+
+import (
+ "context"
+ "fmt"
+ "sync"
+
+ "go.uber.org/atomic"
+)
+
+type Pool struct {
+ // This field needs to be the first in the struct to ensure proper word alignment on 32-bit platforms.
+ // See: https://golang.org/pkg/sync/atomic/#pkg-note-BUG
+ currentMessagesInPool atomic.Int64
+ messagePool sync.Pool
+ maxNumMessages uint32
+ maxMessageBufferSize uint16
+}
+
+func New(maxNumMessages uint32, maxMessageBufferSize uint16) *Pool {
+ return &Pool{
+ maxNumMessages: maxNumMessages,
+ maxMessageBufferSize: maxMessageBufferSize,
+ }
+}
+
+// AcquireMessage returns an empty Message instance from Message pool.
+//
+// The returned Message instance may be passed to ReleaseMessage when it is
+// no longer needed. This allows Message recycling, reduces GC pressure
+// and usually improves performance.
+func (p *Pool) AcquireMessage(ctx context.Context) *Message {
+ v := p.messagePool.Get()
+ if v == nil {
+ return NewMessage(ctx)
+ }
+ r, ok := v.(*Message)
+ if !ok {
+ panic(fmt.Errorf("invalid message type(%T) for pool", v))
+ }
+ p.currentMessagesInPool.Dec()
+ r.ctx = ctx
+ return r
+}
+
+// ReleaseMessage returns req acquired via AcquireMessage to Message pool.
+//
+// It is forbidden accessing req and/or its' members after returning
+// it to Message pool.
+func (p *Pool) ReleaseMessage(req *Message) {
+ for {
+ v := p.currentMessagesInPool.Load()
+ if v >= int64(p.maxNumMessages) {
+ return
+ }
+ next := v + 1
+ if p.currentMessagesInPool.CompareAndSwap(v, next) {
+ break
+ }
+ }
+ req.Reset()
+ req.ctx = nil
+ p.messagePool.Put(req)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/message/tcpOptions.go b/vendor/github.com/plgd-dev/go-coap/v3/message/tcpOptions.go
new file mode 100644
index 0000000..b6d6a74
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/tcpOptions.go
@@ -0,0 +1,78 @@
+package message
+
+// Signal CSM Option IDs
+/*
+ +-----+---+---+-------------------+--------+--------+---------+
+ | No. | C | R | Name | Format | Length | Default |
+ +-----+---+---+-------------------+--------+--------+---------+
+ | 2 | | | MaxMessageSize | uint | 0-4 | 1152 |
+ | 4 | | | BlockWiseTransfer | empty | 0 | (none) |
+ +-----+---+---+-------------------+--------+--------+---------+
+ C=Critical, R=Repeatable
+*/
+
+const (
+ TCPMaxMessageSize OptionID = 2
+ TCPBlockWiseTransfer OptionID = 4
+)
+
+// Signal Ping/Pong Option IDs
+/*
+ +-----+---+---+-------------------+--------+--------+---------+
+ | No. | C | R | Name | Format | Length | Default |
+ +-----+---+---+-------------------+--------+--------+---------+
+ | 2 | | | Custody | empty | 0 | (none) |
+ +-----+---+---+-------------------+--------+--------+---------+
+ C=Critical, R=Repeatable
+*/
+
+const (
+ TCPCustody OptionID = 2
+)
+
+// Signal Release Option IDs
+/*
+ +-----+---+---+---------------------+--------+--------+---------+
+ | No. | C | R | Name | Format | Length | Default |
+ +-----+---+---+---------------------+--------+--------+---------+
+ | 2 | | x | Alternative-Address | string | 1-255 | (none) |
+ | 4 | | | Hold-Off | uint3 | 0-3 | (none) |
+ +-----+---+---+---------------------+--------+--------+---------+
+ C=Critical, R=Repeatable
+*/
+
+const (
+ TCPAlternativeAddress OptionID = 2
+ TCPHoldOff OptionID = 4
+)
+
+// Signal Abort Option IDs
+/*
+ +-----+---+---+---------------------+--------+--------+---------+
+ | No. | C | R | Name | Format | Length | Default |
+ +-----+---+---+---------------------+--------+--------+---------+
+ | 2 | | | Bad-CSM-Option | uint | 0-2 | (none) |
+ +-----+---+---+---------------------+--------+--------+---------+
+ C=Critical, R=Repeatable
+*/
+const (
+ TCPBadCSMOption OptionID = 2
+)
+
+var TCPSignalCSMOptionDefs = map[OptionID]OptionDef{
+ TCPMaxMessageSize: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 4},
+ TCPBlockWiseTransfer: {ValueFormat: ValueEmpty, MinLen: 0, MaxLen: 0},
+}
+
+var TCPSignalPingPongOptionDefs = map[OptionID]OptionDef{
+ TCPCustody: {ValueFormat: ValueEmpty, MinLen: 0, MaxLen: 0},
+}
+
+var TCPSignalReleaseOptionDefs = map[OptionID]OptionDef{
+ TCPAlternativeAddress: {ValueFormat: ValueString, MinLen: 1, MaxLen: 255},
+ TCPHoldOff: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 3},
+}
+
+var TCPSignalAbortOptionDefs = map[OptionID]OptionDef{
+ TCPBadCSMOption: {ValueFormat: ValueUint, MinLen: 0, MaxLen: 2},
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/message/type.go b/vendor/github.com/plgd-dev/go-coap/v3/message/type.go
similarity index 75%
rename from vendor/github.com/plgd-dev/go-coap/v2/udp/message/type.go
rename to vendor/github.com/plgd-dev/go-coap/v3/message/type.go
index 842a6be..1c0e0ea 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/message/type.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/message/type.go
@@ -1,15 +1,18 @@
package message
import (
+ "math"
"strconv"
)
// Type represents the message type.
// It's only part of CoAP UDP messages.
// Reliable transports like TCP do not have a type.
-type Type uint8
+type Type int16
const (
+ // Used for unset
+ Unset Type = -1
// Confirmable messages require acknowledgements.
Confirmable Type = 0
// NonConfirmable messages do not require acknowledgements.
@@ -21,10 +24,11 @@ const (
)
var typeToString = map[Type]string{
+ Unset: "Unset",
Confirmable: "Confirmable",
NonConfirmable: "NonConfirmable",
Acknowledgement: "Acknowledgement",
- Reset: "reset",
+ Reset: "Reset",
}
func (t Type) String() string {
@@ -34,3 +38,8 @@ func (t Type) String() string {
}
return "Type(" + strconv.FormatInt(int64(t), 10) + ")"
}
+
+// ValidateType validates the type for UDP. (0 <= typ <= 255)
+func ValidateType(typ Type) bool {
+ return typ >= 0 && typ <= math.MaxUint8
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/mux/client.go b/vendor/github.com/plgd-dev/go-coap/v3/mux/client.go
new file mode 100644
index 0000000..2a82077
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/mux/client.go
@@ -0,0 +1,51 @@
+package mux
+
+import (
+ "context"
+ "io"
+ "net"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+)
+
+type Observation = interface {
+ Cancel(ctx context.Context, opts ...message.Option) error
+ Canceled() bool
+}
+
+type Conn interface {
+ // create message from pool
+ AcquireMessage(ctx context.Context) *pool.Message
+ // return back the message to the pool for next use
+ ReleaseMessage(m *pool.Message)
+
+ Ping(ctx context.Context) error
+ Get(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error)
+ Delete(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error)
+ Post(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error)
+ Put(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error)
+ Observe(ctx context.Context, path string, observeFunc func(notification *pool.Message), opts ...message.Option) (Observation, error)
+
+ RemoteAddr() net.Addr
+ // NetConn returns the underlying connection that is wrapped by client. The Conn returned is shared by all invocations of NetConn, so do not modify it.
+ NetConn() net.Conn
+ Context() context.Context
+ SetContextValue(key interface{}, val interface{})
+ WriteMessage(req *pool.Message) error
+ // used for GET,PUT,POST,DELETE
+ Do(req *pool.Message) (*pool.Message, error)
+ // used for observation (GET with observe 0)
+ DoObserve(req *pool.Message, observeFunc func(req *pool.Message)) (Observation, error)
+ Close() error
+ Sequence() uint64
+ // Done signalizes that connection is not more processed.
+ Done() <-chan struct{}
+ AddOnClose(func())
+
+ NewGetRequest(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error)
+ NewObserveRequest(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error)
+ NewPutRequest(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error)
+ NewPostRequest(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error)
+ NewDeleteRequest(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/mux/message.go b/vendor/github.com/plgd-dev/go-coap/v3/mux/message.go
new file mode 100644
index 0000000..bba3c2c
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/mux/message.go
@@ -0,0 +1,16 @@
+package mux
+
+import "github.com/plgd-dev/go-coap/v3/message/pool"
+
+// RouteParams contains all the information related to a route
+type RouteParams struct {
+ Path string
+ Vars map[string]string
+ PathTemplate string
+}
+
+// Message contains message with sequence number.
+type Message struct {
+ *pool.Message
+ RouteParams *RouteParams
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/mux/middleware.go b/vendor/github.com/plgd-dev/go-coap/v3/mux/middleware.go
similarity index 76%
rename from vendor/github.com/plgd-dev/go-coap/v2/mux/middleware.go
rename to vendor/github.com/plgd-dev/go-coap/v3/mux/middleware.go
index 42d3b54..94ad7ba 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/mux/middleware.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/mux/middleware.go
@@ -5,11 +5,6 @@ package mux
// to it, and then calls the handler passed as parameter to the MiddlewareFunc.
type MiddlewareFunc func(Handler) Handler
-// middleware interface is anything which implements a MiddlewareFunc named Middleware.
-type middleware interface {
- Middleware(handler Handler) Handler
-}
-
// Middleware allows MiddlewareFunc to implement the middleware interface.
func (mw MiddlewareFunc) Middleware(handler Handler) Handler {
return mw(handler)
@@ -17,7 +12,5 @@ func (mw MiddlewareFunc) Middleware(handler Handler) Handler {
// Use appends a MiddlewareFunc to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router.
func (r *Router) Use(mwf ...MiddlewareFunc) {
- for _, fn := range mwf {
- r.middlewares = append(r.middlewares, fn)
- }
+ r.middlewares = append(r.middlewares, mwf...)
}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/mux/muxResponseWriter.go b/vendor/github.com/plgd-dev/go-coap/v3/mux/muxResponseWriter.go
new file mode 100644
index 0000000..32ea9d4
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/mux/muxResponseWriter.go
@@ -0,0 +1,47 @@
+package mux
+
+import (
+ "io"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+)
+
+// ToHandler converts mux handler to udp/dtls/tcp handler.
+func ToHandler[C Conn](m Handler) func(w *responsewriter.ResponseWriter[C], r *pool.Message) {
+ return func(w *responsewriter.ResponseWriter[C], r *pool.Message) {
+ muxw := &muxResponseWriter[C]{
+ w: w,
+ }
+ m.ServeCOAP(muxw, &Message{
+ Message: r,
+ RouteParams: new(RouteParams),
+ })
+ }
+}
+
+type muxResponseWriter[C Conn] struct {
+ w *responsewriter.ResponseWriter[C]
+}
+
+// SetResponse simplifies the setup of the response for the request. ETags must be set via options. For advanced setup, use Message().
+func (w *muxResponseWriter[C]) SetResponse(code codes.Code, contentFormat message.MediaType, d io.ReadSeeker, opts ...message.Option) error {
+ return w.w.SetResponse(code, contentFormat, d, opts...)
+}
+
+// Conn peer connection.
+func (w *muxResponseWriter[C]) Conn() Conn {
+ return w.w.Conn()
+}
+
+// Message direct access to the response.
+func (w *muxResponseWriter[C]) Message() *pool.Message {
+ return w.w.Message()
+}
+
+// SetMessage replaces the response message. Ensure that Token, MessageID(udp), and Type(udp) messages are paired correctly.
+func (w *muxResponseWriter[C]) SetMessage(msg *pool.Message) {
+ w.w.SetMessage(msg)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/mux/regexp.go b/vendor/github.com/plgd-dev/go-coap/v3/mux/regexp.go
new file mode 100644
index 0000000..f405335
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/mux/regexp.go
@@ -0,0 +1,171 @@
+// The code in this file is taken and adapated from gorilla/mux package.
+
+// Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package mux
+
+import (
+ "bytes"
+ "fmt"
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+func newRouteRegexp(path string) (*routeRegexp, error) {
+ // Check if it is well-formed.
+ idxs, errBraces := braceIndices(path)
+ if errBraces != nil {
+ return nil, errBraces
+ }
+ // Backup the original.
+ template := path
+ // Now let's parse it.
+ defaultPattern := "[^/]+"
+ varsN := make([]string, len(idxs)/2)
+ varsR := make([]*regexp.Regexp, len(idxs)/2)
+ pattern := bytes.NewBufferString("")
+ pattern.WriteByte('^')
+ reverse := bytes.NewBufferString("")
+ var end int
+ var err error
+ for i := 0; i < len(idxs); i += 2 {
+ // Set all values we are interested in.
+ raw := path[end:idxs[i]]
+ end = idxs[i+1]
+ parts := strings.SplitN(path[idxs[i]+1:end-1], ":", 2)
+ name := parts[0]
+ patt := defaultPattern
+ if len(parts) == 2 {
+ patt = parts[1]
+ }
+ // Name or pattern can't be empty.
+ if name == "" || patt == "" {
+ return nil, fmt.Errorf("mux: missing name or pattern in %q",
+ path[idxs[i]:end])
+ }
+ // Build the regexp pattern.
+ fmt.Fprintf(pattern, "%s(?P<%s>%s)", regexp.QuoteMeta(raw), varGroupName(i/2), patt)
+
+ // Build the reverse template.
+ fmt.Fprintf(reverse, "%s%%s", raw)
+
+ // Append variable name and compiled pattern.
+ varsN[i/2] = name
+ varsR[i/2], err = regexp.Compile(fmt.Sprintf("^%s$", patt))
+ if err != nil {
+ return nil, err
+ }
+ }
+ // Add the remaining.
+ raw := path[end:]
+ pattern.WriteString(regexp.QuoteMeta(raw))
+
+ pattern.WriteByte('$')
+
+ // Compile full regexp.
+ reg, errCompile := regexp.Compile(pattern.String())
+ if errCompile != nil {
+ return nil, errCompile
+ }
+
+ // Check for capturing groups which used to work in older versions
+ if reg.NumSubexp() != len(idxs)/2 {
+ panic(fmt.Sprintf("route %s contains capture groups in its regexp. ", template) +
+ "Only non-capturing groups are accepted: e.g. (?:pattern) instead of (pattern)")
+ }
+
+ // Done!
+ return &routeRegexp{
+ template: template,
+ regexp: reg,
+ reverse: reverse.String(),
+ varsN: varsN,
+ varsR: varsR,
+ }, nil
+}
+
+// routeRegexp stores a regexp to match a host or path and information to
+// collect and validate route variables.
+type routeRegexp struct {
+ // The unmodified template.
+ template string
+
+ // Expanded regexp.
+ regexp *regexp.Regexp
+ // Reverse template.
+ reverse string
+ // Variable names.
+ varsN []string
+ // Variable regexps (validators).
+ varsR []*regexp.Regexp
+}
+
+// varGroupName builds a capturing group name for the indexed variable.
+func varGroupName(idx int) string {
+ return "v" + strconv.Itoa(idx)
+}
+
+// braceIndices returns the first level curly brace indices from a string.
+// It returns an error in case of unbalanced braces.
+func braceIndices(s string) ([]int, error) {
+ var level, idx int
+ var idxs []int
+ for i := 0; i < len(s); i++ {
+ switch s[i] {
+ case '{':
+ if level++; level == 1 {
+ idx = i
+ }
+ case '}':
+ if level--; level == 0 {
+ idxs = append(idxs, idx, i+1)
+ } else if level < 0 {
+ return nil, fmt.Errorf("mux: unbalanced braces in %q", s)
+ }
+ }
+ }
+ if level != 0 {
+ return nil, fmt.Errorf("mux: unbalanced braces in %q", s)
+ }
+ return idxs, nil
+}
+
+func (route *routeRegexp) extractRouteParams(path string, routeParams *RouteParams) {
+ matches := route.regexp.FindStringSubmatchIndex(path)
+ if len(matches) > 0 {
+ extractVars(path, matches, route.varsN, routeParams.Vars)
+ }
+}
+
+func extractVars(input string, matches []int, names []string, output map[string]string) {
+ for i, name := range names {
+ output[name] = input[matches[2*i+2]:matches[2*i+3]]
+ }
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/mux/router.go b/vendor/github.com/plgd-dev/go-coap/v3/mux/router.go
similarity index 52%
rename from vendor/github.com/plgd-dev/go-coap/v2/mux/router.go
rename to vendor/github.com/plgd-dev/go-coap/v3/mux/router.go
index 33189ae..5eea894 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/mux/router.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/mux/router.go
@@ -2,16 +2,20 @@ package mux
import (
"errors"
+ "fmt"
"io"
"sync"
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
)
type ResponseWriter = interface {
SetResponse(code codes.Code, contentFormat message.MediaType, d io.ReadSeeker, opts ...message.Option) error
- Client() Client
+ Conn() Conn
+ SetMessage(m *pool.Message)
+ Message() *pool.Message
}
type Handler interface {
@@ -24,6 +28,8 @@ type Handler interface {
// Handler object that calls f.
type HandlerFunc func(w ResponseWriter, r *Message)
+type ErrorFunc = func(error)
+
// ServeCOAP calls f(w, r).
func (f HandlerFunc) ServeCOAP(w ResponseWriter, r *Message) {
f(w, r)
@@ -35,63 +41,80 @@ func (f HandlerFunc) ServeCOAP(w ResponseWriter, r *Message) {
// with same name.
// Router is also safe for concurrent access from multiple goroutines.
type Router struct {
- z map[string]muxEntry
+ middlewares []MiddlewareFunc
+ errors ErrorFunc
+
m *sync.RWMutex
- defaultHandler Handler
- middlewares []MiddlewareFunc
+ defaultHandler Handler // guarded by m
+ z map[string]Route // guarded by m
}
-type muxEntry struct {
- h Handler
- pattern string
+type Route struct {
+ h Handler
+ pattern string
+ regexMatcher *routeRegexp
+}
+
+func (route *Route) GetRouteRegexp() (string, error) {
+ if route.regexMatcher.regexp == nil {
+ return "", errors.New("mux: route does not have a regexp")
+ }
+ return route.regexMatcher.regexp.String(), nil
}
// NewRouter allocates and returns a new Router.
func NewRouter() *Router {
- return &Router{
- z: make(map[string]muxEntry),
- m: new(sync.RWMutex),
+ router := &Router{
middlewares: make([]MiddlewareFunc, 0, 2),
- defaultHandler: HandlerFunc(func(w ResponseWriter, r *Message) {
- w.SetResponse(codes.NotFound, message.TextPlain, nil)
- }),
+ errors: func(err error) {
+ fmt.Println(err)
+ },
+
+ m: new(sync.RWMutex),
+ z: make(map[string]Route),
}
+ router.defaultHandler = HandlerFunc(func(w ResponseWriter, m *Message) {
+ if err := w.SetResponse(codes.NotFound, message.TextPlain, nil); err != nil {
+ router.errors(fmt.Errorf("router handler: cannot set response: %w", err))
+ }
+ })
+ return router
}
// Does path match pattern?
-func pathMatch(pattern, path string) bool {
- switch pattern {
- case "", "/":
- switch path {
- case "", "/":
- return true
- }
- return false
- default:
- n := len(pattern)
- if pattern[n-1] != '/' {
- return pattern == path
- }
- return len(path) >= n && path[0:n] == pattern
- }
+func pathMatch(pattern Route, path string) bool {
+ return pattern.regexMatcher.regexp.MatchString(path)
}
// Find a handler on a handler map given a path string
// Most-specific (longest) pattern wins
-func (r *Router) match(path string) (h Handler, pattern string) {
+func (r *Router) Match(path string, routeParams *RouteParams) (matchedRoute *Route, matchedPattern string) {
r.m.RLock()
- defer r.m.RUnlock()
- var n = 0
- for k, v := range r.z {
- if !pathMatch(k, path) {
+ n := 0
+ for pattern, route := range r.z {
+ if !pathMatch(route, path) {
continue
}
- if h == nil || len(k) > n {
- n = len(k)
- h = v.h
- pattern = v.pattern
+ if matchedRoute == nil || len(pattern) > n {
+ n = len(pattern)
+ r := route
+ matchedRoute = &r
+ matchedPattern = pattern
}
}
+ r.m.RUnlock()
+
+ if matchedRoute == nil {
+ return
+ }
+
+ routeParams.Path = path
+ if routeParams.Vars == nil {
+ routeParams.Vars = make(map[string]string)
+ }
+ routeParams.PathTemplate = matchedPattern
+ matchedRoute.regexMatcher.extractRouteParams(path, routeParams)
+
return
}
@@ -100,18 +123,19 @@ func (r *Router) Handle(pattern string, handler Handler) error {
switch pattern {
case "", "/":
pattern = "/"
- default:
- if pattern[0] == '/' {
- pattern = pattern[1:]
- }
}
if handler == nil {
return errors.New("nil handler")
}
+ routeRegex, err := newRouteRegexp(pattern)
+ if err != nil {
+ return err
+ }
+
r.m.Lock()
- r.z[pattern] = muxEntry{h: handler, pattern: pattern}
+ r.z[pattern] = Route{h: handler, pattern: pattern, regexMatcher: routeRegex}
r.m.Unlock()
return nil
}
@@ -119,13 +143,15 @@ func (r *Router) Handle(pattern string, handler Handler) error {
// DefaultHandle set default handler to the Router
func (r *Router) DefaultHandle(handler Handler) {
r.m.Lock()
+ defer r.m.Unlock()
r.defaultHandler = handler
- r.m.Unlock()
}
// HandleFunc adds a handler function to the Router for pattern.
func (r *Router) HandleFunc(pattern string, handler func(w ResponseWriter, r *Message)) {
- r.Handle(pattern, HandlerFunc(handler))
+ if err := r.Handle(pattern, HandlerFunc(handler)); err != nil {
+ r.errors(fmt.Errorf("cannot handle pattern(%v): %w", pattern, err))
+ }
}
// DefaultHandleFunc set a default handler function to the Router.
@@ -148,24 +174,47 @@ func (r *Router) HandleRemove(pattern string) error {
return errors.New("pattern is not registered in")
}
+// GetRoute obtains route from the pattern it has been assigned
+func (r *Router) GetRoute(pattern string) *Route {
+ r.m.RLock()
+ defer r.m.RUnlock()
+ if route, ok := r.z[pattern]; ok {
+ return &route
+ }
+ return nil
+}
+
+func (r *Router) GetRoutes() map[string]Route {
+ r.m.RLock()
+ defer r.m.RUnlock()
+ return r.z
+}
+
// ServeCOAP dispatches the request to the handler whose
// pattern most closely matches the request message. If DefaultServeMux
// is used the correct thing for DS queries is done: a possible parent
// is sought.
// If no handler is found a standard NotFound message is returned
func (r *Router) ServeCOAP(w ResponseWriter, req *Message) {
- path, err := req.Options.Path()
+ path, err := req.Options().Path()
+ r.m.RLock()
+ defaultHandler := r.defaultHandler
+ r.m.RUnlock()
if err != nil {
- r.defaultHandler.ServeCOAP(w, req)
+ defaultHandler.ServeCOAP(w, req)
return
}
- h, _ := r.match(path)
- if h == nil {
- h = r.defaultHandler
+ var h Handler
+ matchedMuxEntry, _ := r.Match(path, req.RouteParams)
+ if matchedMuxEntry == nil {
+ h = defaultHandler
+ } else {
+ h = matchedMuxEntry.h
}
if h == nil {
return
}
+
for i := len(r.middlewares) - 1; i >= 0; i-- {
h = r.middlewares[i].Middleware(h)
}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/blockwise/blockwise.go b/vendor/github.com/plgd-dev/go-coap/v3/net/blockwise/blockwise.go
new file mode 100644
index 0000000..1828d75
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/blockwise/blockwise.go
@@ -0,0 +1,844 @@
+package blockwise
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "time"
+
+ "github.com/dsnet/golib/memfile"
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/pkg/cache"
+ "golang.org/x/sync/semaphore"
+)
+
+// Block Option value is represented: https://tools.ietf.org/html/rfc7959#section-2.2
+// 0
+// 0 1 2 3 4 5 6 7
+// +-+-+-+-+-+-+-+-+
+// | NUM |M| SZX |
+// +-+-+-+-+-+-+-+-+
+// 0 1
+// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | NUM |M| SZX |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 0 1 2
+// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | NUM |M| SZX |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+const (
+ // max block size is 3bytes: https://tools.ietf.org/html/rfc7959#section-2.1
+ maxBlockValue = 0xffffff
+ // maxBlockNumber is 20bits (NUM)
+ maxBlockNumber = 0xffff7
+ // moreBlocksFollowingMask is represented by one bit (M)
+ moreBlocksFollowingMask = 0x8
+ // szxMask last 3bits represents SZX (SZX)
+ szxMask = 0x7
+)
+
+// SZX enum representation for the size of the block: https://tools.ietf.org/html/rfc7959#section-2.2
+type SZX uint8
+
+const (
+ // SZX16 block of size 16bytes
+ SZX16 SZX = 0
+ // SZX32 block of size 32bytes
+ SZX32 SZX = 1
+ // SZX64 block of size 64bytes
+ SZX64 SZX = 2
+ // SZX128 block of size 128bytes
+ SZX128 SZX = 3
+ // SZX256 block of size 256bytes
+ SZX256 SZX = 4
+ // SZX512 block of size 512bytes
+ SZX512 SZX = 5
+ // SZX1024 block of size 1024bytes
+ SZX1024 SZX = 6
+ // SZXBERT block of size n*1024bytes
+ SZXBERT SZX = 7
+)
+
+var szxToSize = map[SZX]int64{
+ SZX16: 16,
+ SZX32: 32,
+ SZX64: 64,
+ SZX128: 128,
+ SZX256: 256,
+ SZX512: 512,
+ SZX1024: 1024,
+ SZXBERT: 1024,
+}
+
+// Size number of bytes.
+func (s SZX) Size() int64 {
+ val, ok := szxToSize[s]
+ if ok {
+ return val
+ }
+ return -1
+}
+
+// EncodeBlockOption encodes block values to coap option.
+func EncodeBlockOption(szx SZX, blockNumber int64, moreBlocksFollowing bool) (uint32, error) {
+ if szx > SZXBERT {
+ return 0, ErrInvalidSZX
+ }
+ if blockNumber < 0 {
+ return 0, ErrBlockNumberExceedLimit
+ }
+ if blockNumber > maxBlockNumber {
+ return 0, ErrBlockNumberExceedLimit
+ }
+ blockVal := uint32(blockNumber << 4)
+ m := uint32(0)
+ if moreBlocksFollowing {
+ m = 1
+ }
+ blockVal += m << 3
+ blockVal += uint32(szx)
+ return blockVal, nil
+}
+
+// DecodeBlockOption decodes coap block option to block values.
+func DecodeBlockOption(blockVal uint32) (szx SZX, blockNumber int64, moreBlocksFollowing bool, err error) {
+ if blockVal > maxBlockValue {
+ err = ErrBlockInvalidSize
+ return
+ }
+
+ szx = SZX(blockVal & szxMask) // masking for the SZX
+ if (blockVal & moreBlocksFollowingMask) != 0 { // masking for the "M"
+ moreBlocksFollowing = true
+ }
+ blockNumber = int64(blockVal) >> 4 // shifting out the SZX and M vals. leaving the block number behind
+ if blockNumber > maxBlockNumber {
+ err = ErrBlockNumberExceedLimit
+ }
+ return
+}
+
+type Client interface {
+ // create message from pool
+ AcquireMessage(ctx context.Context) *pool.Message
+ // return back the message to the pool for next use
+ ReleaseMessage(m *pool.Message)
+}
+
+type BlockWise[C Client] struct {
+ cc C
+ receivingMessagesCache *cache.Cache[uint64, *messageGuard]
+ sendingMessagesCache *cache.Cache[uint64, *pool.Message]
+ errors func(error)
+ getSentRequestFromOutside func(token message.Token) (*pool.Message, bool)
+ expiration time.Duration
+}
+
+type messageGuard struct {
+ *pool.Message
+ *semaphore.Weighted
+}
+
+func newRequestGuard(request *pool.Message) *messageGuard {
+ return &messageGuard{
+ Message: request,
+ Weighted: semaphore.NewWeighted(1),
+ }
+}
+
+// New provides blockwise.
+// getSentRequestFromOutside must returns a copy of request which will be released after use.
+func New[C Client](
+ cc C,
+ expiration time.Duration,
+ errors func(error),
+ getSentRequestFromOutside func(token message.Token) (*pool.Message, bool),
+) *BlockWise[C] {
+ if getSentRequestFromOutside == nil {
+ getSentRequestFromOutside = func(token message.Token) (*pool.Message, bool) { return nil, false }
+ }
+ return &BlockWise[C]{
+ cc: cc,
+ receivingMessagesCache: cache.NewCache[uint64, *messageGuard](),
+ sendingMessagesCache: cache.NewCache[uint64, *pool.Message](),
+ errors: errors,
+ getSentRequestFromOutside: getSentRequestFromOutside,
+ expiration: expiration,
+ }
+}
+
+func bufferSize(szx SZX, maxMessageSize uint32) int64 {
+ if szx < SZXBERT {
+ return szx.Size()
+ }
+ return (int64(maxMessageSize) / szx.Size()) * szx.Size()
+}
+
+// CheckExpirations iterates over caches and remove expired items.
+func (b *BlockWise[C]) CheckExpirations(now time.Time) {
+ b.receivingMessagesCache.CheckExpirations(now)
+ b.sendingMessagesCache.CheckExpirations(now)
+}
+
+func (b *BlockWise[C]) cloneMessage(r *pool.Message) *pool.Message {
+ req := b.cc.AcquireMessage(r.Context())
+ req.SetCode(r.Code())
+ req.SetToken(r.Token())
+ req.ResetOptionsTo(r.Options())
+ req.SetType(r.Type())
+ return req
+}
+
+func payloadSizeError(err error) error {
+ return fmt.Errorf("cannot get size of payload: %w", err)
+}
+
+// Do sends an coap message and returns an coap response via blockwise transfer.
+func (b *BlockWise[C]) Do(r *pool.Message, maxSzx SZX, maxMessageSize uint32, do func(req *pool.Message) (*pool.Message, error)) (*pool.Message, error) {
+ if maxSzx > SZXBERT {
+ return nil, fmt.Errorf("invalid szx")
+ }
+ if len(r.Token()) == 0 {
+ return nil, fmt.Errorf("invalid token")
+ }
+
+ expire, ok := r.Context().Deadline()
+ if !ok {
+ expire = time.Now().Add(b.expiration)
+ }
+ _, loaded := b.sendingMessagesCache.LoadOrStore(r.Token().Hash(), cache.NewElement(r, expire, nil))
+ if loaded {
+ return nil, fmt.Errorf("invalid token")
+ }
+ defer b.sendingMessagesCache.Delete(r.Token().Hash())
+ if r.Body() == nil {
+ return do(r)
+ }
+ payloadSize, err := r.BodySize()
+ if err != nil {
+ return nil, payloadSizeError(err)
+ }
+ if payloadSize <= maxSzx.Size() {
+ return do(r)
+ }
+
+ switch r.Code() {
+ case codes.POST, codes.PUT:
+ break
+ default:
+ return nil, fmt.Errorf("unsupported command(%v)", r.Code())
+ }
+ req := b.cloneMessage(r)
+ defer b.cc.ReleaseMessage(req)
+ req.SetOptionUint32(message.Size1, uint32(payloadSize))
+ block, err := EncodeBlockOption(maxSzx, 0, true)
+ if err != nil {
+ return nil, fmt.Errorf("cannot encode block option(%v, %v, %v) to bw request: %w", maxSzx, 0, true, err)
+ }
+ req.SetOptionUint32(message.Block1, block)
+ newBufLen := bufferSize(maxSzx, maxMessageSize)
+ buf := make([]byte, newBufLen)
+ newOff, err := r.Body().Seek(0, io.SeekStart)
+ if err != nil {
+ return nil, fmt.Errorf("cannot seek in payload: %w", err)
+ }
+ readed, err := io.ReadFull(r.Body(), buf)
+ if errors.Is(err, io.ErrUnexpectedEOF) {
+ if newOff+int64(readed) == payloadSize {
+ err = nil
+ }
+ }
+ if err != nil {
+ return nil, fmt.Errorf("cannot read payload: %w", err)
+ }
+ buf = buf[:readed]
+ req.SetBody(bytes.NewReader(buf))
+ return do(req)
+}
+
+func newWriteRequestResponse[C Client](cc C, request *pool.Message) *responsewriter.ResponseWriter[C] {
+ req := cc.AcquireMessage(request.Context())
+ req.SetCode(request.Code())
+ req.SetToken(request.Token())
+ req.ResetOptionsTo(request.Options())
+ req.SetBody(request.Body())
+ return responsewriter.New(req, cc, request.Options()...)
+}
+
+// WriteMessage sends an coap message via blockwise transfer.
+func (b *BlockWise[C]) WriteMessage(request *pool.Message, maxSZX SZX, maxMessageSize uint32, writeMessage func(r *pool.Message) error) error {
+ startSendingMessageBlock, err := EncodeBlockOption(maxSZX, 0, true)
+ if err != nil {
+ return fmt.Errorf("cannot encode start sending message block option(%v,%v,%v): %w", maxSZX, 0, true, err)
+ }
+
+ w := newWriteRequestResponse(b.cc, request)
+ err = b.startSendingMessage(w, maxSZX, maxMessageSize, startSendingMessageBlock)
+ if err != nil {
+ return fmt.Errorf("cannot start writing request: %w", err)
+ }
+ return writeMessage(w.Message())
+}
+
+func fitSZX(r *pool.Message, blockType message.OptionID, maxSZX SZX) SZX {
+ block, err := r.GetOptionUint32(blockType)
+ if err != nil {
+ return maxSZX
+ }
+
+ szx, _, _, err := DecodeBlockOption(block)
+ if err != nil {
+ return maxSZX
+ }
+
+ if maxSZX > szx {
+ return szx
+ }
+ return maxSZX
+}
+
+func (b *BlockWise[C]) sendEntityIncomplete(w *responsewriter.ResponseWriter[C], token message.Token) {
+ sendMessage := b.cc.AcquireMessage(w.Message().Context())
+ sendMessage.SetCode(codes.RequestEntityIncomplete)
+ sendMessage.SetToken(token)
+ sendMessage.SetType(message.NonConfirmable)
+ w.SetMessage(sendMessage)
+}
+
+func wantsToBeReceived(r *pool.Message) bool {
+ hasBlock1 := r.HasOption(message.Block1)
+ hasBlock2 := r.HasOption(message.Block2)
+ if hasBlock1 && (r.Code() == codes.POST || r.Code() == codes.PUT) {
+ // r contains payload which we received
+ return true
+ }
+ if hasBlock2 && (r.Code() >= codes.GET && r.Code() <= codes.DELETE) {
+ // r is command to get next block
+ return false
+ }
+ if r.Code() == codes.Continue {
+ return false
+ }
+ return true
+}
+
+func (b *BlockWise[C]) getSendingMessageCode(token uint64) (codes.Code, bool) {
+ v := b.sendingMessagesCache.Load(token)
+ if v == nil {
+ return codes.Empty, false
+ }
+ return v.Data().Code(), true
+}
+
+// Handle middleware which constructs COAP request from blockwise transfer and send COAP response via blockwise.
+func (b *BlockWise[C]) Handle(w *responsewriter.ResponseWriter[C], r *pool.Message, maxSZX SZX, maxMessageSize uint32, next func(w *responsewriter.ResponseWriter[C], r *pool.Message)) {
+ if maxSZX > SZXBERT {
+ panic("invalid maxSZX")
+ }
+ token := r.Token()
+
+ if len(token) == 0 {
+ err := b.handleReceivedMessage(w, r, maxSZX, maxMessageSize, next)
+ if err != nil {
+ b.sendEntityIncomplete(w, token)
+ b.errors(fmt.Errorf("handleReceivedMessage(%v): %w", r, err))
+ }
+ return
+ }
+ tokenStr := token.Hash()
+
+ sendingMessageCode, sendingMessageExist := b.getSendingMessageCode(tokenStr)
+ if !sendingMessageExist || wantsToBeReceived(r) {
+ err := b.handleReceivedMessage(w, r, maxSZX, maxMessageSize, next)
+ if err != nil {
+ b.sendEntityIncomplete(w, token)
+ b.errors(fmt.Errorf("handleReceivedMessage(%v): %w", r, err))
+ }
+ return
+ }
+ more, err := b.continueSendingMessage(w, r, maxSZX, maxMessageSize, sendingMessageCode)
+ if err != nil {
+ b.sendingMessagesCache.Delete(tokenStr)
+ b.errors(fmt.Errorf("continueSendingMessage(%v): %w", r, err))
+ return
+ }
+ // For codes GET,POST,PUT,DELETE, we want them to wait for pairing response and then delete them when the full response comes in or when timeout occurs.
+ if !more && sendingMessageCode > codes.DELETE {
+ b.sendingMessagesCache.Delete(tokenStr)
+ }
+}
+
+func (b *BlockWise[C]) handleReceivedMessage(w *responsewriter.ResponseWriter[C], r *pool.Message, maxSZX SZX, maxMessageSize uint32, next func(w *responsewriter.ResponseWriter[C], r *pool.Message)) error {
+ startSendingMessageBlock, err := EncodeBlockOption(maxSZX, 0, true)
+ if err != nil {
+ return fmt.Errorf("cannot encode start sending message block option(%v,%v,%v): %w", maxSZX, 0, true, err)
+ }
+ switch r.Code() {
+ case codes.Empty, codes.CSM, codes.Ping, codes.Pong, codes.Release, codes.Abort:
+ next(w, r)
+ return nil
+ case codes.GET, codes.DELETE:
+ maxSZX = fitSZX(r, message.Block2, maxSZX)
+ block, errG := r.GetOptionUint32(message.Block2)
+ if errG == nil {
+ r.Remove(message.Block2)
+ }
+ next(w, r)
+ if w.Message().Code() == codes.Content && errG == nil {
+ startSendingMessageBlock = block
+ }
+ case codes.POST, codes.PUT:
+ maxSZX = fitSZX(r, message.Block1, maxSZX)
+ errP := b.processReceivedMessage(w, r, maxSZX, next, message.Block1, message.Size1)
+ if errP != nil {
+ return errP
+ }
+ default:
+ maxSZX = fitSZX(r, message.Block2, maxSZX)
+ errP := b.processReceivedMessage(w, r, maxSZX, next, message.Block2, message.Size2)
+ if errP != nil {
+ return errP
+ }
+ }
+ return b.startSendingMessage(w, maxSZX, maxMessageSize, startSendingMessageBlock)
+}
+
+func (b *BlockWise[C]) createSendingMessage(sendingMessage *pool.Message, maxSZX SZX, maxMessageSize uint32, block uint32) (sendMessage *pool.Message, more bool, err error) {
+ blockType := message.Block2
+ sizeType := message.Size2
+ token := sendingMessage.Token()
+ switch sendingMessage.Code() {
+ case codes.POST, codes.PUT:
+ blockType = message.Block1
+ sizeType = message.Size1
+ }
+
+ szx, num, _, err := DecodeBlockOption(block)
+ if err != nil {
+ return nil, false, fmt.Errorf("cannot decode %v option: %w", blockType, err)
+ }
+
+ sendMessage = b.cc.AcquireMessage(sendingMessage.Context())
+ sendMessage.SetCode(sendingMessage.Code())
+ sendMessage.ResetOptionsTo(sendingMessage.Options())
+ sendMessage.SetToken(token)
+ sendMessage.SetType(sendingMessage.Type())
+ payloadSize, err := sendingMessage.BodySize()
+ if err != nil {
+ b.cc.ReleaseMessage(sendMessage)
+ return nil, false, payloadSizeError(err)
+ }
+ if szx > maxSZX {
+ szx = maxSZX
+ }
+ newBufLen := bufferSize(szx, maxMessageSize)
+ off := num * szx.Size()
+ if blockType == message.Block1 {
+ // For block1, we need to skip the already sent bytes.
+ off += newBufLen
+ }
+ offSeek, err := sendingMessage.Body().Seek(off, io.SeekStart)
+ if err != nil {
+ b.cc.ReleaseMessage(sendMessage)
+ return nil, false, fmt.Errorf("cannot seek in response: %w", err)
+ }
+ if off != offSeek {
+ b.cc.ReleaseMessage(sendMessage)
+ return nil, false, fmt.Errorf("cannot seek to requested offset(%v != %v)", off, offSeek)
+ }
+ buf := make([]byte, 1024)
+ if int64(len(buf)) < newBufLen {
+ buf = make([]byte, newBufLen)
+ }
+ buf = buf[:newBufLen]
+
+ readed, err := io.ReadFull(sendingMessage.Body(), buf)
+ if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF) {
+ if offSeek+int64(readed) == payloadSize {
+ err = nil
+ }
+ }
+ if err != nil {
+ b.cc.ReleaseMessage(sendMessage)
+ return nil, false, fmt.Errorf("cannot read response: %w", err)
+ }
+
+ buf = buf[:readed]
+ sendMessage.SetBody(bytes.NewReader(buf))
+ more = true
+ if offSeek+int64(readed) == payloadSize {
+ more = false
+ }
+ sendMessage.SetOptionUint32(sizeType, uint32(payloadSize))
+ num = (offSeek) / szx.Size()
+ block, err = EncodeBlockOption(szx, num, more)
+ if err != nil {
+ b.cc.ReleaseMessage(sendMessage)
+ return nil, false, fmt.Errorf("cannot encode block option(%v,%v,%v): %w", szx, num, more, err)
+ }
+ sendMessage.SetOptionUint32(blockType, block)
+ return sendMessage, more, nil
+}
+
+func (b *BlockWise[C]) continueSendingMessage(w *responsewriter.ResponseWriter[C], r *pool.Message, maxSZX SZX, maxMessageSize uint32, sendingMessageCode codes.Code /* msg *pool.Message*/) (bool, error) {
+ blockType := message.Block2
+ switch sendingMessageCode {
+ case codes.POST, codes.PUT:
+ blockType = message.Block1
+ }
+
+ block, err := r.GetOptionUint32(blockType)
+ if err != nil {
+ return false, fmt.Errorf("cannot get %v option: %w", blockType, err)
+ }
+ var sendMessage *pool.Message
+ var more bool
+ b.sendingMessagesCache.LoadWithFunc(r.Token().Hash(), func(value *cache.Element[*pool.Message]) *cache.Element[*pool.Message] {
+ sendMessage, more, err = b.createSendingMessage(value.Data(), maxSZX, maxMessageSize, block)
+ if err != nil {
+ err = fmt.Errorf("cannot create sending message: %w", err)
+ }
+ return nil
+ })
+ if err == nil && sendMessage == nil {
+ err = fmt.Errorf("cannot find sending message for token(%v)", r.Token())
+ }
+ if err != nil {
+ return false, fmt.Errorf("handleSendingMessage: %w", err)
+ }
+ w.SetMessage(sendMessage)
+ return more, err
+}
+
+func isObserveResponse(msg *pool.Message) bool {
+ _, err := msg.GetOptionUint32(message.Observe)
+ if err != nil {
+ return false
+ }
+ return msg.Code() >= codes.Created
+}
+
+func (b *BlockWise[C]) startSendingMessage(w *responsewriter.ResponseWriter[C], maxSZX SZX, maxMessageSize uint32, block uint32) error {
+ payloadSize, err := w.Message().BodySize()
+ if err != nil {
+ return payloadSizeError(err)
+ }
+
+ if payloadSize < maxSZX.Size() {
+ return nil
+ }
+ sendingMessage, _, err := b.createSendingMessage(w.Message(), maxSZX, maxMessageSize, block)
+ if err != nil {
+ return fmt.Errorf("handleSendingMessage: cannot create sending message: %w", err)
+ }
+ originalSendingMessage := w.Swap(sendingMessage)
+ if isObserveResponse(w.Message()) {
+ b.cc.ReleaseMessage(originalSendingMessage)
+ // https://tools.ietf.org/html/rfc7959#section-2.6 - we don't need store it because client will be get values via GET.
+ return nil
+ }
+ expire, ok := sendingMessage.Context().Deadline()
+ if !ok {
+ expire = time.Now().Add(b.expiration)
+ }
+ el, loaded := b.sendingMessagesCache.LoadOrStore(sendingMessage.Token().Hash(), cache.NewElement(originalSendingMessage, expire, nil))
+ if loaded {
+ defer b.cc.ReleaseMessage(originalSendingMessage)
+ return fmt.Errorf("cannot add message (%v) to sending message cache: message(%v) with token(%v) already exist", originalSendingMessage, el.Data(), sendingMessage.Token())
+ }
+ return nil
+}
+
+func (b *BlockWise[C]) getSentRequest(token message.Token) *pool.Message {
+ data, ok := b.sendingMessagesCache.LoadWithFunc(token.Hash(), func(value *cache.Element[*pool.Message]) *cache.Element[*pool.Message] {
+ if value == nil {
+ return nil
+ }
+ v := value.Data()
+ msg := b.cc.AcquireMessage(v.Context())
+ msg.SetCode(v.Code())
+ msg.SetToken(v.Token())
+ msg.ResetOptionsTo(v.Options())
+ msg.SetType(v.Type())
+ return cache.NewElement(msg, value.ValidUntil.Load(), nil)
+ })
+ if ok {
+ return data.Data()
+ }
+ globalRequest, ok := b.getSentRequestFromOutside(token)
+ if ok {
+ return globalRequest
+ }
+ return nil
+}
+
+func (b *BlockWise[C]) handleObserveResponse(sentRequest *pool.Message) (message.Token, time.Time, error) {
+ // https://tools.ietf.org/html/rfc7959#section-2.6 - performs GET with new token.
+ if sentRequest == nil {
+ return nil, time.Time{}, fmt.Errorf("observation is not registered")
+ }
+ token, err := message.GetToken()
+ if err != nil {
+ return nil, time.Time{}, fmt.Errorf("cannot get token for create GET request: %w", err)
+ }
+ validUntil := time.Now().Add(b.expiration) // context of observation can be expired.
+ bwSentRequest := b.cloneMessage(sentRequest)
+ bwSentRequest.SetToken(token)
+ _, loaded := b.sendingMessagesCache.LoadOrStore(token.Hash(), cache.NewElement(bwSentRequest, validUntil, nil))
+ if loaded {
+ return nil, time.Time{}, fmt.Errorf("cannot process message: message with token already exist")
+ }
+ return token, validUntil, nil
+}
+
+func (b *BlockWise[C]) getValidUntil(sentRequest *pool.Message) time.Time {
+ validUntil := time.Now().Add(b.expiration)
+ if sentRequest != nil {
+ if deadline, ok := sentRequest.Context().Deadline(); ok {
+ return deadline
+ }
+ }
+ return validUntil
+}
+
+func getSzx(szx, maxSzx SZX) SZX {
+ if szx > maxSzx {
+ return maxSzx
+ }
+ return szx
+}
+
+func (b *BlockWise[C]) getPayloadFromCachedReceivedMessage(r, cachedReceivedMessage *pool.Message) (*memfile.File, int64, error) {
+ payloadFile, ok := cachedReceivedMessage.Body().(*memfile.File)
+ if !ok {
+ return nil, 0, fmt.Errorf("invalid body type(%T) stored in receivingMessagesCache", cachedReceivedMessage.Body())
+ }
+ rETAG, errETAG := r.GetOptionBytes(message.ETag)
+ cachedReceivedMessageETAG, errCachedReceivedMessageETAG := cachedReceivedMessage.GetOptionBytes(message.ETag)
+ switch {
+ case errETAG == nil && errCachedReceivedMessageETAG != nil:
+ if len(cachedReceivedMessageETAG) > 0 { // make sure there is an etag there
+ return nil, 0, fmt.Errorf("received message doesn't contains ETAG but cached received message contains it(%v)", cachedReceivedMessageETAG)
+ }
+ case errETAG != nil && errCachedReceivedMessageETAG == nil:
+ if len(rETAG) > 0 { // make sure there is an etag there
+ return nil, 0, fmt.Errorf("received message contains ETAG(%v) but cached received message doesn't", rETAG)
+ }
+ case !bytes.Equal(rETAG, cachedReceivedMessageETAG):
+ // ETAG was changed - drop data and set new ETAG
+ cachedReceivedMessage.SetOptionBytes(message.ETag, rETAG)
+ if err := payloadFile.Truncate(0); err != nil {
+ return nil, 0, fmt.Errorf("cannot truncate cached request: %w", err)
+ }
+ }
+
+ payloadSize, err := cachedReceivedMessage.BodySize()
+ if err != nil {
+ return nil, 0, payloadSizeError(err)
+ }
+ return payloadFile, payloadSize, nil
+}
+
+func copyToPayloadFromOffset(r *pool.Message, payloadFile *memfile.File, offset int64) (int64, error) {
+ payloadSize := int64(0)
+ copyn, err := payloadFile.Seek(offset, io.SeekStart)
+ if err != nil {
+ return 0, fmt.Errorf("cannot seek to off(%v) of cached request: %w", offset, err)
+ }
+ written := int64(0)
+ if r.Body() != nil {
+ _, err = r.Body().Seek(0, io.SeekStart)
+ if err != nil {
+ return 0, fmt.Errorf("cannot seek to start of request: %w", err)
+ }
+ written, err = io.Copy(payloadFile, r.Body())
+ if err != nil {
+ return 0, fmt.Errorf("cannot copy to cached request: %w", err)
+ }
+ }
+ payloadSize = copyn + written
+ err = payloadFile.Truncate(payloadSize)
+ if err != nil {
+ return 0, fmt.Errorf("cannot truncate cached request: %w", err)
+ }
+ return payloadSize, nil
+}
+
+func (b *BlockWise[C]) getCachedReceivedMessage(mg *messageGuard, r *pool.Message, tokenStr uint64, validUntil time.Time) (*pool.Message, func(), error) {
+ cannotLockError := func(err error) error {
+ return fmt.Errorf("processReceivedMessage: cannot lock message: %w", err)
+ }
+ if mg != nil {
+ errA := mg.Acquire(mg.Context(), 1)
+ if errA != nil {
+ return nil, nil, cannotLockError(errA)
+ }
+ return mg.Message, func() { mg.Release(1) }, nil
+ }
+ closeFnList := []func(){}
+ appendToClose := func(m *messageGuard) {
+ closeFnList = append(closeFnList, func() {
+ m.Release(1)
+ })
+ }
+ closeFn := func() {
+ for i := range closeFnList {
+ closeFnList[len(closeFnList)-1-i]()
+ }
+ }
+ msg := b.cc.AcquireMessage(r.Context())
+ msg.ResetOptionsTo(r.Options())
+ msg.SetToken(r.Token())
+ msg.SetSequence(r.Sequence())
+ msg.SetBody(memfile.New(make([]byte, 0, 1024)))
+ msg.SetCode(r.Code())
+ mg = newRequestGuard(msg)
+ errA := mg.Acquire(mg.Context(), 1)
+ if errA != nil {
+ return nil, nil, cannotLockError(errA)
+ }
+ appendToClose(mg)
+ element, loaded := b.receivingMessagesCache.LoadOrStore(tokenStr, cache.NewElement(mg, validUntil, func(d *messageGuard) {
+ if d == nil {
+ return
+ }
+ b.sendingMessagesCache.Delete(tokenStr)
+ }))
+ // request was already stored in cache, silently
+ if loaded {
+ mg = element.Data()
+ if mg == nil {
+ closeFn()
+ return nil, nil, fmt.Errorf("request was already stored in cache")
+ }
+ errA := mg.Acquire(mg.Context(), 1)
+ if errA != nil {
+ closeFn()
+ return nil, nil, cannotLockError(errA)
+ }
+ appendToClose(mg)
+ }
+
+ return mg.Message, closeFn, nil
+}
+
+//nolint:gocyclo,gocognit
+func (b *BlockWise[C]) processReceivedMessage(w *responsewriter.ResponseWriter[C], r *pool.Message, maxSzx SZX, next func(w *responsewriter.ResponseWriter[C], r *pool.Message), blockType message.OptionID, sizeType message.OptionID) error {
+ // TODO: lower cyclomatic complexity
+ token := r.Token()
+ if len(token) == 0 {
+ next(w, r)
+ return nil
+ }
+ if r.Code() == codes.GET || r.Code() == codes.DELETE {
+ next(w, r)
+ return nil
+ }
+ block, err := r.GetOptionUint32(blockType)
+ if err != nil {
+ if errors.Is(err, message.ErrOptionNotFound) {
+ next(w, r)
+ return nil
+ }
+ return fmt.Errorf("cannot get Block(optionID=%d) option: %w", blockType, err)
+ }
+ szx, num, more, err := DecodeBlockOption(block)
+ if err != nil {
+ return fmt.Errorf("cannot decode block option: %w", err)
+ }
+ sentRequest := b.getSentRequest(token)
+ if sentRequest != nil {
+ defer b.cc.ReleaseMessage(sentRequest)
+ }
+ validUntil := b.getValidUntil(sentRequest)
+ if blockType == message.Block2 && sentRequest == nil {
+ return fmt.Errorf("cannot request body without paired request")
+ }
+ if isObserveResponse(r) {
+ token, validUntil, err = b.handleObserveResponse(sentRequest)
+ if err != nil {
+ return fmt.Errorf("cannot process message: %w", err)
+ }
+ }
+
+ tokenStr := token.Hash()
+ var cachedReceivedMessageGuard *messageGuard
+ if e := b.receivingMessagesCache.Load(tokenStr); e != nil {
+ cachedReceivedMessageGuard = e.Data()
+ }
+ if cachedReceivedMessageGuard == nil {
+ szx = getSzx(szx, maxSzx)
+ // if there is no more then just forward req to next handler
+ if !more {
+ next(w, r)
+ return nil
+ }
+ }
+ cachedReceivedMessage, closeCachedReceivedMessage, err := b.getCachedReceivedMessage(cachedReceivedMessageGuard, r, tokenStr, validUntil)
+ if err != nil {
+ return err
+ }
+ defer closeCachedReceivedMessage()
+
+ defer func(err *error) {
+ if *err != nil {
+ b.receivingMessagesCache.Delete(tokenStr)
+ }
+ }(&err)
+ payloadFile, payloadSize, err := b.getPayloadFromCachedReceivedMessage(r, cachedReceivedMessage)
+ if err != nil {
+ return fmt.Errorf("cannot get payload: %w", err)
+ }
+ off := num * szx.Size()
+ if off == payloadSize {
+ payloadSize, err = copyToPayloadFromOffset(r, payloadFile, off)
+ if err != nil {
+ return fmt.Errorf("cannot copy data to payload: %w", err)
+ }
+ if !more {
+ b.receivingMessagesCache.Delete(tokenStr)
+ cachedReceivedMessage.Remove(blockType)
+ cachedReceivedMessage.Remove(sizeType)
+ cachedReceivedMessage.SetType(r.Type())
+ if !bytes.Equal(cachedReceivedMessage.Token(), token) {
+ b.sendingMessagesCache.Delete(tokenStr)
+ }
+ _, errS := cachedReceivedMessage.Body().Seek(0, io.SeekStart)
+ if errS != nil {
+ return fmt.Errorf("cannot seek to start of cachedReceivedMessage request: %w", errS)
+ }
+ next(w, cachedReceivedMessage)
+ return nil
+ }
+ }
+
+ szx = getSzx(szx, maxSzx)
+ sendMessage := b.cc.AcquireMessage(r.Context())
+ sendMessage.SetToken(token)
+ if blockType == message.Block2 {
+ num = payloadSize / szx.Size()
+ sendMessage.ResetOptionsTo(sentRequest.Options())
+ sendMessage.SetCode(sentRequest.Code())
+ sendMessage.Remove(message.Observe)
+ sendMessage.Remove(message.Block1)
+ sendMessage.Remove(message.Size1)
+ } else {
+ sendMessage.SetCode(codes.Continue)
+ }
+ respBlock, err := EncodeBlockOption(szx, num, more)
+ if err != nil {
+ b.cc.ReleaseMessage(sendMessage)
+ return fmt.Errorf("cannot encode block option(%v,%v,%v): %w", szx, num, more, err)
+ }
+ sendMessage.SetOptionUint32(blockType, respBlock)
+ w.SetMessage(sendMessage)
+ return nil
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/blockwise/error.go b/vendor/github.com/plgd-dev/go-coap/v3/net/blockwise/error.go
similarity index 86%
rename from vendor/github.com/plgd-dev/go-coap/v2/net/blockwise/error.go
rename to vendor/github.com/plgd-dev/go-coap/v3/net/blockwise/error.go
index af4a511..6bc7763 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/blockwise/error.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/blockwise/error.go
@@ -15,8 +15,8 @@ var (
// ErrInvalidOptionBlock1 message has invalid value of Block1
ErrInvalidOptionBlock1 = errors.New("message has invalid value of Block1")
- // ErrInvalidReponseCode response code has invalid value
- ErrInvalidReponseCode = errors.New("response code has invalid value")
+ // ErrInvalidResponseCode response code has invalid value
+ ErrInvalidResponseCode = errors.New("response code has invalid value")
// ErrInvalidPayloadSize invalid payload size
ErrInvalidPayloadSize = errors.New("invalid payload size")
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/client/client.go b/vendor/github.com/plgd-dev/go-coap/v3/net/client/client.go
new file mode 100644
index 0000000..b2cdca9
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/client/client.go
@@ -0,0 +1,241 @@
+package client
+
+import (
+ "context"
+ "fmt"
+ "io"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ limitparallelrequests "github.com/plgd-dev/go-coap/v3/net/client/limitParallelRequests"
+ "github.com/plgd-dev/go-coap/v3/net/observation"
+)
+
+type (
+ GetTokenFunc = func() (message.Token, error)
+)
+
+type Conn interface {
+ // create message from pool
+ AcquireMessage(ctx context.Context) *pool.Message
+ // return back the message to the pool for next use
+ ReleaseMessage(m *pool.Message)
+ WriteMessage(req *pool.Message) error
+ AsyncPing(receivedPong func()) (func(), error)
+ Context() context.Context
+}
+
+type Client[C Conn] struct {
+ cc Conn
+ observationHandler *observation.Handler[C]
+ getToken GetTokenFunc
+ *limitparallelrequests.LimitParallelRequests
+}
+
+func New[C Conn](cc C, observationHandler *observation.Handler[C], getToken GetTokenFunc, limitParallelRequests *limitparallelrequests.LimitParallelRequests) *Client[C] {
+ return &Client[C]{
+ cc: cc,
+ observationHandler: observationHandler,
+ getToken: getToken,
+ LimitParallelRequests: limitParallelRequests,
+ }
+}
+
+func (c *Client[C]) GetToken() (message.Token, error) {
+ return c.getToken()
+}
+
+// NewGetRequest creates get request.
+//
+// Use ctx to set timeout.
+func (c *Client[C]) NewGetRequest(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error) {
+ req := c.cc.AcquireMessage(ctx)
+ token, err := c.GetToken()
+ if err != nil {
+ c.cc.ReleaseMessage(req)
+ return nil, err
+ }
+ err = req.SetupGet(path, token, opts...)
+ if err != nil {
+ c.cc.ReleaseMessage(req)
+ return nil, err
+ }
+ return req, nil
+}
+
+// Get issues a GET to the specified path.
+//
+// Use ctx to set timeout.
+//
+// An error is returned if by failure to speak COAP (such as a network connectivity problem).
+// Any status code doesn't cause an error.
+func (c *Client[C]) Get(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error) {
+ req, err := c.NewGetRequest(ctx, path, opts...)
+ if err != nil {
+ return nil, fmt.Errorf("cannot create get request: %w", err)
+ }
+ defer c.cc.ReleaseMessage(req)
+ return c.Do(req)
+}
+
+type Observation = interface {
+ Cancel(ctx context.Context, opts ...message.Option) error
+ Canceled() bool
+}
+
+// NewObserveRequest creates observe request.
+//
+// Use ctx to set timeout.
+func (c *Client[C]) NewObserveRequest(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error) {
+ req, err := c.NewGetRequest(ctx, path, opts...)
+ if err != nil {
+ return nil, err
+ }
+ req.SetObserve(0)
+ return req, nil
+}
+
+// Observe subscribes for every change of resource on path.
+func (c *Client[C]) Observe(ctx context.Context, path string, observeFunc func(req *pool.Message), opts ...message.Option) (Observation, error) {
+ req, err := c.NewObserveRequest(ctx, path, opts...)
+ if err != nil {
+ return nil, err
+ }
+ defer c.cc.ReleaseMessage(req)
+ return c.DoObserve(req, observeFunc)
+}
+
+func (c *Client[C]) GetObservationRequest(token message.Token) (*pool.Message, bool) {
+ return c.observationHandler.GetObservationRequest(token)
+}
+
+// NewPostRequest creates post request.
+//
+// Use ctx to set timeout.
+//
+// An error is returned if by failure to speak COAP (such as a network connectivity problem).
+// Any status code doesn't cause an error.
+//
+// If payload is nil then content format is not used.
+func (c *Client[C]) NewPostRequest(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error) {
+ req := c.cc.AcquireMessage(ctx)
+ token, err := c.GetToken()
+ if err != nil {
+ c.cc.ReleaseMessage(req)
+ return nil, err
+ }
+ err = req.SetupPost(path, token, contentFormat, payload, opts...)
+ if err != nil {
+ c.cc.ReleaseMessage(req)
+ return nil, err
+ }
+ return req, nil
+}
+
+// Post issues a POST to the specified path.
+//
+// Use ctx to set timeout.
+//
+// An error is returned if by failure to speak COAP (such as a network connectivity problem).
+// Any status code doesn't cause an error.
+//
+// If payload is nil then content format is not used.
+func (c *Client[C]) Post(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error) {
+ req, err := c.NewPostRequest(ctx, path, contentFormat, payload, opts...)
+ if err != nil {
+ return nil, fmt.Errorf("cannot create post request: %w", err)
+ }
+ defer c.cc.ReleaseMessage(req)
+ return c.Do(req)
+}
+
+// NewPutRequest creates put request.
+//
+// Use ctx to set timeout.
+//
+// If payload is nil then content format is not used.
+func (c *Client[C]) NewPutRequest(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error) {
+ req := c.cc.AcquireMessage(ctx)
+ token, err := c.GetToken()
+ if err != nil {
+ c.cc.ReleaseMessage(req)
+ return nil, err
+ }
+ err = req.SetupPut(path, token, contentFormat, payload, opts...)
+ if err != nil {
+ c.cc.ReleaseMessage(req)
+ return nil, err
+ }
+ return req, nil
+}
+
+// Put issues a PUT to the specified path.
+//
+// Use ctx to set timeout.
+//
+// An error is returned if by failure to speak COAP (such as a network connectivity problem).
+// Any status code doesn't cause an error.
+//
+// If payload is nil then content format is not used.
+func (c *Client[C]) Put(ctx context.Context, path string, contentFormat message.MediaType, payload io.ReadSeeker, opts ...message.Option) (*pool.Message, error) {
+ req, err := c.NewPutRequest(ctx, path, contentFormat, payload, opts...)
+ if err != nil {
+ return nil, fmt.Errorf("cannot create put request: %w", err)
+ }
+ defer c.cc.ReleaseMessage(req)
+ return c.Do(req)
+}
+
+// NewDeleteRequest creates delete request.
+//
+// Use ctx to set timeout.
+func (c *Client[C]) NewDeleteRequest(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error) {
+ req := c.cc.AcquireMessage(ctx)
+ token, err := c.GetToken()
+ if err != nil {
+ c.cc.ReleaseMessage(req)
+ return nil, err
+ }
+ err = req.SetupDelete(path, token, opts...)
+ if err != nil {
+ c.cc.ReleaseMessage(req)
+ return nil, err
+ }
+ return req, nil
+}
+
+// Delete deletes the resource identified by the request path.
+//
+// Use ctx to set timeout.
+func (c *Client[C]) Delete(ctx context.Context, path string, opts ...message.Option) (*pool.Message, error) {
+ req, err := c.NewDeleteRequest(ctx, path, opts...)
+ if err != nil {
+ return nil, fmt.Errorf("cannot create delete request: %w", err)
+ }
+ defer c.cc.ReleaseMessage(req)
+ return c.Do(req)
+}
+
+// Ping issues a PING to the client and waits for PONG response.
+//
+// Use ctx to set timeout.
+func (c *Client[C]) Ping(ctx context.Context) error {
+ resp := make(chan bool, 1)
+ receivedPong := func() {
+ select {
+ case resp <- true:
+ default:
+ }
+ }
+ cancel, err := c.cc.AsyncPing(receivedPong)
+ if err != nil {
+ return err
+ }
+ defer cancel()
+ select {
+ case <-resp:
+ return nil
+ case <-ctx.Done():
+ return ctx.Err()
+ }
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/client/limitParallelRequests/limitParallelRequests.go b/vendor/github.com/plgd-dev/go-coap/v3/net/client/limitParallelRequests/limitParallelRequests.go
new file mode 100644
index 0000000..c718fd2
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/client/limitParallelRequests/limitParallelRequests.go
@@ -0,0 +1,135 @@
+package limitparallelrequests
+
+import (
+ "context"
+ "fmt"
+ "hash/crc64"
+ "math"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ coapSync "github.com/plgd-dev/go-coap/v3/pkg/sync"
+ "golang.org/x/sync/semaphore"
+)
+
+type (
+ DoFunc = func(req *pool.Message) (*pool.Message, error)
+ DoObserveFunc = func(req *pool.Message, observeFunc func(req *pool.Message)) (Observation, error)
+)
+
+type Observation = interface {
+ Cancel(ctx context.Context, opts ...message.Option) error
+ Canceled() bool
+}
+
+type endpointQueue struct {
+ processedCounter int64
+ orderedRequest []chan struct{}
+}
+
+type LimitParallelRequests struct {
+ endpointLimit int64
+ limit *semaphore.Weighted
+ do DoFunc
+ doObserve DoObserveFunc
+ // only one request can be processed by one endpoint
+ endpointQueues *coapSync.Map[uint64, *endpointQueue]
+}
+
+// New creates new LimitParallelRequests. When limit, endpointLimit == 0, then limit is not used.
+func New(limit, endpointLimit int64, do DoFunc, doObserve DoObserveFunc) *LimitParallelRequests {
+ if limit <= 0 {
+ limit = math.MaxInt64
+ }
+ if endpointLimit <= 0 {
+ endpointLimit = math.MaxInt64
+ }
+ return &LimitParallelRequests{
+ limit: semaphore.NewWeighted(limit),
+ endpointLimit: endpointLimit,
+ do: do,
+ doObserve: doObserve,
+ endpointQueues: coapSync.NewMap[uint64, *endpointQueue](),
+ }
+}
+
+func hash(opts message.Options) uint64 {
+ h := crc64.New(crc64.MakeTable(crc64.ISO))
+ for _, opt := range opts {
+ if opt.ID == message.URIPath {
+ _, _ = h.Write(opt.Value) // hash never returns an error
+ }
+ }
+ return h.Sum64()
+}
+
+func (c *LimitParallelRequests) acquireEndpoint(ctx context.Context, endpointLimitKey uint64) error {
+ reqChan := make(chan struct{}) // channel is closed when request can be processed by releaseEndpoint
+ _, _ = c.endpointQueues.LoadOrStoreWithFunc(endpointLimitKey, func(value *endpointQueue) *endpointQueue {
+ if value.processedCounter < c.endpointLimit {
+ close(reqChan)
+ value.processedCounter++
+ return value
+ }
+ value.orderedRequest = append(value.orderedRequest, reqChan)
+ return value
+ }, func() *endpointQueue {
+ close(reqChan)
+ return &endpointQueue{
+ processedCounter: 1,
+ }
+ })
+ select {
+ case <-ctx.Done():
+ c.releaseEndpoint(endpointLimitKey)
+ return ctx.Err()
+ case <-reqChan:
+ return nil
+ }
+}
+
+func (c *LimitParallelRequests) releaseEndpoint(endpointLimitKey uint64) {
+ _, _ = c.endpointQueues.ReplaceWithFunc(endpointLimitKey, func(oldValue *endpointQueue, oldLoaded bool) (newValue *endpointQueue, doDelete bool) {
+ if oldLoaded {
+ if len(oldValue.orderedRequest) > 0 {
+ reqChan := oldValue.orderedRequest[0]
+ oldValue.orderedRequest = oldValue.orderedRequest[1:]
+ close(reqChan)
+ } else {
+ oldValue.processedCounter--
+ if oldValue.processedCounter == 0 {
+ return nil, true
+ }
+ }
+ return oldValue, false
+ }
+ return nil, true
+ })
+}
+
+func (c *LimitParallelRequests) Do(req *pool.Message) (*pool.Message, error) {
+ endpointLimitKey := hash(req.Options())
+ if err := c.acquireEndpoint(req.Context(), endpointLimitKey); err != nil {
+ return nil, fmt.Errorf("cannot process request %v for client endpoint limit: %w", req, err)
+ }
+ defer c.releaseEndpoint(endpointLimitKey)
+ if err := c.limit.Acquire(req.Context(), 1); err != nil {
+ return nil, fmt.Errorf("cannot process request %v for client limit: %w", req, err)
+ }
+ defer c.limit.Release(1)
+ return c.do(req)
+}
+
+func (c *LimitParallelRequests) DoObserve(req *pool.Message, observeFunc func(req *pool.Message)) (Observation, error) {
+ endpointLimitKey := hash(req.Options())
+ if err := c.acquireEndpoint(req.Context(), endpointLimitKey); err != nil {
+ return nil, fmt.Errorf("cannot process observe request %v for client endpoint limit: %w", req, err)
+ }
+ defer c.releaseEndpoint(endpointLimitKey)
+ err := c.limit.Acquire(req.Context(), 1)
+ if err != nil {
+ return nil, fmt.Errorf("cannot process observe request %v for client limit: %w", req, err)
+ }
+ defer c.limit.Release(1)
+ return c.doObserve(req, observeFunc)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/client/receivedMessageReader.go b/vendor/github.com/plgd-dev/go-coap/v3/net/client/receivedMessageReader.go
new file mode 100644
index 0000000..acbf4cc
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/client/receivedMessageReader.go
@@ -0,0 +1,96 @@
+package client
+
+import (
+ "sync"
+
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "go.uber.org/atomic"
+)
+
+type ReceivedMessageReaderClient interface {
+ Done() <-chan struct{}
+ ProcessReceivedMessage(req *pool.Message)
+}
+
+type ReceivedMessageReader[C ReceivedMessageReaderClient] struct {
+ queue chan *pool.Message
+ cc C
+
+ private struct {
+ mutex sync.Mutex
+ loopDone chan struct{}
+ readingMessages *atomic.Bool
+ }
+}
+
+// NewReceivedMessageReader creates a new ReceivedMessageReader[C] instance.
+func NewReceivedMessageReader[C ReceivedMessageReaderClient](cc C, queueSize int) *ReceivedMessageReader[C] {
+ r := ReceivedMessageReader[C]{
+ queue: make(chan *pool.Message, queueSize),
+ cc: cc,
+ private: struct {
+ mutex sync.Mutex
+ loopDone chan struct{}
+ readingMessages *atomic.Bool
+ }{
+ loopDone: make(chan struct{}),
+ readingMessages: atomic.NewBool(true),
+ },
+ }
+
+ go r.loop(r.private.loopDone, r.private.readingMessages)
+ return &r
+}
+
+// C returns the channel to push received messages to.
+func (r *ReceivedMessageReader[C]) C() chan<- *pool.Message {
+ return r.queue
+}
+
+// The loop function continuously listens to messages. IT can be replaced with a new one by calling the TryToReplaceLoop function,
+// ensuring that only one loop is reading from the queue at a time.
+// The loopDone channel is used to signal when the loop should be closed.
+// The readingMessages variable is used to indicate if the loop is currently reading from the queue.
+// When the loop is not reading from the queue, it sets readingMessages to false, and when it starts reading again, it sets it to true.
+// If the client is closed, the loop also closes.
+func (r *ReceivedMessageReader[C]) loop(loopDone chan struct{}, readingMessages *atomic.Bool) {
+ for {
+ select {
+ // if the loop is replaced, the old loop will be closed
+ case <-loopDone:
+ return
+ // process received message until the queue is empty
+ case req := <-r.queue:
+ // This signalizes that the loop is not reading messages.
+ readingMessages.Store(false)
+ r.cc.ProcessReceivedMessage(req)
+ // This signalizes that the loop is reading messages. We call mutex because we want to ensure that TryToReplaceLoop has ended and
+ // loopDone is closed if it was replaced.
+ r.private.mutex.Lock()
+ readingMessages.Store(true)
+ r.private.mutex.Unlock()
+ // if the client is closed, the loop will be closed
+ case <-r.cc.Done():
+ return
+ }
+ }
+}
+
+// TryToReplaceLoop function attempts to replace the loop with a new one,
+// but only if the loop is not currently reading messages. If the loop is reading messages,
+// the function returns immediately. If the loop is not reading messages, the current loop is closed,
+// and new loopDone and readingMessages channels and variables are created.
+func (r *ReceivedMessageReader[C]) TryToReplaceLoop() {
+ r.private.mutex.Lock()
+ if r.private.readingMessages.Load() {
+ r.private.mutex.Unlock()
+ return
+ }
+ defer r.private.mutex.Unlock()
+ close(r.private.loopDone)
+ loopDone := make(chan struct{})
+ readingMessages := atomic.NewBool(true)
+ r.private.loopDone = loopDone
+ r.private.readingMessages = readingMessages
+ go r.loop(loopDone, readingMessages)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/conn.go b/vendor/github.com/plgd-dev/go-coap/v3/net/conn.go
new file mode 100644
index 0000000..8d6faab
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/conn.go
@@ -0,0 +1,128 @@
+package net
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "sync"
+
+ "go.uber.org/atomic"
+)
+
+// Conn is a generic stream-oriented network connection that provides Read/Write with context.
+//
+// Multiple goroutines may invoke methods on a Conn simultaneously.
+type Conn struct {
+ connection net.Conn
+ closed atomic.Bool
+ handshakeContext func(ctx context.Context) error
+ lock sync.Mutex
+}
+
+// NewConn creates connection over net.Conn.
+func NewConn(c net.Conn) *Conn {
+ connection := Conn{
+ connection: c,
+ }
+
+ if v, ok := c.(interface {
+ HandshakeContext(ctx context.Context) error
+ }); ok {
+ connection.handshakeContext = v.HandshakeContext
+ }
+
+ return &connection
+}
+
+// LocalAddr returns the local network address. The Addr returned is shared by all invocations of LocalAddr, so do not modify it.
+func (c *Conn) LocalAddr() net.Addr {
+ return c.connection.LocalAddr()
+}
+
+// NetConn returns the underlying connection that is wrapped by c. The Conn returned is shared by all invocations of Connection, so do not modify it.
+func (c *Conn) NetConn() net.Conn {
+ return c.connection
+}
+
+// RemoteAddr returns the remote network address. The Addr returned is shared by all invocations of RemoteAddr, so do not modify it.
+func (c *Conn) RemoteAddr() net.Addr {
+ return c.connection.RemoteAddr()
+}
+
+// Close closes the connection.
+func (c *Conn) Close() error {
+ if !c.closed.CompareAndSwap(false, true) {
+ return nil
+ }
+ return c.connection.Close()
+}
+
+func (c *Conn) handshake(ctx context.Context) error {
+ if c.handshakeContext != nil {
+ err := c.handshakeContext(ctx)
+ if err == nil {
+ return nil
+ }
+ errC := c.Close()
+ if errC == nil {
+ return err
+ }
+ return fmt.Errorf("%v", []error{err, errC})
+ }
+ return nil
+}
+
+// WriteWithContext writes data with context.
+func (c *Conn) WriteWithContext(ctx context.Context, data []byte) error {
+ if err := c.handshake(ctx); err != nil {
+ return err
+ }
+ written := 0
+ c.lock.Lock()
+ defer c.lock.Unlock()
+ for written < len(data) {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ default:
+ }
+ if c.closed.Load() {
+ return ErrConnectionIsClosed
+ }
+ n, err := c.connection.Write(data[written:])
+ if err != nil {
+ return err
+ }
+ written += n
+ }
+ return nil
+}
+
+// ReadFullWithContext reads stream with context until whole buffer is satisfied.
+func (c *Conn) ReadFullWithContext(ctx context.Context, buffer []byte) error {
+ offset := 0
+ for offset < len(buffer) {
+ n, err := c.ReadWithContext(ctx, buffer[offset:])
+ if err != nil {
+ return fmt.Errorf("cannot read full from connection: %w", err)
+ }
+ offset += n
+ }
+ return nil
+}
+
+// ReadWithContext reads stream with context.
+func (c *Conn) ReadWithContext(ctx context.Context, buffer []byte) (int, error) {
+ select {
+ case <-ctx.Done():
+ return -1, ctx.Err()
+ default:
+ }
+ if c.closed.Load() {
+ return -1, ErrConnectionIsClosed
+ }
+ if err := c.handshake(ctx); err != nil {
+ return -1, err
+ }
+ return c.connection.Read(buffer)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/connUDP.go b/vendor/github.com/plgd-dev/go-coap/v3/net/connUDP.go
similarity index 52%
rename from vendor/github.com/plgd-dev/go-coap/v2/net/connUDP.go
rename to vendor/github.com/plgd-dev/go-coap/v3/net/connUDP.go
index e38f361..f749b22 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/connUDP.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/connUDP.go
@@ -5,9 +5,9 @@ import (
"fmt"
"net"
"strings"
- "sync"
"time"
+ "go.uber.org/atomic"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
)
@@ -16,15 +16,11 @@ import (
//
// Multiple goroutines may invoke methods on a UDPConn simultaneously.
type UDPConn struct {
- heartBeat time.Duration
- connection *net.UDPConn
- packetConn packetConn
- errors func(err error)
- network string
- onReadTimeout func() error
- onWriteTimeout func() error
-
- lock sync.Mutex
+ packetConn packetConn
+ network string
+ connection *net.UDPConn
+ errors func(err error)
+ closed atomic.Bool
}
type ControlMessage struct {
@@ -140,18 +136,14 @@ func IsIPv6(addr net.IP) bool {
return false
}
-var defaultUDPConnOptions = udpConnOptions{
- heartBeat: time.Millisecond * 200,
- errors: func(err error) {
- fmt.Println(err)
+var DefaultUDPConnConfig = UDPConnConfig{
+ Errors: func(err error) {
+ // don't log any error from fails for multicast requests
},
}
-type udpConnOptions struct {
- heartBeat time.Duration
- errors func(err error)
- onReadTimeout func() error
- onWriteTimeout func() error
+type UDPConnConfig struct {
+ Errors func(err error)
}
func NewListenUDP(network, addr string, opts ...UDPOption) (*UDPConn, error) {
@@ -168,27 +160,31 @@ func NewListenUDP(network, addr string, opts ...UDPOption) (*UDPConn, error) {
// NewUDPConn creates connection over net.UDPConn.
func NewUDPConn(network string, c *net.UDPConn, opts ...UDPOption) *UDPConn {
- cfg := defaultUDPConnOptions
+ cfg := DefaultUDPConnConfig
for _, o := range opts {
- o.applyUDP(&cfg)
+ o.ApplyUDP(&cfg)
}
- var packetConn packetConn
-
- if IsIPv6(c.LocalAddr().(*net.UDPAddr).IP) {
- packetConn = newPacketConnIPv6(ipv6.NewPacketConn(c))
+ laddr := c.LocalAddr()
+ if laddr == nil {
+ panic(fmt.Errorf("invalid UDP connection"))
+ }
+ addr, ok := laddr.(*net.UDPAddr)
+ if !ok {
+ panic(fmt.Errorf("invalid address type(%T), UDP address expected", laddr))
+ }
+ var pc packetConn
+ if IsIPv6(addr.IP) {
+ pc = newPacketConnIPv6(ipv6.NewPacketConn(c))
} else {
- packetConn = newPacketConnIPv4(ipv4.NewPacketConn(c))
+ pc = newPacketConnIPv4(ipv4.NewPacketConn(c))
}
return &UDPConn{
- network: network,
- connection: c,
- heartBeat: cfg.heartBeat,
- packetConn: packetConn,
- errors: cfg.errors,
- onReadTimeout: cfg.onReadTimeout,
- onWriteTimeout: cfg.onWriteTimeout,
+ network: network,
+ connection: c,
+ packetConn: pc,
+ errors: cfg.Errors,
}
}
@@ -209,97 +205,204 @@ func (c *UDPConn) Network() string {
// Close closes the connection.
func (c *UDPConn) Close() error {
+ if !c.closed.CompareAndSwap(false, true) {
+ return nil
+ }
return c.connection.Close()
}
-func (c *UDPConn) writeToAddr(deadline time.Time, multicastHopLimit int, iface net.Interface, srcAddr net.Addr, port string, raddr *net.UDPAddr, buffer []byte) error {
- netType := "udp4"
+func (c *UDPConn) writeToAddr(iface *net.Interface, src *net.IP, multicastHopLimit int, raddr *net.UDPAddr, buffer []byte) error {
+ var pktSrc net.IP
+ var p packetConn
if IsIPv6(raddr.IP) {
- netType = "udp6"
+ p = newPacketConnIPv6(ipv6.NewPacketConn(c.connection))
+ pktSrc = net.IPv6zero
+ } else {
+ p = newPacketConnIPv4(ipv4.NewPacketConn(c.connection))
+ pktSrc = net.IPv4zero
}
- addrMask := srcAddr.String()
- addr := strings.Split(addrMask, "/")[0]
- if strings.Contains(addr, ":") && netType == "udp4" {
- return nil
+ if src != nil {
+ pktSrc = *src
}
- if !strings.Contains(addr, ":") && netType == "udp6" {
- return nil
+
+ if c.closed.Load() {
+ return ErrConnectionIsClosed
}
- var p packetConn
- if netType == "udp4" {
- p = newPacketConnIPv4(ipv4.NewPacketConn(c.connection))
+ if iface != nil {
+ if err := p.SetMulticastInterface(iface); err != nil {
+ return err
+ }
+ }
+ if err := p.SetMulticastHopLimit(multicastHopLimit); err != nil {
+ return err
+ }
+
+ var err error
+ if iface != nil || src != nil {
+ _, err = p.WriteTo(buffer, &ControlMessage{
+ Src: pktSrc,
+ IfIndex: iface.Index,
+ }, raddr)
} else {
- p = newPacketConnIPv6(ipv6.NewPacketConn(c.connection))
+ _, err = p.WriteTo(buffer, nil, raddr)
+ }
+ return err
+}
+
+func filterAddressesByNetwork(network string, ifaceAddrs []net.Addr) []net.Addr {
+ filtered := make([]net.Addr, 0, len(ifaceAddrs))
+ for _, srcAddr := range ifaceAddrs {
+ addrMask := srcAddr.String()
+ addr := strings.Split(addrMask, "/")[0]
+ if strings.Contains(addr, ":") && network == "udp4" {
+ continue
+ }
+ if !strings.Contains(addr, ":") && network == "udp6" {
+ continue
+ }
+ filtered = append(filtered, srcAddr)
+ }
+ return filtered
+}
+
+func convAddrsToIps(ifaceAddrs []net.Addr) []net.IP {
+ ips := make([]net.IP, 0, len(ifaceAddrs))
+ for _, addr := range ifaceAddrs {
+ addrMask := addr.String()
+ addr := strings.Split(addrMask, "/")[0]
+ ip := net.ParseIP(addr)
+ if ip != nil {
+ ips = append(ips, ip)
+ }
+ }
+ return ips
+}
+
+// WriteMulticast sends multicast to the remote multicast address.
+// By default it is sent over all network interfaces and all compatible source IP addresses with hop limit 1.
+// Via opts you can specify the network interface, source IP address, and hop limit.
+func (c *UDPConn) WriteMulticast(ctx context.Context, raddr *net.UDPAddr, buffer []byte, opts ...MulticastOption) error {
+ opt := MulticastOptions{
+ HopLimit: 1,
}
+ for _, o := range opts {
+ o.applyMC(&opt)
+ }
+ return c.writeMulticast(ctx, raddr, buffer, opt)
+}
- if err := p.SetMulticastInterface(&iface); err != nil {
+func (c *UDPConn) writeMulticastWithInterface(raddr *net.UDPAddr, buffer []byte, opt MulticastOptions) error {
+ if opt.Iface == nil && opt.IFaceMode == MulticastSpecificInterface {
+ return fmt.Errorf("invalid interface")
+ }
+ if opt.Source != nil {
+ return c.writeToAddr(opt.Iface, opt.Source, opt.HopLimit, raddr, buffer)
+ }
+ ifaceAddrs, err := opt.Iface.Addrs()
+ if err != nil {
return err
}
- p.SetMulticastHopLimit(multicastHopLimit)
- err := p.SetWriteDeadline(deadline)
+ netType := "udp4"
+ if IsIPv6(raddr.IP) {
+ netType = "udp6"
+ }
+ var errors []error
+ for _, ip := range convAddrsToIps(filterAddressesByNetwork(netType, ifaceAddrs)) {
+ ipAddr := ip
+ opt.Source = &ipAddr
+ err = c.writeToAddr(opt.Iface, opt.Source, opt.HopLimit, raddr, buffer)
+ if err != nil {
+ errors = append(errors, err)
+ }
+ }
+ if errors == nil {
+ return nil
+ }
+ if len(errors) == 1 {
+ return errors[0]
+ }
+ return fmt.Errorf("%v", errors)
+}
+
+func (c *UDPConn) writeMulticastToAllInterfaces(raddr *net.UDPAddr, buffer []byte, opt MulticastOptions) error {
+ ifaces, err := net.Interfaces()
if err != nil {
- return fmt.Errorf("cannot write multicast with context: cannot set write deadline for connection: %w", err)
+ return fmt.Errorf("cannot get interfaces for multicast connection: %w", err)
}
- ip := net.ParseIP(addr)
- if ip == nil {
- return fmt.Errorf("cannot parse ip (%v) for iface %v", ip, iface.Name)
+
+ var errors []error
+ for i := range ifaces {
+ iface := ifaces[i]
+ if iface.Flags&net.FlagMulticast == 0 {
+ continue
+ }
+ if iface.Flags&net.FlagUp != net.FlagUp {
+ continue
+ }
+ specificOpt := opt
+ specificOpt.Iface = &iface
+ specificOpt.IFaceMode = MulticastSpecificInterface
+ err = c.writeMulticastWithInterface(raddr, buffer, specificOpt)
+ if err != nil {
+ if opt.InterfaceError != nil {
+ opt.InterfaceError(&iface, err)
+ continue
+ }
+ errors = append(errors, err)
+ }
}
- _, err = p.WriteTo(buffer, &ControlMessage{
- Src: ip,
- IfIndex: iface.Index,
- }, raddr)
- return err
+ if errors == nil {
+ return nil
+ }
+ if len(errors) == 1 {
+ return errors[0]
+ }
+ return fmt.Errorf("%v", errors)
}
-func (c *UDPConn) WriteMulticast(ctx context.Context, raddr *net.UDPAddr, hopLimit int, buffer []byte) error {
+func (c *UDPConn) validateMulticast(ctx context.Context, raddr *net.UDPAddr, opt MulticastOptions) error {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ default:
+ }
if raddr == nil {
return fmt.Errorf("cannot write multicast with context: invalid raddr")
}
if _, ok := c.packetConn.(*packetConnIPv4); ok && IsIPv6(raddr.IP) {
- return fmt.Errorf("cannot write multicast with context: invalid destination address")
+ return fmt.Errorf("cannot write multicast with context: invalid destination address(%v)", raddr.IP)
+ }
+ if opt.Source != nil && IsIPv6(*opt.Source) && !IsIPv6(raddr.IP) {
+ return fmt.Errorf("cannot write multicast with context: invalid source address(%v) for destination(%v)", opt.Source, raddr.IP)
}
+ return nil
+}
- ifaces, err := net.Interfaces()
+func (c *UDPConn) writeMulticast(ctx context.Context, raddr *net.UDPAddr, buffer []byte, opt MulticastOptions) error {
+ err := c.validateMulticast(ctx, raddr, opt)
if err != nil {
- return fmt.Errorf("cannot write multicast with context: cannot get interfaces for multicast connection: %w", err)
+ return err
}
- c.lock.Lock()
- defer c.lock.Unlock()
-LOOP:
- for _, iface := range ifaces {
- ifaceAddrs, err := iface.Addrs()
+
+ switch opt.IFaceMode {
+ case MulticastAllInterface:
+ err := c.writeMulticastToAllInterfaces(raddr, buffer, opt)
if err != nil {
- continue
+ return fmt.Errorf("cannot write multicast to all interfaces: %w", err)
}
- if len(ifaceAddrs) == 0 {
- continue
- }
- select {
- case <-ctx.Done():
- return ctx.Err()
- default:
+ case MulticastAnyInterface:
+ err := c.writeToAddr(nil, opt.Source, opt.HopLimit, raddr, buffer)
+ if err != nil {
+ return fmt.Errorf("cannot write multicast to any: %w", err)
}
-
- addr := strings.Split(c.connection.LocalAddr().String(), ":")
- port := addr[len(addr)-1]
-
- for _, ifaceAddr := range ifaceAddrs {
- deadline := time.Now().Add(c.heartBeat)
- err = c.writeToAddr(deadline, hopLimit, iface, ifaceAddr, port, raddr, buffer)
- if err != nil {
- if isTemporary(err, deadline) {
- if c.onWriteTimeout != nil {
- err := c.onWriteTimeout()
- if err != nil {
- return fmt.Errorf("cannot write multicast to %v: on timeout returns error: %w", iface.Name, err)
- }
- }
- continue LOOP
- }
- if c.errors != nil {
- c.errors(fmt.Errorf("cannot write multicast to %v: %w", iface.Name, err))
- }
+ case MulticastSpecificInterface:
+ err := c.writeMulticastWithInterface(raddr, buffer, opt)
+ if err != nil {
+ if opt.InterfaceError != nil {
+ opt.InterfaceError(opt.Iface, err)
+ return nil
}
+ return fmt.Errorf("cannot write multicast to %v: %w", opt.Iface.Name, err)
}
}
return nil
@@ -311,34 +414,20 @@ func (c *UDPConn) WriteWithContext(ctx context.Context, raddr *net.UDPAddr, buff
return fmt.Errorf("cannot write with context: invalid raddr")
}
- written := 0
- c.lock.Lock()
- defer c.lock.Unlock()
- for written < len(buffer) {
- select {
- case <-ctx.Done():
- return ctx.Err()
- default:
- }
- deadline := time.Now().Add(c.heartBeat)
- err := c.connection.SetWriteDeadline(deadline)
- if err != nil {
- return fmt.Errorf("cannot set write deadline for udp connection: %w", err)
- }
- n, err := WriteToUDP(c.connection, raddr, buffer[written:])
- if err != nil {
- if isTemporary(err, deadline) {
- if c.onWriteTimeout != nil {
- err := c.onWriteTimeout()
- if err != nil {
- return fmt.Errorf("cannot write to udp connection: on timeout returns error: %w", err)
- }
- }
- continue
- }
- return fmt.Errorf("cannot write to udp connection: %w", err)
- }
- written += n
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ default:
+ }
+ if c.closed.Load() {
+ return ErrConnectionIsClosed
+ }
+ n, err := WriteToUDP(c.connection, raddr, buffer)
+ if err != nil {
+ return err
+ }
+ if n != len(buffer) {
+ return ErrWriteInterrupted
}
return nil
@@ -346,33 +435,19 @@ func (c *UDPConn) WriteWithContext(ctx context.Context, raddr *net.UDPAddr, buff
// ReadWithContext reads packet with context.
func (c *UDPConn) ReadWithContext(ctx context.Context, buffer []byte) (int, *net.UDPAddr, error) {
- for {
- select {
- case <-ctx.Done():
- return -1, nil, ctx.Err()
- default:
- }
- deadline := time.Now().Add(c.heartBeat)
- err := c.connection.SetReadDeadline(deadline)
- if err != nil {
- return -1, nil, fmt.Errorf("cannot set read deadline for udp connection: %w", err)
- }
- n, s, err := c.connection.ReadFromUDP(buffer)
- if err != nil {
- // check context in regular intervals and then resume listening
- if isTemporary(err, deadline) {
- if c.onReadTimeout != nil {
- err := c.onReadTimeout()
- if err != nil {
- return -1, nil, fmt.Errorf("cannot read from udp connection: on timeout returns error: %w", err)
- }
- }
- continue
- }
- return -1, nil, fmt.Errorf("cannot read from udp connection: %w", err)
- }
- return n, s, err
+ select {
+ case <-ctx.Done():
+ return -1, nil, ctx.Err()
+ default:
+ }
+ if c.closed.Load() {
+ return -1, nil, ErrConnectionIsClosed
+ }
+ n, s, err := c.connection.ReadFromUDP(buffer)
+ if err != nil {
+ return -1, nil, fmt.Errorf("cannot read from udp connection: %w", err)
}
+ return n, s, err
}
// SetMulticastLoopback sets whether transmitted multicast packets
@@ -399,3 +474,8 @@ func (c *UDPConn) JoinGroup(ifi *net.Interface, group net.Addr) error {
func (c *UDPConn) LeaveGroup(ifi *net.Interface, group net.Addr) error {
return c.packetConn.LeaveGroup(ifi, group)
}
+
+// NetConn returns the underlying connection that is wrapped by c. The Conn returned is shared by all invocations of NetConn, so do not modify it.
+func (c *UDPConn) NetConn() net.Conn {
+ return c.connection
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/dtlslistener.go b/vendor/github.com/plgd-dev/go-coap/v3/net/dtlslistener.go
new file mode 100644
index 0000000..b797507
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/dtlslistener.go
@@ -0,0 +1,197 @@
+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"
+ "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
+}
+
+// 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) {
+ 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, fmt.Errorf("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()
+ 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
+ }
+ }
+}
+
+// AcceptWithContext waits with context for a generic Conn.
+func (l *DTLSListener) AcceptWithContext(ctx context.Context) (net.Conn, error) {
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ default:
+ }
+ 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
+ }
+ }
+}
+
+// Accept waits for a generic Conn.
+func (l *DTLSListener) Accept() (net.Conn, error) {
+ return l.AcceptWithContext(context.Background())
+}
+
+// Close closes the connection.
+func (l *DTLSListener) Close() error {
+ if !l.closed.CompareAndSwap(false, true) {
+ return nil
+ }
+ close(l.done)
+ defer l.wg.Wait()
+ return l.listener.Close()
+}
+
+// Addr represents a network end point address.
+func (l *DTLSListener) Addr() net.Addr {
+ return l.listener.Addr()
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/error.go b/vendor/github.com/plgd-dev/go-coap/v3/net/error.go
new file mode 100644
index 0000000..be56417
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/error.go
@@ -0,0 +1,25 @@
+package net
+
+import (
+ "context"
+ "errors"
+ "io"
+ "net"
+)
+
+var (
+ ErrListenerIsClosed = io.EOF
+ ErrConnectionIsClosed = io.EOF
+ ErrWriteInterrupted = errors.New("only part data was written to socket")
+)
+
+func IsCancelOrCloseError(err error) bool {
+ if err == nil {
+ return false
+ }
+ if errors.Is(err, context.Canceled) || errors.Is(err, io.EOF) || errors.Is(err, net.ErrClosed) {
+ // this error was produced by cancellation context or closing connection.
+ return true
+ }
+ return false
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/error_unix.go b/vendor/github.com/plgd-dev/go-coap/v3/net/error_unix.go
new file mode 100644
index 0000000..164f111
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/error_unix.go
@@ -0,0 +1,16 @@
+//go:build aix || darwin || dragonfly || freebsd || js || linux || netbsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd js linux netbsd openbsd solaris
+
+package net
+
+import (
+ "errors"
+ "syscall"
+)
+
+// Check if error returned by operation on a socket failed because
+// the other side has closed the connection.
+func IsConnectionBrokenError(err error) bool {
+ return errors.Is(err, syscall.EPIPE) ||
+ errors.Is(err, syscall.ECONNRESET)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/error_windows.go b/vendor/github.com/plgd-dev/go-coap/v3/net/error_windows.go
new file mode 100644
index 0000000..f745c9b
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/error_windows.go
@@ -0,0 +1,14 @@
+//go:build windows
+// +build windows
+
+package net
+
+import (
+ "errors"
+ "syscall"
+)
+
+func IsConnectionBrokenError(err error) bool {
+ return errors.Is(err, syscall.WSAECONNRESET) ||
+ errors.Is(err, syscall.WSAECONNABORTED)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/monitor/inactivity/keepalive.go b/vendor/github.com/plgd-dev/go-coap/v3/net/monitor/inactivity/keepalive.go
new file mode 100644
index 0000000..dcb34fe
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/monitor/inactivity/keepalive.go
@@ -0,0 +1,63 @@
+package inactivity
+
+import (
+ "unsafe"
+
+ "go.uber.org/atomic"
+)
+
+type cancelPingFunc func()
+
+type KeepAlive[C Conn] struct {
+ pongToken atomic.Uint64
+ onInactive OnInactiveFunc[C]
+
+ sendPing func(cc C, receivePong func()) (func(), error)
+ cancelPing atomic.UnsafePointer
+ numFails atomic.Uint32
+
+ maxRetries uint32
+}
+
+func NewKeepAlive[C Conn](maxRetries uint32, onInactive OnInactiveFunc[C], sendPing func(cc C, receivePong func()) (func(), error)) *KeepAlive[C] {
+ return &KeepAlive[C]{
+ maxRetries: maxRetries,
+ sendPing: sendPing,
+ onInactive: onInactive,
+ }
+}
+
+func (m *KeepAlive[C]) checkCancelPing() {
+ cancelPingPtr := m.cancelPing.Swap(nil)
+ if cancelPingPtr != nil {
+ cancelPing := *(*cancelPingFunc)(cancelPingPtr)
+ cancelPing()
+ }
+}
+
+func (m *KeepAlive[C]) OnInactive(cc C) {
+ v := m.incrementFails()
+ m.checkCancelPing()
+ if v > m.maxRetries {
+ m.onInactive(cc)
+ return
+ }
+ pongToken := m.pongToken.Add(1)
+ cancel, err := m.sendPing(cc, func() {
+ if m.pongToken.Load() == pongToken {
+ m.resetFails()
+ }
+ })
+ if err != nil {
+ return
+ }
+ m.cancelPing.Store(unsafe.Pointer(&cancel))
+}
+
+func (m *KeepAlive[C]) incrementFails() uint32 {
+ return m.numFails.Add(1)
+}
+
+func (m *KeepAlive[C]) resetFails() {
+ m.numFails.Store(0)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/monitor/inactivity/monitor.go b/vendor/github.com/plgd-dev/go-coap/v3/net/monitor/inactivity/monitor.go
new file mode 100644
index 0000000..33c0202
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/monitor/inactivity/monitor.go
@@ -0,0 +1,68 @@
+package inactivity
+
+import (
+ "context"
+ "sync/atomic"
+ "time"
+)
+
+type OnInactiveFunc[C Conn] func(cc C)
+
+type Conn = interface {
+ Context() context.Context
+ Close() error
+}
+
+type Monitor[C Conn] struct {
+ lastActivity atomic.Value
+ duration time.Duration
+ onInactive OnInactiveFunc[C]
+}
+
+func (m *Monitor[C]) Notify() {
+ m.lastActivity.Store(time.Now())
+}
+
+func (m *Monitor[C]) LastActivity() time.Time {
+ if t, ok := m.lastActivity.Load().(time.Time); ok {
+ return t
+ }
+ return time.Time{}
+}
+
+func CloseConn(cc Conn) {
+ // call cc.Close() directly to check and handle error if necessary
+ _ = cc.Close()
+}
+
+func New[C Conn](duration time.Duration, onInactive OnInactiveFunc[C]) *Monitor[C] {
+ m := &Monitor[C]{
+ duration: duration,
+ onInactive: onInactive,
+ }
+ m.Notify()
+ return m
+}
+
+func (m *Monitor[C]) CheckInactivity(now time.Time, cc C) {
+ if m.onInactive == nil || m.duration == time.Duration(0) {
+ return
+ }
+ if now.After(m.LastActivity().Add(m.duration)) {
+ m.onInactive(cc)
+ }
+}
+
+type NilMonitor[C Conn] struct{}
+
+func (m *NilMonitor[C]) CheckInactivity(time.Time, C) {
+ // do nothing
+}
+
+func (m *NilMonitor[C]) Notify() {
+ // do nothing
+}
+
+func NewNilMonitor[C Conn]() *NilMonitor[C] {
+ return &NilMonitor[C]{}
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/observation/handler.go b/vendor/github.com/plgd-dev/go-coap/v3/net/observation/handler.go
new file mode 100644
index 0000000..f170269
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/observation/handler.go
@@ -0,0 +1,267 @@
+package observation
+
+import (
+ "context"
+ "fmt"
+ "sync"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/pkg/errors"
+ coapSync "github.com/plgd-dev/go-coap/v3/pkg/sync"
+ "go.uber.org/atomic"
+)
+
+type DoFunc = func(req *pool.Message) (*pool.Message, error)
+
+type Client interface {
+ Context() context.Context
+ WriteMessage(req *pool.Message) error
+ ReleaseMessage(msg *pool.Message)
+ AcquireMessage(ctx context.Context) *pool.Message
+}
+
+// The HandlerFunc type is an adapter to allow the use of
+// ordinary functions as COAP handlers.
+type HandlerFunc[C Client] func(*responsewriter.ResponseWriter[C], *pool.Message)
+
+type Handler[C Client] struct {
+ cc C
+ observations *coapSync.Map[uint64, *Observation[C]]
+ next HandlerFunc[C]
+ do DoFunc
+}
+
+func (h *Handler[C]) Handle(w *responsewriter.ResponseWriter[C], r *pool.Message) {
+ if o, ok := h.observations.Load(r.Token().Hash()); ok {
+ o.handle(r)
+ return
+ }
+ h.next(w, r)
+}
+
+func (h *Handler[C]) client() C {
+ return h.cc
+}
+
+func (h *Handler[C]) NewObservation(req *pool.Message, observeFunc func(req *pool.Message)) (*Observation[C], error) {
+ observe, err := req.Observe()
+ if err != nil {
+ return nil, fmt.Errorf("cannot get observe option: %w", err)
+ }
+ if observe != 0 {
+ return nil, fmt.Errorf("invalid value of observe(%v): expected 0", observe)
+ }
+ token := req.Token()
+ if len(token) == 0 {
+ return nil, fmt.Errorf("empty token")
+ }
+ options, err := req.Options().Clone()
+ if err != nil {
+ return nil, fmt.Errorf("cannot clone options: %w", err)
+ }
+ respObservationChan := make(chan respObservationMessage, 1)
+ o := newObservation(message.Message{
+ Token: req.Token(),
+ Code: req.Code(),
+ Options: options,
+ }, h, observeFunc, respObservationChan)
+ defer func(err *error) {
+ if *err != nil {
+ o.cleanUp()
+ }
+ }(&err)
+ if _, loaded := h.observations.LoadOrStore(token.Hash(), o); loaded {
+ err = errors.ErrKeyAlreadyExists
+ return nil, err
+ }
+
+ err = h.cc.WriteMessage(req)
+ if err != nil {
+ return nil, err
+ }
+ select {
+ case <-req.Context().Done():
+ err = req.Context().Err()
+ return nil, err
+ case <-h.cc.Context().Done():
+ err = fmt.Errorf("connection was closed: %w", h.cc.Context().Err())
+ return nil, err
+ case resp := <-respObservationChan:
+ if resp.code != codes.Content && resp.code != codes.Valid {
+ err = fmt.Errorf("unexpected return code(%v)", resp.code)
+ return nil, err
+ }
+ if resp.notSupported {
+ o.cleanUp()
+ }
+ return o, nil
+ }
+}
+
+func (h *Handler[C]) GetObservation(key uint64) (*Observation[C], bool) {
+ return h.observations.Load(key)
+}
+
+// GetObservationRequest returns observation request for token
+func (h *Handler[C]) GetObservationRequest(token message.Token) (*pool.Message, bool) {
+ obs, ok := h.GetObservation(token.Hash())
+ if !ok {
+ return nil, false
+ }
+ req := obs.Request()
+ msg := h.cc.AcquireMessage(h.cc.Context())
+ msg.ResetOptionsTo(req.Options)
+ msg.SetCode(req.Code)
+ msg.SetToken(req.Token)
+ return msg, true
+}
+
+func (h *Handler[C]) pullOutObservation(key uint64) (*Observation[C], bool) {
+ return h.observations.LoadAndDelete(key)
+}
+
+func NewHandler[C Client](cc C, next HandlerFunc[C], do DoFunc) *Handler[C] {
+ return &Handler[C]{
+ cc: cc,
+ observations: coapSync.NewMap[uint64, *Observation[C]](),
+ next: next,
+ do: do,
+ }
+}
+
+type respObservationMessage struct {
+ code codes.Code
+ notSupported bool
+}
+
+// Observation represents subscription to resource on the server
+type Observation[C Client] struct {
+ req message.Message
+ observeFunc func(req *pool.Message)
+ respObservationChan chan respObservationMessage
+ waitForResponse atomic.Bool
+ observationHandler *Handler[C]
+
+ private struct { // members guarded by mutex
+ mutex sync.Mutex
+ obsSequence uint32
+ lastEvent time.Time
+ etag []byte
+ }
+}
+
+func (o *Observation[C]) Canceled() bool {
+ _, ok := o.observationHandler.GetObservation(o.req.Token.Hash())
+ return !ok
+}
+
+func newObservation[C Client](req message.Message, observationHandler *Handler[C], observeFunc func(req *pool.Message), respObservationChan chan respObservationMessage) *Observation[C] {
+ return &Observation[C]{
+ req: req,
+ waitForResponse: *atomic.NewBool(true),
+ respObservationChan: respObservationChan,
+ observeFunc: observeFunc,
+ observationHandler: observationHandler,
+ }
+}
+
+func (o *Observation[C]) handle(r *pool.Message) {
+ if o.waitForResponse.CompareAndSwap(true, false) {
+ select {
+ case o.respObservationChan <- respObservationMessage{
+ code: r.Code(),
+ notSupported: !r.HasOption(message.Observe),
+ }:
+ default:
+ }
+ o.respObservationChan = nil
+ }
+ if o.wantBeNotified(r) {
+ o.observeFunc(r)
+ }
+}
+
+func (o *Observation[C]) cleanUp() bool {
+ // we can ignore err during cleanUp, if err != nil then some other
+ // part of code already removed the handler for the token
+ _, ok := o.observationHandler.pullOutObservation(o.req.Token.Hash())
+ return ok
+}
+
+func (o *Observation[C]) client() C {
+ return o.observationHandler.client()
+}
+
+func (o *Observation[C]) Request() message.Message {
+ return o.req
+}
+
+func (o *Observation[C]) etag() []byte {
+ o.private.mutex.Lock()
+ defer o.private.mutex.Unlock()
+ return o.private.etag
+}
+
+// Cancel remove observation from server. For recreate observation use Observe.
+func (o *Observation[C]) Cancel(ctx context.Context, opts ...message.Option) error {
+ if !o.cleanUp() {
+ // observation was already cleanup
+ return nil
+ }
+
+ req := o.client().AcquireMessage(ctx)
+ defer o.client().ReleaseMessage(req)
+ req.ResetOptionsTo(opts)
+ req.SetCode(codes.GET)
+ req.SetObserve(1)
+ if path, err := o.req.Options.Path(); err == nil {
+ if err := req.SetPath(path); err != nil {
+ return fmt.Errorf("cannot set path(%v): %w", path, err)
+ }
+ }
+ req.SetToken(o.req.Token)
+ etag := o.etag()
+ if len(etag) > 0 {
+ _ = req.SetETag(etag) // ignore invalid etag
+ }
+ resp, err := o.observationHandler.do(req)
+ if err != nil {
+ return err
+ }
+ defer o.client().ReleaseMessage(resp)
+ if resp.Code() != codes.Content && resp.Code() != codes.Valid {
+ return fmt.Errorf("unexpected return code(%v)", resp.Code())
+ }
+ return nil
+}
+
+func (o *Observation[C]) wantBeNotified(r *pool.Message) bool {
+ obsSequence, err := r.Observe()
+ if err != nil {
+ return true
+ }
+ now := time.Now()
+
+ o.private.mutex.Lock()
+ defer o.private.mutex.Unlock()
+ if !ValidSequenceNumber(o.private.obsSequence, obsSequence, o.private.lastEvent, now) {
+ return false
+ }
+
+ o.private.obsSequence = obsSequence
+ o.private.lastEvent = now
+ if etag, err := r.ETag(); err == nil {
+ if cap(o.private.etag) < len(etag) {
+ o.private.etag = make([]byte, len(etag))
+ }
+ if len(o.private.etag) != len(etag) {
+ o.private.etag = o.private.etag[:len(etag)]
+ }
+ copy(o.private.etag, etag)
+ }
+ return true
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/observation/observation.go b/vendor/github.com/plgd-dev/go-coap/v3/net/observation/observation.go
similarity index 66%
rename from vendor/github.com/plgd-dev/go-coap/v2/net/observation/observation.go
rename to vendor/github.com/plgd-dev/go-coap/v3/net/observation/observation.go
index bb19b94..074d315 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/observation/observation.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/observation/observation.go
@@ -8,11 +8,11 @@ import (
const ObservationSequenceTimeout = 128 * time.Second
// ValidSequenceNumber implements conditions in https://tools.ietf.org/html/rfc7641#section-3.4
-func ValidSequenceNumber(old, new uint32, lastEventOccurs time.Time, now time.Time) bool {
- if old < new && (new-old) < (1<<23) {
+func ValidSequenceNumber(oldValue, newValue uint32, lastEventOccurs time.Time, now time.Time) bool {
+ if oldValue < newValue && (newValue-oldValue) < (1<<23) {
return true
}
- if old > new && (old-new) > (1<<23) {
+ if oldValue > newValue && (oldValue-newValue) > (1<<23) {
return true
}
if now.Sub(lastEventOccurs) > ObservationSequenceTimeout {
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/options.go b/vendor/github.com/plgd-dev/go-coap/v3/net/options.go
new file mode 100644
index 0000000..c037ef9
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/options.go
@@ -0,0 +1,143 @@
+package net
+
+import "net"
+
+// A UDPOption sets options such as errors parameters, etc.
+type UDPOption interface {
+ ApplyUDP(*UDPConnConfig)
+}
+
+type ErrorsOpt struct {
+ errors func(err error)
+}
+
+func (h ErrorsOpt) ApplyUDP(o *UDPConnConfig) {
+ o.Errors = h.errors
+}
+
+func WithErrors(v func(err error)) ErrorsOpt {
+ return ErrorsOpt{
+ errors: v,
+ }
+}
+
+func DefaultMulticastOptions() MulticastOptions {
+ return MulticastOptions{
+ IFaceMode: MulticastAllInterface,
+ HopLimit: 1,
+ }
+}
+
+type MulticastInterfaceMode int
+
+const (
+ MulticastAllInterface MulticastInterfaceMode = 0
+ MulticastAnyInterface MulticastInterfaceMode = 1
+ MulticastSpecificInterface MulticastInterfaceMode = 2
+)
+
+type InterfaceError = func(iface *net.Interface, err error)
+
+type MulticastOptions struct {
+ IFaceMode MulticastInterfaceMode
+ Iface *net.Interface
+ Source *net.IP
+ HopLimit int
+ InterfaceError InterfaceError
+}
+
+func (m *MulticastOptions) Apply(o MulticastOption) {
+ o.applyMC(m)
+}
+
+// A MulticastOption sets options such as hop limit, etc.
+type MulticastOption interface {
+ applyMC(*MulticastOptions)
+}
+
+type MulticastInterfaceModeOpt struct {
+ mode MulticastInterfaceMode
+}
+
+func (m MulticastInterfaceModeOpt) applyMC(o *MulticastOptions) {
+ o.IFaceMode = m.mode
+}
+
+func WithAnyMulticastInterface() MulticastOption {
+ return MulticastInterfaceModeOpt{mode: MulticastAnyInterface}
+}
+
+func WithAllMulticastInterface() MulticastOption {
+ return MulticastInterfaceModeOpt{mode: MulticastAllInterface}
+}
+
+type MulticastInterfaceOpt struct {
+ iface net.Interface
+}
+
+func (m MulticastInterfaceOpt) applyMC(o *MulticastOptions) {
+ o.Iface = &m.iface
+ o.IFaceMode = MulticastSpecificInterface
+}
+
+func WithMulticastInterface(iface net.Interface) MulticastOption {
+ return &MulticastInterfaceOpt{iface: iface}
+}
+
+type MulticastHoplimitOpt struct {
+ hoplimit int
+}
+
+func (m MulticastHoplimitOpt) applyMC(o *MulticastOptions) {
+ o.HopLimit = m.hoplimit
+}
+
+func WithMulticastHoplimit(hoplimit int) MulticastOption {
+ return &MulticastHoplimitOpt{hoplimit: hoplimit}
+}
+
+type MulticastSourceOpt struct {
+ source net.IP
+}
+
+func (m MulticastSourceOpt) applyMC(o *MulticastOptions) {
+ o.Source = &m.source
+}
+
+func WithMulticastSource(source net.IP) MulticastOption {
+ return &MulticastSourceOpt{source: source}
+}
+
+type MulticastInterfaceErrorOpt struct {
+ interfaceError InterfaceError
+}
+
+func (m MulticastInterfaceErrorOpt) applyMC(o *MulticastOptions) {
+ o.InterfaceError = m.interfaceError
+}
+
+// WithMulticastInterfaceError sets the callback for interface errors. If it is set error is not propagated as result of WriteMulticast.
+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/vendor/github.com/plgd-dev/go-coap/v3/net/responsewriter/responseWriter.go b/vendor/github.com/plgd-dev/go-coap/v3/net/responsewriter/responseWriter.go
new file mode 100644
index 0000000..44fe2d9
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/responsewriter/responseWriter.go
@@ -0,0 +1,79 @@
+package responsewriter
+
+import (
+ "io"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/noresponse"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+)
+
+type Client interface {
+ ReleaseMessage(msg *pool.Message)
+}
+
+// A ResponseWriter is used by an COAP handler to construct an COAP response.
+type ResponseWriter[C Client] struct {
+ noResponseValue *uint32
+ response *pool.Message
+ cc C
+}
+
+func New[C Client](response *pool.Message, cc C, requestOptions ...message.Option) *ResponseWriter[C] {
+ var noResponseValue *uint32
+ if len(requestOptions) > 0 {
+ reqOpts := message.Options(requestOptions)
+ v, err := reqOpts.GetUint32(message.NoResponse)
+ if err == nil {
+ noResponseValue = &v
+ }
+ }
+
+ return &ResponseWriter[C]{
+ response: response,
+ cc: cc,
+ noResponseValue: noResponseValue,
+ }
+}
+
+// SetResponse simplifies the setup of the response for the request. ETags must be set via options. For advanced setup, use Message().
+func (r *ResponseWriter[C]) SetResponse(code codes.Code, contentFormat message.MediaType, d io.ReadSeeker, opts ...message.Option) error {
+ if r.noResponseValue != nil {
+ err := noresponse.IsNoResponseCode(code, *r.noResponseValue)
+ if err != nil {
+ return err
+ }
+ }
+
+ r.response.SetCode(code)
+ r.response.ResetOptionsTo(opts)
+ if d != nil {
+ r.response.SetContentFormat(contentFormat)
+ r.response.SetBody(d)
+ }
+ return nil
+}
+
+// SetMessage replaces the response message. The original message was released to the message pool, so don't use it any more. Ensure that Token, MessageID(udp), and Type(udp) messages are paired correctly.
+func (r *ResponseWriter[C]) SetMessage(m *pool.Message) {
+ r.cc.ReleaseMessage(r.response)
+ r.response = m
+}
+
+// Message direct access to the response.
+func (r *ResponseWriter[C]) Message() *pool.Message {
+ return r.response
+}
+
+// Swap message in response without releasing.
+func (r *ResponseWriter[C]) Swap(m *pool.Message) *pool.Message {
+ tmp := r.response
+ r.response = m
+ return tmp
+}
+
+// CConn peer connection.
+func (r *ResponseWriter[C]) Conn() C {
+ return r.cc
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/tcplistener.go b/vendor/github.com/plgd-dev/go-coap/v3/net/tcplistener.go
new file mode 100644
index 0000000..43cc955
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/tcplistener.go
@@ -0,0 +1,69 @@
+package net
+
+import (
+ "context"
+ "fmt"
+ "net"
+
+ "go.uber.org/atomic"
+)
+
+// TCPListener is a TCP network listener that provides accept with context.
+type TCPListener struct {
+ listener *net.TCPListener
+ closed atomic.Bool
+}
+
+func newNetTCPListen(network string, addr string) (*net.TCPListener, error) {
+ a, err := net.ResolveTCPAddr(network, addr)
+ if err != nil {
+ return nil, fmt.Errorf("cannot create new net tcp listener: %w", err)
+ }
+
+ tcp, err := net.ListenTCP(network, a)
+ if err != nil {
+ return nil, fmt.Errorf("cannot create new net tcp listener: %w", err)
+ }
+ return tcp, nil
+}
+
+// NewTCPListener creates tcp listener.
+// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only).
+func NewTCPListener(network string, addr string) (*TCPListener, error) {
+ tcp, err := newNetTCPListen(network, addr)
+ if err != nil {
+ return nil, fmt.Errorf("cannot create new tcp listener: %w", err)
+ }
+ return &TCPListener{listener: tcp}, nil
+}
+
+// AcceptWithContext waits with context for a generic Conn.
+func (l *TCPListener) AcceptWithContext(ctx context.Context) (net.Conn, error) {
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ default:
+ }
+ if l.closed.Load() {
+ return nil, ErrListenerIsClosed
+ }
+ return l.listener.Accept()
+}
+
+// Accept waits for a generic Conn.
+func (l *TCPListener) Accept() (net.Conn, error) {
+ return l.AcceptWithContext(context.Background())
+}
+
+// Close closes the connection.
+func (l *TCPListener) Close() error {
+ if !l.closed.CompareAndSwap(false, true) {
+ return nil
+ }
+ return l.listener.Close()
+}
+
+// Addr represents a network end point address.
+func (l *TCPListener) Addr() net.Addr {
+ return l.listener.Addr()
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/net/tlslistener.go b/vendor/github.com/plgd-dev/go-coap/v3/net/tlslistener.go
new file mode 100644
index 0000000..df12b1a
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/tlslistener.go
@@ -0,0 +1,66 @@
+package net
+
+import (
+ "context"
+ "crypto/tls"
+ "fmt"
+ "net"
+
+ "go.uber.org/atomic"
+)
+
+// TLSListener is a TLS listener that provides accept with context.
+type TLSListener struct {
+ listener net.Listener
+ tcp *net.TCPListener
+ closed atomic.Bool
+}
+
+// NewTLSListener creates tcp listener.
+// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only).
+func NewTLSListener(network string, addr string, tlsCfg *tls.Config) (*TLSListener, error) {
+ tcp, err := newNetTCPListen(network, addr)
+ if err != nil {
+ return nil, fmt.Errorf("cannot create new tls listener: %w", err)
+ }
+ tls := tls.NewListener(tcp, tlsCfg)
+ return &TLSListener{
+ tcp: tcp,
+ listener: tls,
+ }, nil
+}
+
+// AcceptWithContext waits with context for a generic Conn.
+func (l *TLSListener) AcceptWithContext(ctx context.Context) (net.Conn, error) {
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ default:
+ }
+ if l.closed.Load() {
+ return nil, ErrListenerIsClosed
+ }
+ rw, err := l.listener.Accept()
+ if err != nil {
+ return nil, err
+ }
+ return rw, nil
+}
+
+// Accept waits for a generic Conn.
+func (l *TLSListener) Accept() (net.Conn, error) {
+ return l.AcceptWithContext(context.Background())
+}
+
+// Close closes the connection.
+func (l *TLSListener) Close() error {
+ if !l.closed.CompareAndSwap(false, true) {
+ return nil
+ }
+ return l.listener.Close()
+}
+
+// Addr represents a network end point address.
+func (l *TLSListener) Addr() net.Addr {
+ return l.listener.Addr()
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/net/udp.go b/vendor/github.com/plgd-dev/go-coap/v3/net/udp.go
similarity index 99%
rename from vendor/github.com/plgd-dev/go-coap/v2/net/udp.go
rename to vendor/github.com/plgd-dev/go-coap/v3/net/udp.go
index 22bf7cc..0459266 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/net/udp.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/net/udp.go
@@ -12,5 +12,4 @@ func WriteToUDP(conn *net.UDPConn, raddr *net.UDPAddr, b []byte) (int, error) {
return conn.WriteToUDP(b, raddr)
}
return conn.Write(b)
-
}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/options/commonOptions.go b/vendor/github.com/plgd-dev/go-coap/v3/options/commonOptions.go
new file mode 100644
index 0000000..535bb8b
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/options/commonOptions.go
@@ -0,0 +1,786 @@
+package options
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "time"
+
+ dtlsServer "github.com/plgd-dev/go-coap/v3/dtls/server"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "github.com/plgd-dev/go-coap/v3/mux"
+ "github.com/plgd-dev/go-coap/v3/net/blockwise"
+ "github.com/plgd-dev/go-coap/v3/net/client"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/options/config"
+ "github.com/plgd-dev/go-coap/v3/pkg/runner/periodic"
+ tcpClient "github.com/plgd-dev/go-coap/v3/tcp/client"
+ tcpServer "github.com/plgd-dev/go-coap/v3/tcp/server"
+ udpClient "github.com/plgd-dev/go-coap/v3/udp/client"
+ udpServer "github.com/plgd-dev/go-coap/v3/udp/server"
+)
+
+type ErrorFunc = config.ErrorFunc
+
+type Handler interface {
+ tcpClient.HandlerFunc | udpClient.HandlerFunc
+}
+
+// HandlerFuncOpt handler function option.
+type HandlerFuncOpt[H Handler] struct {
+ h H
+}
+
+func panicForInvalidHandlerFunc(t, exp any) {
+ panic(fmt.Errorf("invalid HandlerFunc type %T, expected %T", t, exp))
+}
+
+func (o HandlerFuncOpt[H]) TCPServerApply(cfg *tcpServer.Config) {
+ switch v := any(o.h).(type) {
+ case tcpClient.HandlerFunc:
+ cfg.Handler = v
+ default:
+ var exp tcpClient.HandlerFunc
+ panicForInvalidHandlerFunc(v, exp)
+ }
+}
+
+func (o HandlerFuncOpt[H]) TCPClientApply(cfg *tcpClient.Config) {
+ switch v := any(o.h).(type) {
+ case tcpClient.HandlerFunc:
+ cfg.Handler = v
+ default:
+ var exp tcpClient.HandlerFunc
+ panicForInvalidHandlerFunc(v, exp)
+ }
+}
+
+func (o HandlerFuncOpt[H]) UDPServerApply(cfg *udpServer.Config) {
+ switch v := any(o.h).(type) {
+ case udpClient.HandlerFunc:
+ cfg.Handler = v
+ default:
+ var exp udpClient.HandlerFunc
+ panicForInvalidHandlerFunc(v, exp)
+ }
+}
+
+func (o HandlerFuncOpt[H]) DTLSServerApply(cfg *dtlsServer.Config) {
+ switch v := any(o.h).(type) {
+ case udpClient.HandlerFunc:
+ cfg.Handler = v
+ default:
+ var exp udpClient.HandlerFunc
+ panicForInvalidHandlerFunc(v, exp)
+ }
+}
+
+func (o HandlerFuncOpt[H]) UDPClientApply(cfg *udpClient.Config) {
+ switch v := any(o.h).(type) {
+ case udpClient.HandlerFunc:
+ cfg.Handler = v
+ default:
+ var t udpClient.HandlerFunc
+ panicForInvalidHandlerFunc(v, t)
+ }
+}
+
+// WithHandlerFunc set handle for handling request's.
+func WithHandlerFunc[H Handler](h H) HandlerFuncOpt[H] {
+ return HandlerFuncOpt[H]{h: h}
+}
+
+// HandlerFuncOpt handler function option.
+type MuxHandlerOpt struct {
+ m mux.Handler
+}
+
+func (o MuxHandlerOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.Handler = mux.ToHandler[*tcpClient.Conn](o.m)
+}
+
+func (o MuxHandlerOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.Handler = mux.ToHandler[*tcpClient.Conn](o.m)
+}
+
+func (o MuxHandlerOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.Handler = mux.ToHandler[*udpClient.Conn](o.m)
+}
+
+func (o MuxHandlerOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.Handler = mux.ToHandler[*udpClient.Conn](o.m)
+}
+
+func (o MuxHandlerOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.Handler = mux.ToHandler[*udpClient.Conn](o.m)
+}
+
+// WithMux set's multiplexer for handle requests.
+func WithMux(m mux.Handler) MuxHandlerOpt {
+ return MuxHandlerOpt{
+ m: m,
+ }
+}
+
+// ContextOpt handler function option.
+type ContextOpt struct {
+ ctx context.Context
+}
+
+func (o ContextOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.Ctx = o.ctx
+}
+
+func (o ContextOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.Ctx = o.ctx
+}
+
+func (o ContextOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.Ctx = o.ctx
+}
+
+func (o ContextOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.Ctx = o.ctx
+}
+
+func (o ContextOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.Ctx = o.ctx
+}
+
+// WithContext set's parent context of server.
+func WithContext(ctx context.Context) ContextOpt {
+ return ContextOpt{ctx: ctx}
+}
+
+// MaxMessageSizeOpt handler function option.
+type MaxMessageSizeOpt struct {
+ maxMessageSize uint32
+}
+
+func (o MaxMessageSizeOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.MaxMessageSize = o.maxMessageSize
+}
+
+func (o MaxMessageSizeOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.MaxMessageSize = o.maxMessageSize
+}
+
+func (o MaxMessageSizeOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.MaxMessageSize = o.maxMessageSize
+}
+
+func (o MaxMessageSizeOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.MaxMessageSize = o.maxMessageSize
+}
+
+func (o MaxMessageSizeOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.MaxMessageSize = o.maxMessageSize
+}
+
+// WithMaxMessageSize limit size of processed message.
+func WithMaxMessageSize(maxMessageSize uint32) MaxMessageSizeOpt {
+ return MaxMessageSizeOpt{maxMessageSize: maxMessageSize}
+}
+
+// ErrorsOpt errors option.
+type ErrorsOpt struct {
+ errors ErrorFunc
+}
+
+func (o ErrorsOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.Errors = o.errors
+}
+
+func (o ErrorsOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.Errors = o.errors
+}
+
+func (o ErrorsOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.Errors = o.errors
+}
+
+func (o ErrorsOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.Errors = o.errors
+}
+
+func (o ErrorsOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.Errors = o.errors
+}
+
+// WithErrors set function for logging error.
+func WithErrors(errors ErrorFunc) ErrorsOpt {
+ return ErrorsOpt{errors: errors}
+}
+
+// ProcessReceivedMessageOpt gopool option.
+type ProcessReceivedMessageOpt[C responsewriter.Client] struct {
+ ProcessReceivedMessageFunc config.ProcessReceivedMessageFunc[C]
+}
+
+func panicForInvalidProcessReceivedMessageFunc(t, exp any) {
+ panic(fmt.Errorf("invalid ProcessReceivedMessageFunc type %T, expected %T", t, exp))
+}
+
+func (o ProcessReceivedMessageOpt[C]) TCPServerApply(cfg *tcpServer.Config) {
+ switch v := any(o.ProcessReceivedMessageFunc).(type) {
+ case config.ProcessReceivedMessageFunc[*tcpClient.Conn]:
+ cfg.ProcessReceivedMessage = v
+ default:
+ var t config.ProcessReceivedMessageFunc[*tcpClient.Conn]
+ panicForInvalidProcessReceivedMessageFunc(v, t)
+ }
+}
+
+func (o ProcessReceivedMessageOpt[C]) TCPClientApply(cfg *tcpClient.Config) {
+ switch v := any(o.ProcessReceivedMessageFunc).(type) {
+ case config.ProcessReceivedMessageFunc[*tcpClient.Conn]:
+ cfg.ProcessReceivedMessage = v
+ default:
+ var t config.ProcessReceivedMessageFunc[*tcpClient.Conn]
+ panicForInvalidProcessReceivedMessageFunc(v, t)
+ }
+}
+
+func (o ProcessReceivedMessageOpt[C]) UDPServerApply(cfg *udpServer.Config) {
+ switch v := any(o.ProcessReceivedMessageFunc).(type) {
+ case config.ProcessReceivedMessageFunc[*udpClient.Conn]:
+ cfg.ProcessReceivedMessage = v
+ default:
+ var t config.ProcessReceivedMessageFunc[*udpClient.Conn]
+ panicForInvalidProcessReceivedMessageFunc(v, t)
+ }
+}
+
+func (o ProcessReceivedMessageOpt[C]) DTLSServerApply(cfg *dtlsServer.Config) {
+ switch v := any(o.ProcessReceivedMessageFunc).(type) {
+ case config.ProcessReceivedMessageFunc[*udpClient.Conn]:
+ cfg.ProcessReceivedMessage = v
+ default:
+ var t config.ProcessReceivedMessageFunc[*udpClient.Conn]
+ panicForInvalidProcessReceivedMessageFunc(v, t)
+ }
+}
+
+func (o ProcessReceivedMessageOpt[C]) UDPClientApply(cfg *udpClient.Config) {
+ switch v := any(o.ProcessReceivedMessageFunc).(type) {
+ case config.ProcessReceivedMessageFunc[*udpClient.Conn]:
+ cfg.ProcessReceivedMessage = v
+ default:
+ var t config.ProcessReceivedMessageFunc[*udpClient.Conn]
+ panicForInvalidProcessReceivedMessageFunc(v, t)
+ }
+}
+
+func WithProcessReceivedMessageFunc[C responsewriter.Client](processReceivedMessageFunc config.ProcessReceivedMessageFunc[C]) ProcessReceivedMessageOpt[C] {
+ return ProcessReceivedMessageOpt[C]{ProcessReceivedMessageFunc: processReceivedMessageFunc}
+}
+
+type (
+ UDPOnInactive = func(cc *udpClient.Conn)
+ TCPOnInactive = func(cc *tcpClient.Conn)
+)
+
+type OnInactiveFunc interface {
+ UDPOnInactive | TCPOnInactive
+}
+
+func panicForInvalidOnInactiveFunc(t, exp any) {
+ panic(fmt.Errorf("invalid OnInactiveFunc type %T, expected %T", t, exp))
+}
+
+// KeepAliveOpt keepalive option.
+type KeepAliveOpt[C OnInactiveFunc] struct {
+ timeout time.Duration
+ onInactive C
+ maxRetries uint32
+}
+
+func (o KeepAliveOpt[C]) toTCPCreateInactivityMonitor(onInactive TCPOnInactive) func() tcpClient.InactivityMonitor {
+ return func() tcpClient.InactivityMonitor {
+ keepalive := inactivity.NewKeepAlive(o.maxRetries, onInactive, func(cc *tcpClient.Conn, receivePong func()) (func(), error) {
+ return cc.AsyncPing(receivePong)
+ })
+ return inactivity.New(o.timeout/time.Duration(o.maxRetries+1), keepalive.OnInactive)
+ }
+}
+
+func (o KeepAliveOpt[C]) toUDPCreateInactivityMonitor(onInactive UDPOnInactive) func() udpClient.InactivityMonitor {
+ return func() udpClient.InactivityMonitor {
+ keepalive := inactivity.NewKeepAlive(o.maxRetries, onInactive, func(cc *udpClient.Conn, receivePong func()) (func(), error) {
+ return cc.AsyncPing(receivePong)
+ })
+ return inactivity.New(o.timeout/time.Duration(o.maxRetries+1), keepalive.OnInactive)
+ }
+}
+
+func (o KeepAliveOpt[C]) TCPServerApply(cfg *tcpServer.Config) {
+ switch onInactive := any(o.onInactive).(type) {
+ case TCPOnInactive:
+ cfg.CreateInactivityMonitor = o.toTCPCreateInactivityMonitor(onInactive)
+ default:
+ var t TCPOnInactive
+ panicForInvalidOnInactiveFunc(onInactive, t)
+ }
+}
+
+func (o KeepAliveOpt[C]) TCPClientApply(cfg *tcpClient.Config) {
+ switch onInactive := any(o.onInactive).(type) {
+ case TCPOnInactive:
+ cfg.CreateInactivityMonitor = o.toTCPCreateInactivityMonitor(onInactive)
+ default:
+ var t TCPOnInactive
+ panicForInvalidOnInactiveFunc(onInactive, t)
+ }
+}
+
+func (o KeepAliveOpt[C]) UDPServerApply(cfg *udpServer.Config) {
+ switch onInactive := any(o.onInactive).(type) {
+ case UDPOnInactive:
+ cfg.CreateInactivityMonitor = o.toUDPCreateInactivityMonitor(onInactive)
+ default:
+ var t UDPOnInactive
+ panicForInvalidOnInactiveFunc(onInactive, t)
+ }
+}
+
+func (o KeepAliveOpt[C]) DTLSServerApply(cfg *dtlsServer.Config) {
+ switch onInactive := any(o.onInactive).(type) {
+ case UDPOnInactive:
+ cfg.CreateInactivityMonitor = o.toUDPCreateInactivityMonitor(onInactive)
+ default:
+ var t UDPOnInactive
+ panicForInvalidOnInactiveFunc(onInactive, t)
+ }
+}
+
+func (o KeepAliveOpt[C]) UDPClientApply(cfg *udpClient.Config) {
+ switch onInactive := any(o.onInactive).(type) {
+ case UDPOnInactive:
+ cfg.CreateInactivityMonitor = o.toUDPCreateInactivityMonitor(onInactive)
+ default:
+ var t UDPOnInactive
+ panicForInvalidOnInactiveFunc(onInactive, t)
+ }
+}
+
+// WithKeepAlive monitoring's client connection's.
+func WithKeepAlive[C OnInactiveFunc](maxRetries uint32, timeout time.Duration, onInactive C) KeepAliveOpt[C] {
+ return KeepAliveOpt[C]{
+ maxRetries: maxRetries,
+ timeout: timeout,
+ onInactive: onInactive,
+ }
+}
+
+// InactivityMonitorOpt notifies when a connection was inactive for a given duration.
+type InactivityMonitorOpt[C OnInactiveFunc] struct {
+ duration time.Duration
+ onInactive C
+}
+
+func (o InactivityMonitorOpt[C]) toTCPCreateInactivityMonitor(onInactive TCPOnInactive) func() tcpClient.InactivityMonitor {
+ return func() tcpClient.InactivityMonitor {
+ return inactivity.New(o.duration, onInactive)
+ }
+}
+
+func (o InactivityMonitorOpt[C]) toUDPCreateInactivityMonitor(onInactive UDPOnInactive) func() udpClient.InactivityMonitor {
+ return func() udpClient.InactivityMonitor {
+ return inactivity.New(o.duration, onInactive)
+ }
+}
+
+func (o InactivityMonitorOpt[C]) TCPServerApply(cfg *tcpServer.Config) {
+ switch onInactive := any(o.onInactive).(type) {
+ case TCPOnInactive:
+ cfg.CreateInactivityMonitor = o.toTCPCreateInactivityMonitor(onInactive)
+ default:
+ var t TCPOnInactive
+ panicForInvalidOnInactiveFunc(onInactive, t)
+ }
+}
+
+func (o InactivityMonitorOpt[C]) TCPClientApply(cfg *tcpClient.Config) {
+ switch onInactive := any(o.onInactive).(type) {
+ case TCPOnInactive:
+ cfg.CreateInactivityMonitor = o.toTCPCreateInactivityMonitor(onInactive)
+ default:
+ var t TCPOnInactive
+ panicForInvalidOnInactiveFunc(onInactive, t)
+ }
+}
+
+func (o InactivityMonitorOpt[C]) UDPServerApply(cfg *udpServer.Config) {
+ switch onInactive := any(o.onInactive).(type) {
+ case UDPOnInactive:
+ cfg.CreateInactivityMonitor = o.toUDPCreateInactivityMonitor(onInactive)
+ default:
+ var t UDPOnInactive
+ panicForInvalidOnInactiveFunc(onInactive, t)
+ }
+}
+
+func (o InactivityMonitorOpt[C]) DTLSServerApply(cfg *dtlsServer.Config) {
+ switch onInactive := any(o.onInactive).(type) {
+ case UDPOnInactive:
+ cfg.CreateInactivityMonitor = o.toUDPCreateInactivityMonitor(onInactive)
+ default:
+ var t UDPOnInactive
+ panicForInvalidOnInactiveFunc(onInactive, t)
+ }
+}
+
+func (o InactivityMonitorOpt[C]) UDPClientApply(cfg *udpClient.Config) {
+ switch onInactive := any(o.onInactive).(type) {
+ case UDPOnInactive:
+ cfg.CreateInactivityMonitor = o.toUDPCreateInactivityMonitor(onInactive)
+ default:
+ var t UDPOnInactive
+ panicForInvalidOnInactiveFunc(onInactive, t)
+ }
+}
+
+// WithInactivityMonitor set deadline's for read operations over client connection.
+func WithInactivityMonitor[C OnInactiveFunc](duration time.Duration, onInactive C) InactivityMonitorOpt[C] {
+ return InactivityMonitorOpt[C]{
+ duration: duration,
+ onInactive: onInactive,
+ }
+}
+
+// NetOpt network option.
+type NetOpt struct {
+ net string
+}
+
+func (o NetOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.Net = o.net
+}
+
+func (o NetOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.Net = o.net
+}
+
+// WithNetwork define's tcp version (udp4, udp6, tcp) for client.
+func WithNetwork(net string) NetOpt {
+ return NetOpt{net: net}
+}
+
+// PeriodicRunnerOpt function which is executed in every ticks
+type PeriodicRunnerOpt struct {
+ periodicRunner periodic.Func
+}
+
+func (o PeriodicRunnerOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.PeriodicRunner = o.periodicRunner
+}
+
+func (o PeriodicRunnerOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.PeriodicRunner = o.periodicRunner
+}
+
+func (o PeriodicRunnerOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.PeriodicRunner = o.periodicRunner
+}
+
+func (o PeriodicRunnerOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.PeriodicRunner = o.periodicRunner
+}
+
+func (o PeriodicRunnerOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.PeriodicRunner = o.periodicRunner
+}
+
+// WithPeriodicRunner set function which is executed in every ticks.
+func WithPeriodicRunner(periodicRunner periodic.Func) PeriodicRunnerOpt {
+ return PeriodicRunnerOpt{periodicRunner: periodicRunner}
+}
+
+// BlockwiseOpt network option.
+type BlockwiseOpt struct {
+ transferTimeout time.Duration
+ enable bool
+ szx blockwise.SZX
+}
+
+func (o BlockwiseOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.BlockwiseEnable = o.enable
+ cfg.BlockwiseSZX = o.szx
+ cfg.BlockwiseTransferTimeout = o.transferTimeout
+}
+
+func (o BlockwiseOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.BlockwiseEnable = o.enable
+ cfg.BlockwiseSZX = o.szx
+ cfg.BlockwiseTransferTimeout = o.transferTimeout
+}
+
+func (o BlockwiseOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.BlockwiseEnable = o.enable
+ cfg.BlockwiseSZX = o.szx
+ cfg.BlockwiseTransferTimeout = o.transferTimeout
+}
+
+func (o BlockwiseOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.BlockwiseEnable = o.enable
+ cfg.BlockwiseSZX = o.szx
+ cfg.BlockwiseTransferTimeout = o.transferTimeout
+}
+
+func (o BlockwiseOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.BlockwiseEnable = o.enable
+ cfg.BlockwiseSZX = o.szx
+ cfg.BlockwiseTransferTimeout = o.transferTimeout
+}
+
+// WithBlockwise configure's blockwise transfer.
+func WithBlockwise(enable bool, szx blockwise.SZX, transferTimeout time.Duration) BlockwiseOpt {
+ return BlockwiseOpt{
+ enable: enable,
+ szx: szx,
+ transferTimeout: transferTimeout,
+ }
+}
+
+type OnNewConnFunc interface {
+ tcpServer.OnNewConnFunc | udpServer.OnNewConnFunc
+}
+
+// OnNewConnOpt network option.
+type OnNewConnOpt[F OnNewConnFunc] struct {
+ f F
+}
+
+func panicForInvalidOnNewConnFunc(t, exp any) {
+ panic(fmt.Errorf("invalid OnNewConnFunc type %T, expected %T", t, exp))
+}
+
+func (o OnNewConnOpt[F]) UDPServerApply(cfg *udpServer.Config) {
+ switch v := any(o.f).(type) {
+ case udpServer.OnNewConnFunc:
+ cfg.OnNewConn = v
+ default:
+ var exp udpServer.OnNewConnFunc
+ panicForInvalidOnNewConnFunc(v, exp)
+ }
+}
+
+func (o OnNewConnOpt[F]) DTLSServerApply(cfg *dtlsServer.Config) {
+ switch v := any(o.f).(type) {
+ case udpServer.OnNewConnFunc:
+ cfg.OnNewConn = v
+ default:
+ var exp udpServer.OnNewConnFunc
+ panicForInvalidOnNewConnFunc(v, exp)
+ }
+}
+
+func (o OnNewConnOpt[F]) TCPServerApply(cfg *tcpServer.Config) {
+ switch v := any(o.f).(type) {
+ case tcpServer.OnNewConnFunc:
+ cfg.OnNewConn = v
+ default:
+ var exp tcpServer.OnNewConnFunc
+ panicForInvalidOnNewConnFunc(v, exp)
+ }
+}
+
+// WithOnNewConn server's notify about new client connection.
+func WithOnNewConn[F OnNewConnFunc](onNewConn F) OnNewConnOpt[F] {
+ return OnNewConnOpt[F]{
+ f: onNewConn,
+ }
+}
+
+// CloseSocketOpt close socket option.
+type CloseSocketOpt struct{}
+
+func (o CloseSocketOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.CloseSocket = true
+}
+
+func (o CloseSocketOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.CloseSocket = true
+}
+
+// WithCloseSocket closes socket at the close connection.
+func WithCloseSocket() CloseSocketOpt {
+ return CloseSocketOpt{}
+}
+
+// DialerOpt dialer option.
+type DialerOpt struct {
+ dialer *net.Dialer
+}
+
+func (o DialerOpt) UDPClientApply(cfg *udpClient.Config) {
+ if o.dialer != nil {
+ cfg.Dialer = o.dialer
+ }
+}
+
+func (o DialerOpt) TCPClientApply(cfg *tcpClient.Config) {
+ if o.dialer != nil {
+ cfg.Dialer = o.dialer
+ }
+}
+
+// WithDialer set dialer for dial.
+func WithDialer(dialer *net.Dialer) DialerOpt {
+ return DialerOpt{
+ dialer: dialer,
+ }
+}
+
+// ConnectionCacheOpt network option.
+type MessagePoolOpt struct {
+ messagePool *pool.Pool
+}
+
+func (o MessagePoolOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.MessagePool = o.messagePool
+}
+
+func (o MessagePoolOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.MessagePool = o.messagePool
+}
+
+func (o MessagePoolOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.MessagePool = o.messagePool
+}
+
+func (o MessagePoolOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.MessagePool = o.messagePool
+}
+
+func (o MessagePoolOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.MessagePool = o.messagePool
+}
+
+// WithMessagePool configure's message pool for acquire/releasing coap messages
+func WithMessagePool(messagePool *pool.Pool) MessagePoolOpt {
+ return MessagePoolOpt{
+ messagePool: messagePool,
+ }
+}
+
+// GetTokenOpt token option.
+type GetTokenOpt struct {
+ getToken client.GetTokenFunc
+}
+
+func (o GetTokenOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.GetToken = o.getToken
+}
+
+func (o GetTokenOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.GetToken = o.getToken
+}
+
+func (o GetTokenOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.GetToken = o.getToken
+}
+
+func (o GetTokenOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.GetToken = o.getToken
+}
+
+func (o GetTokenOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.GetToken = o.getToken
+}
+
+// WithGetToken set function for generating tokens.
+func WithGetToken(getToken client.GetTokenFunc) GetTokenOpt {
+ return GetTokenOpt{getToken: getToken}
+}
+
+// LimitClientParallelRequestOpt limit's number of parallel requests from client.
+type LimitClientParallelRequestOpt struct {
+ limitClientParallelRequests int64
+}
+
+func (o LimitClientParallelRequestOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.LimitClientParallelRequests = o.limitClientParallelRequests
+}
+
+func (o LimitClientParallelRequestOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.LimitClientParallelRequests = o.limitClientParallelRequests
+}
+
+func (o LimitClientParallelRequestOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.LimitClientParallelRequests = o.limitClientParallelRequests
+}
+
+func (o LimitClientParallelRequestOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.LimitClientParallelRequests = o.limitClientParallelRequests
+}
+
+func (o LimitClientParallelRequestOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.LimitClientParallelRequests = o.limitClientParallelRequests
+}
+
+// WithLimitClientParallelRequestOpt limits number of parallel requests from client. (default: 1)
+func WithLimitClientParallelRequest(limitClientParallelRequests int64) LimitClientParallelRequestOpt {
+ return LimitClientParallelRequestOpt{limitClientParallelRequests: limitClientParallelRequests}
+}
+
+// LimitClientEndpointParallelRequestOpt limit's number of parallel requests to endpoint by client.
+type LimitClientEndpointParallelRequestOpt struct {
+ limitClientEndpointParallelRequests int64
+}
+
+func (o LimitClientEndpointParallelRequestOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.LimitClientEndpointParallelRequests = o.limitClientEndpointParallelRequests
+}
+
+func (o LimitClientEndpointParallelRequestOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.LimitClientEndpointParallelRequests = o.limitClientEndpointParallelRequests
+}
+
+func (o LimitClientEndpointParallelRequestOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.LimitClientEndpointParallelRequests = o.limitClientEndpointParallelRequests
+}
+
+func (o LimitClientEndpointParallelRequestOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.LimitClientEndpointParallelRequests = o.limitClientEndpointParallelRequests
+}
+
+func (o LimitClientEndpointParallelRequestOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.LimitClientEndpointParallelRequests = o.limitClientEndpointParallelRequests
+}
+
+// WithLimitClientEndpointParallelRequest limits number of parallel requests to endpoint from client. (default: 1)
+func WithLimitClientEndpointParallelRequest(limitClientEndpointParallelRequests int64) LimitClientEndpointParallelRequestOpt {
+ return LimitClientEndpointParallelRequestOpt{limitClientEndpointParallelRequests: limitClientEndpointParallelRequests}
+}
+
+// ReceivedMessageQueueSizeOpt limit's message queue size for received messages.
+type ReceivedMessageQueueSizeOpt struct {
+ receivedMessageQueueSize int
+}
+
+func (o ReceivedMessageQueueSizeOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.ReceivedMessageQueueSize = o.receivedMessageQueueSize
+}
+
+func (o ReceivedMessageQueueSizeOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.ReceivedMessageQueueSize = o.receivedMessageQueueSize
+}
+
+func (o ReceivedMessageQueueSizeOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.ReceivedMessageQueueSize = o.receivedMessageQueueSize
+}
+
+func (o ReceivedMessageQueueSizeOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.ReceivedMessageQueueSize = o.receivedMessageQueueSize
+}
+
+func (o ReceivedMessageQueueSizeOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.ReceivedMessageQueueSize = o.receivedMessageQueueSize
+}
+
+// WithReceivedMessageQueueSize limit's message queue size for received messages. (default: 16)
+func WithReceivedMessageQueueSize(receivedMessageQueueSize int) ReceivedMessageQueueSizeOpt {
+ return ReceivedMessageQueueSizeOpt{receivedMessageQueueSize: receivedMessageQueueSize}
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/options/config/common.go b/vendor/github.com/plgd-dev/go-coap/v3/options/config/common.go
new file mode 100644
index 0000000..e6fd876
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/options/config/common.go
@@ -0,0 +1,61 @@
+package config
+
+import (
+ "context"
+ "fmt"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "github.com/plgd-dev/go-coap/v3/net/blockwise"
+ "github.com/plgd-dev/go-coap/v3/net/client"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/pkg/runner/periodic"
+)
+
+type (
+ ErrorFunc = func(error)
+ HandlerFunc[C responsewriter.Client] func(w *responsewriter.ResponseWriter[C], r *pool.Message)
+ ProcessReceivedMessageFunc[C responsewriter.Client] func(req *pool.Message, cc C, handler HandlerFunc[C])
+)
+
+type Common[C responsewriter.Client] struct {
+ LimitClientParallelRequests int64
+ LimitClientEndpointParallelRequests int64
+ Ctx context.Context
+ Errors ErrorFunc
+ PeriodicRunner periodic.Func
+ MessagePool *pool.Pool
+ GetToken client.GetTokenFunc
+ MaxMessageSize uint32
+ BlockwiseTransferTimeout time.Duration
+ BlockwiseSZX blockwise.SZX
+ BlockwiseEnable bool
+ ProcessReceivedMessage ProcessReceivedMessageFunc[C]
+ ReceivedMessageQueueSize int
+}
+
+func NewCommon[C responsewriter.Client]() Common[C] {
+ return Common[C]{
+ Ctx: context.Background(),
+ MaxMessageSize: 64 * 1024,
+ Errors: func(err error) {
+ fmt.Println(err)
+ },
+ BlockwiseSZX: blockwise.SZX1024,
+ BlockwiseEnable: true,
+ BlockwiseTransferTimeout: time.Second * 3,
+ PeriodicRunner: func(f func(now time.Time) bool) {
+ go func() {
+ for f(time.Now()) {
+ time.Sleep(4 * time.Second)
+ }
+ }()
+ },
+ MessagePool: pool.New(1024, 2048),
+ GetToken: message.GetToken,
+ LimitClientParallelRequests: 1,
+ LimitClientEndpointParallelRequests: 1,
+ ReceivedMessageQueueSize: 16,
+ }
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/options/tcpOptions.go b/vendor/github.com/plgd-dev/go-coap/v3/options/tcpOptions.go
new file mode 100644
index 0000000..ec2f9fb
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/options/tcpOptions.go
@@ -0,0 +1,76 @@
+package options
+
+import (
+ "crypto/tls"
+
+ tcpClient "github.com/plgd-dev/go-coap/v3/tcp/client"
+ tcpServer "github.com/plgd-dev/go-coap/v3/tcp/server"
+)
+
+// DisablePeerTCPSignalMessageCSMsOpt coap-tcp csm option.
+type DisablePeerTCPSignalMessageCSMsOpt struct{}
+
+func (o DisablePeerTCPSignalMessageCSMsOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.DisablePeerTCPSignalMessageCSMs = true
+}
+
+func (o DisablePeerTCPSignalMessageCSMsOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.DisablePeerTCPSignalMessageCSMs = true
+}
+
+// WithDisablePeerTCPSignalMessageCSMs ignor peer's CSM message.
+func WithDisablePeerTCPSignalMessageCSMs() DisablePeerTCPSignalMessageCSMsOpt {
+ return DisablePeerTCPSignalMessageCSMsOpt{}
+}
+
+// DisableTCPSignalMessageCSMOpt coap-tcp csm option.
+type DisableTCPSignalMessageCSMOpt struct{}
+
+func (o DisableTCPSignalMessageCSMOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.DisableTCPSignalMessageCSM = true
+}
+
+func (o DisableTCPSignalMessageCSMOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.DisableTCPSignalMessageCSM = true
+}
+
+// WithDisableTCPSignalMessageCSM don't send CSM when client conn is created.
+func WithDisableTCPSignalMessageCSM() DisableTCPSignalMessageCSMOpt {
+ return DisableTCPSignalMessageCSMOpt{}
+}
+
+// TLSOpt tls configuration option.
+type TLSOpt struct {
+ tlsCfg *tls.Config
+}
+
+func (o TLSOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.TLSCfg = o.tlsCfg
+}
+
+// WithTLS creates tls connection.
+func WithTLS(cfg *tls.Config) TLSOpt {
+ return TLSOpt{
+ tlsCfg: cfg,
+ }
+}
+
+// ConnectionCacheOpt network option.
+type ConnectionCacheSizeOpt struct {
+ connectionCacheSize uint16
+}
+
+func (o ConnectionCacheSizeOpt) TCPServerApply(cfg *tcpServer.Config) {
+ cfg.ConnectionCacheSize = o.connectionCacheSize
+}
+
+func (o ConnectionCacheSizeOpt) TCPClientApply(cfg *tcpClient.Config) {
+ cfg.ConnectionCacheSize = o.connectionCacheSize
+}
+
+// WithConnectionCacheSize configure's maximum size of cache of read buffer.
+func WithConnectionCacheSize(connectionCacheSize uint16) ConnectionCacheSizeOpt {
+ return ConnectionCacheSizeOpt{
+ connectionCacheSize: connectionCacheSize,
+ }
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/options/udpOptions.go b/vendor/github.com/plgd-dev/go-coap/v3/options/udpOptions.go
new file mode 100644
index 0000000..77f4ff9
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/options/udpOptions.go
@@ -0,0 +1,70 @@
+package options
+
+import (
+ "time"
+
+ dtlsServer "github.com/plgd-dev/go-coap/v3/dtls/server"
+ udpClient "github.com/plgd-dev/go-coap/v3/udp/client"
+ udpServer "github.com/plgd-dev/go-coap/v3/udp/server"
+)
+
+// TransmissionOpt transmission options.
+type TransmissionOpt struct {
+ transmissionNStart uint32
+ transmissionAcknowledgeTimeout time.Duration
+ transmissionMaxRetransmit uint32
+}
+
+func (o TransmissionOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.TransmissionNStart = o.transmissionNStart
+ cfg.TransmissionAcknowledgeTimeout = o.transmissionAcknowledgeTimeout
+ cfg.TransmissionMaxRetransmit = o.transmissionMaxRetransmit
+}
+
+func (o TransmissionOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.TransmissionNStart = o.transmissionNStart
+ cfg.TransmissionAcknowledgeTimeout = o.transmissionAcknowledgeTimeout
+ cfg.TransmissionMaxRetransmit = o.transmissionMaxRetransmit
+}
+
+func (o TransmissionOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.TransmissionNStart = o.transmissionNStart
+ cfg.TransmissionAcknowledgeTimeout = o.transmissionAcknowledgeTimeout
+ cfg.TransmissionMaxRetransmit = o.transmissionMaxRetransmit
+}
+
+// WithTransmission set options for (re)transmission for Confirmable message-s.
+func WithTransmission(transmissionNStart uint32,
+ transmissionAcknowledgeTimeout time.Duration,
+ transmissionMaxRetransmit uint32,
+) TransmissionOpt {
+ return TransmissionOpt{
+ transmissionNStart: transmissionNStart,
+ transmissionAcknowledgeTimeout: transmissionAcknowledgeTimeout,
+ transmissionMaxRetransmit: transmissionMaxRetransmit,
+ }
+}
+
+// MTUOpt transmission options.
+type MTUOpt struct {
+ mtu uint16
+}
+
+func (o MTUOpt) UDPServerApply(cfg *udpServer.Config) {
+ cfg.MTU = o.mtu
+}
+
+func (o MTUOpt) DTLSServerApply(cfg *dtlsServer.Config) {
+ cfg.MTU = o.mtu
+}
+
+func (o MTUOpt) UDPClientApply(cfg *udpClient.Config) {
+ cfg.MTU = o.mtu
+}
+
+// Setup MTU unit
+func WithMTU(mtu uint16) MTUOpt {
+ return MTUOpt{
+ mtu: mtu,
+ }
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/pkg/cache/cache.go b/vendor/github.com/plgd-dev/go-coap/v3/pkg/cache/cache.go
new file mode 100644
index 0000000..21099fc
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/pkg/cache/cache.go
@@ -0,0 +1,85 @@
+package cache
+
+import (
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/pkg/sync"
+ "go.uber.org/atomic"
+)
+
+func DefaultOnExpire[D any](D) {
+ // for nothing on expire
+}
+
+type Element[D any] struct {
+ ValidUntil atomic.Time
+ data D
+ onExpire func(d D)
+}
+
+func (e *Element[D]) IsExpired(now time.Time) bool {
+ value := e.ValidUntil.Load()
+ if value.IsZero() {
+ return false
+ }
+ return now.After(value)
+}
+
+func (e *Element[D]) Data() D {
+ return e.data
+}
+
+func NewElement[D any](data D, validUntil time.Time, onExpire func(d D)) *Element[D] {
+ if onExpire == nil {
+ onExpire = DefaultOnExpire[D]
+ }
+ e := &Element[D]{data: data, onExpire: onExpire}
+ e.ValidUntil.Store(validUntil)
+ return e
+}
+
+type Cache[K comparable, D any] struct {
+ *sync.Map[K, *Element[D]]
+}
+
+func NewCache[K comparable, D any]() *Cache[K, D] {
+ return &Cache[K, D]{
+ Map: sync.NewMap[K, *Element[D]](),
+ }
+}
+
+func (c *Cache[K, D]) LoadOrStore(key K, e *Element[D]) (actual *Element[D], loaded bool) {
+ now := time.Now()
+ c.Map.ReplaceWithFunc(key, func(oldValue *Element[D], oldLoaded bool) (newValue *Element[D], deleteValue bool) {
+ if oldLoaded {
+ if !oldValue.IsExpired(now) {
+ actual = oldValue
+ return oldValue, false
+ }
+ }
+ actual = e
+ return e, false
+ })
+ return actual, actual != e
+}
+
+func (c *Cache[K, D]) Load(key K) (actual *Element[D]) {
+ actual, loaded := c.Map.Load(key)
+ if !loaded {
+ return nil
+ }
+ if actual.IsExpired(time.Now()) {
+ return nil
+ }
+ return actual
+}
+
+func (c *Cache[K, D]) CheckExpirations(now time.Time) {
+ c.Range(func(key K, value *Element[D]) bool {
+ if value.IsExpired(now) {
+ c.Map.Delete(key)
+ value.onExpire(value.Data())
+ }
+ return true
+ })
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/pkg/connections/connections.go b/vendor/github.com/plgd-dev/go-coap/v3/pkg/connections/connections.go
new file mode 100644
index 0000000..d2de865
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/pkg/connections/connections.go
@@ -0,0 +1,73 @@
+package connections
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "sync"
+ "time"
+)
+
+type Connections struct {
+ data *sync.Map
+}
+
+func New() *Connections {
+ return &Connections{
+ data: &sync.Map{},
+ }
+}
+
+type Connection interface {
+ Context() context.Context
+ CheckExpirations(now time.Time)
+ Close() error
+ RemoteAddr() net.Addr
+}
+
+func (c *Connections) Store(conn Connection) {
+ c.data.Store(conn.RemoteAddr().String(), conn)
+}
+
+func (c *Connections) length() int {
+ var l int
+ c.data.Range(func(k, v interface{}) bool {
+ l++
+ return true
+ })
+ return l
+}
+
+func (c *Connections) copyConnections() []Connection {
+ m := make([]Connection, 0, c.length())
+ c.data.Range(func(key, value interface{}) bool {
+ con, ok := value.(Connection)
+ if !ok {
+ panic(fmt.Errorf("invalid type %T in connections map", con))
+ }
+ m = append(m, con)
+ return true
+ })
+ return m
+}
+
+func (c *Connections) CheckExpirations(now time.Time) {
+ for _, cc := range c.copyConnections() {
+ select {
+ case <-cc.Context().Done():
+ continue
+ default:
+ cc.CheckExpirations(now)
+ }
+ }
+}
+
+func (c *Connections) Close() {
+ for _, cc := range c.copyConnections() {
+ _ = cc.Close()
+ }
+}
+
+func (c *Connections) Delete(conn Connection) {
+ c.data.Delete(conn.RemoteAddr().String())
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/pkg/errors/error.go b/vendor/github.com/plgd-dev/go-coap/v3/pkg/errors/error.go
new file mode 100644
index 0000000..e98098b
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/pkg/errors/error.go
@@ -0,0 +1,5 @@
+package errors
+
+import "errors"
+
+var ErrKeyAlreadyExists = errors.New("key already exists")
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/pkg/fn/funcList.go b/vendor/github.com/plgd-dev/go-coap/v3/pkg/fn/funcList.go
new file mode 100644
index 0000000..9ed31e8
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/pkg/fn/funcList.go
@@ -0,0 +1,19 @@
+package fn
+
+type FuncList []func()
+
+// Return a function that executions all added functions
+//
+// Functions are executed in reverse order they were added.
+func (c FuncList) ToFunction() func() {
+ return func() {
+ for i := range c {
+ c[len(c)-1-i]()
+ }
+ }
+}
+
+// Execute all added functions
+func (c FuncList) Execute() {
+ c.ToFunction()()
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/pkg/rand/rand.go b/vendor/github.com/plgd-dev/go-coap/v3/pkg/rand/rand.go
new file mode 100644
index 0000000..124d313
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/pkg/rand/rand.go
@@ -0,0 +1,31 @@
+package rand
+
+import (
+ "math/rand"
+ "sync"
+)
+
+type Rand struct {
+ src *rand.Rand
+ lock sync.Mutex
+}
+
+func NewRand(seed int64) *Rand {
+ return &Rand{
+ src: rand.New(rand.NewSource(seed)),
+ }
+}
+
+func (l *Rand) Int63() int64 {
+ l.lock.Lock()
+ val := l.src.Int63()
+ l.lock.Unlock()
+ return val
+}
+
+func (l *Rand) Uint32() uint32 {
+ l.lock.Lock()
+ val := l.src.Uint32()
+ l.lock.Unlock()
+ return val
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/pkg/runner/periodic/periodic.go b/vendor/github.com/plgd-dev/go-coap/v3/pkg/runner/periodic/periodic.go
new file mode 100644
index 0000000..7cfe624
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/pkg/runner/periodic/periodic.go
@@ -0,0 +1,43 @@
+package periodic
+
+import (
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+type Func = func(f func(now time.Time) bool)
+
+func New(stop <-chan struct{}, tick time.Duration) Func {
+ var m sync.Map
+ var idx uint64
+ go func() {
+ t := time.NewTicker(tick)
+ defer t.Stop()
+ for {
+ var now time.Time
+ select {
+ case now = <-t.C:
+ case <-stop:
+ return
+ }
+ v := make(map[uint64]func(time.Time) bool)
+ m.Range(func(key, value interface{}) bool {
+ v[key.(uint64)] = value.(func(time.Time) bool) //nolint:forcetypeassert
+ return true
+ })
+ for k, f := range v {
+ if ok := f(now); !ok {
+ m.Delete(k)
+ }
+ }
+ }
+ }()
+ return func(f func(time.Time) bool) {
+ if f == nil {
+ return
+ }
+ v := atomic.AddUint64(&idx, 1)
+ m.Store(v, f)
+ }
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/pkg/sync/map.go b/vendor/github.com/plgd-dev/go-coap/v3/pkg/sync/map.go
new file mode 100644
index 0000000..321aefb
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/pkg/sync/map.go
@@ -0,0 +1,215 @@
+package sync
+
+import (
+ "sync"
+
+ "golang.org/x/exp/maps"
+)
+
+// Map is like a Go map[interface{}]interface{} but is safe for concurrent use by multiple goroutines.
+type Map[K comparable, V any] struct {
+ mutex sync.RWMutex
+ data map[K]V
+}
+
+// NewMap creates map.
+func NewMap[K comparable, V any]() *Map[K, V] {
+ return &Map[K, V]{
+ data: make(map[K]V),
+ }
+}
+
+// Store sets the value for a key.
+func (m *Map[K, V]) Store(key K, value V) {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+ m.data[key] = value
+}
+
+// Load returns the value stored in the map for a key, or nil if no value is present. The loaded value is read-only and should not be modified.
+// The ok result indicates whether value was found in the map.
+func (m *Map[K, V]) Load(key K) (V, bool) {
+ m.mutex.RLock()
+ defer m.mutex.RUnlock()
+ v, ok := m.data[key]
+ return v, ok
+}
+
+// LoadOrStore returns the existing value for the key if present. The loaded value is read-only and should not be modified.
+// Otherwise, it stores and returns the given value. The loaded result is true if the value was loaded, false if stored.
+func (m *Map[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) {
+ m.mutex.RLock()
+ v, ok := m.data[key]
+ m.mutex.RUnlock()
+ if ok {
+ return v, true
+ }
+ m.mutex.Lock()
+ m.data[key] = value
+ m.mutex.Unlock()
+ return value, false
+}
+
+// Replace replaces the existing value with a new value and returns old value for the key.
+func (m *Map[K, V]) Replace(key K, value V) (oldValue V, oldLoaded bool) {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+ v, ok := m.data[key]
+ m.data[key] = value
+ return v, ok
+}
+
+// Delete deletes the value for the key.
+func (m *Map[K, V]) Delete(key K) {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+ delete(m.data, key)
+}
+
+// LoadAndDelete loads and deletes the value for the key.
+func (m *Map[K, V]) LoadAndDelete(key K) (V, bool) {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+ value, ok := m.data[key]
+ delete(m.data, key)
+ return value, ok
+}
+
+// LoadAndDelete loads and deletes the value for the key.
+func (m *Map[K, V]) LoadAndDeleteAll() map[K]V {
+ m.mutex.Lock()
+ data := m.data
+ m.data = make(map[K]V)
+ m.mutex.Unlock()
+ return data
+}
+
+// CopyData creates a deep copy of the internal map.
+func (m *Map[K, V]) CopyData() map[K]V {
+ c := make(map[K]V)
+ m.mutex.RLock()
+ maps.Copy(c, m.data)
+ m.mutex.RUnlock()
+ return c
+}
+
+// Length returns number of stored values.
+func (m *Map[K, V]) Length() int {
+ m.mutex.RLock()
+ defer m.mutex.RUnlock()
+ return len(m.data)
+}
+
+// Range calls f sequentially for each key and value present in the map. If f returns false, range stops the iteration.
+//
+// Range does not copy the whole map, instead the read lock is locked on iteration of the map, and unlocked before f is called.
+func (m *Map[K, V]) Range(f func(key K, value V) bool) {
+ m.mutex.RLock()
+ defer m.mutex.RUnlock()
+ for key, value := range m.data {
+ m.mutex.RUnlock()
+ ok := f(key, value)
+ m.mutex.RLock()
+ if !ok {
+ return
+ }
+ }
+}
+
+// Range2 calls f sequentially for each key and value present in the map. If f returns false, range stops the iteration.
+//
+// Range2 differs from Range by keepting a read lock locked during the whole call.
+func (m *Map[K, V]) Range2(f func(key K, value V) bool) {
+ m.mutex.RLock()
+ defer m.mutex.RUnlock()
+ for key, value := range m.data {
+ ok := f(key, value)
+ if !ok {
+ return
+ }
+ }
+}
+
+// StoreWithFunc creates a new element and stores it in the map under the given key.
+//
+// The createFunc is invoked under a write lock.
+func (m *Map[K, V]) StoreWithFunc(key K, createFunc func() V) {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+ m.data[key] = createFunc()
+}
+
+// LoadWithFunc tries to load element for key from the map, if it exists then the onload functions is invoked on it.
+//
+// The onLoadFunc is invoked under a read lock.
+func (m *Map[K, V]) LoadWithFunc(key K, onLoadFunc func(value V) V) (V, bool) {
+ m.mutex.RLock()
+ defer m.mutex.RUnlock()
+ value, ok := m.data[key]
+ if ok && onLoadFunc != nil {
+ value = onLoadFunc(value)
+ }
+ return value, ok
+}
+
+// LoadOrStoreWithFunc loads an existing element from the map or creates a new element and stores it in the map
+//
+// The onLoadFunc or createFunc are invoked under a write lock.
+func (m *Map[K, V]) LoadOrStoreWithFunc(key K, onLoadFunc func(value V) V, createFunc func() V) (actual V, loaded bool) {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+ v, ok := m.data[key]
+ if ok {
+ if onLoadFunc != nil {
+ v = onLoadFunc(v)
+ }
+ return v, true
+ }
+ v = createFunc()
+ m.data[key] = v
+ return v, false
+}
+
+// ReplaceWithFunc checks whether key exists in the map, invokes the onReplaceFunc callback on the pair (value, ok) and either deletes or stores the element
+// in the map based on the returned values from the onReplaceFunc callback.
+//
+// The onReplaceFunc callback is invoked under a write lock.
+func (m *Map[K, V]) ReplaceWithFunc(key K, onReplaceFunc func(oldValue V, oldLoaded bool) (newValue V, doDelete bool)) (oldValue V, oldLoaded bool) {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+ v, ok := m.data[key]
+ newValue, del := onReplaceFunc(v, ok)
+ if del {
+ delete(m.data, key)
+ return v, ok
+ }
+ m.data[key] = newValue
+ return v, ok
+}
+
+// DeleteWithFunc removes the key from the map and if a value existed invokes the onDeleteFunc callback on the removed value.
+//
+// The onDeleteFunc callback is invoked under a write lock.
+func (m *Map[K, V]) DeleteWithFunc(key K, onDeleteFunc func(value V)) {
+ _, _ = m.LoadAndDeleteWithFunc(key, func(value V) V {
+ onDeleteFunc(value)
+ return value
+ })
+}
+
+// LoadAndDeleteWithFunc removes the key from the map and if a value existed invokes the onLoadFunc callback on the removed and return it.
+//
+// The onLoadFunc callback is invoked under a write lock.
+func (m *Map[K, V]) LoadAndDeleteWithFunc(key K, onLoadFunc func(value V) V) (V, bool) {
+ var v V
+ var loaded bool
+ m.ReplaceWithFunc(key, func(oldValue V, oldLoaded bool) (newValue V, doDelete bool) {
+ if oldLoaded {
+ loaded = true
+ v = onLoadFunc(oldValue)
+ return v, true
+ }
+ return oldValue, true
+ })
+ return v, loaded
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/tcp/client/config.go b/vendor/github.com/plgd-dev/go-coap/v3/tcp/client/config.go
new file mode 100644
index 0000000..dd212d9
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/tcp/client/config.go
@@ -0,0 +1,49 @@
+package client
+
+import (
+ "crypto/tls"
+ "fmt"
+ "net"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/options/config"
+)
+
+var DefaultConfig = func() Config {
+ opts := Config{
+ Common: config.NewCommon[*Conn](),
+ CreateInactivityMonitor: func() InactivityMonitor {
+ return inactivity.NewNilMonitor[*Conn]()
+ },
+ Dialer: &net.Dialer{Timeout: time.Second * 3},
+ Net: "tcp",
+ ConnectionCacheSize: 2048,
+ }
+ opts.Handler = func(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ switch r.Code() {
+ case codes.POST, codes.PUT, codes.GET, codes.DELETE:
+ if err := w.SetResponse(codes.NotFound, message.TextPlain, nil); err != nil {
+ opts.Errors(fmt.Errorf("client handler: cannot set response: %w", err))
+ }
+ }
+ }
+ return opts
+}()
+
+type Config struct {
+ config.Common[*Conn]
+ CreateInactivityMonitor CreateInactivityMonitorFunc
+ Net string
+ Dialer *net.Dialer
+ TLSCfg *tls.Config
+ Handler HandlerFunc
+ ConnectionCacheSize uint16
+ DisablePeerTCPSignalMessageCSMs bool
+ CloseSocket bool
+ DisableTCPSignalMessageCSM bool
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/tcp/client/conn.go b/vendor/github.com/plgd-dev/go-coap/v3/tcp/client/conn.go
new file mode 100644
index 0000000..2f3da22
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/tcp/client/conn.go
@@ -0,0 +1,370 @@
+package client
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ coapNet "github.com/plgd-dev/go-coap/v3/net"
+ "github.com/plgd-dev/go-coap/v3/net/blockwise"
+ "github.com/plgd-dev/go-coap/v3/net/client"
+ limitparallelrequests "github.com/plgd-dev/go-coap/v3/net/client/limitParallelRequests"
+ "github.com/plgd-dev/go-coap/v3/net/observation"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ coapErrors "github.com/plgd-dev/go-coap/v3/pkg/errors"
+ coapSync "github.com/plgd-dev/go-coap/v3/pkg/sync"
+ "go.uber.org/atomic"
+)
+
+type InactivityMonitor interface {
+ Notify()
+ CheckInactivity(now time.Time, cc *Conn)
+}
+
+type (
+ HandlerFunc = func(*responsewriter.ResponseWriter[*Conn], *pool.Message)
+ ErrorFunc = func(error)
+ EventFunc = func()
+ GetMIDFunc = func() int32
+ CreateInactivityMonitorFunc = func() InactivityMonitor
+)
+
+type Notifier interface {
+ Notify()
+}
+
+// Conn represents a virtual connection to a conceptual endpoint, to perform COAPs commands.
+type Conn struct {
+ *client.Client[*Conn]
+ session *Session
+ observationHandler *observation.Handler[*Conn]
+ processReceivedMessage func(req *pool.Message, cc *Conn, handler HandlerFunc)
+ tokenHandlerContainer *coapSync.Map[uint64, HandlerFunc]
+ blockWise *blockwise.BlockWise[*Conn]
+ blockwiseSZX blockwise.SZX
+ peerMaxMessageSize atomic.Uint32
+ disablePeerTCPSignalMessageCSMs bool
+ peerBlockWiseTranferEnabled atomic.Bool
+
+ receivedMessageReader *client.ReceivedMessageReader[*Conn]
+}
+
+// NewConn creates connection over session and observation.
+func NewConn(
+ connection *coapNet.Conn,
+ createBlockWise func(cc *Conn) *blockwise.BlockWise[*Conn],
+ inactivityMonitor InactivityMonitor,
+ cfg *Config,
+) *Conn {
+ if cfg.GetToken == nil {
+ cfg.GetToken = message.GetToken
+ }
+ cc := Conn{
+ tokenHandlerContainer: coapSync.NewMap[uint64, HandlerFunc](),
+ blockwiseSZX: cfg.BlockwiseSZX,
+ disablePeerTCPSignalMessageCSMs: cfg.DisablePeerTCPSignalMessageCSMs,
+ }
+ limitParallelRequests := limitparallelrequests.New(cfg.LimitClientParallelRequests, cfg.LimitClientEndpointParallelRequests, cc.do, cc.doObserve)
+ cc.observationHandler = observation.NewHandler(&cc, cfg.Handler, limitParallelRequests.Do)
+ cc.Client = client.New(&cc, cc.observationHandler, cfg.GetToken, limitParallelRequests)
+ cc.blockWise = createBlockWise(&cc)
+ session := NewSession(cfg.Ctx,
+ connection,
+ cfg.MaxMessageSize,
+ cfg.Errors,
+ cfg.DisableTCPSignalMessageCSM,
+ cfg.CloseSocket,
+ inactivityMonitor,
+ cfg.ConnectionCacheSize,
+ cfg.MessagePool,
+ )
+ cc.session = session
+ if cc.processReceivedMessage == nil {
+ cc.processReceivedMessage = processReceivedMessage
+ }
+ cc.receivedMessageReader = client.NewReceivedMessageReader(&cc, cfg.ReceivedMessageQueueSize)
+ return &cc
+}
+
+func processReceivedMessage(req *pool.Message, cc *Conn, handler HandlerFunc) {
+ cc.ProcessReceivedMessageWithHandler(req, handler)
+}
+
+func (cc *Conn) ProcessReceivedMessage(req *pool.Message) {
+ cc.processReceivedMessage(req, cc, cc.handle)
+}
+
+func (cc *Conn) Session() *Session {
+ return cc.session
+}
+
+// Close closes connection without wait of ends Run function.
+func (cc *Conn) Close() error {
+ err := cc.session.Close()
+ if errors.Is(err, net.ErrClosed) {
+ return nil
+ }
+ return err
+}
+
+func (cc *Conn) doInternal(req *pool.Message) (*pool.Message, error) {
+ token := req.Token()
+ if token == nil {
+ return nil, fmt.Errorf("invalid token")
+ }
+ respChan := make(chan *pool.Message, 1)
+ if _, loaded := cc.tokenHandlerContainer.LoadOrStore(token.Hash(), func(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ r.Hijack()
+ select {
+ case respChan <- r:
+ default:
+ }
+ }); loaded {
+ return nil, fmt.Errorf("cannot add token handler: %w", coapErrors.ErrKeyAlreadyExists)
+ }
+ defer func() {
+ _, _ = cc.tokenHandlerContainer.LoadAndDelete(token.Hash())
+ }()
+ if err := cc.session.WriteMessage(req); err != nil {
+ return nil, fmt.Errorf("cannot write request: %w", err)
+ }
+
+ cc.receivedMessageReader.TryToReplaceLoop()
+
+ select {
+ case <-req.Context().Done():
+ return nil, req.Context().Err()
+ case <-cc.session.Context().Done():
+ return nil, fmt.Errorf("connection was closed: %w", cc.Context().Err())
+ case resp := <-respChan:
+ return resp, nil
+ }
+}
+
+// Do sends an coap message and returns an coap response.
+//
+// An error is returned if by failure to speak COAP (such as a network connectivity problem).
+// Any status code doesn't cause an error.
+//
+// Caller is responsible to release request and response.
+func (cc *Conn) do(req *pool.Message) (*pool.Message, error) {
+ if !cc.peerBlockWiseTranferEnabled.Load() || cc.blockWise == nil {
+ return cc.doInternal(req)
+ }
+ resp, err := cc.blockWise.Do(req, cc.blockwiseSZX, cc.session.maxMessageSize, cc.doInternal)
+ if err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+func (cc *Conn) writeMessage(req *pool.Message) error {
+ return cc.session.WriteMessage(req)
+}
+
+// WriteMessage sends an coap message.
+func (cc *Conn) WriteMessage(req *pool.Message) error {
+ if !cc.peerBlockWiseTranferEnabled.Load() || cc.blockWise == nil {
+ return cc.writeMessage(req)
+ }
+ return cc.blockWise.WriteMessage(req, cc.blockwiseSZX, cc.Session().maxMessageSize, cc.writeMessage)
+}
+
+// Context returns the client's context.
+//
+// If connections was closed context is cancelled.
+func (cc *Conn) Context() context.Context {
+ return cc.session.Context()
+}
+
+// AsyncPing sends ping and receivedPong will be called when pong arrives. It returns cancellation of ping operation.
+func (cc *Conn) AsyncPing(receivedPong func()) (func(), error) {
+ token, err := message.GetToken()
+ if err != nil {
+ return nil, fmt.Errorf("cannot get token: %w", err)
+ }
+ req := cc.session.messagePool.AcquireMessage(cc.Context())
+ req.SetToken(token)
+ req.SetCode(codes.Ping)
+ defer cc.ReleaseMessage(req)
+
+ if _, loaded := cc.tokenHandlerContainer.LoadOrStore(token.Hash(), func(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ if r.Code() == codes.Pong {
+ receivedPong()
+ }
+ }); loaded {
+ return nil, fmt.Errorf("cannot add token handler: %w", coapErrors.ErrKeyAlreadyExists)
+ }
+ removeTokenHandler := func() {
+ _, _ = cc.tokenHandlerContainer.LoadAndDelete(token.Hash())
+ }
+ err = cc.session.WriteMessage(req)
+ if err != nil {
+ removeTokenHandler()
+ return nil, fmt.Errorf("cannot write request: %w", err)
+ }
+ return removeTokenHandler, nil
+}
+
+// Run reads and process requests from a connection, until the connection is not closed.
+func (cc *Conn) Run() (err error) {
+ return cc.session.Run(cc)
+}
+
+// AddOnClose calls function on close connection event.
+func (cc *Conn) AddOnClose(f EventFunc) {
+ cc.session.AddOnClose(f)
+}
+
+// RemoteAddr gets remote address.
+func (cc *Conn) RemoteAddr() net.Addr {
+ return cc.session.RemoteAddr()
+}
+
+func (cc *Conn) LocalAddr() net.Addr {
+ return cc.session.LocalAddr()
+}
+
+// Sequence acquires sequence number.
+func (cc *Conn) Sequence() uint64 {
+ return cc.session.Sequence()
+}
+
+// SetContextValue stores the value associated with key to context of connection.
+func (cc *Conn) SetContextValue(key interface{}, val interface{}) {
+ cc.session.SetContextValue(key, val)
+}
+
+// Done signalizes that connection is not more processed.
+func (cc *Conn) Done() <-chan struct{} {
+ return cc.session.Done()
+}
+
+// CheckExpirations checks and remove expired items from caches.
+func (cc *Conn) CheckExpirations(now time.Time) {
+ cc.session.CheckExpirations(now, cc)
+ if cc.blockWise != nil {
+ cc.blockWise.CheckExpirations(now)
+ }
+}
+
+func (cc *Conn) AcquireMessage(ctx context.Context) *pool.Message {
+ return cc.session.AcquireMessage(ctx)
+}
+
+func (cc *Conn) ReleaseMessage(m *pool.Message) {
+ cc.session.ReleaseMessage(m)
+}
+
+// NetConn returns the underlying connection that is wrapped by cc. The Conn returned is shared by all invocations of NetConn, so do not modify it.
+func (cc *Conn) NetConn() net.Conn {
+ return cc.session.NetConn()
+}
+
+// DoObserve subscribes for every change with request.
+func (cc *Conn) doObserve(req *pool.Message, observeFunc func(req *pool.Message)) (client.Observation, error) {
+ return cc.observationHandler.NewObservation(req, observeFunc)
+}
+
+func (cc *Conn) ProcessReceivedMessageWithHandler(req *pool.Message, handler HandlerFunc) {
+ origResp := cc.AcquireMessage(cc.Context())
+ origResp.SetToken(req.Token())
+ w := responsewriter.New(origResp, cc, req.Options()...)
+ handler(w, req)
+ defer cc.ReleaseMessage(w.Message())
+ if !req.IsHijacked() {
+ cc.ReleaseMessage(req)
+ }
+ if w.Message().IsModified() {
+ err := cc.Session().WriteMessage(w.Message())
+ if err != nil {
+ if errC := cc.Close(); errC != nil {
+ cc.Session().errors(fmt.Errorf("cannot close connection: %w", errC))
+ }
+ cc.Session().errors(fmt.Errorf("cannot write response to %v: %w", cc.RemoteAddr(), err))
+ }
+ }
+}
+
+func (cc *Conn) blockwiseHandle(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ if h, ok := cc.tokenHandlerContainer.Load(r.Token().Hash()); ok {
+ h(w, r)
+ return
+ }
+ cc.observationHandler.Handle(w, r)
+}
+
+func (cc *Conn) handle(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ if cc.blockWise != nil && cc.peerBlockWiseTranferEnabled.Load() {
+ cc.blockWise.Handle(w, r, cc.blockwiseSZX, cc.Session().maxMessageSize, cc.blockwiseHandle)
+ return
+ }
+ if h, ok := cc.tokenHandlerContainer.LoadAndDelete(r.Token().Hash()); ok {
+ h(w, r)
+ return
+ }
+ cc.observationHandler.Handle(w, r)
+}
+
+func (cc *Conn) sendPong(token message.Token) error {
+ req := cc.AcquireMessage(cc.Context())
+ defer cc.ReleaseMessage(req)
+ req.SetCode(codes.Pong)
+ req.SetToken(token)
+ return cc.Session().WriteMessage(req)
+}
+
+func (cc *Conn) handleSignals(r *pool.Message) bool {
+ switch r.Code() {
+ case codes.CSM:
+ if cc.disablePeerTCPSignalMessageCSMs {
+ return true
+ }
+ if size, err := r.GetOptionUint32(message.TCPMaxMessageSize); err == nil {
+ cc.peerMaxMessageSize.Store(size)
+ }
+ if r.HasOption(message.TCPBlockWiseTransfer) {
+ cc.peerBlockWiseTranferEnabled.Store(true)
+ }
+ return true
+ case codes.Ping:
+ // if r.HasOption(message.TCPCustody) {
+ // TODO
+ // }
+ if err := cc.sendPong(r.Token()); err != nil && !coapNet.IsConnectionBrokenError(err) {
+ cc.Session().errors(fmt.Errorf("cannot handle ping signal: %w", err))
+ }
+ return true
+ case codes.Release:
+ // if r.HasOption(message.TCPAlternativeAddress) {
+ // TODO
+ // }
+ return true
+ case codes.Abort:
+ // if r.HasOption(message.TCPBadCSMOption) {
+ // TODO
+ // }
+ return true
+ case codes.Pong:
+ if h, ok := cc.tokenHandlerContainer.LoadAndDelete(r.Token().Hash()); ok {
+ cc.processReceivedMessage(r, cc, h)
+ }
+ return true
+ }
+ return false
+}
+
+func (cc *Conn) pushToReceivedMessageQueue(r *pool.Message) {
+ if cc.handleSignals(r) {
+ return
+ }
+ select {
+ case cc.receivedMessageReader.C() <- r:
+ case <-cc.Context().Done():
+ }
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/tcp/client/session.go b/vendor/github.com/plgd-dev/go-coap/v3/tcp/client/session.go
new file mode 100644
index 0000000..8332b26
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/tcp/client/session.go
@@ -0,0 +1,272 @@
+package client
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "net"
+ "sync"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ coapNet "github.com/plgd-dev/go-coap/v3/net"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/tcp/coder"
+ "go.uber.org/atomic"
+)
+
+type Session struct {
+ // This field needs to be the first in the struct to ensure proper word alignment on 32-bit platforms.
+ // See: https://golang.org/pkg/sync/atomic/#pkg-note-BUG
+ sequence atomic.Uint64
+ inactivityMonitor InactivityMonitor
+ errSendCSM error
+ cancel context.CancelFunc
+ done chan struct{}
+ errors ErrorFunc
+ connection *coapNet.Conn
+ messagePool *pool.Pool
+ ctx atomic.Value // TODO: change to atomic.Pointer[context.Context] for go1.19
+ maxMessageSize uint32
+ private struct {
+ mutex sync.Mutex
+ onClose []EventFunc
+ }
+ connectionCacheSize uint16
+ disableTCPSignalMessageCSM bool
+ closeSocket bool
+}
+
+func NewSession(
+ ctx context.Context,
+ connection *coapNet.Conn,
+ maxMessageSize uint32,
+ errors ErrorFunc,
+ disableTCPSignalMessageCSM bool,
+ closeSocket bool,
+ inactivityMonitor InactivityMonitor,
+ connectionCacheSize uint16,
+ messagePool *pool.Pool,
+) *Session {
+ ctx, cancel := context.WithCancel(ctx)
+ if errors == nil {
+ errors = func(error) {
+ // default no-op
+ }
+ }
+ if inactivityMonitor == nil {
+ inactivityMonitor = inactivity.NewNilMonitor[*Conn]()
+ }
+
+ s := &Session{
+ cancel: cancel,
+ connection: connection,
+ maxMessageSize: maxMessageSize,
+ errors: errors,
+ disableTCPSignalMessageCSM: disableTCPSignalMessageCSM,
+ closeSocket: closeSocket,
+ inactivityMonitor: inactivityMonitor,
+ done: make(chan struct{}),
+ connectionCacheSize: connectionCacheSize,
+ messagePool: messagePool,
+ }
+ s.ctx.Store(&ctx)
+
+ if !disableTCPSignalMessageCSM {
+ err := s.sendCSM()
+ if err != nil {
+ s.errSendCSM = fmt.Errorf("cannot send CSM: %w", err)
+ }
+ }
+
+ return s
+}
+
+// SetContextValue stores the value associated with key to context of connection.
+func (s *Session) SetContextValue(key interface{}, val interface{}) {
+ ctx := context.WithValue(s.Context(), key, val)
+ s.ctx.Store(&ctx)
+}
+
+// Done signalizes that connection is not more processed.
+func (s *Session) Done() <-chan struct{} {
+ return s.done
+}
+
+func (s *Session) AddOnClose(f EventFunc) {
+ s.private.mutex.Lock()
+ defer s.private.mutex.Unlock()
+ s.private.onClose = append(s.private.onClose, f)
+}
+
+func (s *Session) popOnClose() []EventFunc {
+ s.private.mutex.Lock()
+ defer s.private.mutex.Unlock()
+ tmp := s.private.onClose
+ s.private.onClose = nil
+ return tmp
+}
+
+func (s *Session) shutdown() {
+ defer close(s.done)
+ for _, f := range s.popOnClose() {
+ f()
+ }
+}
+
+func (s *Session) Close() error {
+ s.cancel()
+ if s.closeSocket {
+ return s.connection.Close()
+ }
+ return nil
+}
+
+func (s *Session) Sequence() uint64 {
+ return s.sequence.Inc()
+}
+
+func (s *Session) Context() context.Context {
+ return *s.ctx.Load().(*context.Context) //nolint:forcetypeassert
+}
+
+func seekBufferToNextMessage(buffer *bytes.Buffer, msgSize int) *bytes.Buffer {
+ if msgSize == buffer.Len() {
+ // buffer is empty so reset it
+ buffer.Reset()
+ return buffer
+ }
+ // rewind to next message
+ trimmed := 0
+ for trimmed != msgSize {
+ b := make([]byte, 4096)
+ max := 4096
+ if msgSize-trimmed < max {
+ max = msgSize - trimmed
+ }
+ v, _ := buffer.Read(b[:max])
+ trimmed += v
+ }
+ return buffer
+}
+
+func (s *Session) processBuffer(buffer *bytes.Buffer, cc *Conn) error {
+ for buffer.Len() > 0 {
+ var header coder.MessageHeader
+ _, err := coder.DefaultCoder.DecodeHeader(buffer.Bytes(), &header)
+ if errors.Is(err, message.ErrShortRead) {
+ return nil
+ }
+ if header.MessageLength > s.maxMessageSize {
+ return fmt.Errorf("max message size(%v) was exceeded %v", s.maxMessageSize, header.MessageLength)
+ }
+ if uint32(buffer.Len()) < header.MessageLength {
+ return nil
+ }
+ req := s.messagePool.AcquireMessage(s.Context())
+ read, err := req.UnmarshalWithDecoder(coder.DefaultCoder, buffer.Bytes()[:header.MessageLength])
+ if err != nil {
+ s.messagePool.ReleaseMessage(req)
+ return fmt.Errorf("cannot unmarshal with header: %w", err)
+ }
+ buffer = seekBufferToNextMessage(buffer, read)
+ req.SetSequence(s.Sequence())
+ s.inactivityMonitor.Notify()
+ cc.pushToReceivedMessageQueue(req)
+ }
+ return nil
+}
+
+func (s *Session) WriteMessage(req *pool.Message) error {
+ data, err := req.MarshalWithEncoder(coder.DefaultCoder)
+ if err != nil {
+ return fmt.Errorf("cannot marshal: %w", err)
+ }
+ err = s.connection.WriteWithContext(req.Context(), data)
+ if err != nil {
+ return fmt.Errorf("cannot write to connection: %w", err)
+ }
+ return err
+}
+
+func (s *Session) sendCSM() error {
+ token, err := message.GetToken()
+ if err != nil {
+ return fmt.Errorf("cannot get token: %w", err)
+ }
+ req := s.messagePool.AcquireMessage(s.Context())
+ defer s.messagePool.ReleaseMessage(req)
+ req.SetCode(codes.CSM)
+ req.SetToken(token)
+ return s.WriteMessage(req)
+}
+
+func shrinkBufferIfNecessary(buffer *bytes.Buffer, maxCap uint16) *bytes.Buffer {
+ if buffer.Len() == 0 && buffer.Cap() > int(maxCap) {
+ buffer = bytes.NewBuffer(make([]byte, 0, maxCap))
+ }
+ return buffer
+}
+
+// Run reads and process requests from a connection, until the connection is not closed.
+func (s *Session) Run(cc *Conn) (err error) {
+ defer func() {
+ err1 := s.Close()
+ if err == nil {
+ err = err1
+ }
+ s.shutdown()
+ }()
+ if s.errSendCSM != nil {
+ return s.errSendCSM
+ }
+ buffer := bytes.NewBuffer(make([]byte, 0, s.connectionCacheSize))
+ readBuf := make([]byte, s.connectionCacheSize)
+ for {
+ err = s.processBuffer(buffer, cc)
+ if err != nil {
+ return err
+ }
+ buffer = shrinkBufferIfNecessary(buffer, s.connectionCacheSize)
+ readLen, err := s.connection.ReadWithContext(s.Context(), readBuf)
+ if err != nil {
+ if coapNet.IsConnectionBrokenError(err) { // other side closed the connection, ignore the error and return
+ return nil
+ }
+ return fmt.Errorf("cannot read from connection: %w", err)
+ }
+ if readLen > 0 {
+ buffer.Write(readBuf[:readLen])
+ }
+ }
+}
+
+// CheckExpirations checks and remove expired items from caches.
+func (s *Session) CheckExpirations(now time.Time, cc *Conn) {
+ s.inactivityMonitor.CheckInactivity(now, cc)
+}
+
+func (s *Session) AcquireMessage(ctx context.Context) *pool.Message {
+ return s.messagePool.AcquireMessage(ctx)
+}
+
+func (s *Session) ReleaseMessage(m *pool.Message) {
+ s.messagePool.ReleaseMessage(m)
+}
+
+// RemoteAddr gets remote address.
+func (s *Session) RemoteAddr() net.Addr {
+ return s.connection.RemoteAddr()
+}
+
+func (s *Session) LocalAddr() net.Addr {
+ return s.connection.LocalAddr()
+}
+
+// NetConn returns the underlying connection that is wrapped by s. The Conn returned is shared by all invocations of NetConn, so do not modify it.
+func (s *Session) NetConn() net.Conn {
+ return s.connection.NetConn()
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/tcp/coder/coder.go b/vendor/github.com/plgd-dev/go-coap/v3/tcp/coder/coder.go
new file mode 100644
index 0000000..9979370
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/tcp/coder/coder.go
@@ -0,0 +1,254 @@
+package coder
+
+import (
+ "encoding/binary"
+ "errors"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+)
+
+var DefaultCoder = new(Coder)
+
+const (
+ MessageLength13Base = 13
+ MessageLength14Base = 269
+ MessageLength15Base = 65805
+ messageMaxLen = 0x7fff0000 // Large number that works in 32-bit builds
+)
+
+type Coder struct{}
+
+type MessageHeader struct {
+ Token []byte
+ Length uint32
+ MessageLength uint32
+ Code codes.Code
+}
+
+func (c *Coder) Size(m message.Message) (int, error) {
+ size, err := c.Encode(m, nil)
+ if errors.Is(err, message.ErrTooSmall) {
+ err = nil
+ }
+ return size, err
+}
+
+func getHeader(messageLength int) (uint8, []byte) {
+ if messageLength < MessageLength13Base {
+ return uint8(messageLength), nil
+ }
+ if messageLength < MessageLength14Base {
+ extLen := messageLength - MessageLength13Base
+ extLenBytes := []byte{uint8(extLen)}
+ return 13, extLenBytes
+ }
+ if messageLength < MessageLength15Base {
+ extLen := messageLength - MessageLength14Base
+ extLenBytes := make([]byte, 2)
+ binary.BigEndian.PutUint16(extLenBytes, uint16(extLen))
+ return 14, extLenBytes
+ }
+ if messageLength < messageMaxLen {
+ extLen := messageLength - MessageLength15Base
+ extLenBytes := make([]byte, 4)
+ binary.BigEndian.PutUint32(extLenBytes, uint32(extLen))
+ return 15, extLenBytes
+ }
+ return 0, nil
+}
+
+func (c *Coder) Encode(m message.Message, buf []byte) (int, error) {
+ /*
+ A CoAP Message message lomessage.OKs like:
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Len | TKL | Extended Length ...
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Code | TKL bytes ...
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Options (if any) ...
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ |1 1 1 1 1 1 1 1| Payload (if any) ...
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ The size of the Extended Length field is inferred from the value of the
+ Len field as follows:
+
+ | Len value | Extended Length size | Total length |
+ +------------+-----------------------+---------------------------+
+ | 0-12 | 0 | Len |
+ | 13 | 1 | Extended Length + 13 |
+ | 14 | 2 | Extended Length + 269 |
+ | 15 | 4 | Extended Length + 65805 |
+ */
+
+ if len(m.Token) > message.MaxTokenSize {
+ return -1, message.ErrInvalidTokenLen
+ }
+
+ payloadLen := len(m.Payload)
+ if payloadLen > 0 {
+ // for separator 0xff
+ payloadLen++
+ }
+ optionsLen, err := m.Options.Marshal(nil)
+ if !errors.Is(err, message.ErrTooSmall) {
+ return -1, err
+ }
+ bufLen := payloadLen + optionsLen
+ lenNib, extLenBytes := getHeader(bufLen)
+
+ var hdr [1 + 4 + message.MaxTokenSize + 1]byte
+ hdrLen := 1 + len(extLenBytes) + len(m.Token) + 1
+ hdrOff := 0
+
+ copyToHdr := func(offset int, data []byte) int {
+ if len(data) > 0 {
+ copy(hdr[hdrOff:hdrOff+len(data)], data)
+ offset += len(data)
+ }
+ return offset
+ }
+
+ // Length and TKL nibbles.
+ hdr[hdrOff] = uint8(0xf&len(m.Token)) | (lenNib << 4)
+ hdrOff++
+
+ // Extended length, if present.
+ hdrOff = copyToHdr(hdrOff, extLenBytes)
+
+ // Code.
+ hdr[hdrOff] = byte(m.Code)
+ hdrOff++
+
+ // Token.
+ copyToHdr(hdrOff, m.Token)
+
+ bufLen += hdrLen
+ if len(buf) < bufLen {
+ return bufLen, message.ErrTooSmall
+ }
+
+ copy(buf, hdr[:hdrLen])
+ optionsLen, err = m.Options.Marshal(buf[hdrLen:])
+ switch {
+ case err == nil:
+ case errors.Is(err, message.ErrTooSmall):
+ return bufLen, err
+ default:
+ return -1, err
+ }
+ if len(m.Payload) > 0 {
+ copy(buf[hdrLen+optionsLen:], []byte{0xff})
+ copy(buf[hdrLen+optionsLen+1:], m.Payload)
+ }
+
+ return bufLen, nil
+}
+
+func (c *Coder) DecodeHeader(data []byte, h *MessageHeader) (int, error) {
+ hdrOff := uint32(0)
+ if len(data) == 0 {
+ return -1, message.ErrShortRead
+ }
+
+ firstByte := data[0]
+ data = data[1:]
+ hdrOff++
+
+ lenNib := (firstByte & 0xf0) >> 4
+ tkl := firstByte & 0x0f
+
+ var opLen int
+ switch {
+ case lenNib < MessageLength13Base:
+ opLen = int(lenNib)
+ case lenNib == 13:
+ if len(data) < 1 {
+ return -1, message.ErrShortRead
+ }
+ extLen := data[0]
+ data = data[1:]
+ hdrOff++
+ opLen = MessageLength13Base + int(extLen)
+ case lenNib == 14:
+ if len(data) < 2 {
+ return -1, message.ErrShortRead
+ }
+ extLen := binary.BigEndian.Uint16(data)
+ data = data[2:]
+ hdrOff += 2
+ opLen = MessageLength14Base + int(extLen)
+ case lenNib == 15:
+ if len(data) < 4 {
+ return -1, message.ErrShortRead
+ }
+ extLen := binary.BigEndian.Uint32(data)
+ data = data[4:]
+ hdrOff += 4
+ opLen = MessageLength15Base + int(extLen)
+ }
+
+ h.MessageLength = hdrOff + 1 + uint32(tkl) + uint32(opLen)
+ if len(data) < 1 {
+ return -1, message.ErrShortRead
+ }
+ h.Code = codes.Code(data[0])
+ data = data[1:]
+ hdrOff++
+ if len(data) < int(tkl) {
+ return -1, message.ErrShortRead
+ }
+ if tkl > 0 {
+ h.Token = data[:tkl]
+ }
+ hdrOff += uint32(tkl)
+ h.Length = hdrOff
+ return int(h.Length), nil
+}
+
+func (c *Coder) DecodeWithHeader(data []byte, header MessageHeader, m *message.Message) (int, error) {
+ optionDefs := message.CoapOptionDefs
+ processed := header.Length
+ switch header.Code {
+ case codes.CSM:
+ optionDefs = message.TCPSignalCSMOptionDefs
+ case codes.Ping, codes.Pong:
+ optionDefs = message.TCPSignalPingPongOptionDefs
+ case codes.Release:
+ optionDefs = message.TCPSignalReleaseOptionDefs
+ case codes.Abort:
+ optionDefs = message.TCPSignalAbortOptionDefs
+ }
+
+ proc, err := m.Options.Unmarshal(data, optionDefs)
+ if err != nil {
+ return -1, err
+ }
+ data = data[proc:]
+ processed += uint32(proc)
+
+ if len(data) > 0 {
+ m.Payload = data
+ }
+ processed += uint32(len(data))
+ m.Code = header.Code
+ m.Token = header.Token
+
+ return int(processed), nil
+}
+
+func (c *Coder) Decode(data []byte, m *message.Message) (int, error) {
+ var header MessageHeader
+ _, err := c.DecodeHeader(data, &header)
+ if err != nil {
+ return -1, err
+ }
+ if uint32(len(data)) < header.MessageLength {
+ return -1, message.ErrShortRead
+ }
+ return c.DecodeWithHeader(data[header.Length:], header, m)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/message/error.go b/vendor/github.com/plgd-dev/go-coap/v3/tcp/coder/error.go
similarity index 90%
rename from vendor/github.com/plgd-dev/go-coap/v2/udp/message/error.go
rename to vendor/github.com/plgd-dev/go-coap/v3/tcp/coder/error.go
index 9f550aa..ac7ae99 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/message/error.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/tcp/coder/error.go
@@ -1,4 +1,4 @@
-package message
+package coder
import "errors"
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/tcp/server/config.go b/vendor/github.com/plgd-dev/go-coap/v3/tcp/server/config.go
new file mode 100644
index 0000000..6147ec3
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/tcp/server/config.go
@@ -0,0 +1,62 @@
+package server
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/options/config"
+ "github.com/plgd-dev/go-coap/v3/tcp/client"
+)
+
+// The HandlerFunc type is an adapter to allow the use of
+// ordinary functions as COAP handlers.
+type HandlerFunc = func(*responsewriter.ResponseWriter[*client.Conn], *pool.Message)
+
+type ErrorFunc = func(error)
+
+type GoPoolFunc = func(func()) error
+
+// OnNewConnFunc is the callback for new connections.
+type OnNewConnFunc = func(cc *client.Conn)
+
+var DefaultConfig = func() Config {
+ opts := Config{
+ Common: config.NewCommon[*client.Conn](),
+ CreateInactivityMonitor: func() client.InactivityMonitor {
+ maxRetries := uint32(2)
+ timeout := time.Second * 16
+ onInactive := func(cc *client.Conn) {
+ _ = cc.Close()
+ }
+ keepalive := inactivity.NewKeepAlive(maxRetries, onInactive, func(cc *client.Conn, receivePong func()) (func(), error) {
+ return cc.AsyncPing(receivePong)
+ })
+ return inactivity.New(timeout/time.Duration(maxRetries+1), keepalive.OnInactive)
+ },
+ OnNewConn: func(cc *client.Conn) {
+ // do nothing by default
+ },
+ ConnectionCacheSize: 2 * 1024,
+ }
+ opts.Handler = func(w *responsewriter.ResponseWriter[*client.Conn], r *pool.Message) {
+ if err := w.SetResponse(codes.NotFound, message.TextPlain, nil); err != nil {
+ opts.Errors(fmt.Errorf("server handler: cannot set response: %w", err))
+ }
+ }
+ return opts
+}()
+
+type Config struct {
+ config.Common[*client.Conn]
+ CreateInactivityMonitor client.CreateInactivityMonitorFunc
+ Handler HandlerFunc
+ OnNewConn OnNewConnFunc
+ ConnectionCacheSize uint16
+ DisablePeerTCPSignalMessageCSMs bool
+ DisableTCPSignalMessageCSM bool
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/tcp/server/server.go b/vendor/github.com/plgd-dev/go-coap/v3/tcp/server/server.go
new file mode 100644
index 0000000..a869e29
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/tcp/server/server.go
@@ -0,0 +1,223 @@
+package server
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net"
+ "sync"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ coapNet "github.com/plgd-dev/go-coap/v3/net"
+ "github.com/plgd-dev/go-coap/v3/net/blockwise"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/pkg/connections"
+ "github.com/plgd-dev/go-coap/v3/tcp/client"
+)
+
+// A Option sets options such as credentials, codec and keepalive parameters, etc.
+type Option interface {
+ TCPServerApply(cfg *Config)
+}
+
+// Listener defined used by coap
+type Listener interface {
+ Close() error
+ AcceptWithContext(ctx context.Context) (net.Conn, error)
+}
+
+type Server struct {
+ listenMutex sync.Mutex
+ listen Listener
+ ctx context.Context
+ cancel context.CancelFunc
+ cfg *Config
+}
+
+func New(opt ...Option) *Server {
+ cfg := DefaultConfig
+ for _, o := range opt {
+ o.TCPServerApply(&cfg)
+ }
+
+ ctx, cancel := context.WithCancel(cfg.Ctx)
+
+ if cfg.CreateInactivityMonitor == nil {
+ cfg.CreateInactivityMonitor = func() client.InactivityMonitor {
+ return inactivity.NewNilMonitor[*client.Conn]()
+ }
+ }
+ if cfg.MessagePool == nil {
+ cfg.MessagePool = pool.New(0, 0)
+ }
+
+ if cfg.Errors == nil {
+ cfg.Errors = func(error) {
+ // default no-op
+ }
+ }
+ if cfg.GetToken == nil {
+ cfg.GetToken = message.GetToken
+ }
+ errorsFunc := cfg.Errors
+ // assign updated func to opts.errors so opts.handler also uses the updated error handler
+ cfg.Errors = func(err error) {
+ if coapNet.IsCancelOrCloseError(err) {
+ // this error was produced by cancellation context or closing connection.
+ return
+ }
+ errorsFunc(fmt.Errorf("tcp: %w", err))
+ }
+
+ return &Server{
+ ctx: ctx,
+ cancel: cancel,
+ cfg: &cfg,
+ }
+}
+
+func (s *Server) checkAndSetListener(l Listener) error {
+ s.listenMutex.Lock()
+ defer s.listenMutex.Unlock()
+ if s.listen != nil {
+ return fmt.Errorf("server already serves listener")
+ }
+ s.listen = l
+ 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
+ }
+ switch {
+ case errors.Is(err, coapNet.ErrListenerIsClosed):
+ s.Stop()
+ return false
+ case errors.Is(err, context.DeadlineExceeded), errors.Is(err, context.Canceled):
+ select {
+ case <-s.ctx.Done():
+ default:
+ s.cfg.Errors(fmt.Errorf("cannot accept connection: %w", err))
+ return true
+ }
+ return false
+ default:
+ return true
+ }
+}
+
+func (s *Server) serveConnection(connections *connections.Connections, rw net.Conn) {
+ var cc *client.Conn
+ monitor := s.cfg.CreateInactivityMonitor()
+ cc = s.createConn(coapNet.NewConn(rw), monitor)
+ if s.cfg.OnNewConn != nil {
+ s.cfg.OnNewConn(cc)
+ }
+ connections.Store(cc)
+ defer connections.Delete(cc)
+
+ if err := cc.Run(); err != nil {
+ s.cfg.Errors(fmt.Errorf("%v: %w", cc.RemoteAddr(), err))
+ }
+}
+
+func (s *Server) Serve(l Listener) error {
+ if s.cfg.BlockwiseSZX > blockwise.SZXBERT {
+ return fmt.Errorf("invalid blockwiseSZX")
+ }
+
+ err := s.checkAndSetListener(l)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ s.Stop()
+ }()
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ connections := connections.New()
+ s.cfg.PeriodicRunner(func(now time.Time) bool {
+ connections.CheckExpirations(now)
+ return s.ctx.Err() == nil
+ })
+ defer connections.Close()
+
+ for {
+ rw, err := l.AcceptWithContext(s.ctx)
+ if ok := s.checkAcceptError(err); !ok {
+ return nil
+ }
+ if rw == nil {
+ continue
+ }
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ s.serveConnection(connections, rw)
+ }()
+ }
+}
+
+// Stop stops server without wait of ends Serve function.
+func (s *Server) Stop() {
+ s.cancel()
+ l := s.popListener()
+ if l == nil {
+ return
+ }
+ if err := l.Close(); err != nil {
+ s.cfg.Errors(fmt.Errorf("cannot close listener: %w", err))
+ }
+}
+
+func (s *Server) createConn(connection *coapNet.Conn, monitor client.InactivityMonitor) *client.Conn {
+ createBlockWise := func(cc *client.Conn) *blockwise.BlockWise[*client.Conn] {
+ return nil
+ }
+ if s.cfg.BlockwiseEnable {
+ createBlockWise = func(cc *client.Conn) *blockwise.BlockWise[*client.Conn] {
+ return blockwise.New(
+ cc,
+ s.cfg.BlockwiseTransferTimeout,
+ s.cfg.Errors,
+ func(token message.Token) (*pool.Message, bool) {
+ return nil, false
+ },
+ )
+ }
+ }
+ cfg := client.DefaultConfig
+ cfg.Ctx = s.ctx
+ cfg.Handler = s.cfg.Handler
+ cfg.MaxMessageSize = s.cfg.MaxMessageSize
+ cfg.Errors = s.cfg.Errors
+ cfg.BlockwiseSZX = s.cfg.BlockwiseSZX
+ cfg.DisablePeerTCPSignalMessageCSMs = s.cfg.DisablePeerTCPSignalMessageCSMs
+ cfg.DisableTCPSignalMessageCSM = s.cfg.DisableTCPSignalMessageCSM
+ cfg.CloseSocket = true
+ cfg.ConnectionCacheSize = s.cfg.ConnectionCacheSize
+ cfg.MessagePool = s.cfg.MessagePool
+ cfg.GetToken = s.cfg.GetToken
+ cfg.ProcessReceivedMessage = s.cfg.ProcessReceivedMessage
+ cfg.ReceivedMessageQueueSize = s.cfg.ReceivedMessageQueueSize
+ cc := client.NewConn(
+ connection,
+ createBlockWise,
+ monitor,
+ &cfg,
+ )
+
+ return cc
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/udp/client.go b/vendor/github.com/plgd-dev/go-coap/v3/udp/client.go
new file mode 100644
index 0000000..26e7a01
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/udp/client.go
@@ -0,0 +1,116 @@
+package udp
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ coapNet "github.com/plgd-dev/go-coap/v3/net"
+ "github.com/plgd-dev/go-coap/v3/net/blockwise"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/options"
+ "github.com/plgd-dev/go-coap/v3/udp/client"
+ "github.com/plgd-dev/go-coap/v3/udp/server"
+)
+
+// A Option sets options such as credentials, keepalive parameters, etc.
+type Option interface {
+ UDPClientApply(cfg *client.Config)
+}
+
+// Dial creates a client connection to the given target.
+func Dial(target string, opts ...Option) (*client.Conn, error) {
+ cfg := client.DefaultConfig
+ for _, o := range opts {
+ o.UDPClientApply(&cfg)
+ }
+ c, err := cfg.Dialer.DialContext(cfg.Ctx, cfg.Net, target)
+ if err != nil {
+ return nil, err
+ }
+ conn, ok := c.(*net.UDPConn)
+ if !ok {
+ return nil, fmt.Errorf("unsupported connection type: %T", c)
+ }
+ opts = append(opts, options.WithCloseSocket())
+ return Client(conn, opts...), nil
+}
+
+// Client creates client over udp connection.
+func Client(conn *net.UDPConn, opts ...Option) *client.Conn {
+ cfg := client.DefaultConfig
+ for _, o := range opts {
+ o.UDPClientApply(&cfg)
+ }
+ if cfg.Errors == nil {
+ cfg.Errors = func(error) {
+ // default no-op
+ }
+ }
+ if cfg.CreateInactivityMonitor == nil {
+ cfg.CreateInactivityMonitor = func() client.InactivityMonitor {
+ return inactivity.NewNilMonitor[*client.Conn]()
+ }
+ }
+ if cfg.MessagePool == nil {
+ cfg.MessagePool = pool.New(0, 0)
+ }
+
+ errorsFunc := cfg.Errors
+ cfg.Errors = func(err error) {
+ if coapNet.IsCancelOrCloseError(err) {
+ // this error was produced by cancellation context or closing connection.
+ return
+ }
+ errorsFunc(fmt.Errorf("udp: %v: %w", conn.RemoteAddr(), err))
+ }
+ addr, _ := conn.RemoteAddr().(*net.UDPAddr)
+ createBlockWise := func(cc *client.Conn) *blockwise.BlockWise[*client.Conn] {
+ return nil
+ }
+ if cfg.BlockwiseEnable {
+ createBlockWise = func(cc *client.Conn) *blockwise.BlockWise[*client.Conn] {
+ v := cc
+ return blockwise.New(
+ v,
+ cfg.BlockwiseTransferTimeout,
+ cfg.Errors,
+ func(token message.Token) (*pool.Message, bool) {
+ return v.GetObservationRequest(token)
+ },
+ )
+ }
+ }
+
+ monitor := cfg.CreateInactivityMonitor()
+ l := coapNet.NewUDPConn(cfg.Net, conn, coapNet.WithErrors(cfg.Errors))
+ session := server.NewSession(cfg.Ctx,
+ context.Background(),
+ l,
+ addr,
+ cfg.MaxMessageSize,
+ cfg.MTU,
+ cfg.CloseSocket,
+ )
+ cc := client.NewConn(session,
+ createBlockWise,
+ monitor,
+ &cfg,
+ )
+ cfg.PeriodicRunner(func(now time.Time) bool {
+ cc.CheckExpirations(now)
+ return cc.Context().Err() == nil
+ })
+
+ go func() {
+ err := cc.Run()
+ if err != nil {
+ cfg.Errors(err)
+ }
+ }()
+
+ return cc
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/udp/client/config.go b/vendor/github.com/plgd-dev/go-coap/v3/udp/client/config.go
new file mode 100644
index 0000000..2b719f8
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/udp/client/config.go
@@ -0,0 +1,55 @@
+package client
+
+import (
+ "fmt"
+ "net"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/options/config"
+)
+
+const DefaultMTU = 1472
+
+var DefaultConfig = func() Config {
+ opts := Config{
+ Common: config.NewCommon[*Conn](),
+ CreateInactivityMonitor: func() InactivityMonitor {
+ return inactivity.NewNilMonitor[*Conn]()
+ },
+ Dialer: &net.Dialer{Timeout: time.Second * 3},
+ Net: "udp",
+ TransmissionNStart: 1,
+ TransmissionAcknowledgeTimeout: time.Second * 2,
+ TransmissionMaxRetransmit: 4,
+ GetMID: message.GetMID,
+ MTU: DefaultMTU,
+ }
+ opts.Handler = func(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ switch r.Code() {
+ case codes.POST, codes.PUT, codes.GET, codes.DELETE:
+ if err := w.SetResponse(codes.NotFound, message.TextPlain, nil); err != nil {
+ opts.Errors(fmt.Errorf("udp client: cannot set response: %w", err))
+ }
+ }
+ }
+ return opts
+}()
+
+type Config struct {
+ config.Common[*Conn]
+ CreateInactivityMonitor CreateInactivityMonitorFunc
+ Net string
+ GetMID GetMIDFunc
+ Handler HandlerFunc
+ Dialer *net.Dialer
+ TransmissionNStart uint32
+ TransmissionAcknowledgeTimeout time.Duration
+ TransmissionMaxRetransmit uint32
+ CloseSocket bool
+ MTU uint16
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/udp/client/conn.go b/vendor/github.com/plgd-dev/go-coap/v3/udp/client/conn.go
new file mode 100644
index 0000000..8e20d87
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/udp/client/conn.go
@@ -0,0 +1,888 @@
+package client
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "math"
+ "net"
+ "sync"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ coapNet "github.com/plgd-dev/go-coap/v3/net"
+ "github.com/plgd-dev/go-coap/v3/net/blockwise"
+ "github.com/plgd-dev/go-coap/v3/net/client"
+ limitparallelrequests "github.com/plgd-dev/go-coap/v3/net/client/limitParallelRequests"
+ "github.com/plgd-dev/go-coap/v3/net/observation"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/options/config"
+ "github.com/plgd-dev/go-coap/v3/pkg/cache"
+ coapErrors "github.com/plgd-dev/go-coap/v3/pkg/errors"
+ "github.com/plgd-dev/go-coap/v3/pkg/fn"
+ coapSync "github.com/plgd-dev/go-coap/v3/pkg/sync"
+ "github.com/plgd-dev/go-coap/v3/udp/coder"
+ "go.uber.org/atomic"
+ "golang.org/x/sync/semaphore"
+)
+
+// https://datatracker.ietf.org/doc/html/rfc7252#section-4.8.2
+const ExchangeLifetime = 247 * time.Second
+
+type (
+ HandlerFunc = func(*responsewriter.ResponseWriter[*Conn], *pool.Message)
+ ErrorFunc = func(error)
+ EventFunc = func()
+ GetMIDFunc = func() int32
+ CreateInactivityMonitorFunc = func() InactivityMonitor
+)
+
+type InactivityMonitor interface {
+ Notify()
+ CheckInactivity(now time.Time, cc *Conn)
+}
+
+type Session interface {
+ Context() context.Context
+ Close() error
+ MaxMessageSize() uint32
+ RemoteAddr() net.Addr
+ LocalAddr() net.Addr
+ // NetConn returns the underlying connection that is wrapped by Session. The Conn returned is shared by all invocations of NetConn, so do not modify it.
+ NetConn() net.Conn
+ WriteMessage(req *pool.Message) error
+ // WriteMulticast sends multicast to the remote multicast address.
+ // By default it is sent over all network interfaces and all compatible source IP addresses with hop limit 1.
+ // Via opts you can specify the network interface, source IP address, and hop limit.
+ WriteMulticastMessage(req *pool.Message, address *net.UDPAddr, opts ...coapNet.MulticastOption) error
+ Run(cc *Conn) error
+ AddOnClose(f EventFunc)
+ SetContextValue(key interface{}, val interface{})
+ Done() <-chan struct{}
+}
+
+type RequestsMap = coapSync.Map[uint64, *pool.Message]
+
+const (
+ errFmtWriteRequest = "cannot write request: %w"
+ errFmtWriteResponse = "cannot write response: %w"
+)
+
+type midElement struct {
+ handler HandlerFunc
+ start time.Time
+ deadline time.Time
+ retransmit atomic.Int32
+
+ private struct {
+ sync.Mutex
+ msg *pool.Message
+ }
+}
+
+func (m *midElement) ReleaseMessage(cc *Conn) {
+ m.private.Lock()
+ defer m.private.Unlock()
+ if m.private.msg != nil {
+ cc.ReleaseMessage(m.private.msg)
+ m.private.msg = nil
+ }
+}
+
+func (m *midElement) IsExpired(now time.Time, maxRetransmit int32) bool {
+ if !m.deadline.IsZero() && now.After(m.deadline) {
+ // remove element if deadline is exceeded
+ return true
+ }
+ retransmit := m.retransmit.Load()
+ return retransmit >= maxRetransmit
+}
+
+func (m *midElement) Retransmit(now time.Time, acknowledgeTimeout time.Duration) bool {
+ if now.After(m.start.Add(acknowledgeTimeout * time.Duration(m.retransmit.Load()+1))) {
+ m.retransmit.Inc()
+ // retransmit
+ return true
+ }
+ // wait for next retransmit
+ return false
+}
+
+func (m *midElement) GetMessage(cc *Conn) (*pool.Message, bool, error) {
+ m.private.Lock()
+ defer m.private.Unlock()
+ if m.private.msg == nil {
+ return nil, false, nil
+ }
+ msg := cc.AcquireMessage(m.private.msg.Context())
+ if err := m.private.msg.Clone(msg); err != nil {
+ cc.ReleaseMessage(msg)
+ return nil, false, err
+ }
+ return msg, true, nil
+}
+
+// Conn represents a virtual connection to a conceptual endpoint, to perform COAPs commands.
+type Conn struct {
+ // This field needs to be the first in the struct to ensure proper word alignment on 32-bit platforms.
+ // See: https://golang.org/pkg/sync/atomic/#pkg-note-BUG
+ sequence atomic.Uint64
+
+ session Session
+ *client.Client[*Conn]
+ inactivityMonitor InactivityMonitor
+
+ blockWise *blockwise.BlockWise[*Conn]
+ observationHandler *observation.Handler[*Conn]
+ transmission *Transmission
+ messagePool *pool.Pool
+
+ processReceivedMessage config.ProcessReceivedMessageFunc[*Conn]
+ errors ErrorFunc
+ responseMsgCache *cache.Cache[string, []byte]
+ msgIDMutex *MutexMap
+
+ tokenHandlerContainer *coapSync.Map[uint64, HandlerFunc]
+ midHandlerContainer *coapSync.Map[int32, *midElement]
+ msgID atomic.Uint32
+ blockwiseSZX blockwise.SZX
+
+ /*
+ An outstanding interaction is either a CON for which an ACK has not
+ yet been received but is still expected (message layer) or a request
+ for which neither a response nor an Acknowledgment message has yet
+ been received but is still expected (which may both occur at the same
+ time, counting as one outstanding interaction).
+ */
+ numOutstandingInteraction *semaphore.Weighted
+ receivedMessageReader *client.ReceivedMessageReader[*Conn]
+}
+
+// Transmission is a threadsafe container for transmission related parameters
+type Transmission struct {
+ nStart *atomic.Uint32
+ acknowledgeTimeout *atomic.Duration
+ maxRetransmit *atomic.Int32
+}
+
+// SetTransmissionNStart changing the nStart value will only effect requests queued after the change. The requests waiting here already before the change will get unblocked when enough weight has been released.
+func (t *Transmission) SetTransmissionNStart(d uint32) {
+ t.nStart.Store(d)
+}
+
+func (t *Transmission) SetTransmissionAcknowledgeTimeout(d time.Duration) {
+ t.acknowledgeTimeout.Store(d)
+}
+
+func (t *Transmission) SetTransmissionMaxRetransmit(d int32) {
+ t.maxRetransmit.Store(d)
+}
+
+func (cc *Conn) Transmission() *Transmission {
+ return cc.transmission
+}
+
+// NewConn creates connection over session and observation.
+func NewConn(
+ session Session,
+ createBlockWise func(cc *Conn) *blockwise.BlockWise[*Conn],
+ inactivityMonitor InactivityMonitor,
+ cfg *Config,
+) *Conn {
+ if cfg.Errors == nil {
+ cfg.Errors = func(error) {
+ // default no-op
+ }
+ }
+ if cfg.GetMID == nil {
+ cfg.GetMID = message.GetMID
+ }
+ if cfg.GetToken == nil {
+ cfg.GetToken = message.GetToken
+ }
+ if cfg.ReceivedMessageQueueSize < 0 {
+ cfg.ReceivedMessageQueueSize = 0
+ }
+
+ cc := Conn{
+ session: session,
+ transmission: &Transmission{
+ atomic.NewUint32(cfg.TransmissionNStart),
+ atomic.NewDuration(cfg.TransmissionAcknowledgeTimeout),
+ atomic.NewInt32(int32(cfg.TransmissionMaxRetransmit)),
+ },
+ blockwiseSZX: cfg.BlockwiseSZX,
+
+ tokenHandlerContainer: coapSync.NewMap[uint64, HandlerFunc](),
+ midHandlerContainer: coapSync.NewMap[int32, *midElement](),
+ processReceivedMessage: cfg.ProcessReceivedMessage,
+ errors: cfg.Errors,
+ msgIDMutex: NewMutexMap(),
+ responseMsgCache: cache.NewCache[string, []byte](),
+ inactivityMonitor: inactivityMonitor,
+ messagePool: cfg.MessagePool,
+ numOutstandingInteraction: semaphore.NewWeighted(math.MaxInt64),
+ }
+ cc.msgID.Store(uint32(cfg.GetMID() - 0xffff/2))
+ cc.blockWise = createBlockWise(&cc)
+ limitParallelRequests := limitparallelrequests.New(cfg.LimitClientParallelRequests, cfg.LimitClientEndpointParallelRequests, cc.do, cc.doObserve)
+ cc.observationHandler = observation.NewHandler(&cc, cfg.Handler, limitParallelRequests.Do)
+ cc.Client = client.New(&cc, cc.observationHandler, cfg.GetToken, limitParallelRequests)
+ if cc.processReceivedMessage == nil {
+ cc.processReceivedMessage = processReceivedMessage
+ }
+ cc.receivedMessageReader = client.NewReceivedMessageReader(&cc, cfg.ReceivedMessageQueueSize)
+ return &cc
+}
+
+func processReceivedMessage(req *pool.Message, cc *Conn, handler config.HandlerFunc[*Conn]) {
+ cc.ProcessReceivedMessageWithHandler(req, handler)
+}
+
+func (cc *Conn) ProcessReceivedMessage(req *pool.Message) {
+ cc.processReceivedMessage(req, cc, cc.handleReq)
+}
+
+func (cc *Conn) Session() Session {
+ return cc.session
+}
+
+func (cc *Conn) GetMessageID() int32 {
+ // To prevent collisions during reconnections, it is important to always increment the global counter.
+ // For example, if a connection (cc) is established and later closed due to inactivity, a new cc may
+ // be created shortly after. However, if the new cc is initialized with the same message ID as the
+ // previous one, the receiver may mistakenly treat the incoming message as a duplicate and discard it.
+ // Hence, by incrementing the global counter, we can ensure unique message IDs and avoid such issues.
+ message.GetMID()
+ return int32(uint16(cc.msgID.Inc()))
+}
+
+// Close closes connection without waiting for the end of the Run function.
+func (cc *Conn) Close() error {
+ err := cc.session.Close()
+ if errors.Is(err, net.ErrClosed) {
+ return nil
+ }
+ return err
+}
+
+func (cc *Conn) doInternal(req *pool.Message) (*pool.Message, error) {
+ token := req.Token()
+ if token == nil {
+ return nil, fmt.Errorf("invalid token")
+ }
+
+ respChan := make(chan *pool.Message, 1)
+ if _, loaded := cc.tokenHandlerContainer.LoadOrStore(token.Hash(), func(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ r.Hijack()
+ select {
+ case respChan <- r:
+ default:
+ }
+ }); loaded {
+ return nil, fmt.Errorf("cannot add token(%v) handler: %w", token, coapErrors.ErrKeyAlreadyExists)
+ }
+ defer func() {
+ _, _ = cc.tokenHandlerContainer.LoadAndDelete(token.Hash())
+ }()
+ err := cc.writeMessage(req)
+ if err != nil {
+ return nil, fmt.Errorf(errFmtWriteRequest, err)
+ }
+ cc.receivedMessageReader.TryToReplaceLoop()
+ select {
+ case <-req.Context().Done():
+ return nil, req.Context().Err()
+ case <-cc.Context().Done():
+ return nil, fmt.Errorf("connection was closed: %w", cc.session.Context().Err())
+ case resp := <-respChan:
+ return resp, nil
+ }
+}
+
+// Do sends an coap message and returns an coap response.
+//
+// An error is returned if by failure to speak COAP (such as a network connectivity problem).
+// Any status code doesn't cause an error.
+//
+// Caller is responsible to release request and response.
+func (cc *Conn) do(req *pool.Message) (*pool.Message, error) {
+ if cc.blockWise == nil {
+ return cc.doInternal(req)
+ }
+ resp, err := cc.blockWise.Do(req, cc.blockwiseSZX, cc.session.MaxMessageSize(), func(bwReq *pool.Message) (*pool.Message, error) {
+ if bwReq.Options().HasOption(message.Block1) || bwReq.Options().HasOption(message.Block2) {
+ bwReq.SetMessageID(cc.GetMessageID())
+ }
+ return cc.doInternal(bwReq)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// DoObserve subscribes for every change with request.
+func (cc *Conn) doObserve(req *pool.Message, observeFunc func(req *pool.Message)) (client.Observation, error) {
+ return cc.observationHandler.NewObservation(req, observeFunc)
+}
+
+func (cc *Conn) releaseOutstandingInteraction() {
+ cc.numOutstandingInteraction.Release(1)
+}
+
+func (cc *Conn) acquireOutstandingInteraction(ctx context.Context) error {
+ nStart := cc.Transmission().nStart.Load()
+ if nStart == 0 {
+ return fmt.Errorf("invalid NStart value %v", nStart)
+ }
+ n := math.MaxInt64 - int64(cc.Transmission().nStart.Load()) + 1
+ err := cc.numOutstandingInteraction.Acquire(ctx, n)
+ if err != nil {
+ return err
+ }
+ cc.numOutstandingInteraction.Release(n - 1)
+ return nil
+}
+
+func (cc *Conn) waitForAcknowledge(req *pool.Message, waitForResponseChan chan struct{}) error {
+ cc.receivedMessageReader.TryToReplaceLoop()
+ select {
+ case <-waitForResponseChan:
+ return nil
+ case <-req.Context().Done():
+ return req.Context().Err()
+ case <-cc.Context().Done():
+ return fmt.Errorf("connection was closed: %w", cc.Context().Err())
+ }
+}
+
+func (cc *Conn) prepareWriteMessage(req *pool.Message, handler HandlerFunc) (func(), error) {
+ var closeFns fn.FuncList
+
+ // Only confirmable messages ever match an message ID
+ switch req.Type() {
+ case message.Confirmable:
+ msg := cc.AcquireMessage(req.Context())
+ if err := req.Clone(msg); err != nil {
+ cc.ReleaseMessage(msg)
+ return nil, fmt.Errorf("cannot clone message: %w", err)
+ }
+ if req.Code() >= codes.GET && req.Code() <= codes.DELETE {
+ if err := cc.acquireOutstandingInteraction(req.Context()); err != nil {
+ return nil, err
+ }
+ closeFns = append(closeFns, func() {
+ cc.releaseOutstandingInteraction()
+ })
+ }
+ deadline, _ := req.Context().Deadline()
+ if _, loaded := cc.midHandlerContainer.LoadOrStore(req.MessageID(), &midElement{
+ handler: handler,
+ start: time.Now(),
+ deadline: deadline,
+ private: struct {
+ sync.Mutex
+ msg *pool.Message
+ }{msg: msg},
+ }); loaded {
+ closeFns.Execute()
+ return nil, fmt.Errorf("cannot insert mid(%v) handler: %w", req.MessageID(), coapErrors.ErrKeyAlreadyExists)
+ }
+ closeFns = append(closeFns, func() {
+ _, _ = cc.midHandlerContainer.LoadAndDelete(req.MessageID())
+ })
+ case message.NonConfirmable:
+ /* TODO need to acquireOutstandingInteraction
+ if req.Code() >= codes.GET && req.Code() <= codes.DELETE {
+ }
+ */
+ }
+ return closeFns.ToFunction(), nil
+}
+
+func (cc *Conn) writeMessageAsync(req *pool.Message) error {
+ req.UpsertType(message.Confirmable)
+ req.UpsertMessageID(cc.GetMessageID())
+ closeFn, err := cc.prepareWriteMessage(req, func(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ // do nothing
+ })
+ if err != nil {
+ return err
+ }
+ defer closeFn()
+ if err := cc.session.WriteMessage(req); err != nil {
+ return fmt.Errorf(errFmtWriteRequest, err)
+ }
+ return nil
+}
+
+func (cc *Conn) writeMessage(req *pool.Message) error {
+ req.UpsertType(message.Confirmable)
+ req.UpsertMessageID(cc.GetMessageID())
+ if req.Type() != message.Confirmable {
+ return cc.writeMessageAsync(req)
+ }
+ respChan := make(chan struct{})
+ closeFn, err := cc.prepareWriteMessage(req, func(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ close(respChan)
+ })
+ if err != nil {
+ return err
+ }
+ defer closeFn()
+ if err := cc.session.WriteMessage(req); err != nil {
+ return fmt.Errorf(errFmtWriteRequest, err)
+ }
+ if err := cc.waitForAcknowledge(req, respChan); err != nil {
+ return fmt.Errorf(errFmtWriteRequest, err)
+ }
+ return nil
+}
+
+// WriteMessage sends an coap message.
+func (cc *Conn) WriteMessage(req *pool.Message) error {
+ if cc.blockWise == nil {
+ return cc.writeMessage(req)
+ }
+ return cc.blockWise.WriteMessage(req, cc.blockwiseSZX, cc.session.MaxMessageSize(), func(bwReq *pool.Message) error {
+ if bwReq.Options().HasOption(message.Block1) || bwReq.Options().HasOption(message.Block2) {
+ bwReq.SetMessageID(cc.GetMessageID())
+ }
+ return cc.writeMessage(bwReq)
+ })
+}
+
+// Context returns the client's context.
+//
+// If connections was closed context is cancelled.
+func (cc *Conn) Context() context.Context {
+ return cc.session.Context()
+}
+
+// AsyncPing sends ping and receivedPong will be called when pong arrives. It returns cancellation of ping operation.
+func (cc *Conn) AsyncPing(receivedPong func()) (func(), error) {
+ req := cc.AcquireMessage(cc.Context())
+ req.SetType(message.Confirmable)
+ req.SetCode(codes.Empty)
+ mid := cc.GetMessageID()
+ req.SetMessageID(mid)
+ if _, loaded := cc.midHandlerContainer.LoadOrStore(mid, &midElement{
+ handler: func(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ if r.Type() == message.Reset || r.Type() == message.Acknowledgement {
+ receivedPong()
+ }
+ },
+ start: time.Now(),
+ deadline: time.Time{}, // no deadline
+ private: struct {
+ sync.Mutex
+ msg *pool.Message
+ }{msg: req},
+ }); loaded {
+ return nil, fmt.Errorf("cannot insert mid(%v) handler: %w", mid, coapErrors.ErrKeyAlreadyExists)
+ }
+ removeMidHandler := func() {
+ if elem, ok := cc.midHandlerContainer.LoadAndDelete(mid); ok {
+ elem.ReleaseMessage(cc)
+ }
+ }
+ if err := cc.session.WriteMessage(req); err != nil {
+ removeMidHandler()
+ return nil, fmt.Errorf(errFmtWriteRequest, err)
+ }
+ return removeMidHandler, nil
+}
+
+// Run reads and process requests from a connection, until the connection is closed.
+func (cc *Conn) Run() error {
+ return cc.session.Run(cc)
+}
+
+// AddOnClose calls function on close connection event.
+func (cc *Conn) AddOnClose(f EventFunc) {
+ cc.session.AddOnClose(f)
+}
+
+func (cc *Conn) RemoteAddr() net.Addr {
+ return cc.session.RemoteAddr()
+}
+
+func (cc *Conn) LocalAddr() net.Addr {
+ return cc.session.LocalAddr()
+}
+
+func (cc *Conn) sendPong(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ if err := w.SetResponse(codes.Empty, message.TextPlain, nil); err != nil {
+ cc.errors(fmt.Errorf("cannot send pong response: %w", err))
+ }
+ if r.Type() == message.Confirmable {
+ w.Message().SetType(message.Acknowledgement)
+ w.Message().SetMessageID(r.MessageID())
+ } else {
+ if w.Message().Type() != message.Reset {
+ w.Message().SetType(message.NonConfirmable)
+ }
+ w.Message().SetMessageID(cc.GetMessageID())
+ }
+}
+
+func (cc *Conn) handle(w *responsewriter.ResponseWriter[*Conn], m *pool.Message) {
+ if m.IsSeparateMessage() {
+ // msg was processed by token handler - just drop it.
+ return
+ }
+ if cc.blockWise != nil {
+ cc.blockWise.Handle(w, m, cc.blockwiseSZX, cc.session.MaxMessageSize(), func(rw *responsewriter.ResponseWriter[*Conn], rm *pool.Message) {
+ if h, ok := cc.tokenHandlerContainer.LoadAndDelete(rm.Token().Hash()); ok {
+ h(rw, rm)
+ return
+ }
+ cc.observationHandler.Handle(rw, rm)
+ })
+ return
+ }
+ if h, ok := cc.tokenHandlerContainer.LoadAndDelete(m.Token().Hash()); ok {
+ h(w, m)
+ return
+ }
+ cc.observationHandler.Handle(w, m)
+}
+
+// Sequence acquires sequence number.
+func (cc *Conn) Sequence() uint64 {
+ return cc.sequence.Add(1)
+}
+
+func (cc *Conn) responseMsgCacheID(msgID int32) string {
+ return fmt.Sprintf("resp-%v-%d", cc.RemoteAddr(), msgID)
+}
+
+func (cc *Conn) addResponseToCache(resp *pool.Message) error {
+ marshaledResp, err := resp.MarshalWithEncoder(coder.DefaultCoder)
+ if err != nil {
+ return err
+ }
+ cacheMsg := make([]byte, len(marshaledResp))
+ copy(cacheMsg, marshaledResp)
+ cc.responseMsgCache.LoadOrStore(cc.responseMsgCacheID(resp.MessageID()), cache.NewElement(cacheMsg, time.Now().Add(ExchangeLifetime), nil))
+ return nil
+}
+
+func (cc *Conn) getResponseFromCache(mid int32, resp *pool.Message) (bool, error) {
+ cachedResp := cc.responseMsgCache.Load(cc.responseMsgCacheID(mid))
+ if cachedResp == nil {
+ return false, nil
+ }
+ if rawMsg := cachedResp.Data(); len(rawMsg) > 0 {
+ _, err := resp.UnmarshalWithDecoder(coder.DefaultCoder, rawMsg)
+ if err != nil {
+ return false, err
+ }
+ return true, nil
+ }
+ return false, nil
+}
+
+// checkMyMessageID compare client msgID against peer messageID and if it is near < 0xffff/4 then incrase msgID.
+// When msgIDs met it can cause issue because cache can send message to which doesn't bellows to request.
+func (cc *Conn) checkMyMessageID(req *pool.Message) {
+ if req.Type() == message.Confirmable {
+ for {
+ oldID := cc.msgID.Load()
+ if uint16(req.MessageID())-uint16(cc.msgID.Load()) >= 0xffff/4 {
+ return
+ }
+ newID := oldID + 0xffff/2
+ if cc.msgID.CompareAndSwap(oldID, newID) {
+ break
+ }
+ }
+ }
+}
+
+func (cc *Conn) checkResponseCache(req *pool.Message, w *responsewriter.ResponseWriter[*Conn]) (bool, error) {
+ if req.Type() == message.Confirmable || req.Type() == message.NonConfirmable {
+ if ok, err := cc.getResponseFromCache(req.MessageID(), w.Message()); ok {
+ w.Message().SetMessageID(req.MessageID())
+ w.Message().SetType(message.NonConfirmable)
+ if req.Type() == message.Confirmable {
+ // req could be changed from NonConfirmation to confirmation message.
+ w.Message().SetType(message.Acknowledgement)
+ }
+ return true, nil
+ } else if err != nil {
+ return false, fmt.Errorf("cannot unmarshal response from cache: %w", err)
+ }
+ }
+ return false, nil
+}
+
+func isPongOrResetResponse(w *responsewriter.ResponseWriter[*Conn]) bool {
+ return w.Message().IsModified() && (w.Message().Type() == message.Reset || w.Message().Code() == codes.Empty)
+}
+
+func sendJustAcknowledgeMessage(reqType message.Type, w *responsewriter.ResponseWriter[*Conn]) bool {
+ return reqType == message.Confirmable && !w.Message().IsModified()
+}
+
+func (cc *Conn) processResponse(reqType message.Type, reqMessageID int32, w *responsewriter.ResponseWriter[*Conn]) error {
+ switch {
+ case isPongOrResetResponse(w):
+ if reqType == message.Confirmable {
+ w.Message().SetType(message.Acknowledgement)
+ w.Message().SetMessageID(reqMessageID)
+ } else {
+ if w.Message().Type() != message.Reset {
+ w.Message().SetType(message.NonConfirmable)
+ }
+ w.Message().SetMessageID(cc.GetMessageID())
+ }
+ return nil
+ case sendJustAcknowledgeMessage(reqType, w):
+ // send message to separate(confirm received) message, if response is not modified
+ w.Message().SetCode(codes.Empty)
+ w.Message().SetType(message.Acknowledgement)
+ w.Message().SetMessageID(reqMessageID)
+ w.Message().SetToken(nil)
+ err := cc.addResponseToCache(w.Message())
+ if err != nil {
+ return fmt.Errorf("cannot cache response: %w", err)
+ }
+ return nil
+ case !w.Message().IsModified():
+ // don't send response
+ return nil
+ }
+
+ // send piggybacked response
+ w.Message().SetType(message.Confirmable)
+ w.Message().SetMessageID(cc.GetMessageID())
+ if reqType == message.Confirmable {
+ w.Message().SetType(message.Acknowledgement)
+ w.Message().SetMessageID(reqMessageID)
+ }
+ if reqType == message.Confirmable || reqType == message.NonConfirmable {
+ err := cc.addResponseToCache(w.Message())
+ if err != nil {
+ return fmt.Errorf("cannot cache response: %w", err)
+ }
+ }
+ return nil
+}
+
+func (cc *Conn) handleReq(w *responsewriter.ResponseWriter[*Conn], req *pool.Message) {
+ defer cc.inactivityMonitor.Notify()
+ reqMid := req.MessageID()
+
+ // The same message ID can not be handled concurrently
+ // for deduplication to work
+ l := cc.msgIDMutex.Lock(reqMid)
+ defer l.Unlock()
+
+ if ok, err := cc.checkResponseCache(req, w); err != nil {
+ cc.closeConnection()
+ cc.errors(fmt.Errorf(errFmtWriteResponse, err))
+ return
+ } else if ok {
+ return
+ }
+
+ w.Message().SetModified(false)
+ reqType := req.Type()
+ reqMessageID := req.MessageID()
+ cc.handle(w, req)
+
+ err := cc.processResponse(reqType, reqMessageID, w)
+ if err != nil {
+ cc.closeConnection()
+ cc.errors(fmt.Errorf(errFmtWriteResponse, err))
+ }
+}
+
+func (cc *Conn) closeConnection() {
+ if errC := cc.Close(); errC != nil {
+ cc.errors(fmt.Errorf("cannot close connection: %w", errC))
+ }
+}
+
+func (cc *Conn) ProcessReceivedMessageWithHandler(req *pool.Message, handler config.HandlerFunc[*Conn]) {
+ defer func() {
+ if !req.IsHijacked() {
+ cc.ReleaseMessage(req)
+ }
+ }()
+ resp := cc.AcquireMessage(cc.Context())
+ resp.SetToken(req.Token())
+ w := responsewriter.New(resp, cc, req.Options()...)
+ defer func() {
+ cc.ReleaseMessage(w.Message())
+ }()
+ handler(w, req)
+ select {
+ case <-cc.Context().Done():
+ return
+ default:
+ }
+ if !w.Message().IsModified() {
+ // nothing to send
+ return
+ }
+ errW := cc.writeMessageAsync(w.Message())
+ if errW != nil {
+ cc.closeConnection()
+ cc.errors(fmt.Errorf(errFmtWriteResponse, errW))
+ }
+}
+
+func (cc *Conn) handlePong(w *responsewriter.ResponseWriter[*Conn], r *pool.Message) {
+ cc.sendPong(w, r)
+}
+
+func (cc *Conn) handleSpecialMessages(r *pool.Message) bool {
+ // ping request
+ if r.Code() == codes.Empty && r.Type() == message.Confirmable && len(r.Token()) == 0 && len(r.Options()) == 0 && r.Body() == nil {
+ cc.ProcessReceivedMessageWithHandler(r, cc.handlePong)
+ return true
+ }
+ // if waits for concrete message handler
+ if elem, ok := cc.midHandlerContainer.LoadAndDelete(r.MessageID()); ok {
+ elem.ReleaseMessage(cc)
+ resp := cc.AcquireMessage(cc.Context())
+ resp.SetToken(r.Token())
+ w := responsewriter.New(resp, cc, r.Options()...)
+ defer func() {
+ cc.ReleaseMessage(w.Message())
+ }()
+ elem.handler(w, r)
+ // we just confirmed that message was processed for cc.writeMessage
+ // the body of the message is need to be processed by the loopOverReceivedMessageQueue goroutine
+ return false
+ }
+ // separate message
+ if r.IsSeparateMessage() {
+ // msg was processed by token handler - just drop it.
+ return true
+ }
+ return false
+}
+
+func (cc *Conn) Process(datagram []byte) error {
+ if uint32(len(datagram)) > cc.session.MaxMessageSize() {
+ return fmt.Errorf("max message size(%v) was exceeded %v", cc.session.MaxMessageSize(), len(datagram))
+ }
+ req := cc.AcquireMessage(cc.Context())
+ _, err := req.UnmarshalWithDecoder(coder.DefaultCoder, datagram)
+ if err != nil {
+ cc.ReleaseMessage(req)
+ return err
+ }
+ req.SetSequence(cc.Sequence())
+ cc.checkMyMessageID(req)
+ cc.inactivityMonitor.Notify()
+ if cc.handleSpecialMessages(req) {
+ return nil
+ }
+ select {
+ case cc.receivedMessageReader.C() <- req:
+ case <-cc.Context().Done():
+ }
+ return nil
+}
+
+// SetContextValue stores the value associated with key to context of connection.
+func (cc *Conn) SetContextValue(key interface{}, val interface{}) {
+ cc.session.SetContextValue(key, val)
+}
+
+// Done signalizes that connection is not more processed.
+func (cc *Conn) Done() <-chan struct{} {
+ return cc.session.Done()
+}
+
+func (cc *Conn) checkMidHandlerContainer(now time.Time, maxRetransmit int32, acknowledgeTimeout time.Duration, key int32, value *midElement) {
+ if value.IsExpired(now, maxRetransmit) {
+ cc.midHandlerContainer.Delete(key)
+ value.ReleaseMessage(cc)
+ cc.errors(fmt.Errorf(errFmtWriteRequest, context.DeadlineExceeded))
+ return
+ }
+ if !value.Retransmit(now, acknowledgeTimeout) {
+ return
+ }
+ msg, ok, err := value.GetMessage(cc)
+ if err != nil {
+ cc.midHandlerContainer.Delete(key)
+ value.ReleaseMessage(cc)
+ cc.errors(fmt.Errorf(errFmtWriteRequest, err))
+ return
+ }
+ if ok {
+ defer cc.ReleaseMessage(msg)
+ err := cc.session.WriteMessage(msg)
+ if err != nil {
+ cc.errors(fmt.Errorf(errFmtWriteRequest, err))
+ }
+ }
+}
+
+// CheckExpirations checks and remove expired items from caches.
+func (cc *Conn) CheckExpirations(now time.Time) {
+ cc.inactivityMonitor.CheckInactivity(now, cc)
+ cc.responseMsgCache.CheckExpirations(now)
+ if cc.blockWise != nil {
+ cc.blockWise.CheckExpirations(now)
+ }
+ maxRetransmit := cc.transmission.maxRetransmit.Load()
+ acknowledgeTimeout := cc.transmission.acknowledgeTimeout.Load()
+ x := struct {
+ now time.Time
+ maxRetransmit int32
+ acknowledgeTimeout time.Duration
+ cc *Conn
+ }{
+ now: now,
+ maxRetransmit: maxRetransmit,
+ acknowledgeTimeout: acknowledgeTimeout,
+ cc: cc,
+ }
+ cc.midHandlerContainer.Range(func(key int32, value *midElement) bool {
+ x.cc.checkMidHandlerContainer(x.now, x.maxRetransmit, x.acknowledgeTimeout, key, value)
+ return true
+ })
+}
+
+func (cc *Conn) AcquireMessage(ctx context.Context) *pool.Message {
+ return cc.messagePool.AcquireMessage(ctx)
+}
+
+func (cc *Conn) ReleaseMessage(m *pool.Message) {
+ cc.messagePool.ReleaseMessage(m)
+}
+
+// WriteMulticastMessage sends multicast to the remote multicast address.
+// By default it is sent over all network interfaces and all compatible source IP addresses with hop limit 1.
+// Via opts you can specify the network interface, source IP address, and hop limit.
+func (cc *Conn) WriteMulticastMessage(req *pool.Message, address *net.UDPAddr, options ...coapNet.MulticastOption) error {
+ if req.Type() == message.Confirmable {
+ return fmt.Errorf("multicast messages cannot be confirmable")
+ }
+ req.UpsertMessageID(cc.GetMessageID())
+
+ err := cc.session.WriteMulticastMessage(req, address, options...)
+ if err != nil {
+ return fmt.Errorf(errFmtWriteRequest, err)
+ }
+ return nil
+}
+
+func (cc *Conn) InactivityMonitor() InactivityMonitor {
+ return cc.inactivityMonitor
+}
+
+// NetConn returns the underlying connection that is wrapped by cc. The Conn returned is shared by all invocations of NetConn, so do not modify it.
+func (cc *Conn) NetConn() net.Conn {
+ return cc.session.NetConn()
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/mutexmap.go b/vendor/github.com/plgd-dev/go-coap/v3/udp/client/mutexmap.go
similarity index 95%
rename from vendor/github.com/plgd-dev/go-coap/v2/udp/client/mutexmap.go
rename to vendor/github.com/plgd-dev/go-coap/v3/udp/client/mutexmap.go
index afaf7a3..6665ace 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/client/mutexmap.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/udp/client/mutexmap.go
@@ -7,15 +7,15 @@ import (
// MutexMap wraps a map of mutexes. Each key locks separately.
type MutexMap struct {
- ml sync.Mutex // lock for entry map
ma map[interface{}]*mutexMapEntry // entry map
+ ml sync.Mutex // lock for entry map
}
type mutexMapEntry struct {
+ key interface{} // key in ma
m *MutexMap // point back to MutexMap, so we can synchronize removing this mutexMapEntry when cnt==0
el sync.Mutex // entry-specific lock
- cnt int // reference count
- key interface{} // key in ma
+ cnt uint16 // reference count
}
// Unlocker provides an Unlock method to release the lock.
@@ -23,7 +23,7 @@ type Unlocker interface {
Unlock()
}
-// NewMutexMap returns an initalized MutexMap.
+// NewMutexMap returns an initialized MutexMap.
func NewMutexMap() *MutexMap {
return &MutexMap{ma: make(map[interface{}]*mutexMapEntry)}
}
@@ -32,7 +32,6 @@ func NewMutexMap() *MutexMap {
// This method will never return nil and Unlock() must be called
// to release the lock when done.
func (m *MutexMap) Lock(key interface{}) Unlocker {
-
// read or create entry for this key atomically
m.ml.Lock()
e, ok := m.ma[key]
@@ -51,7 +50,6 @@ func (m *MutexMap) Lock(key interface{}) Unlocker {
// Unlock releases the lock for this entry.
func (entry *mutexMapEntry) Unlock() {
-
m := entry.m
// decrement and if needed remove entry atomically
@@ -70,5 +68,4 @@ func (entry *mutexMapEntry) Unlock() {
// now that map stuff is handled, we unlock and let
// anything else waiting on this key through
e.el.Unlock()
-
}
diff --git a/vendor/github.com/plgd-dev/go-coap/v2/udp/message/message.go b/vendor/github.com/plgd-dev/go-coap/v3/udp/coder/coder.go
similarity index 67%
rename from vendor/github.com/plgd-dev/go-coap/v2/udp/message/message.go
rename to vendor/github.com/plgd-dev/go-coap/v3/udp/coder/coder.go
index 63bc464..4b1f0d3 100644
--- a/vendor/github.com/plgd-dev/go-coap/v2/udp/message/message.go
+++ b/vendor/github.com/plgd-dev/go-coap/v3/udp/coder/coder.go
@@ -1,62 +1,37 @@
-package message
+package coder
import (
"encoding/binary"
+ "errors"
+ "fmt"
- "github.com/plgd-dev/go-coap/v2/message"
- "github.com/plgd-dev/go-coap/v2/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
)
-const (
- MESSAGE_LEN13_BASE = 13
- MESSAGE_LEN14_BASE = 269
- MESSAGE_LEN15_BASE = 65805
- MESSAGE_MAX_LEN = 0x7fff0000 // Large number that works in 32-bit builds.
-)
-
-// TcpMessage is a CoAP MessageBase that can encode itself for Message
-// transport.
-type Message struct {
- Code codes.Code
-
- Token message.Token
- Payload []byte
+var DefaultCoder = new(Coder)
- MessageID uint16
- Type Type
-
- Options message.Options //Options must be sorted by ID
-}
+type Coder struct{}
-func (m Message) Size() (int, error) {
+func (c *Coder) Size(m message.Message) (int, error) {
if len(m.Token) > message.MaxTokenSize {
return -1, message.ErrInvalidTokenLen
}
size := 4 + len(m.Token)
payloadLen := len(m.Payload)
optionsLen, err := m.Options.Marshal(nil)
- if err != message.ErrTooSmall {
+ if !errors.Is(err, message.ErrTooSmall) {
return -1, err
}
if payloadLen > 0 {
- //for separator 0xff
+ // for separator 0xff
payloadLen++
}
size += payloadLen + optionsLen
return size, nil
}
-func (m Message) Marshal() ([]byte, error) {
- b := make([]byte, 1024)
- l, err := m.MarshalTo(b)
- if err == message.ErrTooSmall {
- b = append(b[:0], make([]byte, l)...)
- l, err = m.MarshalTo(b)
- }
- return b[:l], err
-}
-
-func (m Message) MarshalTo(buf []byte) (int, error) {
+func (c *Coder) Encode(m message.Message, buf []byte) (int, error) {
/*
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -70,7 +45,13 @@ func (m Message) MarshalTo(buf []byte) (int, error) {
|1 1 1 1 1 1 1 1| Payload (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
- size, err := m.Size()
+ if !message.ValidateMID(m.MessageID) {
+ return -1, fmt.Errorf("invalid MessageID(%v)", m.MessageID)
+ }
+ if !message.ValidateType(m.Type) {
+ return -1, fmt.Errorf("invalid Type(%v)", m.Type)
+ }
+ size, err := c.Size(m)
if err != nil {
return -1, err
}
@@ -79,7 +60,7 @@ func (m Message) MarshalTo(buf []byte) (int, error) {
}
tmpbuf := []byte{0, 0}
- binary.BigEndian.PutUint16(tmpbuf, m.MessageID)
+ binary.BigEndian.PutUint16(tmpbuf, uint16(m.MessageID))
buf[0] = (1 << 6) | byte(m.Type)<<4 | byte(0xf&len(m.Token))
buf[1] = byte(m.Code)
@@ -94,9 +75,9 @@ func (m Message) MarshalTo(buf []byte) (int, error) {
buf = buf[len(m.Token):]
optionsLen, err := m.Options.Marshal(buf)
- switch err {
- case nil:
- case message.ErrTooSmall:
+ switch {
+ case err == nil:
+ case errors.Is(err, message.ErrTooSmall):
return size, err
default:
return -1, err
@@ -111,7 +92,7 @@ func (m Message) MarshalTo(buf []byte) (int, error) {
return size, nil
}
-func (m *Message) Unmarshal(data []byte) (int, error) {
+func (c *Coder) Decode(data []byte, m *message.Message) (int, error) {
size := len(data)
if size < 4 {
return -1, ErrMessageTruncated
@@ -121,7 +102,7 @@ func (m *Message) Unmarshal(data []byte) (int, error) {
return -1, ErrMessageInvalidVersion
}
- typ := Type((data[0] >> 4) & 0x3)
+ typ := message.Type((data[0] >> 4) & 0x3)
tokenLen := int(data[0] & 0xf)
if tokenLen > 8 {
return -1, message.ErrInvalidTokenLen
@@ -153,7 +134,7 @@ func (m *Message) Unmarshal(data []byte) (int, error) {
m.Code = code
m.Token = token
m.Type = typ
- m.MessageID = messageID
+ m.MessageID = int32(messageID)
return size, nil
}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/udp/coder/error.go b/vendor/github.com/plgd-dev/go-coap/v3/udp/coder/error.go
new file mode 100644
index 0000000..ac7ae99
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/udp/coder/error.go
@@ -0,0 +1,8 @@
+package coder
+
+import "errors"
+
+var (
+ ErrMessageTruncated = errors.New("message is truncated")
+ ErrMessageInvalidVersion = errors.New("message has invalid version")
+)
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/udp/server.go b/vendor/github.com/plgd-dev/go-coap/v3/udp/server.go
new file mode 100644
index 0000000..767bfff
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/udp/server.go
@@ -0,0 +1,7 @@
+package udp
+
+import "github.com/plgd-dev/go-coap/v3/udp/server"
+
+func NewServer(opt ...server.Option) *server.Server {
+ return server.New(opt...)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/udp/server/config.go b/vendor/github.com/plgd-dev/go-coap/v3/udp/server/config.go
new file mode 100644
index 0000000..7cfb498
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/udp/server/config.go
@@ -0,0 +1,64 @@
+package server
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/codes"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/options/config"
+ udpClient "github.com/plgd-dev/go-coap/v3/udp/client"
+)
+
+// The HandlerFunc type is an adapter to allow the use of
+// ordinary functions as COAP handlers.
+type HandlerFunc = func(*responsewriter.ResponseWriter[*udpClient.Conn], *pool.Message)
+
+type ErrorFunc = func(error)
+
+// OnNewConnFunc is the callback for new connections.
+type OnNewConnFunc = func(cc *udpClient.Conn)
+
+type GetMIDFunc = func() int32
+
+var DefaultConfig = func() Config {
+ opts := Config{
+ Common: config.NewCommon[*udpClient.Conn](),
+ CreateInactivityMonitor: func() udpClient.InactivityMonitor {
+ timeout := time.Second * 16
+ onInactive := func(cc *udpClient.Conn) {
+ _ = cc.Close()
+ }
+ return inactivity.New(timeout, onInactive)
+ },
+ OnNewConn: func(cc *udpClient.Conn) {
+ // do nothing by default
+ },
+ TransmissionNStart: 1,
+ TransmissionAcknowledgeTimeout: time.Second * 2,
+ TransmissionMaxRetransmit: 4,
+ GetMID: message.GetMID,
+ MTU: udpClient.DefaultMTU,
+ }
+ opts.Handler = func(w *responsewriter.ResponseWriter[*udpClient.Conn], r *pool.Message) {
+ if err := w.SetResponse(codes.NotFound, message.TextPlain, nil); err != nil {
+ opts.Errors(fmt.Errorf("udp server: cannot set response: %w", err))
+ }
+ }
+ return opts
+}()
+
+type Config struct {
+ config.Common[*udpClient.Conn]
+ CreateInactivityMonitor udpClient.CreateInactivityMonitorFunc
+ GetMID GetMIDFunc
+ Handler HandlerFunc
+ OnNewConn OnNewConnFunc
+ TransmissionNStart uint32
+ TransmissionAcknowledgeTimeout time.Duration
+ TransmissionMaxRetransmit uint32
+ MTU uint16
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/udp/server/discover.go b/vendor/github.com/plgd-dev/go-coap/v3/udp/server/discover.go
new file mode 100644
index 0000000..aa41af4
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/udp/server/discover.go
@@ -0,0 +1,90 @@
+package server
+
+import (
+ "context"
+ "fmt"
+ "net"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ 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/pkg/errors"
+ "github.com/plgd-dev/go-coap/v3/udp/client"
+ "github.com/plgd-dev/go-coap/v3/udp/coder"
+)
+
+// Discover sends GET to multicast or unicast address and waits for responses until context timeouts or server shutdown.
+// For unicast there is a difference against the Dial. The Dial is connection-oriented and it means that, if you send a request to an address, the peer must send the response from the same
+// address where was request sent. For Discover it allows the client to send a response from another address where was request send.
+// By default it is sent over all network interfaces and all compatible source IP addresses with hop limit 1.
+// Via opts you can specify the network interface, source IP address, and hop limit.
+func (s *Server) Discover(ctx context.Context, address, path string, receiverFunc func(cc *client.Conn, resp *pool.Message), opts ...coapNet.MulticastOption) error {
+ token, err := s.cfg.GetToken()
+ if err != nil {
+ return fmt.Errorf("cannot get token: %w", err)
+ }
+ req := s.cfg.MessagePool.AcquireMessage(ctx)
+ defer s.cfg.MessagePool.ReleaseMessage(req)
+ err = req.SetupGet(path, token)
+ if err != nil {
+ return fmt.Errorf("cannot create discover request: %w", err)
+ }
+ req.SetMessageID(s.cfg.GetMID())
+ req.SetType(message.NonConfirmable)
+ return s.DiscoveryRequest(req, address, receiverFunc, opts...)
+}
+
+// DiscoveryRequest sends request to multicast/unicast address and wait for responses until request timeouts or server shutdown.
+// For unicast there is a difference against the Dial. The Dial is connection-oriented and it means that, if you send a request to an address, the peer must send the response from the same
+// address where was request sent. For Discover it allows the client to send a response from another address where was request send.
+// By default it is sent over all network interfaces and all compatible source IP addresses with hop limit 1.
+// Via opts you can specify the network interface, source IP address, and hop limit.
+func (s *Server) DiscoveryRequest(req *pool.Message, address string, receiverFunc func(cc *client.Conn, resp *pool.Message), opts ...coapNet.MulticastOption) error {
+ token := req.Token()
+ if len(token) == 0 {
+ return fmt.Errorf("invalid token")
+ }
+ c := s.conn()
+ if c == nil {
+ return fmt.Errorf("server doesn't serve connection")
+ }
+ addr, err := net.ResolveUDPAddr(c.Network(), address)
+ if err != nil {
+ return fmt.Errorf("cannot resolve address: %w", err)
+ }
+
+ data, err := req.MarshalWithEncoder(coder.DefaultCoder)
+ if err != nil {
+ return fmt.Errorf("cannot marshal req: %w", err)
+ }
+ s.multicastRequests.Store(token.Hash(), req)
+ defer s.multicastRequests.Delete(token.Hash())
+ if _, loaded := s.multicastHandler.LoadOrStore(token.Hash(), func(w *responsewriter.ResponseWriter[*client.Conn], r *pool.Message) {
+ receiverFunc(w.Conn(), r)
+ }); loaded {
+ return errors.ErrKeyAlreadyExists
+ }
+ defer func() {
+ _, _ = s.multicastHandler.LoadAndDelete(token.Hash())
+ }()
+
+ if addr.IP.IsMulticast() {
+ err = c.WriteMulticast(req.Context(), addr, data, opts...)
+ if err != nil {
+ return err
+ }
+ } else {
+ err = c.WriteWithContext(req.Context(), addr, data)
+ if err != nil {
+ return err
+ }
+ }
+
+ select {
+ case <-req.Context().Done():
+ return nil
+ case <-s.ctx.Done():
+ return fmt.Errorf("server was closed: %w", s.ctx.Err())
+ }
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/udp/server/server.go b/vendor/github.com/plgd-dev/go-coap/v3/udp/server/server.go
new file mode 100644
index 0000000..8bceeab
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/udp/server/server.go
@@ -0,0 +1,383 @@
+package server
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "sync"
+ "time"
+
+ "github.com/plgd-dev/go-coap/v3/message"
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ coapNet "github.com/plgd-dev/go-coap/v3/net"
+ "github.com/plgd-dev/go-coap/v3/net/blockwise"
+ "github.com/plgd-dev/go-coap/v3/net/monitor/inactivity"
+ "github.com/plgd-dev/go-coap/v3/net/responsewriter"
+ "github.com/plgd-dev/go-coap/v3/pkg/cache"
+ coapSync "github.com/plgd-dev/go-coap/v3/pkg/sync"
+ "github.com/plgd-dev/go-coap/v3/udp/client"
+)
+
+type Server struct {
+ doneCtx context.Context
+ ctx context.Context
+ multicastRequests *client.RequestsMap
+ multicastHandler *coapSync.Map[uint64, HandlerFunc]
+ serverStartedChan chan struct{}
+ doneCancel context.CancelFunc
+ cancel context.CancelFunc
+ responseMsgCache *cache.Cache[string, []byte]
+
+ connsMutex sync.Mutex
+ conns map[string]*client.Conn
+
+ listenMutex sync.Mutex
+ listen *coapNet.UDPConn
+
+ cfg *Config
+}
+
+// A Option sets options such as credentials, codec and keepalive parameters, etc.
+type Option interface {
+ UDPServerApply(cfg *Config)
+}
+
+func New(opt ...Option) *Server {
+ cfg := DefaultConfig
+ for _, o := range opt {
+ o.UDPServerApply(&cfg)
+ }
+
+ if cfg.Errors == nil {
+ cfg.Errors = func(error) {
+ // default no-op
+ }
+ }
+
+ if cfg.GetMID == nil {
+ cfg.GetMID = message.GetMID
+ }
+
+ if cfg.GetToken == nil {
+ cfg.GetToken = message.GetToken
+ }
+
+ if cfg.CreateInactivityMonitor == nil {
+ cfg.CreateInactivityMonitor = func() client.InactivityMonitor {
+ return inactivity.NewNilMonitor[*client.Conn]()
+ }
+ }
+ if cfg.MessagePool == nil {
+ cfg.MessagePool = pool.New(0, 0)
+ }
+
+ ctx, cancel := context.WithCancel(cfg.Ctx)
+ serverStartedChan := make(chan struct{})
+
+ doneCtx, doneCancel := context.WithCancel(context.Background())
+ errorsFunc := cfg.Errors
+ cfg.Errors = func(err error) {
+ if coapNet.IsCancelOrCloseError(err) {
+ // this error was produced by cancellation context or closing connection.
+ return
+ }
+ errorsFunc(fmt.Errorf("udp: %w", err))
+ }
+ return &Server{
+ ctx: ctx,
+ cancel: cancel,
+ multicastHandler: coapSync.NewMap[uint64, HandlerFunc](),
+ multicastRequests: coapSync.NewMap[uint64, *pool.Message](),
+ serverStartedChan: serverStartedChan,
+ doneCtx: doneCtx,
+ doneCancel: doneCancel,
+ responseMsgCache: cache.NewCache[string, []byte](),
+ conns: make(map[string]*client.Conn),
+
+ cfg: &cfg,
+ }
+}
+
+func (s *Server) checkAndSetListener(l *coapNet.UDPConn) error {
+ s.listenMutex.Lock()
+ defer s.listenMutex.Unlock()
+ if s.listen != nil {
+ return fmt.Errorf("server already serve: %v", s.listen.LocalAddr().String())
+ }
+ s.listen = l
+ close(s.serverStartedChan)
+ return nil
+}
+
+func (s *Server) closeConnection(cc *client.Conn) {
+ if err := cc.Close(); err != nil {
+ s.cfg.Errors(fmt.Errorf("cannot close connection: %w", err))
+ }
+}
+
+func (s *Server) Serve(l *coapNet.UDPConn) error {
+ if s.cfg.BlockwiseSZX > blockwise.SZX1024 {
+ return fmt.Errorf("invalid blockwiseSZX")
+ }
+
+ err := s.checkAndSetListener(l)
+ if err != nil {
+ return err
+ }
+
+ defer func() {
+ s.closeSessions()
+ s.doneCancel()
+ s.listenMutex.Lock()
+ defer s.listenMutex.Unlock()
+ s.listen = nil
+ s.serverStartedChan = make(chan struct{}, 1)
+ }()
+
+ m := make([]byte, s.cfg.MaxMessageSize)
+ var wg sync.WaitGroup
+
+ s.cfg.PeriodicRunner(func(now time.Time) bool {
+ s.handleInactivityMonitors(now)
+ s.responseMsgCache.CheckExpirations(now)
+ return s.ctx.Err() == nil
+ })
+
+ for {
+ buf := m
+ n, raddr, err := l.ReadWithContext(s.ctx, buf)
+ if err != nil {
+ wg.Wait()
+
+ select {
+ case <-s.ctx.Done():
+ return nil
+ default:
+ if coapNet.IsCancelOrCloseError(err) {
+ return nil
+ }
+ return err
+ }
+ }
+ buf = buf[:n]
+ cc, err := s.getConn(l, raddr, true)
+ if err != nil {
+ s.cfg.Errors(fmt.Errorf("%v: cannot get client connection: %w", raddr, err))
+ continue
+ }
+ err = cc.Process(buf)
+ if err != nil {
+ s.closeConnection(cc)
+ s.cfg.Errors(fmt.Errorf("%v: cannot process packet: %w", cc.RemoteAddr(), err))
+ }
+ }
+}
+
+func (s *Server) getListener() *coapNet.UDPConn {
+ s.listenMutex.Lock()
+ defer s.listenMutex.Unlock()
+ return s.listen
+}
+
+// Stop stops server without wait of ends Serve function.
+func (s *Server) Stop() {
+ s.cancel()
+ l := s.getListener()
+ if l != nil {
+ if errC := l.Close(); errC != nil {
+ s.cfg.Errors(fmt.Errorf("cannot close listener: %w", errC))
+ }
+ }
+ s.closeSessions()
+}
+
+func (s *Server) closeSessions() {
+ s.connsMutex.Lock()
+ conns := s.conns
+ s.conns = make(map[string]*client.Conn)
+ s.connsMutex.Unlock()
+ for _, cc := range conns {
+ s.closeConnection(cc)
+ if closeFn := getClose(cc); closeFn != nil {
+ closeFn()
+ }
+ }
+}
+
+func (s *Server) conn() *coapNet.UDPConn {
+ s.listenMutex.Lock()
+ serverStartedChan := s.serverStartedChan
+ s.listenMutex.Unlock()
+ select {
+ case <-serverStartedChan:
+ case <-s.ctx.Done():
+ }
+ s.listenMutex.Lock()
+ defer s.listenMutex.Unlock()
+ return s.listen
+}
+
+const closeKey = "gocoapCloseConnection"
+
+func (s *Server) getConns() []*client.Conn {
+ s.connsMutex.Lock()
+ defer s.connsMutex.Unlock()
+ conns := make([]*client.Conn, 0, 32)
+ for _, c := range s.conns {
+ conns = append(conns, c)
+ }
+ return conns
+}
+
+func (s *Server) handleInactivityMonitors(now time.Time) {
+ for _, cc := range s.getConns() {
+ select {
+ case <-cc.Context().Done():
+ if closeFn := getClose(cc); closeFn != nil {
+ closeFn()
+ }
+ continue
+ default:
+ cc.CheckExpirations(now)
+ }
+ }
+}
+
+func getClose(cc *client.Conn) func() {
+ v := cc.Context().Value(closeKey)
+ if v == nil {
+ return nil
+ }
+ closeFn, ok := v.(func())
+ if !ok {
+ panic(fmt.Errorf("invalid type(%T) of context value for key %s", v, closeKey))
+ }
+ return closeFn
+}
+
+func (s *Server) getOrCreateConn(udpConn *coapNet.UDPConn, raddr *net.UDPAddr) (cc *client.Conn, created bool) {
+ s.connsMutex.Lock()
+ defer s.connsMutex.Unlock()
+ key := raddr.String()
+ cc = s.conns[key]
+
+ if cc != nil {
+ return cc, false
+ }
+
+ createBlockWise := func(cc *client.Conn) *blockwise.BlockWise[*client.Conn] {
+ return nil
+ }
+ if s.cfg.BlockwiseEnable {
+ createBlockWise = func(cc *client.Conn) *blockwise.BlockWise[*client.Conn] {
+ v := cc
+ return blockwise.New(
+ v,
+ s.cfg.BlockwiseTransferTimeout,
+ s.cfg.Errors,
+ func(token message.Token) (*pool.Message, bool) {
+ msg, ok := v.GetObservationRequest(token)
+ if ok {
+ return msg, ok
+ }
+ return s.multicastRequests.LoadWithFunc(token.Hash(), func(m *pool.Message) *pool.Message {
+ msg := v.AcquireMessage(m.Context())
+ msg.ResetOptionsTo(m.Options())
+ msg.SetCode(m.Code())
+ msg.SetToken(m.Token())
+ msg.SetMessageID(m.MessageID())
+ return msg
+ })
+ })
+ }
+ }
+ session := NewSession(
+ s.ctx,
+ s.doneCtx,
+ udpConn,
+ raddr,
+ s.cfg.MaxMessageSize,
+ s.cfg.MTU,
+ false,
+ )
+ monitor := s.cfg.CreateInactivityMonitor()
+ cfg := client.DefaultConfig
+ cfg.TransmissionNStart = s.cfg.TransmissionNStart
+ cfg.TransmissionAcknowledgeTimeout = s.cfg.TransmissionAcknowledgeTimeout
+ cfg.TransmissionMaxRetransmit = s.cfg.TransmissionMaxRetransmit
+ cfg.Handler = func(w *responsewriter.ResponseWriter[*client.Conn], r *pool.Message) {
+ h, ok := s.multicastHandler.Load(r.Token().Hash())
+ if ok {
+ h(w, r)
+ return
+ }
+ s.cfg.Handler(w, r)
+ }
+ cfg.BlockwiseSZX = s.cfg.BlockwiseSZX
+ cfg.Errors = s.cfg.Errors
+ cfg.GetMID = s.cfg.GetMID
+ cfg.GetToken = s.cfg.GetToken
+ cfg.MessagePool = s.cfg.MessagePool
+ cfg.ProcessReceivedMessage = s.cfg.ProcessReceivedMessage
+ cfg.ReceivedMessageQueueSize = s.cfg.ReceivedMessageQueueSize
+
+ cc = client.NewConn(
+ session,
+ createBlockWise,
+ monitor,
+ &cfg,
+ )
+ cc.SetContextValue(closeKey, func() {
+ if err := session.Close(); err != nil {
+ s.cfg.Errors(fmt.Errorf("cannot close session: %w", err))
+ }
+ session.shutdown()
+ })
+ cc.AddOnClose(func() {
+ s.connsMutex.Lock()
+ defer s.connsMutex.Unlock()
+ if cc == s.conns[key] {
+ delete(s.conns, key)
+ }
+ })
+ s.conns[key] = cc
+ return cc, true
+}
+
+func (s *Server) getConn(l *coapNet.UDPConn, raddr *net.UDPAddr, firstTime bool) (*client.Conn, error) {
+ cc, created := s.getOrCreateConn(l, raddr)
+ if created {
+ if s.cfg.OnNewConn != nil {
+ s.cfg.OnNewConn(cc)
+ }
+ } else {
+ // check if client is not expired now + 10ms - if so, close it
+ // 10ms - The expected maximum time taken by cc.CheckExpirations and cc.InactivityMonitor().Notify()
+ cc.CheckExpirations(time.Now().Add(10 * time.Millisecond))
+ if cc.Context().Err() == nil {
+ // if client is not closed, extend expiration time
+ cc.InactivityMonitor().Notify()
+ }
+ }
+
+ if cc.Context().Err() != nil {
+ // connection is closed so we need to create new one
+ if closeFn := getClose(cc); closeFn != nil {
+ closeFn()
+ }
+ if firstTime {
+ return s.getConn(l, raddr, false)
+ }
+ return nil, fmt.Errorf("connection is closed")
+ }
+ return cc, nil
+}
+
+func (s *Server) NewConn(addr *net.UDPAddr) (*client.Conn, error) {
+ l := s.getListener()
+ if l == nil {
+ // server is not started/stopped
+ return nil, fmt.Errorf("server is not running")
+ }
+ return s.getConn(l, addr, true)
+}
diff --git a/vendor/github.com/plgd-dev/go-coap/v3/udp/server/session.go b/vendor/github.com/plgd-dev/go-coap/v3/udp/server/session.go
new file mode 100644
index 0000000..870ff53
--- /dev/null
+++ b/vendor/github.com/plgd-dev/go-coap/v3/udp/server/session.go
@@ -0,0 +1,165 @@
+package server
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "sync"
+ "sync/atomic"
+
+ "github.com/plgd-dev/go-coap/v3/message/pool"
+ coapNet "github.com/plgd-dev/go-coap/v3/net"
+ "github.com/plgd-dev/go-coap/v3/udp/client"
+ "github.com/plgd-dev/go-coap/v3/udp/coder"
+)
+
+type EventFunc = func()
+
+type Session struct {
+ onClose []EventFunc
+
+ ctx atomic.Value // TODO: change to atomic.Pointer[context.Context] for go1.19
+
+ doneCtx context.Context
+ connection *coapNet.UDPConn
+ doneCancel context.CancelFunc
+
+ cancel context.CancelFunc
+ raddr *net.UDPAddr
+
+ mutex sync.Mutex
+ maxMessageSize uint32
+ mtu uint16
+
+ closeSocket bool
+}
+
+func NewSession(
+ ctx context.Context,
+ doneCtx context.Context,
+ connection *coapNet.UDPConn,
+ raddr *net.UDPAddr,
+ maxMessageSize uint32,
+ mtu uint16,
+ closeSocket bool,
+) *Session {
+ ctx, cancel := context.WithCancel(ctx)
+
+ doneCtx, doneCancel := context.WithCancel(doneCtx)
+ s := &Session{
+ cancel: cancel,
+ connection: connection,
+ raddr: raddr,
+ maxMessageSize: maxMessageSize,
+ mtu: mtu,
+ closeSocket: closeSocket,
+ doneCtx: doneCtx,
+ doneCancel: doneCancel,
+ }
+ s.ctx.Store(&ctx)
+ return s
+}
+
+// SetContextValue stores the value associated with key to context of connection.
+func (s *Session) SetContextValue(key interface{}, val interface{}) {
+ ctx := context.WithValue(s.Context(), key, val)
+ s.ctx.Store(&ctx)
+}
+
+// Done signalizes that connection is not more processed.
+func (s *Session) Done() <-chan struct{} {
+ return s.doneCtx.Done()
+}
+
+func (s *Session) AddOnClose(f EventFunc) {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ s.onClose = append(s.onClose, f)
+}
+
+func (s *Session) popOnClose() []EventFunc {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ tmp := s.onClose
+ s.onClose = nil
+ return tmp
+}
+
+func (s *Session) shutdown() {
+ defer s.doneCancel()
+ for _, f := range s.popOnClose() {
+ f()
+ }
+}
+
+func (s *Session) Close() error {
+ s.cancel()
+ if s.closeSocket {
+ return s.connection.Close()
+ }
+ return nil
+}
+
+func (s *Session) Context() context.Context {
+ return *s.ctx.Load().(*context.Context) //nolint:forcetypeassert
+}
+
+func (s *Session) WriteMessage(req *pool.Message) error {
+ data, err := req.MarshalWithEncoder(coder.DefaultCoder)
+ if err != nil {
+ return fmt.Errorf("cannot marshal: %w", err)
+ }
+ return s.connection.WriteWithContext(req.Context(), s.raddr, data)
+}
+
+// WriteMulticastMessage sends multicast to the remote multicast address.
+// By default it is sent over all network interfaces and all compatible source IP addresses with hop limit 1.
+// Via opts you can specify the network interface, source IP address, and hop limit.
+func (s *Session) WriteMulticastMessage(req *pool.Message, address *net.UDPAddr, opts ...coapNet.MulticastOption) error {
+ data, err := req.MarshalWithEncoder(coder.DefaultCoder)
+ if err != nil {
+ return fmt.Errorf("cannot marshal: %w", err)
+ }
+
+ return s.connection.WriteMulticast(req.Context(), address, data, opts...)
+}
+
+func (s *Session) Run(cc *client.Conn) (err error) {
+ defer func() {
+ err1 := s.Close()
+ if err == nil {
+ err = err1
+ }
+ s.shutdown()
+ }()
+ m := make([]byte, s.mtu)
+ for {
+ buf := m
+ n, _, err := s.connection.ReadWithContext(s.Context(), buf)
+ if err != nil {
+ return err
+ }
+ buf = buf[:n]
+ err = cc.Process(buf)
+ if err != nil {
+ return err
+ }
+ }
+}
+
+func (s *Session) MaxMessageSize() uint32 {
+ return s.maxMessageSize
+}
+
+func (s *Session) RemoteAddr() net.Addr {
+ return s.raddr
+}
+
+func (s *Session) LocalAddr() net.Addr {
+ return s.connection.LocalAddr()
+}
+
+// NetConn returns the underlying connection that is wrapped by s. The Conn returned is shared by all invocations of NetConn, so do not modify it.
+func (s *Session) NetConn() net.Conn {
+ return s.connection.NetConn()
+}
diff --git a/vendor/github.com/plgd-dev/kit/LICENSE b/vendor/github.com/plgd-dev/kit/LICENSE
deleted file mode 100644
index 261eeb9..0000000
--- a/vendor/github.com/plgd-dev/kit/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/vendor/github.com/plgd-dev/kit/sync/map.go b/vendor/github.com/plgd-dev/kit/sync/map.go
deleted file mode 100644
index 3f5544c..0000000
--- a/vendor/github.com/plgd-dev/kit/sync/map.go
+++ /dev/null
@@ -1,134 +0,0 @@
-package sync
-
-import "sync"
-
-// Map is like a Go map[interface{}]interface{} but is safe for concurrent use by multiple goroutines.
-type Map struct {
- mutex sync.Mutex
- data map[interface{}]interface{}
-}
-
-// NewMap creates map.
-func NewMap() *Map {
- return &Map{
- data: make(map[interface{}]interface{}),
- }
-}
-
-// Delete deletes the value for a key.
-func (m *Map) Delete(key interface{}) {
- m.DeleteWithFunc(key, nil)
-}
-
-func (m *Map) DeleteWithFunc(key interface{}, onDeleteFunc func(value interface{})) {
- m.mutex.Lock()
- defer m.mutex.Unlock()
- value, ok := m.data[key]
- delete(m.data, key)
- if ok && onDeleteFunc != nil {
- onDeleteFunc(value)
- }
-}
-
-// Load returns the value stored in the map for a key, or nil if no value is present.
-// The ok result indicates whether value was found in the map.
-func (m *Map) Load(key interface{}) (value interface{}, ok bool) {
- return m.LoadWithFunc(key, nil)
-}
-
-func (m *Map) LoadWithFunc(key interface{}, onLoadFunc func(value interface{}) interface{}) (value interface{}, ok bool) {
- m.mutex.Lock()
- defer m.mutex.Unlock()
- value, ok = m.data[key]
- if ok && onLoadFunc != nil {
- value = onLoadFunc(value)
- }
- return
-}
-
-// LoadOrStore returns the existing value for the key if present.
-// Otherwise, it stores and returns the given value. The loaded result is true if the value was loaded, false if stored.
-func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) {
- return m.LoadOrStoreWithFunc(key, nil, func() interface{} { return value })
-}
-
-func (m *Map) LoadOrStoreWithFunc(key interface{}, onLoadFunc func(value interface{}) interface{}, createFunc func() interface{}) (actual interface{}, loaded bool) {
- m.mutex.Lock()
- defer m.mutex.Unlock()
- v, ok := m.data[key]
- if ok {
- if onLoadFunc != nil {
- v = onLoadFunc(v)
- }
- return v, ok
- }
- v = createFunc()
- m.data[key] = v
- return v, ok
-}
-
-// Replace replaces the existing value with a new value and returns old value for the key.
-func (m *Map) Replace(key, value interface{}) (oldValue interface{}, oldLoaded bool) {
- return m.ReplaceWithFunc(key, func(oldValue interface{}, oldLoaded bool) (newValue interface{}, delete bool) { return value, false })
-}
-
-func (m *Map) ReplaceWithFunc(key interface{}, onReplaceFunc func(oldValue interface{}, oldLoaded bool) (newValue interface{}, delete bool)) (oldValue interface{}, oldLoaded bool) {
- m.mutex.Lock()
- defer m.mutex.Unlock()
- v, ok := m.data[key]
- newValue, del := onReplaceFunc(v, ok)
- if del {
- delete(m.data, key)
- return v, ok
- }
- m.data[key] = newValue
- return v, ok
-}
-
-// Range calls f sequentially for each key and value present in the map. If f returns false, range stops the iteration.
-func (m *Map) Range(f func(key, value interface{}) bool) {
- m.mutex.Lock()
- defer m.mutex.Unlock()
- for key, value := range m.data {
- ok := f(key, value)
- if !ok {
- return
- }
- }
-}
-
-// Store sets the value for a key.
-func (m *Map) Store(key, value interface{}) {
- m.StoreWithFunc(key, func() interface{} { return value })
-}
-
-func (m *Map) StoreWithFunc(key interface{}, createFunc func() interface{}) {
- m.mutex.Lock()
- defer m.mutex.Unlock()
- m.data[key] = createFunc()
-}
-
-// PullOut loads and deletes the value for a key.
-func (m *Map) PullOut(key interface{}) (value interface{}, ok bool) {
- return m.PullOutWithFunc(key, nil)
-}
-
-func (m *Map) PullOutWithFunc(key interface{}, onLoadFunc func(value interface{}) interface{}) (value interface{}, ok bool) {
- m.mutex.Lock()
- defer m.mutex.Unlock()
- value, ok = m.data[key]
- delete(m.data, key)
- if ok && onLoadFunc != nil {
- value = onLoadFunc(value)
- }
- return
-}
-
-// PullOutAll extracts internal map data and replace it with empty map.
-func (m *Map) PullOutAll() (data map[interface{}]interface{}) {
- m.mutex.Lock()
- defer m.mutex.Unlock()
- data = m.data
- m.data = make(map[interface{}]interface{})
- return
-}
diff --git a/vendor/github.com/plgd-dev/kit/sync/once.go b/vendor/github.com/plgd-dev/kit/sync/once.go
deleted file mode 100644
index 339b4f6..0000000
--- a/vendor/github.com/plgd-dev/kit/sync/once.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package sync
-
-import (
- "sync"
- "sync/atomic"
-)
-
-// Once performs exactly one action.
-// See sync.Once for more details.
-type Once struct {
- m sync.Mutex
- done uint32
-}
-
-// Done returns true after Try executes succesfully.
-func (o *Once) Done() bool {
- return atomic.LoadUint32(&o.done) == 1
-}
-
-// Try executes the function f exactly once for this instance of Once.
-// If the function f returns false, it enables further execution attempts.
-func (o *Once) Try(f func() bool) {
- if atomic.LoadUint32(&o.done) == 1 {
- return
- }
-
- o.m.Lock()
- defer o.m.Unlock()
- if o.done == 1 {
- return
- }
- if f() {
- atomic.StoreUint32(&o.done, 1)
- }
-}
diff --git a/vendor/github.com/plgd-dev/kit/sync/pool.go b/vendor/github.com/plgd-dev/kit/sync/pool.go
deleted file mode 100644
index ebde9f8..0000000
--- a/vendor/github.com/plgd-dev/kit/sync/pool.go
+++ /dev/null
@@ -1,81 +0,0 @@
-package sync
-
-import (
- "context"
- "fmt"
- "sync"
-)
-
-// Pool is a synchronized key-value store with customizable factory for missing items.
-type Pool struct {
- mtx sync.Mutex
- store map[string]interface{}
- create PoolFunc
-}
-
-// PoolFunc is triggered on a miss by GetOrCreate,
-// so that it may add the missing item to the pool.
-type PoolFunc func(ctx context.Context, key string) (interface{}, error)
-
-// NewPool creates a pool.
-func NewPool() *Pool {
- return &Pool{store: make(map[string]interface{})}
-}
-
-// SetFactory sets the pool factory for GetOrCreate.
-func (p *Pool) SetFactory(f PoolFunc) {
- p.mtx.Lock()
- defer p.mtx.Unlock()
-
- p.create = f
-}
-
-// Put adds an item to the pool.
-func (p *Pool) Put(key string, item interface{}) {
- p.mtx.Lock()
- defer p.mtx.Unlock()
-
- p.store[key] = item
-}
-
-// Get returns an item from the pool or false.
-func (p *Pool) Get(key string) (_ interface{}, ok bool) {
- p.mtx.Lock()
- defer p.mtx.Unlock()
-
- item, ok := p.store[key]
- return item, ok
-}
-
-// Delete pops an item from the pool or false.
-func (p *Pool) Delete(key string) (_ interface{}, ok bool) {
- p.mtx.Lock()
- defer p.mtx.Unlock()
-
- item, ok := p.store[key]
- delete(p.store, key)
-
- return item, ok
-}
-
-// GetOrCreate returns an item and calls the factory on a mis.
-// Warning: The factory function is called under the lock,
-// therefore it must not call any Pool's methods to avoid deadlocks.
-func (p *Pool) GetOrCreate(ctx context.Context, key string) (interface{}, error) {
- p.mtx.Lock()
- defer p.mtx.Unlock()
-
- if item, ok := p.store[key]; ok {
- return item, nil
- }
-
- if p.create == nil {
- return nil, fmt.Errorf("missing pool factory")
- }
- item, err := p.create(ctx, key)
- if err != nil {
- return nil, fmt.Errorf("could not create pool item %s: %w", key, err)
- }
- p.store[key] = item
- return item, nil
-}
diff --git a/vendor/github.com/plgd-dev/kit/sync/refcounter.go b/vendor/github.com/plgd-dev/kit/sync/refcounter.go
deleted file mode 100644
index d8c7867..0000000
--- a/vendor/github.com/plgd-dev/kit/sync/refcounter.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package sync
-
-import (
- "context"
- "sync/atomic"
-)
-
-type ReleaseDataFunc = func(ctx context.Context, data interface{}) error
-
-type RefCounter struct {
- count int64
- data interface{}
- releaseDataFunc ReleaseDataFunc
-}
-
-// Data returns data
-func (r *RefCounter) Data() interface{} {
- v := atomic.LoadInt64(&r.count)
- if v <= 0 {
- panic("using RefCounter after data released")
- }
- return r.data
-}
-
-// Acquire increments counter
-func (r *RefCounter) Acquire() {
- v := atomic.AddInt64(&r.count, 1)
- if v <= 1 {
- panic("using RefCounter after data released")
- }
-}
-
-// Count returns current counter value.
-func (r *RefCounter) Count() int64 {
- return atomic.LoadInt64(&r.count)
-}
-
-// Release decrements counter, when counter reach 0, releaseDataFunc will be called
-func (r *RefCounter) Release(ctx context.Context) error {
- v := atomic.AddInt64(&r.count, -1)
- if v < 0 {
- panic("using RefCounter after data released")
- }
- if v == 0 {
- if r.releaseDataFunc != nil {
- return r.releaseDataFunc(ctx, r.data)
- }
- }
- return nil
-}
-
-// NewRefCounter creates RefCounter
-func NewRefCounter(data interface{}, releaseDataFunc ReleaseDataFunc) *RefCounter {
- return &RefCounter{
- data: data,
- count: 1,
- releaseDataFunc: releaseDataFunc,
- }
-}
diff --git a/vendor/go.uber.org/atomic/.codecov.yml b/vendor/go.uber.org/atomic/.codecov.yml
index 6d4d1be..571116c 100644
--- a/vendor/go.uber.org/atomic/.codecov.yml
+++ b/vendor/go.uber.org/atomic/.codecov.yml
@@ -13,3 +13,7 @@ coverage:
if_not_found: success # if parent is not found report status as success, error, or failure
if_ci_failed: error # if ci fails report status as success, error, or failure
+# Also update COVER_IGNORE_PKGS in the Makefile.
+ignore:
+ - /internal/gen-atomicint/
+ - /internal/gen-valuewrapper/
diff --git a/vendor/go.uber.org/atomic/.gitignore b/vendor/go.uber.org/atomic/.gitignore
index c3fa253..2e337a0 100644
--- a/vendor/go.uber.org/atomic/.gitignore
+++ b/vendor/go.uber.org/atomic/.gitignore
@@ -10,3 +10,6 @@ lint.log
# Profiling output
*.prof
+
+# Output of fossa analyzer
+/fossa
diff --git a/vendor/go.uber.org/atomic/.travis.yml b/vendor/go.uber.org/atomic/.travis.yml
deleted file mode 100644
index 4e73268..0000000
--- a/vendor/go.uber.org/atomic/.travis.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-sudo: false
-language: go
-go_import_path: go.uber.org/atomic
-
-env:
- global:
- - GO111MODULE=on
-
-matrix:
- include:
- - go: 1.12.x
- - go: 1.13.x
- env: LINT=1
-
-cache:
- directories:
- - vendor
-
-before_install:
- - go version
-
-script:
- - test -z "$LINT" || make lint
- - make cover
-
-after_success:
- - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/go.uber.org/atomic/CHANGELOG.md b/vendor/go.uber.org/atomic/CHANGELOG.md
index aef8b6e..6f87f33 100644
--- a/vendor/go.uber.org/atomic/CHANGELOG.md
+++ b/vendor/go.uber.org/atomic/CHANGELOG.md
@@ -4,32 +4,98 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [1.11.0] - 2023-05-02
+### Fixed
+- Fix initialization of `Value` wrappers.
+
+### Added
+- Add `String` method to `atomic.Pointer[T]` type allowing users to safely print
+underlying values of pointers.
+
+[1.11.0]: https://github.com/uber-go/atomic/compare/v1.10.0...v1.11.0
+
+## [1.10.0] - 2022-08-11
+### Added
+- Add `atomic.Float32` type for atomic operations on `float32`.
+- Add `CompareAndSwap` and `Swap` methods to `atomic.String`, `atomic.Error`,
+ and `atomic.Value`.
+- Add generic `atomic.Pointer[T]` type for atomic operations on pointers of any
+ type. This is present only for Go 1.18 or higher, and is a drop-in for
+ replacement for the standard library's `sync/atomic.Pointer` type.
+
+### Changed
+- Deprecate `CAS` methods on all types in favor of corresponding
+ `CompareAndSwap` methods.
+
+Thanks to @eNV25 and @icpd for their contributions to this release.
+
+[1.10.0]: https://github.com/uber-go/atomic/compare/v1.9.0...v1.10.0
+
+## [1.9.0] - 2021-07-15
+### Added
+- Add `Float64.Swap` to match int atomic operations.
+- Add `atomic.Time` type for atomic operations on `time.Time` values.
+
+[1.9.0]: https://github.com/uber-go/atomic/compare/v1.8.0...v1.9.0
+
+## [1.8.0] - 2021-06-09
+### Added
+- Add `atomic.Uintptr` type for atomic operations on `uintptr` values.
+- Add `atomic.UnsafePointer` type for atomic operations on `unsafe.Pointer` values.
+
+[1.8.0]: https://github.com/uber-go/atomic/compare/v1.7.0...v1.8.0
+
+## [1.7.0] - 2020-09-14
+### Added
+- Support JSON serialization and deserialization of primitive atomic types.
+- Support Text marshalling and unmarshalling for string atomics.
+
+### Changed
+- Disallow incorrect comparison of atomic values in a non-atomic way.
+
+### Removed
+- Remove dependency on `golang.org/x/{lint, tools}`.
+
+[1.7.0]: https://github.com/uber-go/atomic/compare/v1.6.0...v1.7.0
+
## [1.6.0] - 2020-02-24
### Changed
- Drop library dependency on `golang.org/x/{lint, tools}`.
+[1.6.0]: https://github.com/uber-go/atomic/compare/v1.5.1...v1.6.0
+
## [1.5.1] - 2019-11-19
- Fix bug where `Bool.CAS` and `Bool.Toggle` do work correctly together
causing `CAS` to fail even though the old value matches.
+[1.5.1]: https://github.com/uber-go/atomic/compare/v1.5.0...v1.5.1
+
## [1.5.0] - 2019-10-29
### Changed
- With Go modules, only the `go.uber.org/atomic` import path is supported now.
If you need to use the old import path, please add a `replace` directive to
your `go.mod`.
+[1.5.0]: https://github.com/uber-go/atomic/compare/v1.4.0...v1.5.0
+
## [1.4.0] - 2019-05-01
### Added
- Add `atomic.Error` type for atomic operations on `error` values.
+[1.4.0]: https://github.com/uber-go/atomic/compare/v1.3.2...v1.4.0
+
## [1.3.2] - 2018-05-02
### Added
- Add `atomic.Duration` type for atomic operations on `time.Duration` values.
+[1.3.2]: https://github.com/uber-go/atomic/compare/v1.3.1...v1.3.2
+
## [1.3.1] - 2017-11-14
### Fixed
- Revert optimization for `atomic.String.Store("")` which caused data races.
+[1.3.1]: https://github.com/uber-go/atomic/compare/v1.3.0...v1.3.1
+
## [1.3.0] - 2017-11-13
### Added
- Add `atomic.Bool.CAS` for compare-and-swap semantics on bools.
@@ -37,10 +103,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Optimize `atomic.String.Store("")` by avoiding an allocation.
+[1.3.0]: https://github.com/uber-go/atomic/compare/v1.2.0...v1.3.0
+
## [1.2.0] - 2017-04-12
### Added
- Shadow `atomic.Value` from `sync/atomic`.
+[1.2.0]: https://github.com/uber-go/atomic/compare/v1.1.0...v1.2.0
+
## [1.1.0] - 2017-03-10
### Added
- Add atomic `Float64` type.
@@ -48,17 +118,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Support new `go.uber.org/atomic` import path.
+[1.1.0]: https://github.com/uber-go/atomic/compare/v1.0.0...v1.1.0
+
## [1.0.0] - 2016-07-18
- Initial release.
-[1.6.0]: https://github.com/uber-go/atomic/compare/v1.5.1...v1.6.0
-[1.5.1]: https://github.com/uber-go/atomic/compare/v1.5.0...v1.5.1
-[1.5.0]: https://github.com/uber-go/atomic/compare/v1.4.0...v1.5.0
-[1.4.0]: https://github.com/uber-go/atomic/compare/v1.3.2...v1.4.0
-[1.3.2]: https://github.com/uber-go/atomic/compare/v1.3.1...v1.3.2
-[1.3.1]: https://github.com/uber-go/atomic/compare/v1.3.0...v1.3.1
-[1.3.0]: https://github.com/uber-go/atomic/compare/v1.2.0...v1.3.0
-[1.2.0]: https://github.com/uber-go/atomic/compare/v1.1.0...v1.2.0
-[1.1.0]: https://github.com/uber-go/atomic/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/uber-go/atomic/releases/tag/v1.0.0
diff --git a/vendor/go.uber.org/atomic/Makefile b/vendor/go.uber.org/atomic/Makefile
index 39af0fb..46c945b 100644
--- a/vendor/go.uber.org/atomic/Makefile
+++ b/vendor/go.uber.org/atomic/Makefile
@@ -2,8 +2,16 @@
export GOBIN ?= $(shell pwd)/bin
GOLINT = $(GOBIN)/golint
+GEN_ATOMICINT = $(GOBIN)/gen-atomicint
+GEN_ATOMICWRAPPER = $(GOBIN)/gen-atomicwrapper
+STATICCHECK = $(GOBIN)/staticcheck
-GO_FILES ?= *.go
+GO_FILES ?= $(shell find . '(' -path .git -o -path vendor ')' -prune -o -name '*.go' -print)
+
+# Also update ignore section in .codecov.yml.
+COVER_IGNORE_PKGS = \
+ go.uber.org/atomic/internal/gen-atomicint \
+ go.uber.org/atomic/internal/gen-atomicwrapper
.PHONY: build
build:
@@ -20,16 +28,52 @@ gofmt:
@[ ! -s "$(FMT_LOG)" ] || (echo "gofmt failed:" && cat $(FMT_LOG) && false)
$(GOLINT):
- go install golang.org/x/lint/golint
+ cd tools && go install golang.org/x/lint/golint
+
+$(STATICCHECK):
+ cd tools && go install honnef.co/go/tools/cmd/staticcheck
+
+$(GEN_ATOMICWRAPPER): $(wildcard ./internal/gen-atomicwrapper/*)
+ go build -o $@ ./internal/gen-atomicwrapper
+
+$(GEN_ATOMICINT): $(wildcard ./internal/gen-atomicint/*)
+ go build -o $@ ./internal/gen-atomicint
.PHONY: golint
golint: $(GOLINT)
$(GOLINT) ./...
+.PHONY: staticcheck
+staticcheck: $(STATICCHECK)
+ $(STATICCHECK) ./...
+
.PHONY: lint
-lint: gofmt golint
+lint: gofmt golint staticcheck generatenodirty
+
+# comma separated list of packages to consider for code coverage.
+COVER_PKG = $(shell \
+ go list -find ./... | \
+ grep -v $(foreach pkg,$(COVER_IGNORE_PKGS),-e "^$(pkg)$$") | \
+ paste -sd, -)
.PHONY: cover
cover:
- go test -coverprofile=cover.out -coverpkg ./... -v ./...
+ go test -coverprofile=cover.out -coverpkg $(COVER_PKG) -v ./...
go tool cover -html=cover.out -o cover.html
+
+.PHONY: generate
+generate: $(GEN_ATOMICINT) $(GEN_ATOMICWRAPPER)
+ go generate ./...
+
+.PHONY: generatenodirty
+generatenodirty:
+ @[ -z "$$(git status --porcelain)" ] || ( \
+ echo "Working tree is dirty. Commit your changes first."; \
+ git status; \
+ exit 1 )
+ @make generate
+ @status=$$(git status --porcelain); \
+ [ -z "$$status" ] || ( \
+ echo "Working tree is dirty after `make generate`:"; \
+ echo "$$status"; \
+ echo "Please ensure that the generated code is up-to-date." )
diff --git a/vendor/go.uber.org/atomic/README.md b/vendor/go.uber.org/atomic/README.md
index ade0c20..96b47a1 100644
--- a/vendor/go.uber.org/atomic/README.md
+++ b/vendor/go.uber.org/atomic/README.md
@@ -55,8 +55,8 @@ Released under the [MIT License](LICENSE.txt).
[doc-img]: https://godoc.org/github.com/uber-go/atomic?status.svg
[doc]: https://godoc.org/go.uber.org/atomic
-[ci-img]: https://travis-ci.com/uber-go/atomic.svg?branch=master
-[ci]: https://travis-ci.com/uber-go/atomic
+[ci-img]: https://github.com/uber-go/atomic/actions/workflows/go.yml/badge.svg
+[ci]: https://github.com/uber-go/atomic/actions/workflows/go.yml
[cov-img]: https://codecov.io/gh/uber-go/atomic/branch/master/graph/badge.svg
[cov]: https://codecov.io/gh/uber-go/atomic
[reportcard-img]: https://goreportcard.com/badge/go.uber.org/atomic
diff --git a/vendor/go.uber.org/atomic/atomic.go b/vendor/go.uber.org/atomic/atomic.go
deleted file mode 100644
index ad5fa09..0000000
--- a/vendor/go.uber.org/atomic/atomic.go
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright (c) 2016 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Package atomic provides simple wrappers around numerics to enforce atomic
-// access.
-package atomic
-
-import (
- "math"
- "sync/atomic"
- "time"
-)
-
-// Int32 is an atomic wrapper around an int32.
-type Int32 struct{ v int32 }
-
-// NewInt32 creates an Int32.
-func NewInt32(i int32) *Int32 {
- return &Int32{i}
-}
-
-// Load atomically loads the wrapped value.
-func (i *Int32) Load() int32 {
- return atomic.LoadInt32(&i.v)
-}
-
-// Add atomically adds to the wrapped int32 and returns the new value.
-func (i *Int32) Add(n int32) int32 {
- return atomic.AddInt32(&i.v, n)
-}
-
-// Sub atomically subtracts from the wrapped int32 and returns the new value.
-func (i *Int32) Sub(n int32) int32 {
- return atomic.AddInt32(&i.v, -n)
-}
-
-// Inc atomically increments the wrapped int32 and returns the new value.
-func (i *Int32) Inc() int32 {
- return i.Add(1)
-}
-
-// Dec atomically decrements the wrapped int32 and returns the new value.
-func (i *Int32) Dec() int32 {
- return i.Sub(1)
-}
-
-// CAS is an atomic compare-and-swap.
-func (i *Int32) CAS(old, new int32) bool {
- return atomic.CompareAndSwapInt32(&i.v, old, new)
-}
-
-// Store atomically stores the passed value.
-func (i *Int32) Store(n int32) {
- atomic.StoreInt32(&i.v, n)
-}
-
-// Swap atomically swaps the wrapped int32 and returns the old value.
-func (i *Int32) Swap(n int32) int32 {
- return atomic.SwapInt32(&i.v, n)
-}
-
-// Int64 is an atomic wrapper around an int64.
-type Int64 struct{ v int64 }
-
-// NewInt64 creates an Int64.
-func NewInt64(i int64) *Int64 {
- return &Int64{i}
-}
-
-// Load atomically loads the wrapped value.
-func (i *Int64) Load() int64 {
- return atomic.LoadInt64(&i.v)
-}
-
-// Add atomically adds to the wrapped int64 and returns the new value.
-func (i *Int64) Add(n int64) int64 {
- return atomic.AddInt64(&i.v, n)
-}
-
-// Sub atomically subtracts from the wrapped int64 and returns the new value.
-func (i *Int64) Sub(n int64) int64 {
- return atomic.AddInt64(&i.v, -n)
-}
-
-// Inc atomically increments the wrapped int64 and returns the new value.
-func (i *Int64) Inc() int64 {
- return i.Add(1)
-}
-
-// Dec atomically decrements the wrapped int64 and returns the new value.
-func (i *Int64) Dec() int64 {
- return i.Sub(1)
-}
-
-// CAS is an atomic compare-and-swap.
-func (i *Int64) CAS(old, new int64) bool {
- return atomic.CompareAndSwapInt64(&i.v, old, new)
-}
-
-// Store atomically stores the passed value.
-func (i *Int64) Store(n int64) {
- atomic.StoreInt64(&i.v, n)
-}
-
-// Swap atomically swaps the wrapped int64 and returns the old value.
-func (i *Int64) Swap(n int64) int64 {
- return atomic.SwapInt64(&i.v, n)
-}
-
-// Uint32 is an atomic wrapper around an uint32.
-type Uint32 struct{ v uint32 }
-
-// NewUint32 creates a Uint32.
-func NewUint32(i uint32) *Uint32 {
- return &Uint32{i}
-}
-
-// Load atomically loads the wrapped value.
-func (i *Uint32) Load() uint32 {
- return atomic.LoadUint32(&i.v)
-}
-
-// Add atomically adds to the wrapped uint32 and returns the new value.
-func (i *Uint32) Add(n uint32) uint32 {
- return atomic.AddUint32(&i.v, n)
-}
-
-// Sub atomically subtracts from the wrapped uint32 and returns the new value.
-func (i *Uint32) Sub(n uint32) uint32 {
- return atomic.AddUint32(&i.v, ^(n - 1))
-}
-
-// Inc atomically increments the wrapped uint32 and returns the new value.
-func (i *Uint32) Inc() uint32 {
- return i.Add(1)
-}
-
-// Dec atomically decrements the wrapped int32 and returns the new value.
-func (i *Uint32) Dec() uint32 {
- return i.Sub(1)
-}
-
-// CAS is an atomic compare-and-swap.
-func (i *Uint32) CAS(old, new uint32) bool {
- return atomic.CompareAndSwapUint32(&i.v, old, new)
-}
-
-// Store atomically stores the passed value.
-func (i *Uint32) Store(n uint32) {
- atomic.StoreUint32(&i.v, n)
-}
-
-// Swap atomically swaps the wrapped uint32 and returns the old value.
-func (i *Uint32) Swap(n uint32) uint32 {
- return atomic.SwapUint32(&i.v, n)
-}
-
-// Uint64 is an atomic wrapper around a uint64.
-type Uint64 struct{ v uint64 }
-
-// NewUint64 creates a Uint64.
-func NewUint64(i uint64) *Uint64 {
- return &Uint64{i}
-}
-
-// Load atomically loads the wrapped value.
-func (i *Uint64) Load() uint64 {
- return atomic.LoadUint64(&i.v)
-}
-
-// Add atomically adds to the wrapped uint64 and returns the new value.
-func (i *Uint64) Add(n uint64) uint64 {
- return atomic.AddUint64(&i.v, n)
-}
-
-// Sub atomically subtracts from the wrapped uint64 and returns the new value.
-func (i *Uint64) Sub(n uint64) uint64 {
- return atomic.AddUint64(&i.v, ^(n - 1))
-}
-
-// Inc atomically increments the wrapped uint64 and returns the new value.
-func (i *Uint64) Inc() uint64 {
- return i.Add(1)
-}
-
-// Dec atomically decrements the wrapped uint64 and returns the new value.
-func (i *Uint64) Dec() uint64 {
- return i.Sub(1)
-}
-
-// CAS is an atomic compare-and-swap.
-func (i *Uint64) CAS(old, new uint64) bool {
- return atomic.CompareAndSwapUint64(&i.v, old, new)
-}
-
-// Store atomically stores the passed value.
-func (i *Uint64) Store(n uint64) {
- atomic.StoreUint64(&i.v, n)
-}
-
-// Swap atomically swaps the wrapped uint64 and returns the old value.
-func (i *Uint64) Swap(n uint64) uint64 {
- return atomic.SwapUint64(&i.v, n)
-}
-
-// Bool is an atomic Boolean.
-type Bool struct{ v uint32 }
-
-// NewBool creates a Bool.
-func NewBool(initial bool) *Bool {
- return &Bool{boolToInt(initial)}
-}
-
-// Load atomically loads the Boolean.
-func (b *Bool) Load() bool {
- return truthy(atomic.LoadUint32(&b.v))
-}
-
-// CAS is an atomic compare-and-swap.
-func (b *Bool) CAS(old, new bool) bool {
- return atomic.CompareAndSwapUint32(&b.v, boolToInt(old), boolToInt(new))
-}
-
-// Store atomically stores the passed value.
-func (b *Bool) Store(new bool) {
- atomic.StoreUint32(&b.v, boolToInt(new))
-}
-
-// Swap sets the given value and returns the previous value.
-func (b *Bool) Swap(new bool) bool {
- return truthy(atomic.SwapUint32(&b.v, boolToInt(new)))
-}
-
-// Toggle atomically negates the Boolean and returns the previous value.
-func (b *Bool) Toggle() bool {
- for {
- old := b.Load()
- if b.CAS(old, !old) {
- return old
- }
- }
-}
-
-func truthy(n uint32) bool {
- return n == 1
-}
-
-func boolToInt(b bool) uint32 {
- if b {
- return 1
- }
- return 0
-}
-
-// Float64 is an atomic wrapper around float64.
-type Float64 struct {
- v uint64
-}
-
-// NewFloat64 creates a Float64.
-func NewFloat64(f float64) *Float64 {
- return &Float64{math.Float64bits(f)}
-}
-
-// Load atomically loads the wrapped value.
-func (f *Float64) Load() float64 {
- return math.Float64frombits(atomic.LoadUint64(&f.v))
-}
-
-// Store atomically stores the passed value.
-func (f *Float64) Store(s float64) {
- atomic.StoreUint64(&f.v, math.Float64bits(s))
-}
-
-// Add atomically adds to the wrapped float64 and returns the new value.
-func (f *Float64) Add(s float64) float64 {
- for {
- old := f.Load()
- new := old + s
- if f.CAS(old, new) {
- return new
- }
- }
-}
-
-// Sub atomically subtracts from the wrapped float64 and returns the new value.
-func (f *Float64) Sub(s float64) float64 {
- return f.Add(-s)
-}
-
-// CAS is an atomic compare-and-swap.
-func (f *Float64) CAS(old, new float64) bool {
- return atomic.CompareAndSwapUint64(&f.v, math.Float64bits(old), math.Float64bits(new))
-}
-
-// Duration is an atomic wrapper around time.Duration
-// https://godoc.org/time#Duration
-type Duration struct {
- v Int64
-}
-
-// NewDuration creates a Duration.
-func NewDuration(d time.Duration) *Duration {
- return &Duration{v: *NewInt64(int64(d))}
-}
-
-// Load atomically loads the wrapped value.
-func (d *Duration) Load() time.Duration {
- return time.Duration(d.v.Load())
-}
-
-// Store atomically stores the passed value.
-func (d *Duration) Store(n time.Duration) {
- d.v.Store(int64(n))
-}
-
-// Add atomically adds to the wrapped time.Duration and returns the new value.
-func (d *Duration) Add(n time.Duration) time.Duration {
- return time.Duration(d.v.Add(int64(n)))
-}
-
-// Sub atomically subtracts from the wrapped time.Duration and returns the new value.
-func (d *Duration) Sub(n time.Duration) time.Duration {
- return time.Duration(d.v.Sub(int64(n)))
-}
-
-// Swap atomically swaps the wrapped time.Duration and returns the old value.
-func (d *Duration) Swap(n time.Duration) time.Duration {
- return time.Duration(d.v.Swap(int64(n)))
-}
-
-// CAS is an atomic compare-and-swap.
-func (d *Duration) CAS(old, new time.Duration) bool {
- return d.v.CAS(int64(old), int64(new))
-}
-
-// Value shadows the type of the same name from sync/atomic
-// https://godoc.org/sync/atomic#Value
-type Value struct{ atomic.Value }
diff --git a/vendor/go.uber.org/atomic/bool.go b/vendor/go.uber.org/atomic/bool.go
new file mode 100644
index 0000000..f0a2ddd
--- /dev/null
+++ b/vendor/go.uber.org/atomic/bool.go
@@ -0,0 +1,88 @@
+// @generated Code generated by gen-atomicwrapper.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "encoding/json"
+)
+
+// Bool is an atomic type-safe wrapper for bool values.
+type Bool struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v Uint32
+}
+
+var _zeroBool bool
+
+// NewBool creates a new Bool.
+func NewBool(val bool) *Bool {
+ x := &Bool{}
+ if val != _zeroBool {
+ x.Store(val)
+ }
+ return x
+}
+
+// Load atomically loads the wrapped bool.
+func (x *Bool) Load() bool {
+ return truthy(x.v.Load())
+}
+
+// Store atomically stores the passed bool.
+func (x *Bool) Store(val bool) {
+ x.v.Store(boolToInt(val))
+}
+
+// CAS is an atomic compare-and-swap for bool values.
+//
+// Deprecated: Use CompareAndSwap.
+func (x *Bool) CAS(old, new bool) (swapped bool) {
+ return x.CompareAndSwap(old, new)
+}
+
+// CompareAndSwap is an atomic compare-and-swap for bool values.
+func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) {
+ return x.v.CompareAndSwap(boolToInt(old), boolToInt(new))
+}
+
+// Swap atomically stores the given bool and returns the old
+// value.
+func (x *Bool) Swap(val bool) (old bool) {
+ return truthy(x.v.Swap(boolToInt(val)))
+}
+
+// MarshalJSON encodes the wrapped bool into JSON.
+func (x *Bool) MarshalJSON() ([]byte, error) {
+ return json.Marshal(x.Load())
+}
+
+// UnmarshalJSON decodes a bool from JSON.
+func (x *Bool) UnmarshalJSON(b []byte) error {
+ var v bool
+ if err := json.Unmarshal(b, &v); err != nil {
+ return err
+ }
+ x.Store(v)
+ return nil
+}
diff --git a/vendor/go.uber.org/atomic/bool_ext.go b/vendor/go.uber.org/atomic/bool_ext.go
new file mode 100644
index 0000000..a2e60e9
--- /dev/null
+++ b/vendor/go.uber.org/atomic/bool_ext.go
@@ -0,0 +1,53 @@
+// Copyright (c) 2020 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "strconv"
+)
+
+//go:generate bin/gen-atomicwrapper -name=Bool -type=bool -wrapped=Uint32 -pack=boolToInt -unpack=truthy -cas -swap -json -file=bool.go
+
+func truthy(n uint32) bool {
+ return n == 1
+}
+
+func boolToInt(b bool) uint32 {
+ if b {
+ return 1
+ }
+ return 0
+}
+
+// Toggle atomically negates the Boolean and returns the previous value.
+func (b *Bool) Toggle() (old bool) {
+ for {
+ old := b.Load()
+ if b.CAS(old, !old) {
+ return old
+ }
+ }
+}
+
+// String encodes the wrapped value as a string.
+func (b *Bool) String() string {
+ return strconv.FormatBool(b.Load())
+}
diff --git a/vendor/go.uber.org/atomic/doc.go b/vendor/go.uber.org/atomic/doc.go
new file mode 100644
index 0000000..ae7390e
--- /dev/null
+++ b/vendor/go.uber.org/atomic/doc.go
@@ -0,0 +1,23 @@
+// Copyright (c) 2020 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// Package atomic provides simple wrappers around numerics to enforce atomic
+// access.
+package atomic
diff --git a/vendor/go.uber.org/atomic/duration.go b/vendor/go.uber.org/atomic/duration.go
new file mode 100644
index 0000000..7c23868
--- /dev/null
+++ b/vendor/go.uber.org/atomic/duration.go
@@ -0,0 +1,89 @@
+// @generated Code generated by gen-atomicwrapper.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "encoding/json"
+ "time"
+)
+
+// Duration is an atomic type-safe wrapper for time.Duration values.
+type Duration struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v Int64
+}
+
+var _zeroDuration time.Duration
+
+// NewDuration creates a new Duration.
+func NewDuration(val time.Duration) *Duration {
+ x := &Duration{}
+ if val != _zeroDuration {
+ x.Store(val)
+ }
+ return x
+}
+
+// Load atomically loads the wrapped time.Duration.
+func (x *Duration) Load() time.Duration {
+ return time.Duration(x.v.Load())
+}
+
+// Store atomically stores the passed time.Duration.
+func (x *Duration) Store(val time.Duration) {
+ x.v.Store(int64(val))
+}
+
+// CAS is an atomic compare-and-swap for time.Duration values.
+//
+// Deprecated: Use CompareAndSwap.
+func (x *Duration) CAS(old, new time.Duration) (swapped bool) {
+ return x.CompareAndSwap(old, new)
+}
+
+// CompareAndSwap is an atomic compare-and-swap for time.Duration values.
+func (x *Duration) CompareAndSwap(old, new time.Duration) (swapped bool) {
+ return x.v.CompareAndSwap(int64(old), int64(new))
+}
+
+// Swap atomically stores the given time.Duration and returns the old
+// value.
+func (x *Duration) Swap(val time.Duration) (old time.Duration) {
+ return time.Duration(x.v.Swap(int64(val)))
+}
+
+// MarshalJSON encodes the wrapped time.Duration into JSON.
+func (x *Duration) MarshalJSON() ([]byte, error) {
+ return json.Marshal(x.Load())
+}
+
+// UnmarshalJSON decodes a time.Duration from JSON.
+func (x *Duration) UnmarshalJSON(b []byte) error {
+ var v time.Duration
+ if err := json.Unmarshal(b, &v); err != nil {
+ return err
+ }
+ x.Store(v)
+ return nil
+}
diff --git a/vendor/go.uber.org/atomic/duration_ext.go b/vendor/go.uber.org/atomic/duration_ext.go
new file mode 100644
index 0000000..4c18b0a
--- /dev/null
+++ b/vendor/go.uber.org/atomic/duration_ext.go
@@ -0,0 +1,40 @@
+// Copyright (c) 2020 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import "time"
+
+//go:generate bin/gen-atomicwrapper -name=Duration -type=time.Duration -wrapped=Int64 -pack=int64 -unpack=time.Duration -cas -swap -json -imports time -file=duration.go
+
+// Add atomically adds to the wrapped time.Duration and returns the new value.
+func (d *Duration) Add(delta time.Duration) time.Duration {
+ return time.Duration(d.v.Add(int64(delta)))
+}
+
+// Sub atomically subtracts from the wrapped time.Duration and returns the new value.
+func (d *Duration) Sub(delta time.Duration) time.Duration {
+ return time.Duration(d.v.Sub(int64(delta)))
+}
+
+// String encodes the wrapped value as a string.
+func (d *Duration) String() string {
+ return d.Load().String()
+}
diff --git a/vendor/go.uber.org/atomic/error.go b/vendor/go.uber.org/atomic/error.go
index 0489d19..b7e3f12 100644
--- a/vendor/go.uber.org/atomic/error.go
+++ b/vendor/go.uber.org/atomic/error.go
@@ -1,4 +1,6 @@
-// Copyright (c) 2016 Uber Technologies, Inc.
+// @generated Code generated by gen-atomicwrapper.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -20,36 +22,51 @@
package atomic
-// Error is an atomic type-safe wrapper around Value for errors
-type Error struct{ v Value }
+// Error is an atomic type-safe wrapper for error values.
+type Error struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v Value
+}
-// errorHolder is non-nil holder for error object.
-// atomic.Value panics on saving nil object, so err object needs to be
-// wrapped with valid object first.
-type errorHolder struct{ err error }
+var _zeroError error
-// NewError creates new atomic error object
-func NewError(err error) *Error {
- e := &Error{}
- if err != nil {
- e.Store(err)
+// NewError creates a new Error.
+func NewError(val error) *Error {
+ x := &Error{}
+ if val != _zeroError {
+ x.Store(val)
}
- return e
+ return x
+}
+
+// Load atomically loads the wrapped error.
+func (x *Error) Load() error {
+ return unpackError(x.v.Load())
}
-// Load atomically loads the wrapped error
-func (e *Error) Load() error {
- v := e.v.Load()
- if v == nil {
- return nil
+// Store atomically stores the passed error.
+func (x *Error) Store(val error) {
+ x.v.Store(packError(val))
+}
+
+// CompareAndSwap is an atomic compare-and-swap for error values.
+func (x *Error) CompareAndSwap(old, new error) (swapped bool) {
+ if x.v.CompareAndSwap(packError(old), packError(new)) {
+ return true
+ }
+
+ if old == _zeroError {
+ // If the old value is the empty value, then it's possible the
+ // underlying Value hasn't been set and is nil, so retry with nil.
+ return x.v.CompareAndSwap(nil, packError(new))
}
- eh := v.(errorHolder)
- return eh.err
+ return false
}
-// Store atomically stores error.
-// NOTE: a holder object is allocated on each Store call.
-func (e *Error) Store(err error) {
- e.v.Store(errorHolder{err: err})
+// Swap atomically stores the given error and returns the old
+// value.
+func (x *Error) Swap(val error) (old error) {
+ return unpackError(x.v.Swap(packError(val)))
}
diff --git a/vendor/go.uber.org/atomic/error_ext.go b/vendor/go.uber.org/atomic/error_ext.go
new file mode 100644
index 0000000..d31fb63
--- /dev/null
+++ b/vendor/go.uber.org/atomic/error_ext.go
@@ -0,0 +1,39 @@
+// Copyright (c) 2020-2022 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+// atomic.Value panics on nil inputs, or if the underlying type changes.
+// Stabilize by always storing a custom struct that we control.
+
+//go:generate bin/gen-atomicwrapper -name=Error -type=error -wrapped=Value -pack=packError -unpack=unpackError -compareandswap -swap -file=error.go
+
+type packedError struct{ Value error }
+
+func packError(v error) interface{} {
+ return packedError{v}
+}
+
+func unpackError(v interface{}) error {
+ if err, ok := v.(packedError); ok {
+ return err.Value
+ }
+ return nil
+}
diff --git a/vendor/go.uber.org/atomic/float32.go b/vendor/go.uber.org/atomic/float32.go
new file mode 100644
index 0000000..62c3633
--- /dev/null
+++ b/vendor/go.uber.org/atomic/float32.go
@@ -0,0 +1,77 @@
+// @generated Code generated by gen-atomicwrapper.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "encoding/json"
+ "math"
+)
+
+// Float32 is an atomic type-safe wrapper for float32 values.
+type Float32 struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v Uint32
+}
+
+var _zeroFloat32 float32
+
+// NewFloat32 creates a new Float32.
+func NewFloat32(val float32) *Float32 {
+ x := &Float32{}
+ if val != _zeroFloat32 {
+ x.Store(val)
+ }
+ return x
+}
+
+// Load atomically loads the wrapped float32.
+func (x *Float32) Load() float32 {
+ return math.Float32frombits(x.v.Load())
+}
+
+// Store atomically stores the passed float32.
+func (x *Float32) Store(val float32) {
+ x.v.Store(math.Float32bits(val))
+}
+
+// Swap atomically stores the given float32 and returns the old
+// value.
+func (x *Float32) Swap(val float32) (old float32) {
+ return math.Float32frombits(x.v.Swap(math.Float32bits(val)))
+}
+
+// MarshalJSON encodes the wrapped float32 into JSON.
+func (x *Float32) MarshalJSON() ([]byte, error) {
+ return json.Marshal(x.Load())
+}
+
+// UnmarshalJSON decodes a float32 from JSON.
+func (x *Float32) UnmarshalJSON(b []byte) error {
+ var v float32
+ if err := json.Unmarshal(b, &v); err != nil {
+ return err
+ }
+ x.Store(v)
+ return nil
+}
diff --git a/vendor/go.uber.org/atomic/float32_ext.go b/vendor/go.uber.org/atomic/float32_ext.go
new file mode 100644
index 0000000..b0cd8d9
--- /dev/null
+++ b/vendor/go.uber.org/atomic/float32_ext.go
@@ -0,0 +1,76 @@
+// Copyright (c) 2020-2022 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "math"
+ "strconv"
+)
+
+//go:generate bin/gen-atomicwrapper -name=Float32 -type=float32 -wrapped=Uint32 -pack=math.Float32bits -unpack=math.Float32frombits -swap -json -imports math -file=float32.go
+
+// Add atomically adds to the wrapped float32 and returns the new value.
+func (f *Float32) Add(delta float32) float32 {
+ for {
+ old := f.Load()
+ new := old + delta
+ if f.CAS(old, new) {
+ return new
+ }
+ }
+}
+
+// Sub atomically subtracts from the wrapped float32 and returns the new value.
+func (f *Float32) Sub(delta float32) float32 {
+ return f.Add(-delta)
+}
+
+// CAS is an atomic compare-and-swap for float32 values.
+//
+// Deprecated: Use CompareAndSwap
+func (f *Float32) CAS(old, new float32) (swapped bool) {
+ return f.CompareAndSwap(old, new)
+}
+
+// CompareAndSwap is an atomic compare-and-swap for float32 values.
+//
+// Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators
+// but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN.
+// This avoids typical CompareAndSwap loops from blocking forever, e.g.,
+//
+// for {
+// old := atom.Load()
+// new = f(old)
+// if atom.CompareAndSwap(old, new) {
+// break
+// }
+// }
+//
+// If CompareAndSwap did not match NaN to match, then the above would loop forever.
+func (f *Float32) CompareAndSwap(old, new float32) (swapped bool) {
+ return f.v.CompareAndSwap(math.Float32bits(old), math.Float32bits(new))
+}
+
+// String encodes the wrapped value as a string.
+func (f *Float32) String() string {
+ // 'g' is the behavior for floats with %v.
+ return strconv.FormatFloat(float64(f.Load()), 'g', -1, 32)
+}
diff --git a/vendor/go.uber.org/atomic/float64.go b/vendor/go.uber.org/atomic/float64.go
new file mode 100644
index 0000000..5bc11ca
--- /dev/null
+++ b/vendor/go.uber.org/atomic/float64.go
@@ -0,0 +1,77 @@
+// @generated Code generated by gen-atomicwrapper.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "encoding/json"
+ "math"
+)
+
+// Float64 is an atomic type-safe wrapper for float64 values.
+type Float64 struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v Uint64
+}
+
+var _zeroFloat64 float64
+
+// NewFloat64 creates a new Float64.
+func NewFloat64(val float64) *Float64 {
+ x := &Float64{}
+ if val != _zeroFloat64 {
+ x.Store(val)
+ }
+ return x
+}
+
+// Load atomically loads the wrapped float64.
+func (x *Float64) Load() float64 {
+ return math.Float64frombits(x.v.Load())
+}
+
+// Store atomically stores the passed float64.
+func (x *Float64) Store(val float64) {
+ x.v.Store(math.Float64bits(val))
+}
+
+// Swap atomically stores the given float64 and returns the old
+// value.
+func (x *Float64) Swap(val float64) (old float64) {
+ return math.Float64frombits(x.v.Swap(math.Float64bits(val)))
+}
+
+// MarshalJSON encodes the wrapped float64 into JSON.
+func (x *Float64) MarshalJSON() ([]byte, error) {
+ return json.Marshal(x.Load())
+}
+
+// UnmarshalJSON decodes a float64 from JSON.
+func (x *Float64) UnmarshalJSON(b []byte) error {
+ var v float64
+ if err := json.Unmarshal(b, &v); err != nil {
+ return err
+ }
+ x.Store(v)
+ return nil
+}
diff --git a/vendor/go.uber.org/atomic/float64_ext.go b/vendor/go.uber.org/atomic/float64_ext.go
new file mode 100644
index 0000000..48c52b0
--- /dev/null
+++ b/vendor/go.uber.org/atomic/float64_ext.go
@@ -0,0 +1,76 @@
+// Copyright (c) 2020-2022 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "math"
+ "strconv"
+)
+
+//go:generate bin/gen-atomicwrapper -name=Float64 -type=float64 -wrapped=Uint64 -pack=math.Float64bits -unpack=math.Float64frombits -swap -json -imports math -file=float64.go
+
+// Add atomically adds to the wrapped float64 and returns the new value.
+func (f *Float64) Add(delta float64) float64 {
+ for {
+ old := f.Load()
+ new := old + delta
+ if f.CAS(old, new) {
+ return new
+ }
+ }
+}
+
+// Sub atomically subtracts from the wrapped float64 and returns the new value.
+func (f *Float64) Sub(delta float64) float64 {
+ return f.Add(-delta)
+}
+
+// CAS is an atomic compare-and-swap for float64 values.
+//
+// Deprecated: Use CompareAndSwap
+func (f *Float64) CAS(old, new float64) (swapped bool) {
+ return f.CompareAndSwap(old, new)
+}
+
+// CompareAndSwap is an atomic compare-and-swap for float64 values.
+//
+// Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators
+// but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN.
+// This avoids typical CompareAndSwap loops from blocking forever, e.g.,
+//
+// for {
+// old := atom.Load()
+// new = f(old)
+// if atom.CompareAndSwap(old, new) {
+// break
+// }
+// }
+//
+// If CompareAndSwap did not match NaN to match, then the above would loop forever.
+func (f *Float64) CompareAndSwap(old, new float64) (swapped bool) {
+ return f.v.CompareAndSwap(math.Float64bits(old), math.Float64bits(new))
+}
+
+// String encodes the wrapped value as a string.
+func (f *Float64) String() string {
+ // 'g' is the behavior for floats with %v.
+ return strconv.FormatFloat(f.Load(), 'g', -1, 64)
+}
diff --git a/vendor/go.uber.org/atomic/gen.go b/vendor/go.uber.org/atomic/gen.go
new file mode 100644
index 0000000..1e9ef4f
--- /dev/null
+++ b/vendor/go.uber.org/atomic/gen.go
@@ -0,0 +1,27 @@
+// Copyright (c) 2020 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+//go:generate bin/gen-atomicint -name=Int32 -wrapped=int32 -file=int32.go
+//go:generate bin/gen-atomicint -name=Int64 -wrapped=int64 -file=int64.go
+//go:generate bin/gen-atomicint -name=Uint32 -wrapped=uint32 -unsigned -file=uint32.go
+//go:generate bin/gen-atomicint -name=Uint64 -wrapped=uint64 -unsigned -file=uint64.go
+//go:generate bin/gen-atomicint -name=Uintptr -wrapped=uintptr -unsigned -file=uintptr.go
diff --git a/vendor/go.uber.org/atomic/go.mod b/vendor/go.uber.org/atomic/go.mod
deleted file mode 100644
index a935dae..0000000
--- a/vendor/go.uber.org/atomic/go.mod
+++ /dev/null
@@ -1,10 +0,0 @@
-module go.uber.org/atomic
-
-require (
- github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/stretchr/testify v1.3.0
- golang.org/x/lint v0.0.0-20190930215403-16217165b5de
- golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c // indirect
-)
-
-go 1.13
diff --git a/vendor/go.uber.org/atomic/go.sum b/vendor/go.uber.org/atomic/go.sum
deleted file mode 100644
index 51b2b62..0000000
--- a/vendor/go.uber.org/atomic/go.sum
+++ /dev/null
@@ -1,22 +0,0 @@
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
-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/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/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c h1:IGkKhmfzcztjm6gYkykvu/NiS8kaqbCWAEWWAyf8J5U=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/vendor/go.uber.org/atomic/int32.go b/vendor/go.uber.org/atomic/int32.go
new file mode 100644
index 0000000..5320eac
--- /dev/null
+++ b/vendor/go.uber.org/atomic/int32.go
@@ -0,0 +1,109 @@
+// @generated Code generated by gen-atomicint.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "encoding/json"
+ "strconv"
+ "sync/atomic"
+)
+
+// Int32 is an atomic wrapper around int32.
+type Int32 struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v int32
+}
+
+// NewInt32 creates a new Int32.
+func NewInt32(val int32) *Int32 {
+ return &Int32{v: val}
+}
+
+// Load atomically loads the wrapped value.
+func (i *Int32) Load() int32 {
+ return atomic.LoadInt32(&i.v)
+}
+
+// Add atomically adds to the wrapped int32 and returns the new value.
+func (i *Int32) Add(delta int32) int32 {
+ return atomic.AddInt32(&i.v, delta)
+}
+
+// Sub atomically subtracts from the wrapped int32 and returns the new value.
+func (i *Int32) Sub(delta int32) int32 {
+ return atomic.AddInt32(&i.v, -delta)
+}
+
+// Inc atomically increments the wrapped int32 and returns the new value.
+func (i *Int32) Inc() int32 {
+ return i.Add(1)
+}
+
+// Dec atomically decrements the wrapped int32 and returns the new value.
+func (i *Int32) Dec() int32 {
+ return i.Sub(1)
+}
+
+// CAS is an atomic compare-and-swap.
+//
+// Deprecated: Use CompareAndSwap.
+func (i *Int32) CAS(old, new int32) (swapped bool) {
+ return i.CompareAndSwap(old, new)
+}
+
+// CompareAndSwap is an atomic compare-and-swap.
+func (i *Int32) CompareAndSwap(old, new int32) (swapped bool) {
+ return atomic.CompareAndSwapInt32(&i.v, old, new)
+}
+
+// Store atomically stores the passed value.
+func (i *Int32) Store(val int32) {
+ atomic.StoreInt32(&i.v, val)
+}
+
+// Swap atomically swaps the wrapped int32 and returns the old value.
+func (i *Int32) Swap(val int32) (old int32) {
+ return atomic.SwapInt32(&i.v, val)
+}
+
+// MarshalJSON encodes the wrapped int32 into JSON.
+func (i *Int32) MarshalJSON() ([]byte, error) {
+ return json.Marshal(i.Load())
+}
+
+// UnmarshalJSON decodes JSON into the wrapped int32.
+func (i *Int32) UnmarshalJSON(b []byte) error {
+ var v int32
+ if err := json.Unmarshal(b, &v); err != nil {
+ return err
+ }
+ i.Store(v)
+ return nil
+}
+
+// String encodes the wrapped value as a string.
+func (i *Int32) String() string {
+ v := i.Load()
+ return strconv.FormatInt(int64(v), 10)
+}
diff --git a/vendor/go.uber.org/atomic/int64.go b/vendor/go.uber.org/atomic/int64.go
new file mode 100644
index 0000000..460821d
--- /dev/null
+++ b/vendor/go.uber.org/atomic/int64.go
@@ -0,0 +1,109 @@
+// @generated Code generated by gen-atomicint.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "encoding/json"
+ "strconv"
+ "sync/atomic"
+)
+
+// Int64 is an atomic wrapper around int64.
+type Int64 struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v int64
+}
+
+// NewInt64 creates a new Int64.
+func NewInt64(val int64) *Int64 {
+ return &Int64{v: val}
+}
+
+// Load atomically loads the wrapped value.
+func (i *Int64) Load() int64 {
+ return atomic.LoadInt64(&i.v)
+}
+
+// Add atomically adds to the wrapped int64 and returns the new value.
+func (i *Int64) Add(delta int64) int64 {
+ return atomic.AddInt64(&i.v, delta)
+}
+
+// Sub atomically subtracts from the wrapped int64 and returns the new value.
+func (i *Int64) Sub(delta int64) int64 {
+ return atomic.AddInt64(&i.v, -delta)
+}
+
+// Inc atomically increments the wrapped int64 and returns the new value.
+func (i *Int64) Inc() int64 {
+ return i.Add(1)
+}
+
+// Dec atomically decrements the wrapped int64 and returns the new value.
+func (i *Int64) Dec() int64 {
+ return i.Sub(1)
+}
+
+// CAS is an atomic compare-and-swap.
+//
+// Deprecated: Use CompareAndSwap.
+func (i *Int64) CAS(old, new int64) (swapped bool) {
+ return i.CompareAndSwap(old, new)
+}
+
+// CompareAndSwap is an atomic compare-and-swap.
+func (i *Int64) CompareAndSwap(old, new int64) (swapped bool) {
+ return atomic.CompareAndSwapInt64(&i.v, old, new)
+}
+
+// Store atomically stores the passed value.
+func (i *Int64) Store(val int64) {
+ atomic.StoreInt64(&i.v, val)
+}
+
+// Swap atomically swaps the wrapped int64 and returns the old value.
+func (i *Int64) Swap(val int64) (old int64) {
+ return atomic.SwapInt64(&i.v, val)
+}
+
+// MarshalJSON encodes the wrapped int64 into JSON.
+func (i *Int64) MarshalJSON() ([]byte, error) {
+ return json.Marshal(i.Load())
+}
+
+// UnmarshalJSON decodes JSON into the wrapped int64.
+func (i *Int64) UnmarshalJSON(b []byte) error {
+ var v int64
+ if err := json.Unmarshal(b, &v); err != nil {
+ return err
+ }
+ i.Store(v)
+ return nil
+}
+
+// String encodes the wrapped value as a string.
+func (i *Int64) String() string {
+ v := i.Load()
+ return strconv.FormatInt(int64(v), 10)
+}
diff --git a/vendor/go.uber.org/atomic/nocmp.go b/vendor/go.uber.org/atomic/nocmp.go
new file mode 100644
index 0000000..54b7417
--- /dev/null
+++ b/vendor/go.uber.org/atomic/nocmp.go
@@ -0,0 +1,35 @@
+// Copyright (c) 2020 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+// nocmp is an uncomparable struct. Embed this inside another struct to make
+// it uncomparable.
+//
+// type Foo struct {
+// nocmp
+// // ...
+// }
+//
+// This DOES NOT:
+//
+// - Disallow shallow copies of structs
+// - Disallow comparison of pointers to uncomparable structs
+type nocmp [0]func()
diff --git a/vendor/go.uber.org/atomic/pointer_go118.go b/vendor/go.uber.org/atomic/pointer_go118.go
new file mode 100644
index 0000000..1fb6c03
--- /dev/null
+++ b/vendor/go.uber.org/atomic/pointer_go118.go
@@ -0,0 +1,31 @@
+// Copyright (c) 2022 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+//go:build go1.18
+// +build go1.18
+
+package atomic
+
+import "fmt"
+
+// String returns a human readable representation of a Pointer's underlying value.
+func (p *Pointer[T]) String() string {
+ return fmt.Sprint(p.Load())
+}
diff --git a/vendor/go.uber.org/atomic/pointer_go118_pre119.go b/vendor/go.uber.org/atomic/pointer_go118_pre119.go
new file mode 100644
index 0000000..e0f47db
--- /dev/null
+++ b/vendor/go.uber.org/atomic/pointer_go118_pre119.go
@@ -0,0 +1,60 @@
+// Copyright (c) 2022 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+//go:build go1.18 && !go1.19
+// +build go1.18,!go1.19
+
+package atomic
+
+import "unsafe"
+
+type Pointer[T any] struct {
+ _ nocmp // disallow non-atomic comparison
+ p UnsafePointer
+}
+
+// NewPointer creates a new Pointer.
+func NewPointer[T any](v *T) *Pointer[T] {
+ var p Pointer[T]
+ if v != nil {
+ p.p.Store(unsafe.Pointer(v))
+ }
+ return &p
+}
+
+// Load atomically loads the wrapped value.
+func (p *Pointer[T]) Load() *T {
+ return (*T)(p.p.Load())
+}
+
+// Store atomically stores the passed value.
+func (p *Pointer[T]) Store(val *T) {
+ p.p.Store(unsafe.Pointer(val))
+}
+
+// Swap atomically swaps the wrapped pointer and returns the old value.
+func (p *Pointer[T]) Swap(val *T) (old *T) {
+ return (*T)(p.p.Swap(unsafe.Pointer(val)))
+}
+
+// CompareAndSwap is an atomic compare-and-swap.
+func (p *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) {
+ return p.p.CompareAndSwap(unsafe.Pointer(old), unsafe.Pointer(new))
+}
diff --git a/vendor/go.uber.org/atomic/pointer_go119.go b/vendor/go.uber.org/atomic/pointer_go119.go
new file mode 100644
index 0000000..6726f17
--- /dev/null
+++ b/vendor/go.uber.org/atomic/pointer_go119.go
@@ -0,0 +1,61 @@
+// Copyright (c) 2022 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+//go:build go1.19
+// +build go1.19
+
+package atomic
+
+import "sync/atomic"
+
+// Pointer is an atomic pointer of type *T.
+type Pointer[T any] struct {
+ _ nocmp // disallow non-atomic comparison
+ p atomic.Pointer[T]
+}
+
+// NewPointer creates a new Pointer.
+func NewPointer[T any](v *T) *Pointer[T] {
+ var p Pointer[T]
+ if v != nil {
+ p.p.Store(v)
+ }
+ return &p
+}
+
+// Load atomically loads the wrapped value.
+func (p *Pointer[T]) Load() *T {
+ return p.p.Load()
+}
+
+// Store atomically stores the passed value.
+func (p *Pointer[T]) Store(val *T) {
+ p.p.Store(val)
+}
+
+// Swap atomically swaps the wrapped pointer and returns the old value.
+func (p *Pointer[T]) Swap(val *T) (old *T) {
+ return p.p.Swap(val)
+}
+
+// CompareAndSwap is an atomic compare-and-swap.
+func (p *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) {
+ return p.p.CompareAndSwap(old, new)
+}
diff --git a/vendor/go.uber.org/atomic/string.go b/vendor/go.uber.org/atomic/string.go
index ede8136..061466c 100644
--- a/vendor/go.uber.org/atomic/string.go
+++ b/vendor/go.uber.org/atomic/string.go
@@ -1,4 +1,6 @@
-// Copyright (c) 2016 Uber Technologies, Inc.
+// @generated Code generated by gen-atomicwrapper.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -20,30 +22,51 @@
package atomic
-// String is an atomic type-safe wrapper around Value for strings.
-type String struct{ v Value }
+// String is an atomic type-safe wrapper for string values.
+type String struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v Value
+}
+
+var _zeroString string
-// NewString creates a String.
-func NewString(str string) *String {
- s := &String{}
- if str != "" {
- s.Store(str)
+// NewString creates a new String.
+func NewString(val string) *String {
+ x := &String{}
+ if val != _zeroString {
+ x.Store(val)
}
- return s
+ return x
}
// Load atomically loads the wrapped string.
-func (s *String) Load() string {
- v := s.v.Load()
- if v == nil {
- return ""
- }
- return v.(string)
+func (x *String) Load() string {
+ return unpackString(x.v.Load())
}
// Store atomically stores the passed string.
-// Note: Converting the string to an interface{} to store in the Value
-// requires an allocation.
-func (s *String) Store(str string) {
- s.v.Store(str)
+func (x *String) Store(val string) {
+ x.v.Store(packString(val))
+}
+
+// CompareAndSwap is an atomic compare-and-swap for string values.
+func (x *String) CompareAndSwap(old, new string) (swapped bool) {
+ if x.v.CompareAndSwap(packString(old), packString(new)) {
+ return true
+ }
+
+ if old == _zeroString {
+ // If the old value is the empty value, then it's possible the
+ // underlying Value hasn't been set and is nil, so retry with nil.
+ return x.v.CompareAndSwap(nil, packString(new))
+ }
+
+ return false
+}
+
+// Swap atomically stores the given string and returns the old
+// value.
+func (x *String) Swap(val string) (old string) {
+ return unpackString(x.v.Swap(packString(val)))
}
diff --git a/vendor/go.uber.org/atomic/string_ext.go b/vendor/go.uber.org/atomic/string_ext.go
new file mode 100644
index 0000000..019109c
--- /dev/null
+++ b/vendor/go.uber.org/atomic/string_ext.go
@@ -0,0 +1,54 @@
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+//go:generate bin/gen-atomicwrapper -name=String -type=string -wrapped Value -pack packString -unpack unpackString -compareandswap -swap -file=string.go
+
+func packString(s string) interface{} {
+ return s
+}
+
+func unpackString(v interface{}) string {
+ if s, ok := v.(string); ok {
+ return s
+ }
+ return ""
+}
+
+// String returns the wrapped value.
+func (s *String) String() string {
+ return s.Load()
+}
+
+// MarshalText encodes the wrapped string into a textual form.
+//
+// This makes it encodable as JSON, YAML, XML, and more.
+func (s *String) MarshalText() ([]byte, error) {
+ return []byte(s.Load()), nil
+}
+
+// UnmarshalText decodes text and replaces the wrapped string with it.
+//
+// This makes it decodable from JSON, YAML, XML, and more.
+func (s *String) UnmarshalText(b []byte) error {
+ s.Store(string(b))
+ return nil
+}
diff --git a/vendor/go.uber.org/atomic/time.go b/vendor/go.uber.org/atomic/time.go
new file mode 100644
index 0000000..cc2a230
--- /dev/null
+++ b/vendor/go.uber.org/atomic/time.go
@@ -0,0 +1,55 @@
+// @generated Code generated by gen-atomicwrapper.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "time"
+)
+
+// Time is an atomic type-safe wrapper for time.Time values.
+type Time struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v Value
+}
+
+var _zeroTime time.Time
+
+// NewTime creates a new Time.
+func NewTime(val time.Time) *Time {
+ x := &Time{}
+ if val != _zeroTime {
+ x.Store(val)
+ }
+ return x
+}
+
+// Load atomically loads the wrapped time.Time.
+func (x *Time) Load() time.Time {
+ return unpackTime(x.v.Load())
+}
+
+// Store atomically stores the passed time.Time.
+func (x *Time) Store(val time.Time) {
+ x.v.Store(packTime(val))
+}
diff --git a/vendor/go.uber.org/atomic/time_ext.go b/vendor/go.uber.org/atomic/time_ext.go
new file mode 100644
index 0000000..1e3dc97
--- /dev/null
+++ b/vendor/go.uber.org/atomic/time_ext.go
@@ -0,0 +1,36 @@
+// Copyright (c) 2021 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import "time"
+
+//go:generate bin/gen-atomicwrapper -name=Time -type=time.Time -wrapped=Value -pack=packTime -unpack=unpackTime -imports time -file=time.go
+
+func packTime(t time.Time) interface{} {
+ return t
+}
+
+func unpackTime(v interface{}) time.Time {
+ if t, ok := v.(time.Time); ok {
+ return t
+ }
+ return time.Time{}
+}
diff --git a/vendor/go.uber.org/atomic/uint32.go b/vendor/go.uber.org/atomic/uint32.go
new file mode 100644
index 0000000..4adc294
--- /dev/null
+++ b/vendor/go.uber.org/atomic/uint32.go
@@ -0,0 +1,109 @@
+// @generated Code generated by gen-atomicint.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "encoding/json"
+ "strconv"
+ "sync/atomic"
+)
+
+// Uint32 is an atomic wrapper around uint32.
+type Uint32 struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v uint32
+}
+
+// NewUint32 creates a new Uint32.
+func NewUint32(val uint32) *Uint32 {
+ return &Uint32{v: val}
+}
+
+// Load atomically loads the wrapped value.
+func (i *Uint32) Load() uint32 {
+ return atomic.LoadUint32(&i.v)
+}
+
+// Add atomically adds to the wrapped uint32 and returns the new value.
+func (i *Uint32) Add(delta uint32) uint32 {
+ return atomic.AddUint32(&i.v, delta)
+}
+
+// Sub atomically subtracts from the wrapped uint32 and returns the new value.
+func (i *Uint32) Sub(delta uint32) uint32 {
+ return atomic.AddUint32(&i.v, ^(delta - 1))
+}
+
+// Inc atomically increments the wrapped uint32 and returns the new value.
+func (i *Uint32) Inc() uint32 {
+ return i.Add(1)
+}
+
+// Dec atomically decrements the wrapped uint32 and returns the new value.
+func (i *Uint32) Dec() uint32 {
+ return i.Sub(1)
+}
+
+// CAS is an atomic compare-and-swap.
+//
+// Deprecated: Use CompareAndSwap.
+func (i *Uint32) CAS(old, new uint32) (swapped bool) {
+ return i.CompareAndSwap(old, new)
+}
+
+// CompareAndSwap is an atomic compare-and-swap.
+func (i *Uint32) CompareAndSwap(old, new uint32) (swapped bool) {
+ return atomic.CompareAndSwapUint32(&i.v, old, new)
+}
+
+// Store atomically stores the passed value.
+func (i *Uint32) Store(val uint32) {
+ atomic.StoreUint32(&i.v, val)
+}
+
+// Swap atomically swaps the wrapped uint32 and returns the old value.
+func (i *Uint32) Swap(val uint32) (old uint32) {
+ return atomic.SwapUint32(&i.v, val)
+}
+
+// MarshalJSON encodes the wrapped uint32 into JSON.
+func (i *Uint32) MarshalJSON() ([]byte, error) {
+ return json.Marshal(i.Load())
+}
+
+// UnmarshalJSON decodes JSON into the wrapped uint32.
+func (i *Uint32) UnmarshalJSON(b []byte) error {
+ var v uint32
+ if err := json.Unmarshal(b, &v); err != nil {
+ return err
+ }
+ i.Store(v)
+ return nil
+}
+
+// String encodes the wrapped value as a string.
+func (i *Uint32) String() string {
+ v := i.Load()
+ return strconv.FormatUint(uint64(v), 10)
+}
diff --git a/vendor/go.uber.org/atomic/uint64.go b/vendor/go.uber.org/atomic/uint64.go
new file mode 100644
index 0000000..0e2eddb
--- /dev/null
+++ b/vendor/go.uber.org/atomic/uint64.go
@@ -0,0 +1,109 @@
+// @generated Code generated by gen-atomicint.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "encoding/json"
+ "strconv"
+ "sync/atomic"
+)
+
+// Uint64 is an atomic wrapper around uint64.
+type Uint64 struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v uint64
+}
+
+// NewUint64 creates a new Uint64.
+func NewUint64(val uint64) *Uint64 {
+ return &Uint64{v: val}
+}
+
+// Load atomically loads the wrapped value.
+func (i *Uint64) Load() uint64 {
+ return atomic.LoadUint64(&i.v)
+}
+
+// Add atomically adds to the wrapped uint64 and returns the new value.
+func (i *Uint64) Add(delta uint64) uint64 {
+ return atomic.AddUint64(&i.v, delta)
+}
+
+// Sub atomically subtracts from the wrapped uint64 and returns the new value.
+func (i *Uint64) Sub(delta uint64) uint64 {
+ return atomic.AddUint64(&i.v, ^(delta - 1))
+}
+
+// Inc atomically increments the wrapped uint64 and returns the new value.
+func (i *Uint64) Inc() uint64 {
+ return i.Add(1)
+}
+
+// Dec atomically decrements the wrapped uint64 and returns the new value.
+func (i *Uint64) Dec() uint64 {
+ return i.Sub(1)
+}
+
+// CAS is an atomic compare-and-swap.
+//
+// Deprecated: Use CompareAndSwap.
+func (i *Uint64) CAS(old, new uint64) (swapped bool) {
+ return i.CompareAndSwap(old, new)
+}
+
+// CompareAndSwap is an atomic compare-and-swap.
+func (i *Uint64) CompareAndSwap(old, new uint64) (swapped bool) {
+ return atomic.CompareAndSwapUint64(&i.v, old, new)
+}
+
+// Store atomically stores the passed value.
+func (i *Uint64) Store(val uint64) {
+ atomic.StoreUint64(&i.v, val)
+}
+
+// Swap atomically swaps the wrapped uint64 and returns the old value.
+func (i *Uint64) Swap(val uint64) (old uint64) {
+ return atomic.SwapUint64(&i.v, val)
+}
+
+// MarshalJSON encodes the wrapped uint64 into JSON.
+func (i *Uint64) MarshalJSON() ([]byte, error) {
+ return json.Marshal(i.Load())
+}
+
+// UnmarshalJSON decodes JSON into the wrapped uint64.
+func (i *Uint64) UnmarshalJSON(b []byte) error {
+ var v uint64
+ if err := json.Unmarshal(b, &v); err != nil {
+ return err
+ }
+ i.Store(v)
+ return nil
+}
+
+// String encodes the wrapped value as a string.
+func (i *Uint64) String() string {
+ v := i.Load()
+ return strconv.FormatUint(uint64(v), 10)
+}
diff --git a/vendor/go.uber.org/atomic/uintptr.go b/vendor/go.uber.org/atomic/uintptr.go
new file mode 100644
index 0000000..7d5b000
--- /dev/null
+++ b/vendor/go.uber.org/atomic/uintptr.go
@@ -0,0 +1,109 @@
+// @generated Code generated by gen-atomicint.
+
+// Copyright (c) 2020-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "encoding/json"
+ "strconv"
+ "sync/atomic"
+)
+
+// Uintptr is an atomic wrapper around uintptr.
+type Uintptr struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v uintptr
+}
+
+// NewUintptr creates a new Uintptr.
+func NewUintptr(val uintptr) *Uintptr {
+ return &Uintptr{v: val}
+}
+
+// Load atomically loads the wrapped value.
+func (i *Uintptr) Load() uintptr {
+ return atomic.LoadUintptr(&i.v)
+}
+
+// Add atomically adds to the wrapped uintptr and returns the new value.
+func (i *Uintptr) Add(delta uintptr) uintptr {
+ return atomic.AddUintptr(&i.v, delta)
+}
+
+// Sub atomically subtracts from the wrapped uintptr and returns the new value.
+func (i *Uintptr) Sub(delta uintptr) uintptr {
+ return atomic.AddUintptr(&i.v, ^(delta - 1))
+}
+
+// Inc atomically increments the wrapped uintptr and returns the new value.
+func (i *Uintptr) Inc() uintptr {
+ return i.Add(1)
+}
+
+// Dec atomically decrements the wrapped uintptr and returns the new value.
+func (i *Uintptr) Dec() uintptr {
+ return i.Sub(1)
+}
+
+// CAS is an atomic compare-and-swap.
+//
+// Deprecated: Use CompareAndSwap.
+func (i *Uintptr) CAS(old, new uintptr) (swapped bool) {
+ return i.CompareAndSwap(old, new)
+}
+
+// CompareAndSwap is an atomic compare-and-swap.
+func (i *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) {
+ return atomic.CompareAndSwapUintptr(&i.v, old, new)
+}
+
+// Store atomically stores the passed value.
+func (i *Uintptr) Store(val uintptr) {
+ atomic.StoreUintptr(&i.v, val)
+}
+
+// Swap atomically swaps the wrapped uintptr and returns the old value.
+func (i *Uintptr) Swap(val uintptr) (old uintptr) {
+ return atomic.SwapUintptr(&i.v, val)
+}
+
+// MarshalJSON encodes the wrapped uintptr into JSON.
+func (i *Uintptr) MarshalJSON() ([]byte, error) {
+ return json.Marshal(i.Load())
+}
+
+// UnmarshalJSON decodes JSON into the wrapped uintptr.
+func (i *Uintptr) UnmarshalJSON(b []byte) error {
+ var v uintptr
+ if err := json.Unmarshal(b, &v); err != nil {
+ return err
+ }
+ i.Store(v)
+ return nil
+}
+
+// String encodes the wrapped value as a string.
+func (i *Uintptr) String() string {
+ v := i.Load()
+ return strconv.FormatUint(uint64(v), 10)
+}
diff --git a/vendor/go.uber.org/atomic/unsafe_pointer.go b/vendor/go.uber.org/atomic/unsafe_pointer.go
new file mode 100644
index 0000000..34868ba
--- /dev/null
+++ b/vendor/go.uber.org/atomic/unsafe_pointer.go
@@ -0,0 +1,65 @@
+// Copyright (c) 2021-2022 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import (
+ "sync/atomic"
+ "unsafe"
+)
+
+// UnsafePointer is an atomic wrapper around unsafe.Pointer.
+type UnsafePointer struct {
+ _ nocmp // disallow non-atomic comparison
+
+ v unsafe.Pointer
+}
+
+// NewUnsafePointer creates a new UnsafePointer.
+func NewUnsafePointer(val unsafe.Pointer) *UnsafePointer {
+ return &UnsafePointer{v: val}
+}
+
+// Load atomically loads the wrapped value.
+func (p *UnsafePointer) Load() unsafe.Pointer {
+ return atomic.LoadPointer(&p.v)
+}
+
+// Store atomically stores the passed value.
+func (p *UnsafePointer) Store(val unsafe.Pointer) {
+ atomic.StorePointer(&p.v, val)
+}
+
+// Swap atomically swaps the wrapped unsafe.Pointer and returns the old value.
+func (p *UnsafePointer) Swap(val unsafe.Pointer) (old unsafe.Pointer) {
+ return atomic.SwapPointer(&p.v, val)
+}
+
+// CAS is an atomic compare-and-swap.
+//
+// Deprecated: Use CompareAndSwap
+func (p *UnsafePointer) CAS(old, new unsafe.Pointer) (swapped bool) {
+ return p.CompareAndSwap(old, new)
+}
+
+// CompareAndSwap is an atomic compare-and-swap.
+func (p *UnsafePointer) CompareAndSwap(old, new unsafe.Pointer) (swapped bool) {
+ return atomic.CompareAndSwapPointer(&p.v, old, new)
+}
diff --git a/vendor/go.uber.org/atomic/value.go b/vendor/go.uber.org/atomic/value.go
new file mode 100644
index 0000000..52caedb
--- /dev/null
+++ b/vendor/go.uber.org/atomic/value.go
@@ -0,0 +1,31 @@
+// Copyright (c) 2020 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package atomic
+
+import "sync/atomic"
+
+// Value shadows the type of the same name from sync/atomic
+// https://godoc.org/sync/atomic#Value
+type Value struct {
+ _ nocmp // disallow non-atomic comparison
+
+ atomic.Value
+}
diff --git a/vendor/golang.org/x/crypto/AUTHORS b/vendor/golang.org/x/crypto/AUTHORS
deleted file mode 100644
index 2b00ddb..0000000
--- a/vendor/golang.org/x/crypto/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at https://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/crypto/CONTRIBUTORS b/vendor/golang.org/x/crypto/CONTRIBUTORS
deleted file mode 100644
index 1fbd3e9..0000000
--- a/vendor/golang.org/x/crypto/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at https://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/crypto/cryptobyte/asn1.go b/vendor/golang.org/x/crypto/cryptobyte/asn1.go
index d3596ee..6fc2838 100644
--- a/vendor/golang.org/x/crypto/cryptobyte/asn1.go
+++ b/vendor/golang.org/x/crypto/cryptobyte/asn1.go
@@ -117,6 +117,19 @@ func (b *Builder) AddASN1GeneralizedTime(t time.Time) {
})
}
+// AddASN1UTCTime appends a DER-encoded ASN.1 UTCTime.
+func (b *Builder) AddASN1UTCTime(t time.Time) {
+ b.AddASN1(asn1.UTCTime, func(c *Builder) {
+ // As utilized by the X.509 profile, UTCTime can only
+ // represent the years 1950 through 2049.
+ if t.Year() < 1950 || t.Year() >= 2050 {
+ b.err = fmt.Errorf("cryptobyte: cannot represent %v as a UTCTime", t)
+ return
+ }
+ c.AddBytes([]byte(t.Format(defaultUTCTimeFormatStr)))
+ })
+}
+
// AddASN1BitString appends a DER-encoded ASN.1 BIT STRING. This does not
// support BIT STRINGs that are not a whole number of bytes.
func (b *Builder) AddASN1BitString(data []byte) {
@@ -251,36 +264,35 @@ func (s *String) ReadASN1Boolean(out *bool) bool {
return true
}
-var bigIntType = reflect.TypeOf((*big.Int)(nil)).Elem()
-
// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
-// not point to an integer or to a big.Int, it panics. It reports whether the
-// read was successful.
+// not point to an integer, to a big.Int, or to a []byte it panics. Only
+// positive and zero values can be decoded into []byte, and they are returned as
+// big-endian binary values that share memory with s. Positive values will have
+// no leading zeroes, and zero will be returned as a single zero byte.
+// ReadASN1Integer reports whether the read was successful.
func (s *String) ReadASN1Integer(out interface{}) bool {
- if reflect.TypeOf(out).Kind() != reflect.Ptr {
- panic("out is not a pointer")
- }
- switch reflect.ValueOf(out).Elem().Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ switch out := out.(type) {
+ case *int, *int8, *int16, *int32, *int64:
var i int64
if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) {
return false
}
reflect.ValueOf(out).Elem().SetInt(i)
return true
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ case *uint, *uint8, *uint16, *uint32, *uint64:
var u uint64
if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) {
return false
}
reflect.ValueOf(out).Elem().SetUint(u)
return true
- case reflect.Struct:
- if reflect.TypeOf(out).Elem() == bigIntType {
- return s.readASN1BigInt(out.(*big.Int))
- }
+ case *big.Int:
+ return s.readASN1BigInt(out)
+ case *[]byte:
+ return s.readASN1Bytes(out)
+ default:
+ panic("out does not point to an integer type")
}
- panic("out does not point to an integer type")
}
func checkASN1Integer(bytes []byte) bool {
@@ -320,6 +332,21 @@ func (s *String) readASN1BigInt(out *big.Int) bool {
return true
}
+func (s *String) readASN1Bytes(out *[]byte) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
+ return false
+ }
+ if bytes[0]&0x80 == 0x80 {
+ return false
+ }
+ for len(bytes) > 1 && bytes[0] == 0 {
+ bytes = bytes[1:]
+ }
+ *out = bytes
+ return true
+}
+
func (s *String) readASN1Int64(out *int64) bool {
var bytes String
if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
@@ -394,11 +421,24 @@ func (s *String) ReadASN1Enum(out *int) bool {
func (s *String) readBase128Int(out *int) bool {
ret := 0
for i := 0; len(*s) > 0; i++ {
- if i == 4 {
+ if i == 5 {
+ return false
+ }
+ // Avoid overflowing int on a 32-bit platform.
+ // We don't want different behavior based on the architecture.
+ if ret >= 1<<(31-7) {
return false
}
ret <<= 7
b := s.read(1)[0]
+
+ // ITU-T X.690, section 8.19.2:
+ // The subidentifier shall be encoded in the fewest possible octets,
+ // that is, the leading octet of the subidentifier shall not have the value 0x80.
+ if i == 0 && b == 0x80 {
+ return false
+ }
+
ret |= int(b & 0x7f)
if b&0x80 == 0 {
*out = ret
@@ -466,6 +506,45 @@ func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
return true
}
+const defaultUTCTimeFormatStr = "060102150405Z0700"
+
+// ReadASN1UTCTime decodes an ASN.1 UTCTime into out and advances.
+// It reports whether the read was successful.
+func (s *String) ReadASN1UTCTime(out *time.Time) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.UTCTime) {
+ return false
+ }
+ t := string(bytes)
+
+ formatStr := defaultUTCTimeFormatStr
+ var err error
+ res, err := time.Parse(formatStr, t)
+ if err != nil {
+ // Fallback to minute precision if we can't parse second
+ // precision. If we are following X.509 or X.690 we shouldn't
+ // support this, but we do.
+ formatStr = "0601021504Z0700"
+ res, err = time.Parse(formatStr, t)
+ }
+ if err != nil {
+ return false
+ }
+
+ if serialized := res.Format(formatStr); serialized != t {
+ return false
+ }
+
+ if res.Year() >= 2050 {
+ // UTCTime interprets the low order digits 50-99 as 1950-99.
+ // This only applies to its use in the X.509 profile.
+ // See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+ res = res.AddDate(-100, 0, 0)
+ }
+ *out = res
+ return true
+}
+
// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances.
// It reports whether the read was successful.
func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
@@ -475,7 +554,7 @@ func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
return false
}
- paddingBits := uint8(bytes[0])
+ paddingBits := bytes[0]
bytes = bytes[1:]
if paddingBits > 7 ||
len(bytes) == 0 && paddingBits != 0 ||
@@ -488,7 +567,7 @@ func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
return true
}
-// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It is
+// ReadASN1BitStringAsBytes decodes an ASN.1 BIT STRING into out and advances. It is
// an error if the BIT STRING is not a whole number of bytes. It reports
// whether the read was successful.
func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
@@ -497,7 +576,7 @@ func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
return false
}
- paddingBits := uint8(bytes[0])
+ paddingBits := bytes[0]
if paddingBits != 0 {
return false
}
@@ -597,34 +676,27 @@ func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
return s.ReadASN1(&unused, tag)
}
-// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER
-// explicitly tagged with tag into out and advances. If no element with a
-// matching tag is present, it writes defaultValue into out instead. If out
-// does not point to an integer or to a big.Int, it panics. It reports
-// whether the read was successful.
+// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER explicitly
+// tagged with tag into out and advances. If no element with a matching tag is
+// present, it writes defaultValue into out instead. Otherwise, it behaves like
+// ReadASN1Integer.
func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultValue interface{}) bool {
- if reflect.TypeOf(out).Kind() != reflect.Ptr {
- panic("out is not a pointer")
- }
var present bool
var i String
if !s.ReadOptionalASN1(&i, &present, tag) {
return false
}
if !present {
- switch reflect.ValueOf(out).Elem().Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ switch out.(type) {
+ case *int, *int8, *int16, *int32, *int64,
+ *uint, *uint8, *uint16, *uint32, *uint64, *[]byte:
reflect.ValueOf(out).Elem().Set(reflect.ValueOf(defaultValue))
- case reflect.Struct:
- if reflect.TypeOf(out).Elem() != bigIntType {
- panic("invalid integer type")
- }
- if reflect.TypeOf(defaultValue).Kind() != reflect.Ptr ||
- reflect.TypeOf(defaultValue).Elem() != bigIntType {
+ case *big.Int:
+ if defaultValue, ok := defaultValue.(*big.Int); ok {
+ out.(*big.Int).Set(defaultValue)
+ } else {
panic("out points to big.Int, but defaultValue does not")
}
- out.(*big.Int).Set(defaultValue.(*big.Int))
default:
panic("invalid integer type")
}
diff --git a/vendor/golang.org/x/crypto/cryptobyte/builder.go b/vendor/golang.org/x/crypto/cryptobyte/builder.go
index ca7b1db..c05ac7d 100644
--- a/vendor/golang.org/x/crypto/cryptobyte/builder.go
+++ b/vendor/golang.org/x/crypto/cryptobyte/builder.go
@@ -95,6 +95,11 @@ func (b *Builder) AddUint32(v uint32) {
b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
}
+// AddUint64 appends a big-endian, 64-bit value to the byte string.
+func (b *Builder) AddUint64(v uint64) {
+ b.add(byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
+}
+
// AddBytes appends a sequence of bytes to the byte string.
func (b *Builder) AddBytes(v []byte) {
b.add(v...)
@@ -106,13 +111,13 @@ func (b *Builder) AddBytes(v []byte) {
// supplied to them. The child builder passed to the continuation can be used
// to build the content of the length-prefixed sequence. For example:
//
-// parent := cryptobyte.NewBuilder()
-// parent.AddUint8LengthPrefixed(func (child *Builder) {
-// child.AddUint8(42)
-// child.AddUint8LengthPrefixed(func (grandchild *Builder) {
-// grandchild.AddUint8(5)
-// })
-// })
+// parent := cryptobyte.NewBuilder()
+// parent.AddUint8LengthPrefixed(func (child *Builder) {
+// child.AddUint8(42)
+// child.AddUint8LengthPrefixed(func (grandchild *Builder) {
+// grandchild.AddUint8(5)
+// })
+// })
//
// It is an error to write more bytes to the child than allowed by the reserved
// length prefix. After the continuation returns, the child must be considered
@@ -298,9 +303,9 @@ func (b *Builder) add(bytes ...byte) {
b.result = append(b.result, bytes...)
}
-// Unwrite rolls back n bytes written directly to the Builder. An attempt by a
-// child builder passed to a continuation to unwrite bytes from its parent will
-// panic.
+// Unwrite rolls back non-negative n bytes written directly to the Builder.
+// An attempt by a child builder passed to a continuation to unwrite bytes
+// from its parent will panic.
func (b *Builder) Unwrite(n int) {
if b.err != nil {
return
@@ -312,6 +317,9 @@ func (b *Builder) Unwrite(n int) {
if length < 0 {
panic("cryptobyte: internal error")
}
+ if n < 0 {
+ panic("cryptobyte: attempted to unwrite negative number of bytes")
+ }
if n > length {
panic("cryptobyte: attempted to unwrite more than was written")
}
diff --git a/vendor/golang.org/x/crypto/cryptobyte/string.go b/vendor/golang.org/x/crypto/cryptobyte/string.go
index 589d297..0531a3d 100644
--- a/vendor/golang.org/x/crypto/cryptobyte/string.go
+++ b/vendor/golang.org/x/crypto/cryptobyte/string.go
@@ -81,6 +81,17 @@ func (s *String) ReadUint32(out *uint32) bool {
return true
}
+// ReadUint64 decodes a big-endian, 64-bit value into out and advances over it.
+// It reports whether the read was successful.
+func (s *String) ReadUint64(out *uint64) bool {
+ v := s.read(8)
+ if v == nil {
+ return false
+ }
+ *out = uint64(v[0])<<56 | uint64(v[1])<<48 | uint64(v[2])<<40 | uint64(v[3])<<32 | uint64(v[4])<<24 | uint64(v[5])<<16 | uint64(v[6])<<8 | uint64(v[7])
+ return true
+}
+
func (s *String) readUnsigned(out *uint32, length int) bool {
v := s.read(length)
if v == nil {
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go
index 4b9a655..00f963e 100644
--- a/vendor/golang.org/x/crypto/curve25519/curve25519.go
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519.go
@@ -5,13 +5,11 @@
// Package curve25519 provides an implementation of the X25519 function, which
// performs scalar multiplication on the elliptic curve known as Curve25519.
// See RFC 7748.
+//
+// Starting in Go 1.20, this package is a wrapper for the X25519 implementation
+// in the crypto/ecdh package.
package curve25519 // import "golang.org/x/crypto/curve25519"
-import (
- "crypto/subtle"
- "fmt"
-)
-
// ScalarMult sets dst to the product scalar * point.
//
// Deprecated: when provided a low-order point, ScalarMult will set dst to all
@@ -27,7 +25,7 @@ func ScalarMult(dst, scalar, point *[32]byte) {
// It is recommended to use the X25519 function with Basepoint instead, as
// copying into fixed size arrays can lead to unexpected bugs.
func ScalarBaseMult(dst, scalar *[32]byte) {
- ScalarMult(dst, scalar, &basePoint)
+ scalarBaseMult(dst, scalar)
}
const (
@@ -40,21 +38,10 @@ const (
// Basepoint is the canonical Curve25519 generator.
var Basepoint []byte
-var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+var basePoint = [32]byte{9}
func init() { Basepoint = basePoint[:] }
-func checkBasepoint() {
- if subtle.ConstantTimeCompare(Basepoint, []byte{
- 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- }) != 1 {
- panic("curve25519: global Basepoint value was modified")
- }
-}
-
// X25519 returns the result of the scalar multiplication (scalar * point),
// according to RFC 7748, Section 5. scalar, point and the return value are
// slices of 32 bytes.
@@ -70,26 +57,3 @@ func X25519(scalar, point []byte) ([]byte, error) {
var dst [32]byte
return x25519(&dst, scalar, point)
}
-
-func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
- var in [32]byte
- if l := len(scalar); l != 32 {
- return nil, fmt.Errorf("bad scalar length: %d, expected %d", l, 32)
- }
- if l := len(point); l != 32 {
- return nil, fmt.Errorf("bad point length: %d, expected %d", l, 32)
- }
- copy(in[:], scalar)
- if &point[0] == &Basepoint[0] {
- checkBasepoint()
- ScalarBaseMult(dst, &in)
- } else {
- var base, zero [32]byte
- copy(base[:], point)
- ScalarMult(dst, &in, &base)
- if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
- return nil, fmt.Errorf("bad input point: low order point")
- }
- }
- return dst[:], nil
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go b/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
deleted file mode 100644
index 5120b77..0000000
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build amd64,!gccgo,!appengine,!purego
-
-package curve25519
-
-// These functions are implemented in the .s files. The names of the functions
-// in the rest of the file are also taken from the SUPERCOP sources to help
-// people following along.
-
-//go:noescape
-
-func cswap(inout *[5]uint64, v uint64)
-
-//go:noescape
-
-func ladderstep(inout *[5][5]uint64)
-
-//go:noescape
-
-func freeze(inout *[5]uint64)
-
-//go:noescape
-
-func mul(dest, a, b *[5]uint64)
-
-//go:noescape
-
-func square(out, in *[5]uint64)
-
-// mladder uses a Montgomery ladder to calculate (xr/zr) *= s.
-func mladder(xr, zr *[5]uint64, s *[32]byte) {
- var work [5][5]uint64
-
- work[0] = *xr
- setint(&work[1], 1)
- setint(&work[2], 0)
- work[3] = *xr
- setint(&work[4], 1)
-
- j := uint(6)
- var prevbit byte
-
- for i := 31; i >= 0; i-- {
- for j < 8 {
- bit := ((*s)[i] >> j) & 1
- swap := bit ^ prevbit
- prevbit = bit
- cswap(&work[1], uint64(swap))
- ladderstep(&work)
- j--
- }
- j = 7
- }
-
- *xr = work[1]
- *zr = work[2]
-}
-
-func scalarMult(out, in, base *[32]byte) {
- var e [32]byte
- copy(e[:], (*in)[:])
- e[0] &= 248
- e[31] &= 127
- e[31] |= 64
-
- var t, z [5]uint64
- unpack(&t, base)
- mladder(&t, &z, &e)
- invert(&z, &z)
- mul(&t, &t, &z)
- pack(out, &t)
-}
-
-func setint(r *[5]uint64, v uint64) {
- r[0] = v
- r[1] = 0
- r[2] = 0
- r[3] = 0
- r[4] = 0
-}
-
-// unpack sets r = x where r consists of 5, 51-bit limbs in little-endian
-// order.
-func unpack(r *[5]uint64, x *[32]byte) {
- r[0] = uint64(x[0]) |
- uint64(x[1])<<8 |
- uint64(x[2])<<16 |
- uint64(x[3])<<24 |
- uint64(x[4])<<32 |
- uint64(x[5])<<40 |
- uint64(x[6]&7)<<48
-
- r[1] = uint64(x[6])>>3 |
- uint64(x[7])<<5 |
- uint64(x[8])<<13 |
- uint64(x[9])<<21 |
- uint64(x[10])<<29 |
- uint64(x[11])<<37 |
- uint64(x[12]&63)<<45
-
- r[2] = uint64(x[12])>>6 |
- uint64(x[13])<<2 |
- uint64(x[14])<<10 |
- uint64(x[15])<<18 |
- uint64(x[16])<<26 |
- uint64(x[17])<<34 |
- uint64(x[18])<<42 |
- uint64(x[19]&1)<<50
-
- r[3] = uint64(x[19])>>1 |
- uint64(x[20])<<7 |
- uint64(x[21])<<15 |
- uint64(x[22])<<23 |
- uint64(x[23])<<31 |
- uint64(x[24])<<39 |
- uint64(x[25]&15)<<47
-
- r[4] = uint64(x[25])>>4 |
- uint64(x[26])<<4 |
- uint64(x[27])<<12 |
- uint64(x[28])<<20 |
- uint64(x[29])<<28 |
- uint64(x[30])<<36 |
- uint64(x[31]&127)<<44
-}
-
-// pack sets out = x where out is the usual, little-endian form of the 5,
-// 51-bit limbs in x.
-func pack(out *[32]byte, x *[5]uint64) {
- t := *x
- freeze(&t)
-
- out[0] = byte(t[0])
- out[1] = byte(t[0] >> 8)
- out[2] = byte(t[0] >> 16)
- out[3] = byte(t[0] >> 24)
- out[4] = byte(t[0] >> 32)
- out[5] = byte(t[0] >> 40)
- out[6] = byte(t[0] >> 48)
-
- out[6] ^= byte(t[1]<<3) & 0xf8
- out[7] = byte(t[1] >> 5)
- out[8] = byte(t[1] >> 13)
- out[9] = byte(t[1] >> 21)
- out[10] = byte(t[1] >> 29)
- out[11] = byte(t[1] >> 37)
- out[12] = byte(t[1] >> 45)
-
- out[12] ^= byte(t[2]<<6) & 0xc0
- out[13] = byte(t[2] >> 2)
- out[14] = byte(t[2] >> 10)
- out[15] = byte(t[2] >> 18)
- out[16] = byte(t[2] >> 26)
- out[17] = byte(t[2] >> 34)
- out[18] = byte(t[2] >> 42)
- out[19] = byte(t[2] >> 50)
-
- out[19] ^= byte(t[3]<<1) & 0xfe
- out[20] = byte(t[3] >> 7)
- out[21] = byte(t[3] >> 15)
- out[22] = byte(t[3] >> 23)
- out[23] = byte(t[3] >> 31)
- out[24] = byte(t[3] >> 39)
- out[25] = byte(t[3] >> 47)
-
- out[25] ^= byte(t[4]<<4) & 0xf0
- out[26] = byte(t[4] >> 4)
- out[27] = byte(t[4] >> 12)
- out[28] = byte(t[4] >> 20)
- out[29] = byte(t[4] >> 28)
- out[30] = byte(t[4] >> 36)
- out[31] = byte(t[4] >> 44)
-}
-
-// invert calculates r = x^-1 mod p using Fermat's little theorem.
-func invert(r *[5]uint64, x *[5]uint64) {
- var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t [5]uint64
-
- square(&z2, x) /* 2 */
- square(&t, &z2) /* 4 */
- square(&t, &t) /* 8 */
- mul(&z9, &t, x) /* 9 */
- mul(&z11, &z9, &z2) /* 11 */
- square(&t, &z11) /* 22 */
- mul(&z2_5_0, &t, &z9) /* 2^5 - 2^0 = 31 */
-
- square(&t, &z2_5_0) /* 2^6 - 2^1 */
- for i := 1; i < 5; i++ { /* 2^20 - 2^10 */
- square(&t, &t)
- }
- mul(&z2_10_0, &t, &z2_5_0) /* 2^10 - 2^0 */
-
- square(&t, &z2_10_0) /* 2^11 - 2^1 */
- for i := 1; i < 10; i++ { /* 2^20 - 2^10 */
- square(&t, &t)
- }
- mul(&z2_20_0, &t, &z2_10_0) /* 2^20 - 2^0 */
-
- square(&t, &z2_20_0) /* 2^21 - 2^1 */
- for i := 1; i < 20; i++ { /* 2^40 - 2^20 */
- square(&t, &t)
- }
- mul(&t, &t, &z2_20_0) /* 2^40 - 2^0 */
-
- square(&t, &t) /* 2^41 - 2^1 */
- for i := 1; i < 10; i++ { /* 2^50 - 2^10 */
- square(&t, &t)
- }
- mul(&z2_50_0, &t, &z2_10_0) /* 2^50 - 2^0 */
-
- square(&t, &z2_50_0) /* 2^51 - 2^1 */
- for i := 1; i < 50; i++ { /* 2^100 - 2^50 */
- square(&t, &t)
- }
- mul(&z2_100_0, &t, &z2_50_0) /* 2^100 - 2^0 */
-
- square(&t, &z2_100_0) /* 2^101 - 2^1 */
- for i := 1; i < 100; i++ { /* 2^200 - 2^100 */
- square(&t, &t)
- }
- mul(&t, &t, &z2_100_0) /* 2^200 - 2^0 */
-
- square(&t, &t) /* 2^201 - 2^1 */
- for i := 1; i < 50; i++ { /* 2^250 - 2^50 */
- square(&t, &t)
- }
- mul(&t, &t, &z2_50_0) /* 2^250 - 2^0 */
-
- square(&t, &t) /* 2^251 - 2^1 */
- square(&t, &t) /* 2^252 - 2^2 */
- square(&t, &t) /* 2^253 - 2^3 */
-
- square(&t, &t) /* 2^254 - 2^4 */
-
- square(&t, &t) /* 2^255 - 2^5 */
- mul(r, &t, &z11) /* 2^255 - 21 */
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s b/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s
deleted file mode 100644
index 0250c88..0000000
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s
+++ /dev/null
@@ -1,1793 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This code was translated into a form compatible with 6a from the public
-// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
-
-// +build amd64,!gccgo,!appengine,!purego
-
-#define REDMASK51 0x0007FFFFFFFFFFFF
-
-// These constants cannot be encoded in non-MOVQ immediates.
-// We access them directly from memory instead.
-
-DATA ·_121666_213(SB)/8, $996687872
-GLOBL ·_121666_213(SB), 8, $8
-
-DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA
-GLOBL ·_2P0(SB), 8, $8
-
-DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE
-GLOBL ·_2P1234(SB), 8, $8
-
-// func freeze(inout *[5]uint64)
-TEXT ·freeze(SB),7,$0-8
- MOVQ inout+0(FP), DI
-
- MOVQ 0(DI),SI
- MOVQ 8(DI),DX
- MOVQ 16(DI),CX
- MOVQ 24(DI),R8
- MOVQ 32(DI),R9
- MOVQ $REDMASK51,AX
- MOVQ AX,R10
- SUBQ $18,R10
- MOVQ $3,R11
-REDUCELOOP:
- MOVQ SI,R12
- SHRQ $51,R12
- ANDQ AX,SI
- ADDQ R12,DX
- MOVQ DX,R12
- SHRQ $51,R12
- ANDQ AX,DX
- ADDQ R12,CX
- MOVQ CX,R12
- SHRQ $51,R12
- ANDQ AX,CX
- ADDQ R12,R8
- MOVQ R8,R12
- SHRQ $51,R12
- ANDQ AX,R8
- ADDQ R12,R9
- MOVQ R9,R12
- SHRQ $51,R12
- ANDQ AX,R9
- IMUL3Q $19,R12,R12
- ADDQ R12,SI
- SUBQ $1,R11
- JA REDUCELOOP
- MOVQ $1,R12
- CMPQ R10,SI
- CMOVQLT R11,R12
- CMPQ AX,DX
- CMOVQNE R11,R12
- CMPQ AX,CX
- CMOVQNE R11,R12
- CMPQ AX,R8
- CMOVQNE R11,R12
- CMPQ AX,R9
- CMOVQNE R11,R12
- NEGQ R12
- ANDQ R12,AX
- ANDQ R12,R10
- SUBQ R10,SI
- SUBQ AX,DX
- SUBQ AX,CX
- SUBQ AX,R8
- SUBQ AX,R9
- MOVQ SI,0(DI)
- MOVQ DX,8(DI)
- MOVQ CX,16(DI)
- MOVQ R8,24(DI)
- MOVQ R9,32(DI)
- RET
-
-// func ladderstep(inout *[5][5]uint64)
-TEXT ·ladderstep(SB),0,$296-8
- MOVQ inout+0(FP),DI
-
- MOVQ 40(DI),SI
- MOVQ 48(DI),DX
- MOVQ 56(DI),CX
- MOVQ 64(DI),R8
- MOVQ 72(DI),R9
- MOVQ SI,AX
- MOVQ DX,R10
- MOVQ CX,R11
- MOVQ R8,R12
- MOVQ R9,R13
- ADDQ ·_2P0(SB),AX
- ADDQ ·_2P1234(SB),R10
- ADDQ ·_2P1234(SB),R11
- ADDQ ·_2P1234(SB),R12
- ADDQ ·_2P1234(SB),R13
- ADDQ 80(DI),SI
- ADDQ 88(DI),DX
- ADDQ 96(DI),CX
- ADDQ 104(DI),R8
- ADDQ 112(DI),R9
- SUBQ 80(DI),AX
- SUBQ 88(DI),R10
- SUBQ 96(DI),R11
- SUBQ 104(DI),R12
- SUBQ 112(DI),R13
- MOVQ SI,0(SP)
- MOVQ DX,8(SP)
- MOVQ CX,16(SP)
- MOVQ R8,24(SP)
- MOVQ R9,32(SP)
- MOVQ AX,40(SP)
- MOVQ R10,48(SP)
- MOVQ R11,56(SP)
- MOVQ R12,64(SP)
- MOVQ R13,72(SP)
- MOVQ 40(SP),AX
- MULQ 40(SP)
- MOVQ AX,SI
- MOVQ DX,CX
- MOVQ 40(SP),AX
- SHLQ $1,AX
- MULQ 48(SP)
- MOVQ AX,R8
- MOVQ DX,R9
- MOVQ 40(SP),AX
- SHLQ $1,AX
- MULQ 56(SP)
- MOVQ AX,R10
- MOVQ DX,R11
- MOVQ 40(SP),AX
- SHLQ $1,AX
- MULQ 64(SP)
- MOVQ AX,R12
- MOVQ DX,R13
- MOVQ 40(SP),AX
- SHLQ $1,AX
- MULQ 72(SP)
- MOVQ AX,R14
- MOVQ DX,R15
- MOVQ 48(SP),AX
- MULQ 48(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 48(SP),AX
- SHLQ $1,AX
- MULQ 56(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 48(SP),AX
- SHLQ $1,AX
- MULQ 64(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 48(SP),DX
- IMUL3Q $38,DX,AX
- MULQ 72(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 56(SP),AX
- MULQ 56(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 56(SP),DX
- IMUL3Q $38,DX,AX
- MULQ 64(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 56(SP),DX
- IMUL3Q $38,DX,AX
- MULQ 72(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 64(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 64(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 64(SP),DX
- IMUL3Q $38,DX,AX
- MULQ 72(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 72(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 72(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ $REDMASK51,DX
- SHLQ $13,SI,CX
- ANDQ DX,SI
- SHLQ $13,R8,R9
- ANDQ DX,R8
- ADDQ CX,R8
- SHLQ $13,R10,R11
- ANDQ DX,R10
- ADDQ R9,R10
- SHLQ $13,R12,R13
- ANDQ DX,R12
- ADDQ R11,R12
- SHLQ $13,R14,R15
- ANDQ DX,R14
- ADDQ R13,R14
- IMUL3Q $19,R15,CX
- ADDQ CX,SI
- MOVQ SI,CX
- SHRQ $51,CX
- ADDQ R8,CX
- ANDQ DX,SI
- MOVQ CX,R8
- SHRQ $51,CX
- ADDQ R10,CX
- ANDQ DX,R8
- MOVQ CX,R9
- SHRQ $51,CX
- ADDQ R12,CX
- ANDQ DX,R9
- MOVQ CX,AX
- SHRQ $51,CX
- ADDQ R14,CX
- ANDQ DX,AX
- MOVQ CX,R10
- SHRQ $51,CX
- IMUL3Q $19,CX,CX
- ADDQ CX,SI
- ANDQ DX,R10
- MOVQ SI,80(SP)
- MOVQ R8,88(SP)
- MOVQ R9,96(SP)
- MOVQ AX,104(SP)
- MOVQ R10,112(SP)
- MOVQ 0(SP),AX
- MULQ 0(SP)
- MOVQ AX,SI
- MOVQ DX,CX
- MOVQ 0(SP),AX
- SHLQ $1,AX
- MULQ 8(SP)
- MOVQ AX,R8
- MOVQ DX,R9
- MOVQ 0(SP),AX
- SHLQ $1,AX
- MULQ 16(SP)
- MOVQ AX,R10
- MOVQ DX,R11
- MOVQ 0(SP),AX
- SHLQ $1,AX
- MULQ 24(SP)
- MOVQ AX,R12
- MOVQ DX,R13
- MOVQ 0(SP),AX
- SHLQ $1,AX
- MULQ 32(SP)
- MOVQ AX,R14
- MOVQ DX,R15
- MOVQ 8(SP),AX
- MULQ 8(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 8(SP),AX
- SHLQ $1,AX
- MULQ 16(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 8(SP),AX
- SHLQ $1,AX
- MULQ 24(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 8(SP),DX
- IMUL3Q $38,DX,AX
- MULQ 32(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 16(SP),AX
- MULQ 16(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 16(SP),DX
- IMUL3Q $38,DX,AX
- MULQ 24(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 16(SP),DX
- IMUL3Q $38,DX,AX
- MULQ 32(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 24(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 24(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 24(SP),DX
- IMUL3Q $38,DX,AX
- MULQ 32(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 32(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 32(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ $REDMASK51,DX
- SHLQ $13,SI,CX
- ANDQ DX,SI
- SHLQ $13,R8,R9
- ANDQ DX,R8
- ADDQ CX,R8
- SHLQ $13,R10,R11
- ANDQ DX,R10
- ADDQ R9,R10
- SHLQ $13,R12,R13
- ANDQ DX,R12
- ADDQ R11,R12
- SHLQ $13,R14,R15
- ANDQ DX,R14
- ADDQ R13,R14
- IMUL3Q $19,R15,CX
- ADDQ CX,SI
- MOVQ SI,CX
- SHRQ $51,CX
- ADDQ R8,CX
- ANDQ DX,SI
- MOVQ CX,R8
- SHRQ $51,CX
- ADDQ R10,CX
- ANDQ DX,R8
- MOVQ CX,R9
- SHRQ $51,CX
- ADDQ R12,CX
- ANDQ DX,R9
- MOVQ CX,AX
- SHRQ $51,CX
- ADDQ R14,CX
- ANDQ DX,AX
- MOVQ CX,R10
- SHRQ $51,CX
- IMUL3Q $19,CX,CX
- ADDQ CX,SI
- ANDQ DX,R10
- MOVQ SI,120(SP)
- MOVQ R8,128(SP)
- MOVQ R9,136(SP)
- MOVQ AX,144(SP)
- MOVQ R10,152(SP)
- MOVQ SI,SI
- MOVQ R8,DX
- MOVQ R9,CX
- MOVQ AX,R8
- MOVQ R10,R9
- ADDQ ·_2P0(SB),SI
- ADDQ ·_2P1234(SB),DX
- ADDQ ·_2P1234(SB),CX
- ADDQ ·_2P1234(SB),R8
- ADDQ ·_2P1234(SB),R9
- SUBQ 80(SP),SI
- SUBQ 88(SP),DX
- SUBQ 96(SP),CX
- SUBQ 104(SP),R8
- SUBQ 112(SP),R9
- MOVQ SI,160(SP)
- MOVQ DX,168(SP)
- MOVQ CX,176(SP)
- MOVQ R8,184(SP)
- MOVQ R9,192(SP)
- MOVQ 120(DI),SI
- MOVQ 128(DI),DX
- MOVQ 136(DI),CX
- MOVQ 144(DI),R8
- MOVQ 152(DI),R9
- MOVQ SI,AX
- MOVQ DX,R10
- MOVQ CX,R11
- MOVQ R8,R12
- MOVQ R9,R13
- ADDQ ·_2P0(SB),AX
- ADDQ ·_2P1234(SB),R10
- ADDQ ·_2P1234(SB),R11
- ADDQ ·_2P1234(SB),R12
- ADDQ ·_2P1234(SB),R13
- ADDQ 160(DI),SI
- ADDQ 168(DI),DX
- ADDQ 176(DI),CX
- ADDQ 184(DI),R8
- ADDQ 192(DI),R9
- SUBQ 160(DI),AX
- SUBQ 168(DI),R10
- SUBQ 176(DI),R11
- SUBQ 184(DI),R12
- SUBQ 192(DI),R13
- MOVQ SI,200(SP)
- MOVQ DX,208(SP)
- MOVQ CX,216(SP)
- MOVQ R8,224(SP)
- MOVQ R9,232(SP)
- MOVQ AX,240(SP)
- MOVQ R10,248(SP)
- MOVQ R11,256(SP)
- MOVQ R12,264(SP)
- MOVQ R13,272(SP)
- MOVQ 224(SP),SI
- IMUL3Q $19,SI,AX
- MOVQ AX,280(SP)
- MULQ 56(SP)
- MOVQ AX,SI
- MOVQ DX,CX
- MOVQ 232(SP),DX
- IMUL3Q $19,DX,AX
- MOVQ AX,288(SP)
- MULQ 48(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 200(SP),AX
- MULQ 40(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 200(SP),AX
- MULQ 48(SP)
- MOVQ AX,R8
- MOVQ DX,R9
- MOVQ 200(SP),AX
- MULQ 56(SP)
- MOVQ AX,R10
- MOVQ DX,R11
- MOVQ 200(SP),AX
- MULQ 64(SP)
- MOVQ AX,R12
- MOVQ DX,R13
- MOVQ 200(SP),AX
- MULQ 72(SP)
- MOVQ AX,R14
- MOVQ DX,R15
- MOVQ 208(SP),AX
- MULQ 40(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 208(SP),AX
- MULQ 48(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 208(SP),AX
- MULQ 56(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 208(SP),AX
- MULQ 64(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 208(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 72(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 216(SP),AX
- MULQ 40(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 216(SP),AX
- MULQ 48(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 216(SP),AX
- MULQ 56(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 216(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 64(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 216(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 72(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 224(SP),AX
- MULQ 40(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 224(SP),AX
- MULQ 48(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 280(SP),AX
- MULQ 64(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 280(SP),AX
- MULQ 72(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 232(SP),AX
- MULQ 40(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 288(SP),AX
- MULQ 56(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 288(SP),AX
- MULQ 64(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 288(SP),AX
- MULQ 72(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ $REDMASK51,DX
- SHLQ $13,SI,CX
- ANDQ DX,SI
- SHLQ $13,R8,R9
- ANDQ DX,R8
- ADDQ CX,R8
- SHLQ $13,R10,R11
- ANDQ DX,R10
- ADDQ R9,R10
- SHLQ $13,R12,R13
- ANDQ DX,R12
- ADDQ R11,R12
- SHLQ $13,R14,R15
- ANDQ DX,R14
- ADDQ R13,R14
- IMUL3Q $19,R15,CX
- ADDQ CX,SI
- MOVQ SI,CX
- SHRQ $51,CX
- ADDQ R8,CX
- MOVQ CX,R8
- SHRQ $51,CX
- ANDQ DX,SI
- ADDQ R10,CX
- MOVQ CX,R9
- SHRQ $51,CX
- ANDQ DX,R8
- ADDQ R12,CX
- MOVQ CX,AX
- SHRQ $51,CX
- ANDQ DX,R9
- ADDQ R14,CX
- MOVQ CX,R10
- SHRQ $51,CX
- ANDQ DX,AX
- IMUL3Q $19,CX,CX
- ADDQ CX,SI
- ANDQ DX,R10
- MOVQ SI,40(SP)
- MOVQ R8,48(SP)
- MOVQ R9,56(SP)
- MOVQ AX,64(SP)
- MOVQ R10,72(SP)
- MOVQ 264(SP),SI
- IMUL3Q $19,SI,AX
- MOVQ AX,200(SP)
- MULQ 16(SP)
- MOVQ AX,SI
- MOVQ DX,CX
- MOVQ 272(SP),DX
- IMUL3Q $19,DX,AX
- MOVQ AX,208(SP)
- MULQ 8(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 240(SP),AX
- MULQ 0(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 240(SP),AX
- MULQ 8(SP)
- MOVQ AX,R8
- MOVQ DX,R9
- MOVQ 240(SP),AX
- MULQ 16(SP)
- MOVQ AX,R10
- MOVQ DX,R11
- MOVQ 240(SP),AX
- MULQ 24(SP)
- MOVQ AX,R12
- MOVQ DX,R13
- MOVQ 240(SP),AX
- MULQ 32(SP)
- MOVQ AX,R14
- MOVQ DX,R15
- MOVQ 248(SP),AX
- MULQ 0(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 248(SP),AX
- MULQ 8(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 248(SP),AX
- MULQ 16(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 248(SP),AX
- MULQ 24(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 248(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 32(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 256(SP),AX
- MULQ 0(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 256(SP),AX
- MULQ 8(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 256(SP),AX
- MULQ 16(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 256(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 24(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 256(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 32(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 264(SP),AX
- MULQ 0(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 264(SP),AX
- MULQ 8(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 200(SP),AX
- MULQ 24(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 200(SP),AX
- MULQ 32(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 272(SP),AX
- MULQ 0(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 208(SP),AX
- MULQ 16(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 208(SP),AX
- MULQ 24(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 208(SP),AX
- MULQ 32(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ $REDMASK51,DX
- SHLQ $13,SI,CX
- ANDQ DX,SI
- SHLQ $13,R8,R9
- ANDQ DX,R8
- ADDQ CX,R8
- SHLQ $13,R10,R11
- ANDQ DX,R10
- ADDQ R9,R10
- SHLQ $13,R12,R13
- ANDQ DX,R12
- ADDQ R11,R12
- SHLQ $13,R14,R15
- ANDQ DX,R14
- ADDQ R13,R14
- IMUL3Q $19,R15,CX
- ADDQ CX,SI
- MOVQ SI,CX
- SHRQ $51,CX
- ADDQ R8,CX
- MOVQ CX,R8
- SHRQ $51,CX
- ANDQ DX,SI
- ADDQ R10,CX
- MOVQ CX,R9
- SHRQ $51,CX
- ANDQ DX,R8
- ADDQ R12,CX
- MOVQ CX,AX
- SHRQ $51,CX
- ANDQ DX,R9
- ADDQ R14,CX
- MOVQ CX,R10
- SHRQ $51,CX
- ANDQ DX,AX
- IMUL3Q $19,CX,CX
- ADDQ CX,SI
- ANDQ DX,R10
- MOVQ SI,DX
- MOVQ R8,CX
- MOVQ R9,R11
- MOVQ AX,R12
- MOVQ R10,R13
- ADDQ ·_2P0(SB),DX
- ADDQ ·_2P1234(SB),CX
- ADDQ ·_2P1234(SB),R11
- ADDQ ·_2P1234(SB),R12
- ADDQ ·_2P1234(SB),R13
- ADDQ 40(SP),SI
- ADDQ 48(SP),R8
- ADDQ 56(SP),R9
- ADDQ 64(SP),AX
- ADDQ 72(SP),R10
- SUBQ 40(SP),DX
- SUBQ 48(SP),CX
- SUBQ 56(SP),R11
- SUBQ 64(SP),R12
- SUBQ 72(SP),R13
- MOVQ SI,120(DI)
- MOVQ R8,128(DI)
- MOVQ R9,136(DI)
- MOVQ AX,144(DI)
- MOVQ R10,152(DI)
- MOVQ DX,160(DI)
- MOVQ CX,168(DI)
- MOVQ R11,176(DI)
- MOVQ R12,184(DI)
- MOVQ R13,192(DI)
- MOVQ 120(DI),AX
- MULQ 120(DI)
- MOVQ AX,SI
- MOVQ DX,CX
- MOVQ 120(DI),AX
- SHLQ $1,AX
- MULQ 128(DI)
- MOVQ AX,R8
- MOVQ DX,R9
- MOVQ 120(DI),AX
- SHLQ $1,AX
- MULQ 136(DI)
- MOVQ AX,R10
- MOVQ DX,R11
- MOVQ 120(DI),AX
- SHLQ $1,AX
- MULQ 144(DI)
- MOVQ AX,R12
- MOVQ DX,R13
- MOVQ 120(DI),AX
- SHLQ $1,AX
- MULQ 152(DI)
- MOVQ AX,R14
- MOVQ DX,R15
- MOVQ 128(DI),AX
- MULQ 128(DI)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 128(DI),AX
- SHLQ $1,AX
- MULQ 136(DI)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 128(DI),AX
- SHLQ $1,AX
- MULQ 144(DI)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 128(DI),DX
- IMUL3Q $38,DX,AX
- MULQ 152(DI)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 136(DI),AX
- MULQ 136(DI)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 136(DI),DX
- IMUL3Q $38,DX,AX
- MULQ 144(DI)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 136(DI),DX
- IMUL3Q $38,DX,AX
- MULQ 152(DI)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 144(DI),DX
- IMUL3Q $19,DX,AX
- MULQ 144(DI)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 144(DI),DX
- IMUL3Q $38,DX,AX
- MULQ 152(DI)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 152(DI),DX
- IMUL3Q $19,DX,AX
- MULQ 152(DI)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ $REDMASK51,DX
- SHLQ $13,SI,CX
- ANDQ DX,SI
- SHLQ $13,R8,R9
- ANDQ DX,R8
- ADDQ CX,R8
- SHLQ $13,R10,R11
- ANDQ DX,R10
- ADDQ R9,R10
- SHLQ $13,R12,R13
- ANDQ DX,R12
- ADDQ R11,R12
- SHLQ $13,R14,R15
- ANDQ DX,R14
- ADDQ R13,R14
- IMUL3Q $19,R15,CX
- ADDQ CX,SI
- MOVQ SI,CX
- SHRQ $51,CX
- ADDQ R8,CX
- ANDQ DX,SI
- MOVQ CX,R8
- SHRQ $51,CX
- ADDQ R10,CX
- ANDQ DX,R8
- MOVQ CX,R9
- SHRQ $51,CX
- ADDQ R12,CX
- ANDQ DX,R9
- MOVQ CX,AX
- SHRQ $51,CX
- ADDQ R14,CX
- ANDQ DX,AX
- MOVQ CX,R10
- SHRQ $51,CX
- IMUL3Q $19,CX,CX
- ADDQ CX,SI
- ANDQ DX,R10
- MOVQ SI,120(DI)
- MOVQ R8,128(DI)
- MOVQ R9,136(DI)
- MOVQ AX,144(DI)
- MOVQ R10,152(DI)
- MOVQ 160(DI),AX
- MULQ 160(DI)
- MOVQ AX,SI
- MOVQ DX,CX
- MOVQ 160(DI),AX
- SHLQ $1,AX
- MULQ 168(DI)
- MOVQ AX,R8
- MOVQ DX,R9
- MOVQ 160(DI),AX
- SHLQ $1,AX
- MULQ 176(DI)
- MOVQ AX,R10
- MOVQ DX,R11
- MOVQ 160(DI),AX
- SHLQ $1,AX
- MULQ 184(DI)
- MOVQ AX,R12
- MOVQ DX,R13
- MOVQ 160(DI),AX
- SHLQ $1,AX
- MULQ 192(DI)
- MOVQ AX,R14
- MOVQ DX,R15
- MOVQ 168(DI),AX
- MULQ 168(DI)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 168(DI),AX
- SHLQ $1,AX
- MULQ 176(DI)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 168(DI),AX
- SHLQ $1,AX
- MULQ 184(DI)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 168(DI),DX
- IMUL3Q $38,DX,AX
- MULQ 192(DI)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 176(DI),AX
- MULQ 176(DI)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 176(DI),DX
- IMUL3Q $38,DX,AX
- MULQ 184(DI)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 176(DI),DX
- IMUL3Q $38,DX,AX
- MULQ 192(DI)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 184(DI),DX
- IMUL3Q $19,DX,AX
- MULQ 184(DI)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 184(DI),DX
- IMUL3Q $38,DX,AX
- MULQ 192(DI)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 192(DI),DX
- IMUL3Q $19,DX,AX
- MULQ 192(DI)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ $REDMASK51,DX
- SHLQ $13,SI,CX
- ANDQ DX,SI
- SHLQ $13,R8,R9
- ANDQ DX,R8
- ADDQ CX,R8
- SHLQ $13,R10,R11
- ANDQ DX,R10
- ADDQ R9,R10
- SHLQ $13,R12,R13
- ANDQ DX,R12
- ADDQ R11,R12
- SHLQ $13,R14,R15
- ANDQ DX,R14
- ADDQ R13,R14
- IMUL3Q $19,R15,CX
- ADDQ CX,SI
- MOVQ SI,CX
- SHRQ $51,CX
- ADDQ R8,CX
- ANDQ DX,SI
- MOVQ CX,R8
- SHRQ $51,CX
- ADDQ R10,CX
- ANDQ DX,R8
- MOVQ CX,R9
- SHRQ $51,CX
- ADDQ R12,CX
- ANDQ DX,R9
- MOVQ CX,AX
- SHRQ $51,CX
- ADDQ R14,CX
- ANDQ DX,AX
- MOVQ CX,R10
- SHRQ $51,CX
- IMUL3Q $19,CX,CX
- ADDQ CX,SI
- ANDQ DX,R10
- MOVQ SI,160(DI)
- MOVQ R8,168(DI)
- MOVQ R9,176(DI)
- MOVQ AX,184(DI)
- MOVQ R10,192(DI)
- MOVQ 184(DI),SI
- IMUL3Q $19,SI,AX
- MOVQ AX,0(SP)
- MULQ 16(DI)
- MOVQ AX,SI
- MOVQ DX,CX
- MOVQ 192(DI),DX
- IMUL3Q $19,DX,AX
- MOVQ AX,8(SP)
- MULQ 8(DI)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 160(DI),AX
- MULQ 0(DI)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 160(DI),AX
- MULQ 8(DI)
- MOVQ AX,R8
- MOVQ DX,R9
- MOVQ 160(DI),AX
- MULQ 16(DI)
- MOVQ AX,R10
- MOVQ DX,R11
- MOVQ 160(DI),AX
- MULQ 24(DI)
- MOVQ AX,R12
- MOVQ DX,R13
- MOVQ 160(DI),AX
- MULQ 32(DI)
- MOVQ AX,R14
- MOVQ DX,R15
- MOVQ 168(DI),AX
- MULQ 0(DI)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 168(DI),AX
- MULQ 8(DI)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 168(DI),AX
- MULQ 16(DI)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 168(DI),AX
- MULQ 24(DI)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 168(DI),DX
- IMUL3Q $19,DX,AX
- MULQ 32(DI)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 176(DI),AX
- MULQ 0(DI)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 176(DI),AX
- MULQ 8(DI)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 176(DI),AX
- MULQ 16(DI)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 176(DI),DX
- IMUL3Q $19,DX,AX
- MULQ 24(DI)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 176(DI),DX
- IMUL3Q $19,DX,AX
- MULQ 32(DI)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 184(DI),AX
- MULQ 0(DI)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 184(DI),AX
- MULQ 8(DI)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 0(SP),AX
- MULQ 24(DI)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 0(SP),AX
- MULQ 32(DI)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 192(DI),AX
- MULQ 0(DI)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 8(SP),AX
- MULQ 16(DI)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 8(SP),AX
- MULQ 24(DI)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 8(SP),AX
- MULQ 32(DI)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ $REDMASK51,DX
- SHLQ $13,SI,CX
- ANDQ DX,SI
- SHLQ $13,R8,R9
- ANDQ DX,R8
- ADDQ CX,R8
- SHLQ $13,R10,R11
- ANDQ DX,R10
- ADDQ R9,R10
- SHLQ $13,R12,R13
- ANDQ DX,R12
- ADDQ R11,R12
- SHLQ $13,R14,R15
- ANDQ DX,R14
- ADDQ R13,R14
- IMUL3Q $19,R15,CX
- ADDQ CX,SI
- MOVQ SI,CX
- SHRQ $51,CX
- ADDQ R8,CX
- MOVQ CX,R8
- SHRQ $51,CX
- ANDQ DX,SI
- ADDQ R10,CX
- MOVQ CX,R9
- SHRQ $51,CX
- ANDQ DX,R8
- ADDQ R12,CX
- MOVQ CX,AX
- SHRQ $51,CX
- ANDQ DX,R9
- ADDQ R14,CX
- MOVQ CX,R10
- SHRQ $51,CX
- ANDQ DX,AX
- IMUL3Q $19,CX,CX
- ADDQ CX,SI
- ANDQ DX,R10
- MOVQ SI,160(DI)
- MOVQ R8,168(DI)
- MOVQ R9,176(DI)
- MOVQ AX,184(DI)
- MOVQ R10,192(DI)
- MOVQ 144(SP),SI
- IMUL3Q $19,SI,AX
- MOVQ AX,0(SP)
- MULQ 96(SP)
- MOVQ AX,SI
- MOVQ DX,CX
- MOVQ 152(SP),DX
- IMUL3Q $19,DX,AX
- MOVQ AX,8(SP)
- MULQ 88(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 120(SP),AX
- MULQ 80(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 120(SP),AX
- MULQ 88(SP)
- MOVQ AX,R8
- MOVQ DX,R9
- MOVQ 120(SP),AX
- MULQ 96(SP)
- MOVQ AX,R10
- MOVQ DX,R11
- MOVQ 120(SP),AX
- MULQ 104(SP)
- MOVQ AX,R12
- MOVQ DX,R13
- MOVQ 120(SP),AX
- MULQ 112(SP)
- MOVQ AX,R14
- MOVQ DX,R15
- MOVQ 128(SP),AX
- MULQ 80(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 128(SP),AX
- MULQ 88(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 128(SP),AX
- MULQ 96(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 128(SP),AX
- MULQ 104(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 128(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 112(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 136(SP),AX
- MULQ 80(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 136(SP),AX
- MULQ 88(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 136(SP),AX
- MULQ 96(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 136(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 104(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 136(SP),DX
- IMUL3Q $19,DX,AX
- MULQ 112(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 144(SP),AX
- MULQ 80(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 144(SP),AX
- MULQ 88(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 0(SP),AX
- MULQ 104(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 0(SP),AX
- MULQ 112(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 152(SP),AX
- MULQ 80(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 8(SP),AX
- MULQ 96(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 8(SP),AX
- MULQ 104(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 8(SP),AX
- MULQ 112(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ $REDMASK51,DX
- SHLQ $13,SI,CX
- ANDQ DX,SI
- SHLQ $13,R8,R9
- ANDQ DX,R8
- ADDQ CX,R8
- SHLQ $13,R10,R11
- ANDQ DX,R10
- ADDQ R9,R10
- SHLQ $13,R12,R13
- ANDQ DX,R12
- ADDQ R11,R12
- SHLQ $13,R14,R15
- ANDQ DX,R14
- ADDQ R13,R14
- IMUL3Q $19,R15,CX
- ADDQ CX,SI
- MOVQ SI,CX
- SHRQ $51,CX
- ADDQ R8,CX
- MOVQ CX,R8
- SHRQ $51,CX
- ANDQ DX,SI
- ADDQ R10,CX
- MOVQ CX,R9
- SHRQ $51,CX
- ANDQ DX,R8
- ADDQ R12,CX
- MOVQ CX,AX
- SHRQ $51,CX
- ANDQ DX,R9
- ADDQ R14,CX
- MOVQ CX,R10
- SHRQ $51,CX
- ANDQ DX,AX
- IMUL3Q $19,CX,CX
- ADDQ CX,SI
- ANDQ DX,R10
- MOVQ SI,40(DI)
- MOVQ R8,48(DI)
- MOVQ R9,56(DI)
- MOVQ AX,64(DI)
- MOVQ R10,72(DI)
- MOVQ 160(SP),AX
- MULQ ·_121666_213(SB)
- SHRQ $13,AX
- MOVQ AX,SI
- MOVQ DX,CX
- MOVQ 168(SP),AX
- MULQ ·_121666_213(SB)
- SHRQ $13,AX
- ADDQ AX,CX
- MOVQ DX,R8
- MOVQ 176(SP),AX
- MULQ ·_121666_213(SB)
- SHRQ $13,AX
- ADDQ AX,R8
- MOVQ DX,R9
- MOVQ 184(SP),AX
- MULQ ·_121666_213(SB)
- SHRQ $13,AX
- ADDQ AX,R9
- MOVQ DX,R10
- MOVQ 192(SP),AX
- MULQ ·_121666_213(SB)
- SHRQ $13,AX
- ADDQ AX,R10
- IMUL3Q $19,DX,DX
- ADDQ DX,SI
- ADDQ 80(SP),SI
- ADDQ 88(SP),CX
- ADDQ 96(SP),R8
- ADDQ 104(SP),R9
- ADDQ 112(SP),R10
- MOVQ SI,80(DI)
- MOVQ CX,88(DI)
- MOVQ R8,96(DI)
- MOVQ R9,104(DI)
- MOVQ R10,112(DI)
- MOVQ 104(DI),SI
- IMUL3Q $19,SI,AX
- MOVQ AX,0(SP)
- MULQ 176(SP)
- MOVQ AX,SI
- MOVQ DX,CX
- MOVQ 112(DI),DX
- IMUL3Q $19,DX,AX
- MOVQ AX,8(SP)
- MULQ 168(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 80(DI),AX
- MULQ 160(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 80(DI),AX
- MULQ 168(SP)
- MOVQ AX,R8
- MOVQ DX,R9
- MOVQ 80(DI),AX
- MULQ 176(SP)
- MOVQ AX,R10
- MOVQ DX,R11
- MOVQ 80(DI),AX
- MULQ 184(SP)
- MOVQ AX,R12
- MOVQ DX,R13
- MOVQ 80(DI),AX
- MULQ 192(SP)
- MOVQ AX,R14
- MOVQ DX,R15
- MOVQ 88(DI),AX
- MULQ 160(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 88(DI),AX
- MULQ 168(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 88(DI),AX
- MULQ 176(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 88(DI),AX
- MULQ 184(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 88(DI),DX
- IMUL3Q $19,DX,AX
- MULQ 192(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 96(DI),AX
- MULQ 160(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 96(DI),AX
- MULQ 168(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 96(DI),AX
- MULQ 176(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 96(DI),DX
- IMUL3Q $19,DX,AX
- MULQ 184(SP)
- ADDQ AX,SI
- ADCQ DX,CX
- MOVQ 96(DI),DX
- IMUL3Q $19,DX,AX
- MULQ 192(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 104(DI),AX
- MULQ 160(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 104(DI),AX
- MULQ 168(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 0(SP),AX
- MULQ 184(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 0(SP),AX
- MULQ 192(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 112(DI),AX
- MULQ 160(SP)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 8(SP),AX
- MULQ 176(SP)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 8(SP),AX
- MULQ 184(SP)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 8(SP),AX
- MULQ 192(SP)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ $REDMASK51,DX
- SHLQ $13,SI,CX
- ANDQ DX,SI
- SHLQ $13,R8,R9
- ANDQ DX,R8
- ADDQ CX,R8
- SHLQ $13,R10,R11
- ANDQ DX,R10
- ADDQ R9,R10
- SHLQ $13,R12,R13
- ANDQ DX,R12
- ADDQ R11,R12
- SHLQ $13,R14,R15
- ANDQ DX,R14
- ADDQ R13,R14
- IMUL3Q $19,R15,CX
- ADDQ CX,SI
- MOVQ SI,CX
- SHRQ $51,CX
- ADDQ R8,CX
- MOVQ CX,R8
- SHRQ $51,CX
- ANDQ DX,SI
- ADDQ R10,CX
- MOVQ CX,R9
- SHRQ $51,CX
- ANDQ DX,R8
- ADDQ R12,CX
- MOVQ CX,AX
- SHRQ $51,CX
- ANDQ DX,R9
- ADDQ R14,CX
- MOVQ CX,R10
- SHRQ $51,CX
- ANDQ DX,AX
- IMUL3Q $19,CX,CX
- ADDQ CX,SI
- ANDQ DX,R10
- MOVQ SI,80(DI)
- MOVQ R8,88(DI)
- MOVQ R9,96(DI)
- MOVQ AX,104(DI)
- MOVQ R10,112(DI)
- RET
-
-// func cswap(inout *[4][5]uint64, v uint64)
-TEXT ·cswap(SB),7,$0
- MOVQ inout+0(FP),DI
- MOVQ v+8(FP),SI
-
- SUBQ $1, SI
- NOTQ SI
- MOVQ SI, X15
- PSHUFD $0x44, X15, X15
-
- MOVOU 0(DI), X0
- MOVOU 16(DI), X2
- MOVOU 32(DI), X4
- MOVOU 48(DI), X6
- MOVOU 64(DI), X8
- MOVOU 80(DI), X1
- MOVOU 96(DI), X3
- MOVOU 112(DI), X5
- MOVOU 128(DI), X7
- MOVOU 144(DI), X9
-
- MOVO X1, X10
- MOVO X3, X11
- MOVO X5, X12
- MOVO X7, X13
- MOVO X9, X14
-
- PXOR X0, X10
- PXOR X2, X11
- PXOR X4, X12
- PXOR X6, X13
- PXOR X8, X14
- PAND X15, X10
- PAND X15, X11
- PAND X15, X12
- PAND X15, X13
- PAND X15, X14
- PXOR X10, X0
- PXOR X10, X1
- PXOR X11, X2
- PXOR X11, X3
- PXOR X12, X4
- PXOR X12, X5
- PXOR X13, X6
- PXOR X13, X7
- PXOR X14, X8
- PXOR X14, X9
-
- MOVOU X0, 0(DI)
- MOVOU X2, 16(DI)
- MOVOU X4, 32(DI)
- MOVOU X6, 48(DI)
- MOVOU X8, 64(DI)
- MOVOU X1, 80(DI)
- MOVOU X3, 96(DI)
- MOVOU X5, 112(DI)
- MOVOU X7, 128(DI)
- MOVOU X9, 144(DI)
- RET
-
-// func mul(dest, a, b *[5]uint64)
-TEXT ·mul(SB),0,$16-24
- MOVQ dest+0(FP), DI
- MOVQ a+8(FP), SI
- MOVQ b+16(FP), DX
-
- MOVQ DX,CX
- MOVQ 24(SI),DX
- IMUL3Q $19,DX,AX
- MOVQ AX,0(SP)
- MULQ 16(CX)
- MOVQ AX,R8
- MOVQ DX,R9
- MOVQ 32(SI),DX
- IMUL3Q $19,DX,AX
- MOVQ AX,8(SP)
- MULQ 8(CX)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 0(SI),AX
- MULQ 0(CX)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 0(SI),AX
- MULQ 8(CX)
- MOVQ AX,R10
- MOVQ DX,R11
- MOVQ 0(SI),AX
- MULQ 16(CX)
- MOVQ AX,R12
- MOVQ DX,R13
- MOVQ 0(SI),AX
- MULQ 24(CX)
- MOVQ AX,R14
- MOVQ DX,R15
- MOVQ 0(SI),AX
- MULQ 32(CX)
- MOVQ AX,BX
- MOVQ DX,BP
- MOVQ 8(SI),AX
- MULQ 0(CX)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 8(SI),AX
- MULQ 8(CX)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 8(SI),AX
- MULQ 16(CX)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 8(SI),AX
- MULQ 24(CX)
- ADDQ AX,BX
- ADCQ DX,BP
- MOVQ 8(SI),DX
- IMUL3Q $19,DX,AX
- MULQ 32(CX)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 16(SI),AX
- MULQ 0(CX)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 16(SI),AX
- MULQ 8(CX)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 16(SI),AX
- MULQ 16(CX)
- ADDQ AX,BX
- ADCQ DX,BP
- MOVQ 16(SI),DX
- IMUL3Q $19,DX,AX
- MULQ 24(CX)
- ADDQ AX,R8
- ADCQ DX,R9
- MOVQ 16(SI),DX
- IMUL3Q $19,DX,AX
- MULQ 32(CX)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 24(SI),AX
- MULQ 0(CX)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ 24(SI),AX
- MULQ 8(CX)
- ADDQ AX,BX
- ADCQ DX,BP
- MOVQ 0(SP),AX
- MULQ 24(CX)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 0(SP),AX
- MULQ 32(CX)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 32(SI),AX
- MULQ 0(CX)
- ADDQ AX,BX
- ADCQ DX,BP
- MOVQ 8(SP),AX
- MULQ 16(CX)
- ADDQ AX,R10
- ADCQ DX,R11
- MOVQ 8(SP),AX
- MULQ 24(CX)
- ADDQ AX,R12
- ADCQ DX,R13
- MOVQ 8(SP),AX
- MULQ 32(CX)
- ADDQ AX,R14
- ADCQ DX,R15
- MOVQ $REDMASK51,SI
- SHLQ $13,R8,R9
- ANDQ SI,R8
- SHLQ $13,R10,R11
- ANDQ SI,R10
- ADDQ R9,R10
- SHLQ $13,R12,R13
- ANDQ SI,R12
- ADDQ R11,R12
- SHLQ $13,R14,R15
- ANDQ SI,R14
- ADDQ R13,R14
- SHLQ $13,BX,BP
- ANDQ SI,BX
- ADDQ R15,BX
- IMUL3Q $19,BP,DX
- ADDQ DX,R8
- MOVQ R8,DX
- SHRQ $51,DX
- ADDQ R10,DX
- MOVQ DX,CX
- SHRQ $51,DX
- ANDQ SI,R8
- ADDQ R12,DX
- MOVQ DX,R9
- SHRQ $51,DX
- ANDQ SI,CX
- ADDQ R14,DX
- MOVQ DX,AX
- SHRQ $51,DX
- ANDQ SI,R9
- ADDQ BX,DX
- MOVQ DX,R10
- SHRQ $51,DX
- ANDQ SI,AX
- IMUL3Q $19,DX,DX
- ADDQ DX,R8
- ANDQ SI,R10
- MOVQ R8,0(DI)
- MOVQ CX,8(DI)
- MOVQ R9,16(DI)
- MOVQ AX,24(DI)
- MOVQ R10,32(DI)
- RET
-
-// func square(out, in *[5]uint64)
-TEXT ·square(SB),7,$0-16
- MOVQ out+0(FP), DI
- MOVQ in+8(FP), SI
-
- MOVQ 0(SI),AX
- MULQ 0(SI)
- MOVQ AX,CX
- MOVQ DX,R8
- MOVQ 0(SI),AX
- SHLQ $1,AX
- MULQ 8(SI)
- MOVQ AX,R9
- MOVQ DX,R10
- MOVQ 0(SI),AX
- SHLQ $1,AX
- MULQ 16(SI)
- MOVQ AX,R11
- MOVQ DX,R12
- MOVQ 0(SI),AX
- SHLQ $1,AX
- MULQ 24(SI)
- MOVQ AX,R13
- MOVQ DX,R14
- MOVQ 0(SI),AX
- SHLQ $1,AX
- MULQ 32(SI)
- MOVQ AX,R15
- MOVQ DX,BX
- MOVQ 8(SI),AX
- MULQ 8(SI)
- ADDQ AX,R11
- ADCQ DX,R12
- MOVQ 8(SI),AX
- SHLQ $1,AX
- MULQ 16(SI)
- ADDQ AX,R13
- ADCQ DX,R14
- MOVQ 8(SI),AX
- SHLQ $1,AX
- MULQ 24(SI)
- ADDQ AX,R15
- ADCQ DX,BX
- MOVQ 8(SI),DX
- IMUL3Q $38,DX,AX
- MULQ 32(SI)
- ADDQ AX,CX
- ADCQ DX,R8
- MOVQ 16(SI),AX
- MULQ 16(SI)
- ADDQ AX,R15
- ADCQ DX,BX
- MOVQ 16(SI),DX
- IMUL3Q $38,DX,AX
- MULQ 24(SI)
- ADDQ AX,CX
- ADCQ DX,R8
- MOVQ 16(SI),DX
- IMUL3Q $38,DX,AX
- MULQ 32(SI)
- ADDQ AX,R9
- ADCQ DX,R10
- MOVQ 24(SI),DX
- IMUL3Q $19,DX,AX
- MULQ 24(SI)
- ADDQ AX,R9
- ADCQ DX,R10
- MOVQ 24(SI),DX
- IMUL3Q $38,DX,AX
- MULQ 32(SI)
- ADDQ AX,R11
- ADCQ DX,R12
- MOVQ 32(SI),DX
- IMUL3Q $19,DX,AX
- MULQ 32(SI)
- ADDQ AX,R13
- ADCQ DX,R14
- MOVQ $REDMASK51,SI
- SHLQ $13,CX,R8
- ANDQ SI,CX
- SHLQ $13,R9,R10
- ANDQ SI,R9
- ADDQ R8,R9
- SHLQ $13,R11,R12
- ANDQ SI,R11
- ADDQ R10,R11
- SHLQ $13,R13,R14
- ANDQ SI,R13
- ADDQ R12,R13
- SHLQ $13,R15,BX
- ANDQ SI,R15
- ADDQ R14,R15
- IMUL3Q $19,BX,DX
- ADDQ DX,CX
- MOVQ CX,DX
- SHRQ $51,DX
- ADDQ R9,DX
- ANDQ SI,CX
- MOVQ DX,R8
- SHRQ $51,DX
- ADDQ R11,DX
- ANDQ SI,R8
- MOVQ DX,R9
- SHRQ $51,DX
- ADDQ R13,DX
- ANDQ SI,R9
- MOVQ DX,AX
- SHRQ $51,DX
- ADDQ R15,DX
- ANDQ SI,AX
- MOVQ DX,R10
- SHRQ $51,DX
- IMUL3Q $19,DX,DX
- ADDQ DX,CX
- ANDQ SI,R10
- MOVQ CX,0(DI)
- MOVQ R8,8(DI)
- MOVQ R9,16(DI)
- MOVQ AX,24(DI)
- MOVQ R10,32(DI)
- RET
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go b/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go
new file mode 100644
index 0000000..ba647e8
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go
@@ -0,0 +1,105 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.20
+
+package curve25519
+
+import (
+ "crypto/subtle"
+ "errors"
+ "strconv"
+
+ "golang.org/x/crypto/curve25519/internal/field"
+)
+
+func scalarMult(dst, scalar, point *[32]byte) {
+ var e [32]byte
+
+ copy(e[:], scalar[:])
+ e[0] &= 248
+ e[31] &= 127
+ e[31] |= 64
+
+ var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
+ x1.SetBytes(point[:])
+ x2.One()
+ x3.Set(&x1)
+ z3.One()
+
+ swap := 0
+ for pos := 254; pos >= 0; pos-- {
+ b := e[pos/8] >> uint(pos&7)
+ b &= 1
+ swap ^= int(b)
+ x2.Swap(&x3, swap)
+ z2.Swap(&z3, swap)
+ swap = int(b)
+
+ tmp0.Subtract(&x3, &z3)
+ tmp1.Subtract(&x2, &z2)
+ x2.Add(&x2, &z2)
+ z2.Add(&x3, &z3)
+ z3.Multiply(&tmp0, &x2)
+ z2.Multiply(&z2, &tmp1)
+ tmp0.Square(&tmp1)
+ tmp1.Square(&x2)
+ x3.Add(&z3, &z2)
+ z2.Subtract(&z3, &z2)
+ x2.Multiply(&tmp1, &tmp0)
+ tmp1.Subtract(&tmp1, &tmp0)
+ z2.Square(&z2)
+
+ z3.Mult32(&tmp1, 121666)
+ x3.Square(&x3)
+ tmp0.Add(&tmp0, &z3)
+ z3.Multiply(&x1, &z2)
+ z2.Multiply(&tmp1, &tmp0)
+ }
+
+ x2.Swap(&x3, swap)
+ z2.Swap(&z3, swap)
+
+ z2.Invert(&z2)
+ x2.Multiply(&x2, &z2)
+ copy(dst[:], x2.Bytes())
+}
+
+func scalarBaseMult(dst, scalar *[32]byte) {
+ checkBasepoint()
+ scalarMult(dst, scalar, &basePoint)
+}
+
+func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
+ var in [32]byte
+ if l := len(scalar); l != 32 {
+ return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32")
+ }
+ if l := len(point); l != 32 {
+ return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32")
+ }
+ copy(in[:], scalar)
+ if &point[0] == &Basepoint[0] {
+ scalarBaseMult(dst, &in)
+ } else {
+ var base, zero [32]byte
+ copy(base[:], point)
+ scalarMult(dst, &in, &base)
+ if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
+ return nil, errors.New("bad input point: low order point")
+ }
+ }
+ return dst[:], nil
+}
+
+func checkBasepoint() {
+ if subtle.ConstantTimeCompare(Basepoint, []byte{
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ }) != 1 {
+ panic("curve25519: global Basepoint value was modified")
+ }
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_generic.go b/vendor/golang.org/x/crypto/curve25519/curve25519_generic.go
deleted file mode 100644
index c43b13f..0000000
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_generic.go
+++ /dev/null
@@ -1,828 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package curve25519
-
-import "encoding/binary"
-
-// This code is a port of the public domain, "ref10" implementation of
-// curve25519 from SUPERCOP 20130419 by D. J. Bernstein.
-
-// fieldElement represents an element of the field GF(2^255 - 19). An element
-// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
-// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
-// context.
-type fieldElement [10]int32
-
-func feZero(fe *fieldElement) {
- for i := range fe {
- fe[i] = 0
- }
-}
-
-func feOne(fe *fieldElement) {
- feZero(fe)
- fe[0] = 1
-}
-
-func feAdd(dst, a, b *fieldElement) {
- for i := range dst {
- dst[i] = a[i] + b[i]
- }
-}
-
-func feSub(dst, a, b *fieldElement) {
- for i := range dst {
- dst[i] = a[i] - b[i]
- }
-}
-
-func feCopy(dst, src *fieldElement) {
- for i := range dst {
- dst[i] = src[i]
- }
-}
-
-// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0.
-//
-// Preconditions: b in {0,1}.
-func feCSwap(f, g *fieldElement, b int32) {
- b = -b
- for i := range f {
- t := b & (f[i] ^ g[i])
- f[i] ^= t
- g[i] ^= t
- }
-}
-
-// load3 reads a 24-bit, little-endian value from in.
-func load3(in []byte) int64 {
- var r int64
- r = int64(in[0])
- r |= int64(in[1]) << 8
- r |= int64(in[2]) << 16
- return r
-}
-
-// load4 reads a 32-bit, little-endian value from in.
-func load4(in []byte) int64 {
- return int64(binary.LittleEndian.Uint32(in))
-}
-
-func feFromBytes(dst *fieldElement, src *[32]byte) {
- h0 := load4(src[:])
- h1 := load3(src[4:]) << 6
- h2 := load3(src[7:]) << 5
- h3 := load3(src[10:]) << 3
- h4 := load3(src[13:]) << 2
- h5 := load4(src[16:])
- h6 := load3(src[20:]) << 7
- h7 := load3(src[23:]) << 5
- h8 := load3(src[26:]) << 4
- h9 := (load3(src[29:]) & 0x7fffff) << 2
-
- var carry [10]int64
- carry[9] = (h9 + 1<<24) >> 25
- h0 += carry[9] * 19
- h9 -= carry[9] << 25
- carry[1] = (h1 + 1<<24) >> 25
- h2 += carry[1]
- h1 -= carry[1] << 25
- carry[3] = (h3 + 1<<24) >> 25
- h4 += carry[3]
- h3 -= carry[3] << 25
- carry[5] = (h5 + 1<<24) >> 25
- h6 += carry[5]
- h5 -= carry[5] << 25
- carry[7] = (h7 + 1<<24) >> 25
- h8 += carry[7]
- h7 -= carry[7] << 25
-
- carry[0] = (h0 + 1<<25) >> 26
- h1 += carry[0]
- h0 -= carry[0] << 26
- carry[2] = (h2 + 1<<25) >> 26
- h3 += carry[2]
- h2 -= carry[2] << 26
- carry[4] = (h4 + 1<<25) >> 26
- h5 += carry[4]
- h4 -= carry[4] << 26
- carry[6] = (h6 + 1<<25) >> 26
- h7 += carry[6]
- h6 -= carry[6] << 26
- carry[8] = (h8 + 1<<25) >> 26
- h9 += carry[8]
- h8 -= carry[8] << 26
-
- dst[0] = int32(h0)
- dst[1] = int32(h1)
- dst[2] = int32(h2)
- dst[3] = int32(h3)
- dst[4] = int32(h4)
- dst[5] = int32(h5)
- dst[6] = int32(h6)
- dst[7] = int32(h7)
- dst[8] = int32(h8)
- dst[9] = int32(h9)
-}
-
-// feToBytes marshals h to s.
-// Preconditions:
-// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-//
-// Write p=2^255-19; q=floor(h/p).
-// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
-//
-// Proof:
-// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
-// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
-//
-// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
-// Then 0> 25
- q = (h[0] + q) >> 26
- q = (h[1] + q) >> 25
- q = (h[2] + q) >> 26
- q = (h[3] + q) >> 25
- q = (h[4] + q) >> 26
- q = (h[5] + q) >> 25
- q = (h[6] + q) >> 26
- q = (h[7] + q) >> 25
- q = (h[8] + q) >> 26
- q = (h[9] + q) >> 25
-
- // Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20.
- h[0] += 19 * q
- // Goal: Output h-2^255 q, which is between 0 and 2^255-20.
-
- carry[0] = h[0] >> 26
- h[1] += carry[0]
- h[0] -= carry[0] << 26
- carry[1] = h[1] >> 25
- h[2] += carry[1]
- h[1] -= carry[1] << 25
- carry[2] = h[2] >> 26
- h[3] += carry[2]
- h[2] -= carry[2] << 26
- carry[3] = h[3] >> 25
- h[4] += carry[3]
- h[3] -= carry[3] << 25
- carry[4] = h[4] >> 26
- h[5] += carry[4]
- h[4] -= carry[4] << 26
- carry[5] = h[5] >> 25
- h[6] += carry[5]
- h[5] -= carry[5] << 25
- carry[6] = h[6] >> 26
- h[7] += carry[6]
- h[6] -= carry[6] << 26
- carry[7] = h[7] >> 25
- h[8] += carry[7]
- h[7] -= carry[7] << 25
- carry[8] = h[8] >> 26
- h[9] += carry[8]
- h[8] -= carry[8] << 26
- carry[9] = h[9] >> 25
- h[9] -= carry[9] << 25
- // h10 = carry9
-
- // Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
- // Have h[0]+...+2^230 h[9] between 0 and 2^255-1;
- // evidently 2^255 h10-2^255 q = 0.
- // Goal: Output h[0]+...+2^230 h[9].
-
- s[0] = byte(h[0] >> 0)
- s[1] = byte(h[0] >> 8)
- s[2] = byte(h[0] >> 16)
- s[3] = byte((h[0] >> 24) | (h[1] << 2))
- s[4] = byte(h[1] >> 6)
- s[5] = byte(h[1] >> 14)
- s[6] = byte((h[1] >> 22) | (h[2] << 3))
- s[7] = byte(h[2] >> 5)
- s[8] = byte(h[2] >> 13)
- s[9] = byte((h[2] >> 21) | (h[3] << 5))
- s[10] = byte(h[3] >> 3)
- s[11] = byte(h[3] >> 11)
- s[12] = byte((h[3] >> 19) | (h[4] << 6))
- s[13] = byte(h[4] >> 2)
- s[14] = byte(h[4] >> 10)
- s[15] = byte(h[4] >> 18)
- s[16] = byte(h[5] >> 0)
- s[17] = byte(h[5] >> 8)
- s[18] = byte(h[5] >> 16)
- s[19] = byte((h[5] >> 24) | (h[6] << 1))
- s[20] = byte(h[6] >> 7)
- s[21] = byte(h[6] >> 15)
- s[22] = byte((h[6] >> 23) | (h[7] << 3))
- s[23] = byte(h[7] >> 5)
- s[24] = byte(h[7] >> 13)
- s[25] = byte((h[7] >> 21) | (h[8] << 4))
- s[26] = byte(h[8] >> 4)
- s[27] = byte(h[8] >> 12)
- s[28] = byte((h[8] >> 20) | (h[9] << 6))
- s[29] = byte(h[9] >> 2)
- s[30] = byte(h[9] >> 10)
- s[31] = byte(h[9] >> 18)
-}
-
-// feMul calculates h = f * g
-// Can overlap h with f or g.
-//
-// Preconditions:
-// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
-// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
-//
-// Postconditions:
-// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-//
-// Notes on implementation strategy:
-//
-// Using schoolbook multiplication.
-// Karatsuba would save a little in some cost models.
-//
-// Most multiplications by 2 and 19 are 32-bit precomputations;
-// cheaper than 64-bit postcomputations.
-//
-// There is one remaining multiplication by 19 in the carry chain;
-// one *19 precomputation can be merged into this,
-// but the resulting data flow is considerably less clean.
-//
-// There are 12 carries below.
-// 10 of them are 2-way parallelizable and vectorizable.
-// Can get away with 11 carries, but then data flow is much deeper.
-//
-// With tighter constraints on inputs can squeeze carries into int32.
-func feMul(h, f, g *fieldElement) {
- f0 := f[0]
- f1 := f[1]
- f2 := f[2]
- f3 := f[3]
- f4 := f[4]
- f5 := f[5]
- f6 := f[6]
- f7 := f[7]
- f8 := f[8]
- f9 := f[9]
- g0 := g[0]
- g1 := g[1]
- g2 := g[2]
- g3 := g[3]
- g4 := g[4]
- g5 := g[5]
- g6 := g[6]
- g7 := g[7]
- g8 := g[8]
- g9 := g[9]
- g1_19 := 19 * g1 // 1.4*2^29
- g2_19 := 19 * g2 // 1.4*2^30; still ok
- g3_19 := 19 * g3
- g4_19 := 19 * g4
- g5_19 := 19 * g5
- g6_19 := 19 * g6
- g7_19 := 19 * g7
- g8_19 := 19 * g8
- g9_19 := 19 * g9
- f1_2 := 2 * f1
- f3_2 := 2 * f3
- f5_2 := 2 * f5
- f7_2 := 2 * f7
- f9_2 := 2 * f9
- f0g0 := int64(f0) * int64(g0)
- f0g1 := int64(f0) * int64(g1)
- f0g2 := int64(f0) * int64(g2)
- f0g3 := int64(f0) * int64(g3)
- f0g4 := int64(f0) * int64(g4)
- f0g5 := int64(f0) * int64(g5)
- f0g6 := int64(f0) * int64(g6)
- f0g7 := int64(f0) * int64(g7)
- f0g8 := int64(f0) * int64(g8)
- f0g9 := int64(f0) * int64(g9)
- f1g0 := int64(f1) * int64(g0)
- f1g1_2 := int64(f1_2) * int64(g1)
- f1g2 := int64(f1) * int64(g2)
- f1g3_2 := int64(f1_2) * int64(g3)
- f1g4 := int64(f1) * int64(g4)
- f1g5_2 := int64(f1_2) * int64(g5)
- f1g6 := int64(f1) * int64(g6)
- f1g7_2 := int64(f1_2) * int64(g7)
- f1g8 := int64(f1) * int64(g8)
- f1g9_38 := int64(f1_2) * int64(g9_19)
- f2g0 := int64(f2) * int64(g0)
- f2g1 := int64(f2) * int64(g1)
- f2g2 := int64(f2) * int64(g2)
- f2g3 := int64(f2) * int64(g3)
- f2g4 := int64(f2) * int64(g4)
- f2g5 := int64(f2) * int64(g5)
- f2g6 := int64(f2) * int64(g6)
- f2g7 := int64(f2) * int64(g7)
- f2g8_19 := int64(f2) * int64(g8_19)
- f2g9_19 := int64(f2) * int64(g9_19)
- f3g0 := int64(f3) * int64(g0)
- f3g1_2 := int64(f3_2) * int64(g1)
- f3g2 := int64(f3) * int64(g2)
- f3g3_2 := int64(f3_2) * int64(g3)
- f3g4 := int64(f3) * int64(g4)
- f3g5_2 := int64(f3_2) * int64(g5)
- f3g6 := int64(f3) * int64(g6)
- f3g7_38 := int64(f3_2) * int64(g7_19)
- f3g8_19 := int64(f3) * int64(g8_19)
- f3g9_38 := int64(f3_2) * int64(g9_19)
- f4g0 := int64(f4) * int64(g0)
- f4g1 := int64(f4) * int64(g1)
- f4g2 := int64(f4) * int64(g2)
- f4g3 := int64(f4) * int64(g3)
- f4g4 := int64(f4) * int64(g4)
- f4g5 := int64(f4) * int64(g5)
- f4g6_19 := int64(f4) * int64(g6_19)
- f4g7_19 := int64(f4) * int64(g7_19)
- f4g8_19 := int64(f4) * int64(g8_19)
- f4g9_19 := int64(f4) * int64(g9_19)
- f5g0 := int64(f5) * int64(g0)
- f5g1_2 := int64(f5_2) * int64(g1)
- f5g2 := int64(f5) * int64(g2)
- f5g3_2 := int64(f5_2) * int64(g3)
- f5g4 := int64(f5) * int64(g4)
- f5g5_38 := int64(f5_2) * int64(g5_19)
- f5g6_19 := int64(f5) * int64(g6_19)
- f5g7_38 := int64(f5_2) * int64(g7_19)
- f5g8_19 := int64(f5) * int64(g8_19)
- f5g9_38 := int64(f5_2) * int64(g9_19)
- f6g0 := int64(f6) * int64(g0)
- f6g1 := int64(f6) * int64(g1)
- f6g2 := int64(f6) * int64(g2)
- f6g3 := int64(f6) * int64(g3)
- f6g4_19 := int64(f6) * int64(g4_19)
- f6g5_19 := int64(f6) * int64(g5_19)
- f6g6_19 := int64(f6) * int64(g6_19)
- f6g7_19 := int64(f6) * int64(g7_19)
- f6g8_19 := int64(f6) * int64(g8_19)
- f6g9_19 := int64(f6) * int64(g9_19)
- f7g0 := int64(f7) * int64(g0)
- f7g1_2 := int64(f7_2) * int64(g1)
- f7g2 := int64(f7) * int64(g2)
- f7g3_38 := int64(f7_2) * int64(g3_19)
- f7g4_19 := int64(f7) * int64(g4_19)
- f7g5_38 := int64(f7_2) * int64(g5_19)
- f7g6_19 := int64(f7) * int64(g6_19)
- f7g7_38 := int64(f7_2) * int64(g7_19)
- f7g8_19 := int64(f7) * int64(g8_19)
- f7g9_38 := int64(f7_2) * int64(g9_19)
- f8g0 := int64(f8) * int64(g0)
- f8g1 := int64(f8) * int64(g1)
- f8g2_19 := int64(f8) * int64(g2_19)
- f8g3_19 := int64(f8) * int64(g3_19)
- f8g4_19 := int64(f8) * int64(g4_19)
- f8g5_19 := int64(f8) * int64(g5_19)
- f8g6_19 := int64(f8) * int64(g6_19)
- f8g7_19 := int64(f8) * int64(g7_19)
- f8g8_19 := int64(f8) * int64(g8_19)
- f8g9_19 := int64(f8) * int64(g9_19)
- f9g0 := int64(f9) * int64(g0)
- f9g1_38 := int64(f9_2) * int64(g1_19)
- f9g2_19 := int64(f9) * int64(g2_19)
- f9g3_38 := int64(f9_2) * int64(g3_19)
- f9g4_19 := int64(f9) * int64(g4_19)
- f9g5_38 := int64(f9_2) * int64(g5_19)
- f9g6_19 := int64(f9) * int64(g6_19)
- f9g7_38 := int64(f9_2) * int64(g7_19)
- f9g8_19 := int64(f9) * int64(g8_19)
- f9g9_38 := int64(f9_2) * int64(g9_19)
- h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38
- h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19
- h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38
- h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19
- h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38
- h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19
- h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38
- h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19
- h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38
- h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0
- var carry [10]int64
-
- // |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
- // i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
- // |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
- // i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
-
- carry[0] = (h0 + (1 << 25)) >> 26
- h1 += carry[0]
- h0 -= carry[0] << 26
- carry[4] = (h4 + (1 << 25)) >> 26
- h5 += carry[4]
- h4 -= carry[4] << 26
- // |h0| <= 2^25
- // |h4| <= 2^25
- // |h1| <= 1.51*2^58
- // |h5| <= 1.51*2^58
-
- carry[1] = (h1 + (1 << 24)) >> 25
- h2 += carry[1]
- h1 -= carry[1] << 25
- carry[5] = (h5 + (1 << 24)) >> 25
- h6 += carry[5]
- h5 -= carry[5] << 25
- // |h1| <= 2^24; from now on fits into int32
- // |h5| <= 2^24; from now on fits into int32
- // |h2| <= 1.21*2^59
- // |h6| <= 1.21*2^59
-
- carry[2] = (h2 + (1 << 25)) >> 26
- h3 += carry[2]
- h2 -= carry[2] << 26
- carry[6] = (h6 + (1 << 25)) >> 26
- h7 += carry[6]
- h6 -= carry[6] << 26
- // |h2| <= 2^25; from now on fits into int32 unchanged
- // |h6| <= 2^25; from now on fits into int32 unchanged
- // |h3| <= 1.51*2^58
- // |h7| <= 1.51*2^58
-
- carry[3] = (h3 + (1 << 24)) >> 25
- h4 += carry[3]
- h3 -= carry[3] << 25
- carry[7] = (h7 + (1 << 24)) >> 25
- h8 += carry[7]
- h7 -= carry[7] << 25
- // |h3| <= 2^24; from now on fits into int32 unchanged
- // |h7| <= 2^24; from now on fits into int32 unchanged
- // |h4| <= 1.52*2^33
- // |h8| <= 1.52*2^33
-
- carry[4] = (h4 + (1 << 25)) >> 26
- h5 += carry[4]
- h4 -= carry[4] << 26
- carry[8] = (h8 + (1 << 25)) >> 26
- h9 += carry[8]
- h8 -= carry[8] << 26
- // |h4| <= 2^25; from now on fits into int32 unchanged
- // |h8| <= 2^25; from now on fits into int32 unchanged
- // |h5| <= 1.01*2^24
- // |h9| <= 1.51*2^58
-
- carry[9] = (h9 + (1 << 24)) >> 25
- h0 += carry[9] * 19
- h9 -= carry[9] << 25
- // |h9| <= 2^24; from now on fits into int32 unchanged
- // |h0| <= 1.8*2^37
-
- carry[0] = (h0 + (1 << 25)) >> 26
- h1 += carry[0]
- h0 -= carry[0] << 26
- // |h0| <= 2^25; from now on fits into int32 unchanged
- // |h1| <= 1.01*2^24
-
- h[0] = int32(h0)
- h[1] = int32(h1)
- h[2] = int32(h2)
- h[3] = int32(h3)
- h[4] = int32(h4)
- h[5] = int32(h5)
- h[6] = int32(h6)
- h[7] = int32(h7)
- h[8] = int32(h8)
- h[9] = int32(h9)
-}
-
-// feSquare calculates h = f*f. Can overlap h with f.
-//
-// Preconditions:
-// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
-//
-// Postconditions:
-// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-func feSquare(h, f *fieldElement) {
- f0 := f[0]
- f1 := f[1]
- f2 := f[2]
- f3 := f[3]
- f4 := f[4]
- f5 := f[5]
- f6 := f[6]
- f7 := f[7]
- f8 := f[8]
- f9 := f[9]
- f0_2 := 2 * f0
- f1_2 := 2 * f1
- f2_2 := 2 * f2
- f3_2 := 2 * f3
- f4_2 := 2 * f4
- f5_2 := 2 * f5
- f6_2 := 2 * f6
- f7_2 := 2 * f7
- f5_38 := 38 * f5 // 1.31*2^30
- f6_19 := 19 * f6 // 1.31*2^30
- f7_38 := 38 * f7 // 1.31*2^30
- f8_19 := 19 * f8 // 1.31*2^30
- f9_38 := 38 * f9 // 1.31*2^30
- f0f0 := int64(f0) * int64(f0)
- f0f1_2 := int64(f0_2) * int64(f1)
- f0f2_2 := int64(f0_2) * int64(f2)
- f0f3_2 := int64(f0_2) * int64(f3)
- f0f4_2 := int64(f0_2) * int64(f4)
- f0f5_2 := int64(f0_2) * int64(f5)
- f0f6_2 := int64(f0_2) * int64(f6)
- f0f7_2 := int64(f0_2) * int64(f7)
- f0f8_2 := int64(f0_2) * int64(f8)
- f0f9_2 := int64(f0_2) * int64(f9)
- f1f1_2 := int64(f1_2) * int64(f1)
- f1f2_2 := int64(f1_2) * int64(f2)
- f1f3_4 := int64(f1_2) * int64(f3_2)
- f1f4_2 := int64(f1_2) * int64(f4)
- f1f5_4 := int64(f1_2) * int64(f5_2)
- f1f6_2 := int64(f1_2) * int64(f6)
- f1f7_4 := int64(f1_2) * int64(f7_2)
- f1f8_2 := int64(f1_2) * int64(f8)
- f1f9_76 := int64(f1_2) * int64(f9_38)
- f2f2 := int64(f2) * int64(f2)
- f2f3_2 := int64(f2_2) * int64(f3)
- f2f4_2 := int64(f2_2) * int64(f4)
- f2f5_2 := int64(f2_2) * int64(f5)
- f2f6_2 := int64(f2_2) * int64(f6)
- f2f7_2 := int64(f2_2) * int64(f7)
- f2f8_38 := int64(f2_2) * int64(f8_19)
- f2f9_38 := int64(f2) * int64(f9_38)
- f3f3_2 := int64(f3_2) * int64(f3)
- f3f4_2 := int64(f3_2) * int64(f4)
- f3f5_4 := int64(f3_2) * int64(f5_2)
- f3f6_2 := int64(f3_2) * int64(f6)
- f3f7_76 := int64(f3_2) * int64(f7_38)
- f3f8_38 := int64(f3_2) * int64(f8_19)
- f3f9_76 := int64(f3_2) * int64(f9_38)
- f4f4 := int64(f4) * int64(f4)
- f4f5_2 := int64(f4_2) * int64(f5)
- f4f6_38 := int64(f4_2) * int64(f6_19)
- f4f7_38 := int64(f4) * int64(f7_38)
- f4f8_38 := int64(f4_2) * int64(f8_19)
- f4f9_38 := int64(f4) * int64(f9_38)
- f5f5_38 := int64(f5) * int64(f5_38)
- f5f6_38 := int64(f5_2) * int64(f6_19)
- f5f7_76 := int64(f5_2) * int64(f7_38)
- f5f8_38 := int64(f5_2) * int64(f8_19)
- f5f9_76 := int64(f5_2) * int64(f9_38)
- f6f6_19 := int64(f6) * int64(f6_19)
- f6f7_38 := int64(f6) * int64(f7_38)
- f6f8_38 := int64(f6_2) * int64(f8_19)
- f6f9_38 := int64(f6) * int64(f9_38)
- f7f7_38 := int64(f7) * int64(f7_38)
- f7f8_38 := int64(f7_2) * int64(f8_19)
- f7f9_76 := int64(f7_2) * int64(f9_38)
- f8f8_19 := int64(f8) * int64(f8_19)
- f8f9_38 := int64(f8) * int64(f9_38)
- f9f9_38 := int64(f9) * int64(f9_38)
- h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38
- h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38
- h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19
- h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38
- h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38
- h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38
- h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19
- h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38
- h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38
- h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2
- var carry [10]int64
-
- carry[0] = (h0 + (1 << 25)) >> 26
- h1 += carry[0]
- h0 -= carry[0] << 26
- carry[4] = (h4 + (1 << 25)) >> 26
- h5 += carry[4]
- h4 -= carry[4] << 26
-
- carry[1] = (h1 + (1 << 24)) >> 25
- h2 += carry[1]
- h1 -= carry[1] << 25
- carry[5] = (h5 + (1 << 24)) >> 25
- h6 += carry[5]
- h5 -= carry[5] << 25
-
- carry[2] = (h2 + (1 << 25)) >> 26
- h3 += carry[2]
- h2 -= carry[2] << 26
- carry[6] = (h6 + (1 << 25)) >> 26
- h7 += carry[6]
- h6 -= carry[6] << 26
-
- carry[3] = (h3 + (1 << 24)) >> 25
- h4 += carry[3]
- h3 -= carry[3] << 25
- carry[7] = (h7 + (1 << 24)) >> 25
- h8 += carry[7]
- h7 -= carry[7] << 25
-
- carry[4] = (h4 + (1 << 25)) >> 26
- h5 += carry[4]
- h4 -= carry[4] << 26
- carry[8] = (h8 + (1 << 25)) >> 26
- h9 += carry[8]
- h8 -= carry[8] << 26
-
- carry[9] = (h9 + (1 << 24)) >> 25
- h0 += carry[9] * 19
- h9 -= carry[9] << 25
-
- carry[0] = (h0 + (1 << 25)) >> 26
- h1 += carry[0]
- h0 -= carry[0] << 26
-
- h[0] = int32(h0)
- h[1] = int32(h1)
- h[2] = int32(h2)
- h[3] = int32(h3)
- h[4] = int32(h4)
- h[5] = int32(h5)
- h[6] = int32(h6)
- h[7] = int32(h7)
- h[8] = int32(h8)
- h[9] = int32(h9)
-}
-
-// feMul121666 calculates h = f * 121666. Can overlap h with f.
-//
-// Preconditions:
-// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
-//
-// Postconditions:
-// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-func feMul121666(h, f *fieldElement) {
- h0 := int64(f[0]) * 121666
- h1 := int64(f[1]) * 121666
- h2 := int64(f[2]) * 121666
- h3 := int64(f[3]) * 121666
- h4 := int64(f[4]) * 121666
- h5 := int64(f[5]) * 121666
- h6 := int64(f[6]) * 121666
- h7 := int64(f[7]) * 121666
- h8 := int64(f[8]) * 121666
- h9 := int64(f[9]) * 121666
- var carry [10]int64
-
- carry[9] = (h9 + (1 << 24)) >> 25
- h0 += carry[9] * 19
- h9 -= carry[9] << 25
- carry[1] = (h1 + (1 << 24)) >> 25
- h2 += carry[1]
- h1 -= carry[1] << 25
- carry[3] = (h3 + (1 << 24)) >> 25
- h4 += carry[3]
- h3 -= carry[3] << 25
- carry[5] = (h5 + (1 << 24)) >> 25
- h6 += carry[5]
- h5 -= carry[5] << 25
- carry[7] = (h7 + (1 << 24)) >> 25
- h8 += carry[7]
- h7 -= carry[7] << 25
-
- carry[0] = (h0 + (1 << 25)) >> 26
- h1 += carry[0]
- h0 -= carry[0] << 26
- carry[2] = (h2 + (1 << 25)) >> 26
- h3 += carry[2]
- h2 -= carry[2] << 26
- carry[4] = (h4 + (1 << 25)) >> 26
- h5 += carry[4]
- h4 -= carry[4] << 26
- carry[6] = (h6 + (1 << 25)) >> 26
- h7 += carry[6]
- h6 -= carry[6] << 26
- carry[8] = (h8 + (1 << 25)) >> 26
- h9 += carry[8]
- h8 -= carry[8] << 26
-
- h[0] = int32(h0)
- h[1] = int32(h1)
- h[2] = int32(h2)
- h[3] = int32(h3)
- h[4] = int32(h4)
- h[5] = int32(h5)
- h[6] = int32(h6)
- h[7] = int32(h7)
- h[8] = int32(h8)
- h[9] = int32(h9)
-}
-
-// feInvert sets out = z^-1.
-func feInvert(out, z *fieldElement) {
- var t0, t1, t2, t3 fieldElement
- var i int
-
- feSquare(&t0, z)
- for i = 1; i < 1; i++ {
- feSquare(&t0, &t0)
- }
- feSquare(&t1, &t0)
- for i = 1; i < 2; i++ {
- feSquare(&t1, &t1)
- }
- feMul(&t1, z, &t1)
- feMul(&t0, &t0, &t1)
- feSquare(&t2, &t0)
- for i = 1; i < 1; i++ {
- feSquare(&t2, &t2)
- }
- feMul(&t1, &t1, &t2)
- feSquare(&t2, &t1)
- for i = 1; i < 5; i++ {
- feSquare(&t2, &t2)
- }
- feMul(&t1, &t2, &t1)
- feSquare(&t2, &t1)
- for i = 1; i < 10; i++ {
- feSquare(&t2, &t2)
- }
- feMul(&t2, &t2, &t1)
- feSquare(&t3, &t2)
- for i = 1; i < 20; i++ {
- feSquare(&t3, &t3)
- }
- feMul(&t2, &t3, &t2)
- feSquare(&t2, &t2)
- for i = 1; i < 10; i++ {
- feSquare(&t2, &t2)
- }
- feMul(&t1, &t2, &t1)
- feSquare(&t2, &t1)
- for i = 1; i < 50; i++ {
- feSquare(&t2, &t2)
- }
- feMul(&t2, &t2, &t1)
- feSquare(&t3, &t2)
- for i = 1; i < 100; i++ {
- feSquare(&t3, &t3)
- }
- feMul(&t2, &t3, &t2)
- feSquare(&t2, &t2)
- for i = 1; i < 50; i++ {
- feSquare(&t2, &t2)
- }
- feMul(&t1, &t2, &t1)
- feSquare(&t1, &t1)
- for i = 1; i < 5; i++ {
- feSquare(&t1, &t1)
- }
- feMul(out, &t1, &t0)
-}
-
-func scalarMultGeneric(out, in, base *[32]byte) {
- var e [32]byte
-
- copy(e[:], in[:])
- e[0] &= 248
- e[31] &= 127
- e[31] |= 64
-
- var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement
- feFromBytes(&x1, base)
- feOne(&x2)
- feCopy(&x3, &x1)
- feOne(&z3)
-
- swap := int32(0)
- for pos := 254; pos >= 0; pos-- {
- b := e[pos/8] >> uint(pos&7)
- b &= 1
- swap ^= int32(b)
- feCSwap(&x2, &x3, swap)
- feCSwap(&z2, &z3, swap)
- swap = int32(b)
-
- feSub(&tmp0, &x3, &z3)
- feSub(&tmp1, &x2, &z2)
- feAdd(&x2, &x2, &z2)
- feAdd(&z2, &x3, &z3)
- feMul(&z3, &tmp0, &x2)
- feMul(&z2, &z2, &tmp1)
- feSquare(&tmp0, &tmp1)
- feSquare(&tmp1, &x2)
- feAdd(&x3, &z3, &z2)
- feSub(&z2, &z3, &z2)
- feMul(&x2, &tmp1, &tmp0)
- feSub(&tmp1, &tmp1, &tmp0)
- feSquare(&z2, &z2)
- feMul121666(&z3, &tmp1)
- feSquare(&x3, &x3)
- feAdd(&tmp0, &tmp0, &z3)
- feMul(&z3, &x1, &z2)
- feMul(&z2, &tmp1, &tmp0)
- }
-
- feCSwap(&x2, &x3, swap)
- feCSwap(&z2, &z3, swap)
-
- feInvert(&z2, &z2)
- feMul(&x2, &x2, &z2)
- feToBytes(out, &x2)
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go b/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go
new file mode 100644
index 0000000..627df49
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go
@@ -0,0 +1,46 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.20
+
+package curve25519
+
+import "crypto/ecdh"
+
+func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
+ curve := ecdh.X25519()
+ pub, err := curve.NewPublicKey(point)
+ if err != nil {
+ return nil, err
+ }
+ priv, err := curve.NewPrivateKey(scalar)
+ if err != nil {
+ return nil, err
+ }
+ out, err := priv.ECDH(pub)
+ if err != nil {
+ return nil, err
+ }
+ copy(dst[:], out)
+ return dst[:], nil
+}
+
+func scalarMult(dst, scalar, point *[32]byte) {
+ if _, err := x25519(dst, scalar[:], point[:]); err != nil {
+ // The only error condition for x25519 when the inputs are 32 bytes long
+ // is if the output would have been the all-zero value.
+ for i := range dst {
+ dst[i] = 0
+ }
+ }
+}
+
+func scalarBaseMult(dst, scalar *[32]byte) {
+ curve := ecdh.X25519()
+ priv, err := curve.NewPrivateKey(scalar[:])
+ if err != nil {
+ panic("curve25519: internal error: scalarBaseMult was not 32 bytes")
+ }
+ copy(dst[:], priv.PublicKey().Bytes())
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go b/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
deleted file mode 100644
index 047d49a..0000000
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !amd64 gccgo appengine purego
-
-package curve25519
-
-func scalarMult(out, in, base *[32]byte) {
- scalarMultGeneric(out, in, base)
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/README b/vendor/golang.org/x/crypto/curve25519/internal/field/README
new file mode 100644
index 0000000..e25bca7
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/README
@@ -0,0 +1,7 @@
+This package is kept in sync with crypto/ed25519/internal/edwards25519/field in
+the standard library.
+
+If there are any changes in the standard library that need to be synced to this
+package, run sync.sh. It will not overwrite any local changes made since the
+previous sync, so it's ok to land changes in this package first, and then sync
+to the standard library later.
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
new file mode 100644
index 0000000..ca841ad
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
@@ -0,0 +1,416 @@
+// Copyright (c) 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package field implements fast arithmetic modulo 2^255-19.
+package field
+
+import (
+ "crypto/subtle"
+ "encoding/binary"
+ "math/bits"
+)
+
+// Element represents an element of the field GF(2^255-19). Note that this
+// is not a cryptographically secure group, and should only be used to interact
+// with edwards25519.Point coordinates.
+//
+// This type works similarly to math/big.Int, and all arguments and receivers
+// are allowed to alias.
+//
+// The zero value is a valid zero element.
+type Element struct {
+ // An element t represents the integer
+ // t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204
+ //
+ // Between operations, all limbs are expected to be lower than 2^52.
+ l0 uint64
+ l1 uint64
+ l2 uint64
+ l3 uint64
+ l4 uint64
+}
+
+const maskLow51Bits uint64 = (1 << 51) - 1
+
+var feZero = &Element{0, 0, 0, 0, 0}
+
+// Zero sets v = 0, and returns v.
+func (v *Element) Zero() *Element {
+ *v = *feZero
+ return v
+}
+
+var feOne = &Element{1, 0, 0, 0, 0}
+
+// One sets v = 1, and returns v.
+func (v *Element) One() *Element {
+ *v = *feOne
+ return v
+}
+
+// reduce reduces v modulo 2^255 - 19 and returns it.
+func (v *Element) reduce() *Element {
+ v.carryPropagate()
+
+ // After the light reduction we now have a field element representation
+ // v < 2^255 + 2^13 * 19, but need v < 2^255 - 19.
+
+ // If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1,
+ // generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise.
+ c := (v.l0 + 19) >> 51
+ c = (v.l1 + c) >> 51
+ c = (v.l2 + c) >> 51
+ c = (v.l3 + c) >> 51
+ c = (v.l4 + c) >> 51
+
+ // If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's
+ // effectively applying the reduction identity to the carry.
+ v.l0 += 19 * c
+
+ v.l1 += v.l0 >> 51
+ v.l0 = v.l0 & maskLow51Bits
+ v.l2 += v.l1 >> 51
+ v.l1 = v.l1 & maskLow51Bits
+ v.l3 += v.l2 >> 51
+ v.l2 = v.l2 & maskLow51Bits
+ v.l4 += v.l3 >> 51
+ v.l3 = v.l3 & maskLow51Bits
+ // no additional carry
+ v.l4 = v.l4 & maskLow51Bits
+
+ return v
+}
+
+// Add sets v = a + b, and returns v.
+func (v *Element) Add(a, b *Element) *Element {
+ v.l0 = a.l0 + b.l0
+ v.l1 = a.l1 + b.l1
+ v.l2 = a.l2 + b.l2
+ v.l3 = a.l3 + b.l3
+ v.l4 = a.l4 + b.l4
+ // Using the generic implementation here is actually faster than the
+ // assembly. Probably because the body of this function is so simple that
+ // the compiler can figure out better optimizations by inlining the carry
+ // propagation. TODO
+ return v.carryPropagateGeneric()
+}
+
+// Subtract sets v = a - b, and returns v.
+func (v *Element) Subtract(a, b *Element) *Element {
+ // We first add 2 * p, to guarantee the subtraction won't underflow, and
+ // then subtract b (which can be up to 2^255 + 2^13 * 19).
+ v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0
+ v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1
+ v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2
+ v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3
+ v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4
+ return v.carryPropagate()
+}
+
+// Negate sets v = -a, and returns v.
+func (v *Element) Negate(a *Element) *Element {
+ return v.Subtract(feZero, a)
+}
+
+// Invert sets v = 1/z mod p, and returns v.
+//
+// If z == 0, Invert returns v = 0.
+func (v *Element) Invert(z *Element) *Element {
+ // Inversion is implemented as exponentiation with exponent p − 2. It uses the
+ // same sequence of 255 squarings and 11 multiplications as [Curve25519].
+ var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element
+
+ z2.Square(z) // 2
+ t.Square(&z2) // 4
+ t.Square(&t) // 8
+ z9.Multiply(&t, z) // 9
+ z11.Multiply(&z9, &z2) // 11
+ t.Square(&z11) // 22
+ z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0
+
+ t.Square(&z2_5_0) // 2^6 - 2^1
+ for i := 0; i < 4; i++ {
+ t.Square(&t) // 2^10 - 2^5
+ }
+ z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0
+
+ t.Square(&z2_10_0) // 2^11 - 2^1
+ for i := 0; i < 9; i++ {
+ t.Square(&t) // 2^20 - 2^10
+ }
+ z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0
+
+ t.Square(&z2_20_0) // 2^21 - 2^1
+ for i := 0; i < 19; i++ {
+ t.Square(&t) // 2^40 - 2^20
+ }
+ t.Multiply(&t, &z2_20_0) // 2^40 - 2^0
+
+ t.Square(&t) // 2^41 - 2^1
+ for i := 0; i < 9; i++ {
+ t.Square(&t) // 2^50 - 2^10
+ }
+ z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0
+
+ t.Square(&z2_50_0) // 2^51 - 2^1
+ for i := 0; i < 49; i++ {
+ t.Square(&t) // 2^100 - 2^50
+ }
+ z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0
+
+ t.Square(&z2_100_0) // 2^101 - 2^1
+ for i := 0; i < 99; i++ {
+ t.Square(&t) // 2^200 - 2^100
+ }
+ t.Multiply(&t, &z2_100_0) // 2^200 - 2^0
+
+ t.Square(&t) // 2^201 - 2^1
+ for i := 0; i < 49; i++ {
+ t.Square(&t) // 2^250 - 2^50
+ }
+ t.Multiply(&t, &z2_50_0) // 2^250 - 2^0
+
+ t.Square(&t) // 2^251 - 2^1
+ t.Square(&t) // 2^252 - 2^2
+ t.Square(&t) // 2^253 - 2^3
+ t.Square(&t) // 2^254 - 2^4
+ t.Square(&t) // 2^255 - 2^5
+
+ return v.Multiply(&t, &z11) // 2^255 - 21
+}
+
+// Set sets v = a, and returns v.
+func (v *Element) Set(a *Element) *Element {
+ *v = *a
+ return v
+}
+
+// SetBytes sets v to x, which must be a 32-byte little-endian encoding.
+//
+// Consistent with RFC 7748, the most significant bit (the high bit of the
+// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
+// are accepted. Note that this is laxer than specified by RFC 8032.
+func (v *Element) SetBytes(x []byte) *Element {
+ if len(x) != 32 {
+ panic("edwards25519: invalid field element input size")
+ }
+
+ // Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51).
+ v.l0 = binary.LittleEndian.Uint64(x[0:8])
+ v.l0 &= maskLow51Bits
+ // Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51).
+ v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3
+ v.l1 &= maskLow51Bits
+ // Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51).
+ v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6
+ v.l2 &= maskLow51Bits
+ // Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51).
+ v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1
+ v.l3 &= maskLow51Bits
+ // Bits 204:251 (bytes 24:32, bits 192:256, shift 12, mask 51).
+ // Note: not bytes 25:33, shift 4, to avoid overread.
+ v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12
+ v.l4 &= maskLow51Bits
+
+ return v
+}
+
+// Bytes returns the canonical 32-byte little-endian encoding of v.
+func (v *Element) Bytes() []byte {
+ // This function is outlined to make the allocations inline in the caller
+ // rather than happen on the heap.
+ var out [32]byte
+ return v.bytes(&out)
+}
+
+func (v *Element) bytes(out *[32]byte) []byte {
+ t := *v
+ t.reduce()
+
+ var buf [8]byte
+ for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} {
+ bitsOffset := i * 51
+ binary.LittleEndian.PutUint64(buf[:], l<= len(out) {
+ break
+ }
+ out[off] |= bb
+ }
+ }
+
+ return out[:]
+}
+
+// Equal returns 1 if v and u are equal, and 0 otherwise.
+func (v *Element) Equal(u *Element) int {
+ sa, sv := u.Bytes(), v.Bytes()
+ return subtle.ConstantTimeCompare(sa, sv)
+}
+
+// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise.
+func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) }
+
+// Select sets v to a if cond == 1, and to b if cond == 0.
+func (v *Element) Select(a, b *Element, cond int) *Element {
+ m := mask64Bits(cond)
+ v.l0 = (m & a.l0) | (^m & b.l0)
+ v.l1 = (m & a.l1) | (^m & b.l1)
+ v.l2 = (m & a.l2) | (^m & b.l2)
+ v.l3 = (m & a.l3) | (^m & b.l3)
+ v.l4 = (m & a.l4) | (^m & b.l4)
+ return v
+}
+
+// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
+func (v *Element) Swap(u *Element, cond int) {
+ m := mask64Bits(cond)
+ t := m & (v.l0 ^ u.l0)
+ v.l0 ^= t
+ u.l0 ^= t
+ t = m & (v.l1 ^ u.l1)
+ v.l1 ^= t
+ u.l1 ^= t
+ t = m & (v.l2 ^ u.l2)
+ v.l2 ^= t
+ u.l2 ^= t
+ t = m & (v.l3 ^ u.l3)
+ v.l3 ^= t
+ u.l3 ^= t
+ t = m & (v.l4 ^ u.l4)
+ v.l4 ^= t
+ u.l4 ^= t
+}
+
+// IsNegative returns 1 if v is negative, and 0 otherwise.
+func (v *Element) IsNegative() int {
+ return int(v.Bytes()[0] & 1)
+}
+
+// Absolute sets v to |u|, and returns v.
+func (v *Element) Absolute(u *Element) *Element {
+ return v.Select(new(Element).Negate(u), u, u.IsNegative())
+}
+
+// Multiply sets v = x * y, and returns v.
+func (v *Element) Multiply(x, y *Element) *Element {
+ feMul(v, x, y)
+ return v
+}
+
+// Square sets v = x * x, and returns v.
+func (v *Element) Square(x *Element) *Element {
+ feSquare(v, x)
+ return v
+}
+
+// Mult32 sets v = x * y, and returns v.
+func (v *Element) Mult32(x *Element, y uint32) *Element {
+ x0lo, x0hi := mul51(x.l0, y)
+ x1lo, x1hi := mul51(x.l1, y)
+ x2lo, x2hi := mul51(x.l2, y)
+ x3lo, x3hi := mul51(x.l3, y)
+ x4lo, x4hi := mul51(x.l4, y)
+ v.l0 = x0lo + 19*x4hi // carried over per the reduction identity
+ v.l1 = x1lo + x0hi
+ v.l2 = x2lo + x1hi
+ v.l3 = x3lo + x2hi
+ v.l4 = x4lo + x3hi
+ // The hi portions are going to be only 32 bits, plus any previous excess,
+ // so we can skip the carry propagation.
+ return v
+}
+
+// mul51 returns lo + hi * 2⁵¹ = a * b.
+func mul51(a uint64, b uint32) (lo uint64, hi uint64) {
+ mh, ml := bits.Mul64(a, uint64(b))
+ lo = ml & maskLow51Bits
+ hi = (mh << 13) | (ml >> 51)
+ return
+}
+
+// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
+func (v *Element) Pow22523(x *Element) *Element {
+ var t0, t1, t2 Element
+
+ t0.Square(x) // x^2
+ t1.Square(&t0) // x^4
+ t1.Square(&t1) // x^8
+ t1.Multiply(x, &t1) // x^9
+ t0.Multiply(&t0, &t1) // x^11
+ t0.Square(&t0) // x^22
+ t0.Multiply(&t1, &t0) // x^31
+ t1.Square(&t0) // x^62
+ for i := 1; i < 5; i++ { // x^992
+ t1.Square(&t1)
+ }
+ t0.Multiply(&t1, &t0) // x^1023 -> 1023 = 2^10 - 1
+ t1.Square(&t0) // 2^11 - 2
+ for i := 1; i < 10; i++ { // 2^20 - 2^10
+ t1.Square(&t1)
+ }
+ t1.Multiply(&t1, &t0) // 2^20 - 1
+ t2.Square(&t1) // 2^21 - 2
+ for i := 1; i < 20; i++ { // 2^40 - 2^20
+ t2.Square(&t2)
+ }
+ t1.Multiply(&t2, &t1) // 2^40 - 1
+ t1.Square(&t1) // 2^41 - 2
+ for i := 1; i < 10; i++ { // 2^50 - 2^10
+ t1.Square(&t1)
+ }
+ t0.Multiply(&t1, &t0) // 2^50 - 1
+ t1.Square(&t0) // 2^51 - 2
+ for i := 1; i < 50; i++ { // 2^100 - 2^50
+ t1.Square(&t1)
+ }
+ t1.Multiply(&t1, &t0) // 2^100 - 1
+ t2.Square(&t1) // 2^101 - 2
+ for i := 1; i < 100; i++ { // 2^200 - 2^100
+ t2.Square(&t2)
+ }
+ t1.Multiply(&t2, &t1) // 2^200 - 1
+ t1.Square(&t1) // 2^201 - 2
+ for i := 1; i < 50; i++ { // 2^250 - 2^50
+ t1.Square(&t1)
+ }
+ t0.Multiply(&t1, &t0) // 2^250 - 1
+ t0.Square(&t0) // 2^251 - 2
+ t0.Square(&t0) // 2^252 - 4
+ return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3)
+}
+
+// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion.
+var sqrtM1 = &Element{1718705420411056, 234908883556509,
+ 2233514472574048, 2117202627021982, 765476049583133}
+
+// SqrtRatio sets r to the non-negative square root of the ratio of u and v.
+//
+// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio
+// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
+// and returns r and 0.
+func (r *Element) SqrtRatio(u, v *Element) (rr *Element, wasSquare int) {
+ var a, b Element
+
+ // r = (u * v3) * (u * v7)^((p-5)/8)
+ v2 := a.Square(v)
+ uv3 := b.Multiply(u, b.Multiply(v2, v))
+ uv7 := a.Multiply(uv3, a.Square(v2))
+ r.Multiply(uv3, r.Pow22523(uv7))
+
+ check := a.Multiply(v, a.Square(r)) // check = v * r^2
+
+ uNeg := b.Negate(u)
+ correctSignSqrt := check.Equal(u)
+ flippedSignSqrt := check.Equal(uNeg)
+ flippedSignSqrtI := check.Equal(uNeg.Multiply(uNeg, sqrtM1))
+
+ rPrime := b.Multiply(r, sqrtM1) // r_prime = SQRT_M1 * r
+ // r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r)
+ r.Select(rPrime, r, flippedSignSqrt|flippedSignSqrtI)
+
+ r.Absolute(r) // Choose the nonnegative square root.
+ return r, correctSignSqrt | flippedSignSqrt
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
new file mode 100644
index 0000000..edcf163
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
@@ -0,0 +1,16 @@
+// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
+
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
+
+package field
+
+// feMul sets out = a * b. It works like feMulGeneric.
+//
+//go:noescape
+func feMul(out *Element, a *Element, b *Element)
+
+// feSquare sets out = a * a. It works like feSquareGeneric.
+//
+//go:noescape
+func feSquare(out *Element, a *Element)
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
new file mode 100644
index 0000000..293f013
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
@@ -0,0 +1,379 @@
+// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
+
+//go:build amd64 && gc && !purego
+// +build amd64,gc,!purego
+
+#include "textflag.h"
+
+// func feMul(out *Element, a *Element, b *Element)
+TEXT ·feMul(SB), NOSPLIT, $0-24
+ MOVQ a+8(FP), CX
+ MOVQ b+16(FP), BX
+
+ // r0 = a0×b0
+ MOVQ (CX), AX
+ MULQ (BX)
+ MOVQ AX, DI
+ MOVQ DX, SI
+
+ // r0 += 19×a1×b4
+ MOVQ 8(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 32(BX)
+ ADDQ AX, DI
+ ADCQ DX, SI
+
+ // r0 += 19×a2×b3
+ MOVQ 16(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 24(BX)
+ ADDQ AX, DI
+ ADCQ DX, SI
+
+ // r0 += 19×a3×b2
+ MOVQ 24(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 16(BX)
+ ADDQ AX, DI
+ ADCQ DX, SI
+
+ // r0 += 19×a4×b1
+ MOVQ 32(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 8(BX)
+ ADDQ AX, DI
+ ADCQ DX, SI
+
+ // r1 = a0×b1
+ MOVQ (CX), AX
+ MULQ 8(BX)
+ MOVQ AX, R9
+ MOVQ DX, R8
+
+ // r1 += a1×b0
+ MOVQ 8(CX), AX
+ MULQ (BX)
+ ADDQ AX, R9
+ ADCQ DX, R8
+
+ // r1 += 19×a2×b4
+ MOVQ 16(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 32(BX)
+ ADDQ AX, R9
+ ADCQ DX, R8
+
+ // r1 += 19×a3×b3
+ MOVQ 24(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 24(BX)
+ ADDQ AX, R9
+ ADCQ DX, R8
+
+ // r1 += 19×a4×b2
+ MOVQ 32(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 16(BX)
+ ADDQ AX, R9
+ ADCQ DX, R8
+
+ // r2 = a0×b2
+ MOVQ (CX), AX
+ MULQ 16(BX)
+ MOVQ AX, R11
+ MOVQ DX, R10
+
+ // r2 += a1×b1
+ MOVQ 8(CX), AX
+ MULQ 8(BX)
+ ADDQ AX, R11
+ ADCQ DX, R10
+
+ // r2 += a2×b0
+ MOVQ 16(CX), AX
+ MULQ (BX)
+ ADDQ AX, R11
+ ADCQ DX, R10
+
+ // r2 += 19×a3×b4
+ MOVQ 24(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 32(BX)
+ ADDQ AX, R11
+ ADCQ DX, R10
+
+ // r2 += 19×a4×b3
+ MOVQ 32(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 24(BX)
+ ADDQ AX, R11
+ ADCQ DX, R10
+
+ // r3 = a0×b3
+ MOVQ (CX), AX
+ MULQ 24(BX)
+ MOVQ AX, R13
+ MOVQ DX, R12
+
+ // r3 += a1×b2
+ MOVQ 8(CX), AX
+ MULQ 16(BX)
+ ADDQ AX, R13
+ ADCQ DX, R12
+
+ // r3 += a2×b1
+ MOVQ 16(CX), AX
+ MULQ 8(BX)
+ ADDQ AX, R13
+ ADCQ DX, R12
+
+ // r3 += a3×b0
+ MOVQ 24(CX), AX
+ MULQ (BX)
+ ADDQ AX, R13
+ ADCQ DX, R12
+
+ // r3 += 19×a4×b4
+ MOVQ 32(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 32(BX)
+ ADDQ AX, R13
+ ADCQ DX, R12
+
+ // r4 = a0×b4
+ MOVQ (CX), AX
+ MULQ 32(BX)
+ MOVQ AX, R15
+ MOVQ DX, R14
+
+ // r4 += a1×b3
+ MOVQ 8(CX), AX
+ MULQ 24(BX)
+ ADDQ AX, R15
+ ADCQ DX, R14
+
+ // r4 += a2×b2
+ MOVQ 16(CX), AX
+ MULQ 16(BX)
+ ADDQ AX, R15
+ ADCQ DX, R14
+
+ // r4 += a3×b1
+ MOVQ 24(CX), AX
+ MULQ 8(BX)
+ ADDQ AX, R15
+ ADCQ DX, R14
+
+ // r4 += a4×b0
+ MOVQ 32(CX), AX
+ MULQ (BX)
+ ADDQ AX, R15
+ ADCQ DX, R14
+
+ // First reduction chain
+ MOVQ $0x0007ffffffffffff, AX
+ SHLQ $0x0d, DI, SI
+ SHLQ $0x0d, R9, R8
+ SHLQ $0x0d, R11, R10
+ SHLQ $0x0d, R13, R12
+ SHLQ $0x0d, R15, R14
+ ANDQ AX, DI
+ IMUL3Q $0x13, R14, R14
+ ADDQ R14, DI
+ ANDQ AX, R9
+ ADDQ SI, R9
+ ANDQ AX, R11
+ ADDQ R8, R11
+ ANDQ AX, R13
+ ADDQ R10, R13
+ ANDQ AX, R15
+ ADDQ R12, R15
+
+ // Second reduction chain (carryPropagate)
+ MOVQ DI, SI
+ SHRQ $0x33, SI
+ MOVQ R9, R8
+ SHRQ $0x33, R8
+ MOVQ R11, R10
+ SHRQ $0x33, R10
+ MOVQ R13, R12
+ SHRQ $0x33, R12
+ MOVQ R15, R14
+ SHRQ $0x33, R14
+ ANDQ AX, DI
+ IMUL3Q $0x13, R14, R14
+ ADDQ R14, DI
+ ANDQ AX, R9
+ ADDQ SI, R9
+ ANDQ AX, R11
+ ADDQ R8, R11
+ ANDQ AX, R13
+ ADDQ R10, R13
+ ANDQ AX, R15
+ ADDQ R12, R15
+
+ // Store output
+ MOVQ out+0(FP), AX
+ MOVQ DI, (AX)
+ MOVQ R9, 8(AX)
+ MOVQ R11, 16(AX)
+ MOVQ R13, 24(AX)
+ MOVQ R15, 32(AX)
+ RET
+
+// func feSquare(out *Element, a *Element)
+TEXT ·feSquare(SB), NOSPLIT, $0-16
+ MOVQ a+8(FP), CX
+
+ // r0 = l0×l0
+ MOVQ (CX), AX
+ MULQ (CX)
+ MOVQ AX, SI
+ MOVQ DX, BX
+
+ // r0 += 38×l1×l4
+ MOVQ 8(CX), AX
+ IMUL3Q $0x26, AX, AX
+ MULQ 32(CX)
+ ADDQ AX, SI
+ ADCQ DX, BX
+
+ // r0 += 38×l2×l3
+ MOVQ 16(CX), AX
+ IMUL3Q $0x26, AX, AX
+ MULQ 24(CX)
+ ADDQ AX, SI
+ ADCQ DX, BX
+
+ // r1 = 2×l0×l1
+ MOVQ (CX), AX
+ SHLQ $0x01, AX
+ MULQ 8(CX)
+ MOVQ AX, R8
+ MOVQ DX, DI
+
+ // r1 += 38×l2×l4
+ MOVQ 16(CX), AX
+ IMUL3Q $0x26, AX, AX
+ MULQ 32(CX)
+ ADDQ AX, R8
+ ADCQ DX, DI
+
+ // r1 += 19×l3×l3
+ MOVQ 24(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 24(CX)
+ ADDQ AX, R8
+ ADCQ DX, DI
+
+ // r2 = 2×l0×l2
+ MOVQ (CX), AX
+ SHLQ $0x01, AX
+ MULQ 16(CX)
+ MOVQ AX, R10
+ MOVQ DX, R9
+
+ // r2 += l1×l1
+ MOVQ 8(CX), AX
+ MULQ 8(CX)
+ ADDQ AX, R10
+ ADCQ DX, R9
+
+ // r2 += 38×l3×l4
+ MOVQ 24(CX), AX
+ IMUL3Q $0x26, AX, AX
+ MULQ 32(CX)
+ ADDQ AX, R10
+ ADCQ DX, R9
+
+ // r3 = 2×l0×l3
+ MOVQ (CX), AX
+ SHLQ $0x01, AX
+ MULQ 24(CX)
+ MOVQ AX, R12
+ MOVQ DX, R11
+
+ // r3 += 2×l1×l2
+ MOVQ 8(CX), AX
+ IMUL3Q $0x02, AX, AX
+ MULQ 16(CX)
+ ADDQ AX, R12
+ ADCQ DX, R11
+
+ // r3 += 19×l4×l4
+ MOVQ 32(CX), AX
+ IMUL3Q $0x13, AX, AX
+ MULQ 32(CX)
+ ADDQ AX, R12
+ ADCQ DX, R11
+
+ // r4 = 2×l0×l4
+ MOVQ (CX), AX
+ SHLQ $0x01, AX
+ MULQ 32(CX)
+ MOVQ AX, R14
+ MOVQ DX, R13
+
+ // r4 += 2×l1×l3
+ MOVQ 8(CX), AX
+ IMUL3Q $0x02, AX, AX
+ MULQ 24(CX)
+ ADDQ AX, R14
+ ADCQ DX, R13
+
+ // r4 += l2×l2
+ MOVQ 16(CX), AX
+ MULQ 16(CX)
+ ADDQ AX, R14
+ ADCQ DX, R13
+
+ // First reduction chain
+ MOVQ $0x0007ffffffffffff, AX
+ SHLQ $0x0d, SI, BX
+ SHLQ $0x0d, R8, DI
+ SHLQ $0x0d, R10, R9
+ SHLQ $0x0d, R12, R11
+ SHLQ $0x0d, R14, R13
+ ANDQ AX, SI
+ IMUL3Q $0x13, R13, R13
+ ADDQ R13, SI
+ ANDQ AX, R8
+ ADDQ BX, R8
+ ANDQ AX, R10
+ ADDQ DI, R10
+ ANDQ AX, R12
+ ADDQ R9, R12
+ ANDQ AX, R14
+ ADDQ R11, R14
+
+ // Second reduction chain (carryPropagate)
+ MOVQ SI, BX
+ SHRQ $0x33, BX
+ MOVQ R8, DI
+ SHRQ $0x33, DI
+ MOVQ R10, R9
+ SHRQ $0x33, R9
+ MOVQ R12, R11
+ SHRQ $0x33, R11
+ MOVQ R14, R13
+ SHRQ $0x33, R13
+ ANDQ AX, SI
+ IMUL3Q $0x13, R13, R13
+ ADDQ R13, SI
+ ANDQ AX, R8
+ ADDQ BX, R8
+ ANDQ AX, R10
+ ADDQ DI, R10
+ ANDQ AX, R12
+ ADDQ R9, R12
+ ANDQ AX, R14
+ ADDQ R11, R14
+
+ // Store output
+ MOVQ out+0(FP), AX
+ MOVQ SI, (AX)
+ MOVQ R8, 8(AX)
+ MOVQ R10, 16(AX)
+ MOVQ R12, 24(AX)
+ MOVQ R14, 32(AX)
+ RET
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
new file mode 100644
index 0000000..ddb6c9b
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
@@ -0,0 +1,12 @@
+// Copyright (c) 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 || !gc || purego
+// +build !amd64 !gc purego
+
+package field
+
+func feMul(v, x, y *Element) { feMulGeneric(v, x, y) }
+
+func feSquare(v, x *Element) { feSquareGeneric(v, x) }
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
new file mode 100644
index 0000000..af459ef
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
@@ -0,0 +1,16 @@
+// Copyright (c) 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build arm64 && gc && !purego
+// +build arm64,gc,!purego
+
+package field
+
+//go:noescape
+func carryPropagate(v *Element)
+
+func (v *Element) carryPropagate() *Element {
+ carryPropagate(v)
+ return v
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
new file mode 100644
index 0000000..5c91e45
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
@@ -0,0 +1,43 @@
+// Copyright (c) 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build arm64 && gc && !purego
+// +build arm64,gc,!purego
+
+#include "textflag.h"
+
+// carryPropagate works exactly like carryPropagateGeneric and uses the
+// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but
+// avoids loading R0-R4 twice and uses LDP and STP.
+//
+// See https://golang.org/issues/43145 for the main compiler issue.
+//
+// func carryPropagate(v *Element)
+TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8
+ MOVD v+0(FP), R20
+
+ LDP 0(R20), (R0, R1)
+ LDP 16(R20), (R2, R3)
+ MOVD 32(R20), R4
+
+ AND $0x7ffffffffffff, R0, R10
+ AND $0x7ffffffffffff, R1, R11
+ AND $0x7ffffffffffff, R2, R12
+ AND $0x7ffffffffffff, R3, R13
+ AND $0x7ffffffffffff, R4, R14
+
+ ADD R0>>51, R11, R11
+ ADD R1>>51, R12, R12
+ ADD R2>>51, R13, R13
+ ADD R3>>51, R14, R14
+ // R4>>51 * 19 + R10 -> R10
+ LSR $51, R4, R21
+ MOVD $19, R22
+ MADD R22, R10, R21, R10
+
+ STP (R10, R11), 0(R20)
+ STP (R12, R13), 16(R20)
+ MOVD R14, 32(R20)
+
+ RET
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
new file mode 100644
index 0000000..234a5b2
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
@@ -0,0 +1,12 @@
+// Copyright (c) 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !arm64 || !gc || purego
+// +build !arm64 !gc purego
+
+package field
+
+func (v *Element) carryPropagate() *Element {
+ return v.carryPropagateGeneric()
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
new file mode 100644
index 0000000..2671217
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
@@ -0,0 +1,264 @@
+// Copyright (c) 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package field
+
+import "math/bits"
+
+// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
+// bits.Mul64 and bits.Add64 intrinsics.
+type uint128 struct {
+ lo, hi uint64
+}
+
+// mul64 returns a * b.
+func mul64(a, b uint64) uint128 {
+ hi, lo := bits.Mul64(a, b)
+ return uint128{lo, hi}
+}
+
+// addMul64 returns v + a * b.
+func addMul64(v uint128, a, b uint64) uint128 {
+ hi, lo := bits.Mul64(a, b)
+ lo, c := bits.Add64(lo, v.lo, 0)
+ hi, _ = bits.Add64(hi, v.hi, c)
+ return uint128{lo, hi}
+}
+
+// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
+func shiftRightBy51(a uint128) uint64 {
+ return (a.hi << (64 - 51)) | (a.lo >> 51)
+}
+
+func feMulGeneric(v, a, b *Element) {
+ a0 := a.l0
+ a1 := a.l1
+ a2 := a.l2
+ a3 := a.l3
+ a4 := a.l4
+
+ b0 := b.l0
+ b1 := b.l1
+ b2 := b.l2
+ b3 := b.l3
+ b4 := b.l4
+
+ // Limb multiplication works like pen-and-paper columnar multiplication, but
+ // with 51-bit limbs instead of digits.
+ //
+ // a4 a3 a2 a1 a0 x
+ // b4 b3 b2 b1 b0 =
+ // ------------------------
+ // a4b0 a3b0 a2b0 a1b0 a0b0 +
+ // a4b1 a3b1 a2b1 a1b1 a0b1 +
+ // a4b2 a3b2 a2b2 a1b2 a0b2 +
+ // a4b3 a3b3 a2b3 a1b3 a0b3 +
+ // a4b4 a3b4 a2b4 a1b4 a0b4 =
+ // ----------------------------------------------
+ // r8 r7 r6 r5 r4 r3 r2 r1 r0
+ //
+ // We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
+ // reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
+ // r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
+ //
+ // Reduction can be carried out simultaneously to multiplication. For
+ // example, we do not compute r5: whenever the result of a multiplication
+ // belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
+ //
+ // a4b0 a3b0 a2b0 a1b0 a0b0 +
+ // a3b1 a2b1 a1b1 a0b1 19×a4b1 +
+ // a2b2 a1b2 a0b2 19×a4b2 19×a3b2 +
+ // a1b3 a0b3 19×a4b3 19×a3b3 19×a2b3 +
+ // a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4 =
+ // --------------------------------------
+ // r4 r3 r2 r1 r0
+ //
+ // Finally we add up the columns into wide, overlapping limbs.
+
+ a1_19 := a1 * 19
+ a2_19 := a2 * 19
+ a3_19 := a3 * 19
+ a4_19 := a4 * 19
+
+ // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+ r0 := mul64(a0, b0)
+ r0 = addMul64(r0, a1_19, b4)
+ r0 = addMul64(r0, a2_19, b3)
+ r0 = addMul64(r0, a3_19, b2)
+ r0 = addMul64(r0, a4_19, b1)
+
+ // r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
+ r1 := mul64(a0, b1)
+ r1 = addMul64(r1, a1, b0)
+ r1 = addMul64(r1, a2_19, b4)
+ r1 = addMul64(r1, a3_19, b3)
+ r1 = addMul64(r1, a4_19, b2)
+
+ // r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
+ r2 := mul64(a0, b2)
+ r2 = addMul64(r2, a1, b1)
+ r2 = addMul64(r2, a2, b0)
+ r2 = addMul64(r2, a3_19, b4)
+ r2 = addMul64(r2, a4_19, b3)
+
+ // r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
+ r3 := mul64(a0, b3)
+ r3 = addMul64(r3, a1, b2)
+ r3 = addMul64(r3, a2, b1)
+ r3 = addMul64(r3, a3, b0)
+ r3 = addMul64(r3, a4_19, b4)
+
+ // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+ r4 := mul64(a0, b4)
+ r4 = addMul64(r4, a1, b3)
+ r4 = addMul64(r4, a2, b2)
+ r4 = addMul64(r4, a3, b1)
+ r4 = addMul64(r4, a4, b0)
+
+ // After the multiplication, we need to reduce (carry) the five coefficients
+ // to obtain a result with limbs that are at most slightly larger than 2⁵¹,
+ // to respect the Element invariant.
+ //
+ // Overall, the reduction works the same as carryPropagate, except with
+ // wider inputs: we take the carry for each coefficient by shifting it right
+ // by 51, and add it to the limb above it. The top carry is multiplied by 19
+ // according to the reduction identity and added to the lowest limb.
+ //
+ // The largest coefficient (r0) will be at most 111 bits, which guarantees
+ // that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
+ //
+ // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+ // r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
+ // r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
+ // r0 < 2⁷ × 2⁵² × 2⁵²
+ // r0 < 2¹¹¹
+ //
+ // Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
+ // 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
+ // allows us to easily apply the reduction identity.
+ //
+ // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+ // r4 < 5 × 2⁵² × 2⁵²
+ // r4 < 2¹⁰⁷
+ //
+
+ c0 := shiftRightBy51(r0)
+ c1 := shiftRightBy51(r1)
+ c2 := shiftRightBy51(r2)
+ c3 := shiftRightBy51(r3)
+ c4 := shiftRightBy51(r4)
+
+ rr0 := r0.lo&maskLow51Bits + c4*19
+ rr1 := r1.lo&maskLow51Bits + c0
+ rr2 := r2.lo&maskLow51Bits + c1
+ rr3 := r3.lo&maskLow51Bits + c2
+ rr4 := r4.lo&maskLow51Bits + c3
+
+ // Now all coefficients fit into 64-bit registers but are still too large to
+ // be passed around as a Element. We therefore do one last carry chain,
+ // where the carries will be small enough to fit in the wiggle room above 2⁵¹.
+ *v = Element{rr0, rr1, rr2, rr3, rr4}
+ v.carryPropagate()
+}
+
+func feSquareGeneric(v, a *Element) {
+ l0 := a.l0
+ l1 := a.l1
+ l2 := a.l2
+ l3 := a.l3
+ l4 := a.l4
+
+ // Squaring works precisely like multiplication above, but thanks to its
+ // symmetry we get to group a few terms together.
+ //
+ // l4 l3 l2 l1 l0 x
+ // l4 l3 l2 l1 l0 =
+ // ------------------------
+ // l4l0 l3l0 l2l0 l1l0 l0l0 +
+ // l4l1 l3l1 l2l1 l1l1 l0l1 +
+ // l4l2 l3l2 l2l2 l1l2 l0l2 +
+ // l4l3 l3l3 l2l3 l1l3 l0l3 +
+ // l4l4 l3l4 l2l4 l1l4 l0l4 =
+ // ----------------------------------------------
+ // r8 r7 r6 r5 r4 r3 r2 r1 r0
+ //
+ // l4l0 l3l0 l2l0 l1l0 l0l0 +
+ // l3l1 l2l1 l1l1 l0l1 19×l4l1 +
+ // l2l2 l1l2 l0l2 19×l4l2 19×l3l2 +
+ // l1l3 l0l3 19×l4l3 19×l3l3 19×l2l3 +
+ // l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4 =
+ // --------------------------------------
+ // r4 r3 r2 r1 r0
+ //
+ // With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
+ // only three Mul64 and four Add64, instead of five and eight.
+
+ l0_2 := l0 * 2
+ l1_2 := l1 * 2
+
+ l1_38 := l1 * 38
+ l2_38 := l2 * 38
+ l3_38 := l3 * 38
+
+ l3_19 := l3 * 19
+ l4_19 := l4 * 19
+
+ // r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
+ r0 := mul64(l0, l0)
+ r0 = addMul64(r0, l1_38, l4)
+ r0 = addMul64(r0, l2_38, l3)
+
+ // r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
+ r1 := mul64(l0_2, l1)
+ r1 = addMul64(r1, l2_38, l4)
+ r1 = addMul64(r1, l3_19, l3)
+
+ // r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
+ r2 := mul64(l0_2, l2)
+ r2 = addMul64(r2, l1, l1)
+ r2 = addMul64(r2, l3_38, l4)
+
+ // r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
+ r3 := mul64(l0_2, l3)
+ r3 = addMul64(r3, l1_2, l2)
+ r3 = addMul64(r3, l4_19, l4)
+
+ // r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
+ r4 := mul64(l0_2, l4)
+ r4 = addMul64(r4, l1_2, l3)
+ r4 = addMul64(r4, l2, l2)
+
+ c0 := shiftRightBy51(r0)
+ c1 := shiftRightBy51(r1)
+ c2 := shiftRightBy51(r2)
+ c3 := shiftRightBy51(r3)
+ c4 := shiftRightBy51(r4)
+
+ rr0 := r0.lo&maskLow51Bits + c4*19
+ rr1 := r1.lo&maskLow51Bits + c0
+ rr2 := r2.lo&maskLow51Bits + c1
+ rr3 := r3.lo&maskLow51Bits + c2
+ rr4 := r4.lo&maskLow51Bits + c3
+
+ *v = Element{rr0, rr1, rr2, rr3, rr4}
+ v.carryPropagate()
+}
+
+// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction
+// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. TODO inline
+func (v *Element) carryPropagateGeneric() *Element {
+ c0 := v.l0 >> 51
+ c1 := v.l1 >> 51
+ c2 := v.l2 >> 51
+ c3 := v.l3 >> 51
+ c4 := v.l4 >> 51
+
+ v.l0 = v.l0&maskLow51Bits + c4*19
+ v.l1 = v.l1&maskLow51Bits + c0
+ v.l2 = v.l2&maskLow51Bits + c1
+ v.l3 = v.l3&maskLow51Bits + c2
+ v.l4 = v.l4&maskLow51Bits + c3
+
+ return v
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
new file mode 100644
index 0000000..e3685f9
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
@@ -0,0 +1 @@
+b0c49ae9f59d233526f8934262c5bbbe14d4358d
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
new file mode 100644
index 0000000..1ba22a8
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
@@ -0,0 +1,19 @@
+#! /bin/bash
+set -euo pipefail
+
+cd "$(git rev-parse --show-toplevel)"
+
+STD_PATH=src/crypto/ed25519/internal/edwards25519/field
+LOCAL_PATH=curve25519/internal/field
+LAST_SYNC_REF=$(cat $LOCAL_PATH/sync.checkpoint)
+
+git fetch https://go.googlesource.com/go master
+
+if git diff --quiet $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH; then
+ echo "No changes."
+else
+ NEW_REF=$(git rev-parse FETCH_HEAD | tee $LOCAL_PATH/sync.checkpoint)
+ echo "Applying changes from $LAST_SYNC_REF to $NEW_REF..."
+ git diff $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH | \
+ git apply -3 --directory=$LOCAL_PATH
+fi
diff --git a/vendor/golang.org/x/xerrors/LICENSE b/vendor/golang.org/x/exp/LICENSE
similarity index 96%
rename from vendor/golang.org/x/xerrors/LICENSE
rename to vendor/golang.org/x/exp/LICENSE
index e4a47e1..6a66aea 100644
--- a/vendor/golang.org/x/xerrors/LICENSE
+++ b/vendor/golang.org/x/exp/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2019 The Go Authors. All rights reserved.
+Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
diff --git a/vendor/golang.org/x/xerrors/PATENTS b/vendor/golang.org/x/exp/PATENTS
similarity index 100%
rename from vendor/golang.org/x/xerrors/PATENTS
rename to vendor/golang.org/x/exp/PATENTS
diff --git a/vendor/golang.org/x/exp/maps/maps.go b/vendor/golang.org/x/exp/maps/maps.go
new file mode 100644
index 0000000..ecc0dab
--- /dev/null
+++ b/vendor/golang.org/x/exp/maps/maps.go
@@ -0,0 +1,94 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package maps defines various functions useful with maps of any type.
+package maps
+
+// Keys returns the keys of the map m.
+// The keys will be in an indeterminate order.
+func Keys[M ~map[K]V, K comparable, V any](m M) []K {
+ r := make([]K, 0, len(m))
+ for k := range m {
+ r = append(r, k)
+ }
+ return r
+}
+
+// Values returns the values of the map m.
+// The values will be in an indeterminate order.
+func Values[M ~map[K]V, K comparable, V any](m M) []V {
+ r := make([]V, 0, len(m))
+ for _, v := range m {
+ r = append(r, v)
+ }
+ return r
+}
+
+// Equal reports whether two maps contain the same key/value pairs.
+// Values are compared using ==.
+func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool {
+ if len(m1) != len(m2) {
+ return false
+ }
+ for k, v1 := range m1 {
+ if v2, ok := m2[k]; !ok || v1 != v2 {
+ return false
+ }
+ }
+ return true
+}
+
+// EqualFunc is like Equal, but compares values using eq.
+// Keys are still compared with ==.
+func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool {
+ if len(m1) != len(m2) {
+ return false
+ }
+ for k, v1 := range m1 {
+ if v2, ok := m2[k]; !ok || !eq(v1, v2) {
+ return false
+ }
+ }
+ return true
+}
+
+// Clear removes all entries from m, leaving it empty.
+func Clear[M ~map[K]V, K comparable, V any](m M) {
+ for k := range m {
+ delete(m, k)
+ }
+}
+
+// Clone returns a copy of m. This is a shallow clone:
+// the new keys and values are set using ordinary assignment.
+func Clone[M ~map[K]V, K comparable, V any](m M) M {
+ // Preserve nil in case it matters.
+ if m == nil {
+ return nil
+ }
+ r := make(M, len(m))
+ for k, v := range m {
+ r[k] = v
+ }
+ return r
+}
+
+// Copy copies all key/value pairs in src adding them to dst.
+// When a key in src is already present in dst,
+// the value in dst will be overwritten by the value associated
+// with the key in src.
+func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) {
+ for k, v := range src {
+ dst[k] = v
+ }
+}
+
+// DeleteFunc deletes any key/value pairs from m for which del returns true.
+func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) {
+ for k, v := range m {
+ if del(k, v) {
+ delete(m, k)
+ }
+ }
+}
diff --git a/vendor/golang.org/x/net/AUTHORS b/vendor/golang.org/x/net/AUTHORS
deleted file mode 100644
index 15167cd..0000000
--- a/vendor/golang.org/x/net/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/net/CONTRIBUTORS b/vendor/golang.org/x/net/CONTRIBUTORS
deleted file mode 100644
index 1c4577e..0000000
--- a/vendor/golang.org/x/net/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/net/bpf/doc.go b/vendor/golang.org/x/net/bpf/doc.go
index ae62feb..04ec1c8 100644
--- a/vendor/golang.org/x/net/bpf/doc.go
+++ b/vendor/golang.org/x/net/bpf/doc.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
/*
-
Package bpf implements marshaling and unmarshaling of programs for the
Berkeley Packet Filter virtual machine, and provides a Go implementation
of the virtual machine.
@@ -21,7 +20,7 @@ access to kernel functions, and while conditional branches are
allowed, they can only jump forwards, to guarantee that there are no
infinite loops.
-The virtual machine
+# The virtual machine
The BPF VM is an accumulator machine. Its main register, called
register A, is an implicit source and destination in all arithmetic
@@ -50,7 +49,7 @@ to extensions, which are essentially calls to kernel utility
functions. Currently, the only extensions supported by this package
are the Linux packet filter extensions.
-Examples
+# Examples
This packet filter selects all ARP packets.
@@ -77,6 +76,5 @@ This packet filter captures a random 1% sample of traffic.
// Ignore.
bpf.RetConstant{Val: 0},
})
-
*/
package bpf // import "golang.org/x/net/bpf"
diff --git a/vendor/golang.org/x/net/bpf/vm_instructions.go b/vendor/golang.org/x/net/bpf/vm_instructions.go
index cf8947c..0aa307c 100644
--- a/vendor/golang.org/x/net/bpf/vm_instructions.go
+++ b/vendor/golang.org/x/net/bpf/vm_instructions.go
@@ -94,7 +94,7 @@ func jumpIfCommon(cond JumpTest, skipTrue, skipFalse uint8, regA uint32, value u
func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) {
offset := int(ins.Off)
- size := int(ins.Size)
+ size := ins.Size
return loadCommon(in, offset, size)
}
@@ -121,7 +121,7 @@ func loadExtension(ins LoadExtension, in []byte) uint32 {
func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) {
offset := int(ins.Off) + int(regX)
- size := int(ins.Size)
+ size := ins.Size
return loadCommon(in, offset, size)
}
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr.go b/vendor/golang.org/x/net/internal/socket/cmsghdr.go
index 0a73e27..4bdaaaf 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
index 14dbb3a..0d30e0a 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
// +build aix darwin dragonfly freebsd netbsd openbsd
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
index bac6681..4936e8a 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build arm mips mipsle 386
+//go:build (arm || mips || mipsle || 386 || ppc) && linux
+// +build arm mips mipsle 386 ppc
// +build linux
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
index 27be0ef..f6877f9 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x
+//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
+// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
// +build linux
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
index 7dedd43..d3dbe1b 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build amd64
-// +build solaris
+//go:build amd64 && solaris
+// +build amd64,solaris
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
index e581011..1d9f2ed 100644
--- a/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
@@ -2,13 +2,24 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
-type cmsghdr struct{}
+func controlHeaderLen() int {
+ return 0
+}
+
+func controlMessageLen(dataLen int) int {
+ return 0
+}
-const sizeofCmsghdr = 0
+func controlMessageSpace(dataLen int) int {
+ return 0
+}
+
+type cmsghdr struct{}
func (h *cmsghdr) len() int { return 0 }
func (h *cmsghdr) lvl() int { return 0 }
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go
new file mode 100644
index 0000000..19d4678
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go
@@ -0,0 +1,22 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
+
+package socket
+
+import "golang.org/x/sys/unix"
+
+func controlHeaderLen() int {
+ return unix.CmsgLen(0)
+}
+
+func controlMessageLen(dataLen int) int {
+ return unix.CmsgLen(dataLen)
+}
+
+func controlMessageSpace(dataLen int) int {
+ return unix.CmsgSpace(dataLen)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go
new file mode 100644
index 0000000..68dc8ad
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go
@@ -0,0 +1,11 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+func (h *cmsghdr) set(l, lvl, typ int) {
+ h.Len = int32(l)
+ h.Level = int32(lvl)
+ h.Type = int32(typ)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/complete_dontwait.go b/vendor/golang.org/x/net/internal/socket/complete_dontwait.go
new file mode 100644
index 0000000..5b1d50a
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/complete_dontwait.go
@@ -0,0 +1,26 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package socket
+
+import (
+ "syscall"
+)
+
+// ioComplete checks the flags and result of a syscall, to be used as return
+// value in a syscall.RawConn.Read or Write callback.
+func ioComplete(flags int, operr error) bool {
+ if flags&syscall.MSG_DONTWAIT != 0 {
+ // Caller explicitly said don't wait, so always return immediately.
+ return true
+ }
+ if operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK {
+ // No data available, block for I/O and try again.
+ return false
+ }
+ return true
+}
diff --git a/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go b/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go
new file mode 100644
index 0000000..be63409
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go
@@ -0,0 +1,22 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || windows || zos
+// +build aix windows zos
+
+package socket
+
+import (
+ "syscall"
+)
+
+// ioComplete checks the flags and result of a syscall, to be used as return
+// value in a syscall.RawConn.Read or Write callback.
+func ioComplete(flags int, operr error) bool {
+ if operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK {
+ // No data available, block for I/O and try again.
+ return false
+ }
+ return true
+}
diff --git a/vendor/golang.org/x/net/internal/socket/empty.s b/vendor/golang.org/x/net/internal/socket/empty.s
index bff0231..90ab4ca 100644
--- a/vendor/golang.org/x/net/internal/socket/empty.s
+++ b/vendor/golang.org/x/net/internal/socket/empty.s
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build darwin && go1.12
// +build darwin,go1.12
// This exists solely so we can linkname in symbols from syscall.
diff --git a/vendor/golang.org/x/net/internal/socket/error_unix.go b/vendor/golang.org/x/net/internal/socket/error_unix.go
index f14872d..78f4129 100644
--- a/vendor/golang.org/x/net/internal/socket/error_unix.go
+++ b/vendor/golang.org/x/net/internal/socket/error_unix.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_32bit.go b/vendor/golang.org/x/net/internal/socket/iovec_32bit.go
index 05d6082..2b8fbb3 100644
--- a/vendor/golang.org/x/net/internal/socket/iovec_32bit.go
+++ b/vendor/golang.org/x/net/internal/socket/iovec_32bit.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build arm mips mipsle 386
+//go:build (arm || mips || mipsle || 386 || ppc) && (darwin || dragonfly || freebsd || linux || netbsd || openbsd)
+// +build arm mips mipsle 386 ppc
// +build darwin dragonfly freebsd linux netbsd openbsd
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_64bit.go b/vendor/golang.org/x/net/internal/socket/iovec_64bit.go
index dfeda75..2e94e96 100644
--- a/vendor/golang.org/x/net/internal/socket/iovec_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/iovec_64bit.go
@@ -2,8 +2,9 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x
-// +build aix darwin dragonfly freebsd linux netbsd openbsd
+//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos)
+// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
+// +build aix darwin dragonfly freebsd linux netbsd openbsd zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
index 8d17a40..f7da2bc 100644
--- a/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build amd64
-// +build solaris
+//go:build amd64 && solaris
+// +build amd64,solaris
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/iovec_stub.go b/vendor/golang.org/x/net/internal/socket/iovec_stub.go
index a746e90..14caf52 100644
--- a/vendor/golang.org/x/net/internal/socket/iovec_stub.go
+++ b/vendor/golang.org/x/net/internal/socket/iovec_stub.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go b/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
index 1a7f279..113e773 100644
--- a/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
+++ b/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !aix && !linux && !netbsd
// +build !aix,!linux,!netbsd
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go b/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
index f110068..41883c5 100644
--- a/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
+++ b/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
@@ -2,29 +2,20 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || linux || netbsd
// +build aix linux netbsd
package socket
-import "net"
+import (
+ "net"
+ "os"
+ "sync"
+ "syscall"
+)
type mmsghdrs []mmsghdr
-func (hs mmsghdrs) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr) []byte) error {
- for i := range hs {
- vs := make([]iovec, len(ms[i].Buffers))
- var sa []byte
- if parseFn != nil {
- sa = make([]byte, sizeofSockaddrInet6)
- }
- if marshalFn != nil {
- sa = marshalFn(ms[i].Addr)
- }
- hs[i].Hdr.pack(vs, ms[i].Buffers, ms[i].OOB, sa)
- }
- return nil
-}
-
func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error {
for i := range hs {
ms[i].N = int(hs[i].Len)
@@ -40,3 +31,166 @@ func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr,
}
return nil
}
+
+// mmsghdrsPacker packs Message-slices into mmsghdrs (re-)using pre-allocated buffers.
+type mmsghdrsPacker struct {
+ // hs are the pre-allocated mmsghdrs.
+ hs mmsghdrs
+ // sockaddrs is the pre-allocated buffer for the Hdr.Name buffers.
+ // We use one large buffer for all messages and slice it up.
+ sockaddrs []byte
+ // vs are the pre-allocated iovecs.
+ // We allocate one large buffer for all messages and slice it up. This allows to reuse the buffer
+ // if the number of buffers per message is distributed differently between calls.
+ vs []iovec
+}
+
+func (p *mmsghdrsPacker) prepare(ms []Message) {
+ n := len(ms)
+ if n <= cap(p.hs) {
+ p.hs = p.hs[:n]
+ } else {
+ p.hs = make(mmsghdrs, n)
+ }
+ if n*sizeofSockaddrInet6 <= cap(p.sockaddrs) {
+ p.sockaddrs = p.sockaddrs[:n*sizeofSockaddrInet6]
+ } else {
+ p.sockaddrs = make([]byte, n*sizeofSockaddrInet6)
+ }
+
+ nb := 0
+ for _, m := range ms {
+ nb += len(m.Buffers)
+ }
+ if nb <= cap(p.vs) {
+ p.vs = p.vs[:nb]
+ } else {
+ p.vs = make([]iovec, nb)
+ }
+}
+
+func (p *mmsghdrsPacker) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr, []byte) int) mmsghdrs {
+ p.prepare(ms)
+ hs := p.hs
+ vsRest := p.vs
+ saRest := p.sockaddrs
+ for i := range hs {
+ nvs := len(ms[i].Buffers)
+ vs := vsRest[:nvs]
+ vsRest = vsRest[nvs:]
+
+ var sa []byte
+ if parseFn != nil {
+ sa = saRest[:sizeofSockaddrInet6]
+ saRest = saRest[sizeofSockaddrInet6:]
+ } else if marshalFn != nil {
+ n := marshalFn(ms[i].Addr, saRest)
+ if n > 0 {
+ sa = saRest[:n]
+ saRest = saRest[n:]
+ }
+ }
+ hs[i].Hdr.pack(vs, ms[i].Buffers, ms[i].OOB, sa)
+ }
+ return hs
+}
+
+// syscaller is a helper to invoke recvmmsg and sendmmsg via the RawConn.Read/Write interface.
+// It is reusable, to amortize the overhead of allocating a closure for the function passed to
+// RawConn.Read/Write.
+type syscaller struct {
+ n int
+ operr error
+ hs mmsghdrs
+ flags int
+
+ boundRecvmmsgF func(uintptr) bool
+ boundSendmmsgF func(uintptr) bool
+}
+
+func (r *syscaller) init() {
+ r.boundRecvmmsgF = r.recvmmsgF
+ r.boundSendmmsgF = r.sendmmsgF
+}
+
+func (r *syscaller) recvmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) {
+ r.n = 0
+ r.operr = nil
+ r.hs = hs
+ r.flags = flags
+ if err := c.Read(r.boundRecvmmsgF); err != nil {
+ return r.n, err
+ }
+ if r.operr != nil {
+ return r.n, os.NewSyscallError("recvmmsg", r.operr)
+ }
+ return r.n, nil
+}
+
+func (r *syscaller) recvmmsgF(s uintptr) bool {
+ r.n, r.operr = recvmmsg(s, r.hs, r.flags)
+ return ioComplete(r.flags, r.operr)
+}
+
+func (r *syscaller) sendmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) {
+ r.n = 0
+ r.operr = nil
+ r.hs = hs
+ r.flags = flags
+ if err := c.Write(r.boundSendmmsgF); err != nil {
+ return r.n, err
+ }
+ if r.operr != nil {
+ return r.n, os.NewSyscallError("sendmmsg", r.operr)
+ }
+ return r.n, nil
+}
+
+func (r *syscaller) sendmmsgF(s uintptr) bool {
+ r.n, r.operr = sendmmsg(s, r.hs, r.flags)
+ return ioComplete(r.flags, r.operr)
+}
+
+// mmsgTmps holds reusable temporary helpers for recvmmsg and sendmmsg.
+type mmsgTmps struct {
+ packer mmsghdrsPacker
+ syscaller syscaller
+}
+
+var defaultMmsgTmpsPool = mmsgTmpsPool{
+ p: sync.Pool{
+ New: func() interface{} {
+ tmps := new(mmsgTmps)
+ tmps.syscaller.init()
+ return tmps
+ },
+ },
+}
+
+type mmsgTmpsPool struct {
+ p sync.Pool
+}
+
+func (p *mmsgTmpsPool) Get() *mmsgTmps {
+ m := p.p.Get().(*mmsgTmps)
+ // Clear fields up to the len (not the cap) of the slice,
+ // assuming that the previous caller only used that many elements.
+ for i := range m.packer.sockaddrs {
+ m.packer.sockaddrs[i] = 0
+ }
+ m.packer.sockaddrs = m.packer.sockaddrs[:0]
+ for i := range m.packer.vs {
+ m.packer.vs[i] = iovec{}
+ }
+ m.packer.vs = m.packer.vs[:0]
+ for i := range m.packer.hs {
+ m.packer.hs[i].Len = 0
+ m.packer.hs[i].Hdr = msghdr{}
+ }
+ m.packer.hs = m.packer.hs[:0]
+ return m
+}
+
+func (p *mmsgTmpsPool) Put(tmps *mmsgTmps) {
+ p.p.Put(tmps)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go b/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
index 77f44c1..25f6847 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
// +build aix darwin dragonfly freebsd netbsd openbsd
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go b/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
index c5562dd..5b8e00f 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || netbsd
// +build aix darwin dragonfly freebsd netbsd
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
index a7a5987..b4658fb 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build arm mips mipsle 386
+//go:build (arm || mips || mipsle || 386 || ppc) && linux
+// +build arm mips mipsle 386 ppc
// +build linux
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
index e731833..42411af 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x
+//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
+// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
// +build linux
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
index 6465b20..3098f5d 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build amd64
-// +build solaris
+//go:build amd64 && solaris
+// +build amd64,solaris
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_stub.go b/vendor/golang.org/x/net/internal/socket/msghdr_stub.go
index 873490a..eb79151 100644
--- a/vendor/golang.org/x/net/internal/socket/msghdr_stub.go
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_stub.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go
new file mode 100644
index 0000000..324e9ee
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go
@@ -0,0 +1,36 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build s390x && zos
+// +build s390x,zos
+
+package socket
+
+import "unsafe"
+
+func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
+ for i := range vs {
+ vs[i].set(bs[i])
+ }
+ if len(vs) > 0 {
+ h.Iov = &vs[0]
+ h.Iovlen = int32(len(vs))
+ }
+ if len(oob) > 0 {
+ h.Control = (*byte)(unsafe.Pointer(&oob[0]))
+ h.Controllen = uint32(len(oob))
+ }
+ if sa != nil {
+ h.Name = (*byte)(unsafe.Pointer(&sa[0]))
+ h.Namelen = uint32(len(sa))
+ }
+}
+
+func (h *msghdr) controllen() int {
+ return int(h.Controllen)
+}
+
+func (h *msghdr) flags() int {
+ return int(h.Flags)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/norace.go b/vendor/golang.org/x/net/internal/socket/norace.go
index 9519ffb..de0ad42 100644
--- a/vendor/golang.org/x/net/internal/socket/norace.go
+++ b/vendor/golang.org/x/net/internal/socket/norace.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !race
// +build !race
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/race.go b/vendor/golang.org/x/net/internal/socket/race.go
index df60c62..f0a28a6 100644
--- a/vendor/golang.org/x/net/internal/socket/race.go
+++ b/vendor/golang.org/x/net/internal/socket/race.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build race
// +build race
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn.go b/vendor/golang.org/x/net/internal/socket/rawconn.go
index b07b890..87e8107 100644
--- a/vendor/golang.org/x/net/internal/socket/rawconn.go
+++ b/vendor/golang.org/x/net/internal/socket/rawconn.go
@@ -17,18 +17,45 @@ type Conn struct {
c syscall.RawConn
}
+// tcpConn is an interface implemented by net.TCPConn.
+// It can be used for interface assertions to check if a net.Conn is a TCP connection.
+type tcpConn interface {
+ SyscallConn() (syscall.RawConn, error)
+ SetLinger(int) error
+}
+
+var _ tcpConn = (*net.TCPConn)(nil)
+
+// udpConn is an interface implemented by net.UDPConn.
+// It can be used for interface assertions to check if a net.Conn is a UDP connection.
+type udpConn interface {
+ SyscallConn() (syscall.RawConn, error)
+ ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
+}
+
+var _ udpConn = (*net.UDPConn)(nil)
+
+// ipConn is an interface implemented by net.IPConn.
+// It can be used for interface assertions to check if a net.Conn is an IP connection.
+type ipConn interface {
+ SyscallConn() (syscall.RawConn, error)
+ ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *net.IPAddr, err error)
+}
+
+var _ ipConn = (*net.IPConn)(nil)
+
// NewConn returns a new raw connection.
func NewConn(c net.Conn) (*Conn, error) {
var err error
var cc Conn
switch c := c.(type) {
- case *net.TCPConn:
+ case tcpConn:
cc.network = "tcp"
cc.c, err = c.SyscallConn()
- case *net.UDPConn:
+ case udpConn:
cc.network = "udp"
cc.c, err = c.SyscallConn()
- case *net.IPConn:
+ case ipConn:
cc.network = "ip"
cc.c, err = c.SyscallConn()
default:
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
index d01fc4c..8f79b38 100644
--- a/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
+++ b/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
@@ -2,43 +2,30 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build linux
// +build linux
package socket
import (
"net"
- "os"
- "syscall"
)
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
for i := range ms {
ms[i].raceWrite()
}
- hs := make(mmsghdrs, len(ms))
+ tmps := defaultMmsgTmpsPool.Get()
+ defer defaultMmsgTmpsPool.Put(tmps)
var parseFn func([]byte, string) (net.Addr, error)
if c.network != "tcp" {
parseFn = parseInetAddr
}
- if err := hs.pack(ms, parseFn, nil); err != nil {
- return 0, err
- }
- var operr error
- var n int
- fn := func(s uintptr) bool {
- n, operr = recvmmsg(s, hs, flags)
- if operr == syscall.EAGAIN {
- return false
- }
- return true
- }
- if err := c.c.Read(fn); err != nil {
+ hs := tmps.packer.pack(ms, parseFn, nil)
+ n, err := tmps.syscaller.recvmmsg(c.c, hs, flags)
+ if err != nil {
return n, err
}
- if operr != nil {
- return n, os.NewSyscallError("recvmmsg", operr)
- }
if err := hs[:n].unpack(ms[:n], parseFn, c.network); err != nil {
return n, err
}
@@ -49,29 +36,17 @@ func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
for i := range ms {
ms[i].raceRead()
}
- hs := make(mmsghdrs, len(ms))
- var marshalFn func(net.Addr) []byte
+ tmps := defaultMmsgTmpsPool.Get()
+ defer defaultMmsgTmpsPool.Put(tmps)
+ var marshalFn func(net.Addr, []byte) int
if c.network != "tcp" {
marshalFn = marshalInetAddr
}
- if err := hs.pack(ms, nil, marshalFn); err != nil {
- return 0, err
- }
- var operr error
- var n int
- fn := func(s uintptr) bool {
- n, operr = sendmmsg(s, hs, flags)
- if operr == syscall.EAGAIN {
- return false
- }
- return true
- }
- if err := c.c.Write(fn); err != nil {
+ hs := tmps.packer.pack(ms, nil, marshalFn)
+ n, err := tmps.syscaller.sendmmsg(c.c, hs, flags)
+ if err != nil {
return n, err
}
- if operr != nil {
- return n, os.NewSyscallError("sendmmsg", operr)
- }
if err := hs[:n].unpack(ms[:n], nil, ""); err != nil {
return n, err
}
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go
index d5ae3f8..f7d0b0d 100644
--- a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go
+++ b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go
@@ -2,32 +2,28 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package socket
import (
+ "net"
"os"
- "syscall"
)
func (c *Conn) recvMsg(m *Message, flags int) error {
m.raceWrite()
- var h msghdr
- vs := make([]iovec, len(m.Buffers))
- var sa []byte
- if c.network != "tcp" {
- sa = make([]byte, sizeofSockaddrInet6)
- }
- h.pack(vs, m.Buffers, m.OOB, sa)
- var operr error
- var n int
+ var (
+ operr error
+ n int
+ oobn int
+ recvflags int
+ from net.Addr
+ )
fn := func(s uintptr) bool {
- n, operr = recvmsg(s, &h, flags)
- if operr == syscall.EAGAIN {
- return false
- }
- return true
+ n, oobn, recvflags, from, operr = recvmsg(s, m.Buffers, m.OOB, flags, c.network)
+ return ioComplete(flags, operr)
}
if err := c.c.Read(fn); err != nil {
return err
@@ -35,36 +31,22 @@ func (c *Conn) recvMsg(m *Message, flags int) error {
if operr != nil {
return os.NewSyscallError("recvmsg", operr)
}
- if c.network != "tcp" {
- var err error
- m.Addr, err = parseInetAddr(sa[:], c.network)
- if err != nil {
- return err
- }
- }
+ m.Addr = from
m.N = n
- m.NN = h.controllen()
- m.Flags = h.flags()
+ m.NN = oobn
+ m.Flags = recvflags
return nil
}
func (c *Conn) sendMsg(m *Message, flags int) error {
m.raceRead()
- var h msghdr
- vs := make([]iovec, len(m.Buffers))
- var sa []byte
- if m.Addr != nil {
- sa = marshalInetAddr(m.Addr)
- }
- h.pack(vs, m.Buffers, m.OOB, sa)
- var operr error
- var n int
+ var (
+ operr error
+ n int
+ )
fn := func(s uintptr) bool {
- n, operr = sendmsg(s, &h, flags)
- if operr == syscall.EAGAIN {
- return false
- }
- return true
+ n, operr = sendmsg(s, m.Buffers, m.OOB, m.Addr, flags)
+ return ioComplete(flags, operr)
}
if err := c.c.Write(fn); err != nil {
return err
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
index fe5bb94..02f3285 100644
--- a/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
+++ b/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !linux
// +build !linux
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
index b8cea6f..dd78587 100644
--- a/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
+++ b/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/socket.go b/vendor/golang.org/x/net/internal/socket/socket.go
index 23571b8..dba47bf 100644
--- a/vendor/golang.org/x/net/internal/socket/socket.go
+++ b/vendor/golang.org/x/net/internal/socket/socket.go
@@ -90,17 +90,9 @@ func (o *Option) SetInt(c *Conn, v int) error {
return o.set(c, b)
}
-func controlHeaderLen() int {
- return roundup(sizeofCmsghdr)
-}
-
-func controlMessageLen(dataLen int) int {
- return roundup(sizeofCmsghdr) + dataLen
-}
-
// ControlMessageSpace returns the whole length of control message.
func ControlMessageSpace(dataLen int) int {
- return roundup(sizeofCmsghdr) + roundup(dataLen)
+ return controlMessageSpace(dataLen)
}
// A ControlMessage represents the head message in a stream of control
diff --git a/vendor/golang.org/x/net/internal/socket/sys.go b/vendor/golang.org/x/net/internal/socket/sys.go
index ee492ba..4a26af1 100644
--- a/vendor/golang.org/x/net/internal/socket/sys.go
+++ b/vendor/golang.org/x/net/internal/socket/sys.go
@@ -9,13 +9,8 @@ import (
"unsafe"
)
-var (
- // NativeEndian is the machine native endian implementation of
- // ByteOrder.
- NativeEndian binary.ByteOrder
-
- kernelAlign int
-)
+// NativeEndian is the machine native endian implementation of ByteOrder.
+var NativeEndian binary.ByteOrder
func init() {
i := uint32(1)
@@ -25,9 +20,4 @@ func init() {
} else {
NativeEndian = binary.BigEndian
}
- kernelAlign = probeProtocolStack()
-}
-
-func roundup(l int) int {
- return (l + kernelAlign - 1) &^ (kernelAlign - 1)
}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_bsd.go b/vendor/golang.org/x/net/internal/socket/sys_bsd.go
index d432835..b258879 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_bsd.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_bsd.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd openbsd
+//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd openbsd solaris
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/sys_bsdvar.go b/vendor/golang.org/x/net/internal/socket/sys_bsdvar.go
deleted file mode 100644
index b4f41b5..0000000
--- a/vendor/golang.org/x/net/internal/socket/sys_bsdvar.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build aix freebsd netbsd openbsd
-
-package socket
-
-import (
- "runtime"
- "unsafe"
-)
-
-func probeProtocolStack() int {
- if (runtime.GOOS == "netbsd" || runtime.GOOS == "openbsd") && runtime.GOARCH == "arm" {
- return 8
- }
- if runtime.GOOS == "aix" {
- return 1
- }
- var p uintptr
- return int(unsafe.Sizeof(p))
-}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_const_unix.go b/vendor/golang.org/x/net/internal/socket/sys_const_unix.go
index 43797d6..5d99f23 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_const_unix.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_const_unix.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
@@ -14,4 +15,7 @@ const (
sysAF_INET6 = unix.AF_INET6
sysSOCK_RAW = unix.SOCK_RAW
+
+ sizeofSockaddrInet4 = unix.SizeofSockaddrInet4
+ sizeofSockaddrInet6 = unix.SizeofSockaddrInet6
)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_dragonfly.go b/vendor/golang.org/x/net/internal/socket/sys_dragonfly.go
deleted file mode 100644
index ed0448f..0000000
--- a/vendor/golang.org/x/net/internal/socket/sys_dragonfly.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package socket
-
-import (
- "sync"
- "syscall"
- "unsafe"
-)
-
-// See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h
-var (
- osreldateOnce sync.Once
- osreldate uint32
-)
-
-// First __DragonFly_version after September 2019 ABI changes
-// http://lists.dragonflybsd.org/pipermail/users/2019-September/358280.html
-const _dragonflyABIChangeVersion = 500705
-
-func probeProtocolStack() int {
- osreldateOnce.Do(func() { osreldate, _ = syscall.SysctlUint32("kern.osreldate") })
- var p uintptr
- if int(unsafe.Sizeof(p)) == 8 && osreldate >= _dragonflyABIChangeVersion {
- return int(unsafe.Sizeof(p))
- }
- // 64-bit Dragonfly before the September 2019 ABI changes still requires
- // 32-bit aligned access to network subsystem.
- return 4
-}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_go1_11_darwin.go b/vendor/golang.org/x/net/internal/socket/sys_go1_11_darwin.go
deleted file mode 100644
index 02d2b3c..0000000
--- a/vendor/golang.org/x/net/internal/socket/sys_go1_11_darwin.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.12
-
-package socket
-
-import (
- "syscall"
- "unsafe"
-)
-
-func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
- l := uint32(len(b))
- _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)
- return int(l), errnoErr(errno)
-}
-
-func setsockopt(s uintptr, level, name int, b []byte) error {
- _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)
- return errnoErr(errno)
-}
-
-func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
- n, _, errno := syscall.Syscall(syscall.SYS_RECVMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
- return int(n), errnoErr(errno)
-}
-
-func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
- n, _, errno := syscall.Syscall(syscall.SYS_SENDMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
- return int(n), errnoErr(errno)
-}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linkname.go b/vendor/golang.org/x/net/internal/socket/sys_linkname.go
deleted file mode 100644
index 61c3f38..0000000
--- a/vendor/golang.org/x/net/internal/socket/sys_linkname.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build aix go1.12,darwin
-
-package socket
-
-import (
- "syscall"
- "unsafe"
-)
-
-//go:linkname syscall_getsockopt syscall.getsockopt
-func syscall_getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *uint32) error
-
-func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
- l := uint32(len(b))
- err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l)
- return int(l), err
-}
-
-//go:linkname syscall_setsockopt syscall.setsockopt
-func syscall_setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) error
-
-func setsockopt(s uintptr, level, name int, b []byte) error {
- return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b)))
-}
-
-//go:linkname syscall_recvmsg syscall.recvmsg
-func syscall_recvmsg(s int, msg *syscall.Msghdr, flags int) (n int, err error)
-
-func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
- return syscall_recvmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags)
-}
-
-//go:linkname syscall_sendmsg syscall.sendmsg
-func syscall_sendmsg(s int, msg *syscall.Msghdr, flags int) (n int, err error)
-
-func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
- return syscall_sendmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags)
-}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux.go b/vendor/golang.org/x/net/internal/socket/sys_linux.go
index 1559521..76f5b8a 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_linux.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_linux.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build linux && !s390x && !386
// +build linux,!s390x,!386
package socket
@@ -11,11 +12,6 @@ import (
"unsafe"
)
-func probeProtocolStack() int {
- var p uintptr
- return int(unsafe.Sizeof(p))
-}
-
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
n, _, errno := syscall.Syscall6(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
return int(n), errnoErr(errno)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_386.go b/vendor/golang.org/x/net/internal/socket/sys_linux_386.go
index 235b2cc..c877ef2 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_linux_386.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_linux_386.go
@@ -9,41 +9,14 @@ import (
"unsafe"
)
-func probeProtocolStack() int { return 4 }
-
const (
- sysSETSOCKOPT = 0xe
- sysGETSOCKOPT = 0xf
- sysSENDMSG = 0x10
- sysRECVMSG = 0x11
- sysRECVMMSG = 0x13
- sysSENDMMSG = 0x14
+ sysRECVMMSG = 0x13
+ sysSENDMMSG = 0x14
)
func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
func rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
-func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
- l := uint32(len(b))
- _, errno := socketcall(sysGETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)
- return int(l), errnoErr(errno)
-}
-
-func setsockopt(s uintptr, level, name int, b []byte) error {
- _, errno := socketcall(sysSETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)
- return errnoErr(errno)
-}
-
-func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
- n, errno := socketcall(sysRECVMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0)
- return int(n), errnoErr(errno)
-}
-
-func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
- n, errno := socketcall(sysSENDMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0)
- return int(n), errnoErr(errno)
-}
-
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
n, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
return int(n), errnoErr(errno)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go
new file mode 100644
index 0000000..af964e6
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build loong64
+// +build loong64
+
+package socket
+
+const (
+ sysRECVMMSG = 0xf3
+ sysSENDMMSG = 0x10d
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_darwin.go b/vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go
similarity index 53%
rename from vendor/golang.org/x/net/internal/socket/sys_darwin.go
rename to vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go
index b17d223..90cfaa9 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_darwin.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go
@@ -1,7 +1,10 @@
-// Copyright 2017 The Go Authors. All rights reserved.
+// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package socket
-func probeProtocolStack() int { return 4 }
+const (
+ sysRECVMMSG = 0x157
+ sysSENDMMSG = 0x15d
+)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go
index 64f69f1..5b128fb 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build riscv64
// +build riscv64
package socket
diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go b/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go
index 327979e..c877ef2 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go
@@ -9,41 +9,14 @@ import (
"unsafe"
)
-func probeProtocolStack() int { return 8 }
-
const (
- sysSETSOCKOPT = 0xe
- sysGETSOCKOPT = 0xf
- sysSENDMSG = 0x10
- sysRECVMSG = 0x11
- sysRECVMMSG = 0x13
- sysSENDMMSG = 0x14
+ sysRECVMMSG = 0x13
+ sysSENDMMSG = 0x14
)
func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
func rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
-func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
- l := uint32(len(b))
- _, errno := socketcall(sysGETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)
- return int(l), errnoErr(errno)
-}
-
-func setsockopt(s uintptr, level, name int, b []byte) error {
- _, errno := socketcall(sysSETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)
- return errnoErr(errno)
-}
-
-func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
- n, errno := socketcall(sysRECVMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0)
- return int(n), errnoErr(errno)
-}
-
-func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
- n, errno := socketcall(sysSENDMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0)
- return int(n), errnoErr(errno)
-}
-
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
n, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
return int(n), errnoErr(errno)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_posix.go b/vendor/golang.org/x/net/internal/socket/sys_posix.go
index 22eae80..42b8f23 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_posix.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_posix.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package socket
@@ -16,35 +17,36 @@ import (
"time"
)
-func marshalInetAddr(a net.Addr) []byte {
+// marshalInetAddr writes a in sockaddr format into the buffer b.
+// The buffer must be sufficiently large (sizeofSockaddrInet4/6).
+// Returns the number of bytes written.
+func marshalInetAddr(a net.Addr, b []byte) int {
switch a := a.(type) {
case *net.TCPAddr:
- return marshalSockaddr(a.IP, a.Port, a.Zone)
+ return marshalSockaddr(a.IP, a.Port, a.Zone, b)
case *net.UDPAddr:
- return marshalSockaddr(a.IP, a.Port, a.Zone)
+ return marshalSockaddr(a.IP, a.Port, a.Zone, b)
case *net.IPAddr:
- return marshalSockaddr(a.IP, 0, a.Zone)
+ return marshalSockaddr(a.IP, 0, a.Zone, b)
default:
- return nil
+ return 0
}
}
-func marshalSockaddr(ip net.IP, port int, zone string) []byte {
+func marshalSockaddr(ip net.IP, port int, zone string, b []byte) int {
if ip4 := ip.To4(); ip4 != nil {
- b := make([]byte, sizeofSockaddrInet)
switch runtime.GOOS {
case "android", "illumos", "linux", "solaris", "windows":
NativeEndian.PutUint16(b[:2], uint16(sysAF_INET))
default:
- b[0] = sizeofSockaddrInet
+ b[0] = sizeofSockaddrInet4
b[1] = sysAF_INET
}
binary.BigEndian.PutUint16(b[2:4], uint16(port))
copy(b[4:8], ip4)
- return b
+ return sizeofSockaddrInet4
}
if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil {
- b := make([]byte, sizeofSockaddrInet6)
switch runtime.GOOS {
case "android", "illumos", "linux", "solaris", "windows":
NativeEndian.PutUint16(b[:2], uint16(sysAF_INET6))
@@ -57,9 +59,9 @@ func marshalSockaddr(ip net.IP, port int, zone string) []byte {
if zone != "" {
NativeEndian.PutUint32(b[24:28], uint32(zoneCache.index(zone)))
}
- return b
+ return sizeofSockaddrInet6
}
- return nil
+ return 0
}
func parseInetAddr(b []byte, network string) (net.Addr, error) {
@@ -76,7 +78,7 @@ func parseInetAddr(b []byte, network string) (net.Addr, error) {
var ip net.IP
var zone string
if af == sysAF_INET {
- if len(b) < sizeofSockaddrInet {
+ if len(b) < sizeofSockaddrInet4 {
return nil, errors.New("short address")
}
ip = make(net.IP, net.IPv4len)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_solaris.go b/vendor/golang.org/x/net/internal/socket/sys_solaris.go
deleted file mode 100644
index 66b5547..0000000
--- a/vendor/golang.org/x/net/internal/socket/sys_solaris.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package socket
-
-import (
- "runtime"
- "syscall"
- "unsafe"
-)
-
-func probeProtocolStack() int {
- switch runtime.GOARCH {
- case "amd64":
- return 4
- default:
- var p uintptr
- return int(unsafe.Sizeof(p))
- }
-}
-
-//go:cgo_import_dynamic libc___xnet_getsockopt __xnet_getsockopt "libsocket.so"
-//go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so"
-//go:cgo_import_dynamic libc___xnet_recvmsg __xnet_recvmsg "libsocket.so"
-//go:cgo_import_dynamic libc___xnet_sendmsg __xnet_sendmsg "libsocket.so"
-
-//go:linkname procGetsockopt libc___xnet_getsockopt
-//go:linkname procSetsockopt libc_setsockopt
-//go:linkname procRecvmsg libc___xnet_recvmsg
-//go:linkname procSendmsg libc___xnet_sendmsg
-
-var (
- procGetsockopt uintptr
- procSetsockopt uintptr
- procRecvmsg uintptr
- procSendmsg uintptr
-)
-
-func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (uintptr, uintptr, syscall.Errno)
-func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (uintptr, uintptr, syscall.Errno)
-
-func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
- l := uint32(len(b))
- _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procGetsockopt)), 5, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)
- return int(l), errnoErr(errno)
-}
-
-func setsockopt(s uintptr, level, name int, b []byte) error {
- _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procSetsockopt)), 5, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)
- return errnoErr(errno)
-}
-
-func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
- n, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procRecvmsg)), 3, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0)
- return int(n), errnoErr(errno)
-}
-
-func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
- n, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procSendmsg)), 3, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0)
- return int(n), errnoErr(errno)
-}
-
-func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
- return 0, errNotImplemented
-}
-
-func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
- return 0, errNotImplemented
-}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_solaris_amd64.s b/vendor/golang.org/x/net/internal/socket/sys_solaris_amd64.s
deleted file mode 100644
index a18ac5e..0000000
--- a/vendor/golang.org/x/net/internal/socket/sys_solaris_amd64.s
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-TEXT ·sysvicall6(SB),NOSPLIT,$0-88
- JMP syscall·sysvicall6(SB)
-
-TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88
- JMP syscall·rawSysvicall6(SB)
diff --git a/vendor/golang.org/x/net/internal/socket/sys_stub.go b/vendor/golang.org/x/net/internal/socket/sys_stub.go
index 0f61742..7cfb349 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_stub.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_stub.go
@@ -2,15 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package socket
-import (
- "net"
- "runtime"
- "unsafe"
-)
+import "net"
const (
sysAF_UNSPEC = 0x0
@@ -18,17 +15,10 @@ const (
sysAF_INET6 = 0xa
sysSOCK_RAW = 0x3
-)
-func probeProtocolStack() int {
- switch runtime.GOARCH {
- case "amd64p32", "mips64p32":
- return 4
- default:
- var p uintptr
- return int(unsafe.Sizeof(p))
- }
-}
+ sizeofSockaddrInet4 = 0x10
+ sizeofSockaddrInet6 = 0x1c
+)
func marshalInetAddr(ip net.IP, port int, zone string) []byte {
return nil
@@ -46,11 +36,11 @@ func setsockopt(s uintptr, level, name int, b []byte) error {
return errNotImplemented
}
-func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
- return 0, errNotImplemented
+func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
+ return 0, 0, 0, nil, errNotImplemented
}
-func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
+func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
return 0, errNotImplemented
}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_unix.go b/vendor/golang.org/x/net/internal/socket/sys_unix.go
index 0eb7128..de82393 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_unix.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_unix.go
@@ -2,32 +2,121 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build dragonfly freebsd linux,!s390x,!386 netbsd openbsd
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package socket
import (
- "syscall"
+ "net"
"unsafe"
+
+ "golang.org/x/sys/unix"
)
+//go:linkname syscall_getsockopt syscall.getsockopt
+func syscall_getsockopt(s, level, name int, val unsafe.Pointer, vallen *uint32) error
+
+//go:linkname syscall_setsockopt syscall.setsockopt
+func syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error
+
func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
l := uint32(len(b))
- _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)
- return int(l), errnoErr(errno)
+ err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l)
+ return int(l), err
}
func setsockopt(s uintptr, level, name int, b []byte) error {
- _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)
- return errnoErr(errno)
+ return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b)))
}
-func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
- n, _, errno := syscall.Syscall(syscall.SYS_RECVMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
- return int(n), errnoErr(errno)
+func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
+ var unixFrom unix.Sockaddr
+ n, oobn, recvflags, unixFrom, err = unix.RecvmsgBuffers(int(s), buffers, oob, flags)
+ if unixFrom != nil {
+ from = sockaddrToAddr(unixFrom, network)
+ }
+ return
}
-func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
- n, _, errno := syscall.Syscall(syscall.SYS_SENDMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
- return int(n), errnoErr(errno)
+func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
+ var unixTo unix.Sockaddr
+ if to != nil {
+ unixTo = addrToSockaddr(to)
+ }
+ return unix.SendmsgBuffers(int(s), buffers, oob, unixTo, flags)
+}
+
+// addrToSockaddr converts a net.Addr to a unix.Sockaddr.
+func addrToSockaddr(a net.Addr) unix.Sockaddr {
+ var (
+ ip net.IP
+ port int
+ zone string
+ )
+ switch a := a.(type) {
+ case *net.TCPAddr:
+ ip = a.IP
+ port = a.Port
+ zone = a.Zone
+ case *net.UDPAddr:
+ ip = a.IP
+ port = a.Port
+ zone = a.Zone
+ case *net.IPAddr:
+ ip = a.IP
+ zone = a.Zone
+ default:
+ return nil
+ }
+
+ if ip4 := ip.To4(); ip4 != nil {
+ sa := unix.SockaddrInet4{Port: port}
+ copy(sa.Addr[:], ip4)
+ return &sa
+ }
+
+ if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil {
+ sa := unix.SockaddrInet6{Port: port}
+ copy(sa.Addr[:], ip6)
+ if zone != "" {
+ sa.ZoneId = uint32(zoneCache.index(zone))
+ }
+ return &sa
+ }
+
+ return nil
+}
+
+// sockaddrToAddr converts a unix.Sockaddr to a net.Addr.
+func sockaddrToAddr(sa unix.Sockaddr, network string) net.Addr {
+ var (
+ ip net.IP
+ port int
+ zone string
+ )
+ switch sa := sa.(type) {
+ case *unix.SockaddrInet4:
+ ip = make(net.IP, net.IPv4len)
+ copy(ip, sa.Addr[:])
+ port = sa.Port
+ case *unix.SockaddrInet6:
+ ip = make(net.IP, net.IPv6len)
+ copy(ip, sa.Addr[:])
+ port = sa.Port
+ if sa.ZoneId > 0 {
+ zone = zoneCache.name(int(sa.ZoneId))
+ }
+ default:
+ return nil
+ }
+
+ switch network {
+ case "tcp", "tcp4", "tcp6":
+ return &net.TCPAddr{IP: ip, Port: port, Zone: zone}
+ case "udp", "udp4", "udp6":
+ return &net.UDPAddr{IP: ip, Port: port, Zone: zone}
+ default:
+ return &net.IPAddr{IP: ip, Zone: zone}
+ }
}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_windows.go b/vendor/golang.org/x/net/internal/socket/sys_windows.go
index d556a44..b738b89 100644
--- a/vendor/golang.org/x/net/internal/socket/sys_windows.go
+++ b/vendor/golang.org/x/net/internal/socket/sys_windows.go
@@ -5,6 +5,7 @@
package socket
import (
+ "net"
"syscall"
"unsafe"
@@ -22,25 +23,8 @@ const (
sysAF_INET6 = windows.AF_INET6
sysSOCK_RAW = windows.SOCK_RAW
-)
-
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]uint8
-}
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
-const (
- sizeofSockaddrInet = 0x10
+ sizeofSockaddrInet4 = 0x10
sizeofSockaddrInet6 = 0x1c
)
@@ -54,11 +38,11 @@ func setsockopt(s uintptr, level, name int, b []byte) error {
return syscall.Setsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), int32(len(b)))
}
-func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
- return 0, errNotImplemented
+func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
+ return 0, 0, 0, nil, errNotImplemented
}
-func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
+func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
return 0, errNotImplemented
}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go
new file mode 100644
index 0000000..eaa896c
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go
@@ -0,0 +1,66 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+)
+
+func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
+func syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+func probeProtocolStack() int {
+ return 4 // sizeof(int) on GOOS=zos GOARCH=s390x
+}
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ l := uint32(len(b))
+ _, _, errno := syscall_syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)
+ return int(l), errnoErr(errno)
+}
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ _, _, errno := syscall_syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)
+ return errnoErr(errno)
+}
+
+func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
+ var h msghdr
+ vs := make([]iovec, len(buffers))
+ var sa []byte
+ if network != "tcp" {
+ sa = make([]byte, sizeofSockaddrInet6)
+ }
+ h.pack(vs, buffers, oob, sa)
+ sn, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags))
+ n = int(sn)
+ oobn = h.controllen()
+ recvflags = h.flags()
+ err = errnoErr(errno)
+ if network != "tcp" {
+ var err2 error
+ from, err2 = parseInetAddr(sa, network)
+ if err2 != nil && err == nil {
+ err = err2
+ }
+ }
+ return
+}
+
+func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
+ var h msghdr
+ vs := make([]iovec, len(buffers))
+ var sa []byte
+ if to != nil {
+ var a [sizeofSockaddrInet6]byte
+ n := marshalInetAddr(to, a[:])
+ sa = a[:n]
+ }
+ h.pack(vs, buffers, oob, sa)
+ n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags))
+ return int(n), errnoErr(errno)
+}
diff --git a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s
new file mode 100644
index 0000000..60d5839
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s
@@ -0,0 +1,11 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·syscall_syscall(SB),NOSPLIT,$0
+ JMP syscall·_syscall(SB)
+
+TEXT ·syscall_syscall6(SB),NOSPLIT,$0
+ JMP syscall·_syscall6(SB)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go b/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go
index e740c8f..00691bd 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go
@@ -2,6 +2,7 @@
// cgo -godefs defs_aix.go
// Added for go1.11 compatibility
+//go:build aix
// +build aix
package socket
@@ -33,28 +34,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]uint8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x10
- sizeofMsghdr = 0x30
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go
deleted file mode 100644
index 083bda5..0000000
--- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs defs_darwin.go
-
-package socket
-
-type iovec struct {
- Base *byte
- Len uint32
-}
-
-type msghdr struct {
- Name *byte
- Namelen uint32
- Iov *iovec
- Iovlen int32
- Control *byte
- Controllen uint32
- Flags int32
-}
-
-type cmsghdr struct {
- Len uint32
- Level int32
- Type int32
-}
-
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
-const (
- sizeofIovec = 0x8
- sizeofMsghdr = 0x1c
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
-)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go
index 55c6c9f..98dcfe4 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go
@@ -26,28 +26,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x10
- sizeofMsghdr = 0x30
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go
deleted file mode 100644
index 083bda5..0000000
--- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs defs_darwin.go
-
-package socket
-
-type iovec struct {
- Base *byte
- Len uint32
-}
-
-type msghdr struct {
- Name *byte
- Namelen uint32
- Iov *iovec
- Iovlen int32
- Control *byte
- Controllen uint32
- Flags int32
-}
-
-type cmsghdr struct {
- Len uint32
- Level int32
- Type int32
-}
-
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
-const (
- sizeofIovec = 0x8
- sizeofMsghdr = 0x1c
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
-)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go
index 55c6c9f..98dcfe4 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go
@@ -26,28 +26,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x10
- sizeofMsghdr = 0x30
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go
index 8b7d161..636d129 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go
@@ -26,28 +26,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x10
- sizeofMsghdr = 0x30
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go
index 3e71ff5..87707fe 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go
@@ -24,28 +24,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x8
- sizeofMsghdr = 0x1c
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go
index 238d90d..7db7781 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go
@@ -26,28 +26,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x10
- sizeofMsghdr = 0x30
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go
index 3e71ff5..87707fe 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go
@@ -24,28 +24,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x8
- sizeofMsghdr = 0x1c
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go
index 238d90d..7db7781 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go
@@ -26,28 +26,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x10
- sizeofMsghdr = 0x30
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_riscv64.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_riscv64.go
new file mode 100644
index 0000000..965c0b2
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_riscv64.go
@@ -0,0 +1,30 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen int32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go
index d33025b..4c19269 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go
@@ -29,26 +29,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x8
- sizeofMsghdr = 0x1c
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go
index b20d216..3dcd5c8 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go
@@ -32,26 +32,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x10
- sizeofMsghdr = 0x38
- sizeofCmsghdr = 0x10
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x38
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go
index 1bb10a4..4c19269 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go
@@ -29,27 +29,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x8
sizeofMsghdr = 0x1c
-
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go
index 7f6e8a7..3dcd5c8 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go
@@ -32,27 +32,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x10
sizeofMsghdr = 0x38
-
- sizeofCmsghdr = 0x10
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go
new file mode 100644
index 0000000..6a94fec
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go
@@ -0,0 +1,40 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+//go:build loong64
+// +build loong64
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint64
+ Control *byte
+ Controllen uint64
+ Flags int32
+ Pad_cgo_0 [4]byte
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+ Pad_cgo_0 [4]byte
+}
+
+type cmsghdr struct {
+ Len uint64
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x38
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go
index 1bb10a4..4c19269 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go
@@ -29,27 +29,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x8
sizeofMsghdr = 0x1c
-
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go
index 7f6e8a7..3dcd5c8 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go
@@ -32,27 +32,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x10
sizeofMsghdr = 0x38
-
- sizeofCmsghdr = 0x10
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go
index 7f6e8a7..3dcd5c8 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go
@@ -32,27 +32,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x10
sizeofMsghdr = 0x38
-
- sizeofCmsghdr = 0x10
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go
index 1bb10a4..4c19269 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go
@@ -29,27 +29,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x8
sizeofMsghdr = 0x1c
-
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc.go
new file mode 100644
index 0000000..4c19269
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc.go
@@ -0,0 +1,35 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint32
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type mmsghdr struct {
+ Hdr msghdr
+ Len uint32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go
index 7f6e8a7..3dcd5c8 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go
@@ -32,27 +32,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x10
sizeofMsghdr = 0x38
-
- sizeofCmsghdr = 0x10
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go
index 7f6e8a7..3dcd5c8 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go
@@ -32,27 +32,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x10
sizeofMsghdr = 0x38
-
- sizeofCmsghdr = 0x10
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go
index f12a1d7..c066272 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go
@@ -1,6 +1,7 @@
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs defs_linux.go
+//go:build riscv64
// +build riscv64
package socket
@@ -33,27 +34,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x10
sizeofMsghdr = 0x38
-
- sizeofCmsghdr = 0x10
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go
index 7f6e8a7..3dcd5c8 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go
@@ -32,27 +32,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- X__pad [8]uint8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x10
sizeofMsghdr = 0x38
-
- sizeofCmsghdr = 0x10
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go
index 7e258ce..f95572d 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go
@@ -29,29 +29,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x8
sizeofMsghdr = 0x1c
-
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go
index b3f9c0d..a92fd60 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go
@@ -32,29 +32,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x10
sizeofMsghdr = 0x30
-
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go
index 7e258ce..f95572d 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go
@@ -29,29 +29,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
sizeofIovec = 0x8
sizeofMsghdr = 0x1c
-
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go
index da26ef0..a92fd60 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go
@@ -32,28 +32,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x10
- sizeofMsghdr = 0x30
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go
index 73655a1..e792ec2 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go
@@ -24,28 +24,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x8
- sizeofMsghdr = 0x1c
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go
index 0a4de80..b68ff2d 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go
@@ -26,28 +26,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x10
- sizeofMsghdr = 0x30
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go
index 73655a1..e792ec2 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go
@@ -24,28 +24,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x8
- sizeofMsghdr = 0x1c
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x8
+ sizeofMsghdr = 0x1c
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go
index 0a4de80..b68ff2d 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go
@@ -26,28 +26,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Len uint8
- Family uint8
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Len uint8
- Family uint8
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
const (
- sizeofIovec = 0x10
- sizeofMsghdr = 0x30
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x1c
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go
new file mode 100644
index 0000000..3c9576e
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go
@@ -0,0 +1,30 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_openbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_ppc64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_ppc64.go
new file mode 100644
index 0000000..cebde76
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_ppc64.go
@@ -0,0 +1,30 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_openbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_riscv64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_riscv64.go
new file mode 100644
index 0000000..cebde76
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_riscv64.go
@@ -0,0 +1,30 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_openbsd.go
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Namelen uint32
+ Iov *iovec
+ Iovlen uint32
+ Control *byte
+ Controllen uint32
+ Flags int32
+}
+
+type cmsghdr struct {
+ Len uint32
+ Level int32
+ Type int32
+}
+
+const (
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
+)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go
index 353cd5f..359cfec 100644
--- a/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go
+++ b/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go
@@ -26,27 +26,7 @@ type cmsghdr struct {
Type int32
}
-type sockaddrInet struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]int8
-}
-
-type sockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
- X__sin6_src_id uint32
-}
-
const (
- sizeofIovec = 0x10
- sizeofMsghdr = 0x30
- sizeofCmsghdr = 0xc
-
- sizeofSockaddrInet = 0x10
- sizeofSockaddrInet6 = 0x20
+ sizeofIovec = 0x10
+ sizeofMsghdr = 0x30
)
diff --git a/vendor/golang.org/x/net/internal/socket/zsys_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/zsys_zos_s390x.go
new file mode 100644
index 0000000..49b62c8
--- /dev/null
+++ b/vendor/golang.org/x/net/internal/socket/zsys_zos_s390x.go
@@ -0,0 +1,28 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package socket
+
+type iovec struct {
+ Base *byte
+ Len uint64
+}
+
+type msghdr struct {
+ Name *byte
+ Iov *iovec
+ Control *byte
+ Flags int32
+ Namelen uint32
+ Iovlen int32
+ Controllen uint32
+}
+
+type cmsghdr struct {
+ Len int32
+ Level int32
+ Type int32
+}
+
+const sizeofCmsghdr = 12
diff --git a/vendor/golang.org/x/net/ipv4/control_bsd.go b/vendor/golang.org/x/net/ipv4/control_bsd.go
index 69c4f55..b7385df 100644
--- a/vendor/golang.org/x/net/ipv4/control_bsd.go
+++ b/vendor/golang.org/x/net/ipv4/control_bsd.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
// +build aix darwin dragonfly freebsd netbsd openbsd
package ipv4
@@ -13,11 +14,13 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
func marshalDst(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIP, sysIP_RECVDSTADDR, net.IPv4len)
+ m.MarshalHeader(iana.ProtocolIP, unix.IP_RECVDSTADDR, net.IPv4len)
return m.Next(net.IPv4len)
}
@@ -30,7 +33,7 @@ func parseDst(cm *ControlMessage, b []byte) {
func marshalInterface(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIP, sysIP_RECVIF, syscall.SizeofSockaddrDatalink)
+ m.MarshalHeader(iana.ProtocolIP, sockoptReceiveInterface, syscall.SizeofSockaddrDatalink)
return m.Next(syscall.SizeofSockaddrDatalink)
}
diff --git a/vendor/golang.org/x/net/ipv4/control_pktinfo.go b/vendor/golang.org/x/net/ipv4/control_pktinfo.go
index 425338f..0e748db 100644
--- a/vendor/golang.org/x/net/ipv4/control_pktinfo.go
+++ b/vendor/golang.org/x/net/ipv4/control_pktinfo.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build darwin || linux || solaris
// +build darwin linux solaris
package ipv4
@@ -12,11 +13,13 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIP, sysIP_PKTINFO, sizeofInetPktinfo)
+ m.MarshalHeader(iana.ProtocolIP, unix.IP_PKTINFO, sizeofInetPktinfo)
if cm != nil {
pi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0]))
if ip := cm.Src.To4(); ip != nil {
diff --git a/vendor/golang.org/x/net/ipv4/control_stub.go b/vendor/golang.org/x/net/ipv4/control_stub.go
index a0c049d..f27322c 100644
--- a/vendor/golang.org/x/net/ipv4/control_stub.go
+++ b/vendor/golang.org/x/net/ipv4/control_stub.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/control_unix.go b/vendor/golang.org/x/net/ipv4/control_unix.go
index b27fa49..2413e02 100644
--- a/vendor/golang.org/x/net/ipv4/control_unix.go
+++ b/vendor/golang.org/x/net/ipv4/control_unix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package ipv4
@@ -11,6 +12,8 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
@@ -64,7 +67,7 @@ func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) er
func marshalTTL(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIP, sysIP_RECVTTL, 1)
+ m.MarshalHeader(iana.ProtocolIP, unix.IP_RECVTTL, 1)
return m.Next(1)
}
diff --git a/vendor/golang.org/x/net/ipv4/control_zos.go b/vendor/golang.org/x/net/ipv4/control_zos.go
new file mode 100644
index 0000000..de11c42
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv4/control_zos.go
@@ -0,0 +1,88 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
+ m := socket.ControlMessage(b)
+ m.MarshalHeader(iana.ProtocolIP, unix.IP_PKTINFO, sizeofInetPktinfo)
+ if cm != nil {
+ pi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0]))
+ if ip := cm.Src.To4(); ip != nil {
+ copy(pi.Addr[:], ip)
+ }
+ if cm.IfIndex > 0 {
+ pi.setIfindex(cm.IfIndex)
+ }
+ }
+ return m.Next(sizeofInetPktinfo)
+}
+
+func parsePacketInfo(cm *ControlMessage, b []byte) {
+ pi := (*inetPktinfo)(unsafe.Pointer(&b[0]))
+ cm.IfIndex = int(pi.Ifindex)
+ if len(cm.Dst) < net.IPv4len {
+ cm.Dst = make(net.IP, net.IPv4len)
+ }
+ copy(cm.Dst, pi.Addr[:])
+}
+
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
+ opt.Lock()
+ defer opt.Unlock()
+ if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagTTL)
+ } else {
+ opt.clear(FlagTTL)
+ }
+ }
+ if so, ok := sockOpts[ssoPacketInfo]; ok {
+ if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
+ } else {
+ opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
+ }
+ }
+ } else {
+ if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagDst)
+ } else {
+ opt.clear(FlagDst)
+ }
+ }
+ if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
+ return err
+ }
+ if on {
+ opt.set(FlagInterface)
+ } else {
+ opt.clear(FlagInterface)
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/golang.org/x/net/ipv4/doc.go b/vendor/golang.org/x/net/ipv4/doc.go
index 2458349..6fbdc52 100644
--- a/vendor/golang.org/x/net/ipv4/doc.go
+++ b/vendor/golang.org/x/net/ipv4/doc.go
@@ -16,8 +16,7 @@
// 3376.
// Source-specific multicast is defined in RFC 4607.
//
-//
-// Unicasting
+// # Unicasting
//
// The options for unicasting are available for net.TCPConn,
// net.UDPConn and net.IPConn which are created as network connections
@@ -51,8 +50,7 @@
// }(c)
// }
//
-//
-// Multicasting
+// # Multicasting
//
// The options for multicasting are available for net.UDPConn and
// net.IPConn which are created as network connections that use the
@@ -141,8 +139,7 @@
// }
// }
//
-//
-// More multicasting
+// # More multicasting
//
// An application that uses PacketConn or RawConn may join multiple
// multicast groups. For example, a UDP listener with port 1024 might
@@ -200,8 +197,7 @@
// // error handling
// }
//
-//
-// Source-specific multicasting
+// # Source-specific multicasting
//
// An application that uses PacketConn or RawConn on IGMPv3 supported
// platform is able to join source-specific multicast groups.
diff --git a/vendor/golang.org/x/net/ipv4/header.go b/vendor/golang.org/x/net/ipv4/header.go
index c271ca4..a00a3ea 100644
--- a/vendor/golang.org/x/net/ipv4/header.go
+++ b/vendor/golang.org/x/net/ipv4/header.go
@@ -67,7 +67,7 @@ func (h *Header) Marshal() ([]byte, error) {
b[1] = byte(h.TOS)
flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13)
switch runtime.GOOS {
- case "darwin", "dragonfly", "netbsd":
+ case "darwin", "ios", "dragonfly", "netbsd":
socket.NativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))
socket.NativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
case "freebsd":
@@ -126,7 +126,7 @@ func (h *Header) Parse(b []byte) error {
h.Src = net.IPv4(b[12], b[13], b[14], b[15])
h.Dst = net.IPv4(b[16], b[17], b[18], b[19])
switch runtime.GOOS {
- case "darwin", "dragonfly", "netbsd":
+ case "darwin", "ios", "dragonfly", "netbsd":
h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4])) + hdrlen
h.FragOff = int(socket.NativeEndian.Uint16(b[6:8]))
case "freebsd":
diff --git a/vendor/golang.org/x/net/ipv4/icmp_stub.go b/vendor/golang.org/x/net/ipv4/icmp_stub.go
index 21bb29a..cd4ee6e 100644
--- a/vendor/golang.org/x/net/ipv4/icmp_stub.go
+++ b/vendor/golang.org/x/net/ipv4/icmp_stub.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !linux
// +build !linux
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/payload_cmsg.go b/vendor/golang.org/x/net/ipv4/payload_cmsg.go
index e761466..1bb370e 100644
--- a/vendor/golang.org/x/net/ipv4/payload_cmsg.go
+++ b/vendor/golang.org/x/net/ipv4/payload_cmsg.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go
index 1116256..53f0794 100644
--- a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go
+++ b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_posix.go b/vendor/golang.org/x/net/ipv4/sockopt_posix.go
index dea6451..eb07c1c 100644
--- a/vendor/golang.org/x/net/ipv4/sockopt_posix.go
+++ b/vendor/golang.org/x/net/ipv4/sockopt_posix.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_stub.go
index 37d4806..cf03689 100644
--- a/vendor/golang.org/x/net/ipv4/sockopt_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sockopt_stub.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_aix.go b/vendor/golang.org/x/net/ipv4/sys_aix.go
index 3d1201e..02730cd 100644
--- a/vendor/golang.org/x/net/ipv4/sys_aix.go
+++ b/vendor/golang.org/x/net/ipv4/sys_aix.go
@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
// Added for go1.11 compatibility
+//go:build aix
// +build aix
package ipv4
@@ -13,26 +14,31 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
+// IP_RECVIF is defined on AIX but doesn't work. IP_RECVINTERFACE must be used instead.
+const sockoptReceiveInterface = unix.IP_RECVINTERFACE
+
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
- ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
- ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+ ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},
+ ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+ ctlInterface: {unix.IP_RECVINTERFACE, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
}
sockOpts = map[int]*sockOpt{
- ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
- ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
- ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 1}},
- ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
- ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
- ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
- ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVINTERFACE, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
}
)
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreq.go b/vendor/golang.org/x/net/ipv4/sys_asmreq.go
index 76d670a..22322b3 100644
--- a/vendor/golang.org/x/net/ipv4/sys_asmreq.go
+++ b/vendor/golang.org/x/net/ipv4/sys_asmreq.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || windows
// +build aix darwin dragonfly freebsd netbsd openbsd solaris windows
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go b/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go
index 6dc339c..fde6401 100644
--- a/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !aix && !darwin && !dragonfly && !freebsd && !netbsd && !openbsd && !solaris && !windows
// +build !aix,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!windows
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreqn.go b/vendor/golang.org/x/net/ipv4/sys_asmreqn.go
index 1f24f69..54eb990 100644
--- a/vendor/golang.org/x/net/ipv4/sys_asmreqn.go
+++ b/vendor/golang.org/x/net/ipv4/sys_asmreqn.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build darwin || freebsd || linux
// +build darwin freebsd linux
package ipv4
@@ -11,6 +12,8 @@ import (
"unsafe"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) {
@@ -18,7 +21,7 @@ func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) {
if _, err := so.Get(c, b); err != nil {
return nil, err
}
- mreqn := (*ipMreqn)(unsafe.Pointer(&b[0]))
+ mreqn := (*unix.IPMreqn)(unsafe.Pointer(&b[0]))
if mreqn.Ifindex == 0 {
return nil, nil
}
@@ -30,13 +33,13 @@ func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) {
}
func (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
- var mreqn ipMreqn
+ var mreqn unix.IPMreqn
if ifi != nil {
mreqn.Ifindex = int32(ifi.Index)
}
if grp != nil {
mreqn.Multiaddr = [4]byte{grp[0], grp[1], grp[2], grp[3]}
}
- b := (*[sizeofIPMreqn]byte)(unsafe.Pointer(&mreqn))[:sizeofIPMreqn]
+ b := (*[unix.SizeofIPMreqn]byte)(unsafe.Pointer(&mreqn))[:unix.SizeofIPMreqn]
return so.Set(c, b)
}
diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go b/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go
index 48ef556..dcb15f2 100644
--- a/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !darwin && !freebsd && !linux
// +build !darwin,!freebsd,!linux
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_bpf.go b/vendor/golang.org/x/net/ipv4/sys_bpf.go
index 5c03dce..fb11e32 100644
--- a/vendor/golang.org/x/net/ipv4/sys_bpf.go
+++ b/vendor/golang.org/x/net/ipv4/sys_bpf.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build linux
// +build linux
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go b/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go
index 5c98642..fc53a0d 100644
--- a/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !linux
// +build !linux
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_bsd.go b/vendor/golang.org/x/net/ipv4/sys_bsd.go
index 58256dd..e191b2f 100644
--- a/vendor/golang.org/x/net/ipv4/sys_bsd.go
+++ b/vendor/golang.org/x/net/ipv4/sys_bsd.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build netbsd || openbsd
// +build netbsd openbsd
package ipv4
@@ -12,26 +13,30 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
+const sockoptReceiveInterface = unix.IP_RECVIF
+
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
- ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
- ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+ ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},
+ ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+ ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
}
sockOpts = map[int]*sockOpt{
- ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
- ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
- ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 1}},
- ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
- ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
- ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
- ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
}
)
diff --git a/vendor/golang.org/x/net/ipv4/sys_darwin.go b/vendor/golang.org/x/net/ipv4/sys_darwin.go
index ac213c7..cac6f3c 100644
--- a/vendor/golang.org/x/net/ipv4/sys_darwin.go
+++ b/vendor/golang.org/x/net/ipv4/sys_darwin.go
@@ -11,34 +11,38 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
+const sockoptReceiveInterface = unix.IP_RECVIF
+
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
- ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
- ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
- ctlPacketInfo: {sysIP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},
+ ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+ ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+ ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
}
sockOpts = map[int]*sockOpt{
- ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
- ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
- ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
- ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
- ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
- ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
- ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
- ssoStripHeader: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_STRIPHDR, Len: 4}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVPKTINFO, Len: 4}},
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoStripHeader: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_STRIPHDR, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}},
}
)
diff --git a/vendor/golang.org/x/net/ipv4/sys_dragonfly.go b/vendor/golang.org/x/net/ipv4/sys_dragonfly.go
index 859764f..0620d0e 100644
--- a/vendor/golang.org/x/net/ipv4/sys_dragonfly.go
+++ b/vendor/golang.org/x/net/ipv4/sys_dragonfly.go
@@ -10,26 +10,30 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
+const sockoptReceiveInterface = unix.IP_RECVIF
+
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
- ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
- ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+ ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},
+ ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+ ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
}
sockOpts = map[int]*sockOpt{
- ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
- ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
- ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
- ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
- ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
- ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
- ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
}
)
diff --git a/vendor/golang.org/x/net/ipv4/sys_freebsd.go b/vendor/golang.org/x/net/ipv4/sys_freebsd.go
index 482873d..8961228 100644
--- a/vendor/golang.org/x/net/ipv4/sys_freebsd.go
+++ b/vendor/golang.org/x/net/ipv4/sys_freebsd.go
@@ -13,38 +13,42 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
+const sockoptReceiveInterface = unix.IP_RECVIF
+
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
- ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
- ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+ ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},
+ ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+ ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
}
sockOpts = map[int]*sockOpt{
- ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
- ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
- ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
- ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
- ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
- ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
- ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
}
)
func init() {
freebsdVersion, _ = syscall.SysctlUint32("kern.osreldate")
if freebsdVersion >= 1000000 {
- sockOpts[ssoMulticastInterface] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn}
+ sockOpts[ssoMulticastInterface] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn}
}
if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" {
archs, _ := syscall.Sysctl("kern.supported_archs")
diff --git a/vendor/golang.org/x/net/ipv4/sys_linux.go b/vendor/golang.org/x/net/ipv4/sys_linux.go
index cf755c7..4588a5f 100644
--- a/vendor/golang.org/x/net/ipv4/sys_linux.go
+++ b/vendor/golang.org/x/net/ipv4/sys_linux.go
@@ -11,31 +11,32 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
"golang.org/x/sys/unix"
)
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTTL: {sysIP_TTL, 1, marshalTTL, parseTTL},
- ctlPacketInfo: {sysIP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlTTL: {unix.IP_TTL, 1, marshalTTL, parseTTL},
+ ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
}
sockOpts = map[int]*sockOpt{
- ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
- ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
- ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 4}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
- ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
- ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_PKTINFO, Len: 4}},
- ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
- ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolReserved, Name: sysICMP_FILTER, Len: sizeofICMPFilter}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_PKTINFO, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolReserved, Name: unix.ICMP_FILTER, Len: sizeofICMPFilter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
ssoAttachFilter: {Option: socket.Option{Level: unix.SOL_SOCKET, Name: unix.SO_ATTACH_FILTER, Len: unix.SizeofSockFprog}},
}
)
diff --git a/vendor/golang.org/x/net/ipv4/sys_solaris.go b/vendor/golang.org/x/net/ipv4/sys_solaris.go
index 832fef1..0bb9f3e 100644
--- a/vendor/golang.org/x/net/ipv4/sys_solaris.go
+++ b/vendor/golang.org/x/net/ipv4/sys_solaris.go
@@ -11,29 +11,33 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
+const sockoptReceiveInterface = unix.IP_RECVIF
+
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTTL: {sysIP_RECVTTL, 4, marshalTTL, parseTTL},
- ctlPacketInfo: {sysIP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlTTL: {unix.IP_RECVTTL, 4, marshalTTL, parseTTL},
+ ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
}
sockOpts = map[int]sockOpt{
- ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
- ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
- ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 1}},
- ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
- ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVPKTINFO, Len: 4}},
- ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},
+ ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
}
)
diff --git a/vendor/golang.org/x/net/ipv4/sys_ssmreq.go b/vendor/golang.org/x/net/ipv4/sys_ssmreq.go
index eeced7f..6a4e7ab 100644
--- a/vendor/golang.org/x/net/ipv4/sys_ssmreq.go
+++ b/vendor/golang.org/x/net/ipv4/sys_ssmreq.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build darwin || freebsd || linux || solaris
// +build darwin freebsd linux solaris
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go b/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go
index c092167..157159f 100644
--- a/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !darwin && !freebsd && !linux && !solaris
// +build !darwin,!freebsd,!linux,!solaris
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_stub.go b/vendor/golang.org/x/net/ipv4/sys_stub.go
index b9c85b3..d550851 100644
--- a/vendor/golang.org/x/net/ipv4/sys_stub.go
+++ b/vendor/golang.org/x/net/ipv4/sys_stub.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4
diff --git a/vendor/golang.org/x/net/ipv4/sys_windows.go b/vendor/golang.org/x/net/ipv4/sys_windows.go
index b0913d5..c5e9506 100644
--- a/vendor/golang.org/x/net/ipv4/sys_windows.go
+++ b/vendor/golang.org/x/net/ipv4/sys_windows.go
@@ -7,34 +7,15 @@ package ipv4
import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/windows"
)
const (
- // See ws2tcpip.h.
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_MULTICAST_IF = 0x9
- sysIP_MULTICAST_TTL = 0xa
- sysIP_MULTICAST_LOOP = 0xb
- sysIP_ADD_MEMBERSHIP = 0xc
- sysIP_DROP_MEMBERSHIP = 0xd
- sysIP_DONTFRAGMENT = 0xe
- sysIP_ADD_SOURCE_MEMBERSHIP = 0xf
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x10
- sysIP_PKTINFO = 0x13
-
- sizeofInetPktinfo = 0x8
sizeofIPMreq = 0x8
sizeofIPMreqSource = 0xc
)
-type inetPktinfo struct {
- Addr [4]byte
- Ifindex int32
-}
-
type ipMreq struct {
Multiaddr [4]byte
Interface [4]byte
@@ -51,17 +32,13 @@ var (
ctlOpts = [ctlMax]ctlOpt{}
sockOpts = map[int]*sockOpt{
- ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
- ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
- ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 4}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
- ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_TTL, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_LOOP, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
}
)
-
-func (pi *inetPktinfo) setIfindex(i int) {
- pi.Ifindex = int32(i)
-}
diff --git a/vendor/golang.org/x/net/ipv4/sys_zos.go b/vendor/golang.org/x/net/ipv4/sys_zos.go
new file mode 100644
index 0000000..be20640
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv4/sys_zos.go
@@ -0,0 +1,57 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv4
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},
+ ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ }
+)
+
+func (pi *inetPktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet4)(unsafe.Pointer(&gr.Group))
+ sa.Family = syscall.AF_INET
+ sa.Len = sizeofSockaddrInet4
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet4)(unsafe.Pointer(&gsr.Group))
+ sa.Family = syscall.AF_INET
+ sa.Len = sizeofSockaddrInet4
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet4)(unsafe.Pointer(&gsr.Source))
+ sa.Family = syscall.AF_INET
+ sa.Len = sizeofSockaddrInet4
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go b/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go
index c741d5c..b7f2d6e 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go
@@ -2,28 +2,12 @@
// cgo -godefs defs_aix.go
// Added for go1.11 compatibility
+//go:build aix
// +build aix
package ipv4
const (
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_RECVOPTS = 0x5
- sysIP_RECVRETOPTS = 0x6
- sysIP_RECVDSTADDR = 0x7
- sysIP_RETOPTS = 0x8
- sysIP_RECVIF = 0x20
- sysIP_RECVTTL = 0x22
-
- sysIP_MULTICAST_IF = 0x9
- sysIP_MULTICAST_TTL = 0xa
- sysIP_MULTICAST_LOOP = 0xb
- sysIP_ADD_MEMBERSHIP = 0xc
- sysIP_DROP_MEMBERSHIP = 0xd
-
sizeofIPMreq = 0x8
)
diff --git a/vendor/golang.org/x/net/ipv4/zsys_darwin.go b/vendor/golang.org/x/net/ipv4/zsys_darwin.go
index e05a251..6c1b705 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_darwin.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_darwin.go
@@ -4,45 +4,11 @@
package ipv4
const (
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_RECVOPTS = 0x5
- sysIP_RECVRETOPTS = 0x6
- sysIP_RECVDSTADDR = 0x7
- sysIP_RETOPTS = 0x8
- sysIP_RECVIF = 0x14
- sysIP_STRIPHDR = 0x17
- sysIP_RECVTTL = 0x18
- sysIP_BOUND_IF = 0x19
- sysIP_PKTINFO = 0x1a
- sysIP_RECVPKTINFO = 0x1a
-
- sysIP_MULTICAST_IF = 0x9
- sysIP_MULTICAST_TTL = 0xa
- sysIP_MULTICAST_LOOP = 0xb
- sysIP_ADD_MEMBERSHIP = 0xc
- sysIP_DROP_MEMBERSHIP = 0xd
- sysIP_MULTICAST_VIF = 0xe
- sysIP_MULTICAST_IFINDEX = 0x42
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x46
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x47
- sysIP_BLOCK_SOURCE = 0x48
- sysIP_UNBLOCK_SOURCE = 0x49
- sysMCAST_JOIN_GROUP = 0x50
- sysMCAST_LEAVE_GROUP = 0x51
- sysMCAST_JOIN_SOURCE_GROUP = 0x52
- sysMCAST_LEAVE_SOURCE_GROUP = 0x53
- sysMCAST_BLOCK_SOURCE = 0x54
- sysMCAST_UNBLOCK_SOURCE = 0x55
-
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x84
sizeofGroupSourceReq = 0x104
@@ -75,12 +41,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr [4]byte /* in_addr */
Sourceaddr [4]byte /* in_addr */
diff --git a/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go b/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go
index 6d65e9f..2155df1 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go
@@ -4,24 +4,6 @@
package ipv4
const (
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_RECVOPTS = 0x5
- sysIP_RECVRETOPTS = 0x6
- sysIP_RECVDSTADDR = 0x7
- sysIP_RETOPTS = 0x8
- sysIP_RECVIF = 0x14
- sysIP_RECVTTL = 0x41
-
- sysIP_MULTICAST_IF = 0x9
- sysIP_MULTICAST_TTL = 0xa
- sysIP_MULTICAST_LOOP = 0xb
- sysIP_MULTICAST_VIF = 0xe
- sysIP_ADD_MEMBERSHIP = 0xc
- sysIP_DROP_MEMBERSHIP = 0xd
-
sizeofIPMreq = 0x8
)
diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go
index 136e2b8..ae40482 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go
@@ -4,45 +4,10 @@
package ipv4
const (
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_RECVOPTS = 0x5
- sysIP_RECVRETOPTS = 0x6
- sysIP_RECVDSTADDR = 0x7
- sysIP_SENDSRCADDR = 0x7
- sysIP_RETOPTS = 0x8
- sysIP_RECVIF = 0x14
- sysIP_ONESBCAST = 0x17
- sysIP_BINDANY = 0x18
- sysIP_RECVTTL = 0x41
- sysIP_MINTTL = 0x42
- sysIP_DONTFRAG = 0x43
- sysIP_RECVTOS = 0x44
-
- sysIP_MULTICAST_IF = 0x9
- sysIP_MULTICAST_TTL = 0xa
- sysIP_MULTICAST_LOOP = 0xb
- sysIP_ADD_MEMBERSHIP = 0xc
- sysIP_DROP_MEMBERSHIP = 0xd
- sysIP_MULTICAST_VIF = 0xe
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x46
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x47
- sysIP_BLOCK_SOURCE = 0x48
- sysIP_UNBLOCK_SOURCE = 0x49
- sysMCAST_JOIN_GROUP = 0x50
- sysMCAST_LEAVE_GROUP = 0x51
- sysMCAST_JOIN_SOURCE_GROUP = 0x52
- sysMCAST_LEAVE_SOURCE_GROUP = 0x53
- sysMCAST_BLOCK_SOURCE = 0x54
- sysMCAST_UNBLOCK_SOURCE = 0x55
-
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x84
sizeofGroupSourceReq = 0x104
@@ -69,12 +34,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr [4]byte /* in_addr */
Sourceaddr [4]byte /* in_addr */
diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go
index 4f730f1..9018186 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go
@@ -4,45 +4,10 @@
package ipv4
const (
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_RECVOPTS = 0x5
- sysIP_RECVRETOPTS = 0x6
- sysIP_RECVDSTADDR = 0x7
- sysIP_SENDSRCADDR = 0x7
- sysIP_RETOPTS = 0x8
- sysIP_RECVIF = 0x14
- sysIP_ONESBCAST = 0x17
- sysIP_BINDANY = 0x18
- sysIP_RECVTTL = 0x41
- sysIP_MINTTL = 0x42
- sysIP_DONTFRAG = 0x43
- sysIP_RECVTOS = 0x44
-
- sysIP_MULTICAST_IF = 0x9
- sysIP_MULTICAST_TTL = 0xa
- sysIP_MULTICAST_LOOP = 0xb
- sysIP_ADD_MEMBERSHIP = 0xc
- sysIP_DROP_MEMBERSHIP = 0xd
- sysIP_MULTICAST_VIF = 0xe
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x46
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x47
- sysIP_BLOCK_SOURCE = 0x48
- sysIP_UNBLOCK_SOURCE = 0x49
- sysMCAST_JOIN_GROUP = 0x50
- sysMCAST_LEAVE_GROUP = 0x51
- sysMCAST_JOIN_SOURCE_GROUP = 0x52
- sysMCAST_LEAVE_SOURCE_GROUP = 0x53
- sysMCAST_BLOCK_SOURCE = 0x54
- sysMCAST_UNBLOCK_SOURCE = 0x55
-
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
@@ -69,12 +34,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr [4]byte /* in_addr */
Sourceaddr [4]byte /* in_addr */
diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go
index 4f730f1..9018186 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go
@@ -4,45 +4,10 @@
package ipv4
const (
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_RECVOPTS = 0x5
- sysIP_RECVRETOPTS = 0x6
- sysIP_RECVDSTADDR = 0x7
- sysIP_SENDSRCADDR = 0x7
- sysIP_RETOPTS = 0x8
- sysIP_RECVIF = 0x14
- sysIP_ONESBCAST = 0x17
- sysIP_BINDANY = 0x18
- sysIP_RECVTTL = 0x41
- sysIP_MINTTL = 0x42
- sysIP_DONTFRAG = 0x43
- sysIP_RECVTOS = 0x44
-
- sysIP_MULTICAST_IF = 0x9
- sysIP_MULTICAST_TTL = 0xa
- sysIP_MULTICAST_LOOP = 0xb
- sysIP_ADD_MEMBERSHIP = 0xc
- sysIP_DROP_MEMBERSHIP = 0xd
- sysIP_MULTICAST_VIF = 0xe
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x46
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x47
- sysIP_BLOCK_SOURCE = 0x48
- sysIP_UNBLOCK_SOURCE = 0x49
- sysMCAST_JOIN_GROUP = 0x50
- sysMCAST_LEAVE_GROUP = 0x51
- sysMCAST_JOIN_SOURCE_GROUP = 0x52
- sysMCAST_LEAVE_SOURCE_GROUP = 0x53
- sysMCAST_BLOCK_SOURCE = 0x54
- sysMCAST_UNBLOCK_SOURCE = 0x55
-
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
@@ -69,12 +34,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr [4]byte /* in_addr */
Sourceaddr [4]byte /* in_addr */
diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go
index ecebf32..0feb9a7 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go
@@ -4,45 +4,10 @@
package ipv4
const (
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_RECVOPTS = 0x5
- sysIP_RECVRETOPTS = 0x6
- sysIP_RECVDSTADDR = 0x7
- sysIP_SENDSRCADDR = 0x7
- sysIP_RETOPTS = 0x8
- sysIP_RECVIF = 0x14
- sysIP_ONESBCAST = 0x17
- sysIP_BINDANY = 0x18
- sysIP_RECVTTL = 0x41
- sysIP_MINTTL = 0x42
- sysIP_DONTFRAG = 0x43
- sysIP_RECVTOS = 0x44
-
- sysIP_MULTICAST_IF = 0x9
- sysIP_MULTICAST_TTL = 0xa
- sysIP_MULTICAST_LOOP = 0xb
- sysIP_ADD_MEMBERSHIP = 0xc
- sysIP_DROP_MEMBERSHIP = 0xd
- sysIP_MULTICAST_VIF = 0xe
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x46
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x47
- sysIP_BLOCK_SOURCE = 0x48
- sysIP_UNBLOCK_SOURCE = 0x49
- sysMCAST_JOIN_GROUP = 0x50
- sysMCAST_LEAVE_GROUP = 0x51
- sysMCAST_JOIN_SOURCE_GROUP = 0x52
- sysMCAST_LEAVE_SOURCE_GROUP = 0x53
- sysMCAST_BLOCK_SOURCE = 0x54
- sysMCAST_UNBLOCK_SOURCE = 0x55
-
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
@@ -69,12 +34,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr [4]byte /* in_addr */
Sourceaddr [4]byte /* in_addr */
diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go
new file mode 100644
index 0000000..0feb9a7
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go
@@ -0,0 +1,52 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package ipv4
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]uint8
+ X__ss_align int64
+ X__ss_pad2 [112]uint8
+}
+
+type sockaddrInet struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]uint8
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr [4]byte /* in_addr */
+ Sourceaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type groupReq struct {
+ Interface uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_386.go b/vendor/golang.org/x/net/ipv4/zsys_linux_386.go
index 1c7fdfa..d510357 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_386.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_386.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x84
sizeofGroupSourceReq = 0x104
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go
index a04e785..eb10cc7 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go b/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go
index 1c7fdfa..d510357 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x84
sizeofGroupSourceReq = 0x104
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go
index a04e785..eb10cc7 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go
new file mode 100644
index 0000000..e15c22c
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go
@@ -0,0 +1,77 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+//go:build loong64
+// +build loong64
+
+package ipv4
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go
index 1c7fdfa..d510357 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x84
sizeofGroupSourceReq = 0x104
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go
index a04e785..eb10cc7 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go
index a04e785..eb10cc7 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go
index 1c7fdfa..d510357 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x84
sizeofGroupSourceReq = 0x104
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go
index 3c5ea54..29202e4 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x84
sizeofGroupSourceReq = 0x104
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go
index a04e785..eb10cc7 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go
index a04e785..eb10cc7 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go
index e626134..e2edebd 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go
@@ -1,69 +1,18 @@
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs defs_linux.go
+//go:build riscv64
// +build riscv64
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
@@ -104,12 +53,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go b/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go
index a04e785..eb10cc7 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go
@@ -4,64 +4,12 @@
package ipv4
const (
- sysIP_TOS = 0x1
- sysIP_TTL = 0x2
- sysIP_HDRINCL = 0x3
- sysIP_OPTIONS = 0x4
- sysIP_ROUTER_ALERT = 0x5
- sysIP_RECVOPTS = 0x6
- sysIP_RETOPTS = 0x7
- sysIP_PKTINFO = 0x8
- sysIP_PKTOPTIONS = 0x9
- sysIP_MTU_DISCOVER = 0xa
- sysIP_RECVERR = 0xb
- sysIP_RECVTTL = 0xc
- sysIP_RECVTOS = 0xd
- sysIP_MTU = 0xe
- sysIP_FREEBIND = 0xf
- sysIP_TRANSPARENT = 0x13
- sysIP_RECVRETOPTS = 0x7
- sysIP_ORIGDSTADDR = 0x14
- sysIP_RECVORIGDSTADDR = 0x14
- sysIP_MINTTL = 0x15
- sysIP_NODEFRAG = 0x16
- sysIP_UNICAST_IF = 0x32
-
- sysIP_MULTICAST_IF = 0x20
- sysIP_MULTICAST_TTL = 0x21
- sysIP_MULTICAST_LOOP = 0x22
- sysIP_ADD_MEMBERSHIP = 0x23
- sysIP_DROP_MEMBERSHIP = 0x24
- sysIP_UNBLOCK_SOURCE = 0x25
- sysIP_BLOCK_SOURCE = 0x26
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
- sysIP_MSFILTER = 0x29
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIP_MULTICAST_ALL = 0x31
-
- sysICMP_FILTER = 0x1
-
- sysSO_EE_ORIGIN_NONE = 0x0
- sysSO_EE_ORIGIN_LOCAL = 0x1
- sysSO_EE_ORIGIN_ICMP = 0x2
- sysSO_EE_ORIGIN_ICMP6 = 0x3
- sysSO_EE_ORIGIN_TXSTATUS = 0x4
- sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
- sizeofIPMreqn = 0xc
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
@@ -102,12 +50,6 @@ type ipMreq struct {
Interface [4]byte /* in_addr */
}
-type ipMreqn struct {
- Multiaddr [4]byte /* in_addr */
- Address [4]byte /* in_addr */
- Ifindex int32
-}
-
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
diff --git a/vendor/golang.org/x/net/ipv4/zsys_netbsd.go b/vendor/golang.org/x/net/ipv4/zsys_netbsd.go
index 8cfc648..a2ef2f6 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_netbsd.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_netbsd.go
@@ -4,23 +4,6 @@
package ipv4
const (
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_RECVOPTS = 0x5
- sysIP_RECVRETOPTS = 0x6
- sysIP_RECVDSTADDR = 0x7
- sysIP_RETOPTS = 0x8
- sysIP_RECVIF = 0x14
- sysIP_RECVTTL = 0x17
-
- sysIP_MULTICAST_IF = 0x9
- sysIP_MULTICAST_TTL = 0xa
- sysIP_MULTICAST_LOOP = 0xb
- sysIP_ADD_MEMBERSHIP = 0xc
- sysIP_DROP_MEMBERSHIP = 0xd
-
sizeofIPMreq = 0x8
)
diff --git a/vendor/golang.org/x/net/ipv4/zsys_openbsd.go b/vendor/golang.org/x/net/ipv4/zsys_openbsd.go
index 37629cb..b293a33 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_openbsd.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_openbsd.go
@@ -4,23 +4,6 @@
package ipv4
const (
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_RECVOPTS = 0x5
- sysIP_RECVRETOPTS = 0x6
- sysIP_RECVDSTADDR = 0x7
- sysIP_RETOPTS = 0x8
- sysIP_RECVIF = 0x1e
- sysIP_RECVTTL = 0x1f
-
- sysIP_MULTICAST_IF = 0x9
- sysIP_MULTICAST_TTL = 0xa
- sysIP_MULTICAST_LOOP = 0xb
- sysIP_ADD_MEMBERSHIP = 0xc
- sysIP_DROP_MEMBERSHIP = 0xd
-
sizeofIPMreq = 0x8
)
diff --git a/vendor/golang.org/x/net/ipv4/zsys_solaris.go b/vendor/golang.org/x/net/ipv4/zsys_solaris.go
index cb80a30..e1a961b 100644
--- a/vendor/golang.org/x/net/ipv4/zsys_solaris.go
+++ b/vendor/golang.org/x/net/ipv4/zsys_solaris.go
@@ -4,49 +4,6 @@
package ipv4
const (
- sysIP_OPTIONS = 0x1
- sysIP_HDRINCL = 0x2
- sysIP_TOS = 0x3
- sysIP_TTL = 0x4
- sysIP_RECVOPTS = 0x5
- sysIP_RECVRETOPTS = 0x6
- sysIP_RECVDSTADDR = 0x7
- sysIP_RETOPTS = 0x8
- sysIP_RECVIF = 0x9
- sysIP_RECVSLLA = 0xa
- sysIP_RECVTTL = 0xb
-
- sysIP_MULTICAST_IF = 0x10
- sysIP_MULTICAST_TTL = 0x11
- sysIP_MULTICAST_LOOP = 0x12
- sysIP_ADD_MEMBERSHIP = 0x13
- sysIP_DROP_MEMBERSHIP = 0x14
- sysIP_BLOCK_SOURCE = 0x15
- sysIP_UNBLOCK_SOURCE = 0x16
- sysIP_ADD_SOURCE_MEMBERSHIP = 0x17
- sysIP_DROP_SOURCE_MEMBERSHIP = 0x18
- sysIP_NEXTHOP = 0x19
-
- sysIP_PKTINFO = 0x1a
- sysIP_RECVPKTINFO = 0x1a
- sysIP_DONTFRAG = 0x1b
-
- sysIP_BOUND_IF = 0x41
- sysIP_UNSPEC_SRC = 0x42
- sysIP_BROADCAST_TTL = 0x43
- sysIP_DHCPINIT_IF = 0x45
-
- sysIP_REUSEADDR = 0x104
- sysIP_DONTROUTE = 0x105
- sysIP_BROADCAST = 0x106
-
- sysMCAST_JOIN_GROUP = 0x29
- sysMCAST_LEAVE_GROUP = 0x2a
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_JOIN_SOURCE_GROUP = 0x2d
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2e
-
sizeofSockaddrStorage = 0x100
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
diff --git a/vendor/golang.org/x/net/ipv4/zsys_zos_s390x.go b/vendor/golang.org/x/net/ipv4/zsys_zos_s390x.go
new file mode 100644
index 0000000..692abf6
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv4/zsys_zos_s390x.go
@@ -0,0 +1,56 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Hand edited based on zerrors_zos_s390x.go
+// TODO(Bill O'Farrell): auto-generate.
+
+package ipv4
+
+const (
+ sizeofIPMreq = 8
+ sizeofSockaddrInet4 = 16
+ sizeofSockaddrStorage = 128
+ sizeofGroupReq = 136
+ sizeofGroupSourceReq = 264
+ sizeofInetPktinfo = 8
+)
+
+type sockaddrInet4 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte
+ Zero [8]uint8
+}
+
+type inetPktinfo struct {
+ Addr [4]byte
+ Ifindex uint32
+}
+
+type sockaddrStorage struct {
+ Len uint8
+ Family byte
+ ss_pad1 [6]byte
+ ss_align int64
+ ss_pad2 [112]byte
+}
+
+type groupReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
diff --git a/vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go b/vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go
index 9fd9eb1..2733ddb 100644
--- a/vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go
+++ b/vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build darwin
// +build darwin
package ipv6
@@ -11,11 +12,13 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
func marshal2292HopLimit(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_2292HOPLIMIT, 4)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_2292HOPLIMIT, 4)
if cm != nil {
socket.NativeEndian.PutUint32(m.Data(4), uint32(cm.HopLimit))
}
@@ -24,7 +27,7 @@ func marshal2292HopLimit(b []byte, cm *ControlMessage) []byte {
func marshal2292PacketInfo(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_2292PKTINFO, sizeofInet6Pktinfo)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_2292PKTINFO, sizeofInet6Pktinfo)
if cm != nil {
pi := (*inet6Pktinfo)(unsafe.Pointer(&m.Data(sizeofInet6Pktinfo)[0]))
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
@@ -39,7 +42,7 @@ func marshal2292PacketInfo(b []byte, cm *ControlMessage) []byte {
func marshal2292NextHop(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_2292NEXTHOP, sizeofSockaddrInet6)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_2292NEXTHOP, sizeofSockaddrInet6)
if cm != nil {
sa := (*sockaddrInet6)(unsafe.Pointer(&m.Data(sizeofSockaddrInet6)[0]))
sa.setSockaddr(cm.NextHop, cm.IfIndex)
diff --git a/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go b/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go
index 8c221b5..9c90844 100644
--- a/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go
+++ b/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv6
@@ -12,11 +13,13 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
func marshalTrafficClass(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_TCLASS, 4)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_TCLASS, 4)
if cm != nil {
socket.NativeEndian.PutUint32(m.Data(4), uint32(cm.TrafficClass))
}
@@ -29,7 +32,7 @@ func parseTrafficClass(cm *ControlMessage, b []byte) {
func marshalHopLimit(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_HOPLIMIT, 4)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_HOPLIMIT, 4)
if cm != nil {
socket.NativeEndian.PutUint32(m.Data(4), uint32(cm.HopLimit))
}
@@ -42,7 +45,7 @@ func parseHopLimit(cm *ControlMessage, b []byte) {
func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_PKTINFO, sizeofInet6Pktinfo)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_PKTINFO, sizeofInet6Pktinfo)
if cm != nil {
pi := (*inet6Pktinfo)(unsafe.Pointer(&m.Data(sizeofInet6Pktinfo)[0]))
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
@@ -66,7 +69,7 @@ func parsePacketInfo(cm *ControlMessage, b []byte) {
func marshalNextHop(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_NEXTHOP, sizeofSockaddrInet6)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_NEXTHOP, sizeofSockaddrInet6)
if cm != nil {
sa := (*sockaddrInet6)(unsafe.Pointer(&m.Data(sizeofSockaddrInet6)[0]))
sa.setSockaddr(cm.NextHop, cm.IfIndex)
@@ -79,7 +82,7 @@ func parseNextHop(cm *ControlMessage, b []byte) {
func marshalPathMTU(b []byte, cm *ControlMessage) []byte {
m := socket.ControlMessage(b)
- m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_PATHMTU, sizeofIPv6Mtuinfo)
+ m.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo)
return m.Next(sizeofIPv6Mtuinfo)
}
diff --git a/vendor/golang.org/x/net/ipv6/control_stub.go b/vendor/golang.org/x/net/ipv6/control_stub.go
index 1d773cb..b7e8643 100644
--- a/vendor/golang.org/x/net/ipv6/control_stub.go
+++ b/vendor/golang.org/x/net/ipv6/control_stub.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/control_unix.go b/vendor/golang.org/x/net/ipv6/control_unix.go
index 0971a00..63e475d 100644
--- a/vendor/golang.org/x/net/ipv6/control_unix.go
+++ b/vendor/golang.org/x/net/ipv6/control_unix.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/dgramopt.go b/vendor/golang.org/x/net/ipv6/dgramopt.go
index 1f422e7..846f0e1 100644
--- a/vendor/golang.org/x/net/ipv6/dgramopt.go
+++ b/vendor/golang.org/x/net/ipv6/dgramopt.go
@@ -245,7 +245,7 @@ func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
return true, offset, nil
}
-// SetChecksum enables the kernel checksum processing. If on is ture,
+// SetChecksum enables the kernel checksum processing. If on is true,
// the offset should be an offset in bytes into the data of where the
// checksum field is located.
func (c *dgramOpt) SetChecksum(on bool, offset int) error {
diff --git a/vendor/golang.org/x/net/ipv6/doc.go b/vendor/golang.org/x/net/ipv6/doc.go
index e0be9d5..2148b81 100644
--- a/vendor/golang.org/x/net/ipv6/doc.go
+++ b/vendor/golang.org/x/net/ipv6/doc.go
@@ -17,8 +17,7 @@
// On Darwin, this package requires OS X Mavericks version 10.9 or
// above, or equivalent.
//
-//
-// Unicasting
+// # Unicasting
//
// The options for unicasting are available for net.TCPConn,
// net.UDPConn and net.IPConn which are created as network connections
@@ -52,8 +51,7 @@
// }(c)
// }
//
-//
-// Multicasting
+// # Multicasting
//
// The options for multicasting are available for net.UDPConn and
// net.IPConn which are created as network connections that use the
@@ -140,8 +138,7 @@
// }
// }
//
-//
-// More multicasting
+// # More multicasting
//
// An application that uses PacketConn may join multiple multicast
// groups. For example, a UDP listener with port 1024 might join two
@@ -199,8 +196,7 @@
// // error handling
// }
//
-//
-// Source-specific multicasting
+// # Source-specific multicasting
//
// An application that uses PacketConn on MLDv2 supported platform is
// able to join source-specific multicast groups.
diff --git a/vendor/golang.org/x/net/ipv6/icmp_bsd.go b/vendor/golang.org/x/net/ipv6/icmp_bsd.go
index b03025c..120bf87 100644
--- a/vendor/golang.org/x/net/ipv6/icmp_bsd.go
+++ b/vendor/golang.org/x/net/ipv6/icmp_bsd.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
// +build aix darwin dragonfly freebsd netbsd openbsd
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/icmp_stub.go b/vendor/golang.org/x/net/ipv6/icmp_stub.go
index 370e51a..d60136a 100644
--- a/vendor/golang.org/x/net/ipv6/icmp_stub.go
+++ b/vendor/golang.org/x/net/ipv6/icmp_stub.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/icmp_zos.go b/vendor/golang.org/x/net/ipv6/icmp_zos.go
new file mode 100644
index 0000000..ddf8f09
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv6/icmp_zos.go
@@ -0,0 +1,29 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+func (f *icmpv6Filter) accept(typ ICMPType) {
+ f.Filt[typ>>5] |= 1 << (uint32(typ) & 31)
+
+}
+
+func (f *icmpv6Filter) block(typ ICMPType) {
+ f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)
+
+}
+
+func (f *icmpv6Filter) setAll(block bool) {
+ for i := range f.Filt {
+ if block {
+ f.Filt[i] = 0
+ } else {
+ f.Filt[i] = 1<<32 - 1
+ }
+ }
+}
+
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
+ return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
+}
diff --git a/vendor/golang.org/x/net/ipv6/payload_cmsg.go b/vendor/golang.org/x/net/ipv6/payload_cmsg.go
index 284a042..b0692e4 100644
--- a/vendor/golang.org/x/net/ipv6/payload_cmsg.go
+++ b/vendor/golang.org/x/net/ipv6/payload_cmsg.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/payload_nocmsg.go b/vendor/golang.org/x/net/ipv6/payload_nocmsg.go
index c5a4c96..cd0ff50 100644
--- a/vendor/golang.org/x/net/ipv6/payload_nocmsg.go
+++ b/vendor/golang.org/x/net/ipv6/payload_nocmsg.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_posix.go b/vendor/golang.org/x/net/ipv6/sockopt_posix.go
index 824c623..37c6287 100644
--- a/vendor/golang.org/x/net/ipv6/sockopt_posix.go
+++ b/vendor/golang.org/x/net/ipv6/sockopt_posix.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_stub.go b/vendor/golang.org/x/net/ipv6/sockopt_stub.go
index 0a87a93..32fd866 100644
--- a/vendor/golang.org/x/net/ipv6/sockopt_stub.go
+++ b/vendor/golang.org/x/net/ipv6/sockopt_stub.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_aix.go b/vendor/golang.org/x/net/ipv6/sys_aix.go
index bce7091..a47182a 100644
--- a/vendor/golang.org/x/net/ipv6/sys_aix.go
+++ b/vendor/golang.org/x/net/ipv6/sys_aix.go
@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
// Added for go1.11 compatibility
+//go:build aix
// +build aix
package ipv6
@@ -14,32 +15,34 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
- ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
- ctlPacketInfo: {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
- ctlNextHop: {sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
- ctlPathMTU: {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlNextHop: {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
}
sockOpts = map[int]*sockOpt{
- ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}},
- ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
- ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
- ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}},
- ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}},
- ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}},
- ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}},
- ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
- ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}},
- ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
}
)
diff --git a/vendor/golang.org/x/net/ipv6/sys_asmreq.go b/vendor/golang.org/x/net/ipv6/sys_asmreq.go
index 8c3934c..6ff9950 100644
--- a/vendor/golang.org/x/net/ipv6/sys_asmreq.go
+++ b/vendor/golang.org/x/net/ipv6/sys_asmreq.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go b/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go
index 87ae481..485290c 100644
--- a/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go
+++ b/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_bpf.go b/vendor/golang.org/x/net/ipv6/sys_bpf.go
index 90ef4df..b5661fb 100644
--- a/vendor/golang.org/x/net/ipv6/sys_bpf.go
+++ b/vendor/golang.org/x/net/ipv6/sys_bpf.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build linux
// +build linux
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go b/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go
index eb9f831..cb00661 100644
--- a/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go
+++ b/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !linux
// +build !linux
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_bsd.go b/vendor/golang.org/x/net/ipv6/sys_bsd.go
index e416eaa..bde41a6 100644
--- a/vendor/golang.org/x/net/ipv6/sys_bsd.go
+++ b/vendor/golang.org/x/net/ipv6/sys_bsd.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build dragonfly || netbsd || openbsd
// +build dragonfly netbsd openbsd
package ipv6
@@ -12,32 +13,34 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
- ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
- ctlPacketInfo: {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
- ctlNextHop: {sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
- ctlPathMTU: {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlNextHop: {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
}
sockOpts = map[int]*sockOpt{
- ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}},
- ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
- ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
- ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}},
- ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}},
- ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}},
- ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}},
- ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
- ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}},
- ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
}
)
diff --git a/vendor/golang.org/x/net/ipv6/sys_darwin.go b/vendor/golang.org/x/net/ipv6/sys_darwin.go
index 12cc5cb..b80ec80 100644
--- a/vendor/golang.org/x/net/ipv6/sys_darwin.go
+++ b/vendor/golang.org/x/net/ipv6/sys_darwin.go
@@ -11,36 +11,38 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
- ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
- ctlPacketInfo: {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
- ctlNextHop: {sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
- ctlPathMTU: {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlNextHop: {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
}
sockOpts = map[int]*sockOpt{
- ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
- ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
- ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}},
- ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}},
- ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}},
- ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}},
- ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}},
- ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
- ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}},
- ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
}
)
diff --git a/vendor/golang.org/x/net/ipv6/sys_freebsd.go b/vendor/golang.org/x/net/ipv6/sys_freebsd.go
index 85a9f5d..6282cf9 100644
--- a/vendor/golang.org/x/net/ipv6/sys_freebsd.go
+++ b/vendor/golang.org/x/net/ipv6/sys_freebsd.go
@@ -13,36 +13,38 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
- ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
- ctlPacketInfo: {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
- ctlNextHop: {sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
- ctlPathMTU: {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlNextHop: {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
}
sockOpts = map[int]sockOpt{
- ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}},
- ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
- ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
- ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}},
- ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}},
- ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}},
- ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}},
- ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
- ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}},
- ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
}
)
diff --git a/vendor/golang.org/x/net/ipv6/sys_linux.go b/vendor/golang.org/x/net/ipv6/sys_linux.go
index 96e8093..82e2121 100644
--- a/vendor/golang.org/x/net/ipv6/sys_linux.go
+++ b/vendor/golang.org/x/net/ipv6/sys_linux.go
@@ -11,36 +11,37 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
"golang.org/x/sys/unix"
)
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
- ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
- ctlPacketInfo: {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
- ctlPathMTU: {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
}
sockOpts = map[int]*sockOpt{
- ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}},
- ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
- ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
- ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}},
- ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}},
- ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}},
- ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}},
- ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
- ssoChecksum: {Option: socket.Option{Level: iana.ProtocolReserved, Name: sysIPV6_CHECKSUM, Len: 4}},
- ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMPV6_FILTER, Len: sizeofICMPv6Filter}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolReserved, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMPV6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
ssoAttachFilter: {Option: socket.Option{Level: unix.SOL_SOCKET, Name: unix.SO_ATTACH_FILTER, Len: unix.SizeofSockFprog}},
}
)
diff --git a/vendor/golang.org/x/net/ipv6/sys_solaris.go b/vendor/golang.org/x/net/ipv6/sys_solaris.go
index d348b5f..1fc30ad 100644
--- a/vendor/golang.org/x/net/ipv6/sys_solaris.go
+++ b/vendor/golang.org/x/net/ipv6/sys_solaris.go
@@ -11,36 +11,38 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
)
var (
ctlOpts = [ctlMax]ctlOpt{
- ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
- ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
- ctlPacketInfo: {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
- ctlNextHop: {sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
- ctlPathMTU: {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ ctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlNextHop: {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
}
sockOpts = map[int]*sockOpt{
- ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}},
- ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
- ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
- ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}},
- ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}},
- ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}},
- ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}},
- ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
- ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}},
- ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
- ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
- ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoPathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
}
)
diff --git a/vendor/golang.org/x/net/ipv6/sys_ssmreq.go b/vendor/golang.org/x/net/ipv6/sys_ssmreq.go
index 9b52e97..023488a 100644
--- a/vendor/golang.org/x/net/ipv6/sys_ssmreq.go
+++ b/vendor/golang.org/x/net/ipv6/sys_ssmreq.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin freebsd linux solaris
+//go:build aix || darwin || freebsd || linux || solaris || zos
+// +build aix darwin freebsd linux solaris zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go b/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go
index d5bc110..acdf2e5 100644
--- a/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go
+++ b/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!freebsd,!linux,!solaris
+//go:build !aix && !darwin && !freebsd && !linux && !solaris && !zos
+// +build !aix,!darwin,!freebsd,!linux,!solaris,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_stub.go b/vendor/golang.org/x/net/ipv6/sys_stub.go
index 4f252d0..5807bba 100644
--- a/vendor/golang.org/x/net/ipv6/sys_stub.go
+++ b/vendor/golang.org/x/net/ipv6/sys_stub.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/sys_windows.go b/vendor/golang.org/x/net/ipv6/sys_windows.go
index fc36b01..fda8a29 100644
--- a/vendor/golang.org/x/net/ipv6/sys_windows.go
+++ b/vendor/golang.org/x/net/ipv6/sys_windows.go
@@ -10,18 +10,11 @@ import (
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/windows"
)
const (
- // See ws2tcpip.h.
- sysIPV6_UNICAST_HOPS = 0x4
- sysIPV6_MULTICAST_IF = 0x9
- sysIPV6_MULTICAST_HOPS = 0xa
- sysIPV6_MULTICAST_LOOP = 0xb
- sysIPV6_JOIN_GROUP = 0xc
- sysIPV6_LEAVE_GROUP = 0xd
- sysIPV6_PKTINFO = 0x13
-
sizeofSockaddrInet6 = 0x1c
sizeofIPv6Mreq = 0x14
@@ -55,12 +48,12 @@ var (
ctlOpts = [ctlMax]ctlOpt{}
sockOpts = map[int]*sockOpt{
- ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
- ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
- ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
- ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
- ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
- ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
}
)
diff --git a/vendor/golang.org/x/net/ipv6/sys_zos.go b/vendor/golang.org/x/net/ipv6/sys_zos.go
new file mode 100644
index 0000000..31adc86
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv6/sys_zos.go
@@ -0,0 +1,72 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+ "net"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+
+ "golang.org/x/sys/unix"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlHopLimit: {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
+ ctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+ ctlPathMTU: {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},
+ ssoHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},
+ ssoMulticastHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},
+ ssoReceiveHopLimit: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},
+ ssoReceivePacketInfo: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},
+ ssoReceivePathMTU: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},
+ ssoChecksum: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ }
+)
+
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+ sa.Family = syscall.AF_INET6
+ copy(sa.Addr[:], ip)
+ sa.Scope_id = uint32(i)
+}
+
+func (pi *inet6Pktinfo) setIfindex(i int) {
+ pi.Ifindex = uint32(i)
+}
+
+func (gr *groupReq) setGroup(grp net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&gr.Group))
+ sa.Family = syscall.AF_INET6
+ sa.Len = sizeofSockaddrInet6
+ copy(sa.Addr[:], grp)
+}
+
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+ sa := (*sockaddrInet6)(unsafe.Pointer(&gsr.Group))
+ sa.Family = syscall.AF_INET6
+ sa.Len = sizeofSockaddrInet6
+ copy(sa.Addr[:], grp)
+ sa = (*sockaddrInet6)(unsafe.Pointer(&gsr.Source))
+ sa.Family = syscall.AF_INET6
+ sa.Len = sizeofSockaddrInet6
+ copy(sa.Addr[:], src)
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go b/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go
index bf44e33..f604b0f 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go
@@ -2,46 +2,12 @@
// cgo -godefs defs_aix.go
// Added for go1.11 compatibility
+//go:build aix
// +build aix
package ipv6
const (
- sysIPV6_UNICAST_HOPS = 0x4
- sysIPV6_MULTICAST_IF = 0x9
- sysIPV6_MULTICAST_HOPS = 0xa
- sysIPV6_MULTICAST_LOOP = 0xb
- sysIPV6_JOIN_GROUP = 0xc
- sysIPV6_LEAVE_GROUP = 0xd
- sysICMP6_FILTER = 0x26
-
- sysIPV6_CHECKSUM = 0x27
- sysIPV6_V6ONLY = 0x25
-
- sysIPV6_RTHDRDSTOPTS = 0x37
-
- sysIPV6_RECVPKTINFO = 0x23
- sysIPV6_RECVHOPLIMIT = 0x29
- sysIPV6_RECVRTHDR = 0x33
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_RECVDSTOPTS = 0x38
-
- sysIPV6_USE_MIN_MTU = 0x2c
- sysIPV6_RECVPATHMTU = 0x2f
- sysIPV6_PATHMTU = 0x2e
-
- sysIPV6_PKTINFO = 0x21
- sysIPV6_HOPLIMIT = 0x28
- sysIPV6_NEXTHOP = 0x30
- sysIPV6_HOPOPTS = 0x34
- sysIPV6_DSTOPTS = 0x36
- sysIPV6_RTHDR = 0x32
-
- sysIPV6_RECVTCLASS = 0x2a
-
- sysIPV6_TCLASS = 0x2b
- sysIPV6_DONTFRAG = 0x2d
-
sizeofSockaddrStorage = 0x508
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_darwin.go b/vendor/golang.org/x/net/ipv6/zsys_darwin.go
index 555744a..dd6f7b2 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_darwin.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_darwin.go
@@ -4,73 +4,6 @@
package ipv6
const (
- sysIPV6_UNICAST_HOPS = 0x4
- sysIPV6_MULTICAST_IF = 0x9
- sysIPV6_MULTICAST_HOPS = 0xa
- sysIPV6_MULTICAST_LOOP = 0xb
- sysIPV6_JOIN_GROUP = 0xc
- sysIPV6_LEAVE_GROUP = 0xd
-
- sysIPV6_PORTRANGE = 0xe
- sysICMP6_FILTER = 0x12
- sysIPV6_2292PKTINFO = 0x13
- sysIPV6_2292HOPLIMIT = 0x14
- sysIPV6_2292NEXTHOP = 0x15
- sysIPV6_2292HOPOPTS = 0x16
- sysIPV6_2292DSTOPTS = 0x17
- sysIPV6_2292RTHDR = 0x18
-
- sysIPV6_2292PKTOPTIONS = 0x19
-
- sysIPV6_CHECKSUM = 0x1a
- sysIPV6_V6ONLY = 0x1b
-
- sysIPV6_IPSEC_POLICY = 0x1c
-
- sysIPV6_RECVTCLASS = 0x23
- sysIPV6_TCLASS = 0x24
-
- sysIPV6_RTHDRDSTOPTS = 0x39
-
- sysIPV6_RECVPKTINFO = 0x3d
-
- sysIPV6_RECVHOPLIMIT = 0x25
- sysIPV6_RECVRTHDR = 0x26
- sysIPV6_RECVHOPOPTS = 0x27
- sysIPV6_RECVDSTOPTS = 0x28
-
- sysIPV6_USE_MIN_MTU = 0x2a
- sysIPV6_RECVPATHMTU = 0x2b
-
- sysIPV6_PATHMTU = 0x2c
-
- sysIPV6_PKTINFO = 0x2e
- sysIPV6_HOPLIMIT = 0x2f
- sysIPV6_NEXTHOP = 0x30
- sysIPV6_HOPOPTS = 0x31
- sysIPV6_DSTOPTS = 0x32
- sysIPV6_RTHDR = 0x33
-
- sysIPV6_AUTOFLOWLABEL = 0x3b
-
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_PREFER_TEMPADDR = 0x3f
-
- sysIPV6_MSFILTER = 0x4a
- sysMCAST_JOIN_GROUP = 0x50
- sysMCAST_LEAVE_GROUP = 0x51
- sysMCAST_JOIN_SOURCE_GROUP = 0x52
- sysMCAST_LEAVE_SOURCE_GROUP = 0x53
- sysMCAST_BLOCK_SOURCE = 0x54
- sysMCAST_UNBLOCK_SOURCE = 0x55
-
- sysIPV6_BOUND_IF = 0x7d
-
- sysIPV6_PORTRANGE_DEFAULT = 0x0
- sysIPV6_PORTRANGE_HIGH = 0x1
- sysIPV6_PORTRANGE_LOW = 0x2
-
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_dragonfly.go b/vendor/golang.org/x/net/ipv6/zsys_dragonfly.go
index cf3cc10..6b45a94 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_dragonfly.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_dragonfly.go
@@ -4,52 +4,6 @@
package ipv6
const (
- sysIPV6_UNICAST_HOPS = 0x4
- sysIPV6_MULTICAST_IF = 0x9
- sysIPV6_MULTICAST_HOPS = 0xa
- sysIPV6_MULTICAST_LOOP = 0xb
- sysIPV6_JOIN_GROUP = 0xc
- sysIPV6_LEAVE_GROUP = 0xd
- sysIPV6_PORTRANGE = 0xe
- sysICMP6_FILTER = 0x12
-
- sysIPV6_CHECKSUM = 0x1a
- sysIPV6_V6ONLY = 0x1b
-
- sysIPV6_IPSEC_POLICY = 0x1c
-
- sysIPV6_RTHDRDSTOPTS = 0x23
- sysIPV6_RECVPKTINFO = 0x24
- sysIPV6_RECVHOPLIMIT = 0x25
- sysIPV6_RECVRTHDR = 0x26
- sysIPV6_RECVHOPOPTS = 0x27
- sysIPV6_RECVDSTOPTS = 0x28
-
- sysIPV6_USE_MIN_MTU = 0x2a
- sysIPV6_RECVPATHMTU = 0x2b
-
- sysIPV6_PATHMTU = 0x2c
-
- sysIPV6_PKTINFO = 0x2e
- sysIPV6_HOPLIMIT = 0x2f
- sysIPV6_NEXTHOP = 0x30
- sysIPV6_HOPOPTS = 0x31
- sysIPV6_DSTOPTS = 0x32
- sysIPV6_RTHDR = 0x33
-
- sysIPV6_RECVTCLASS = 0x39
-
- sysIPV6_AUTOFLOWLABEL = 0x3b
-
- sysIPV6_TCLASS = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_PREFER_TEMPADDR = 0x3f
-
- sysIPV6_PORTRANGE_DEFAULT = 0x0
- sysIPV6_PORTRANGE_HIGH = 0x1
- sysIPV6_PORTRANGE_LOW = 0x2
-
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
sizeofIPv6Mtuinfo = 0x20
diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go
index 73f31b2..8da5592 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go
@@ -4,64 +4,6 @@
package ipv6
const (
- sysIPV6_UNICAST_HOPS = 0x4
- sysIPV6_MULTICAST_IF = 0x9
- sysIPV6_MULTICAST_HOPS = 0xa
- sysIPV6_MULTICAST_LOOP = 0xb
- sysIPV6_JOIN_GROUP = 0xc
- sysIPV6_LEAVE_GROUP = 0xd
- sysIPV6_PORTRANGE = 0xe
- sysICMP6_FILTER = 0x12
-
- sysIPV6_CHECKSUM = 0x1a
- sysIPV6_V6ONLY = 0x1b
-
- sysIPV6_IPSEC_POLICY = 0x1c
-
- sysIPV6_RTHDRDSTOPTS = 0x23
-
- sysIPV6_RECVPKTINFO = 0x24
- sysIPV6_RECVHOPLIMIT = 0x25
- sysIPV6_RECVRTHDR = 0x26
- sysIPV6_RECVHOPOPTS = 0x27
- sysIPV6_RECVDSTOPTS = 0x28
-
- sysIPV6_USE_MIN_MTU = 0x2a
- sysIPV6_RECVPATHMTU = 0x2b
-
- sysIPV6_PATHMTU = 0x2c
-
- sysIPV6_PKTINFO = 0x2e
- sysIPV6_HOPLIMIT = 0x2f
- sysIPV6_NEXTHOP = 0x30
- sysIPV6_HOPOPTS = 0x31
- sysIPV6_DSTOPTS = 0x32
- sysIPV6_RTHDR = 0x33
-
- sysIPV6_RECVTCLASS = 0x39
-
- sysIPV6_AUTOFLOWLABEL = 0x3b
-
- sysIPV6_TCLASS = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_PREFER_TEMPADDR = 0x3f
-
- sysIPV6_BINDANY = 0x40
-
- sysIPV6_MSFILTER = 0x4a
-
- sysMCAST_JOIN_GROUP = 0x50
- sysMCAST_LEAVE_GROUP = 0x51
- sysMCAST_JOIN_SOURCE_GROUP = 0x52
- sysMCAST_LEAVE_SOURCE_GROUP = 0x53
- sysMCAST_BLOCK_SOURCE = 0x54
- sysMCAST_UNBLOCK_SOURCE = 0x55
-
- sysIPV6_PORTRANGE_DEFAULT = 0x0
- sysIPV6_PORTRANGE_HIGH = 0x1
- sysIPV6_PORTRANGE_LOW = 0x2
-
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go
index 490ce7c..72a1a65 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go
@@ -4,64 +4,6 @@
package ipv6
const (
- sysIPV6_UNICAST_HOPS = 0x4
- sysIPV6_MULTICAST_IF = 0x9
- sysIPV6_MULTICAST_HOPS = 0xa
- sysIPV6_MULTICAST_LOOP = 0xb
- sysIPV6_JOIN_GROUP = 0xc
- sysIPV6_LEAVE_GROUP = 0xd
- sysIPV6_PORTRANGE = 0xe
- sysICMP6_FILTER = 0x12
-
- sysIPV6_CHECKSUM = 0x1a
- sysIPV6_V6ONLY = 0x1b
-
- sysIPV6_IPSEC_POLICY = 0x1c
-
- sysIPV6_RTHDRDSTOPTS = 0x23
-
- sysIPV6_RECVPKTINFO = 0x24
- sysIPV6_RECVHOPLIMIT = 0x25
- sysIPV6_RECVRTHDR = 0x26
- sysIPV6_RECVHOPOPTS = 0x27
- sysIPV6_RECVDSTOPTS = 0x28
-
- sysIPV6_USE_MIN_MTU = 0x2a
- sysIPV6_RECVPATHMTU = 0x2b
-
- sysIPV6_PATHMTU = 0x2c
-
- sysIPV6_PKTINFO = 0x2e
- sysIPV6_HOPLIMIT = 0x2f
- sysIPV6_NEXTHOP = 0x30
- sysIPV6_HOPOPTS = 0x31
- sysIPV6_DSTOPTS = 0x32
- sysIPV6_RTHDR = 0x33
-
- sysIPV6_RECVTCLASS = 0x39
-
- sysIPV6_AUTOFLOWLABEL = 0x3b
-
- sysIPV6_TCLASS = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_PREFER_TEMPADDR = 0x3f
-
- sysIPV6_BINDANY = 0x40
-
- sysIPV6_MSFILTER = 0x4a
-
- sysMCAST_JOIN_GROUP = 0x50
- sysMCAST_LEAVE_GROUP = 0x51
- sysMCAST_JOIN_SOURCE_GROUP = 0x52
- sysMCAST_LEAVE_SOURCE_GROUP = 0x53
- sysMCAST_BLOCK_SOURCE = 0x54
- sysMCAST_UNBLOCK_SOURCE = 0x55
-
- sysIPV6_PORTRANGE_DEFAULT = 0x0
- sysIPV6_PORTRANGE_HIGH = 0x1
- sysIPV6_PORTRANGE_LOW = 0x2
-
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go
index 490ce7c..72a1a65 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go
@@ -4,64 +4,6 @@
package ipv6
const (
- sysIPV6_UNICAST_HOPS = 0x4
- sysIPV6_MULTICAST_IF = 0x9
- sysIPV6_MULTICAST_HOPS = 0xa
- sysIPV6_MULTICAST_LOOP = 0xb
- sysIPV6_JOIN_GROUP = 0xc
- sysIPV6_LEAVE_GROUP = 0xd
- sysIPV6_PORTRANGE = 0xe
- sysICMP6_FILTER = 0x12
-
- sysIPV6_CHECKSUM = 0x1a
- sysIPV6_V6ONLY = 0x1b
-
- sysIPV6_IPSEC_POLICY = 0x1c
-
- sysIPV6_RTHDRDSTOPTS = 0x23
-
- sysIPV6_RECVPKTINFO = 0x24
- sysIPV6_RECVHOPLIMIT = 0x25
- sysIPV6_RECVRTHDR = 0x26
- sysIPV6_RECVHOPOPTS = 0x27
- sysIPV6_RECVDSTOPTS = 0x28
-
- sysIPV6_USE_MIN_MTU = 0x2a
- sysIPV6_RECVPATHMTU = 0x2b
-
- sysIPV6_PATHMTU = 0x2c
-
- sysIPV6_PKTINFO = 0x2e
- sysIPV6_HOPLIMIT = 0x2f
- sysIPV6_NEXTHOP = 0x30
- sysIPV6_HOPOPTS = 0x31
- sysIPV6_DSTOPTS = 0x32
- sysIPV6_RTHDR = 0x33
-
- sysIPV6_RECVTCLASS = 0x39
-
- sysIPV6_AUTOFLOWLABEL = 0x3b
-
- sysIPV6_TCLASS = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_PREFER_TEMPADDR = 0x3f
-
- sysIPV6_BINDANY = 0x40
-
- sysIPV6_MSFILTER = 0x4a
-
- sysMCAST_JOIN_GROUP = 0x50
- sysMCAST_LEAVE_GROUP = 0x51
- sysMCAST_JOIN_SOURCE_GROUP = 0x52
- sysMCAST_LEAVE_SOURCE_GROUP = 0x53
- sysMCAST_BLOCK_SOURCE = 0x54
- sysMCAST_UNBLOCK_SOURCE = 0x55
-
- sysIPV6_PORTRANGE_DEFAULT = 0x0
- sysIPV6_PORTRANGE_HIGH = 0x1
- sysIPV6_PORTRANGE_LOW = 0x2
-
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm64.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm64.go
index 47e99ac..5b39eb8 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm64.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm64.go
@@ -4,64 +4,6 @@
package ipv6
const (
- sysIPV6_UNICAST_HOPS = 0x4
- sysIPV6_MULTICAST_IF = 0x9
- sysIPV6_MULTICAST_HOPS = 0xa
- sysIPV6_MULTICAST_LOOP = 0xb
- sysIPV6_JOIN_GROUP = 0xc
- sysIPV6_LEAVE_GROUP = 0xd
- sysIPV6_PORTRANGE = 0xe
- sysICMP6_FILTER = 0x12
-
- sysIPV6_CHECKSUM = 0x1a
- sysIPV6_V6ONLY = 0x1b
-
- sysIPV6_IPSEC_POLICY = 0x1c
-
- sysIPV6_RTHDRDSTOPTS = 0x23
-
- sysIPV6_RECVPKTINFO = 0x24
- sysIPV6_RECVHOPLIMIT = 0x25
- sysIPV6_RECVRTHDR = 0x26
- sysIPV6_RECVHOPOPTS = 0x27
- sysIPV6_RECVDSTOPTS = 0x28
-
- sysIPV6_USE_MIN_MTU = 0x2a
- sysIPV6_RECVPATHMTU = 0x2b
-
- sysIPV6_PATHMTU = 0x2c
-
- sysIPV6_PKTINFO = 0x2e
- sysIPV6_HOPLIMIT = 0x2f
- sysIPV6_NEXTHOP = 0x30
- sysIPV6_HOPOPTS = 0x31
- sysIPV6_DSTOPTS = 0x32
- sysIPV6_RTHDR = 0x33
-
- sysIPV6_RECVTCLASS = 0x39
-
- sysIPV6_AUTOFLOWLABEL = 0x3b
-
- sysIPV6_TCLASS = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_PREFER_TEMPADDR = 0x3f
-
- sysIPV6_BINDANY = 0x40
-
- sysIPV6_MSFILTER = 0x4a
-
- sysMCAST_JOIN_GROUP = 0x50
- sysMCAST_LEAVE_GROUP = 0x51
- sysMCAST_JOIN_SOURCE_GROUP = 0x52
- sysMCAST_LEAVE_SOURCE_GROUP = 0x53
- sysMCAST_BLOCK_SOURCE = 0x54
- sysMCAST_UNBLOCK_SOURCE = 0x55
-
- sysIPV6_PORTRANGE_DEFAULT = 0x0
- sysIPV6_PORTRANGE_HIGH = 0x1
- sysIPV6_PORTRANGE_LOW = 0x2
-
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go
new file mode 100644
index 0000000..5b39eb8
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go
@@ -0,0 +1,64 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package ipv6
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]uint8
+ X__ss_align int64
+ X__ss_pad2 [112]uint8
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_386.go b/vendor/golang.org/x/net/ipv6/zsys_linux_386.go
index bde4a8f..ad71871 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_386.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_386.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go
index 992ac9e..2514ab9 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_arm.go b/vendor/golang.org/x/net/ipv6/zsys_linux_arm.go
index bde4a8f..ad71871 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_arm.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_arm.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go
index 992ac9e..2514ab9 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go
new file mode 100644
index 0000000..598fbfa
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go
@@ -0,0 +1,77 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_linux.go
+
+//go:build loong64
+// +build loong64
+
+package ipv6
+
+const (
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x88
+ sizeofGroupSourceReq = 0x108
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Pad_cgo_0 [4]byte
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go
index bde4a8f..ad71871 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go
index 992ac9e..2514ab9 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go
index 992ac9e..2514ab9 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go
index bde4a8f..ad71871 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go
index 66fd236..d06c2ad 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go
index 992ac9e..2514ab9 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go
index 992ac9e..2514ab9 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go b/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go
index 6083ddc..d4f78e4 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go
@@ -1,91 +1,12 @@
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs defs_linux.go
+//go:build riscv64
// +build riscv64
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go b/vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go
index 992ac9e..2514ab9 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go
@@ -4,86 +4,6 @@
package ipv6
const (
- sysIPV6_ADDRFORM = 0x1
- sysIPV6_2292PKTINFO = 0x2
- sysIPV6_2292HOPOPTS = 0x3
- sysIPV6_2292DSTOPTS = 0x4
- sysIPV6_2292RTHDR = 0x5
- sysIPV6_2292PKTOPTIONS = 0x6
- sysIPV6_CHECKSUM = 0x7
- sysIPV6_2292HOPLIMIT = 0x8
- sysIPV6_NEXTHOP = 0x9
- sysIPV6_FLOWINFO = 0xb
-
- sysIPV6_UNICAST_HOPS = 0x10
- sysIPV6_MULTICAST_IF = 0x11
- sysIPV6_MULTICAST_HOPS = 0x12
- sysIPV6_MULTICAST_LOOP = 0x13
- sysIPV6_ADD_MEMBERSHIP = 0x14
- sysIPV6_DROP_MEMBERSHIP = 0x15
- sysMCAST_JOIN_GROUP = 0x2a
- sysMCAST_LEAVE_GROUP = 0x2d
- sysMCAST_JOIN_SOURCE_GROUP = 0x2e
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_MSFILTER = 0x30
- sysIPV6_ROUTER_ALERT = 0x16
- sysIPV6_MTU_DISCOVER = 0x17
- sysIPV6_MTU = 0x18
- sysIPV6_RECVERR = 0x19
- sysIPV6_V6ONLY = 0x1a
- sysIPV6_JOIN_ANYCAST = 0x1b
- sysIPV6_LEAVE_ANYCAST = 0x1c
-
- sysIPV6_FLOWLABEL_MGR = 0x20
- sysIPV6_FLOWINFO_SEND = 0x21
-
- sysIPV6_IPSEC_POLICY = 0x22
- sysIPV6_XFRM_POLICY = 0x23
-
- sysIPV6_RECVPKTINFO = 0x31
- sysIPV6_PKTINFO = 0x32
- sysIPV6_RECVHOPLIMIT = 0x33
- sysIPV6_HOPLIMIT = 0x34
- sysIPV6_RECVHOPOPTS = 0x35
- sysIPV6_HOPOPTS = 0x36
- sysIPV6_RTHDRDSTOPTS = 0x37
- sysIPV6_RECVRTHDR = 0x38
- sysIPV6_RTHDR = 0x39
- sysIPV6_RECVDSTOPTS = 0x3a
- sysIPV6_DSTOPTS = 0x3b
- sysIPV6_RECVPATHMTU = 0x3c
- sysIPV6_PATHMTU = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_RECVTCLASS = 0x42
- sysIPV6_TCLASS = 0x43
-
- sysIPV6_ADDR_PREFERENCES = 0x48
-
- sysIPV6_PREFER_SRC_TMP = 0x1
- sysIPV6_PREFER_SRC_PUBLIC = 0x2
- sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
- sysIPV6_PREFER_SRC_COA = 0x4
- sysIPV6_PREFER_SRC_HOME = 0x400
- sysIPV6_PREFER_SRC_CGA = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x800
-
- sysIPV6_MINHOPCOUNT = 0x49
-
- sysIPV6_ORIGDSTADDR = 0x4a
- sysIPV6_RECVORIGDSTADDR = 0x4a
- sysIPV6_TRANSPARENT = 0x4b
- sysIPV6_UNICAST_IF = 0x4c
-
- sysICMPV6_FILTER = 0x1
-
- sysICMPV6_FILTER_BLOCK = 0x1
- sysICMPV6_FILTER_PASS = 0x2
- sysICMPV6_FILTER_BLOCKOTHERS = 0x3
- sysICMPV6_FILTER_PASSONLY = 0x4
-
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_netbsd.go b/vendor/golang.org/x/net/ipv6/zsys_netbsd.go
index e39571e..f7335d5 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_netbsd.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_netbsd.go
@@ -4,48 +4,6 @@
package ipv6
const (
- sysIPV6_UNICAST_HOPS = 0x4
- sysIPV6_MULTICAST_IF = 0x9
- sysIPV6_MULTICAST_HOPS = 0xa
- sysIPV6_MULTICAST_LOOP = 0xb
- sysIPV6_JOIN_GROUP = 0xc
- sysIPV6_LEAVE_GROUP = 0xd
- sysIPV6_PORTRANGE = 0xe
- sysICMP6_FILTER = 0x12
-
- sysIPV6_CHECKSUM = 0x1a
- sysIPV6_V6ONLY = 0x1b
-
- sysIPV6_IPSEC_POLICY = 0x1c
-
- sysIPV6_RTHDRDSTOPTS = 0x23
-
- sysIPV6_RECVPKTINFO = 0x24
- sysIPV6_RECVHOPLIMIT = 0x25
- sysIPV6_RECVRTHDR = 0x26
- sysIPV6_RECVHOPOPTS = 0x27
- sysIPV6_RECVDSTOPTS = 0x28
-
- sysIPV6_USE_MIN_MTU = 0x2a
- sysIPV6_RECVPATHMTU = 0x2b
- sysIPV6_PATHMTU = 0x2c
-
- sysIPV6_PKTINFO = 0x2e
- sysIPV6_HOPLIMIT = 0x2f
- sysIPV6_NEXTHOP = 0x30
- sysIPV6_HOPOPTS = 0x31
- sysIPV6_DSTOPTS = 0x32
- sysIPV6_RTHDR = 0x33
-
- sysIPV6_RECVTCLASS = 0x39
-
- sysIPV6_TCLASS = 0x3d
- sysIPV6_DONTFRAG = 0x3e
-
- sysIPV6_PORTRANGE_DEFAULT = 0x0
- sysIPV6_PORTRANGE_HIGH = 0x1
- sysIPV6_PORTRANGE_LOW = 0x2
-
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
sizeofIPv6Mtuinfo = 0x20
diff --git a/vendor/golang.org/x/net/ipv6/zsys_openbsd.go b/vendor/golang.org/x/net/ipv6/zsys_openbsd.go
index cc1899a..6d15928 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_openbsd.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_openbsd.go
@@ -4,57 +4,6 @@
package ipv6
const (
- sysIPV6_UNICAST_HOPS = 0x4
- sysIPV6_MULTICAST_IF = 0x9
- sysIPV6_MULTICAST_HOPS = 0xa
- sysIPV6_MULTICAST_LOOP = 0xb
- sysIPV6_JOIN_GROUP = 0xc
- sysIPV6_LEAVE_GROUP = 0xd
- sysIPV6_PORTRANGE = 0xe
- sysICMP6_FILTER = 0x12
-
- sysIPV6_CHECKSUM = 0x1a
- sysIPV6_V6ONLY = 0x1b
-
- sysIPV6_RTHDRDSTOPTS = 0x23
-
- sysIPV6_RECVPKTINFO = 0x24
- sysIPV6_RECVHOPLIMIT = 0x25
- sysIPV6_RECVRTHDR = 0x26
- sysIPV6_RECVHOPOPTS = 0x27
- sysIPV6_RECVDSTOPTS = 0x28
-
- sysIPV6_USE_MIN_MTU = 0x2a
- sysIPV6_RECVPATHMTU = 0x2b
-
- sysIPV6_PATHMTU = 0x2c
-
- sysIPV6_PKTINFO = 0x2e
- sysIPV6_HOPLIMIT = 0x2f
- sysIPV6_NEXTHOP = 0x30
- sysIPV6_HOPOPTS = 0x31
- sysIPV6_DSTOPTS = 0x32
- sysIPV6_RTHDR = 0x33
-
- sysIPV6_AUTH_LEVEL = 0x35
- sysIPV6_ESP_TRANS_LEVEL = 0x36
- sysIPV6_ESP_NETWORK_LEVEL = 0x37
- sysIPSEC6_OUTSA = 0x38
- sysIPV6_RECVTCLASS = 0x39
-
- sysIPV6_AUTOFLOWLABEL = 0x3b
- sysIPV6_IPCOMP_LEVEL = 0x3c
-
- sysIPV6_TCLASS = 0x3d
- sysIPV6_DONTFRAG = 0x3e
- sysIPV6_PIPEX = 0x3f
-
- sysIPV6_RTABLE = 0x1021
-
- sysIPV6_PORTRANGE_DEFAULT = 0x0
- sysIPV6_PORTRANGE_HIGH = 0x1
- sysIPV6_PORTRANGE_LOW = 0x2
-
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
sizeofIPv6Mtuinfo = 0x20
diff --git a/vendor/golang.org/x/net/ipv6/zsys_solaris.go b/vendor/golang.org/x/net/ipv6/zsys_solaris.go
index 690eef9..1716197 100644
--- a/vendor/golang.org/x/net/ipv6/zsys_solaris.go
+++ b/vendor/golang.org/x/net/ipv6/zsys_solaris.go
@@ -4,74 +4,6 @@
package ipv6
const (
- sysIPV6_UNICAST_HOPS = 0x5
- sysIPV6_MULTICAST_IF = 0x6
- sysIPV6_MULTICAST_HOPS = 0x7
- sysIPV6_MULTICAST_LOOP = 0x8
- sysIPV6_JOIN_GROUP = 0x9
- sysIPV6_LEAVE_GROUP = 0xa
-
- sysIPV6_PKTINFO = 0xb
-
- sysIPV6_HOPLIMIT = 0xc
- sysIPV6_NEXTHOP = 0xd
- sysIPV6_HOPOPTS = 0xe
- sysIPV6_DSTOPTS = 0xf
-
- sysIPV6_RTHDR = 0x10
- sysIPV6_RTHDRDSTOPTS = 0x11
-
- sysIPV6_RECVPKTINFO = 0x12
- sysIPV6_RECVHOPLIMIT = 0x13
- sysIPV6_RECVHOPOPTS = 0x14
-
- sysIPV6_RECVRTHDR = 0x16
-
- sysIPV6_RECVRTHDRDSTOPTS = 0x17
-
- sysIPV6_CHECKSUM = 0x18
- sysIPV6_RECVTCLASS = 0x19
- sysIPV6_USE_MIN_MTU = 0x20
- sysIPV6_DONTFRAG = 0x21
- sysIPV6_SEC_OPT = 0x22
- sysIPV6_SRC_PREFERENCES = 0x23
- sysIPV6_RECVPATHMTU = 0x24
- sysIPV6_PATHMTU = 0x25
- sysIPV6_TCLASS = 0x26
- sysIPV6_V6ONLY = 0x27
-
- sysIPV6_RECVDSTOPTS = 0x28
-
- sysMCAST_JOIN_GROUP = 0x29
- sysMCAST_LEAVE_GROUP = 0x2a
- sysMCAST_BLOCK_SOURCE = 0x2b
- sysMCAST_UNBLOCK_SOURCE = 0x2c
- sysMCAST_JOIN_SOURCE_GROUP = 0x2d
- sysMCAST_LEAVE_SOURCE_GROUP = 0x2e
-
- sysIPV6_PREFER_SRC_HOME = 0x1
- sysIPV6_PREFER_SRC_COA = 0x2
- sysIPV6_PREFER_SRC_PUBLIC = 0x4
- sysIPV6_PREFER_SRC_TMP = 0x8
- sysIPV6_PREFER_SRC_NONCGA = 0x10
- sysIPV6_PREFER_SRC_CGA = 0x20
-
- sysIPV6_PREFER_SRC_MIPMASK = 0x3
- sysIPV6_PREFER_SRC_MIPDEFAULT = 0x1
- sysIPV6_PREFER_SRC_TMPMASK = 0xc
- sysIPV6_PREFER_SRC_TMPDEFAULT = 0x4
- sysIPV6_PREFER_SRC_CGAMASK = 0x30
- sysIPV6_PREFER_SRC_CGADEFAULT = 0x10
-
- sysIPV6_PREFER_SRC_MASK = 0x3f
-
- sysIPV6_PREFER_SRC_DEFAULT = 0x15
-
- sysIPV6_BOUND_IF = 0x41
- sysIPV6_UNSPEC_SRC = 0x42
-
- sysICMP6_FILTER = 0x1
-
sizeofSockaddrStorage = 0x100
sizeofSockaddrInet6 = 0x20
sizeofInet6Pktinfo = 0x14
diff --git a/vendor/golang.org/x/net/ipv6/zsys_zos_s390x.go b/vendor/golang.org/x/net/ipv6/zsys_zos_s390x.go
new file mode 100644
index 0000000..7c75645
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv6/zsys_zos_s390x.go
@@ -0,0 +1,62 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Hand edited based on zerrors_zos_s390x.go
+// TODO(Bill O'Farrell): auto-generate.
+
+package ipv6
+
+const (
+ sizeofSockaddrStorage = 128
+ sizeofICMPv6Filter = 32
+ sizeofInet6Pktinfo = 20
+ sizeofIPv6Mtuinfo = 32
+ sizeofSockaddrInet6 = 28
+ sizeofGroupReq = 136
+ sizeofGroupSourceReq = 264
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family byte
+ ss_pad1 [6]byte
+ ss_align int64
+ ss_pad2 [112]byte
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte
+ Ifindex uint32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ reserved uint32
+ Group sockaddrStorage
+ Source sockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Filt [8]uint32
+}
diff --git a/vendor/golang.org/x/sync/LICENSE b/vendor/golang.org/x/sync/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/vendor/golang.org/x/sync/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/sync/PATENTS b/vendor/golang.org/x/sync/PATENTS
new file mode 100644
index 0000000..7330990
--- /dev/null
+++ b/vendor/golang.org/x/sync/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/sync/semaphore/semaphore.go b/vendor/golang.org/x/sync/semaphore/semaphore.go
new file mode 100644
index 0000000..30f632c
--- /dev/null
+++ b/vendor/golang.org/x/sync/semaphore/semaphore.go
@@ -0,0 +1,136 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package semaphore provides a weighted semaphore implementation.
+package semaphore // import "golang.org/x/sync/semaphore"
+
+import (
+ "container/list"
+ "context"
+ "sync"
+)
+
+type waiter struct {
+ n int64
+ ready chan<- struct{} // Closed when semaphore acquired.
+}
+
+// NewWeighted creates a new weighted semaphore with the given
+// maximum combined weight for concurrent access.
+func NewWeighted(n int64) *Weighted {
+ w := &Weighted{size: n}
+ return w
+}
+
+// Weighted provides a way to bound concurrent access to a resource.
+// The callers can request access with a given weight.
+type Weighted struct {
+ size int64
+ cur int64
+ mu sync.Mutex
+ waiters list.List
+}
+
+// Acquire acquires the semaphore with a weight of n, blocking until resources
+// are available or ctx is done. On success, returns nil. On failure, returns
+// ctx.Err() and leaves the semaphore unchanged.
+//
+// If ctx is already done, Acquire may still succeed without blocking.
+func (s *Weighted) Acquire(ctx context.Context, n int64) error {
+ s.mu.Lock()
+ if s.size-s.cur >= n && s.waiters.Len() == 0 {
+ s.cur += n
+ s.mu.Unlock()
+ return nil
+ }
+
+ if n > s.size {
+ // Don't make other Acquire calls block on one that's doomed to fail.
+ s.mu.Unlock()
+ <-ctx.Done()
+ return ctx.Err()
+ }
+
+ ready := make(chan struct{})
+ w := waiter{n: n, ready: ready}
+ elem := s.waiters.PushBack(w)
+ s.mu.Unlock()
+
+ select {
+ case <-ctx.Done():
+ err := ctx.Err()
+ s.mu.Lock()
+ select {
+ case <-ready:
+ // Acquired the semaphore after we were canceled. Rather than trying to
+ // fix up the queue, just pretend we didn't notice the cancelation.
+ err = nil
+ default:
+ isFront := s.waiters.Front() == elem
+ s.waiters.Remove(elem)
+ // If we're at the front and there're extra tokens left, notify other waiters.
+ if isFront && s.size > s.cur {
+ s.notifyWaiters()
+ }
+ }
+ s.mu.Unlock()
+ return err
+
+ case <-ready:
+ return nil
+ }
+}
+
+// TryAcquire acquires the semaphore with a weight of n without blocking.
+// On success, returns true. On failure, returns false and leaves the semaphore unchanged.
+func (s *Weighted) TryAcquire(n int64) bool {
+ s.mu.Lock()
+ success := s.size-s.cur >= n && s.waiters.Len() == 0
+ if success {
+ s.cur += n
+ }
+ s.mu.Unlock()
+ return success
+}
+
+// Release releases the semaphore with a weight of n.
+func (s *Weighted) Release(n int64) {
+ s.mu.Lock()
+ s.cur -= n
+ if s.cur < 0 {
+ s.mu.Unlock()
+ panic("semaphore: released more than held")
+ }
+ s.notifyWaiters()
+ s.mu.Unlock()
+}
+
+func (s *Weighted) notifyWaiters() {
+ for {
+ next := s.waiters.Front()
+ if next == nil {
+ break // No more waiters blocked.
+ }
+
+ w := next.Value.(waiter)
+ if s.size-s.cur < w.n {
+ // Not enough tokens for the next waiter. We could keep going (to try to
+ // find a waiter with a smaller request), but under load that could cause
+ // starvation for large requests; instead, we leave all remaining waiters
+ // blocked.
+ //
+ // Consider a semaphore used as a read-write lock, with N tokens, N
+ // readers, and one writer. Each reader can Acquire(1) to obtain a read
+ // lock. The writer can Acquire(N) to obtain a write lock, excluding all
+ // of the readers. If we allow the readers to jump ahead in the queue,
+ // the writer will starve — there is always one token available for every
+ // reader.
+ break
+ }
+
+ s.cur += w.n
+ s.waiters.Remove(next)
+ close(w.ready)
+ }
+}
diff --git a/vendor/golang.org/x/sys/AUTHORS b/vendor/golang.org/x/sys/AUTHORS
deleted file mode 100644
index 15167cd..0000000
--- a/vendor/golang.org/x/sys/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/sys/CONTRIBUTORS b/vendor/golang.org/x/sys/CONTRIBUTORS
deleted file mode 100644
index 1c4577e..0000000
--- a/vendor/golang.org/x/sys/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/sys/unix/README.md b/vendor/golang.org/x/sys/unix/README.md
index 579d2d7..7d3c060 100644
--- a/vendor/golang.org/x/sys/unix/README.md
+++ b/vendor/golang.org/x/sys/unix/README.md
@@ -76,7 +76,7 @@ arguments can be passed to the kernel. The third is for low-level use by the
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
let it know that a system call is running.
-When porting Go to an new architecture/OS, this file must be implemented for
+When porting Go to a new architecture/OS, this file must be implemented for
each GOOS/GOARCH pair.
### mksysnum
@@ -107,7 +107,7 @@ prototype can be exported (capitalized) or not.
Adding a new syscall often just requires adding a new `//sys` function prototype
with the desired arguments and a capitalized name so it is exported. However, if
you want the interface to the syscall to be different, often one will make an
-unexported `//sys` prototype, an then write a custom wrapper in
+unexported `//sys` prototype, and then write a custom wrapper in
`syscall_${GOOS}.go`.
### types files
@@ -137,7 +137,7 @@ some `#if/#elif` macros in your include statements.
This script is used to generate the system's various constants. This doesn't
just include the error numbers and error strings, but also the signal numbers
-an a wide variety of miscellaneous constants. The constants come from the list
+and a wide variety of miscellaneous constants. The constants come from the list
of include files in the `includes_${uname}` variable. A regex then picks out
the desired `#define` statements, and generates the corresponding Go constants.
The error numbers and strings are generated from `#include `, and the
@@ -149,7 +149,7 @@ To add a constant, add the header that includes it to the appropriate variable.
Then, edit the regex (if necessary) to match the desired constant. Avoid making
the regex too broad to avoid matching unintended constants.
-### mkmerge.go
+### internal/mkmerge
This program is used to extract duplicate const, func, and type declarations
from the generated architecture-specific files listed below, and merge these
diff --git a/vendor/golang.org/x/sys/unix/aliases.go b/vendor/golang.org/x/sys/unix/aliases.go
index 951fce4..abc89c1 100644
--- a/vendor/golang.org/x/sys/unix/aliases.go
+++ b/vendor/golang.org/x/sys/unix/aliases.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
// +build go1.9
package unix
diff --git a/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s b/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
index 06f84b8..db9171c 100644
--- a/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
+++ b/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
+//go:build gc
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_386.s b/vendor/golang.org/x/sys/unix/asm_bsd_386.s
similarity index 70%
rename from vendor/golang.org/x/sys/unix/asm_netbsd_386.s
rename to vendor/golang.org/x/sys/unix/asm_bsd_386.s
index 48bdcd7..e0fcd9b 100644
--- a/vendor/golang.org/x/sys/unix/asm_netbsd_386.s
+++ b/vendor/golang.org/x/sys/unix/asm_bsd_386.s
@@ -1,14 +1,14 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
+//go:build (freebsd || netbsd || openbsd) && gc
+// +build freebsd netbsd openbsd
+// +build gc
#include "textflag.h"
-//
-// System call support for 386, NetBSD
-//
+// System call support for 386 BSD
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
@@ -22,7 +22,7 @@ TEXT ·Syscall6(SB),NOSPLIT,$0-40
TEXT ·Syscall9(SB),NOSPLIT,$0-52
JMP syscall·Syscall9(SB)
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s b/vendor/golang.org/x/sys/unix/asm_bsd_amd64.s
similarity index 71%
rename from vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
rename to vendor/golang.org/x/sys/unix/asm_bsd_amd64.s
index 6321421..2b99c34 100644
--- a/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
+++ b/vendor/golang.org/x/sys/unix/asm_bsd_amd64.s
@@ -1,14 +1,14 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
+//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && gc
+// +build darwin dragonfly freebsd netbsd openbsd
+// +build gc
#include "textflag.h"
-//
-// System call support for AMD64, Darwin
-//
+// System call support for AMD64 BSD
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_arm.s b/vendor/golang.org/x/sys/unix/asm_bsd_arm.s
similarity index 74%
rename from vendor/golang.org/x/sys/unix/asm_darwin_arm.s
rename to vendor/golang.org/x/sys/unix/asm_bsd_arm.s
index 333242d..d702d4a 100644
--- a/vendor/golang.org/x/sys/unix/asm_darwin_arm.s
+++ b/vendor/golang.org/x/sys/unix/asm_bsd_arm.s
@@ -1,15 +1,14 @@
-// Copyright 2015 The Go Authors. All rights reserved.
+// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
-// +build arm,darwin
+//go:build (freebsd || netbsd || openbsd) && gc
+// +build freebsd netbsd openbsd
+// +build gc
#include "textflag.h"
-//
-// System call support for ARM, Darwin
-//
+// System call support for ARM BSD
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s b/vendor/golang.org/x/sys/unix/asm_bsd_arm64.s
similarity index 73%
rename from vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
rename to vendor/golang.org/x/sys/unix/asm_bsd_arm64.s
index 790ef77..fe36a73 100644
--- a/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
+++ b/vendor/golang.org/x/sys/unix/asm_bsd_arm64.s
@@ -1,14 +1,14 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
+//go:build (darwin || freebsd || netbsd || openbsd) && gc
+// +build darwin freebsd netbsd openbsd
+// +build gc
#include "textflag.h"
-//
-// System call support for AMD64, OpenBSD
-//
+// System call support for ARM64 BSD
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s b/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s
similarity index 73%
rename from vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
rename to vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s
index 2ede05c..e5b9a84 100644
--- a/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
+++ b/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s
@@ -1,13 +1,15 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
+//go:build (darwin || freebsd || netbsd || openbsd) && gc
+// +build darwin freebsd netbsd openbsd
+// +build gc
#include "textflag.h"
//
-// System call support for AMD64, NetBSD
+// System call support for ppc64, BSD
//
// Just jump to package syscall's implementation for all these functions.
diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s b/vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s
similarity index 73%
rename from vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s
rename to vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s
index 0cedea3..d560019 100644
--- a/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s
+++ b/vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s
@@ -1,14 +1,14 @@
-// Copyright 2019 The Go Authors. All rights reserved.
+// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
+//go:build (darwin || freebsd || netbsd || openbsd) && gc
+// +build darwin freebsd netbsd openbsd
+// +build gc
#include "textflag.h"
-//
-// System call support for arm64, OpenBSD
-//
+// System call support for RISCV64 BSD
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_386.s b/vendor/golang.org/x/sys/unix/asm_darwin_386.s
deleted file mode 100644
index 8a72783..0000000
--- a/vendor/golang.org/x/sys/unix/asm_darwin_386.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !gccgo
-
-#include "textflag.h"
-
-//
-// System call support for 386, Darwin
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT ·Syscall(SB),NOSPLIT,$0-28
- JMP syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-40
- JMP syscall·Syscall6(SB)
-
-TEXT ·Syscall9(SB),NOSPLIT,$0-52
- JMP syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
- JMP syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
- JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s b/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
deleted file mode 100644
index 97e0174..0000000
--- a/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !gccgo
-// +build arm64,darwin
-
-#include "textflag.h"
-
-//
-// System call support for AMD64, Darwin
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT ·Syscall(SB),NOSPLIT,$0-56
- B syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-80
- B syscall·Syscall6(SB)
-
-TEXT ·Syscall9(SB),NOSPLIT,$0-104
- B syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
- B syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
- B syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s b/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
deleted file mode 100644
index 603dd57..0000000
--- a/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !gccgo
-
-#include "textflag.h"
-
-//
-// System call support for AMD64, DragonFly
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT ·Syscall(SB),NOSPLIT,$0-56
- JMP syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-80
- JMP syscall·Syscall6(SB)
-
-TEXT ·Syscall9(SB),NOSPLIT,$0-104
- JMP syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
- JMP syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
- JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_386.s b/vendor/golang.org/x/sys/unix/asm_freebsd_386.s
deleted file mode 100644
index c9a0a26..0000000
--- a/vendor/golang.org/x/sys/unix/asm_freebsd_386.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !gccgo
-
-#include "textflag.h"
-
-//
-// System call support for 386, FreeBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT ·Syscall(SB),NOSPLIT,$0-28
- JMP syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-40
- JMP syscall·Syscall6(SB)
-
-TEXT ·Syscall9(SB),NOSPLIT,$0-52
- JMP syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
- JMP syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
- JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s b/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
deleted file mode 100644
index 3517247..0000000
--- a/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !gccgo
-
-#include "textflag.h"
-
-//
-// System call support for AMD64, FreeBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT ·Syscall(SB),NOSPLIT,$0-56
- JMP syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-80
- JMP syscall·Syscall6(SB)
-
-TEXT ·Syscall9(SB),NOSPLIT,$0-104
- JMP syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
- JMP syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
- JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s b/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
deleted file mode 100644
index 9227c87..0000000
--- a/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !gccgo
-
-#include "textflag.h"
-
-//
-// System call support for ARM, FreeBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT ·Syscall(SB),NOSPLIT,$0-28
- B syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-40
- B syscall·Syscall6(SB)
-
-TEXT ·Syscall9(SB),NOSPLIT,$0-52
- B syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
- B syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
- B syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s b/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s
deleted file mode 100644
index d9318cb..0000000
--- a/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !gccgo
-
-#include "textflag.h"
-
-//
-// System call support for ARM64, FreeBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT ·Syscall(SB),NOSPLIT,$0-56
- JMP syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-80
- JMP syscall·Syscall6(SB)
-
-TEXT ·Syscall9(SB),NOSPLIT,$0-104
- JMP syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
- JMP syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
- JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_386.s b/vendor/golang.org/x/sys/unix/asm_linux_386.s
index 448bebb..8fd101d 100644
--- a/vendor/golang.org/x/sys/unix/asm_linux_386.s
+++ b/vendor/golang.org/x/sys/unix/asm_linux_386.s
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
+//go:build gc
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_amd64.s b/vendor/golang.org/x/sys/unix/asm_linux_amd64.s
index c6468a9..7ed38e4 100644
--- a/vendor/golang.org/x/sys/unix/asm_linux_amd64.s
+++ b/vendor/golang.org/x/sys/unix/asm_linux_amd64.s
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
+//go:build gc
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_arm.s b/vendor/golang.org/x/sys/unix/asm_linux_arm.s
index cf0f357..8ef1d51 100644
--- a/vendor/golang.org/x/sys/unix/asm_linux_arm.s
+++ b/vendor/golang.org/x/sys/unix/asm_linux_arm.s
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
+//go:build gc
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_arm64.s b/vendor/golang.org/x/sys/unix/asm_linux_arm64.s
index afe6fdf..98ae027 100644
--- a/vendor/golang.org/x/sys/unix/asm_linux_arm64.s
+++ b/vendor/golang.org/x/sys/unix/asm_linux_arm64.s
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build linux && arm64 && gc
// +build linux
// +build arm64
-// +build !gccgo
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_loong64.s b/vendor/golang.org/x/sys/unix/asm_linux_loong64.s
new file mode 100644
index 0000000..5653572
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_linux_loong64.s
@@ -0,0 +1,54 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && loong64 && gc
+// +build linux
+// +build loong64
+// +build gc
+
+#include "textflag.h"
+
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-56
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-80
+ JMP syscall·Syscall6(SB)
+
+TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
+ JAL runtime·entersyscall(SB)
+ MOVV a1+8(FP), R4
+ MOVV a2+16(FP), R5
+ MOVV a3+24(FP), R6
+ MOVV R0, R7
+ MOVV R0, R8
+ MOVV R0, R9
+ MOVV trap+0(FP), R11 // syscall entry
+ SYSCALL
+ MOVV R4, r1+32(FP)
+ MOVV R0, r2+40(FP) // r2 is not used. Always set to 0
+ JAL runtime·exitsyscall(SB)
+ RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+ JMP syscall·RawSyscall6(SB)
+
+TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
+ MOVV a1+8(FP), R4
+ MOVV a2+16(FP), R5
+ MOVV a3+24(FP), R6
+ MOVV R0, R7
+ MOVV R0, R8
+ MOVV R0, R9
+ MOVV trap+0(FP), R11 // syscall entry
+ SYSCALL
+ MOVV R4, r1+32(FP)
+ MOVV R0, r2+40(FP) // r2 is not used. Always set to 0
+ RET
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s b/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
index ab9d638..21231d2 100644
--- a/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
+++ b/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build linux && (mips64 || mips64le) && gc
// +build linux
// +build mips64 mips64le
-// +build !gccgo
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s b/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
index 99e5399..6783b26 100644
--- a/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
+++ b/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build linux && (mips || mipsle) && gc
// +build linux
// +build mips mipsle
-// +build !gccgo
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s b/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
index 88f7125..19d4989 100644
--- a/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
+++ b/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build linux && (ppc64 || ppc64le) && gc
// +build linux
// +build ppc64 ppc64le
-// +build !gccgo
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s b/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
index 3cfefed..e42eb81 100644
--- a/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
+++ b/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build riscv64,!gccgo
+//go:build riscv64 && gc
+// +build riscv64
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_s390x.s b/vendor/golang.org/x/sys/unix/asm_linux_s390x.s
index a5a863c..c46aab3 100644
--- a/vendor/golang.org/x/sys/unix/asm_linux_s390x.s
+++ b/vendor/golang.org/x/sys/unix/asm_linux_s390x.s
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build s390x
+//go:build linux && s390x && gc
// +build linux
-// +build !gccgo
+// +build s390x
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s b/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
deleted file mode 100644
index e892857..0000000
--- a/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !gccgo
-
-#include "textflag.h"
-
-//
-// System call support for ARM, NetBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT ·Syscall(SB),NOSPLIT,$0-28
- B syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-40
- B syscall·Syscall6(SB)
-
-TEXT ·Syscall9(SB),NOSPLIT,$0-52
- B syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
- B syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
- B syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s b/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s
deleted file mode 100644
index 6f98ba5..0000000
--- a/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !gccgo
-
-#include "textflag.h"
-
-//
-// System call support for ARM64, NetBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT ·Syscall(SB),NOSPLIT,$0-56
- B syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-80
- B syscall·Syscall6(SB)
-
-TEXT ·Syscall9(SB),NOSPLIT,$0-104
- B syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
- B syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
- B syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_386.s b/vendor/golang.org/x/sys/unix/asm_openbsd_386.s
deleted file mode 100644
index 00576f3..0000000
--- a/vendor/golang.org/x/sys/unix/asm_openbsd_386.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !gccgo
-
-#include "textflag.h"
-
-//
-// System call support for 386, OpenBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT ·Syscall(SB),NOSPLIT,$0-28
- JMP syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-40
- JMP syscall·Syscall6(SB)
-
-TEXT ·Syscall9(SB),NOSPLIT,$0-52
- JMP syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
- JMP syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
- JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s b/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s
deleted file mode 100644
index 469bfa1..0000000
--- a/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !gccgo
-
-#include "textflag.h"
-
-//
-// System call support for ARM, OpenBSD
-//
-
-// Just jump to package syscall's implementation for all these functions.
-// The runtime may know about them.
-
-TEXT ·Syscall(SB),NOSPLIT,$0-28
- B syscall·Syscall(SB)
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-40
- B syscall·Syscall6(SB)
-
-TEXT ·Syscall9(SB),NOSPLIT,$0-52
- B syscall·Syscall9(SB)
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
- B syscall·RawSyscall(SB)
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
- B syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s b/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s
index 567a476..5e7a116 100644
--- a/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s
+++ b/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
+//go:build gc
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s b/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
index ded8260..f8c5394 100644
--- a/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
+++ b/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo
+//go:build gc
+// +build gc
#include "textflag.h"
diff --git a/vendor/golang.org/x/sys/unix/asm_zos_s390x.s b/vendor/golang.org/x/sys/unix/asm_zos_s390x.s
new file mode 100644
index 0000000..3b54e18
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_zos_s390x.s
@@ -0,0 +1,426 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x && gc
+// +build zos
+// +build s390x
+// +build gc
+
+#include "textflag.h"
+
+#define PSALAA 1208(R0)
+#define GTAB64(x) 80(x)
+#define LCA64(x) 88(x)
+#define CAA(x) 8(x)
+#define EDCHPXV(x) 1016(x) // in the CAA
+#define SAVSTACK_ASYNC(x) 336(x) // in the LCA
+
+// SS_*, where x=SAVSTACK_ASYNC
+#define SS_LE(x) 0(x)
+#define SS_GO(x) 8(x)
+#define SS_ERRNO(x) 16(x)
+#define SS_ERRNOJR(x) 20(x)
+
+#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6
+
+TEXT ·clearErrno(SB),NOSPLIT,$0-0
+ BL addrerrno<>(SB)
+ MOVD $0, 0(R3)
+ RET
+
+// Returns the address of errno in R3.
+TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
+ // Get library control area (LCA).
+ MOVW PSALAA, R8
+ MOVD LCA64(R8), R8
+
+ // Get __errno FuncDesc.
+ MOVD CAA(R8), R9
+ MOVD EDCHPXV(R9), R9
+ ADD $(0x156*16), R9
+ LMG 0(R9), R5, R6
+
+ // Switch to saved LE stack.
+ MOVD SAVSTACK_ASYNC(R8), R9
+ MOVD 0(R9), R4
+ MOVD $0, 0(R9)
+
+ // Call __errno function.
+ LE_CALL
+ NOPH
+
+ // Switch back to Go stack.
+ XOR R0, R0 // Restore R0 to $0.
+ MOVD R4, 0(R9) // Save stack pointer.
+ RET
+
+TEXT ·syscall_syscall(SB),NOSPLIT,$0-56
+ BL runtime·entersyscall(SB)
+ MOVD a1+8(FP), R1
+ MOVD a2+16(FP), R2
+ MOVD a3+24(FP), R3
+
+ // Get library control area (LCA).
+ MOVW PSALAA, R8
+ MOVD LCA64(R8), R8
+
+ // Get function.
+ MOVD CAA(R8), R9
+ MOVD EDCHPXV(R9), R9
+ MOVD trap+0(FP), R5
+ SLD $4, R5
+ ADD R5, R9
+ LMG 0(R9), R5, R6
+
+ // Restore LE stack.
+ MOVD SAVSTACK_ASYNC(R8), R9
+ MOVD 0(R9), R4
+ MOVD $0, 0(R9)
+
+ // Call function.
+ LE_CALL
+ NOPH
+ XOR R0, R0 // Restore R0 to $0.
+ MOVD R4, 0(R9) // Save stack pointer.
+
+ MOVD R3, r1+32(FP)
+ MOVD R0, r2+40(FP)
+ MOVD R0, err+48(FP)
+ MOVW R3, R4
+ CMP R4, $-1
+ BNE done
+ BL addrerrno<>(SB)
+ MOVWZ 0(R3), R3
+ MOVD R3, err+48(FP)
+done:
+ BL runtime·exitsyscall(SB)
+ RET
+
+TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56
+ MOVD a1+8(FP), R1
+ MOVD a2+16(FP), R2
+ MOVD a3+24(FP), R3
+
+ // Get library control area (LCA).
+ MOVW PSALAA, R8
+ MOVD LCA64(R8), R8
+
+ // Get function.
+ MOVD CAA(R8), R9
+ MOVD EDCHPXV(R9), R9
+ MOVD trap+0(FP), R5
+ SLD $4, R5
+ ADD R5, R9
+ LMG 0(R9), R5, R6
+
+ // Restore LE stack.
+ MOVD SAVSTACK_ASYNC(R8), R9
+ MOVD 0(R9), R4
+ MOVD $0, 0(R9)
+
+ // Call function.
+ LE_CALL
+ NOPH
+ XOR R0, R0 // Restore R0 to $0.
+ MOVD R4, 0(R9) // Save stack pointer.
+
+ MOVD R3, r1+32(FP)
+ MOVD R0, r2+40(FP)
+ MOVD R0, err+48(FP)
+ MOVW R3, R4
+ CMP R4, $-1
+ BNE done
+ BL addrerrno<>(SB)
+ MOVWZ 0(R3), R3
+ MOVD R3, err+48(FP)
+done:
+ RET
+
+TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80
+ BL runtime·entersyscall(SB)
+ MOVD a1+8(FP), R1
+ MOVD a2+16(FP), R2
+ MOVD a3+24(FP), R3
+
+ // Get library control area (LCA).
+ MOVW PSALAA, R8
+ MOVD LCA64(R8), R8
+
+ // Get function.
+ MOVD CAA(R8), R9
+ MOVD EDCHPXV(R9), R9
+ MOVD trap+0(FP), R5
+ SLD $4, R5
+ ADD R5, R9
+ LMG 0(R9), R5, R6
+
+ // Restore LE stack.
+ MOVD SAVSTACK_ASYNC(R8), R9
+ MOVD 0(R9), R4
+ MOVD $0, 0(R9)
+
+ // Fill in parameter list.
+ MOVD a4+32(FP), R12
+ MOVD R12, (2176+24)(R4)
+ MOVD a5+40(FP), R12
+ MOVD R12, (2176+32)(R4)
+ MOVD a6+48(FP), R12
+ MOVD R12, (2176+40)(R4)
+
+ // Call function.
+ LE_CALL
+ NOPH
+ XOR R0, R0 // Restore R0 to $0.
+ MOVD R4, 0(R9) // Save stack pointer.
+
+ MOVD R3, r1+56(FP)
+ MOVD R0, r2+64(FP)
+ MOVD R0, err+72(FP)
+ MOVW R3, R4
+ CMP R4, $-1
+ BNE done
+ BL addrerrno<>(SB)
+ MOVWZ 0(R3), R3
+ MOVD R3, err+72(FP)
+done:
+ BL runtime·exitsyscall(SB)
+ RET
+
+TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80
+ MOVD a1+8(FP), R1
+ MOVD a2+16(FP), R2
+ MOVD a3+24(FP), R3
+
+ // Get library control area (LCA).
+ MOVW PSALAA, R8
+ MOVD LCA64(R8), R8
+
+ // Get function.
+ MOVD CAA(R8), R9
+ MOVD EDCHPXV(R9), R9
+ MOVD trap+0(FP), R5
+ SLD $4, R5
+ ADD R5, R9
+ LMG 0(R9), R5, R6
+
+ // Restore LE stack.
+ MOVD SAVSTACK_ASYNC(R8), R9
+ MOVD 0(R9), R4
+ MOVD $0, 0(R9)
+
+ // Fill in parameter list.
+ MOVD a4+32(FP), R12
+ MOVD R12, (2176+24)(R4)
+ MOVD a5+40(FP), R12
+ MOVD R12, (2176+32)(R4)
+ MOVD a6+48(FP), R12
+ MOVD R12, (2176+40)(R4)
+
+ // Call function.
+ LE_CALL
+ NOPH
+ XOR R0, R0 // Restore R0 to $0.
+ MOVD R4, 0(R9) // Save stack pointer.
+
+ MOVD R3, r1+56(FP)
+ MOVD R0, r2+64(FP)
+ MOVD R0, err+72(FP)
+ MOVW R3, R4
+ CMP R4, $-1
+ BNE done
+ BL ·rrno<>(SB)
+ MOVWZ 0(R3), R3
+ MOVD R3, err+72(FP)
+done:
+ RET
+
+TEXT ·syscall_syscall9(SB),NOSPLIT,$0
+ BL runtime·entersyscall(SB)
+ MOVD a1+8(FP), R1
+ MOVD a2+16(FP), R2
+ MOVD a3+24(FP), R3
+
+ // Get library control area (LCA).
+ MOVW PSALAA, R8
+ MOVD LCA64(R8), R8
+
+ // Get function.
+ MOVD CAA(R8), R9
+ MOVD EDCHPXV(R9), R9
+ MOVD trap+0(FP), R5
+ SLD $4, R5
+ ADD R5, R9
+ LMG 0(R9), R5, R6
+
+ // Restore LE stack.
+ MOVD SAVSTACK_ASYNC(R8), R9
+ MOVD 0(R9), R4
+ MOVD $0, 0(R9)
+
+ // Fill in parameter list.
+ MOVD a4+32(FP), R12
+ MOVD R12, (2176+24)(R4)
+ MOVD a5+40(FP), R12
+ MOVD R12, (2176+32)(R4)
+ MOVD a6+48(FP), R12
+ MOVD R12, (2176+40)(R4)
+ MOVD a7+56(FP), R12
+ MOVD R12, (2176+48)(R4)
+ MOVD a8+64(FP), R12
+ MOVD R12, (2176+56)(R4)
+ MOVD a9+72(FP), R12
+ MOVD R12, (2176+64)(R4)
+
+ // Call function.
+ LE_CALL
+ NOPH
+ XOR R0, R0 // Restore R0 to $0.
+ MOVD R4, 0(R9) // Save stack pointer.
+
+ MOVD R3, r1+80(FP)
+ MOVD R0, r2+88(FP)
+ MOVD R0, err+96(FP)
+ MOVW R3, R4
+ CMP R4, $-1
+ BNE done
+ BL addrerrno<>(SB)
+ MOVWZ 0(R3), R3
+ MOVD R3, err+96(FP)
+done:
+ BL runtime·exitsyscall(SB)
+ RET
+
+TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0
+ MOVD a1+8(FP), R1
+ MOVD a2+16(FP), R2
+ MOVD a3+24(FP), R3
+
+ // Get library control area (LCA).
+ MOVW PSALAA, R8
+ MOVD LCA64(R8), R8
+
+ // Get function.
+ MOVD CAA(R8), R9
+ MOVD EDCHPXV(R9), R9
+ MOVD trap+0(FP), R5
+ SLD $4, R5
+ ADD R5, R9
+ LMG 0(R9), R5, R6
+
+ // Restore LE stack.
+ MOVD SAVSTACK_ASYNC(R8), R9
+ MOVD 0(R9), R4
+ MOVD $0, 0(R9)
+
+ // Fill in parameter list.
+ MOVD a4+32(FP), R12
+ MOVD R12, (2176+24)(R4)
+ MOVD a5+40(FP), R12
+ MOVD R12, (2176+32)(R4)
+ MOVD a6+48(FP), R12
+ MOVD R12, (2176+40)(R4)
+ MOVD a7+56(FP), R12
+ MOVD R12, (2176+48)(R4)
+ MOVD a8+64(FP), R12
+ MOVD R12, (2176+56)(R4)
+ MOVD a9+72(FP), R12
+ MOVD R12, (2176+64)(R4)
+
+ // Call function.
+ LE_CALL
+ NOPH
+ XOR R0, R0 // Restore R0 to $0.
+ MOVD R4, 0(R9) // Save stack pointer.
+
+ MOVD R3, r1+80(FP)
+ MOVD R0, r2+88(FP)
+ MOVD R0, err+96(FP)
+ MOVW R3, R4
+ CMP R4, $-1
+ BNE done
+ BL addrerrno<>(SB)
+ MOVWZ 0(R3), R3
+ MOVD R3, err+96(FP)
+done:
+ RET
+
+// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
+TEXT ·svcCall(SB),NOSPLIT,$0
+ BL runtime·save_g(SB) // Save g and stack pointer
+ MOVW PSALAA, R8
+ MOVD LCA64(R8), R8
+ MOVD SAVSTACK_ASYNC(R8), R9
+ MOVD R15, 0(R9)
+
+ MOVD argv+8(FP), R1 // Move function arguments into registers
+ MOVD dsa+16(FP), g
+ MOVD fnptr+0(FP), R15
+
+ BYTE $0x0D // Branch to function
+ BYTE $0xEF
+
+ BL runtime·load_g(SB) // Restore g and stack pointer
+ MOVW PSALAA, R8
+ MOVD LCA64(R8), R8
+ MOVD SAVSTACK_ASYNC(R8), R9
+ MOVD 0(R9), R15
+
+ RET
+
+// func svcLoad(name *byte) unsafe.Pointer
+TEXT ·svcLoad(SB),NOSPLIT,$0
+ MOVD R15, R2 // Save go stack pointer
+ MOVD name+0(FP), R0 // Move SVC args into registers
+ MOVD $0x80000000, R1
+ MOVD $0, R15
+ BYTE $0x0A // SVC 08 LOAD
+ BYTE $0x08
+ MOVW R15, R3 // Save return code from SVC
+ MOVD R2, R15 // Restore go stack pointer
+ CMP R3, $0 // Check SVC return code
+ BNE error
+
+ MOVD $-2, R3 // Reset last bit of entry point to zero
+ AND R0, R3
+ MOVD R3, addr+8(FP) // Return entry point returned by SVC
+ CMP R0, R3 // Check if last bit of entry point was set
+ BNE done
+
+ MOVD R15, R2 // Save go stack pointer
+ MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
+ BYTE $0x0A // SVC 09 DELETE
+ BYTE $0x09
+ MOVD R2, R15 // Restore go stack pointer
+
+error:
+ MOVD $0, addr+8(FP) // Return 0 on failure
+done:
+ XOR R0, R0 // Reset r0 to 0
+ RET
+
+// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
+TEXT ·svcUnload(SB),NOSPLIT,$0
+ MOVD R15, R2 // Save go stack pointer
+ MOVD name+0(FP), R0 // Move SVC args into registers
+ MOVD addr+8(FP), R15
+ BYTE $0x0A // SVC 09
+ BYTE $0x09
+ XOR R0, R0 // Reset r0 to 0
+ MOVD R15, R1 // Save SVC return code
+ MOVD R2, R15 // Restore go stack pointer
+ MOVD R1, rc+0(FP) // Return SVC return code
+ RET
+
+// func gettid() uint64
+TEXT ·gettid(SB), NOSPLIT, $0
+ // Get library control area (LCA).
+ MOVW PSALAA, R8
+ MOVD LCA64(R8), R8
+
+ // Get CEECAATHDID
+ MOVD CAA(R8), R9
+ MOVD 0x3D0(R9), R9
+ MOVD R9, ret+0(FP)
+
+ RET
diff --git a/vendor/golang.org/x/sys/unix/cap_freebsd.go b/vendor/golang.org/x/sys/unix/cap_freebsd.go
index df52048..0b7c6ad 100644
--- a/vendor/golang.org/x/sys/unix/cap_freebsd.go
+++ b/vendor/golang.org/x/sys/unix/cap_freebsd.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build freebsd
// +build freebsd
package unix
diff --git a/vendor/golang.org/x/sys/unix/constants.go b/vendor/golang.org/x/sys/unix/constants.go
index 3a6ac64..394a396 100644
--- a/vendor/golang.org/x/sys/unix/constants.go
+++ b/vendor/golang.org/x/sys/unix/constants.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package unix
diff --git a/vendor/golang.org/x/sys/unix/dev_aix_ppc.go b/vendor/golang.org/x/sys/unix/dev_aix_ppc.go
index 5e5fb45..65a9985 100644
--- a/vendor/golang.org/x/sys/unix/dev_aix_ppc.go
+++ b/vendor/golang.org/x/sys/unix/dev_aix_ppc.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix
-// +build ppc
+//go:build aix && ppc
+// +build aix,ppc
// Functions to access/create device major and minor numbers matching the
// encoding used by AIX.
diff --git a/vendor/golang.org/x/sys/unix/dev_aix_ppc64.go b/vendor/golang.org/x/sys/unix/dev_aix_ppc64.go
index 8b40124..8fc08ad 100644
--- a/vendor/golang.org/x/sys/unix/dev_aix_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/dev_aix_ppc64.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix
-// +build ppc64
+//go:build aix && ppc64
+// +build aix,ppc64
// Functions to access/create device major and minor numbers matching the
// encoding used AIX.
diff --git a/vendor/golang.org/x/sys/unix/dev_zos.go b/vendor/golang.org/x/sys/unix/dev_zos.go
new file mode 100644
index 0000000..a388e59
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/dev_zos.go
@@ -0,0 +1,29 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+// Functions to access/create device major and minor numbers matching the
+// encoding used by z/OS.
+//
+// The information below is extracted and adapted from macros.
+
+package unix
+
+// Major returns the major component of a z/OS device number.
+func Major(dev uint64) uint32 {
+ return uint32((dev >> 16) & 0x0000FFFF)
+}
+
+// Minor returns the minor component of a z/OS device number.
+func Minor(dev uint64) uint32 {
+ return uint32(dev & 0x0000FFFF)
+}
+
+// Mkdev returns a z/OS device number generated from the given major and minor
+// components.
+func Mkdev(major, minor uint32) uint64 {
+ return (uint64(major) << 16) | uint64(minor)
+}
diff --git a/vendor/golang.org/x/sys/unix/dirent.go b/vendor/golang.org/x/sys/unix/dirent.go
index 304016b..2499f97 100644
--- a/vendor/golang.org/x/sys/unix/dirent.go
+++ b/vendor/golang.org/x/sys/unix/dirent.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package unix
diff --git a/vendor/golang.org/x/sys/unix/endian_big.go b/vendor/golang.org/x/sys/unix/endian_big.go
index 5e92690..a520265 100644
--- a/vendor/golang.org/x/sys/unix/endian_big.go
+++ b/vendor/golang.org/x/sys/unix/endian_big.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
-// +build ppc64 s390x mips mips64
+//go:build armbe || arm64be || m68k || mips || mips64 || mips64p32 || ppc || ppc64 || s390 || s390x || shbe || sparc || sparc64
+// +build armbe arm64be m68k mips mips64 mips64p32 ppc ppc64 s390 s390x shbe sparc sparc64
package unix
diff --git a/vendor/golang.org/x/sys/unix/endian_little.go b/vendor/golang.org/x/sys/unix/endian_little.go
index bcdb5d3..b0f2bc4 100644
--- a/vendor/golang.org/x/sys/unix/endian_little.go
+++ b/vendor/golang.org/x/sys/unix/endian_little.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
-// +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le riscv64
+//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh
+// +build 386 amd64 amd64p32 alpha arm arm64 loong64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh
package unix
diff --git a/vendor/golang.org/x/sys/unix/env_unix.go b/vendor/golang.org/x/sys/unix/env_unix.go
index 84178b0..29ccc4d 100644
--- a/vendor/golang.org/x/sys/unix/env_unix.go
+++ b/vendor/golang.org/x/sys/unix/env_unix.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
// Unix environment variables.
diff --git a/vendor/golang.org/x/sys/unix/epoll_zos.go b/vendor/golang.org/x/sys/unix/epoll_zos.go
new file mode 100644
index 0000000..cedaf7e
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/epoll_zos.go
@@ -0,0 +1,221 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+package unix
+
+import (
+ "sync"
+)
+
+// This file simulates epoll on z/OS using poll.
+
+// Analogous to epoll_event on Linux.
+// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove?
+type EpollEvent struct {
+ Events uint32
+ Fd int32
+ Pad int32
+}
+
+const (
+ EPOLLERR = 0x8
+ EPOLLHUP = 0x10
+ EPOLLIN = 0x1
+ EPOLLMSG = 0x400
+ EPOLLOUT = 0x4
+ EPOLLPRI = 0x2
+ EPOLLRDBAND = 0x80
+ EPOLLRDNORM = 0x40
+ EPOLLWRBAND = 0x200
+ EPOLLWRNORM = 0x100
+ EPOLL_CTL_ADD = 0x1
+ EPOLL_CTL_DEL = 0x2
+ EPOLL_CTL_MOD = 0x3
+ // The following constants are part of the epoll API, but represent
+ // currently unsupported functionality on z/OS.
+ // EPOLL_CLOEXEC = 0x80000
+ // EPOLLET = 0x80000000
+ // EPOLLONESHOT = 0x40000000
+ // EPOLLRDHUP = 0x2000 // Typically used with edge-triggered notis
+ // EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode
+ // EPOLLWAKEUP = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability
+)
+
+// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL
+// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16).
+
+// epToPollEvt converts epoll event field to poll equivalent.
+// In epoll, Events is a 32-bit field, while poll uses 16 bits.
+func epToPollEvt(events uint32) int16 {
+ var ep2p = map[uint32]int16{
+ EPOLLIN: POLLIN,
+ EPOLLOUT: POLLOUT,
+ EPOLLHUP: POLLHUP,
+ EPOLLPRI: POLLPRI,
+ EPOLLERR: POLLERR,
+ }
+
+ var pollEvts int16 = 0
+ for epEvt, pEvt := range ep2p {
+ if (events & epEvt) != 0 {
+ pollEvts |= pEvt
+ }
+ }
+
+ return pollEvts
+}
+
+// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields.
+func pToEpollEvt(revents int16) uint32 {
+ var p2ep = map[int16]uint32{
+ POLLIN: EPOLLIN,
+ POLLOUT: EPOLLOUT,
+ POLLHUP: EPOLLHUP,
+ POLLPRI: EPOLLPRI,
+ POLLERR: EPOLLERR,
+ }
+
+ var epollEvts uint32 = 0
+ for pEvt, epEvt := range p2ep {
+ if (revents & pEvt) != 0 {
+ epollEvts |= epEvt
+ }
+ }
+
+ return epollEvts
+}
+
+// Per-process epoll implementation.
+type epollImpl struct {
+ mu sync.Mutex
+ epfd2ep map[int]*eventPoll
+ nextEpfd int
+}
+
+// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances.
+// On Linux, this is an in-kernel data structure accessed through a fd.
+type eventPoll struct {
+ mu sync.Mutex
+ fds map[int]*EpollEvent
+}
+
+// epoll impl for this process.
+var impl epollImpl = epollImpl{
+ epfd2ep: make(map[int]*eventPoll),
+ nextEpfd: 0,
+}
+
+func (e *epollImpl) epollcreate(size int) (epfd int, err error) {
+ e.mu.Lock()
+ defer e.mu.Unlock()
+ epfd = e.nextEpfd
+ e.nextEpfd++
+
+ e.epfd2ep[epfd] = &eventPoll{
+ fds: make(map[int]*EpollEvent),
+ }
+ return epfd, nil
+}
+
+func (e *epollImpl) epollcreate1(flag int) (fd int, err error) {
+ return e.epollcreate(4)
+}
+
+func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+ e.mu.Lock()
+ defer e.mu.Unlock()
+
+ ep, ok := e.epfd2ep[epfd]
+ if !ok {
+
+ return EBADF
+ }
+
+ switch op {
+ case EPOLL_CTL_ADD:
+ // TODO(neeilan): When we make epfds and fds disjoint, detect epoll
+ // loops here (instances watching each other) and return ELOOP.
+ if _, ok := ep.fds[fd]; ok {
+ return EEXIST
+ }
+ ep.fds[fd] = event
+ case EPOLL_CTL_MOD:
+ if _, ok := ep.fds[fd]; !ok {
+ return ENOENT
+ }
+ ep.fds[fd] = event
+ case EPOLL_CTL_DEL:
+ if _, ok := ep.fds[fd]; !ok {
+ return ENOENT
+ }
+ delete(ep.fds, fd)
+
+ }
+ return nil
+}
+
+// Must be called while holding ep.mu
+func (ep *eventPoll) getFds() []int {
+ fds := make([]int, len(ep.fds))
+ for fd := range ep.fds {
+ fds = append(fds, fd)
+ }
+ return fds
+}
+
+func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+ e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait
+ ep, ok := e.epfd2ep[epfd]
+
+ if !ok {
+ e.mu.Unlock()
+ return 0, EBADF
+ }
+
+ pollfds := make([]PollFd, 4)
+ for fd, epollevt := range ep.fds {
+ pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)})
+ }
+ e.mu.Unlock()
+
+ n, err = Poll(pollfds, msec)
+ if err != nil {
+ return n, err
+ }
+
+ i := 0
+ for _, pFd := range pollfds {
+ if pFd.Revents != 0 {
+ events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)}
+ i++
+ }
+
+ if i == n {
+ break
+ }
+ }
+
+ return n, nil
+}
+
+func EpollCreate(size int) (fd int, err error) {
+ return impl.epollcreate(size)
+}
+
+func EpollCreate1(flag int) (fd int, err error) {
+ return impl.epollcreate1(flag)
+}
+
+func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+ return impl.epollctl(epfd, op, fd, event)
+}
+
+// Because EpollWait mutates events, the caller is expected to coordinate
+// concurrent access if calling with the same epfd from multiple goroutines.
+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+ return impl.epollwait(epfd, events, msec)
+}
diff --git a/vendor/golang.org/x/sys/unix/errors_freebsd_386.go b/vendor/golang.org/x/sys/unix/errors_freebsd_386.go
deleted file mode 100644
index 761db66..0000000
--- a/vendor/golang.org/x/sys/unix/errors_freebsd_386.go
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
-// them here for backwards compatibility.
-
-package unix
-
-const (
- DLT_HHDLC = 0x79
- IFF_SMART = 0x20
- IFT_1822 = 0x2
- IFT_A12MPPSWITCH = 0x82
- IFT_AAL2 = 0xbb
- IFT_AAL5 = 0x31
- IFT_ADSL = 0x5e
- IFT_AFLANE8023 = 0x3b
- IFT_AFLANE8025 = 0x3c
- IFT_ARAP = 0x58
- IFT_ARCNET = 0x23
- IFT_ARCNETPLUS = 0x24
- IFT_ASYNC = 0x54
- IFT_ATM = 0x25
- IFT_ATMDXI = 0x69
- IFT_ATMFUNI = 0x6a
- IFT_ATMIMA = 0x6b
- IFT_ATMLOGICAL = 0x50
- IFT_ATMRADIO = 0xbd
- IFT_ATMSUBINTERFACE = 0x86
- IFT_ATMVCIENDPT = 0xc2
- IFT_ATMVIRTUAL = 0x95
- IFT_BGPPOLICYACCOUNTING = 0xa2
- IFT_BSC = 0x53
- IFT_CCTEMUL = 0x3d
- IFT_CEPT = 0x13
- IFT_CES = 0x85
- IFT_CHANNEL = 0x46
- IFT_CNR = 0x55
- IFT_COFFEE = 0x84
- IFT_COMPOSITELINK = 0x9b
- IFT_DCN = 0x8d
- IFT_DIGITALPOWERLINE = 0x8a
- IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
- IFT_DLSW = 0x4a
- IFT_DOCSCABLEDOWNSTREAM = 0x80
- IFT_DOCSCABLEMACLAYER = 0x7f
- IFT_DOCSCABLEUPSTREAM = 0x81
- IFT_DS0 = 0x51
- IFT_DS0BUNDLE = 0x52
- IFT_DS1FDL = 0xaa
- IFT_DS3 = 0x1e
- IFT_DTM = 0x8c
- IFT_DVBASILN = 0xac
- IFT_DVBASIOUT = 0xad
- IFT_DVBRCCDOWNSTREAM = 0x93
- IFT_DVBRCCMACLAYER = 0x92
- IFT_DVBRCCUPSTREAM = 0x94
- IFT_ENC = 0xf4
- IFT_EON = 0x19
- IFT_EPLRS = 0x57
- IFT_ESCON = 0x49
- IFT_ETHER = 0x6
- IFT_FAITH = 0xf2
- IFT_FAST = 0x7d
- IFT_FASTETHER = 0x3e
- IFT_FASTETHERFX = 0x45
- IFT_FDDI = 0xf
- IFT_FIBRECHANNEL = 0x38
- IFT_FRAMERELAYINTERCONNECT = 0x3a
- IFT_FRAMERELAYMPI = 0x5c
- IFT_FRDLCIENDPT = 0xc1
- IFT_FRELAY = 0x20
- IFT_FRELAYDCE = 0x2c
- IFT_FRF16MFRBUNDLE = 0xa3
- IFT_FRFORWARD = 0x9e
- IFT_G703AT2MB = 0x43
- IFT_G703AT64K = 0x42
- IFT_GIF = 0xf0
- IFT_GIGABITETHERNET = 0x75
- IFT_GR303IDT = 0xb2
- IFT_GR303RDT = 0xb1
- IFT_H323GATEKEEPER = 0xa4
- IFT_H323PROXY = 0xa5
- IFT_HDH1822 = 0x3
- IFT_HDLC = 0x76
- IFT_HDSL2 = 0xa8
- IFT_HIPERLAN2 = 0xb7
- IFT_HIPPI = 0x2f
- IFT_HIPPIINTERFACE = 0x39
- IFT_HOSTPAD = 0x5a
- IFT_HSSI = 0x2e
- IFT_HY = 0xe
- IFT_IBM370PARCHAN = 0x48
- IFT_IDSL = 0x9a
- IFT_IEEE80211 = 0x47
- IFT_IEEE80212 = 0x37
- IFT_IEEE8023ADLAG = 0xa1
- IFT_IFGSN = 0x91
- IFT_IMT = 0xbe
- IFT_INTERLEAVE = 0x7c
- IFT_IP = 0x7e
- IFT_IPFORWARD = 0x8e
- IFT_IPOVERATM = 0x72
- IFT_IPOVERCDLC = 0x6d
- IFT_IPOVERCLAW = 0x6e
- IFT_IPSWITCH = 0x4e
- IFT_IPXIP = 0xf9
- IFT_ISDN = 0x3f
- IFT_ISDNBASIC = 0x14
- IFT_ISDNPRIMARY = 0x15
- IFT_ISDNS = 0x4b
- IFT_ISDNU = 0x4c
- IFT_ISO88022LLC = 0x29
- IFT_ISO88023 = 0x7
- IFT_ISO88024 = 0x8
- IFT_ISO88025 = 0x9
- IFT_ISO88025CRFPINT = 0x62
- IFT_ISO88025DTR = 0x56
- IFT_ISO88025FIBER = 0x73
- IFT_ISO88026 = 0xa
- IFT_ISUP = 0xb3
- IFT_L3IPXVLAN = 0x89
- IFT_LAPB = 0x10
- IFT_LAPD = 0x4d
- IFT_LAPF = 0x77
- IFT_LOCALTALK = 0x2a
- IFT_LOOP = 0x18
- IFT_MEDIAMAILOVERIP = 0x8b
- IFT_MFSIGLINK = 0xa7
- IFT_MIOX25 = 0x26
- IFT_MODEM = 0x30
- IFT_MPC = 0x71
- IFT_MPLS = 0xa6
- IFT_MPLSTUNNEL = 0x96
- IFT_MSDSL = 0x8f
- IFT_MVL = 0xbf
- IFT_MYRINET = 0x63
- IFT_NFAS = 0xaf
- IFT_NSIP = 0x1b
- IFT_OPTICALCHANNEL = 0xc3
- IFT_OPTICALTRANSPORT = 0xc4
- IFT_OTHER = 0x1
- IFT_P10 = 0xc
- IFT_P80 = 0xd
- IFT_PARA = 0x22
- IFT_PFLOG = 0xf6
- IFT_PFSYNC = 0xf7
- IFT_PLC = 0xae
- IFT_POS = 0xab
- IFT_PPPMULTILINKBUNDLE = 0x6c
- IFT_PROPBWAP2MP = 0xb8
- IFT_PROPCNLS = 0x59
- IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
- IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
- IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
- IFT_PROPMUX = 0x36
- IFT_PROPWIRELESSP2P = 0x9d
- IFT_PTPSERIAL = 0x16
- IFT_PVC = 0xf1
- IFT_QLLC = 0x44
- IFT_RADIOMAC = 0xbc
- IFT_RADSL = 0x5f
- IFT_REACHDSL = 0xc0
- IFT_RFC1483 = 0x9f
- IFT_RS232 = 0x21
- IFT_RSRB = 0x4f
- IFT_SDLC = 0x11
- IFT_SDSL = 0x60
- IFT_SHDSL = 0xa9
- IFT_SIP = 0x1f
- IFT_SLIP = 0x1c
- IFT_SMDSDXI = 0x2b
- IFT_SMDSICIP = 0x34
- IFT_SONET = 0x27
- IFT_SONETOVERHEADCHANNEL = 0xb9
- IFT_SONETPATH = 0x32
- IFT_SONETVT = 0x33
- IFT_SRP = 0x97
- IFT_SS7SIGLINK = 0x9c
- IFT_STACKTOSTACK = 0x6f
- IFT_STARLAN = 0xb
- IFT_STF = 0xd7
- IFT_T1 = 0x12
- IFT_TDLC = 0x74
- IFT_TERMPAD = 0x5b
- IFT_TR008 = 0xb0
- IFT_TRANSPHDLC = 0x7b
- IFT_TUNNEL = 0x83
- IFT_ULTRA = 0x1d
- IFT_USB = 0xa0
- IFT_V11 = 0x40
- IFT_V35 = 0x2d
- IFT_V36 = 0x41
- IFT_V37 = 0x78
- IFT_VDSL = 0x61
- IFT_VIRTUALIPADDRESS = 0x70
- IFT_VOICEEM = 0x64
- IFT_VOICEENCAP = 0x67
- IFT_VOICEFXO = 0x65
- IFT_VOICEFXS = 0x66
- IFT_VOICEOVERATM = 0x98
- IFT_VOICEOVERFRAMERELAY = 0x99
- IFT_VOICEOVERIP = 0x68
- IFT_X213 = 0x5d
- IFT_X25 = 0x5
- IFT_X25DDN = 0x4
- IFT_X25HUNTGROUP = 0x7a
- IFT_X25MLP = 0x79
- IFT_X25PLE = 0x28
- IFT_XETHER = 0x1a
- IPPROTO_MAXID = 0x34
- IPV6_FAITH = 0x1d
- IPV6_MIN_MEMBERSHIPS = 0x1f
- IP_FAITH = 0x16
- IP_MAX_SOURCE_FILTER = 0x400
- IP_MIN_MEMBERSHIPS = 0x1f
- MAP_NORESERVE = 0x40
- MAP_RENAME = 0x20
- NET_RT_MAXID = 0x6
- RTF_PRCLONING = 0x10000
- RTM_OLDADD = 0x9
- RTM_OLDDEL = 0xa
- RT_CACHING_CONTEXT = 0x1
- RT_NORTREF = 0x2
- SIOCADDRT = 0x8030720a
- SIOCALIFADDR = 0x8118691b
- SIOCDELRT = 0x8030720b
- SIOCDLIFADDR = 0x8118691d
- SIOCGLIFADDR = 0xc118691c
- SIOCGLIFPHYADDR = 0xc118694b
- SIOCSLIFPHYADDR = 0x8118694a
-)
diff --git a/vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go
deleted file mode 100644
index 070f44b..0000000
--- a/vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
-// them here for backwards compatibility.
-
-package unix
-
-const (
- DLT_HHDLC = 0x79
- IFF_SMART = 0x20
- IFT_1822 = 0x2
- IFT_A12MPPSWITCH = 0x82
- IFT_AAL2 = 0xbb
- IFT_AAL5 = 0x31
- IFT_ADSL = 0x5e
- IFT_AFLANE8023 = 0x3b
- IFT_AFLANE8025 = 0x3c
- IFT_ARAP = 0x58
- IFT_ARCNET = 0x23
- IFT_ARCNETPLUS = 0x24
- IFT_ASYNC = 0x54
- IFT_ATM = 0x25
- IFT_ATMDXI = 0x69
- IFT_ATMFUNI = 0x6a
- IFT_ATMIMA = 0x6b
- IFT_ATMLOGICAL = 0x50
- IFT_ATMRADIO = 0xbd
- IFT_ATMSUBINTERFACE = 0x86
- IFT_ATMVCIENDPT = 0xc2
- IFT_ATMVIRTUAL = 0x95
- IFT_BGPPOLICYACCOUNTING = 0xa2
- IFT_BSC = 0x53
- IFT_CCTEMUL = 0x3d
- IFT_CEPT = 0x13
- IFT_CES = 0x85
- IFT_CHANNEL = 0x46
- IFT_CNR = 0x55
- IFT_COFFEE = 0x84
- IFT_COMPOSITELINK = 0x9b
- IFT_DCN = 0x8d
- IFT_DIGITALPOWERLINE = 0x8a
- IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
- IFT_DLSW = 0x4a
- IFT_DOCSCABLEDOWNSTREAM = 0x80
- IFT_DOCSCABLEMACLAYER = 0x7f
- IFT_DOCSCABLEUPSTREAM = 0x81
- IFT_DS0 = 0x51
- IFT_DS0BUNDLE = 0x52
- IFT_DS1FDL = 0xaa
- IFT_DS3 = 0x1e
- IFT_DTM = 0x8c
- IFT_DVBASILN = 0xac
- IFT_DVBASIOUT = 0xad
- IFT_DVBRCCDOWNSTREAM = 0x93
- IFT_DVBRCCMACLAYER = 0x92
- IFT_DVBRCCUPSTREAM = 0x94
- IFT_ENC = 0xf4
- IFT_EON = 0x19
- IFT_EPLRS = 0x57
- IFT_ESCON = 0x49
- IFT_ETHER = 0x6
- IFT_FAITH = 0xf2
- IFT_FAST = 0x7d
- IFT_FASTETHER = 0x3e
- IFT_FASTETHERFX = 0x45
- IFT_FDDI = 0xf
- IFT_FIBRECHANNEL = 0x38
- IFT_FRAMERELAYINTERCONNECT = 0x3a
- IFT_FRAMERELAYMPI = 0x5c
- IFT_FRDLCIENDPT = 0xc1
- IFT_FRELAY = 0x20
- IFT_FRELAYDCE = 0x2c
- IFT_FRF16MFRBUNDLE = 0xa3
- IFT_FRFORWARD = 0x9e
- IFT_G703AT2MB = 0x43
- IFT_G703AT64K = 0x42
- IFT_GIF = 0xf0
- IFT_GIGABITETHERNET = 0x75
- IFT_GR303IDT = 0xb2
- IFT_GR303RDT = 0xb1
- IFT_H323GATEKEEPER = 0xa4
- IFT_H323PROXY = 0xa5
- IFT_HDH1822 = 0x3
- IFT_HDLC = 0x76
- IFT_HDSL2 = 0xa8
- IFT_HIPERLAN2 = 0xb7
- IFT_HIPPI = 0x2f
- IFT_HIPPIINTERFACE = 0x39
- IFT_HOSTPAD = 0x5a
- IFT_HSSI = 0x2e
- IFT_HY = 0xe
- IFT_IBM370PARCHAN = 0x48
- IFT_IDSL = 0x9a
- IFT_IEEE80211 = 0x47
- IFT_IEEE80212 = 0x37
- IFT_IEEE8023ADLAG = 0xa1
- IFT_IFGSN = 0x91
- IFT_IMT = 0xbe
- IFT_INTERLEAVE = 0x7c
- IFT_IP = 0x7e
- IFT_IPFORWARD = 0x8e
- IFT_IPOVERATM = 0x72
- IFT_IPOVERCDLC = 0x6d
- IFT_IPOVERCLAW = 0x6e
- IFT_IPSWITCH = 0x4e
- IFT_IPXIP = 0xf9
- IFT_ISDN = 0x3f
- IFT_ISDNBASIC = 0x14
- IFT_ISDNPRIMARY = 0x15
- IFT_ISDNS = 0x4b
- IFT_ISDNU = 0x4c
- IFT_ISO88022LLC = 0x29
- IFT_ISO88023 = 0x7
- IFT_ISO88024 = 0x8
- IFT_ISO88025 = 0x9
- IFT_ISO88025CRFPINT = 0x62
- IFT_ISO88025DTR = 0x56
- IFT_ISO88025FIBER = 0x73
- IFT_ISO88026 = 0xa
- IFT_ISUP = 0xb3
- IFT_L3IPXVLAN = 0x89
- IFT_LAPB = 0x10
- IFT_LAPD = 0x4d
- IFT_LAPF = 0x77
- IFT_LOCALTALK = 0x2a
- IFT_LOOP = 0x18
- IFT_MEDIAMAILOVERIP = 0x8b
- IFT_MFSIGLINK = 0xa7
- IFT_MIOX25 = 0x26
- IFT_MODEM = 0x30
- IFT_MPC = 0x71
- IFT_MPLS = 0xa6
- IFT_MPLSTUNNEL = 0x96
- IFT_MSDSL = 0x8f
- IFT_MVL = 0xbf
- IFT_MYRINET = 0x63
- IFT_NFAS = 0xaf
- IFT_NSIP = 0x1b
- IFT_OPTICALCHANNEL = 0xc3
- IFT_OPTICALTRANSPORT = 0xc4
- IFT_OTHER = 0x1
- IFT_P10 = 0xc
- IFT_P80 = 0xd
- IFT_PARA = 0x22
- IFT_PFLOG = 0xf6
- IFT_PFSYNC = 0xf7
- IFT_PLC = 0xae
- IFT_POS = 0xab
- IFT_PPPMULTILINKBUNDLE = 0x6c
- IFT_PROPBWAP2MP = 0xb8
- IFT_PROPCNLS = 0x59
- IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
- IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
- IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
- IFT_PROPMUX = 0x36
- IFT_PROPWIRELESSP2P = 0x9d
- IFT_PTPSERIAL = 0x16
- IFT_PVC = 0xf1
- IFT_QLLC = 0x44
- IFT_RADIOMAC = 0xbc
- IFT_RADSL = 0x5f
- IFT_REACHDSL = 0xc0
- IFT_RFC1483 = 0x9f
- IFT_RS232 = 0x21
- IFT_RSRB = 0x4f
- IFT_SDLC = 0x11
- IFT_SDSL = 0x60
- IFT_SHDSL = 0xa9
- IFT_SIP = 0x1f
- IFT_SLIP = 0x1c
- IFT_SMDSDXI = 0x2b
- IFT_SMDSICIP = 0x34
- IFT_SONET = 0x27
- IFT_SONETOVERHEADCHANNEL = 0xb9
- IFT_SONETPATH = 0x32
- IFT_SONETVT = 0x33
- IFT_SRP = 0x97
- IFT_SS7SIGLINK = 0x9c
- IFT_STACKTOSTACK = 0x6f
- IFT_STARLAN = 0xb
- IFT_STF = 0xd7
- IFT_T1 = 0x12
- IFT_TDLC = 0x74
- IFT_TERMPAD = 0x5b
- IFT_TR008 = 0xb0
- IFT_TRANSPHDLC = 0x7b
- IFT_TUNNEL = 0x83
- IFT_ULTRA = 0x1d
- IFT_USB = 0xa0
- IFT_V11 = 0x40
- IFT_V35 = 0x2d
- IFT_V36 = 0x41
- IFT_V37 = 0x78
- IFT_VDSL = 0x61
- IFT_VIRTUALIPADDRESS = 0x70
- IFT_VOICEEM = 0x64
- IFT_VOICEENCAP = 0x67
- IFT_VOICEFXO = 0x65
- IFT_VOICEFXS = 0x66
- IFT_VOICEOVERATM = 0x98
- IFT_VOICEOVERFRAMERELAY = 0x99
- IFT_VOICEOVERIP = 0x68
- IFT_X213 = 0x5d
- IFT_X25 = 0x5
- IFT_X25DDN = 0x4
- IFT_X25HUNTGROUP = 0x7a
- IFT_X25MLP = 0x79
- IFT_X25PLE = 0x28
- IFT_XETHER = 0x1a
- IPPROTO_MAXID = 0x34
- IPV6_FAITH = 0x1d
- IPV6_MIN_MEMBERSHIPS = 0x1f
- IP_FAITH = 0x16
- IP_MAX_SOURCE_FILTER = 0x400
- IP_MIN_MEMBERSHIPS = 0x1f
- MAP_NORESERVE = 0x40
- MAP_RENAME = 0x20
- NET_RT_MAXID = 0x6
- RTF_PRCLONING = 0x10000
- RTM_OLDADD = 0x9
- RTM_OLDDEL = 0xa
- RT_CACHING_CONTEXT = 0x1
- RT_NORTREF = 0x2
- SIOCADDRT = 0x8040720a
- SIOCALIFADDR = 0x8118691b
- SIOCDELRT = 0x8040720b
- SIOCDLIFADDR = 0x8118691d
- SIOCGLIFADDR = 0xc118691c
- SIOCGLIFPHYADDR = 0xc118694b
- SIOCSLIFPHYADDR = 0x8118694a
-)
diff --git a/vendor/golang.org/x/sys/unix/errors_freebsd_arm.go b/vendor/golang.org/x/sys/unix/errors_freebsd_arm.go
deleted file mode 100644
index 856dca3..0000000
--- a/vendor/golang.org/x/sys/unix/errors_freebsd_arm.go
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package unix
-
-const (
- IFT_1822 = 0x2
- IFT_A12MPPSWITCH = 0x82
- IFT_AAL2 = 0xbb
- IFT_AAL5 = 0x31
- IFT_ADSL = 0x5e
- IFT_AFLANE8023 = 0x3b
- IFT_AFLANE8025 = 0x3c
- IFT_ARAP = 0x58
- IFT_ARCNET = 0x23
- IFT_ARCNETPLUS = 0x24
- IFT_ASYNC = 0x54
- IFT_ATM = 0x25
- IFT_ATMDXI = 0x69
- IFT_ATMFUNI = 0x6a
- IFT_ATMIMA = 0x6b
- IFT_ATMLOGICAL = 0x50
- IFT_ATMRADIO = 0xbd
- IFT_ATMSUBINTERFACE = 0x86
- IFT_ATMVCIENDPT = 0xc2
- IFT_ATMVIRTUAL = 0x95
- IFT_BGPPOLICYACCOUNTING = 0xa2
- IFT_BSC = 0x53
- IFT_CCTEMUL = 0x3d
- IFT_CEPT = 0x13
- IFT_CES = 0x85
- IFT_CHANNEL = 0x46
- IFT_CNR = 0x55
- IFT_COFFEE = 0x84
- IFT_COMPOSITELINK = 0x9b
- IFT_DCN = 0x8d
- IFT_DIGITALPOWERLINE = 0x8a
- IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
- IFT_DLSW = 0x4a
- IFT_DOCSCABLEDOWNSTREAM = 0x80
- IFT_DOCSCABLEMACLAYER = 0x7f
- IFT_DOCSCABLEUPSTREAM = 0x81
- IFT_DS0 = 0x51
- IFT_DS0BUNDLE = 0x52
- IFT_DS1FDL = 0xaa
- IFT_DS3 = 0x1e
- IFT_DTM = 0x8c
- IFT_DVBASILN = 0xac
- IFT_DVBASIOUT = 0xad
- IFT_DVBRCCDOWNSTREAM = 0x93
- IFT_DVBRCCMACLAYER = 0x92
- IFT_DVBRCCUPSTREAM = 0x94
- IFT_ENC = 0xf4
- IFT_EON = 0x19
- IFT_EPLRS = 0x57
- IFT_ESCON = 0x49
- IFT_ETHER = 0x6
- IFT_FAST = 0x7d
- IFT_FASTETHER = 0x3e
- IFT_FASTETHERFX = 0x45
- IFT_FDDI = 0xf
- IFT_FIBRECHANNEL = 0x38
- IFT_FRAMERELAYINTERCONNECT = 0x3a
- IFT_FRAMERELAYMPI = 0x5c
- IFT_FRDLCIENDPT = 0xc1
- IFT_FRELAY = 0x20
- IFT_FRELAYDCE = 0x2c
- IFT_FRF16MFRBUNDLE = 0xa3
- IFT_FRFORWARD = 0x9e
- IFT_G703AT2MB = 0x43
- IFT_G703AT64K = 0x42
- IFT_GIF = 0xf0
- IFT_GIGABITETHERNET = 0x75
- IFT_GR303IDT = 0xb2
- IFT_GR303RDT = 0xb1
- IFT_H323GATEKEEPER = 0xa4
- IFT_H323PROXY = 0xa5
- IFT_HDH1822 = 0x3
- IFT_HDLC = 0x76
- IFT_HDSL2 = 0xa8
- IFT_HIPERLAN2 = 0xb7
- IFT_HIPPI = 0x2f
- IFT_HIPPIINTERFACE = 0x39
- IFT_HOSTPAD = 0x5a
- IFT_HSSI = 0x2e
- IFT_HY = 0xe
- IFT_IBM370PARCHAN = 0x48
- IFT_IDSL = 0x9a
- IFT_IEEE80211 = 0x47
- IFT_IEEE80212 = 0x37
- IFT_IEEE8023ADLAG = 0xa1
- IFT_IFGSN = 0x91
- IFT_IMT = 0xbe
- IFT_INTERLEAVE = 0x7c
- IFT_IP = 0x7e
- IFT_IPFORWARD = 0x8e
- IFT_IPOVERATM = 0x72
- IFT_IPOVERCDLC = 0x6d
- IFT_IPOVERCLAW = 0x6e
- IFT_IPSWITCH = 0x4e
- IFT_ISDN = 0x3f
- IFT_ISDNBASIC = 0x14
- IFT_ISDNPRIMARY = 0x15
- IFT_ISDNS = 0x4b
- IFT_ISDNU = 0x4c
- IFT_ISO88022LLC = 0x29
- IFT_ISO88023 = 0x7
- IFT_ISO88024 = 0x8
- IFT_ISO88025 = 0x9
- IFT_ISO88025CRFPINT = 0x62
- IFT_ISO88025DTR = 0x56
- IFT_ISO88025FIBER = 0x73
- IFT_ISO88026 = 0xa
- IFT_ISUP = 0xb3
- IFT_L3IPXVLAN = 0x89
- IFT_LAPB = 0x10
- IFT_LAPD = 0x4d
- IFT_LAPF = 0x77
- IFT_LOCALTALK = 0x2a
- IFT_LOOP = 0x18
- IFT_MEDIAMAILOVERIP = 0x8b
- IFT_MFSIGLINK = 0xa7
- IFT_MIOX25 = 0x26
- IFT_MODEM = 0x30
- IFT_MPC = 0x71
- IFT_MPLS = 0xa6
- IFT_MPLSTUNNEL = 0x96
- IFT_MSDSL = 0x8f
- IFT_MVL = 0xbf
- IFT_MYRINET = 0x63
- IFT_NFAS = 0xaf
- IFT_NSIP = 0x1b
- IFT_OPTICALCHANNEL = 0xc3
- IFT_OPTICALTRANSPORT = 0xc4
- IFT_OTHER = 0x1
- IFT_P10 = 0xc
- IFT_P80 = 0xd
- IFT_PARA = 0x22
- IFT_PFLOG = 0xf6
- IFT_PFSYNC = 0xf7
- IFT_PLC = 0xae
- IFT_POS = 0xab
- IFT_PPPMULTILINKBUNDLE = 0x6c
- IFT_PROPBWAP2MP = 0xb8
- IFT_PROPCNLS = 0x59
- IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
- IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
- IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
- IFT_PROPMUX = 0x36
- IFT_PROPWIRELESSP2P = 0x9d
- IFT_PTPSERIAL = 0x16
- IFT_PVC = 0xf1
- IFT_QLLC = 0x44
- IFT_RADIOMAC = 0xbc
- IFT_RADSL = 0x5f
- IFT_REACHDSL = 0xc0
- IFT_RFC1483 = 0x9f
- IFT_RS232 = 0x21
- IFT_RSRB = 0x4f
- IFT_SDLC = 0x11
- IFT_SDSL = 0x60
- IFT_SHDSL = 0xa9
- IFT_SIP = 0x1f
- IFT_SLIP = 0x1c
- IFT_SMDSDXI = 0x2b
- IFT_SMDSICIP = 0x34
- IFT_SONET = 0x27
- IFT_SONETOVERHEADCHANNEL = 0xb9
- IFT_SONETPATH = 0x32
- IFT_SONETVT = 0x33
- IFT_SRP = 0x97
- IFT_SS7SIGLINK = 0x9c
- IFT_STACKTOSTACK = 0x6f
- IFT_STARLAN = 0xb
- IFT_STF = 0xd7
- IFT_T1 = 0x12
- IFT_TDLC = 0x74
- IFT_TERMPAD = 0x5b
- IFT_TR008 = 0xb0
- IFT_TRANSPHDLC = 0x7b
- IFT_TUNNEL = 0x83
- IFT_ULTRA = 0x1d
- IFT_USB = 0xa0
- IFT_V11 = 0x40
- IFT_V35 = 0x2d
- IFT_V36 = 0x41
- IFT_V37 = 0x78
- IFT_VDSL = 0x61
- IFT_VIRTUALIPADDRESS = 0x70
- IFT_VOICEEM = 0x64
- IFT_VOICEENCAP = 0x67
- IFT_VOICEFXO = 0x65
- IFT_VOICEFXS = 0x66
- IFT_VOICEOVERATM = 0x98
- IFT_VOICEOVERFRAMERELAY = 0x99
- IFT_VOICEOVERIP = 0x68
- IFT_X213 = 0x5d
- IFT_X25 = 0x5
- IFT_X25DDN = 0x4
- IFT_X25HUNTGROUP = 0x7a
- IFT_X25MLP = 0x79
- IFT_X25PLE = 0x28
- IFT_XETHER = 0x1a
-
- // missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go
- IFF_SMART = 0x20
- IFT_FAITH = 0xf2
- IFT_IPXIP = 0xf9
- IPPROTO_MAXID = 0x34
- IPV6_FAITH = 0x1d
- IP_FAITH = 0x16
- MAP_NORESERVE = 0x40
- MAP_RENAME = 0x20
- NET_RT_MAXID = 0x6
- RTF_PRCLONING = 0x10000
- RTM_OLDADD = 0x9
- RTM_OLDDEL = 0xa
- SIOCADDRT = 0x8030720a
- SIOCALIFADDR = 0x8118691b
- SIOCDELRT = 0x8030720b
- SIOCDLIFADDR = 0x8118691d
- SIOCGLIFADDR = 0xc118691c
- SIOCGLIFPHYADDR = 0xc118694b
- SIOCSLIFPHYADDR = 0x8118694a
-)
diff --git a/vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go
deleted file mode 100644
index 946dcf3..0000000
--- a/vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
-// them here for backwards compatibility.
-
-package unix
-
-const (
- DLT_HHDLC = 0x79
- IPV6_MIN_MEMBERSHIPS = 0x1f
- IP_MAX_SOURCE_FILTER = 0x400
- IP_MIN_MEMBERSHIPS = 0x1f
- RT_CACHING_CONTEXT = 0x1
- RT_NORTREF = 0x2
-)
diff --git a/vendor/golang.org/x/sys/unix/fcntl.go b/vendor/golang.org/x/sys/unix/fcntl.go
index 4dc5348..e9b9912 100644
--- a/vendor/golang.org/x/sys/unix/fcntl.go
+++ b/vendor/golang.org/x/sys/unix/fcntl.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
// +build dragonfly freebsd linux netbsd openbsd
package unix
diff --git a/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go b/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go
index fc0e50e..29d4480 100644
--- a/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go
+++ b/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go
@@ -1,9 +1,10 @@
-// +build linux,386 linux,arm linux,mips linux,mipsle
-
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build (linux && 386) || (linux && arm) || (linux && mips) || (linux && mipsle) || (linux && ppc)
+// +build linux,386 linux,arm linux,mips linux,mipsle linux,ppc
+
package unix
func init() {
diff --git a/vendor/golang.org/x/sys/unix/fdset.go b/vendor/golang.org/x/sys/unix/fdset.go
index b27be0a..a8068f9 100644
--- a/vendor/golang.org/x/sys/unix/fdset.go
+++ b/vendor/golang.org/x/sys/unix/fdset.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package unix
diff --git a/vendor/golang.org/x/sys/unix/fstatfs_zos.go b/vendor/golang.org/x/sys/unix/fstatfs_zos.go
new file mode 100644
index 0000000..e377cc9
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/fstatfs_zos.go
@@ -0,0 +1,164 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+package unix
+
+import (
+ "unsafe"
+)
+
+// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent.
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+ var stat_v Statvfs_t
+ err = Fstatvfs(fd, &stat_v)
+ if err == nil {
+ // populate stat
+ stat.Type = 0
+ stat.Bsize = stat_v.Bsize
+ stat.Blocks = stat_v.Blocks
+ stat.Bfree = stat_v.Bfree
+ stat.Bavail = stat_v.Bavail
+ stat.Files = stat_v.Files
+ stat.Ffree = stat_v.Ffree
+ stat.Fsid = stat_v.Fsid
+ stat.Namelen = stat_v.Namemax
+ stat.Frsize = stat_v.Frsize
+ stat.Flags = stat_v.Flag
+ for passn := 0; passn < 5; passn++ {
+ switch passn {
+ case 0:
+ err = tryGetmntent64(stat)
+ break
+ case 1:
+ err = tryGetmntent128(stat)
+ break
+ case 2:
+ err = tryGetmntent256(stat)
+ break
+ case 3:
+ err = tryGetmntent512(stat)
+ break
+ case 4:
+ err = tryGetmntent1024(stat)
+ break
+ default:
+ break
+ }
+ //proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred)
+ if err == nil || err != nil && err != ERANGE {
+ break
+ }
+ }
+ }
+ return err
+}
+
+func tryGetmntent64(stat *Statfs_t) (err error) {
+ var mnt_ent_buffer struct {
+ header W_Mnth
+ filesys_info [64]W_Mntent
+ }
+ var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
+ fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
+ if err != nil {
+ return err
+ }
+ err = ERANGE //return ERANGE if no match is found in this batch
+ for i := 0; i < fs_count; i++ {
+ if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
+ stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
+ err = nil
+ break
+ }
+ }
+ return err
+}
+
+func tryGetmntent128(stat *Statfs_t) (err error) {
+ var mnt_ent_buffer struct {
+ header W_Mnth
+ filesys_info [128]W_Mntent
+ }
+ var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
+ fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
+ if err != nil {
+ return err
+ }
+ err = ERANGE //return ERANGE if no match is found in this batch
+ for i := 0; i < fs_count; i++ {
+ if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
+ stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
+ err = nil
+ break
+ }
+ }
+ return err
+}
+
+func tryGetmntent256(stat *Statfs_t) (err error) {
+ var mnt_ent_buffer struct {
+ header W_Mnth
+ filesys_info [256]W_Mntent
+ }
+ var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
+ fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
+ if err != nil {
+ return err
+ }
+ err = ERANGE //return ERANGE if no match is found in this batch
+ for i := 0; i < fs_count; i++ {
+ if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
+ stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
+ err = nil
+ break
+ }
+ }
+ return err
+}
+
+func tryGetmntent512(stat *Statfs_t) (err error) {
+ var mnt_ent_buffer struct {
+ header W_Mnth
+ filesys_info [512]W_Mntent
+ }
+ var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
+ fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
+ if err != nil {
+ return err
+ }
+ err = ERANGE //return ERANGE if no match is found in this batch
+ for i := 0; i < fs_count; i++ {
+ if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
+ stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
+ err = nil
+ break
+ }
+ }
+ return err
+}
+
+func tryGetmntent1024(stat *Statfs_t) (err error) {
+ var mnt_ent_buffer struct {
+ header W_Mnth
+ filesys_info [1024]W_Mntent
+ }
+ var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
+ fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
+ if err != nil {
+ return err
+ }
+ err = ERANGE //return ERANGE if no match is found in this batch
+ for i := 0; i < fs_count; i++ {
+ if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
+ stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
+ err = nil
+ break
+ }
+ }
+ return err
+}
diff --git a/vendor/golang.org/x/sys/unix/gccgo.go b/vendor/golang.org/x/sys/unix/gccgo.go
index 86032c1..b06f52d 100644
--- a/vendor/golang.org/x/sys/unix/gccgo.go
+++ b/vendor/golang.org/x/sys/unix/gccgo.go
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build gccgo
-// +build !aix
+//go:build gccgo && !aix && !hurd
+// +build gccgo,!aix,!hurd
package unix
diff --git a/vendor/golang.org/x/sys/unix/gccgo_c.c b/vendor/golang.org/x/sys/unix/gccgo_c.c
index 2cb1fef..f98a1c5 100644
--- a/vendor/golang.org/x/sys/unix/gccgo_c.c
+++ b/vendor/golang.org/x/sys/unix/gccgo_c.c
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build gccgo
-// +build !aix
+//go:build gccgo && !aix && !hurd
+// +build gccgo,!aix,!hurd
#include
#include
diff --git a/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go b/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
index 251a977..e60e49a 100644
--- a/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build gccgo && linux && amd64
// +build gccgo,linux,amd64
package unix
diff --git a/vendor/golang.org/x/sys/unix/ifreq_linux.go b/vendor/golang.org/x/sys/unix/ifreq_linux.go
new file mode 100644
index 0000000..15721a5
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/ifreq_linux.go
@@ -0,0 +1,142 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux
+// +build linux
+
+package unix
+
+import (
+ "unsafe"
+)
+
+// Helpers for dealing with ifreq since it contains a union and thus requires a
+// lot of unsafe.Pointer casts to use properly.
+
+// An Ifreq is a type-safe wrapper around the raw ifreq struct. An Ifreq
+// contains an interface name and a union of arbitrary data which can be
+// accessed using the Ifreq's methods. To create an Ifreq, use the NewIfreq
+// function.
+//
+// Use the Name method to access the stored interface name. The union data
+// fields can be get and set using the following methods:
+// - Uint16/SetUint16: flags
+// - Uint32/SetUint32: ifindex, metric, mtu
+type Ifreq struct{ raw ifreq }
+
+// NewIfreq creates an Ifreq with the input network interface name after
+// validating the name does not exceed IFNAMSIZ-1 (trailing NULL required)
+// bytes.
+func NewIfreq(name string) (*Ifreq, error) {
+ // Leave room for terminating NULL byte.
+ if len(name) >= IFNAMSIZ {
+ return nil, EINVAL
+ }
+
+ var ifr ifreq
+ copy(ifr.Ifrn[:], name)
+
+ return &Ifreq{raw: ifr}, nil
+}
+
+// TODO(mdlayher): get/set methods for hardware address sockaddr, char array, etc.
+
+// Name returns the interface name associated with the Ifreq.
+func (ifr *Ifreq) Name() string {
+ return ByteSliceToString(ifr.raw.Ifrn[:])
+}
+
+// According to netdevice(7), only AF_INET addresses are returned for numerous
+// sockaddr ioctls. For convenience, we expose these as Inet4Addr since the Port
+// field and other data is always empty.
+
+// Inet4Addr returns the Ifreq union data from an embedded sockaddr as a C
+// in_addr/Go []byte (4-byte IPv4 address) value. If the sockaddr family is not
+// AF_INET, an error is returned.
+func (ifr *Ifreq) Inet4Addr() ([]byte, error) {
+ raw := *(*RawSockaddrInet4)(unsafe.Pointer(&ifr.raw.Ifru[:SizeofSockaddrInet4][0]))
+ if raw.Family != AF_INET {
+ // Cannot safely interpret raw.Addr bytes as an IPv4 address.
+ return nil, EINVAL
+ }
+
+ return raw.Addr[:], nil
+}
+
+// SetInet4Addr sets a C in_addr/Go []byte (4-byte IPv4 address) value in an
+// embedded sockaddr within the Ifreq's union data. v must be 4 bytes in length
+// or an error will be returned.
+func (ifr *Ifreq) SetInet4Addr(v []byte) error {
+ if len(v) != 4 {
+ return EINVAL
+ }
+
+ var addr [4]byte
+ copy(addr[:], v)
+
+ ifr.clear()
+ *(*RawSockaddrInet4)(
+ unsafe.Pointer(&ifr.raw.Ifru[:SizeofSockaddrInet4][0]),
+ ) = RawSockaddrInet4{
+ // Always set IP family as ioctls would require it anyway.
+ Family: AF_INET,
+ Addr: addr,
+ }
+
+ return nil
+}
+
+// Uint16 returns the Ifreq union data as a C short/Go uint16 value.
+func (ifr *Ifreq) Uint16() uint16 {
+ return *(*uint16)(unsafe.Pointer(&ifr.raw.Ifru[:2][0]))
+}
+
+// SetUint16 sets a C short/Go uint16 value as the Ifreq's union data.
+func (ifr *Ifreq) SetUint16(v uint16) {
+ ifr.clear()
+ *(*uint16)(unsafe.Pointer(&ifr.raw.Ifru[:2][0])) = v
+}
+
+// Uint32 returns the Ifreq union data as a C int/Go uint32 value.
+func (ifr *Ifreq) Uint32() uint32 {
+ return *(*uint32)(unsafe.Pointer(&ifr.raw.Ifru[:4][0]))
+}
+
+// SetUint32 sets a C int/Go uint32 value as the Ifreq's union data.
+func (ifr *Ifreq) SetUint32(v uint32) {
+ ifr.clear()
+ *(*uint32)(unsafe.Pointer(&ifr.raw.Ifru[:4][0])) = v
+}
+
+// clear zeroes the ifreq's union field to prevent trailing garbage data from
+// being sent to the kernel if an ifreq is reused.
+func (ifr *Ifreq) clear() {
+ for i := range ifr.raw.Ifru {
+ ifr.raw.Ifru[i] = 0
+ }
+}
+
+// TODO(mdlayher): export as IfreqData? For now we can provide helpers such as
+// IoctlGetEthtoolDrvinfo which use these APIs under the hood.
+
+// An ifreqData is an Ifreq which carries pointer data. To produce an ifreqData,
+// use the Ifreq.withData method.
+type ifreqData struct {
+ name [IFNAMSIZ]byte
+ // A type separate from ifreq is required in order to comply with the
+ // unsafe.Pointer rules since the "pointer-ness" of data would not be
+ // preserved if it were cast into the byte array of a raw ifreq.
+ data unsafe.Pointer
+ // Pad to the same size as ifreq.
+ _ [len(ifreq{}.Ifru) - SizeofPtr]byte
+}
+
+// withData produces an ifreqData with the pointer p set for ioctls which require
+// arbitrary pointer data.
+func (ifr Ifreq) withData(p unsafe.Pointer) ifreqData {
+ return ifreqData{
+ name: ifr.raw.Ifrn,
+ data: p,
+ }
+}
diff --git a/vendor/golang.org/x/sys/unix/ioctl_linux.go b/vendor/golang.org/x/sys/unix/ioctl_linux.go
new file mode 100644
index 0000000..0d12c08
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/ioctl_linux.go
@@ -0,0 +1,233 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import "unsafe"
+
+// IoctlRetInt performs an ioctl operation specified by req on a device
+// associated with opened file descriptor fd, and returns a non-negative
+// integer that is returned by the ioctl syscall.
+func IoctlRetInt(fd int, req uint) (int, error) {
+ ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0)
+ if err != 0 {
+ return 0, err
+ }
+ return int(ret), nil
+}
+
+func IoctlGetUint32(fd int, req uint) (uint32, error) {
+ var value uint32
+ err := ioctlPtr(fd, req, unsafe.Pointer(&value))
+ return value, err
+}
+
+func IoctlGetRTCTime(fd int) (*RTCTime, error) {
+ var value RTCTime
+ err := ioctlPtr(fd, RTC_RD_TIME, unsafe.Pointer(&value))
+ return &value, err
+}
+
+func IoctlSetRTCTime(fd int, value *RTCTime) error {
+ return ioctlPtr(fd, RTC_SET_TIME, unsafe.Pointer(value))
+}
+
+func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {
+ var value RTCWkAlrm
+ err := ioctlPtr(fd, RTC_WKALM_RD, unsafe.Pointer(&value))
+ return &value, err
+}
+
+func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {
+ return ioctlPtr(fd, RTC_WKALM_SET, unsafe.Pointer(value))
+}
+
+// IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network
+// device specified by ifname.
+func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {
+ ifr, err := NewIfreq(ifname)
+ if err != nil {
+ return nil, err
+ }
+
+ value := EthtoolDrvinfo{Cmd: ETHTOOL_GDRVINFO}
+ ifrd := ifr.withData(unsafe.Pointer(&value))
+
+ err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd)
+ return &value, err
+}
+
+// IoctlGetWatchdogInfo fetches information about a watchdog device from the
+// Linux watchdog API. For more information, see:
+// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
+func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) {
+ var value WatchdogInfo
+ err := ioctlPtr(fd, WDIOC_GETSUPPORT, unsafe.Pointer(&value))
+ return &value, err
+}
+
+// IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For
+// more information, see:
+// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
+func IoctlWatchdogKeepalive(fd int) error {
+ // arg is ignored and not a pointer, so ioctl is fine instead of ioctlPtr.
+ return ioctl(fd, WDIOC_KEEPALIVE, 0)
+}
+
+// IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the
+// range of data conveyed in value to the file associated with the file
+// descriptor destFd. See the ioctl_ficlonerange(2) man page for details.
+func IoctlFileCloneRange(destFd int, value *FileCloneRange) error {
+ return ioctlPtr(destFd, FICLONERANGE, unsafe.Pointer(value))
+}
+
+// IoctlFileClone performs an FICLONE ioctl operation to clone the entire file
+// associated with the file description srcFd to the file associated with the
+// file descriptor destFd. See the ioctl_ficlone(2) man page for details.
+func IoctlFileClone(destFd, srcFd int) error {
+ return ioctl(destFd, FICLONE, uintptr(srcFd))
+}
+
+type FileDedupeRange struct {
+ Src_offset uint64
+ Src_length uint64
+ Reserved1 uint16
+ Reserved2 uint32
+ Info []FileDedupeRangeInfo
+}
+
+type FileDedupeRangeInfo struct {
+ Dest_fd int64
+ Dest_offset uint64
+ Bytes_deduped uint64
+ Status int32
+ Reserved uint32
+}
+
+// IoctlFileDedupeRange performs an FIDEDUPERANGE ioctl operation to share the
+// range of data conveyed in value from the file associated with the file
+// descriptor srcFd to the value.Info destinations. See the
+// ioctl_fideduperange(2) man page for details.
+func IoctlFileDedupeRange(srcFd int, value *FileDedupeRange) error {
+ buf := make([]byte, SizeofRawFileDedupeRange+
+ len(value.Info)*SizeofRawFileDedupeRangeInfo)
+ rawrange := (*RawFileDedupeRange)(unsafe.Pointer(&buf[0]))
+ rawrange.Src_offset = value.Src_offset
+ rawrange.Src_length = value.Src_length
+ rawrange.Dest_count = uint16(len(value.Info))
+ rawrange.Reserved1 = value.Reserved1
+ rawrange.Reserved2 = value.Reserved2
+
+ for i := range value.Info {
+ rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(
+ uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +
+ uintptr(i*SizeofRawFileDedupeRangeInfo)))
+ rawinfo.Dest_fd = value.Info[i].Dest_fd
+ rawinfo.Dest_offset = value.Info[i].Dest_offset
+ rawinfo.Bytes_deduped = value.Info[i].Bytes_deduped
+ rawinfo.Status = value.Info[i].Status
+ rawinfo.Reserved = value.Info[i].Reserved
+ }
+
+ err := ioctlPtr(srcFd, FIDEDUPERANGE, unsafe.Pointer(&buf[0]))
+
+ // Output
+ for i := range value.Info {
+ rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(
+ uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +
+ uintptr(i*SizeofRawFileDedupeRangeInfo)))
+ value.Info[i].Dest_fd = rawinfo.Dest_fd
+ value.Info[i].Dest_offset = rawinfo.Dest_offset
+ value.Info[i].Bytes_deduped = rawinfo.Bytes_deduped
+ value.Info[i].Status = rawinfo.Status
+ value.Info[i].Reserved = rawinfo.Reserved
+ }
+
+ return err
+}
+
+func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error {
+ return ioctlPtr(fd, HIDIOCGRDESC, unsafe.Pointer(value))
+}
+
+func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) {
+ var value HIDRawDevInfo
+ err := ioctlPtr(fd, HIDIOCGRAWINFO, unsafe.Pointer(&value))
+ return &value, err
+}
+
+func IoctlHIDGetRawName(fd int) (string, error) {
+ var value [_HIDIOCGRAWNAME_LEN]byte
+ err := ioctlPtr(fd, _HIDIOCGRAWNAME, unsafe.Pointer(&value[0]))
+ return ByteSliceToString(value[:]), err
+}
+
+func IoctlHIDGetRawPhys(fd int) (string, error) {
+ var value [_HIDIOCGRAWPHYS_LEN]byte
+ err := ioctlPtr(fd, _HIDIOCGRAWPHYS, unsafe.Pointer(&value[0]))
+ return ByteSliceToString(value[:]), err
+}
+
+func IoctlHIDGetRawUniq(fd int) (string, error) {
+ var value [_HIDIOCGRAWUNIQ_LEN]byte
+ err := ioctlPtr(fd, _HIDIOCGRAWUNIQ, unsafe.Pointer(&value[0]))
+ return ByteSliceToString(value[:]), err
+}
+
+// IoctlIfreq performs an ioctl using an Ifreq structure for input and/or
+// output. See the netdevice(7) man page for details.
+func IoctlIfreq(fd int, req uint, value *Ifreq) error {
+ // It is possible we will add more fields to *Ifreq itself later to prevent
+ // misuse, so pass the raw *ifreq directly.
+ return ioctlPtr(fd, req, unsafe.Pointer(&value.raw))
+}
+
+// TODO(mdlayher): export if and when IfreqData is exported.
+
+// ioctlIfreqData performs an ioctl using an ifreqData structure for input
+// and/or output. See the netdevice(7) man page for details.
+func ioctlIfreqData(fd int, req uint, value *ifreqData) error {
+ // The memory layout of IfreqData (type-safe) and ifreq (not type-safe) are
+ // identical so pass *IfreqData directly.
+ return ioctlPtr(fd, req, unsafe.Pointer(value))
+}
+
+// IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an
+// existing KCM socket, returning a structure containing the file descriptor of
+// the new socket.
+func IoctlKCMClone(fd int) (*KCMClone, error) {
+ var info KCMClone
+ if err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil {
+ return nil, err
+ }
+
+ return &info, nil
+}
+
+// IoctlKCMAttach attaches a TCP socket and associated BPF program file
+// descriptor to a multiplexor.
+func IoctlKCMAttach(fd int, info KCMAttach) error {
+ return ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info))
+}
+
+// IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor.
+func IoctlKCMUnattach(fd int, info KCMUnattach) error {
+ return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
+}
+
+// IoctlLoopGetStatus64 gets the status of the loop device associated with the
+// file descriptor fd using the LOOP_GET_STATUS64 operation.
+func IoctlLoopGetStatus64(fd int) (*LoopInfo64, error) {
+ var value LoopInfo64
+ if err := ioctlPtr(fd, LOOP_GET_STATUS64, unsafe.Pointer(&value)); err != nil {
+ return nil, err
+ }
+ return &value, nil
+}
+
+// IoctlLoopSetStatus64 sets the status of the loop device associated with the
+// file descriptor fd using the LOOP_SET_STATUS64 operation.
+func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error {
+ return ioctlPtr(fd, LOOP_SET_STATUS64, unsafe.Pointer(value))
+}
diff --git a/vendor/golang.org/x/sys/unix/ioctl_signed.go b/vendor/golang.org/x/sys/unix/ioctl_signed.go
new file mode 100644
index 0000000..7def958
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/ioctl_signed.go
@@ -0,0 +1,70 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || solaris
+// +build aix solaris
+
+package unix
+
+import (
+ "unsafe"
+)
+
+// ioctl itself should not be exposed directly, but additional get/set
+// functions for specific types are permissible.
+
+// IoctlSetInt performs an ioctl operation which sets an integer value
+// on fd, using the specified request number.
+func IoctlSetInt(fd int, req int, value int) error {
+ return ioctl(fd, req, uintptr(value))
+}
+
+// IoctlSetPointerInt performs an ioctl operation which sets an
+// integer value on fd, using the specified request number. The ioctl
+// argument is called with a pointer to the integer value, rather than
+// passing the integer value directly.
+func IoctlSetPointerInt(fd int, req int, value int) error {
+ v := int32(value)
+ return ioctlPtr(fd, req, unsafe.Pointer(&v))
+}
+
+// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
+//
+// To change fd's window size, the req argument should be TIOCSWINSZ.
+func IoctlSetWinsize(fd int, req int, value *Winsize) error {
+ // TODO: if we get the chance, remove the req parameter and
+ // hardcode TIOCSWINSZ.
+ return ioctlPtr(fd, req, unsafe.Pointer(value))
+}
+
+// IoctlSetTermios performs an ioctl on fd with a *Termios.
+//
+// The req value will usually be TCSETA or TIOCSETA.
+func IoctlSetTermios(fd int, req int, value *Termios) error {
+ // TODO: if we get the chance, remove the req parameter.
+ return ioctlPtr(fd, req, unsafe.Pointer(value))
+}
+
+// IoctlGetInt performs an ioctl operation which gets an integer value
+// from fd, using the specified request number.
+//
+// A few ioctl requests use the return value as an output parameter;
+// for those, IoctlRetInt should be used instead of this function.
+func IoctlGetInt(fd int, req int) (int, error) {
+ var value int
+ err := ioctlPtr(fd, req, unsafe.Pointer(&value))
+ return value, err
+}
+
+func IoctlGetWinsize(fd int, req int) (*Winsize, error) {
+ var value Winsize
+ err := ioctlPtr(fd, req, unsafe.Pointer(&value))
+ return &value, err
+}
+
+func IoctlGetTermios(fd int, req int) (*Termios, error) {
+ var value Termios
+ err := ioctlPtr(fd, req, unsafe.Pointer(&value))
+ return &value, err
+}
diff --git a/vendor/golang.org/x/sys/unix/ioctl.go b/vendor/golang.org/x/sys/unix/ioctl_unsigned.go
similarity index 79%
rename from vendor/golang.org/x/sys/unix/ioctl.go
rename to vendor/golang.org/x/sys/unix/ioctl_unsigned.go
index 5641678..649913d 100644
--- a/vendor/golang.org/x/sys/unix/ioctl.go
+++ b/vendor/golang.org/x/sys/unix/ioctl_unsigned.go
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd
+// +build darwin dragonfly freebsd hurd linux netbsd openbsd
package unix
import (
- "runtime"
"unsafe"
)
@@ -26,7 +26,7 @@ func IoctlSetInt(fd int, req uint, value int) error {
// passing the integer value directly.
func IoctlSetPointerInt(fd int, req uint, value int) error {
v := int32(value)
- return ioctl(fd, req, uintptr(unsafe.Pointer(&v)))
+ return ioctlPtr(fd, req, unsafe.Pointer(&v))
}
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
@@ -35,9 +35,7 @@ func IoctlSetPointerInt(fd int, req uint, value int) error {
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
// TODO: if we get the chance, remove the req parameter and
// hardcode TIOCSWINSZ.
- err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
- runtime.KeepAlive(value)
- return err
+ return ioctlPtr(fd, req, unsafe.Pointer(value))
}
// IoctlSetTermios performs an ioctl on fd with a *Termios.
@@ -45,9 +43,7 @@ func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
// The req value will usually be TCSETA or TIOCSETA.
func IoctlSetTermios(fd int, req uint, value *Termios) error {
// TODO: if we get the chance, remove the req parameter.
- err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
- runtime.KeepAlive(value)
- return err
+ return ioctlPtr(fd, req, unsafe.Pointer(value))
}
// IoctlGetInt performs an ioctl operation which gets an integer value
@@ -57,18 +53,18 @@ func IoctlSetTermios(fd int, req uint, value *Termios) error {
// for those, IoctlRetInt should be used instead of this function.
func IoctlGetInt(fd int, req uint) (int, error) {
var value int
- err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+ err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return value, err
}
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
var value Winsize
- err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+ err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return &value, err
}
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
var value Termios
- err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+ err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return &value, err
}
diff --git a/vendor/golang.org/x/sys/unix/ioctl_zos.go b/vendor/golang.org/x/sys/unix/ioctl_zos.go
new file mode 100644
index 0000000..cdc21bf
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/ioctl_zos.go
@@ -0,0 +1,72 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build zos && s390x
+// +build zos,s390x
+
+package unix
+
+import (
+ "runtime"
+ "unsafe"
+)
+
+// ioctl itself should not be exposed directly, but additional get/set
+// functions for specific types are permissible.
+
+// IoctlSetInt performs an ioctl operation which sets an integer value
+// on fd, using the specified request number.
+func IoctlSetInt(fd int, req int, value int) error {
+ return ioctl(fd, req, uintptr(value))
+}
+
+// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
+//
+// To change fd's window size, the req argument should be TIOCSWINSZ.
+func IoctlSetWinsize(fd int, req int, value *Winsize) error {
+ // TODO: if we get the chance, remove the req parameter and
+ // hardcode TIOCSWINSZ.
+ return ioctlPtr(fd, req, unsafe.Pointer(value))
+}
+
+// IoctlSetTermios performs an ioctl on fd with a *Termios.
+//
+// The req value is expected to be TCSETS, TCSETSW, or TCSETSF
+func IoctlSetTermios(fd int, req int, value *Termios) error {
+ if (req != TCSETS) && (req != TCSETSW) && (req != TCSETSF) {
+ return ENOSYS
+ }
+ err := Tcsetattr(fd, int(req), value)
+ runtime.KeepAlive(value)
+ return err
+}
+
+// IoctlGetInt performs an ioctl operation which gets an integer value
+// from fd, using the specified request number.
+//
+// A few ioctl requests use the return value as an output parameter;
+// for those, IoctlRetInt should be used instead of this function.
+func IoctlGetInt(fd int, req int) (int, error) {
+ var value int
+ err := ioctlPtr(fd, req, unsafe.Pointer(&value))
+ return value, err
+}
+
+func IoctlGetWinsize(fd int, req int) (*Winsize, error) {
+ var value Winsize
+ err := ioctlPtr(fd, req, unsafe.Pointer(&value))
+ return &value, err
+}
+
+// IoctlGetTermios performs an ioctl on fd with a *Termios.
+//
+// The req value is expected to be TCGETS
+func IoctlGetTermios(fd int, req int) (*Termios, error) {
+ var value Termios
+ if req != TCGETS {
+ return &value, ENOSYS
+ }
+ err := Tcgetattr(fd, &value)
+ return &value, err
+}
diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh
index d257fac..e6f31d3 100644
--- a/vendor/golang.org/x/sys/unix/mkall.sh
+++ b/vendor/golang.org/x/sys/unix/mkall.sh
@@ -50,7 +50,7 @@ if [[ "$GOOS" = "linux" ]]; then
# Use the Docker-based build system
# Files generated through docker (use $cmd so you can Ctl-C the build or run)
$cmd docker build --tag generate:$GOOS $GOOS
- $cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")" && /bin/pwd):/build generate:$GOOS
+ $cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && pwd):/build generate:$GOOS
exit
fi
@@ -70,27 +70,15 @@ aix_ppc64)
mksyscall="go run mksyscall_aix_ppc64.go -aix"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
-darwin_386)
- mkerrors="$mkerrors -m32"
- mksyscall="go run mksyscall.go -l32"
- mktypes="GOARCH=$GOARCH go tool cgo -godefs"
- mkasm="go run mkasm_darwin.go"
- ;;
darwin_amd64)
mkerrors="$mkerrors -m64"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
- mkasm="go run mkasm_darwin.go"
- ;;
-darwin_arm)
- mkerrors="$mkerrors"
- mksyscall="go run mksyscall.go -l32"
- mktypes="GOARCH=$GOARCH go tool cgo -godefs"
- mkasm="go run mkasm_darwin.go"
+ mkasm="go run mkasm.go"
;;
darwin_arm64)
mkerrors="$mkerrors -m64"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
- mkasm="go run mkasm_darwin.go"
+ mkasm="go run mkasm.go"
;;
dragonfly_amd64)
mkerrors="$mkerrors -m64"
@@ -101,25 +89,30 @@ dragonfly_amd64)
freebsd_386)
mkerrors="$mkerrors -m32"
mksyscall="go run mksyscall.go -l32"
- mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
+ mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
freebsd_amd64)
mkerrors="$mkerrors -m64"
- mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
+ mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
freebsd_arm)
mkerrors="$mkerrors"
mksyscall="go run mksyscall.go -l32 -arm"
- mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
+ mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
# Let the type of C char be signed for making the bare syscall
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
freebsd_arm64)
mkerrors="$mkerrors -m64"
- mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
+ mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+ ;;
+freebsd_riscv64)
+ mkerrors="$mkerrors -m64"
+ mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
netbsd_386)
@@ -149,42 +142,60 @@ netbsd_arm64)
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
openbsd_386)
+ mkasm="go run mkasm.go"
mkerrors="$mkerrors -m32"
- mksyscall="go run mksyscall.go -l32 -openbsd"
+ mksyscall="go run mksyscall.go -l32 -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go"
- mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
openbsd_amd64)
+ mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64"
- mksyscall="go run mksyscall.go -openbsd"
+ mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go"
- mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
openbsd_arm)
+ mkasm="go run mkasm.go"
mkerrors="$mkerrors"
- mksyscall="go run mksyscall.go -l32 -openbsd -arm"
+ mksyscall="go run mksyscall.go -l32 -openbsd -arm -libc"
mksysctl="go run mksysctl_openbsd.go"
- mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
# Let the type of C char be signed for making the bare syscall
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
openbsd_arm64)
+ mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64"
- mksyscall="go run mksyscall.go -openbsd"
+ mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go"
- mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
# Let the type of C char be signed for making the bare syscall
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
openbsd_mips64)
+ mkasm="go run mkasm.go"
+ mkerrors="$mkerrors -m64"
+ mksyscall="go run mksyscall.go -openbsd -libc"
+ mksysctl="go run mksysctl_openbsd.go"
+ # Let the type of C char be signed for making the bare syscall
+ # API consistent across platforms.
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+ ;;
+openbsd_ppc64)
+ mkasm="go run mkasm.go"
+ mkerrors="$mkerrors -m64"
+ mksyscall="go run mksyscall.go -openbsd -libc"
+ mksysctl="go run mksysctl_openbsd.go"
+ # Let the type of C char be signed for making the bare syscall
+ # API consistent across platforms.
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+ ;;
+openbsd_riscv64)
+ mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64"
- mksyscall="go run mksyscall.go -openbsd"
+ mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go"
- mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
# Let the type of C char be signed for making the bare syscall
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
@@ -199,7 +210,7 @@ illumos_amd64)
mksyscall="go run mksyscall_solaris.go"
mkerrors=
mksysnum=
- mktypes=
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
*)
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
@@ -221,11 +232,6 @@ esac
if [ "$GOOSARCH" == "aix_ppc64" ]; then
# aix/ppc64 script generates files instead of writing to stdin.
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
- elif [ "$GOOS" == "darwin" ]; then
- # 1.12 and later, syscalls via libSystem
- echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
- # 1.13 and later, syscalls via libSystem (including syscallPtr)
- echo "$mksyscall -tags $GOOS,$GOARCH,go1.13 syscall_darwin.1_13.go |gofmt >zsyscall_$GOOSARCH.1_13.go";
elif [ "$GOOS" == "illumos" ]; then
# illumos code generation requires a --illumos switch
echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go";
@@ -239,5 +245,5 @@ esac
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; fi
- if [ -n "$mkasm" ]; then echo "$mkasm $GOARCH"; fi
+ if [ -n "$mkasm" ]; then echo "$mkasm $GOOS $GOARCH"; fi
) | $run
diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh
index 0d72dbb..47fa6a7 100644
--- a/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -54,23 +54,29 @@ includes_AIX='
includes_Darwin='
#define _DARWIN_C_SOURCE
-#define KERNEL
+#define KERNEL 1
#define _DARWIN_USE_64_BIT_INODE
+#define __APPLE_USE_RFC_3542
#include
#include
#include
+#include
#include
#include
#include
#include
#include
+#include
+#include
#include
+#include
#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include
@@ -78,6 +84,9 @@ includes_Darwin='
#include
#include
#include
+
+// for backwards compatibility because moved TIOCREMOTE to Kernel.framework after MacOSX12.0.sdk.
+#define TIOCREMOTE 0x80047469
'
includes_DragonFly='
@@ -112,6 +121,7 @@ includes_FreeBSD='
#include
#include
#include
+#include
#include
#include
#include
@@ -119,6 +129,7 @@ includes_FreeBSD='
#include
#include
#include
+#include
#include
#include
#include
@@ -193,24 +204,29 @@ struct ltchars {
#include
#include
#include
+#include
+#include
#include
#include
#include
+#include
#include
#include
#include
#include
#include
#include
+#include
#include
#include
+#include
#include
#include
#include
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -220,17 +236,24 @@ struct ltchars {
#include
#include
#include
+#include
+#include
#include
#include
+#include
#include
+#include
#include
#include
#include
+#include
#include
#include
#include
+#include
#include
#include
+#include
#include
#include
#include
@@ -245,8 +268,10 @@ struct ltchars {
#include
#include
#include
+#include
#include
+#include
#include
#if defined(__sparc__)
@@ -274,6 +299,10 @@ struct ltchars {
#define SOL_NETLINK 270
#endif
+#ifndef SOL_SMC
+#define SOL_SMC 286
+#endif
+
#ifdef SOL_BLUETOOTH
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
// but it is already in bluetooth_linux.go
@@ -294,6 +323,17 @@ struct ltchars {
// Including linux/l2tp.h here causes conflicts between linux/in.h
// and netinet/in.h included via net/route.h above.
#define IPPROTO_L2TP 115
+
+// Copied from linux/hid.h.
+// Keep in sync with the size of the referenced fields.
+#define _HIDIOCGRAWNAME_LEN 128 // sizeof_field(struct hid_device, name)
+#define _HIDIOCGRAWPHYS_LEN 64 // sizeof_field(struct hid_device, phys)
+#define _HIDIOCGRAWUNIQ_LEN 64 // sizeof_field(struct hid_device, uniq)
+
+#define _HIDIOCGRAWNAME HIDIOCGRAWNAME(_HIDIOCGRAWNAME_LEN)
+#define _HIDIOCGRAWPHYS HIDIOCGRAWPHYS(_HIDIOCGRAWPHYS_LEN)
+#define _HIDIOCGRAWUNIQ HIDIOCGRAWUNIQ(_HIDIOCGRAWUNIQ_LEN)
+
'
includes_NetBSD='
@@ -373,6 +413,7 @@ includes_SunOS='
#include
#include