chore_: bump go-waku (#5289)
This commit is contained in:
parent
a01ffdbe8e
commit
3996d6fece
99
go.mod
99
go.mod
|
@ -27,7 +27,7 @@ require (
|
|||
github.com/forPelevin/gomoji v1.1.2
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/google/uuid v1.4.0
|
||||
github.com/hashicorp/go-version v1.2.0
|
||||
github.com/imdario/mergo v0.3.12
|
||||
github.com/ipfs/go-cid v0.4.1
|
||||
|
@ -35,11 +35,11 @@ require (
|
|||
github.com/keighl/metabolize v0.0.0-20150915210303-97ab655d4034
|
||||
github.com/kilic/bls12-381 v0.0.0-20200607163746-32e1441c8a9f
|
||||
github.com/lib/pq v1.10.4
|
||||
github.com/libp2p/go-libp2p v0.32.2
|
||||
github.com/libp2p/go-libp2p-pubsub v0.10.1
|
||||
github.com/libp2p/go-libp2p v0.35.0
|
||||
github.com/libp2p/go-libp2p-pubsub v0.11.0
|
||||
github.com/lucasb-eyer/go-colorful v1.0.3
|
||||
github.com/mat/besticon v0.0.0-20210314201728-1579f269edb7
|
||||
github.com/multiformats/go-multiaddr v0.12.3
|
||||
github.com/multiformats/go-multiaddr v0.12.4
|
||||
github.com/multiformats/go-multibase v0.2.0
|
||||
github.com/multiformats/go-multihash v0.2.3
|
||||
github.com/multiformats/go-varint v0.0.7
|
||||
|
@ -48,7 +48,7 @@ require (
|
|||
github.com/oliamb/cutter v0.2.2
|
||||
github.com/pborman/uuid v1.2.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.16.0
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a
|
||||
github.com/status-im/doubleratchet v3.0.0+incompatible
|
||||
github.com/status-im/markdown v0.0.0-20240404192634-b7e33c6ac3d4
|
||||
|
@ -66,9 +66,9 @@ require (
|
|||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
github.com/zenthangplus/goccm v0.0.0-20211005163543-2f2e522aca15
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.18.0
|
||||
golang.org/x/crypto v0.23.0
|
||||
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb
|
||||
google.golang.org/protobuf v1.31.0
|
||||
google.golang.org/protobuf v1.34.1
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
||||
gopkg.in/go-playground/validator.v9 v9.31.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
|
@ -93,15 +93,15 @@ require (
|
|||
github.com/schollz/peerdiscovery v1.7.0
|
||||
github.com/siphiuel/lc-proxy-wrapper v0.0.0-20230516150924-246507cee8c7
|
||||
github.com/urfave/cli/v2 v2.27.2
|
||||
github.com/waku-org/go-waku v0.8.1-0.20240528125047-269417c5e979
|
||||
github.com/waku-org/go-waku v0.8.1-0.20240605190333-d2d2f5672ebd
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.7
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.1
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.2.1
|
||||
go.uber.org/multierr v1.11.0
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
|
||||
golang.org/x/net v0.17.0
|
||||
golang.org/x/text v0.14.0
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
|
||||
golang.org/x/net v0.25.0
|
||||
golang.org/x/text v0.15.0
|
||||
golang.org/x/time v0.5.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -142,13 +142,13 @@ require (
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||
github.com/cruxic/go-hmac-drbg v0.0.0-20170206035330-84c46983886d // indirect
|
||||
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/edsrzf/mmap-go v1.0.0 // indirect
|
||||
github.com/elastic/gosigar v0.14.2 // indirect
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
||||
github.com/flynn/noise v1.0.0 // indirect
|
||||
github.com/flynn/noise v1.1.0 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
|
@ -165,30 +165,29 @@ require (
|
|||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/gopacket v1.1.19 // indirect
|
||||
github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect
|
||||
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect
|
||||
github.com/gorilla/securecookie v1.1.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-bexpr v0.1.10 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
|
||||
github.com/holiman/uint256 v1.2.0 // indirect
|
||||
github.com/huandu/xstrings v1.3.2 // indirect
|
||||
github.com/huin/goupnp v1.3.0 // indirect
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
|
||||
github.com/klauspost/compress v1.17.2 // indirect
|
||||
github.com/klauspost/compress v1.17.8 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/koron/go-ssdp v0.0.4 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
||||
github.com/libp2p/go-cidranger v1.1.0 // indirect
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
|
||||
github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect
|
||||
github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect
|
||||
github.com/libp2p/go-msgio v0.3.0 // indirect
|
||||
github.com/libp2p/go-nat v0.2.0 // indirect
|
||||
github.com/libp2p/go-netroute v0.2.1 // indirect
|
||||
|
@ -199,8 +198,7 @@ require (
|
|||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/miekg/dns v1.1.56 // indirect
|
||||
github.com/miekg/dns v1.1.58 // indirect
|
||||
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
|
||||
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
|
||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||
|
@ -215,34 +213,33 @@ require (
|
|||
github.com/multiformats/go-multicodec v0.9.0 // indirect
|
||||
github.com/multiformats/go-multistream v0.5.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.13.0 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.1.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.15.0 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.2.0 // indirect
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
|
||||
github.com/pion/datachannel v1.5.5 // indirect
|
||||
github.com/pion/dtls/v2 v2.2.7 // indirect
|
||||
github.com/pion/ice/v2 v2.3.6 // indirect
|
||||
github.com/pion/interceptor v0.1.17 // indirect
|
||||
github.com/pion/datachannel v1.5.6 // indirect
|
||||
github.com/pion/dtls/v2 v2.2.11 // indirect
|
||||
github.com/pion/ice/v2 v2.3.24 // indirect
|
||||
github.com/pion/interceptor v0.1.29 // indirect
|
||||
github.com/pion/logging v0.2.2 // indirect
|
||||
github.com/pion/mdns v0.0.7 // indirect
|
||||
github.com/pion/mdns v0.0.12 // indirect
|
||||
github.com/pion/randutil v0.1.0 // indirect
|
||||
github.com/pion/rtcp v1.2.10 // indirect
|
||||
github.com/pion/rtp v1.7.13 // indirect
|
||||
github.com/pion/sctp v1.8.7 // indirect
|
||||
github.com/pion/sdp/v3 v3.0.6 // indirect
|
||||
github.com/pion/srtp/v2 v2.0.15 // indirect
|
||||
github.com/pion/stun v0.6.0 // indirect
|
||||
github.com/pion/transport/v2 v2.2.1 // indirect
|
||||
github.com/pion/turn/v2 v2.1.0 // indirect
|
||||
github.com/pion/webrtc/v3 v3.2.9 // indirect
|
||||
github.com/pion/rtcp v1.2.14 // indirect
|
||||
github.com/pion/rtp v1.8.6 // indirect
|
||||
github.com/pion/sctp v1.8.16 // indirect
|
||||
github.com/pion/sdp/v3 v3.0.9 // indirect
|
||||
github.com/pion/srtp/v2 v2.0.18 // indirect
|
||||
github.com/pion/stun v0.6.1 // indirect
|
||||
github.com/pion/transport/v2 v2.2.5 // indirect
|
||||
github.com/pion/turn/v2 v2.1.6 // indirect
|
||||
github.com/pion/webrtc/v3 v3.2.40 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.10.1 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.48.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/prometheus/tsdb v0.10.0 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4 // indirect
|
||||
github.com/quic-go/quic-go v0.39.4 // indirect
|
||||
github.com/quic-go/webtransport-go v0.6.0 // indirect
|
||||
github.com/quic-go/quic-go v0.44.0 // indirect
|
||||
github.com/quic-go/webtransport-go v0.8.0 // indirect
|
||||
github.com/raulk/go-watchdog v1.3.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
|
@ -276,13 +273,13 @@ require (
|
|||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/dig v1.17.1 // indirect
|
||||
go.uber.org/fx v1.20.1 // indirect
|
||||
go.uber.org/mock v0.3.0 // indirect
|
||||
golang.org/x/mod v0.13.0 // indirect
|
||||
golang.org/x/sync v0.4.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/term v0.16.0 // indirect
|
||||
golang.org/x/tools v0.14.0 // indirect
|
||||
go.uber.org/fx v1.21.1 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/term v0.20.0 // indirect
|
||||
golang.org/x/tools v0.21.0 // indirect
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/blake3 v1.2.1 // indirect
|
||||
|
|
262
go.sum
262
go.sum
|
@ -671,8 +671,8 @@ github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsP
|
|||
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
|
||||
github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
|
||||
github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
|
||||
|
@ -761,8 +761,8 @@ github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
|
|||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ=
|
||||
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
||||
github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
|
||||
github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
|
@ -833,8 +833,8 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
|
|||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||
|
@ -998,8 +998,8 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-github/v39 v39.2.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE=
|
||||
|
@ -1030,16 +1030,18 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe
|
|||
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0=
|
||||
github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo=
|
||||
github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
||||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
|
@ -1070,8 +1072,8 @@ github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z
|
|||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8=
|
||||
github.com/gosuri/uilive v0.0.3/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8=
|
||||
github.com/gosuri/uiprogress v0.0.0-20170224063937-d0567a9d84a1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0=
|
||||
|
@ -1120,8 +1122,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
|||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs=
|
||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
|
@ -1173,8 +1175,6 @@ github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9
|
|||
github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I=
|
||||
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
|
||||
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
|
||||
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
|
||||
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
|
||||
github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY=
|
||||
github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI=
|
||||
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
|
||||
|
@ -1299,8 +1299,8 @@ github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdY
|
|||
github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
|
||||
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
|
||||
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
|
@ -1354,16 +1354,14 @@ github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
|||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
||||
github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
|
||||
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
|
||||
github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ=
|
||||
github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.10.1 h1:/RqOZpEtAolsr8/9CC8KqROJSOZeu7lK7fPftn4MwNg=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.10.1/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw=
|
||||
github.com/libp2p/go-libp2p v0.35.0 h1:1xS1Bkr9X7GtdvV6ntLnDV9xB1kNjHK1lZ0eaO6gnhc=
|
||||
github.com/libp2p/go-libp2p v0.35.0/go.mod h1:snyJQix4ET6Tj+LeI0VPjjxTtdWpeOhYt5lEY0KirkQ=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc=
|
||||
github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ=
|
||||
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
|
||||
github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg=
|
||||
github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU=
|
||||
|
@ -1459,16 +1457,14 @@ github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW
|
|||
github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
|
||||
github.com/meirf/gopart v0.0.0-20180520194036-37e9492a85a8 h1:7TJiWD1knYDpOAPyFBoKqoyvlsa+UwDw0kv0jVN5Mrk=
|
||||
github.com/meirf/gopart v0.0.0-20180520194036-37e9492a85a8/go.mod h1:Uz8uoD6o+eQN19hr6Yro/qKvW+KP6olFq+PK/Nn7gCE=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
|
||||
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
|
||||
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
||||
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
|
||||
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms=
|
||||
|
@ -1535,8 +1531,8 @@ github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU
|
|||
github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4=
|
||||
github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y=
|
||||
github.com/multiformats/go-multiaddr v0.3.2/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0=
|
||||
github.com/multiformats/go-multiaddr v0.12.3 h1:hVBXvPRcKG0w80VinQ23P5t7czWgg65BmIvQKjDydU8=
|
||||
github.com/multiformats/go-multiaddr v0.12.3/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
|
||||
github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc=
|
||||
github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
|
||||
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
|
||||
|
@ -1581,8 +1577,9 @@ github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a
|
|||
github.com/neo4j/neo4j-go-driver v1.8.1-0.20200803113522-b626aa943eba/go.mod h1:ncO5VaFWh0Nrt+4KT4mOZboaczBZcLuHrG+/sUeP8gI=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
|
||||
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
|
@ -1611,8 +1608,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv
|
|||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
|
||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
|
@ -1627,8 +1624,8 @@ github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQ
|
|||
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
||||
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
|
||||
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
|
@ -1654,8 +1651,8 @@ github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.m
|
|||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
|
||||
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
|
||||
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
||||
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||
|
@ -1696,8 +1693,8 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
|
|||
github.com/pierrec/lz4/v4 v4.1.8/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pion/datachannel v1.4.21/go.mod h1:oiNyP4gHx2DIwRzX/MFyH0Rz/Gz05OgBlayAI2hAWjg=
|
||||
github.com/pion/datachannel v1.5.2/go.mod h1:FTGQWaHrdCwIJ1rw6xBIfZVkslikjShim5yr05XFuCQ=
|
||||
github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=
|
||||
github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
|
||||
github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg=
|
||||
github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4=
|
||||
github.com/pion/dtls/v2 v2.0.1/go.mod h1:uMQkz2W0cSqY00xav7WByQ4Hb+18xeQh2oH2fRezr5U=
|
||||
github.com/pion/dtls/v2 v2.0.2/go.mod h1:27PEO3MDdaCfo21heT59/vsdmZc0zMt9wQPcSlLu/1I=
|
||||
github.com/pion/dtls/v2 v2.0.4/go.mod h1:qAkFscX0ZHoI1E07RfYPoRw3manThveu+mlTDdOxoGI=
|
||||
|
@ -1705,29 +1702,30 @@ github.com/pion/dtls/v2 v2.0.7/go.mod h1:QuDII+8FVvk9Dp5t5vYIMTo7hh7uBkra+8QIm7Q
|
|||
github.com/pion/dtls/v2 v2.0.9/go.mod h1:O0Wr7si/Zj5/EBFlDzDd6UtVxx25CE1r7XM7BQKYQho=
|
||||
github.com/pion/dtls/v2 v2.1.1/go.mod h1:qG3gA7ZPZemBqpEFqRKyURYdKEwFZQCGb7gv9T3ON3Y=
|
||||
github.com/pion/dtls/v2 v2.1.2/go.mod h1:o6+WvyLDAlXF7YiPB/RlskRoeK+/JtuaZa5emwQcWus=
|
||||
github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
|
||||
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
|
||||
github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks=
|
||||
github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
|
||||
github.com/pion/ice v0.7.18/go.mod h1:+Bvnm3nYC6Nnp7VV6glUkuOfToB/AtMRZpOU8ihuf4c=
|
||||
github.com/pion/ice/v2 v2.0.15/go.mod h1:ZIiVGevpgAxF/cXiIVmuIUtCb3Xs4gCzCbXB6+nFkSI=
|
||||
github.com/pion/ice/v2 v2.1.7/go.mod h1:kV4EODVD5ux2z8XncbLHIOtcXKtYXVgLVCeVqnpoeP0=
|
||||
github.com/pion/ice/v2 v2.1.10/go.mod h1:kV4EODVD5ux2z8XncbLHIOtcXKtYXVgLVCeVqnpoeP0=
|
||||
github.com/pion/ice/v2 v2.1.12/go.mod h1:ovgYHUmwYLlRvcCLI67PnQ5YGe+upXZbGgllBDG/ktU=
|
||||
github.com/pion/ice/v2 v2.1.20/go.mod h1:hEAldRzBhTtAfvlU1V/2/nLCMvveQWFKPNCop+63/Iw=
|
||||
github.com/pion/ice/v2 v2.3.6 h1:Jgqw36cAud47iD+N6rNX225uHvrgWtAlHfVyOQc3Heg=
|
||||
github.com/pion/ice/v2 v2.3.6/go.mod h1:9/TzKDRwBVAPsC+YOrKH/e3xDrubeTRACU9/sHQarsU=
|
||||
github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI=
|
||||
github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw=
|
||||
github.com/pion/interceptor v0.0.9/go.mod h1:dHgEP5dtxOTf21MObuBAjJeAayPxLUAZjerGH8Xr07c=
|
||||
github.com/pion/interceptor v0.0.12/go.mod h1:qzeuWuD/ZXvPqOnxNcnhWfkCZ2e1kwwslicyyPnhoK4=
|
||||
github.com/pion/interceptor v0.0.13/go.mod h1:svsW2QoLHLoGLUr4pDoSopGBEWk8FZwlfxId/OKRKzo=
|
||||
github.com/pion/interceptor v0.0.15/go.mod h1:pg3J253eGi5bqyKzA74+ej5Y19ez2jkWANVnF+Z9Dfk=
|
||||
github.com/pion/interceptor v0.1.7/go.mod h1:Lh3JSl/cbJ2wP8I3ccrjh1K/deRGRn3UlSPuOTiHb6U=
|
||||
github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w=
|
||||
github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI=
|
||||
github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M=
|
||||
github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4=
|
||||
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/mdns v0.0.4/go.mod h1:R1sL0p50l42S5lJs91oNdUL58nm0QHrhxnSegr++qC0=
|
||||
github.com/pion/mdns v0.0.5/go.mod h1:UgssrvdD3mxpi8tMxAXbsppL3vJ4Jipw1mTCW+al01g=
|
||||
github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U=
|
||||
github.com/pion/mdns v0.0.7/go.mod h1:4iP2UbeFhLI/vWju/bw6ZfwjJzk0z8DNValjGxR/dD8=
|
||||
github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
|
||||
github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk=
|
||||
github.com/pion/quic v0.1.1/go.mod h1:zEU51v7ru8Mp4AUBJvj6psrSth5eEFNnVQK5K48oV3k=
|
||||
github.com/pion/quic v0.1.4/go.mod h1:dBhNvkLoQqRwfi6h3Vqj3IcPLgiW7rkZxBbRdp7Vzvk=
|
||||
github.com/pion/randutil v0.0.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
|
||||
|
@ -1737,8 +1735,9 @@ github.com/pion/rtcp v1.2.3/go.mod h1:zGhIv0RPRF0Z1Wiij22pUt5W/c9fevqSzT4jje/oK7
|
|||
github.com/pion/rtcp v1.2.4/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0=
|
||||
github.com/pion/rtcp v1.2.6/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0=
|
||||
github.com/pion/rtcp v1.2.9/go.mod h1:qVPhiCzAm4D/rxb6XzKeyZiQK69yJpbUDJSF7TgrqNo=
|
||||
github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc=
|
||||
github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I=
|
||||
github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
|
||||
github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE=
|
||||
github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
|
||||
github.com/pion/rtp v1.6.0/go.mod h1:QgfogHsMBVE/RFNno467U/KBqfUywEH+HK+0rtnwsdI=
|
||||
github.com/pion/rtp v1.6.1/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
|
||||
github.com/pion/rtp v1.6.2/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
|
||||
|
@ -1746,31 +1745,31 @@ github.com/pion/rtp v1.6.5/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko
|
|||
github.com/pion/rtp v1.7.0/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
|
||||
github.com/pion/rtp v1.7.2/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
|
||||
github.com/pion/rtp v1.7.4/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
|
||||
github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA=
|
||||
github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
|
||||
github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
|
||||
github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw=
|
||||
github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
|
||||
github.com/pion/sctp v1.7.10/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
|
||||
github.com/pion/sctp v1.7.11/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
|
||||
github.com/pion/sctp v1.7.12/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
|
||||
github.com/pion/sctp v1.8.0/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
|
||||
github.com/pion/sctp v1.8.2/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
|
||||
github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0=
|
||||
github.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw=
|
||||
github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU=
|
||||
github.com/pion/sctp v1.8.13/go.mod h1:YKSgO/bO/6aOMP9LCie1DuD7m+GamiK2yIiPM6vH+GA=
|
||||
github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY=
|
||||
github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE=
|
||||
github.com/pion/sdp/v2 v2.4.0/go.mod h1:L2LxrOpSTJbAns244vfPChbciR/ReU1KWfG04OpkR7E=
|
||||
github.com/pion/sdp/v3 v3.0.4/go.mod h1:bNiSknmJE0HYBprTHXKPQ3+JjacTv5uap92ueJZKsRk=
|
||||
github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw=
|
||||
github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw=
|
||||
github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY=
|
||||
github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M=
|
||||
github.com/pion/srtp v1.5.1/go.mod h1:B+QgX5xPeQTNc1CJStJPHzOlHK66ViMDWTT0HZTCkcA=
|
||||
github.com/pion/srtp v1.5.2/go.mod h1:NiBff/MSxUwMUwx/fRNyD/xGE+dVvf8BOCeXhjCXZ9U=
|
||||
github.com/pion/srtp/v2 v2.0.1/go.mod h1:c8NWHhhkFf/drmHTAblkdu8++lsISEBBdAuiyxgqIsE=
|
||||
github.com/pion/srtp/v2 v2.0.2/go.mod h1:VEyLv4CuxrwGY8cxM+Ng3bmVy8ckz/1t6A0q/msKOw0=
|
||||
github.com/pion/srtp/v2 v2.0.5/go.mod h1:8k6AJlal740mrZ6WYxc4Dg6qDqqhxoRG2GSjlUhDF0A=
|
||||
github.com/pion/srtp/v2 v2.0.15 h1:+tqRtXGsGwHC0G0IUIAzRmdkHvriF79IHVfZGfHrQoA=
|
||||
github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw=
|
||||
github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo=
|
||||
github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA=
|
||||
github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2UA=
|
||||
github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw=
|
||||
github.com/pion/stun v0.6.0 h1:JHT/2iyGDPrFWE8NNC15wnddBN8KifsEDw8swQmrEmU=
|
||||
github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA=
|
||||
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
|
||||
github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
|
||||
github.com/pion/transport v0.6.0/go.mod h1:iWZ07doqOosSLMhZ+FXUTq+TamDoXSllxpbGcfkCmbE=
|
||||
github.com/pion/transport v0.8.10/go.mod h1:tBmha/UCjpum5hqTWhfAEs3CO4/tHSg0MYRhSzR+CZ8=
|
||||
github.com/pion/transport v0.10.0/go.mod h1:BnHnUipd0rZQyTVB2SBGojFHT9CBt5C5TcsJSQGkvSE=
|
||||
|
@ -1778,19 +1777,23 @@ github.com/pion/transport v0.10.1/go.mod h1:PBis1stIILMiis0PewDw91WJeLJkyIMcEk+D
|
|||
github.com/pion/transport v0.12.1/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
|
||||
github.com/pion/transport v0.12.2/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
|
||||
github.com/pion/transport v0.12.3/go.mod h1:OViWW9SP2peE/HbwBvARicmAVnesphkNkCVZIWJ6q9A=
|
||||
github.com/pion/transport v0.13.0 h1:KWTA5ZrQogizzYwPEciGtHPLwpAjE91FgXnyu+Hv2uY=
|
||||
github.com/pion/transport v0.13.0/go.mod h1:yxm9uXpK9bpBBWkITk13cLo1y5/ur5VQpG22ny6EP7g=
|
||||
github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40=
|
||||
github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI=
|
||||
github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc=
|
||||
github.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ=
|
||||
github.com/pion/transport/v2 v2.2.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ=
|
||||
github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c=
|
||||
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
|
||||
github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc=
|
||||
github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
|
||||
github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
|
||||
github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc=
|
||||
github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
|
||||
github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
|
||||
github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4=
|
||||
github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0=
|
||||
github.com/pion/turn/v2 v2.0.4/go.mod h1:1812p4DcGVbYVBTiraUmP50XoKye++AMkbfp+N27mog=
|
||||
github.com/pion/turn/v2 v2.0.5/go.mod h1:APg43CFyt/14Uy7heYUOGWdkem/Wu4PhCO/bjyrTqMw=
|
||||
github.com/pion/turn/v2 v2.0.6/go.mod h1:+y7xl719J8bAEVpSXBXvTxStjJv3hbz9YFflvkpcGPw=
|
||||
github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI=
|
||||
github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs=
|
||||
github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
|
||||
github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc=
|
||||
github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
|
||||
github.com/pion/udp v0.1.0/go.mod h1:BPELIjbwE9PRbd/zxI/KYBnbo7B6+oA6YuEaNE8lths=
|
||||
github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M=
|
||||
github.com/pion/webrtc/v2 v2.2.26/go.mod h1:XMZbZRNHyPDe1gzTIHFcQu02283YO45CbiwFgKvXnmc=
|
||||
|
@ -1798,8 +1801,8 @@ github.com/pion/webrtc/v3 v3.0.11/go.mod h1:WEvXneGTeqNmiR59v5jTsxMc4yXQyOQcRsrd
|
|||
github.com/pion/webrtc/v3 v3.0.27/go.mod h1:QpLDmsU5a/a05n230gRtxZRvfHhFzn9ukGUL2x4G5ic=
|
||||
github.com/pion/webrtc/v3 v3.0.32/go.mod h1:wX3V5dQQUGCifhT1mYftC2kCrDQX6ZJ3B7Yad0R9JK0=
|
||||
github.com/pion/webrtc/v3 v3.1.24-0.20220208053747-94262c1b2b38/go.mod h1:L5S/oAhL0Fzt/rnftVQRrP80/j5jygY7XRZzWwFx6P4=
|
||||
github.com/pion/webrtc/v3 v3.2.9 h1:U8NSjQDlZZ+Iy/hg42Q/u6mhEVSXYvKrOIZiZwYTfLc=
|
||||
github.com/pion/webrtc/v3 v3.2.9/go.mod h1:gjQLMZeyN3jXBGdxGmUYCyKjOuYX/c99BDjGqmadq0A=
|
||||
github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU=
|
||||
github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
|
@ -1827,8 +1830,8 @@ github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O
|
|||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
|
||||
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
|
@ -1836,8 +1839,8 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:
|
|||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
|
@ -1852,8 +1855,8 @@ github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16
|
|||
github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
|
||||
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
|
@ -1871,19 +1874,17 @@ github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
|
|||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.2/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
|
||||
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic=
|
||||
github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/quic-go v0.39.4 h1:PelfiuG7wXEffUT2yceiqz5V6Pc0TA5ruOd1LcmFc1s=
|
||||
github.com/quic-go/quic-go v0.39.4/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q=
|
||||
github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY=
|
||||
github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc=
|
||||
github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0=
|
||||
github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek=
|
||||
github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg=
|
||||
github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM=
|
||||
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
|
||||
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
|
@ -2074,8 +2075,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
|
@ -2138,8 +2137,8 @@ github.com/waku-org/go-discover v0.0.0-20240506173252-4912704efdc5 h1:4K3IS97Jry
|
|||
github.com/waku-org/go-discover v0.0.0-20240506173252-4912704efdc5/go.mod h1:eBHgM6T4EG0RZzxpxKy+rGz/6Dw2Nd8DWxS0lm9ESDw=
|
||||
github.com/waku-org/go-libp2p-rendezvous v0.0.0-20240110193335-a67d1cc760a0 h1:R4YYx2QamhBRl/moIxkDCNW+OP7AHbyWLBygDc/xIMo=
|
||||
github.com/waku-org/go-libp2p-rendezvous v0.0.0-20240110193335-a67d1cc760a0/go.mod h1:EhZP9fee0DYjKH/IOQvoNSy1tSHp2iZadsHGphcAJgY=
|
||||
github.com/waku-org/go-waku v0.8.1-0.20240528125047-269417c5e979 h1:31upWxN0XWBA+bcS0aCJ9jR8HzBNtCg8zKAj+Jvre08=
|
||||
github.com/waku-org/go-waku v0.8.1-0.20240528125047-269417c5e979/go.mod h1:yXnWChXRKTb+NhALbFysluxgSwuxeTF2rhanDJkIx+k=
|
||||
github.com/waku-org/go-waku v0.8.1-0.20240605190333-d2d2f5672ebd h1:g5EneT88eHOakr8Zukx4RP1JICgrSl9ZtmgGS+wQbC8=
|
||||
github.com/waku-org/go-waku v0.8.1-0.20240605190333-d2d2f5672ebd/go.mod h1:biffO55kWbvfO8jdu/aAPiWcmozrfFKPum4EMFDib+k=
|
||||
github.com/waku-org/go-zerokit-rln v0.1.14-0.20240102145250-fa738c0bdf59 h1:jisj+OCI6QydLtFq3Pyhu49wl9ytPN7oAHjMfepHDrA=
|
||||
github.com/waku-org/go-zerokit-rln v0.1.14-0.20240102145250-fa738c0bdf59/go.mod h1:1PdBdPzyTaKt3VnpAHk3zj+r9dXPFOr3IHZP9nFle6E=
|
||||
github.com/waku-org/go-zerokit-rln-apple v0.0.0-20230916172309-ee0ee61dde2b h1:KgZVhsLkxsj5gb/FfndSCQu6VYwALrCOgYI3poR95yE=
|
||||
|
@ -2263,15 +2262,15 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
|||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc=
|
||||
go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
||||
go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk=
|
||||
go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg=
|
||||
go.uber.org/fx v1.21.1 h1:RqBh3cYdzZS0uqwVeEjOX2p73dddLpym315myy/Bpb0=
|
||||
go.uber.org/fx v1.21.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
|
@ -2334,9 +2333,13 @@ golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0
|
|||
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -2351,8 +2354,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
|
@ -2391,8 +2394,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
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/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
|
||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -2482,16 +2485,18 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
|||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
|
@ -2528,8 +2533,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -2685,30 +2690,35 @@ golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
||||
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -2718,14 +2728,14 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -2736,8 +2746,8 @@ golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -2826,8 +2836,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
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/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
|
||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
||||
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
|
||||
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -3024,8 +3034,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
|||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
ISC License
|
||||
|
||||
Copyright (c) 2013-2017 The btcsuite developers
|
||||
Copyright (c) 2015-2020 The Decred developers
|
||||
Copyright (c) 2015-2024 The Decred developers
|
||||
Copyright (c) 2017 The Lightning Network Developers
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2015-2022 The Decred developers
|
||||
// Copyright (c) 2015-2024 The Decred developers
|
||||
// Copyright 2013-2014 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
@ -1221,6 +1221,25 @@ func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) {
|
|||
//
|
||||
// NOTE: The resulting point will be normalized.
|
||||
func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) {
|
||||
scalarBaseMultNonConst(k, result)
|
||||
}
|
||||
|
||||
// jacobianG is the secp256k1 base point converted to Jacobian coordinates and
|
||||
// is defined here to avoid repeatedly converting it.
|
||||
var jacobianG = func() JacobianPoint {
|
||||
var G JacobianPoint
|
||||
bigAffineToJacobian(curveParams.Gx, curveParams.Gy, &G)
|
||||
return G
|
||||
}()
|
||||
|
||||
// scalarBaseMultNonConstSlow computes k*G through ScalarMultNonConst.
|
||||
func scalarBaseMultNonConstSlow(k *ModNScalar, result *JacobianPoint) {
|
||||
ScalarMultNonConst(k, &jacobianG, result)
|
||||
}
|
||||
|
||||
// scalarBaseMultNonConstFast computes k*G through the precomputed lookup
|
||||
// tables.
|
||||
func scalarBaseMultNonConstFast(k *ModNScalar, result *JacobianPoint) {
|
||||
bytePoints := s256BytePoints()
|
||||
|
||||
// Start with the point at infinity.
|
||||
|
|
14
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_embedded.go
generated
vendored
Normal file
14
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_embedded.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2024 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build tinygo
|
||||
|
||||
package secp256k1
|
||||
|
||||
// This file contains the variants suitable for
|
||||
// memory or storage constrained environments.
|
||||
|
||||
func scalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) {
|
||||
scalarBaseMultNonConstSlow(k, result)
|
||||
}
|
14
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_precompute.go
generated
vendored
Normal file
14
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_precompute.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2024 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !tinygo
|
||||
|
||||
package secp256k1
|
||||
|
||||
// This file contains the variants that don't fit in
|
||||
// memory or storage constrained environments.
|
||||
|
||||
func scalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) {
|
||||
scalarBaseMultNonConstFast(k, result)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2020 The Decred developers
|
||||
// Copyright (c) 2020-2023 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -32,11 +32,11 @@ key without actually revealing it.
|
|||
|
||||
# Errors
|
||||
|
||||
Errors returned by this package are of type ecdsa.Error and fully support the
|
||||
standard library errors.Is and errors.As functions. This allows the caller to
|
||||
programmatically determine the specific error by examining the ErrorKind field
|
||||
of the type asserted ecdsa.Error while still providing rich error messages with
|
||||
contextual information. See ErrorKind in the package documentation for a full
|
||||
list.
|
||||
The errors returned by this package are of type ecdsa.Error and fully support
|
||||
the standard library errors.Is and errors.As functions. This allows the caller
|
||||
to programmatically determine the specific error by examining the ErrorKind
|
||||
field of the type asserted ecdsa.Error while still providing rich error messages
|
||||
with contextual information. See ErrorKind in the package documentation for a
|
||||
full list.
|
||||
*/
|
||||
package ecdsa
|
||||
|
|
|
@ -59,6 +59,16 @@ func NewSignature(r, s *secp256k1.ModNScalar) *Signature {
|
|||
return &Signature{*r, *s}
|
||||
}
|
||||
|
||||
// R returns the r value of the signature.
|
||||
func (sig *Signature) R() secp256k1.ModNScalar {
|
||||
return sig.r
|
||||
}
|
||||
|
||||
// S returns the s value of the signature.
|
||||
func (sig *Signature) S() secp256k1.ModNScalar {
|
||||
return sig.s
|
||||
}
|
||||
|
||||
// Serialize returns the ECDSA signature in the Distinguished Encoding Rules
|
||||
// (DER) format per section 10 of [ISO/IEC 8825-1] and such that the S component
|
||||
// of the signature is less than or equal to the half order of the group.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2013-2014 The btcsuite developers
|
||||
// Copyright (c) 2015-2022 The Decred developers
|
||||
// Copyright (c) 2013-2022 Dave Collins
|
||||
// Copyright (c) 2015-2023 The Decred developers
|
||||
// Copyright (c) 2013-2023 Dave Collins
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -435,7 +435,7 @@ func (f *FieldVal) Normalize() *FieldVal {
|
|||
|
||||
// PutBytesUnchecked unpacks the field value to a 32-byte big-endian value
|
||||
// directly into the passed byte slice in constant time. The target slice must
|
||||
// must have at least 32 bytes available or it will panic.
|
||||
// have at least 32 bytes available or it will panic.
|
||||
//
|
||||
// There is a similar function, PutBytes, which unpacks the field value into a
|
||||
// 32-byte array directly. This version is provided since it can be useful
|
||||
|
@ -816,11 +816,10 @@ func (f *FieldVal) Mul(val *FieldVal) *FieldVal {
|
|||
return f.Mul2(f, val)
|
||||
}
|
||||
|
||||
// Mul2 multiplies the passed two field values together and stores the result
|
||||
// result in f in constant time. Note that this function can overflow if
|
||||
// multiplying any of the individual words exceeds a max uint32. In practice,
|
||||
// this means the magnitude of either value involved in the multiplication must
|
||||
// be a max of 8.
|
||||
// Mul2 multiplies the passed two field values together and stores the result in
|
||||
// f in constant time. Note that this function can overflow if multiplying any
|
||||
// of the individual words exceeds a max uint32. In practice, this means the
|
||||
// magnitude of either value involved in the multiplication must be a max of 8.
|
||||
//
|
||||
// The field value is returned to support chaining. This enables syntax like:
|
||||
// f3.Mul2(f, f2).AddInt(1) so that f3 = (f * f2) + 1.
|
||||
|
@ -1510,8 +1509,8 @@ func (f *FieldVal) SquareVal(val *FieldVal) *FieldVal {
|
|||
// Output Max Magnitude: 1
|
||||
func (f *FieldVal) Inverse() *FieldVal {
|
||||
// Fermat's little theorem states that for a nonzero number a and prime
|
||||
// prime p, a^(p-1) = 1 (mod p). Since the multiplicative inverse is
|
||||
// a*b = 1 (mod p), it follows that b = a*a^(p-2) = a^(p-1) = 1 (mod p).
|
||||
// p, a^(p-1) ≡ 1 (mod p). Since the multiplicative inverse is
|
||||
// a*b ≡ 1 (mod p), it follows that b ≡ a*a^(p-2) ≡ a^(p-1) ≡ 1 (mod p).
|
||||
// Thus, a^(p-2) is the multiplicative inverse.
|
||||
//
|
||||
// In order to efficiently compute a^(p-2), p-2 needs to be split into
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2020-2022 The Decred developers
|
||||
// Copyright (c) 2020-2023 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -46,6 +46,8 @@ const (
|
|||
//
|
||||
// The group order of the curve per [SECG] is:
|
||||
// 0xffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141
|
||||
//
|
||||
// nolint: dupword
|
||||
orderWordZero uint32 = 0xd0364141
|
||||
orderWordOne uint32 = 0xbfd25e8c
|
||||
orderWordTwo uint32 = 0xaf48a03b
|
||||
|
@ -76,6 +78,8 @@ const (
|
|||
//
|
||||
// The half order of the secp256k1 curve group is:
|
||||
// 0x7fffffff ffffffff ffffffff ffffffff 5d576e73 57a4501d dfe92f46 681b20a0
|
||||
//
|
||||
// nolint: dupword
|
||||
halfOrderWordZero uint32 = 0x681b20a0
|
||||
halfOrderWordOne uint32 = 0xdfe92f46
|
||||
halfOrderWordTwo uint32 = 0x57a4501d
|
||||
|
@ -364,8 +368,8 @@ func (s *ModNScalar) SetByteSlice(b []byte) bool {
|
|||
}
|
||||
|
||||
// PutBytesUnchecked unpacks the scalar to a 32-byte big-endian value directly
|
||||
// into the passed byte slice in constant time. The target slice must must have
|
||||
// at least 32 bytes available or it will panic.
|
||||
// into the passed byte slice in constant time. The target slice must have at
|
||||
// least 32 bytes available or it will panic.
|
||||
//
|
||||
// There is a similar function, PutBytes, which unpacks the scalar into a
|
||||
// 32-byte array directly. This version is provided since it can be useful to
|
||||
|
|
|
@ -32,6 +32,18 @@ const MaxNonce = uint64(math.MaxUint64) - 1
|
|||
var ErrMaxNonce = errors.New("noise: cipherstate has reached maximum n, a new handshake must be performed")
|
||||
var ErrCipherSuiteCopied = errors.New("noise: CipherSuite has been copied, state is invalid")
|
||||
|
||||
// UnsafeNewCipherState reconstructs a CipherState from exported components.
|
||||
// It is important that, when resuming from an exported state, care is taken
|
||||
// to synchronize the nonce state and not allow rollbacks.
|
||||
func UnsafeNewCipherState(cs CipherSuite, k [32]byte, n uint64) *CipherState {
|
||||
return &CipherState{
|
||||
cs: cs,
|
||||
c: cs.Cipher(k),
|
||||
k: k,
|
||||
n: n,
|
||||
}
|
||||
}
|
||||
|
||||
// Encrypt encrypts the plaintext and then appends the ciphertext and an
|
||||
// authentication tag across the ciphertext and optional authenticated data to
|
||||
// out. This method automatically increments the nonce after every call, so
|
||||
|
@ -86,6 +98,18 @@ func (s *CipherState) Nonce() uint64 {
|
|||
return s.n
|
||||
}
|
||||
|
||||
// SetNonce sets the current value of n.
|
||||
func (s *CipherState) SetNonce(n uint64) {
|
||||
s.n = n
|
||||
}
|
||||
|
||||
// UnsafeKey returns the current value of k. This exports the current key for the
|
||||
// CipherState. Intended to be used alongside UnsafeNewCipherState to resume a
|
||||
// CipherState at a later point.
|
||||
func (s *CipherState) UnsafeKey() [32]byte {
|
||||
return s.k
|
||||
}
|
||||
|
||||
func (s *CipherState) Rekey() {
|
||||
var zeros [32]byte
|
||||
var out []byte
|
||||
|
@ -236,6 +260,7 @@ type HandshakeState struct {
|
|||
rs []byte // remote party's static public key
|
||||
re []byte // remote party's ephemeral public key
|
||||
psk []byte // preshared key, maybe zero length
|
||||
willPsk bool // indicates if preshared key will be used (even if not yet set)
|
||||
messagePatterns [][]MessagePattern
|
||||
shouldWrite bool
|
||||
initiator bool
|
||||
|
@ -294,7 +319,6 @@ func NewHandshakeState(c Config) (*HandshakeState, error) {
|
|||
s: c.StaticKeypair,
|
||||
e: c.EphemeralKeypair,
|
||||
rs: c.PeerStatic,
|
||||
psk: c.PresharedKey,
|
||||
messagePatterns: c.Pattern.Messages,
|
||||
shouldWrite: c.Initiator,
|
||||
initiator: c.Initiator,
|
||||
|
@ -308,11 +332,18 @@ func NewHandshakeState(c Config) (*HandshakeState, error) {
|
|||
copy(hs.re, c.PeerEphemeral)
|
||||
}
|
||||
hs.ss.cs = c.CipherSuite
|
||||
|
||||
pskModifier := ""
|
||||
if len(hs.psk) > 0 {
|
||||
if len(hs.psk) != 32 {
|
||||
return nil, errors.New("noise: specification mandates 256-bit preshared keys")
|
||||
// NB: for psk{0,1} we must have preshared key set in configuration as its needed in the first
|
||||
// message. For psk{2+} we may not know the correct psk yet so it might not be set.
|
||||
if len(c.PresharedKey) > 0 || c.PresharedKeyPlacement >= 2 {
|
||||
hs.willPsk = true
|
||||
if len(c.PresharedKey) > 0 {
|
||||
if err := hs.SetPresharedKey(c.PresharedKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
pskModifier = fmt.Sprintf("psk%d", c.PresharedKeyPlacement)
|
||||
hs.messagePatterns = append([][]MessagePattern(nil), hs.messagePatterns...)
|
||||
if c.PresharedKeyPlacement == 0 {
|
||||
|
@ -321,6 +352,7 @@ func NewHandshakeState(c Config) (*HandshakeState, error) {
|
|||
hs.messagePatterns[c.PresharedKeyPlacement-1] = append(hs.messagePatterns[c.PresharedKeyPlacement-1], MessagePatternPSK)
|
||||
}
|
||||
}
|
||||
|
||||
hs.ss.InitializeSymmetric([]byte("Noise_" + c.Pattern.Name + pskModifier + "_" + string(hs.ss.cs.Name())))
|
||||
hs.ss.MixHash(c.Prologue)
|
||||
for _, m := range c.Pattern.InitiatorPreMessages {
|
||||
|
@ -378,7 +410,7 @@ func (s *HandshakeState) WriteMessage(out, payload []byte) ([]byte, *CipherState
|
|||
s.e = e
|
||||
out = append(out, s.e.Public...)
|
||||
s.ss.MixHash(s.e.Public)
|
||||
if len(s.psk) > 0 {
|
||||
if s.willPsk {
|
||||
s.ss.MixKey(s.e.Public)
|
||||
}
|
||||
case MessagePatternS:
|
||||
|
@ -430,6 +462,9 @@ func (s *HandshakeState) WriteMessage(out, payload []byte) ([]byte, *CipherState
|
|||
}
|
||||
s.ss.MixKey(dh)
|
||||
case MessagePatternPSK:
|
||||
if len(s.psk) == 0 {
|
||||
return nil, nil, nil, errors.New("noise: cannot send psk message without psk set")
|
||||
}
|
||||
s.ss.MixKeyAndHash(s.psk)
|
||||
}
|
||||
}
|
||||
|
@ -451,6 +486,15 @@ func (s *HandshakeState) WriteMessage(out, payload []byte) ([]byte, *CipherState
|
|||
// ErrShortMessage is returned by ReadMessage if a message is not as long as it should be.
|
||||
var ErrShortMessage = errors.New("noise: message is too short")
|
||||
|
||||
func (s *HandshakeState) SetPresharedKey(psk []byte) error {
|
||||
if len(psk) != 32 {
|
||||
return errors.New("noise: specification mandates 256-bit preshared keys")
|
||||
}
|
||||
s.psk = make([]byte, 32)
|
||||
copy(s.psk, psk)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadMessage processes a received handshake message and appends the payload,
|
||||
// if any to out. If the handshake is completed by the call, two CipherStates
|
||||
// will be returned, one is used for encryption of messages to the remote peer,
|
||||
|
@ -486,7 +530,7 @@ func (s *HandshakeState) ReadMessage(out, message []byte) ([]byte, *CipherState,
|
|||
s.re = s.re[:s.ss.cs.DHLen()]
|
||||
copy(s.re, message)
|
||||
s.ss.MixHash(s.re)
|
||||
if len(s.psk) > 0 {
|
||||
if s.willPsk {
|
||||
s.ss.MixKey(s.re)
|
||||
}
|
||||
case MessagePatternS:
|
||||
|
|
|
@ -530,6 +530,7 @@ func (p *Line) decoder() []decoder {
|
|||
func (p *Line) encode(b *buffer) {
|
||||
encodeUint64Opt(b, 1, p.functionIDX)
|
||||
encodeInt64Opt(b, 2, p.Line)
|
||||
encodeInt64Opt(b, 3, p.Column)
|
||||
}
|
||||
|
||||
var lineDecoder = []decoder{
|
||||
|
@ -538,6 +539,8 @@ var lineDecoder = []decoder{
|
|||
func(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) },
|
||||
// optional int64 line = 2
|
||||
func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Line) },
|
||||
// optional int64 column = 3
|
||||
func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Column) },
|
||||
}
|
||||
|
||||
func (p *Function) decoder() []decoder {
|
||||
|
|
|
@ -56,7 +56,7 @@ func javaCPUProfile(b []byte, period int64, parse func(b []byte) (uint64, []byte
|
|||
}
|
||||
|
||||
// Strip out addresses for better merge.
|
||||
if err = p.Aggregate(true, true, true, true, false); err != nil {
|
||||
if err = p.Aggregate(true, true, true, true, false, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ func parseJavaProfile(b []byte) (*Profile, error) {
|
|||
}
|
||||
|
||||
// Strip out addresses for better merge.
|
||||
if err = p.Aggregate(true, true, true, true, false); err != nil {
|
||||
if err = p.Aggregate(true, true, true, true, false, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -326,12 +326,13 @@ func (l *Location) key() locationKey {
|
|||
key.addr -= l.Mapping.Start
|
||||
key.mappingID = l.Mapping.ID
|
||||
}
|
||||
lines := make([]string, len(l.Line)*2)
|
||||
lines := make([]string, len(l.Line)*3)
|
||||
for i, line := range l.Line {
|
||||
if line.Function != nil {
|
||||
lines[i*2] = strconv.FormatUint(line.Function.ID, 16)
|
||||
}
|
||||
lines[i*2+1] = strconv.FormatInt(line.Line, 16)
|
||||
lines[i*2+2] = strconv.FormatInt(line.Column, 16)
|
||||
}
|
||||
key.lines = strings.Join(lines, "|")
|
||||
return key
|
||||
|
@ -418,6 +419,7 @@ func (pm *profileMerger) mapLine(src Line) Line {
|
|||
ln := Line{
|
||||
Function: pm.mapFunction(src.Function),
|
||||
Line: src.Line,
|
||||
Column: src.Column,
|
||||
}
|
||||
return ln
|
||||
}
|
||||
|
|
|
@ -145,6 +145,7 @@ type Location struct {
|
|||
type Line struct {
|
||||
Function *Function
|
||||
Line int64
|
||||
Column int64
|
||||
|
||||
functionIDX uint64
|
||||
}
|
||||
|
@ -436,7 +437,7 @@ func (p *Profile) CheckValid() error {
|
|||
// Aggregate merges the locations in the profile into equivalence
|
||||
// classes preserving the request attributes. It also updates the
|
||||
// samples to point to the merged locations.
|
||||
func (p *Profile) Aggregate(inlineFrame, function, filename, linenumber, address bool) error {
|
||||
func (p *Profile) Aggregate(inlineFrame, function, filename, linenumber, columnnumber, address bool) error {
|
||||
for _, m := range p.Mapping {
|
||||
m.HasInlineFrames = m.HasInlineFrames && inlineFrame
|
||||
m.HasFunctions = m.HasFunctions && function
|
||||
|
@ -458,7 +459,7 @@ func (p *Profile) Aggregate(inlineFrame, function, filename, linenumber, address
|
|||
}
|
||||
|
||||
// Aggregate locations
|
||||
if !inlineFrame || !address || !linenumber {
|
||||
if !inlineFrame || !address || !linenumber || !columnnumber {
|
||||
for _, l := range p.Location {
|
||||
if !inlineFrame && len(l.Line) > 1 {
|
||||
l.Line = l.Line[len(l.Line)-1:]
|
||||
|
@ -466,6 +467,12 @@ func (p *Profile) Aggregate(inlineFrame, function, filename, linenumber, address
|
|||
if !linenumber {
|
||||
for i := range l.Line {
|
||||
l.Line[i].Line = 0
|
||||
l.Line[i].Column = 0
|
||||
}
|
||||
}
|
||||
if !columnnumber {
|
||||
for i := range l.Line {
|
||||
l.Line[i].Column = 0
|
||||
}
|
||||
}
|
||||
if !address {
|
||||
|
@ -627,10 +634,11 @@ func (l *Location) string() string {
|
|||
for li := range l.Line {
|
||||
lnStr := "??"
|
||||
if fn := l.Line[li].Function; fn != nil {
|
||||
lnStr = fmt.Sprintf("%s %s:%d s=%d",
|
||||
lnStr = fmt.Sprintf("%s %s:%d:%d s=%d",
|
||||
fn.Name,
|
||||
fn.Filename,
|
||||
l.Line[li].Line,
|
||||
l.Line[li].Column,
|
||||
fn.StartLine)
|
||||
if fn.Name != fn.SystemName {
|
||||
lnStr = lnStr + "(" + fn.SystemName + ")"
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.4.3
|
||||
- 1.5.3
|
||||
- tip
|
||||
|
||||
script:
|
||||
- go test -v ./...
|
|
@ -0,0 +1,21 @@
|
|||
# Changelog
|
||||
|
||||
## [1.4.0](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) (2023-10-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* UUIDs slice type with Strings() convenience method ([#133](https://github.com/google/uuid/issues/133)) ([cd5fbbd](https://github.com/google/uuid/commit/cd5fbbdd02f3e3467ac18940e07e062be1f864b4))
|
||||
|
||||
### Fixes
|
||||
|
||||
* Clarify that Parse's job is to parse but not necessarily validate strings. (Documents current behavior)
|
||||
|
||||
## [1.3.1](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) (2023-08-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use .EqualFold() to parse urn prefixed UUIDs ([#118](https://github.com/google/uuid/issues/118)) ([574e687](https://github.com/google/uuid/commit/574e6874943741fb99d41764c705173ada5293f0))
|
||||
|
||||
## Changelog
|
|
@ -2,6 +2,22 @@
|
|||
|
||||
We definitely welcome patches and contribution to this project!
|
||||
|
||||
### Tips
|
||||
|
||||
Commits must be formatted according to the [Conventional Commits Specification](https://www.conventionalcommits.org).
|
||||
|
||||
Always try to include a test case! If it is not possible or not necessary,
|
||||
please explain why in the pull request description.
|
||||
|
||||
### Releasing
|
||||
|
||||
Commits that would precipitate a SemVer change, as described in the Conventional
|
||||
Commits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action)
|
||||
to create a release candidate pull request. Once submitted, `release-please`
|
||||
will create a release.
|
||||
|
||||
For tips on how to work with `release-please`, see its documentation.
|
||||
|
||||
### Legal requirements
|
||||
|
||||
In order to protect both you and ourselves, you will need to sign the
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master)
|
||||
# uuid
|
||||
The uuid package generates and inspects UUIDs based on
|
||||
[RFC 4122](http://tools.ietf.org/html/rfc4122)
|
||||
[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122)
|
||||
and DCE 1.1: Authentication and Security Services.
|
||||
|
||||
This package is based on the github.com/pborman/uuid package (previously named
|
||||
|
@ -9,10 +9,12 @@ a UUID is a 16 byte array rather than a byte slice. One loss due to this
|
|||
change is the ability to represent an invalid UUID (vs a NIL UUID).
|
||||
|
||||
###### Install
|
||||
`go get github.com/google/uuid`
|
||||
```sh
|
||||
go get github.com/google/uuid
|
||||
```
|
||||
|
||||
###### Documentation
|
||||
[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid)
|
||||
[![Go Reference](https://pkg.go.dev/badge/github.com/google/uuid.svg)](https://pkg.go.dev/github.com/google/uuid)
|
||||
|
||||
Full `go doc` style documentation for the package can be viewed online without
|
||||
installing this package by using the GoDoc site here:
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
package uuid
|
||||
|
||||
// getHardwareInterface returns nil values for the JS version of the code.
|
||||
// This remvoves the "net" dependency, because it is not used in the browser.
|
||||
// This removes the "net" dependency, because it is not used in the browser.
|
||||
// Using the "net" library inflates the size of the transpiled JS code by 673k bytes.
|
||||
func getHardwareInterface(name string) (string, []byte) { return "", nil }
|
||||
|
|
|
@ -56,11 +56,15 @@ func IsInvalidLengthError(err error) bool {
|
|||
return ok
|
||||
}
|
||||
|
||||
// Parse decodes s into a UUID or returns an error. Both the standard UUID
|
||||
// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the
|
||||
// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex
|
||||
// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
|
||||
// Parse decodes s into a UUID or returns an error if it cannot be parsed. Both
|
||||
// the standard UUID forms defined in RFC 4122
|
||||
// (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) are decoded. In addition,
|
||||
// Parse accepts non-standard strings such as the raw hex encoding
|
||||
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx and 38 byte "Microsoft style" encodings,
|
||||
// e.g. {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. Only the middle 36 bytes are
|
||||
// examined in the latter case. Parse should not be used to validate strings as
|
||||
// it parses non-standard encodings as indicated above.
|
||||
func Parse(s string) (UUID, error) {
|
||||
var uuid UUID
|
||||
switch len(s) {
|
||||
|
@ -69,7 +73,7 @@ func Parse(s string) (UUID, error) {
|
|||
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36 + 9:
|
||||
if strings.ToLower(s[:9]) != "urn:uuid:" {
|
||||
if !strings.EqualFold(s[:9], "urn:uuid:") {
|
||||
return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9])
|
||||
}
|
||||
s = s[9:]
|
||||
|
@ -101,7 +105,8 @@ func Parse(s string) (UUID, error) {
|
|||
9, 11,
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34} {
|
||||
24, 26, 28, 30, 32, 34,
|
||||
} {
|
||||
v, ok := xtob(s[x], s[x+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
|
@ -117,7 +122,7 @@ func ParseBytes(b []byte) (UUID, error) {
|
|||
switch len(b) {
|
||||
case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) {
|
||||
if !bytes.EqualFold(b[:9], []byte("urn:uuid:")) {
|
||||
return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9])
|
||||
}
|
||||
b = b[9:]
|
||||
|
@ -145,7 +150,8 @@ func ParseBytes(b []byte) (UUID, error) {
|
|||
9, 11,
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34} {
|
||||
24, 26, 28, 30, 32, 34,
|
||||
} {
|
||||
v, ok := xtob(b[x], b[x+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
|
@ -292,3 +298,15 @@ func DisableRandPool() {
|
|||
poolMu.Lock()
|
||||
poolPos = randPoolSize
|
||||
}
|
||||
|
||||
// UUIDs is a slice of UUID types.
|
||||
type UUIDs []UUID
|
||||
|
||||
// Strings returns a string slice containing the string form of each UUID in uuids.
|
||||
func (uuids UUIDs) Strings() []string {
|
||||
var uuidStrs = make([]string, len(uuids))
|
||||
for i, uuid := range uuids {
|
||||
uuidStrs[i] = uuid.String()
|
||||
}
|
||||
return uuidStrs
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
; https://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.md]
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
eclint_indent_style = unset
|
|
@ -1,25 +1 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
|
||||
.idea/
|
||||
*.iml
|
||||
coverage.coverprofile
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
run:
|
||||
skip-dirs:
|
||||
- examples/*.go
|
|
@ -1,9 +0,0 @@
|
|||
# This is the official list of Gorilla WebSocket authors for copyright
|
||||
# purposes.
|
||||
#
|
||||
# Please keep the list sorted.
|
||||
|
||||
Gary Burd <gary@beagledreams.com>
|
||||
Google LLC (https://opensource.google.com/)
|
||||
Joachim Bauch <mail@joachim-bauch.de>
|
||||
|
|
@ -1,22 +1,27 @@
|
|||
Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
Copyright (c) 2023 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:
|
||||
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 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.
|
||||
|
||||
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.
|
||||
|
||||
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 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
|
||||
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.
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '')
|
||||
GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||
|
||||
GO_SEC=$(shell which gosec 2> /dev/null || echo '')
|
||||
GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest
|
||||
|
||||
GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '')
|
||||
GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
||||
.PHONY: golangci-lint
|
||||
golangci-lint:
|
||||
$(if $(GO_LINT), ,go install $(GO_LINT_URI))
|
||||
@echo "##### Running golangci-lint"
|
||||
golangci-lint run -v
|
||||
|
||||
.PHONY: gosec
|
||||
gosec:
|
||||
$(if $(GO_SEC), ,go install $(GO_SEC_URI))
|
||||
@echo "##### Running gosec"
|
||||
gosec -exclude-dir examples ./...
|
||||
|
||||
.PHONY: govulncheck
|
||||
govulncheck:
|
||||
$(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI))
|
||||
@echo "##### Running govulncheck"
|
||||
govulncheck ./...
|
||||
|
||||
.PHONY: verify
|
||||
verify: golangci-lint gosec govulncheck
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
@echo "##### Running tests"
|
||||
go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./...
|
|
@ -1,17 +1,14 @@
|
|||
# Gorilla WebSocket
|
||||
# gorilla/websocket
|
||||
|
||||
[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket)
|
||||
[![CircleCI](https://circleci.com/gh/gorilla/websocket.svg?style=svg)](https://circleci.com/gh/gorilla/websocket)
|
||||
![testing](https://github.com/gorilla/websocket/actions/workflows/test.yml/badge.svg)
|
||||
[![codecov](https://codecov.io/github/gorilla/websocket/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/websocket)
|
||||
[![godoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket)
|
||||
[![sourcegraph](https://sourcegraph.com/github.com/gorilla/websocket/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/websocket?badge)
|
||||
|
||||
Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
|
||||
[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
|
||||
Gorilla WebSocket is a [Go](http://golang.org/) implementation of the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
|
||||
|
||||
![Gorilla Logo](https://github.com/gorilla/.github/assets/53367916/d92caabf-98e0-473e-bfbf-ab554ba435e5)
|
||||
|
||||
---
|
||||
|
||||
⚠️ **[The Gorilla WebSocket Package is looking for a new maintainer](https://github.com/gorilla/websocket/issues/370)**
|
||||
|
||||
---
|
||||
|
||||
### Documentation
|
||||
|
||||
|
@ -20,6 +17,7 @@ Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
|
|||
* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command)
|
||||
* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo)
|
||||
* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)
|
||||
* [Write buffer pool example](https://github.com/gorilla/websocket/tree/master/examples/bufferpool)
|
||||
|
||||
### Status
|
||||
|
||||
|
@ -36,4 +34,3 @@ package API is stable.
|
|||
The Gorilla WebSocket package passes the server tests in the [Autobahn Test
|
||||
Suite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn
|
||||
subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).
|
||||
|
||||
|
|
|
@ -9,14 +9,18 @@ import (
|
|||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptrace"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
// ErrBadHandshake is returned when the server response to opening handshake is
|
||||
|
@ -224,6 +228,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
|||
k == "Connection" ||
|
||||
k == "Sec-Websocket-Key" ||
|
||||
k == "Sec-Websocket-Version" ||
|
||||
//#nosec G101 (CWE-798): Potential HTTP request smuggling via parameter pollution
|
||||
k == "Sec-Websocket-Extensions" ||
|
||||
(k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
|
||||
return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
|
||||
|
@ -289,7 +294,9 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
|||
}
|
||||
err = c.SetDeadline(deadline)
|
||||
if err != nil {
|
||||
c.Close()
|
||||
if err := c.Close(); err != nil {
|
||||
log.Printf("websocket: failed to close network connection: %v", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
|
@ -303,7 +310,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
|||
return nil, nil, err
|
||||
}
|
||||
if proxyURL != nil {
|
||||
dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial))
|
||||
dialer, err := proxy.FromURL(proxyURL, netDialerFunc(netDial))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -318,18 +325,20 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
|||
}
|
||||
|
||||
netConn, err := netDial("tcp", hostPort)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if trace != nil && trace.GotConn != nil {
|
||||
trace.GotConn(httptrace.GotConnInfo{
|
||||
Conn: netConn,
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if netConn != nil {
|
||||
netConn.Close()
|
||||
if err := netConn.Close(); err != nil {
|
||||
log.Printf("websocket: failed to close network connection: %v", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -370,6 +379,17 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
|||
|
||||
resp, err := http.ReadResponse(conn.br, req)
|
||||
if err != nil {
|
||||
if d.TLSClientConfig != nil {
|
||||
for _, proto := range d.TLSClientConfig.NextProtos {
|
||||
if proto != "http/1.1" {
|
||||
return nil, nil, fmt.Errorf(
|
||||
"websocket: protocol %q was given but is not supported;"+
|
||||
"sharing tls.Config with net/http Transport can cause this error: %w",
|
||||
proto, err,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
|
@ -388,7 +408,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
|||
// debugging.
|
||||
buf := make([]byte, 1024)
|
||||
n, _ := io.ReadFull(resp.Body, buf)
|
||||
resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))
|
||||
resp.Body = io.NopCloser(bytes.NewReader(buf[:n]))
|
||||
return nil, resp, ErrBadHandshake
|
||||
}
|
||||
|
||||
|
@ -406,17 +426,19 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
|||
break
|
||||
}
|
||||
|
||||
resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||
resp.Body = io.NopCloser(bytes.NewReader([]byte{}))
|
||||
conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")
|
||||
|
||||
netConn.SetDeadline(time.Time{})
|
||||
if err := netConn.SetDeadline(time.Time{}); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
netConn = nil // to avoid close in defer.
|
||||
return conn, resp, nil
|
||||
}
|
||||
|
||||
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||
if cfg == nil {
|
||||
return &tls.Config{}
|
||||
return &tls.Config{MinVersion: tls.VersionTLS12}
|
||||
}
|
||||
return cfg.Clone()
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"compress/flate"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
@ -33,7 +34,9 @@ func decompressNoContextTakeover(r io.Reader) io.ReadCloser {
|
|||
"\x01\x00\x00\xff\xff"
|
||||
|
||||
fr, _ := flateReaderPool.Get().(io.ReadCloser)
|
||||
fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil)
|
||||
if err := fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &flateReadWrapper{fr}
|
||||
}
|
||||
|
||||
|
@ -132,7 +135,9 @@ func (r *flateReadWrapper) Read(p []byte) (int, error) {
|
|||
// Preemptively place the reader back in the pool. This helps with
|
||||
// scenarios where the application does not call NextReader() soon after
|
||||
// this final read.
|
||||
r.Close()
|
||||
if err := r.Close(); err != nil {
|
||||
log.Printf("websocket: flateReadWrapper.Close() returned error: %v", err)
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@ package websocket
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"log"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -181,13 +181,20 @@ var (
|
|||
errInvalidControlFrame = errors.New("websocket: invalid control frame")
|
||||
)
|
||||
|
||||
// maskRand is an io.Reader for generating mask bytes. The reader is initialized
|
||||
// to crypto/rand Reader. Tests swap the reader to a math/rand reader for
|
||||
// reproducible results.
|
||||
var maskRand = rand.Reader
|
||||
|
||||
// newMaskKey returns a new 32 bit value for masking client frames.
|
||||
func newMaskKey() [4]byte {
|
||||
n := rand.Uint32()
|
||||
return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}
|
||||
var k [4]byte
|
||||
_, _ = io.ReadFull(maskRand, k[:])
|
||||
return k
|
||||
}
|
||||
|
||||
func hideTempErr(err error) error {
|
||||
if e, ok := err.(net.Error); ok && e.Temporary() {
|
||||
if e, ok := err.(net.Error); ok {
|
||||
err = &netError{msg: e.Error(), timeout: e.Timeout()}
|
||||
}
|
||||
return err
|
||||
|
@ -372,7 +379,9 @@ func (c *Conn) read(n int) ([]byte, error) {
|
|||
if err == io.EOF {
|
||||
err = errUnexpectedEOF
|
||||
}
|
||||
c.br.Discard(len(p))
|
||||
if _, err := c.br.Discard(len(p)); err != nil {
|
||||
return p, err
|
||||
}
|
||||
return p, err
|
||||
}
|
||||
|
||||
|
@ -387,7 +396,9 @@ func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error
|
|||
return err
|
||||
}
|
||||
|
||||
c.conn.SetWriteDeadline(deadline)
|
||||
if err := c.conn.SetWriteDeadline(deadline); err != nil {
|
||||
return c.writeFatal(err)
|
||||
}
|
||||
if len(buf1) == 0 {
|
||||
_, err = c.conn.Write(buf0)
|
||||
} else {
|
||||
|
@ -397,7 +408,7 @@ func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error
|
|||
return c.writeFatal(err)
|
||||
}
|
||||
if frameType == CloseMessage {
|
||||
c.writeFatal(ErrCloseSent)
|
||||
_ = c.writeFatal(ErrCloseSent)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -438,7 +449,7 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er
|
|||
|
||||
d := 1000 * time.Hour
|
||||
if !deadline.IsZero() {
|
||||
d = deadline.Sub(time.Now())
|
||||
d = time.Until(deadline)
|
||||
if d < 0 {
|
||||
return errWriteTimeout
|
||||
}
|
||||
|
@ -460,13 +471,15 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er
|
|||
return err
|
||||
}
|
||||
|
||||
c.conn.SetWriteDeadline(deadline)
|
||||
if err := c.conn.SetWriteDeadline(deadline); err != nil {
|
||||
return c.writeFatal(err)
|
||||
}
|
||||
_, err = c.conn.Write(buf)
|
||||
if err != nil {
|
||||
return c.writeFatal(err)
|
||||
}
|
||||
if messageType == CloseMessage {
|
||||
c.writeFatal(ErrCloseSent)
|
||||
_ = c.writeFatal(ErrCloseSent)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -477,7 +490,9 @@ func (c *Conn) beginMessage(mw *messageWriter, messageType int) error {
|
|||
// probably better to return an error in this situation, but we cannot
|
||||
// change this without breaking existing applications.
|
||||
if c.writer != nil {
|
||||
c.writer.Close()
|
||||
if err := c.writer.Close(); err != nil {
|
||||
log.Printf("websocket: discarding writer close error: %v", err)
|
||||
}
|
||||
c.writer = nil
|
||||
}
|
||||
|
||||
|
@ -630,7 +645,7 @@ func (w *messageWriter) flushFrame(final bool, extra []byte) error {
|
|||
}
|
||||
|
||||
if final {
|
||||
w.endMessage(errWriteClosed)
|
||||
_ = w.endMessage(errWriteClosed)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -795,7 +810,7 @@ func (c *Conn) advanceFrame() (int, error) {
|
|||
// 1. Skip remainder of previous frame.
|
||||
|
||||
if c.readRemaining > 0 {
|
||||
if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {
|
||||
if _, err := io.CopyN(io.Discard, c.br, c.readRemaining); err != nil {
|
||||
return noFrame, err
|
||||
}
|
||||
}
|
||||
|
@ -817,7 +832,9 @@ func (c *Conn) advanceFrame() (int, error) {
|
|||
rsv2 := p[0]&rsv2Bit != 0
|
||||
rsv3 := p[0]&rsv3Bit != 0
|
||||
mask := p[1]&maskBit != 0
|
||||
c.setReadRemaining(int64(p[1] & 0x7f))
|
||||
if err := c.setReadRemaining(int64(p[1] & 0x7f)); err != nil {
|
||||
return noFrame, err
|
||||
}
|
||||
|
||||
c.readDecompress = false
|
||||
if rsv1 {
|
||||
|
@ -922,7 +939,9 @@ func (c *Conn) advanceFrame() (int, error) {
|
|||
}
|
||||
|
||||
if c.readLimit > 0 && c.readLength > c.readLimit {
|
||||
c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait))
|
||||
if err := c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait)); err != nil {
|
||||
return noFrame, err
|
||||
}
|
||||
return noFrame, ErrReadLimit
|
||||
}
|
||||
|
||||
|
@ -934,7 +953,9 @@ func (c *Conn) advanceFrame() (int, error) {
|
|||
var payload []byte
|
||||
if c.readRemaining > 0 {
|
||||
payload, err = c.read(int(c.readRemaining))
|
||||
c.setReadRemaining(0)
|
||||
if err := c.setReadRemaining(0); err != nil {
|
||||
return noFrame, err
|
||||
}
|
||||
if err != nil {
|
||||
return noFrame, err
|
||||
}
|
||||
|
@ -981,7 +1002,9 @@ func (c *Conn) handleProtocolError(message string) error {
|
|||
if len(data) > maxControlFramePayloadSize {
|
||||
data = data[:maxControlFramePayloadSize]
|
||||
}
|
||||
c.WriteControl(CloseMessage, data, time.Now().Add(writeWait))
|
||||
if err := c.WriteControl(CloseMessage, data, time.Now().Add(writeWait)); err != nil {
|
||||
return err
|
||||
}
|
||||
return errors.New("websocket: " + message)
|
||||
}
|
||||
|
||||
|
@ -998,7 +1021,9 @@ func (c *Conn) handleProtocolError(message string) error {
|
|||
func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
|
||||
// Close previous reader, only relevant for decompression.
|
||||
if c.reader != nil {
|
||||
c.reader.Close()
|
||||
if err := c.reader.Close(); err != nil {
|
||||
log.Printf("websocket: discarding reader close error: %v", err)
|
||||
}
|
||||
c.reader = nil
|
||||
}
|
||||
|
||||
|
@ -1054,7 +1079,9 @@ func (r *messageReader) Read(b []byte) (int, error) {
|
|||
}
|
||||
rem := c.readRemaining
|
||||
rem -= int64(n)
|
||||
c.setReadRemaining(rem)
|
||||
if err := c.setReadRemaining(rem); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if c.readRemaining > 0 && c.readErr == io.EOF {
|
||||
c.readErr = errUnexpectedEOF
|
||||
}
|
||||
|
@ -1094,7 +1121,7 @@ func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
|
|||
if err != nil {
|
||||
return messageType, nil, err
|
||||
}
|
||||
p, err = ioutil.ReadAll(r)
|
||||
p, err = io.ReadAll(r)
|
||||
return messageType, p, err
|
||||
}
|
||||
|
||||
|
@ -1136,7 +1163,9 @@ func (c *Conn) SetCloseHandler(h func(code int, text string) error) {
|
|||
if h == nil {
|
||||
h = func(code int, text string) error {
|
||||
message := FormatCloseMessage(code, "")
|
||||
c.WriteControl(CloseMessage, message, time.Now().Add(writeWait))
|
||||
if err := c.WriteControl(CloseMessage, message, time.Now().Add(writeWait)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -1161,7 +1190,7 @@ func (c *Conn) SetPingHandler(h func(appData string) error) {
|
|||
err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
|
||||
if err == ErrCloseSent {
|
||||
return nil
|
||||
} else if e, ok := err.(net.Error); ok && e.Temporary() {
|
||||
} else if _, ok := err.(net.Error); ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
|
@ -1189,8 +1218,16 @@ func (c *Conn) SetPongHandler(h func(appData string) error) {
|
|||
c.handlePong = h
|
||||
}
|
||||
|
||||
// NetConn returns the underlying connection that is wrapped by c.
|
||||
// Note that writing to or reading from this connection directly will corrupt the
|
||||
// WebSocket connection.
|
||||
func (c *Conn) NetConn() net.Conn {
|
||||
return c.conn
|
||||
}
|
||||
|
||||
// UnderlyingConn returns the internal net.Conn. This can be used to further
|
||||
// modifications to connection specific flags.
|
||||
// Deprecated: Use the NetConn method.
|
||||
func (c *Conn) UnderlyingConn() net.Conn {
|
||||
return c.conn
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ package websocket
|
|||
|
||||
import "unsafe"
|
||||
|
||||
// #nosec G103 -- (CWE-242) Has been audited
|
||||
const wordSize = int(unsafe.Sizeof(uintptr(0)))
|
||||
|
||||
func maskBytes(key [4]byte, pos int, b []byte) int {
|
||||
|
@ -22,6 +23,7 @@ func maskBytes(key [4]byte, pos int, b []byte) int {
|
|||
}
|
||||
|
||||
// Mask one byte at a time to word boundary.
|
||||
//#nosec G103 -- (CWE-242) Has been audited
|
||||
if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 {
|
||||
n = wordSize - n
|
||||
for i := range b[:n] {
|
||||
|
@ -36,11 +38,13 @@ func maskBytes(key [4]byte, pos int, b []byte) int {
|
|||
for i := range k {
|
||||
k[i] = key[(pos+i)&3]
|
||||
}
|
||||
//#nosec G103 -- (CWE-242) Has been audited
|
||||
kw := *(*uintptr)(unsafe.Pointer(&k))
|
||||
|
||||
// Mask one word at a time.
|
||||
n := (len(b) / wordSize) * wordSize
|
||||
for i := 0; i < n; i += wordSize {
|
||||
//#nosec G103 -- (CWE-242) Has been audited
|
||||
*(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,13 @@ import (
|
|||
"bufio"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
type netDialerFunc func(network, addr string) (net.Conn, error)
|
||||
|
@ -21,7 +24,7 @@ func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) {
|
|||
}
|
||||
|
||||
func init() {
|
||||
proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) {
|
||||
proxy.RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy.Dialer) (proxy.Dialer, error) {
|
||||
return &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil
|
||||
})
|
||||
}
|
||||
|
@ -55,7 +58,9 @@ func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error)
|
|||
}
|
||||
|
||||
if err := connectReq.Write(conn); err != nil {
|
||||
conn.Close()
|
||||
if err := conn.Close(); err != nil {
|
||||
log.Printf("httpProxyDialer: failed to close connection: %v", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -64,12 +69,16 @@ func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error)
|
|||
br := bufio.NewReader(conn)
|
||||
resp, err := http.ReadResponse(br, connectReq)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
if err := conn.Close(); err != nil {
|
||||
log.Printf("httpProxyDialer: failed to close connection: %v", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
conn.Close()
|
||||
if err := conn.Close(); err != nil {
|
||||
log.Printf("httpProxyDialer: failed to close connection: %v", err)
|
||||
}
|
||||
f := strings.SplitN(resp.Status, " ", 2)
|
||||
return nil, errors.New(f[1])
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"bufio"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
@ -154,8 +155,8 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
|
|||
}
|
||||
|
||||
challengeKey := r.Header.Get("Sec-Websocket-Key")
|
||||
if challengeKey == "" {
|
||||
return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header is missing or blank")
|
||||
if !isValidChallengeKey(challengeKey) {
|
||||
return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header must be Base64 encoded value of 16-byte in length")
|
||||
}
|
||||
|
||||
subprotocol := u.selectSubprotocol(r, responseHeader)
|
||||
|
@ -183,7 +184,9 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
|
|||
}
|
||||
|
||||
if brw.Reader.Buffered() > 0 {
|
||||
netConn.Close()
|
||||
if err := netConn.Close(); err != nil {
|
||||
log.Printf("websocket: failed to close network connection: %v", err)
|
||||
}
|
||||
return nil, errors.New("websocket: client sent data before handshake is complete")
|
||||
}
|
||||
|
||||
|
@ -248,17 +251,34 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
|
|||
p = append(p, "\r\n"...)
|
||||
|
||||
// Clear deadlines set by HTTP server.
|
||||
netConn.SetDeadline(time.Time{})
|
||||
if err := netConn.SetDeadline(time.Time{}); err != nil {
|
||||
if err := netConn.Close(); err != nil {
|
||||
log.Printf("websocket: failed to close network connection: %v", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if u.HandshakeTimeout > 0 {
|
||||
netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout))
|
||||
if err := netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout)); err != nil {
|
||||
if err := netConn.Close(); err != nil {
|
||||
log.Printf("websocket: failed to close network connection: %v", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if _, err = netConn.Write(p); err != nil {
|
||||
netConn.Close()
|
||||
if err := netConn.Close(); err != nil {
|
||||
log.Printf("websocket: failed to close network connection: %v", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if u.HandshakeTimeout > 0 {
|
||||
netConn.SetWriteDeadline(time.Time{})
|
||||
if err := netConn.SetWriteDeadline(time.Time{}); err != nil {
|
||||
if err := netConn.Close(); err != nil {
|
||||
log.Printf("websocket: failed to close network connection: %v", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return c, nil
|
||||
|
@ -356,8 +376,12 @@ func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte {
|
|||
// bufio.Writer's underlying writer.
|
||||
var wh writeHook
|
||||
bw.Reset(&wh)
|
||||
bw.WriteByte(0)
|
||||
bw.Flush()
|
||||
if err := bw.WriteByte(0); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := bw.Flush(); err != nil {
|
||||
log.Printf("websocket: bufioWriterBuffer: Flush: %v", err)
|
||||
}
|
||||
|
||||
bw.Reset(originalWriter)
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
//go:build go1.17
|
||||
// +build go1.17
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
//go:build !go1.17
|
||||
// +build !go1.17
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
)
|
||||
|
||||
func doHandshake(ctx context.Context, tlsConn *tls.Conn, cfg *tls.Config) error {
|
||||
if err := tlsConn.Handshake(); err != nil {
|
||||
return err
|
||||
}
|
||||
if !cfg.InsecureSkipVerify {
|
||||
if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -6,7 +6,7 @@ package websocket
|
|||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"crypto/sha1" //#nosec G505 -- (CWE-327) https://datatracker.ietf.org/doc/html/rfc6455#page-54
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"net/http"
|
||||
|
@ -17,7 +17,7 @@ import (
|
|||
var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
|
||||
|
||||
func computeAcceptKey(challengeKey string) string {
|
||||
h := sha1.New()
|
||||
h := sha1.New() //#nosec G401 -- (CWE-326) https://datatracker.ietf.org/doc/html/rfc6455#page-54
|
||||
h.Write([]byte(challengeKey))
|
||||
h.Write(keyGUID)
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
|
@ -281,3 +281,18 @@ headers:
|
|||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// isValidChallengeKey checks if the argument meets RFC6455 specification.
|
||||
func isValidChallengeKey(s string) bool {
|
||||
// From RFC6455:
|
||||
//
|
||||
// A |Sec-WebSocket-Key| header field with a base64-encoded (see
|
||||
// Section 4 of [RFC4648]) value that, when decoded, is 16 bytes in
|
||||
// length.
|
||||
|
||||
if s == "" {
|
||||
return false
|
||||
}
|
||||
decoded, err := base64.StdEncoding.DecodeString(s)
|
||||
return err == nil && len(decoded) == 16
|
||||
}
|
||||
|
|
|
@ -1,473 +0,0 @@
|
|||
// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
|
||||
//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy
|
||||
|
||||
// Package proxy provides support for a variety of protocols to proxy network
|
||||
// data.
|
||||
//
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type proxy_direct struct{}
|
||||
|
||||
// Direct is a direct proxy: one that makes network connections directly.
|
||||
var proxy_Direct = proxy_direct{}
|
||||
|
||||
func (proxy_direct) Dial(network, addr string) (net.Conn, error) {
|
||||
return net.Dial(network, addr)
|
||||
}
|
||||
|
||||
// A PerHost directs connections to a default Dialer unless the host name
|
||||
// requested matches one of a number of exceptions.
|
||||
type proxy_PerHost struct {
|
||||
def, bypass proxy_Dialer
|
||||
|
||||
bypassNetworks []*net.IPNet
|
||||
bypassIPs []net.IP
|
||||
bypassZones []string
|
||||
bypassHosts []string
|
||||
}
|
||||
|
||||
// NewPerHost returns a PerHost Dialer that directs connections to either
|
||||
// defaultDialer or bypass, depending on whether the connection matches one of
|
||||
// the configured rules.
|
||||
func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost {
|
||||
return &proxy_PerHost{
|
||||
def: defaultDialer,
|
||||
bypass: bypass,
|
||||
}
|
||||
}
|
||||
|
||||
// Dial connects to the address addr on the given network through either
|
||||
// defaultDialer or bypass.
|
||||
func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) {
|
||||
host, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p.dialerForRequest(host).Dial(network, addr)
|
||||
}
|
||||
|
||||
func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer {
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
for _, net := range p.bypassNetworks {
|
||||
if net.Contains(ip) {
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
for _, bypassIP := range p.bypassIPs {
|
||||
if bypassIP.Equal(ip) {
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
return p.def
|
||||
}
|
||||
|
||||
for _, zone := range p.bypassZones {
|
||||
if strings.HasSuffix(host, zone) {
|
||||
return p.bypass
|
||||
}
|
||||
if host == zone[1:] {
|
||||
// For a zone ".example.com", we match "example.com"
|
||||
// too.
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
for _, bypassHost := range p.bypassHosts {
|
||||
if bypassHost == host {
|
||||
return p.bypass
|
||||
}
|
||||
}
|
||||
return p.def
|
||||
}
|
||||
|
||||
// AddFromString parses a string that contains comma-separated values
|
||||
// specifying hosts that should use the bypass proxy. Each value is either an
|
||||
// IP address, a CIDR range, a zone (*.example.com) or a host name
|
||||
// (localhost). A best effort is made to parse the string and errors are
|
||||
// ignored.
|
||||
func (p *proxy_PerHost) AddFromString(s string) {
|
||||
hosts := strings.Split(s, ",")
|
||||
for _, host := range hosts {
|
||||
host = strings.TrimSpace(host)
|
||||
if len(host) == 0 {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(host, "/") {
|
||||
// We assume that it's a CIDR address like 127.0.0.0/8
|
||||
if _, net, err := net.ParseCIDR(host); err == nil {
|
||||
p.AddNetwork(net)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
p.AddIP(ip)
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(host, "*.") {
|
||||
p.AddZone(host[1:])
|
||||
continue
|
||||
}
|
||||
p.AddHost(host)
|
||||
}
|
||||
}
|
||||
|
||||
// AddIP specifies an IP address that will use the bypass proxy. Note that
|
||||
// this will only take effect if a literal IP address is dialed. A connection
|
||||
// to a named host will never match an IP.
|
||||
func (p *proxy_PerHost) AddIP(ip net.IP) {
|
||||
p.bypassIPs = append(p.bypassIPs, ip)
|
||||
}
|
||||
|
||||
// AddNetwork specifies an IP range that will use the bypass proxy. Note that
|
||||
// this will only take effect if a literal IP address is dialed. A connection
|
||||
// to a named host will never match.
|
||||
func (p *proxy_PerHost) AddNetwork(net *net.IPNet) {
|
||||
p.bypassNetworks = append(p.bypassNetworks, net)
|
||||
}
|
||||
|
||||
// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
|
||||
// "example.com" matches "example.com" and all of its subdomains.
|
||||
func (p *proxy_PerHost) AddZone(zone string) {
|
||||
if strings.HasSuffix(zone, ".") {
|
||||
zone = zone[:len(zone)-1]
|
||||
}
|
||||
if !strings.HasPrefix(zone, ".") {
|
||||
zone = "." + zone
|
||||
}
|
||||
p.bypassZones = append(p.bypassZones, zone)
|
||||
}
|
||||
|
||||
// AddHost specifies a host name that will use the bypass proxy.
|
||||
func (p *proxy_PerHost) AddHost(host string) {
|
||||
if strings.HasSuffix(host, ".") {
|
||||
host = host[:len(host)-1]
|
||||
}
|
||||
p.bypassHosts = append(p.bypassHosts, host)
|
||||
}
|
||||
|
||||
// A Dialer is a means to establish a connection.
|
||||
type proxy_Dialer interface {
|
||||
// Dial connects to the given address via the proxy.
|
||||
Dial(network, addr string) (c net.Conn, err error)
|
||||
}
|
||||
|
||||
// Auth contains authentication parameters that specific Dialers may require.
|
||||
type proxy_Auth struct {
|
||||
User, Password string
|
||||
}
|
||||
|
||||
// FromEnvironment returns the dialer specified by the proxy related variables in
|
||||
// the environment.
|
||||
func proxy_FromEnvironment() proxy_Dialer {
|
||||
allProxy := proxy_allProxyEnv.Get()
|
||||
if len(allProxy) == 0 {
|
||||
return proxy_Direct
|
||||
}
|
||||
|
||||
proxyURL, err := url.Parse(allProxy)
|
||||
if err != nil {
|
||||
return proxy_Direct
|
||||
}
|
||||
proxy, err := proxy_FromURL(proxyURL, proxy_Direct)
|
||||
if err != nil {
|
||||
return proxy_Direct
|
||||
}
|
||||
|
||||
noProxy := proxy_noProxyEnv.Get()
|
||||
if len(noProxy) == 0 {
|
||||
return proxy
|
||||
}
|
||||
|
||||
perHost := proxy_NewPerHost(proxy, proxy_Direct)
|
||||
perHost.AddFromString(noProxy)
|
||||
return perHost
|
||||
}
|
||||
|
||||
// proxySchemes is a map from URL schemes to a function that creates a Dialer
|
||||
// from a URL with such a scheme.
|
||||
var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)
|
||||
|
||||
// RegisterDialerType takes a URL scheme and a function to generate Dialers from
|
||||
// a URL with that scheme and a forwarding Dialer. Registered schemes are used
|
||||
// by FromURL.
|
||||
func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) {
|
||||
if proxy_proxySchemes == nil {
|
||||
proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error))
|
||||
}
|
||||
proxy_proxySchemes[scheme] = f
|
||||
}
|
||||
|
||||
// FromURL returns a Dialer given a URL specification and an underlying
|
||||
// Dialer for it to make network requests.
|
||||
func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) {
|
||||
var auth *proxy_Auth
|
||||
if u.User != nil {
|
||||
auth = new(proxy_Auth)
|
||||
auth.User = u.User.Username()
|
||||
if p, ok := u.User.Password(); ok {
|
||||
auth.Password = p
|
||||
}
|
||||
}
|
||||
|
||||
switch u.Scheme {
|
||||
case "socks5":
|
||||
return proxy_SOCKS5("tcp", u.Host, auth, forward)
|
||||
}
|
||||
|
||||
// If the scheme doesn't match any of the built-in schemes, see if it
|
||||
// was registered by another package.
|
||||
if proxy_proxySchemes != nil {
|
||||
if f, ok := proxy_proxySchemes[u.Scheme]; ok {
|
||||
return f(u, forward)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
|
||||
}
|
||||
|
||||
var (
|
||||
proxy_allProxyEnv = &proxy_envOnce{
|
||||
names: []string{"ALL_PROXY", "all_proxy"},
|
||||
}
|
||||
proxy_noProxyEnv = &proxy_envOnce{
|
||||
names: []string{"NO_PROXY", "no_proxy"},
|
||||
}
|
||||
)
|
||||
|
||||
// envOnce looks up an environment variable (optionally by multiple
|
||||
// names) once. It mitigates expensive lookups on some platforms
|
||||
// (e.g. Windows).
|
||||
// (Borrowed from net/http/transport.go)
|
||||
type proxy_envOnce struct {
|
||||
names []string
|
||||
once sync.Once
|
||||
val string
|
||||
}
|
||||
|
||||
func (e *proxy_envOnce) Get() string {
|
||||
e.once.Do(e.init)
|
||||
return e.val
|
||||
}
|
||||
|
||||
func (e *proxy_envOnce) init() {
|
||||
for _, n := range e.names {
|
||||
e.val = os.Getenv(n)
|
||||
if e.val != "" {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address
|
||||
// with an optional username and password. See RFC 1928 and RFC 1929.
|
||||
func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) {
|
||||
s := &proxy_socks5{
|
||||
network: network,
|
||||
addr: addr,
|
||||
forward: forward,
|
||||
}
|
||||
if auth != nil {
|
||||
s.user = auth.User
|
||||
s.password = auth.Password
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
type proxy_socks5 struct {
|
||||
user, password string
|
||||
network, addr string
|
||||
forward proxy_Dialer
|
||||
}
|
||||
|
||||
const proxy_socks5Version = 5
|
||||
|
||||
const (
|
||||
proxy_socks5AuthNone = 0
|
||||
proxy_socks5AuthPassword = 2
|
||||
)
|
||||
|
||||
const proxy_socks5Connect = 1
|
||||
|
||||
const (
|
||||
proxy_socks5IP4 = 1
|
||||
proxy_socks5Domain = 3
|
||||
proxy_socks5IP6 = 4
|
||||
)
|
||||
|
||||
var proxy_socks5Errors = []string{
|
||||
"",
|
||||
"general failure",
|
||||
"connection forbidden",
|
||||
"network unreachable",
|
||||
"host unreachable",
|
||||
"connection refused",
|
||||
"TTL expired",
|
||||
"command not supported",
|
||||
"address type not supported",
|
||||
}
|
||||
|
||||
// Dial connects to the address addr on the given network via the SOCKS5 proxy.
|
||||
func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) {
|
||||
switch network {
|
||||
case "tcp", "tcp6", "tcp4":
|
||||
default:
|
||||
return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network)
|
||||
}
|
||||
|
||||
conn, err := s.forward.Dial(s.network, s.addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.connect(conn, addr); err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// connect takes an existing connection to a socks5 proxy server,
|
||||
// and commands the server to extend that connection to target,
|
||||
// which must be a canonical address with a host and port.
|
||||
func (s *proxy_socks5) connect(conn net.Conn, target string) error {
|
||||
host, portStr, err := net.SplitHostPort(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
return errors.New("proxy: failed to parse port number: " + portStr)
|
||||
}
|
||||
if port < 1 || port > 0xffff {
|
||||
return errors.New("proxy: port number out of range: " + portStr)
|
||||
}
|
||||
|
||||
// the size here is just an estimate
|
||||
buf := make([]byte, 0, 6+len(host))
|
||||
|
||||
buf = append(buf, proxy_socks5Version)
|
||||
if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 {
|
||||
buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword)
|
||||
} else {
|
||||
buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone)
|
||||
}
|
||||
|
||||
if _, err := conn.Write(buf); err != nil {
|
||||
return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(conn, buf[:2]); err != nil {
|
||||
return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
if buf[0] != 5 {
|
||||
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0])))
|
||||
}
|
||||
if buf[1] == 0xff {
|
||||
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication")
|
||||
}
|
||||
|
||||
// See RFC 1929
|
||||
if buf[1] == proxy_socks5AuthPassword {
|
||||
buf = buf[:0]
|
||||
buf = append(buf, 1 /* password protocol version */)
|
||||
buf = append(buf, uint8(len(s.user)))
|
||||
buf = append(buf, s.user...)
|
||||
buf = append(buf, uint8(len(s.password)))
|
||||
buf = append(buf, s.password...)
|
||||
|
||||
if _, err := conn.Write(buf); err != nil {
|
||||
return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(conn, buf[:2]); err != nil {
|
||||
return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
if buf[1] != 0 {
|
||||
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password")
|
||||
}
|
||||
}
|
||||
|
||||
buf = buf[:0]
|
||||
buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */)
|
||||
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
buf = append(buf, proxy_socks5IP4)
|
||||
ip = ip4
|
||||
} else {
|
||||
buf = append(buf, proxy_socks5IP6)
|
||||
}
|
||||
buf = append(buf, ip...)
|
||||
} else {
|
||||
if len(host) > 255 {
|
||||
return errors.New("proxy: destination host name too long: " + host)
|
||||
}
|
||||
buf = append(buf, proxy_socks5Domain)
|
||||
buf = append(buf, byte(len(host)))
|
||||
buf = append(buf, host...)
|
||||
}
|
||||
buf = append(buf, byte(port>>8), byte(port))
|
||||
|
||||
if _, err := conn.Write(buf); err != nil {
|
||||
return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(conn, buf[:4]); err != nil {
|
||||
return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
failure := "unknown error"
|
||||
if int(buf[1]) < len(proxy_socks5Errors) {
|
||||
failure = proxy_socks5Errors[buf[1]]
|
||||
}
|
||||
|
||||
if len(failure) > 0 {
|
||||
return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure)
|
||||
}
|
||||
|
||||
bytesToDiscard := 0
|
||||
switch buf[3] {
|
||||
case proxy_socks5IP4:
|
||||
bytesToDiscard = net.IPv4len
|
||||
case proxy_socks5IP6:
|
||||
bytesToDiscard = net.IPv6len
|
||||
case proxy_socks5Domain:
|
||||
_, err := io.ReadFull(conn, buf[:1])
|
||||
if err != nil {
|
||||
return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
bytesToDiscard = int(buf[0])
|
||||
default:
|
||||
return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr)
|
||||
}
|
||||
|
||||
if cap(buf) < bytesToDiscard {
|
||||
buf = make([]byte, bytesToDiscard)
|
||||
} else {
|
||||
buf = buf[:bytesToDiscard]
|
||||
}
|
||||
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||
return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
// Also need to discard the port number
|
||||
if _, err := io.ReadFull(conn, buf[:2]); err != nil {
|
||||
return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -30,8 +30,10 @@ const (
|
|||
// head. The ARCCache is similar, but does not require setting any
|
||||
// parameters.
|
||||
type TwoQueueCache[K comparable, V any] struct {
|
||||
size int
|
||||
recentSize int
|
||||
size int
|
||||
recentSize int
|
||||
recentRatio float64
|
||||
ghostRatio float64
|
||||
|
||||
recent simplelru.LRUCache[K, V]
|
||||
frequent simplelru.LRUCache[K, V]
|
||||
|
@ -80,6 +82,8 @@ func New2QParams[K comparable, V any](size int, recentRatio, ghostRatio float64)
|
|||
c := &TwoQueueCache[K, V]{
|
||||
size: size,
|
||||
recentSize: recentSize,
|
||||
recentRatio: recentRatio,
|
||||
ghostRatio: ghostRatio,
|
||||
recent: recent,
|
||||
frequent: frequent,
|
||||
recentEvict: recentEvict,
|
||||
|
@ -171,6 +175,34 @@ func (c *TwoQueueCache[K, V]) Len() int {
|
|||
return c.recent.Len() + c.frequent.Len()
|
||||
}
|
||||
|
||||
// Resize changes the cache size.
|
||||
func (c *TwoQueueCache[K, V]) Resize(size int) (evicted int) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
// Recalculate the sub-sizes
|
||||
recentSize := int(float64(size) * c.recentRatio)
|
||||
evictSize := int(float64(size) * c.ghostRatio)
|
||||
c.size = size
|
||||
c.recentSize = recentSize
|
||||
|
||||
// ensureSpace
|
||||
diff := c.recent.Len() + c.frequent.Len() - size
|
||||
if diff < 0 {
|
||||
diff = 0
|
||||
}
|
||||
for i := 0; i < diff; i++ {
|
||||
c.ensureSpace(true)
|
||||
}
|
||||
|
||||
// Reallocate the LRUs
|
||||
c.recent.Resize(size)
|
||||
c.frequent.Resize(size)
|
||||
c.recentEvict.Resize(evictSize)
|
||||
|
||||
return diff
|
||||
}
|
||||
|
||||
// Keys returns a slice of the keys in the cache.
|
||||
// The frequently used keys are first in the returned slice.
|
||||
func (c *TwoQueueCache[K, V]) Keys() []K {
|
||||
|
|
|
@ -51,9 +51,6 @@ func (c *LRU[K, V]) Add(key K, value V) (evicted bool) {
|
|||
// Check for existing item
|
||||
if ent, ok := c.items[key]; ok {
|
||||
c.evictList.MoveToFront(ent)
|
||||
if c.onEvict != nil {
|
||||
c.onEvict(key, ent.Value)
|
||||
}
|
||||
ent.Value = value
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
before:
|
||||
hooks:
|
||||
- ./gen.sh
|
||||
- go install mvdan.cc/garble@v0.10.1
|
||||
|
||||
builds:
|
||||
-
|
||||
|
@ -32,7 +31,6 @@ builds:
|
|||
- mips64le
|
||||
goarm:
|
||||
- 7
|
||||
gobinary: garble
|
||||
-
|
||||
id: "s2d"
|
||||
binary: s2d
|
||||
|
@ -59,7 +57,6 @@ builds:
|
|||
- mips64le
|
||||
goarm:
|
||||
- 7
|
||||
gobinary: garble
|
||||
-
|
||||
id: "s2sx"
|
||||
binary: s2sx
|
||||
|
@ -87,7 +84,6 @@ builds:
|
|||
- mips64le
|
||||
goarm:
|
||||
- 7
|
||||
gobinary: garble
|
||||
|
||||
archives:
|
||||
-
|
||||
|
|
|
@ -16,6 +16,38 @@ This package provides various compression algorithms.
|
|||
|
||||
# changelog
|
||||
|
||||
* Feb 5th, 2024 - [1.17.6](https://github.com/klauspost/compress/releases/tag/v1.17.6)
|
||||
* zstd: Fix incorrect repeat coding in best mode https://github.com/klauspost/compress/pull/923
|
||||
* s2: Fix DecodeConcurrent deadlock on errors https://github.com/klauspost/compress/pull/925
|
||||
|
||||
* Jan 26th, 2024 - [v1.17.5](https://github.com/klauspost/compress/releases/tag/v1.17.5)
|
||||
* flate: Fix reset with dictionary on custom window encodes https://github.com/klauspost/compress/pull/912
|
||||
* zstd: Add Frame header encoding and stripping https://github.com/klauspost/compress/pull/908
|
||||
* zstd: Limit better/best default window to 8MB https://github.com/klauspost/compress/pull/913
|
||||
* zstd: Speed improvements by @greatroar in https://github.com/klauspost/compress/pull/896 https://github.com/klauspost/compress/pull/910
|
||||
* s2: Fix callbacks for skippable blocks and disallow 0xfe (Padding) by @Jille in https://github.com/klauspost/compress/pull/916 https://github.com/klauspost/compress/pull/917
|
||||
https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/compress/pull/918
|
||||
|
||||
* Dec 1st, 2023 - [v1.17.4](https://github.com/klauspost/compress/releases/tag/v1.17.4)
|
||||
* huff0: Speed up symbol counting by @greatroar in https://github.com/klauspost/compress/pull/887
|
||||
* huff0: Remove byteReader by @greatroar in https://github.com/klauspost/compress/pull/886
|
||||
* gzhttp: Allow overriding decompression on transport https://github.com/klauspost/compress/pull/892
|
||||
* gzhttp: Clamp compression level https://github.com/klauspost/compress/pull/890
|
||||
* gzip: Error out if reserved bits are set https://github.com/klauspost/compress/pull/891
|
||||
|
||||
* Nov 15th, 2023 - [v1.17.3](https://github.com/klauspost/compress/releases/tag/v1.17.3)
|
||||
* fse: Fix max header size https://github.com/klauspost/compress/pull/881
|
||||
* zstd: Improve better/best compression https://github.com/klauspost/compress/pull/877
|
||||
* gzhttp: Fix missing content type on Close https://github.com/klauspost/compress/pull/883
|
||||
|
||||
* Oct 22nd, 2023 - [v1.17.2](https://github.com/klauspost/compress/releases/tag/v1.17.2)
|
||||
* zstd: Fix rare *CORRUPTION* output in "best" mode. See https://github.com/klauspost/compress/pull/876
|
||||
|
||||
* Oct 14th, 2023 - [v1.17.1](https://github.com/klauspost/compress/releases/tag/v1.17.1)
|
||||
* s2: Fix S2 "best" dictionary wrong encoding by @klauspost in https://github.com/klauspost/compress/pull/871
|
||||
* flate: Reduce allocations in decompressor and minor code improvements by @fakefloordiv in https://github.com/klauspost/compress/pull/869
|
||||
* s2: Fix EstimateBlockSize on 6&7 length input by @klauspost in https://github.com/klauspost/compress/pull/867
|
||||
|
||||
* Sept 19th, 2023 - [v1.17.0](https://github.com/klauspost/compress/releases/tag/v1.17.0)
|
||||
* Add experimental dictionary builder https://github.com/klauspost/compress/pull/853
|
||||
* Add xerial snappy read/writer https://github.com/klauspost/compress/pull/838
|
||||
|
@ -23,6 +55,10 @@ This package provides various compression algorithms.
|
|||
* s2: Do 2 overlapping match checks https://github.com/klauspost/compress/pull/839
|
||||
* flate: Add amd64 assembly matchlen https://github.com/klauspost/compress/pull/837
|
||||
* gzip: Copy bufio.Reader on Reset by @thatguystone in https://github.com/klauspost/compress/pull/860
|
||||
|
||||
<details>
|
||||
<summary>See changes to v1.16.x</summary>
|
||||
|
||||
|
||||
* July 1st, 2023 - [v1.16.7](https://github.com/klauspost/compress/releases/tag/v1.16.7)
|
||||
* zstd: Fix default level first dictionary encode https://github.com/klauspost/compress/pull/829
|
||||
|
@ -61,6 +97,7 @@ This package provides various compression algorithms.
|
|||
* s2: Add LZ4 block converter. https://github.com/klauspost/compress/pull/748
|
||||
* s2: Support io.ReaderAt in ReadSeeker. https://github.com/klauspost/compress/pull/747
|
||||
* s2c/s2sx: Use concurrent decoding. https://github.com/klauspost/compress/pull/746
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>See changes to v1.15.x</summary>
|
||||
|
@ -528,6 +565,8 @@ the stateless compress described below.
|
|||
|
||||
For compression performance, see: [this spreadsheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing).
|
||||
|
||||
To disable all assembly add `-tags=noasm`. This works across all packages.
|
||||
|
||||
# Stateless compression
|
||||
|
||||
This package offers stateless compression as a special option for gzip/deflate.
|
||||
|
@ -546,7 +585,7 @@ For direct deflate use, NewStatelessWriter and StatelessDeflate are available. S
|
|||
|
||||
A `bufio.Writer` can of course be used to control write sizes. For example, to use a 4KB buffer:
|
||||
|
||||
```
|
||||
```go
|
||||
// replace 'ioutil.Discard' with your output.
|
||||
gzw, err := gzip.NewWriterLevel(ioutil.Discard, gzip.StatelessCompression)
|
||||
if err != nil {
|
||||
|
|
|
@ -212,7 +212,7 @@ func (s *Scratch) writeCount() error {
|
|||
previous0 bool
|
||||
charnum uint16
|
||||
|
||||
maxHeaderSize = ((int(s.symbolLen) * int(tableLog)) >> 3) + 3
|
||||
maxHeaderSize = ((int(s.symbolLen)*int(tableLog) + 4 + 2) >> 3) + 3
|
||||
|
||||
// Write Table Size
|
||||
bitStream = uint32(tableLog - minTablelog)
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright 2018 Klaus Post. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.
|
||||
|
||||
package huff0
|
||||
|
||||
// byteReader provides a byte reader that reads
|
||||
// little endian values from a byte stream.
|
||||
// The input stream is manually advanced.
|
||||
// The reader performs no bounds checks.
|
||||
type byteReader struct {
|
||||
b []byte
|
||||
off int
|
||||
}
|
||||
|
||||
// init will initialize the reader and set the input.
|
||||
func (b *byteReader) init(in []byte) {
|
||||
b.b = in
|
||||
b.off = 0
|
||||
}
|
||||
|
||||
// Int32 returns a little endian int32 starting at current offset.
|
||||
func (b byteReader) Int32() int32 {
|
||||
v3 := int32(b.b[b.off+3])
|
||||
v2 := int32(b.b[b.off+2])
|
||||
v1 := int32(b.b[b.off+1])
|
||||
v0 := int32(b.b[b.off])
|
||||
return (v3 << 24) | (v2 << 16) | (v1 << 8) | v0
|
||||
}
|
||||
|
||||
// Uint32 returns a little endian uint32 starting at current offset.
|
||||
func (b byteReader) Uint32() uint32 {
|
||||
v3 := uint32(b.b[b.off+3])
|
||||
v2 := uint32(b.b[b.off+2])
|
||||
v1 := uint32(b.b[b.off+1])
|
||||
v0 := uint32(b.b[b.off])
|
||||
return (v3 << 24) | (v2 << 16) | (v1 << 8) | v0
|
||||
}
|
||||
|
||||
// remain will return the number of bytes remaining.
|
||||
func (b byteReader) remain() int {
|
||||
return len(b.b) - b.off
|
||||
}
|
|
@ -350,6 +350,7 @@ func (s *Scratch) compress4Xp(src []byte) ([]byte, error) {
|
|||
// Does not update s.clearCount.
|
||||
func (s *Scratch) countSimple(in []byte) (max int, reuse bool) {
|
||||
reuse = true
|
||||
_ = s.count // Assert that s != nil to speed up the following loop.
|
||||
for _, v := range in {
|
||||
s.count[v]++
|
||||
}
|
||||
|
@ -415,7 +416,7 @@ func (s *Scratch) validateTable(c cTable) bool {
|
|||
|
||||
// minTableLog provides the minimum logSize to safely represent a distribution.
|
||||
func (s *Scratch) minTableLog() uint8 {
|
||||
minBitsSrc := highBit32(uint32(s.br.remain())) + 1
|
||||
minBitsSrc := highBit32(uint32(s.srcLen)) + 1
|
||||
minBitsSymbols := highBit32(uint32(s.symbolLen-1)) + 2
|
||||
if minBitsSrc < minBitsSymbols {
|
||||
return uint8(minBitsSrc)
|
||||
|
@ -427,7 +428,7 @@ func (s *Scratch) minTableLog() uint8 {
|
|||
func (s *Scratch) optimalTableLog() {
|
||||
tableLog := s.TableLog
|
||||
minBits := s.minTableLog()
|
||||
maxBitsSrc := uint8(highBit32(uint32(s.br.remain()-1))) - 1
|
||||
maxBitsSrc := uint8(highBit32(uint32(s.srcLen-1))) - 1
|
||||
if maxBitsSrc < tableLog {
|
||||
// Accuracy can be reduced
|
||||
tableLog = maxBitsSrc
|
||||
|
|
|
@ -88,7 +88,7 @@ type Scratch struct {
|
|||
// Decoders will return ErrMaxDecodedSizeExceeded is this limit is exceeded.
|
||||
MaxDecodedSize int
|
||||
|
||||
br byteReader
|
||||
srcLen int
|
||||
|
||||
// MaxSymbolValue will override the maximum symbol value of the next block.
|
||||
MaxSymbolValue uint8
|
||||
|
@ -170,7 +170,7 @@ func (s *Scratch) prepare(in []byte) (*Scratch, error) {
|
|||
if s.fse == nil {
|
||||
s.fse = &fse.Scratch{}
|
||||
}
|
||||
s.br.init(in)
|
||||
s.srcLen = len(in)
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ func emitCopy(dst []byte, offset, length int) int {
|
|||
i := 0
|
||||
// The maximum length for a single tagCopy1 or tagCopy2 op is 64 bytes. The
|
||||
// threshold for this loop is a little higher (at 68 = 64 + 4), and the
|
||||
// length emitted down below is is a little lower (at 60 = 64 - 4), because
|
||||
// length emitted down below is a little lower (at 60 = 64 - 4), because
|
||||
// it's shorter to encode a length 67 copy as a length 60 tagCopy2 followed
|
||||
// by a length 7 tagCopy1 (which encodes as 3+2 bytes) than to encode it as
|
||||
// a length 64 tagCopy2 followed by a length 3 tagCopy2 (which encodes as
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module github.com/klauspost/compress
|
||||
|
||||
go 1.16
|
||||
go 1.19
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ nyc-taxi-data-10M.csv gzkp 1 3325605752 922273214 13929 227.68
|
|||
|
||||
## Decompressor
|
||||
|
||||
Staus: STABLE - there may still be subtle bugs, but a wide variety of content has been tested.
|
||||
Status: STABLE - there may still be subtle bugs, but a wide variety of content has been tested.
|
||||
|
||||
This library is being continuously [fuzz-tested](https://github.com/klauspost/compress-fuzz),
|
||||
kindly supplied by [fuzzit.dev](https://fuzzit.dev/).
|
||||
|
|
|
@ -554,6 +554,9 @@ func (b *blockDec) prepareSequences(in []byte, hist *history) (err error) {
|
|||
if debugDecoder {
|
||||
printf("Compression modes: 0b%b", compMode)
|
||||
}
|
||||
if compMode&3 != 0 {
|
||||
return errors.New("corrupt block: reserved bits not zero")
|
||||
}
|
||||
for i := uint(0); i < 3; i++ {
|
||||
mode := seqCompMode((compMode >> (6 - i*2)) & 3)
|
||||
if debugDecoder {
|
||||
|
|
|
@ -427,6 +427,16 @@ func (b *blockEnc) encodeLits(lits []byte, raw bool) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// encodeRLE will encode an RLE block.
|
||||
func (b *blockEnc) encodeRLE(val byte, length uint32) {
|
||||
var bh blockHeader
|
||||
bh.setLast(b.last)
|
||||
bh.setSize(length)
|
||||
bh.setType(blockTypeRLE)
|
||||
b.output = bh.appendTo(b.output)
|
||||
b.output = append(b.output, val)
|
||||
}
|
||||
|
||||
// fuzzFseEncoder can be used to fuzz the FSE encoder.
|
||||
func fuzzFseEncoder(data []byte) int {
|
||||
if len(data) > maxSequences || len(data) < 2 {
|
||||
|
@ -479,6 +489,16 @@ func (b *blockEnc) encode(org []byte, raw, rawAllLits bool) error {
|
|||
if len(b.sequences) == 0 {
|
||||
return b.encodeLits(b.literals, rawAllLits)
|
||||
}
|
||||
if len(b.sequences) == 1 && len(org) > 0 && len(b.literals) <= 1 {
|
||||
// Check common RLE cases.
|
||||
seq := b.sequences[0]
|
||||
if seq.litLen == uint32(len(b.literals)) && seq.offset-3 == 1 {
|
||||
// Offset == 1 and 0 or 1 literals.
|
||||
b.encodeRLE(org[0], b.sequences[0].matchLen+zstdMinMatch+seq.litLen)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// We want some difference to at least account for the headers.
|
||||
saved := b.size - len(b.literals) - (b.size >> 6)
|
||||
if saved < 16 {
|
||||
|
|
|
@ -95,42 +95,54 @@ type Header struct {
|
|||
// If there isn't enough input, io.ErrUnexpectedEOF is returned.
|
||||
// The FirstBlock.OK will indicate if enough information was available to decode the first block header.
|
||||
func (h *Header) Decode(in []byte) error {
|
||||
_, err := h.DecodeAndStrip(in)
|
||||
return err
|
||||
}
|
||||
|
||||
// DecodeAndStrip will decode the header from the beginning of the stream
|
||||
// and on success return the remaining bytes.
|
||||
// This will decode the frame header and the first block header if enough bytes are provided.
|
||||
// It is recommended to provide at least HeaderMaxSize bytes.
|
||||
// If the frame header cannot be read an error will be returned.
|
||||
// If there isn't enough input, io.ErrUnexpectedEOF is returned.
|
||||
// The FirstBlock.OK will indicate if enough information was available to decode the first block header.
|
||||
func (h *Header) DecodeAndStrip(in []byte) (remain []byte, err error) {
|
||||
*h = Header{}
|
||||
if len(in) < 4 {
|
||||
return io.ErrUnexpectedEOF
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
h.HeaderSize += 4
|
||||
b, in := in[:4], in[4:]
|
||||
if string(b) != frameMagic {
|
||||
if string(b[1:4]) != skippableFrameMagic || b[0]&0xf0 != 0x50 {
|
||||
return ErrMagicMismatch
|
||||
return nil, ErrMagicMismatch
|
||||
}
|
||||
if len(in) < 4 {
|
||||
return io.ErrUnexpectedEOF
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
h.HeaderSize += 4
|
||||
h.Skippable = true
|
||||
h.SkippableID = int(b[0] & 0xf)
|
||||
h.SkippableSize = binary.LittleEndian.Uint32(in)
|
||||
return nil
|
||||
return in[4:], nil
|
||||
}
|
||||
|
||||
// Read Window_Descriptor
|
||||
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#window_descriptor
|
||||
if len(in) < 1 {
|
||||
return io.ErrUnexpectedEOF
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
fhd, in := in[0], in[1:]
|
||||
h.HeaderSize++
|
||||
h.SingleSegment = fhd&(1<<5) != 0
|
||||
h.HasCheckSum = fhd&(1<<2) != 0
|
||||
if fhd&(1<<3) != 0 {
|
||||
return errors.New("reserved bit set on frame header")
|
||||
return nil, errors.New("reserved bit set on frame header")
|
||||
}
|
||||
|
||||
if !h.SingleSegment {
|
||||
if len(in) < 1 {
|
||||
return io.ErrUnexpectedEOF
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
var wd byte
|
||||
wd, in = in[0], in[1:]
|
||||
|
@ -148,7 +160,7 @@ func (h *Header) Decode(in []byte) error {
|
|||
size = 4
|
||||
}
|
||||
if len(in) < int(size) {
|
||||
return io.ErrUnexpectedEOF
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b, in = in[:size], in[size:]
|
||||
h.HeaderSize += int(size)
|
||||
|
@ -178,7 +190,7 @@ func (h *Header) Decode(in []byte) error {
|
|||
if fcsSize > 0 {
|
||||
h.HasFCS = true
|
||||
if len(in) < fcsSize {
|
||||
return io.ErrUnexpectedEOF
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
b, in = in[:fcsSize], in[fcsSize:]
|
||||
h.HeaderSize += int(fcsSize)
|
||||
|
@ -199,7 +211,7 @@ func (h *Header) Decode(in []byte) error {
|
|||
|
||||
// Frame Header done, we will not fail from now on.
|
||||
if len(in) < 3 {
|
||||
return nil
|
||||
return in, nil
|
||||
}
|
||||
tmp := in[:3]
|
||||
bh := uint32(tmp[0]) | (uint32(tmp[1]) << 8) | (uint32(tmp[2]) << 16)
|
||||
|
@ -209,7 +221,7 @@ func (h *Header) Decode(in []byte) error {
|
|||
cSize := int(bh >> 3)
|
||||
switch blockType {
|
||||
case blockTypeReserved:
|
||||
return nil
|
||||
return in, nil
|
||||
case blockTypeRLE:
|
||||
h.FirstBlock.Compressed = true
|
||||
h.FirstBlock.DecompressedSize = cSize
|
||||
|
@ -225,5 +237,25 @@ func (h *Header) Decode(in []byte) error {
|
|||
}
|
||||
|
||||
h.FirstBlock.OK = true
|
||||
return nil
|
||||
return in, nil
|
||||
}
|
||||
|
||||
// AppendTo will append the encoded header to the dst slice.
|
||||
// There is no error checking performed on the header values.
|
||||
func (h *Header) AppendTo(dst []byte) ([]byte, error) {
|
||||
if h.Skippable {
|
||||
magic := [4]byte{0x50, 0x2a, 0x4d, 0x18}
|
||||
magic[0] |= byte(h.SkippableID & 0xf)
|
||||
dst = append(dst, magic[:]...)
|
||||
f := h.SkippableSize
|
||||
return append(dst, uint8(f), uint8(f>>8), uint8(f>>16), uint8(f>>24)), nil
|
||||
}
|
||||
f := frameHeader{
|
||||
ContentSize: h.FrameContentSize,
|
||||
WindowSize: uint32(h.WindowSize),
|
||||
SingleSegment: h.SingleSegment,
|
||||
Checksum: h.HasCheckSum,
|
||||
DictID: h.DictionaryID,
|
||||
}
|
||||
return f.appendTo(dst), nil
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ var (
|
|||
// can run multiple concurrent stateless decodes. It is even possible to
|
||||
// use stateless decodes while a stream is being decoded.
|
||||
//
|
||||
// The Reset function can be used to initiate a new stream, which is will considerably
|
||||
// The Reset function can be used to initiate a new stream, which will considerably
|
||||
// reduce the allocations normally caused by NewReader.
|
||||
func NewReader(r io.Reader, opts ...DOption) (*Decoder, error) {
|
||||
initPredefined()
|
||||
|
|
|
@ -43,7 +43,7 @@ func (m *match) estBits(bitsPerByte int32) {
|
|||
if m.rep < 0 {
|
||||
ofc = ofCode(uint32(m.s-m.offset) + 3)
|
||||
} else {
|
||||
ofc = ofCode(uint32(m.rep))
|
||||
ofc = ofCode(uint32(m.rep) & 3)
|
||||
}
|
||||
// Cost, excluding
|
||||
ofTT, mlTT := fsePredefEnc[tableOffsets].ct.symbolTT[ofc], fsePredefEnc[tableMatchLengths].ct.symbolTT[mlc]
|
||||
|
@ -135,8 +135,20 @@ func (e *bestFastEncoder) Encode(blk *blockEnc, src []byte) {
|
|||
break
|
||||
}
|
||||
|
||||
// Add block to history
|
||||
s := e.addBlock(src)
|
||||
blk.size = len(src)
|
||||
|
||||
// Check RLE first
|
||||
if len(src) > zstdMinMatch {
|
||||
ml := matchLen(src[1:], src)
|
||||
if ml == len(src)-1 {
|
||||
blk.literals = append(blk.literals, src[0])
|
||||
blk.sequences = append(blk.sequences, seq{litLen: 1, matchLen: uint32(len(src)-1) - zstdMinMatch, offset: 1 + 3})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(src) < minNonLiteralBlockSize {
|
||||
blk.extraLits = len(src)
|
||||
blk.literals = blk.literals[:len(src)]
|
||||
|
@ -201,14 +213,6 @@ encodeLoop:
|
|||
if delta >= e.maxMatchOff || delta <= 0 || load3232(src, offset) != first {
|
||||
return
|
||||
}
|
||||
if debugAsserts {
|
||||
if offset >= s {
|
||||
panic(fmt.Sprintf("offset: %d - s:%d - rep: %d - cur :%d - max: %d", offset, s, rep, e.cur, e.maxMatchOff))
|
||||
}
|
||||
if !bytes.Equal(src[s:s+4], src[offset:offset+4]) {
|
||||
panic(fmt.Sprintf("first match mismatch: %v != %v, first: %08x", src[s:s+4], src[offset:offset+4], first))
|
||||
}
|
||||
}
|
||||
// Try to quick reject if we already have a long match.
|
||||
if m.length > 16 {
|
||||
left := len(src) - int(m.s+m.length)
|
||||
|
@ -227,8 +231,10 @@ encodeLoop:
|
|||
}
|
||||
}
|
||||
l := 4 + e.matchlen(s+4, offset+4, src)
|
||||
if rep < 0 {
|
||||
if m.rep <= 0 {
|
||||
// Extend candidate match backwards as far as possible.
|
||||
// Do not extend repeats as we can assume they are optimal
|
||||
// and offsets change if s == nextEmit.
|
||||
tMin := s - e.maxMatchOff
|
||||
if tMin < 0 {
|
||||
tMin = 0
|
||||
|
@ -239,7 +245,14 @@ encodeLoop:
|
|||
l++
|
||||
}
|
||||
}
|
||||
|
||||
if debugAsserts {
|
||||
if offset >= s {
|
||||
panic(fmt.Sprintf("offset: %d - s:%d - rep: %d - cur :%d - max: %d", offset, s, rep, e.cur, e.maxMatchOff))
|
||||
}
|
||||
if !bytes.Equal(src[s:s+l], src[offset:offset+l]) {
|
||||
panic(fmt.Sprintf("second match mismatch: %v != %v, first: %08x", src[s:s+4], src[offset:offset+4], first))
|
||||
}
|
||||
}
|
||||
cand := match{offset: offset, s: s, length: l, rep: rep}
|
||||
cand.estBits(bitsPerByte)
|
||||
if m.est >= highScore || cand.est-m.est+(cand.s-m.s)*bitsPerByte>>10 < 0 {
|
||||
|
@ -282,6 +295,7 @@ encodeLoop:
|
|||
// Load next and check...
|
||||
e.longTable[nextHashL] = prevEntry{offset: s + e.cur, prev: candidateL.offset}
|
||||
e.table[nextHashS] = prevEntry{offset: s + e.cur, prev: candidateS.offset}
|
||||
index0 := s + 1
|
||||
|
||||
// Look far ahead, unless we have a really long match already...
|
||||
if best.length < goodEnough {
|
||||
|
@ -335,41 +349,45 @@ encodeLoop:
|
|||
}
|
||||
|
||||
if debugAsserts {
|
||||
if best.offset >= best.s {
|
||||
panic(fmt.Sprintf("best.offset > s: %d >= %d", best.offset, best.s))
|
||||
}
|
||||
if best.s < nextEmit {
|
||||
panic(fmt.Sprintf("s %d < nextEmit %d", best.s, nextEmit))
|
||||
}
|
||||
if best.offset < s-e.maxMatchOff {
|
||||
panic(fmt.Sprintf("best.offset < s-e.maxMatchOff: %d < %d", best.offset, s-e.maxMatchOff))
|
||||
}
|
||||
if !bytes.Equal(src[best.s:best.s+best.length], src[best.offset:best.offset+best.length]) {
|
||||
panic(fmt.Sprintf("match mismatch: %v != %v", src[best.s:best.s+best.length], src[best.offset:best.offset+best.length]))
|
||||
}
|
||||
}
|
||||
|
||||
// We have a match, we can store the forward value
|
||||
s = best.s
|
||||
if best.rep > 0 {
|
||||
var seq seq
|
||||
seq.matchLen = uint32(best.length - zstdMinMatch)
|
||||
if debugAsserts && s < nextEmit {
|
||||
panic("s < nextEmit")
|
||||
}
|
||||
addLiterals(&seq, best.s)
|
||||
|
||||
// Repeat. If bit 4 is set, this is a non-lit repeat.
|
||||
seq.offset = uint32(best.rep & 3)
|
||||
if debugSequences {
|
||||
println("repeat sequence", seq, "next s:", s)
|
||||
println("repeat sequence", seq, "next s:", best.s, "off:", best.s-best.offset)
|
||||
}
|
||||
blk.sequences = append(blk.sequences, seq)
|
||||
|
||||
// Index old s + 1 -> s - 1
|
||||
index0 := s + 1
|
||||
s = best.s + best.length
|
||||
|
||||
nextEmit = s
|
||||
if s >= sLimit {
|
||||
if debugEncoder {
|
||||
println("repeat ended", s, best.length)
|
||||
}
|
||||
break encodeLoop
|
||||
}
|
||||
|
||||
// Index skipped...
|
||||
end := s
|
||||
if s > sLimit+4 {
|
||||
end = sLimit + 4
|
||||
}
|
||||
off := index0 + e.cur
|
||||
for index0 < s {
|
||||
for index0 < end {
|
||||
cv0 := load6432(src, index0)
|
||||
h0 := hashLen(cv0, bestLongTableBits, bestLongLen)
|
||||
h1 := hashLen(cv0, bestShortTableBits, bestShortLen)
|
||||
|
@ -378,6 +396,7 @@ encodeLoop:
|
|||
off++
|
||||
index0++
|
||||
}
|
||||
|
||||
switch best.rep {
|
||||
case 2, 4 | 1:
|
||||
offset1, offset2 = offset2, offset1
|
||||
|
@ -386,13 +405,17 @@ encodeLoop:
|
|||
case 4 | 3:
|
||||
offset1, offset2, offset3 = offset1-1, offset1, offset2
|
||||
}
|
||||
if s >= sLimit {
|
||||
if debugEncoder {
|
||||
println("repeat ended", s, best.length)
|
||||
}
|
||||
break encodeLoop
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// A 4-byte match has been found. Update recent offsets.
|
||||
// We'll later see if more than 4 bytes.
|
||||
index0 := s + 1
|
||||
s = best.s
|
||||
t := best.offset
|
||||
offset1, offset2, offset3 = s-t, offset1, offset2
|
||||
|
||||
|
@ -419,19 +442,25 @@ encodeLoop:
|
|||
}
|
||||
blk.sequences = append(blk.sequences, seq)
|
||||
nextEmit = s
|
||||
if s >= sLimit {
|
||||
break encodeLoop
|
||||
|
||||
// Index old s + 1 -> s - 1 or sLimit
|
||||
end := s
|
||||
if s > sLimit-4 {
|
||||
end = sLimit - 4
|
||||
}
|
||||
|
||||
// Index old s + 1 -> s - 1
|
||||
for index0 < s {
|
||||
off := index0 + e.cur
|
||||
for index0 < end {
|
||||
cv0 := load6432(src, index0)
|
||||
h0 := hashLen(cv0, bestLongTableBits, bestLongLen)
|
||||
h1 := hashLen(cv0, bestShortTableBits, bestShortLen)
|
||||
off := index0 + e.cur
|
||||
e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
|
||||
e.table[h1] = prevEntry{offset: off, prev: e.table[h1].offset}
|
||||
index0++
|
||||
off++
|
||||
}
|
||||
if s >= sLimit {
|
||||
break encodeLoop
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -102,9 +102,20 @@ func (e *betterFastEncoder) Encode(blk *blockEnc, src []byte) {
|
|||
e.cur = e.maxMatchOff
|
||||
break
|
||||
}
|
||||
|
||||
// Add block to history
|
||||
s := e.addBlock(src)
|
||||
blk.size = len(src)
|
||||
|
||||
// Check RLE first
|
||||
if len(src) > zstdMinMatch {
|
||||
ml := matchLen(src[1:], src)
|
||||
if ml == len(src)-1 {
|
||||
blk.literals = append(blk.literals, src[0])
|
||||
blk.sequences = append(blk.sequences, seq{litLen: 1, matchLen: uint32(len(src)-1) - zstdMinMatch, offset: 1 + 3})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(src) < minNonLiteralBlockSize {
|
||||
blk.extraLits = len(src)
|
||||
blk.literals = blk.literals[:len(src)]
|
||||
|
@ -145,7 +156,7 @@ encodeLoop:
|
|||
var t int32
|
||||
// We allow the encoder to optionally turn off repeat offsets across blocks
|
||||
canRepeat := len(blk.sequences) > 2
|
||||
var matched int32
|
||||
var matched, index0 int32
|
||||
|
||||
for {
|
||||
if debugAsserts && canRepeat && offset1 == 0 {
|
||||
|
@ -162,6 +173,7 @@ encodeLoop:
|
|||
off := s + e.cur
|
||||
e.longTable[nextHashL] = prevEntry{offset: off, prev: candidateL.offset}
|
||||
e.table[nextHashS] = tableEntry{offset: off, val: uint32(cv)}
|
||||
index0 = s + 1
|
||||
|
||||
if canRepeat {
|
||||
if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
|
||||
|
@ -258,7 +270,6 @@ encodeLoop:
|
|||
}
|
||||
blk.sequences = append(blk.sequences, seq)
|
||||
|
||||
index0 := s + repOff2
|
||||
s += lenght + repOff2
|
||||
nextEmit = s
|
||||
if s >= sLimit {
|
||||
|
@ -498,15 +509,15 @@ encodeLoop:
|
|||
}
|
||||
|
||||
// Index match start+1 (long) -> s - 1
|
||||
index0 := s - l + 1
|
||||
off := index0 + e.cur
|
||||
for index0 < s-1 {
|
||||
cv0 := load6432(src, index0)
|
||||
cv1 := cv0 >> 8
|
||||
h0 := hashLen(cv0, betterLongTableBits, betterLongLen)
|
||||
off := index0 + e.cur
|
||||
e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
|
||||
e.table[hashLen(cv1, betterShortTableBits, betterShortLen)] = tableEntry{offset: off + 1, val: uint32(cv1)}
|
||||
index0 += 2
|
||||
off += 2
|
||||
}
|
||||
|
||||
cv = load6432(src, s)
|
||||
|
@ -672,7 +683,7 @@ encodeLoop:
|
|||
var t int32
|
||||
// We allow the encoder to optionally turn off repeat offsets across blocks
|
||||
canRepeat := len(blk.sequences) > 2
|
||||
var matched int32
|
||||
var matched, index0 int32
|
||||
|
||||
for {
|
||||
if debugAsserts && canRepeat && offset1 == 0 {
|
||||
|
@ -691,6 +702,7 @@ encodeLoop:
|
|||
e.markLongShardDirty(nextHashL)
|
||||
e.table[nextHashS] = tableEntry{offset: off, val: uint32(cv)}
|
||||
e.markShortShardDirty(nextHashS)
|
||||
index0 = s + 1
|
||||
|
||||
if canRepeat {
|
||||
if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
|
||||
|
@ -726,7 +738,6 @@ encodeLoop:
|
|||
blk.sequences = append(blk.sequences, seq)
|
||||
|
||||
// Index match start+1 (long) -> s - 1
|
||||
index0 := s + repOff
|
||||
s += lenght + repOff
|
||||
|
||||
nextEmit = s
|
||||
|
@ -790,7 +801,6 @@ encodeLoop:
|
|||
}
|
||||
blk.sequences = append(blk.sequences, seq)
|
||||
|
||||
index0 := s + repOff2
|
||||
s += lenght + repOff2
|
||||
nextEmit = s
|
||||
if s >= sLimit {
|
||||
|
@ -1024,18 +1034,18 @@ encodeLoop:
|
|||
}
|
||||
|
||||
// Index match start+1 (long) -> s - 1
|
||||
index0 := s - l + 1
|
||||
off := index0 + e.cur
|
||||
for index0 < s-1 {
|
||||
cv0 := load6432(src, index0)
|
||||
cv1 := cv0 >> 8
|
||||
h0 := hashLen(cv0, betterLongTableBits, betterLongLen)
|
||||
off := index0 + e.cur
|
||||
e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
|
||||
e.markLongShardDirty(h0)
|
||||
h1 := hashLen(cv1, betterShortTableBits, betterShortLen)
|
||||
e.table[h1] = tableEntry{offset: off + 1, val: uint32(cv1)}
|
||||
e.markShortShardDirty(h1)
|
||||
index0 += 2
|
||||
off += 2
|
||||
}
|
||||
|
||||
cv = load6432(src, s)
|
||||
|
|
|
@ -94,7 +94,7 @@ func WithEncoderConcurrency(n int) EOption {
|
|||
// The value must be a power of two between MinWindowSize and MaxWindowSize.
|
||||
// A larger value will enable better compression but allocate more memory and,
|
||||
// for above-default values, take considerably longer.
|
||||
// The default value is determined by the compression level.
|
||||
// The default value is determined by the compression level and max 8MB.
|
||||
func WithWindowSize(n int) EOption {
|
||||
return func(o *encoderOptions) error {
|
||||
switch {
|
||||
|
@ -232,9 +232,9 @@ func WithEncoderLevel(l EncoderLevel) EOption {
|
|||
case SpeedDefault:
|
||||
o.windowSize = 8 << 20
|
||||
case SpeedBetterCompression:
|
||||
o.windowSize = 16 << 20
|
||||
o.windowSize = 8 << 20
|
||||
case SpeedBestCompression:
|
||||
o.windowSize = 32 << 20
|
||||
o.windowSize = 8 << 20
|
||||
}
|
||||
}
|
||||
if !o.customALEntropy {
|
||||
|
|
|
@ -76,7 +76,7 @@ func (f frameHeader) appendTo(dst []byte) []byte {
|
|||
if f.SingleSegment {
|
||||
dst = append(dst, uint8(f.ContentSize))
|
||||
}
|
||||
// Unless SingleSegment is set, framessizes < 256 are nto stored.
|
||||
// Unless SingleSegment is set, framessizes < 256 are not stored.
|
||||
case 1:
|
||||
f.ContentSize -= 256
|
||||
dst = append(dst, uint8(f.ContentSize), uint8(f.ContentSize>>8))
|
||||
|
|
|
@ -20,10 +20,9 @@ func (s *fseDecoder) buildDtable() error {
|
|||
if v == -1 {
|
||||
s.dt[highThreshold].setAddBits(uint8(i))
|
||||
highThreshold--
|
||||
symbolNext[i] = 1
|
||||
} else {
|
||||
symbolNext[i] = uint16(v)
|
||||
v = 1
|
||||
}
|
||||
symbolNext[i] = uint16(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,10 +34,12 @@ func (s *fseDecoder) buildDtable() error {
|
|||
for ss, v := range s.norm[:s.symbolLen] {
|
||||
for i := 0; i < int(v); i++ {
|
||||
s.dt[position].setAddBits(uint8(ss))
|
||||
position = (position + step) & tableMask
|
||||
for position > highThreshold {
|
||||
for {
|
||||
// lowprob area
|
||||
position = (position + step) & tableMask
|
||||
if position <= highThreshold {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,8 +157,7 @@ sequenceDecs_decode_amd64_ll_update_zero:
|
|||
|
||||
// Update Literal Length State
|
||||
MOVBQZX DI, R14
|
||||
SHRQ $0x10, DI
|
||||
MOVWQZX DI, DI
|
||||
SHRL $0x10, DI
|
||||
LEAQ (BX)(R14*1), CX
|
||||
MOVQ DX, R15
|
||||
MOVQ CX, BX
|
||||
|
@ -177,8 +176,7 @@ sequenceDecs_decode_amd64_ll_update_zero:
|
|||
|
||||
// Update Match Length State
|
||||
MOVBQZX R8, R14
|
||||
SHRQ $0x10, R8
|
||||
MOVWQZX R8, R8
|
||||
SHRL $0x10, R8
|
||||
LEAQ (BX)(R14*1), CX
|
||||
MOVQ DX, R15
|
||||
MOVQ CX, BX
|
||||
|
@ -197,8 +195,7 @@ sequenceDecs_decode_amd64_ll_update_zero:
|
|||
|
||||
// Update Offset State
|
||||
MOVBQZX R9, R14
|
||||
SHRQ $0x10, R9
|
||||
MOVWQZX R9, R9
|
||||
SHRL $0x10, R9
|
||||
LEAQ (BX)(R14*1), CX
|
||||
MOVQ DX, R15
|
||||
MOVQ CX, BX
|
||||
|
@ -459,8 +456,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero:
|
|||
|
||||
// Update Literal Length State
|
||||
MOVBQZX DI, R14
|
||||
SHRQ $0x10, DI
|
||||
MOVWQZX DI, DI
|
||||
SHRL $0x10, DI
|
||||
LEAQ (BX)(R14*1), CX
|
||||
MOVQ DX, R15
|
||||
MOVQ CX, BX
|
||||
|
@ -479,8 +475,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero:
|
|||
|
||||
// Update Match Length State
|
||||
MOVBQZX R8, R14
|
||||
SHRQ $0x10, R8
|
||||
MOVWQZX R8, R8
|
||||
SHRL $0x10, R8
|
||||
LEAQ (BX)(R14*1), CX
|
||||
MOVQ DX, R15
|
||||
MOVQ CX, BX
|
||||
|
@ -499,8 +494,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero:
|
|||
|
||||
// Update Offset State
|
||||
MOVBQZX R9, R14
|
||||
SHRQ $0x10, R9
|
||||
MOVWQZX R9, R9
|
||||
SHRL $0x10, R9
|
||||
LEAQ (BX)(R14*1), CX
|
||||
MOVQ DX, R15
|
||||
MOVQ CX, BX
|
||||
|
@ -772,11 +766,10 @@ sequenceDecs_decode_bmi2_fill_2_end:
|
|||
BZHIQ R14, R15, R15
|
||||
|
||||
// Update Offset State
|
||||
BZHIQ R8, R15, CX
|
||||
SHRXQ R8, R15, R15
|
||||
MOVQ $0x00001010, R14
|
||||
BEXTRQ R14, R8, R8
|
||||
ADDQ CX, R8
|
||||
BZHIQ R8, R15, CX
|
||||
SHRXQ R8, R15, R15
|
||||
SHRL $0x10, R8
|
||||
ADDQ CX, R8
|
||||
|
||||
// Load ctx.ofTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
@ -784,11 +777,10 @@ sequenceDecs_decode_bmi2_fill_2_end:
|
|||
MOVQ (CX)(R8*8), R8
|
||||
|
||||
// Update Match Length State
|
||||
BZHIQ DI, R15, CX
|
||||
SHRXQ DI, R15, R15
|
||||
MOVQ $0x00001010, R14
|
||||
BEXTRQ R14, DI, DI
|
||||
ADDQ CX, DI
|
||||
BZHIQ DI, R15, CX
|
||||
SHRXQ DI, R15, R15
|
||||
SHRL $0x10, DI
|
||||
ADDQ CX, DI
|
||||
|
||||
// Load ctx.mlTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
@ -796,10 +788,9 @@ sequenceDecs_decode_bmi2_fill_2_end:
|
|||
MOVQ (CX)(DI*8), DI
|
||||
|
||||
// Update Literal Length State
|
||||
BZHIQ SI, R15, CX
|
||||
MOVQ $0x00001010, R14
|
||||
BEXTRQ R14, SI, SI
|
||||
ADDQ CX, SI
|
||||
BZHIQ SI, R15, CX
|
||||
SHRL $0x10, SI
|
||||
ADDQ CX, SI
|
||||
|
||||
// Load ctx.llTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
@ -1032,11 +1023,10 @@ sequenceDecs_decode_56_bmi2_fill_end:
|
|||
BZHIQ R14, R15, R15
|
||||
|
||||
// Update Offset State
|
||||
BZHIQ R8, R15, CX
|
||||
SHRXQ R8, R15, R15
|
||||
MOVQ $0x00001010, R14
|
||||
BEXTRQ R14, R8, R8
|
||||
ADDQ CX, R8
|
||||
BZHIQ R8, R15, CX
|
||||
SHRXQ R8, R15, R15
|
||||
SHRL $0x10, R8
|
||||
ADDQ CX, R8
|
||||
|
||||
// Load ctx.ofTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
@ -1044,11 +1034,10 @@ sequenceDecs_decode_56_bmi2_fill_end:
|
|||
MOVQ (CX)(R8*8), R8
|
||||
|
||||
// Update Match Length State
|
||||
BZHIQ DI, R15, CX
|
||||
SHRXQ DI, R15, R15
|
||||
MOVQ $0x00001010, R14
|
||||
BEXTRQ R14, DI, DI
|
||||
ADDQ CX, DI
|
||||
BZHIQ DI, R15, CX
|
||||
SHRXQ DI, R15, R15
|
||||
SHRL $0x10, DI
|
||||
ADDQ CX, DI
|
||||
|
||||
// Load ctx.mlTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
@ -1056,10 +1045,9 @@ sequenceDecs_decode_56_bmi2_fill_end:
|
|||
MOVQ (CX)(DI*8), DI
|
||||
|
||||
// Update Literal Length State
|
||||
BZHIQ SI, R15, CX
|
||||
MOVQ $0x00001010, R14
|
||||
BEXTRQ R14, SI, SI
|
||||
ADDQ CX, SI
|
||||
BZHIQ SI, R15, CX
|
||||
SHRL $0x10, SI
|
||||
ADDQ CX, SI
|
||||
|
||||
// Load ctx.llTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
@ -1967,8 +1955,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero:
|
|||
|
||||
// Update Literal Length State
|
||||
MOVBQZX DI, R13
|
||||
SHRQ $0x10, DI
|
||||
MOVWQZX DI, DI
|
||||
SHRL $0x10, DI
|
||||
LEAQ (BX)(R13*1), CX
|
||||
MOVQ DX, R14
|
||||
MOVQ CX, BX
|
||||
|
@ -1987,8 +1974,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero:
|
|||
|
||||
// Update Match Length State
|
||||
MOVBQZX R8, R13
|
||||
SHRQ $0x10, R8
|
||||
MOVWQZX R8, R8
|
||||
SHRL $0x10, R8
|
||||
LEAQ (BX)(R13*1), CX
|
||||
MOVQ DX, R14
|
||||
MOVQ CX, BX
|
||||
|
@ -2007,8 +1993,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero:
|
|||
|
||||
// Update Offset State
|
||||
MOVBQZX R9, R13
|
||||
SHRQ $0x10, R9
|
||||
MOVWQZX R9, R9
|
||||
SHRL $0x10, R9
|
||||
LEAQ (BX)(R13*1), CX
|
||||
MOVQ DX, R14
|
||||
MOVQ CX, BX
|
||||
|
@ -2514,11 +2499,10 @@ sequenceDecs_decodeSync_bmi2_fill_2_end:
|
|||
BZHIQ R13, R14, R14
|
||||
|
||||
// Update Offset State
|
||||
BZHIQ R8, R14, CX
|
||||
SHRXQ R8, R14, R14
|
||||
MOVQ $0x00001010, R13
|
||||
BEXTRQ R13, R8, R8
|
||||
ADDQ CX, R8
|
||||
BZHIQ R8, R14, CX
|
||||
SHRXQ R8, R14, R14
|
||||
SHRL $0x10, R8
|
||||
ADDQ CX, R8
|
||||
|
||||
// Load ctx.ofTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
@ -2526,11 +2510,10 @@ sequenceDecs_decodeSync_bmi2_fill_2_end:
|
|||
MOVQ (CX)(R8*8), R8
|
||||
|
||||
// Update Match Length State
|
||||
BZHIQ DI, R14, CX
|
||||
SHRXQ DI, R14, R14
|
||||
MOVQ $0x00001010, R13
|
||||
BEXTRQ R13, DI, DI
|
||||
ADDQ CX, DI
|
||||
BZHIQ DI, R14, CX
|
||||
SHRXQ DI, R14, R14
|
||||
SHRL $0x10, DI
|
||||
ADDQ CX, DI
|
||||
|
||||
// Load ctx.mlTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
@ -2538,10 +2521,9 @@ sequenceDecs_decodeSync_bmi2_fill_2_end:
|
|||
MOVQ (CX)(DI*8), DI
|
||||
|
||||
// Update Literal Length State
|
||||
BZHIQ SI, R14, CX
|
||||
MOVQ $0x00001010, R13
|
||||
BEXTRQ R13, SI, SI
|
||||
ADDQ CX, SI
|
||||
BZHIQ SI, R14, CX
|
||||
SHRL $0x10, SI
|
||||
ADDQ CX, SI
|
||||
|
||||
// Load ctx.llTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
@ -3055,8 +3037,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero:
|
|||
|
||||
// Update Literal Length State
|
||||
MOVBQZX DI, R13
|
||||
SHRQ $0x10, DI
|
||||
MOVWQZX DI, DI
|
||||
SHRL $0x10, DI
|
||||
LEAQ (BX)(R13*1), CX
|
||||
MOVQ DX, R14
|
||||
MOVQ CX, BX
|
||||
|
@ -3075,8 +3056,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero:
|
|||
|
||||
// Update Match Length State
|
||||
MOVBQZX R8, R13
|
||||
SHRQ $0x10, R8
|
||||
MOVWQZX R8, R8
|
||||
SHRL $0x10, R8
|
||||
LEAQ (BX)(R13*1), CX
|
||||
MOVQ DX, R14
|
||||
MOVQ CX, BX
|
||||
|
@ -3095,8 +3075,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero:
|
|||
|
||||
// Update Offset State
|
||||
MOVBQZX R9, R13
|
||||
SHRQ $0x10, R9
|
||||
MOVWQZX R9, R9
|
||||
SHRL $0x10, R9
|
||||
LEAQ (BX)(R13*1), CX
|
||||
MOVQ DX, R14
|
||||
MOVQ CX, BX
|
||||
|
@ -3704,11 +3683,10 @@ sequenceDecs_decodeSync_safe_bmi2_fill_2_end:
|
|||
BZHIQ R13, R14, R14
|
||||
|
||||
// Update Offset State
|
||||
BZHIQ R8, R14, CX
|
||||
SHRXQ R8, R14, R14
|
||||
MOVQ $0x00001010, R13
|
||||
BEXTRQ R13, R8, R8
|
||||
ADDQ CX, R8
|
||||
BZHIQ R8, R14, CX
|
||||
SHRXQ R8, R14, R14
|
||||
SHRL $0x10, R8
|
||||
ADDQ CX, R8
|
||||
|
||||
// Load ctx.ofTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
@ -3716,11 +3694,10 @@ sequenceDecs_decodeSync_safe_bmi2_fill_2_end:
|
|||
MOVQ (CX)(R8*8), R8
|
||||
|
||||
// Update Match Length State
|
||||
BZHIQ DI, R14, CX
|
||||
SHRXQ DI, R14, R14
|
||||
MOVQ $0x00001010, R13
|
||||
BEXTRQ R13, DI, DI
|
||||
ADDQ CX, DI
|
||||
BZHIQ DI, R14, CX
|
||||
SHRXQ DI, R14, R14
|
||||
SHRL $0x10, DI
|
||||
ADDQ CX, DI
|
||||
|
||||
// Load ctx.mlTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
@ -3728,10 +3705,9 @@ sequenceDecs_decodeSync_safe_bmi2_fill_2_end:
|
|||
MOVQ (CX)(DI*8), DI
|
||||
|
||||
// Update Literal Length State
|
||||
BZHIQ SI, R14, CX
|
||||
MOVQ $0x00001010, R13
|
||||
BEXTRQ R13, SI, SI
|
||||
ADDQ CX, SI
|
||||
BZHIQ SI, R14, CX
|
||||
SHRL $0x10, SI
|
||||
ADDQ CX, SI
|
||||
|
||||
// Load ctx.llTable
|
||||
MOVQ ctx+16(FP), CX
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
vendor
|
|
@ -1,31 +0,0 @@
|
|||
os:
|
||||
- linux
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.14.x
|
||||
- 1.15.x
|
||||
|
||||
env:
|
||||
global:
|
||||
- GOTFLAGS="-race"
|
||||
matrix:
|
||||
- BUILD_DEPTYPE=gomod
|
||||
|
||||
|
||||
# disable travis install
|
||||
install:
|
||||
- true
|
||||
|
||||
script:
|
||||
- bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh)
|
||||
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $GOPATH/pkg/mod
|
||||
- $HOME/.cache/go-build
|
||||
|
||||
notifications:
|
||||
email: false
|
|
@ -1,33 +0,0 @@
|
|||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39"
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
pruneopts = "UT"
|
||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe"
|
||||
name = "github.com/pmezard/go-difflib"
|
||||
packages = ["difflib"]
|
||||
pruneopts = "UT"
|
||||
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f85e109eda8f6080877185d1c39e98dd8795e1780c08beca28304b87fd855a1c"
|
||||
name = "github.com/stretchr/testify"
|
||||
packages = ["assert"]
|
||||
pruneopts = "UT"
|
||||
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
|
||||
version = "v1.2.1"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = ["github.com/stretchr/testify/assert"]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
|
@ -1,34 +0,0 @@
|
|||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/stretchr/testify"
|
||||
version = "1.2.1"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 Yulin
|
||||
|
||||
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.
|
|
@ -1,110 +0,0 @@
|
|||
# cidranger
|
||||
|
||||
Fast IP to CIDR block(s) lookup using trie in Golang, inspired by [IPv4 route lookup linux](https://vincent.bernat.im/en/blog/2017-ipv4-route-lookup-linux). Possible use cases include detecting if a IP address is from published cloud provider CIDR blocks (e.g. 52.95.110.1 is contained in published AWS Route53 CIDR 52.95.110.0/24), IP routing rules, etc.
|
||||
|
||||
Forked from https://github.com/yl2chen/cidranger due to upstream inactivity.
|
||||
|
||||
[![GoDoc Reference](https://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](https://godoc.org/github.com/libp2p/go-cidranger)
|
||||
[![Build Status](https://img.shields.io/travis/libp2p/go-cidranger.svg?branch=master&style=flat-square)](https://travis-ci.org/libp2p/go-cidranger)
|
||||
[![Coverage Status](https://img.shields.io/coveralls/libp2p/go-cidranger.svg?branch=master&style=flat-square)](https://coveralls.io/github/libp2p/go-cidranger?branch=master)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/libp2p/go-cidranger?&style=flat-square)](https://goreportcard.com/report/github.com/libp2p/go-cidranger)
|
||||
|
||||
This is visualization of a trie storing CIDR blocks `128.0.0.0/2` `192.0.0.0/2` `200.0.0.0/5` without path compression, the 0/1 number on the path indicates the bit value of the IP address at specified bit position, hence the path from root node to a child node represents a CIDR block that contains all IP ranges of its children, and children's children.
|
||||
<p align="left"><img src="http://i.imgur.com/vSKTEBb.png" width="600" /></p>
|
||||
|
||||
Visualization of trie storing same CIDR blocks with path compression, improving both lookup speed and memory footprint.
|
||||
<p align="left"><img src="http://i.imgur.com/JtaDlD4.png" width="600" /></p>
|
||||
|
||||
## Getting Started
|
||||
Configure imports.
|
||||
```go
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/libp2p/go-cidranger"
|
||||
)
|
||||
```
|
||||
Create a new ranger implemented using Path-Compressed prefix trie.
|
||||
```go
|
||||
ranger := NewPCTrieRanger()
|
||||
```
|
||||
Inserts CIDR blocks.
|
||||
```go
|
||||
_, network1, _ := net.ParseCIDR("192.168.1.0/24")
|
||||
_, network2, _ := net.ParseCIDR("128.168.1.0/24")
|
||||
ranger.Insert(NewBasicRangerEntry(*network1))
|
||||
ranger.Insert(NewBasicRangerEntry(*network2))
|
||||
```
|
||||
To attach any additional value(s) to the entry, simply create custom struct
|
||||
storing the desired value(s) that implements the RangerEntry interface:
|
||||
```go
|
||||
type RangerEntry interface {
|
||||
Network() net.IPNet
|
||||
}
|
||||
```
|
||||
The prefix trie can be visualized as:
|
||||
```
|
||||
0.0.0.0/0 (target_pos:31:has_entry:false)
|
||||
| 1--> 128.0.0.0/1 (target_pos:30:has_entry:false)
|
||||
| | 0--> 128.168.1.0/24 (target_pos:7:has_entry:true)
|
||||
| | 1--> 192.168.1.0/24 (target_pos:7:has_entry:true)
|
||||
```
|
||||
To test if given IP is contained in constructed ranger,
|
||||
```go
|
||||
contains, err = ranger.Contains(net.ParseIP("128.168.1.0")) // returns true, nil
|
||||
contains, err = ranger.Contains(net.ParseIP("192.168.2.0")) // returns false, nil
|
||||
```
|
||||
To get all the networks given is contained in,
|
||||
```go
|
||||
containingNetworks, err = ranger.ContainingNetworks(net.ParseIP("128.168.1.0"))
|
||||
```
|
||||
To get all networks in ranger,
|
||||
```go
|
||||
entries, err := ranger.CoveredNetworks(*AllIPv4) // for IPv4
|
||||
entries, err := ranger.CoveredNetworks(*AllIPv6) // for IPv6
|
||||
```
|
||||
|
||||
## Benchmark
|
||||
Compare hit/miss case for IPv4/IPv6 using PC trie vs brute force implementation, Ranger is initialized with published AWS ip ranges (889 IPv4 CIDR blocks and 360 IPv6)
|
||||
```go
|
||||
// Ipv4 lookup hit scenario
|
||||
BenchmarkPCTrieHitIPv4UsingAWSRanges-4 5000000 353 ns/op
|
||||
BenchmarkBruteRangerHitIPv4UsingAWSRanges-4 100000 13719 ns/op
|
||||
|
||||
// Ipv6 lookup hit scenario, counter-intuitively faster then IPv4 due to less IPv6 CIDR
|
||||
// blocks in the AWS dataset, hence the constructed trie has less path splits and depth.
|
||||
BenchmarkPCTrieHitIPv6UsingAWSRanges-4 10000000 143 ns/op
|
||||
BenchmarkBruteRangerHitIPv6UsingAWSRanges-4 300000 5178 ns/op
|
||||
|
||||
// Ipv4 lookup miss scenario
|
||||
BenchmarkPCTrieMissIPv4UsingAWSRanges-4 20000000 96.5 ns/op
|
||||
BenchmarkBruteRangerMissIPv4UsingAWSRanges-4 50000 24781 ns/op
|
||||
|
||||
// Ipv6 lookup miss scenario
|
||||
BenchmarkPCTrieHMissIPv6UsingAWSRanges-4 10000000 115 ns/op
|
||||
BenchmarkBruteRangerMissIPv6UsingAWSRanges-4 100000 10824 ns/op
|
||||
```
|
||||
|
||||
## Example of IPv6 trie:
|
||||
```
|
||||
::/0 (target_pos:127:has_entry:false)
|
||||
| 0--> 2400::/14 (target_pos:113:has_entry:false)
|
||||
| | 0--> 2400:6400::/22 (target_pos:105:has_entry:false)
|
||||
| | | 0--> 2400:6500::/32 (target_pos:95:has_entry:false)
|
||||
| | | | 0--> 2400:6500::/39 (target_pos:88:has_entry:false)
|
||||
| | | | | 0--> 2400:6500:0:7000::/53 (target_pos:74:has_entry:false)
|
||||
| | | | | | 0--> 2400:6500:0:7000::/54 (target_pos:73:has_entry:false)
|
||||
| | | | | | | 0--> 2400:6500:0:7000::/55 (target_pos:72:has_entry:false)
|
||||
| | | | | | | | 0--> 2400:6500:0:7000::/56 (target_pos:71:has_entry:true)
|
||||
| | | | | | | | 1--> 2400:6500:0:7100::/56 (target_pos:71:has_entry:true)
|
||||
| | | | | | | 1--> 2400:6500:0:7200::/56 (target_pos:71:has_entry:true)
|
||||
| | | | | | 1--> 2400:6500:0:7400::/55 (target_pos:72:has_entry:false)
|
||||
| | | | | | | 0--> 2400:6500:0:7400::/56 (target_pos:71:has_entry:true)
|
||||
| | | | | | | 1--> 2400:6500:0:7500::/56 (target_pos:71:has_entry:true)
|
||||
| | | | | 1--> 2400:6500:100:7000::/54 (target_pos:73:has_entry:false)
|
||||
| | | | | | 0--> 2400:6500:100:7100::/56 (target_pos:71:has_entry:true)
|
||||
| | | | | | 1--> 2400:6500:100:7200::/56 (target_pos:71:has_entry:true)
|
||||
| | | | 1--> 2400:6500:ff00::/64 (target_pos:63:has_entry:true)
|
||||
| | | 1--> 2400:6700:ff00::/64 (target_pos:63:has_entry:true)
|
||||
| | 1--> 2403:b300:ff00::/64 (target_pos:63:has_entry:true)
|
||||
```
|
|
@ -1,124 +0,0 @@
|
|||
package cidranger
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
rnet "github.com/libp2p/go-cidranger/net"
|
||||
)
|
||||
|
||||
// bruteRanger is a brute force implementation of Ranger. Insertion and
|
||||
// deletion of networks is performed on an internal storage in the form of
|
||||
// map[string]net.IPNet (constant time operations). However, inclusion tests are
|
||||
// always performed linearly at no guaranteed traversal order of recorded networks,
|
||||
// so one can assume a worst case performance of O(N). The performance can be
|
||||
// boosted many ways, e.g. changing usage of net.IPNet.Contains() to using masked
|
||||
// bits equality checking, but the main purpose of this implementation is for
|
||||
// testing because the correctness of this implementation can be easily guaranteed,
|
||||
// and used as the ground truth when running a wider range of 'random' tests on
|
||||
// other more sophisticated implementations.
|
||||
type bruteRanger struct {
|
||||
ipV4Entries map[string]RangerEntry
|
||||
ipV6Entries map[string]RangerEntry
|
||||
}
|
||||
|
||||
// newBruteRanger returns a new Ranger.
|
||||
func newBruteRanger() Ranger {
|
||||
return &bruteRanger{
|
||||
ipV4Entries: make(map[string]RangerEntry),
|
||||
ipV6Entries: make(map[string]RangerEntry),
|
||||
}
|
||||
}
|
||||
|
||||
// Insert inserts a RangerEntry into ranger.
|
||||
func (b *bruteRanger) Insert(entry RangerEntry) error {
|
||||
network := entry.Network()
|
||||
key := network.String()
|
||||
if _, found := b.ipV4Entries[key]; !found {
|
||||
entries, err := b.getEntriesByVersion(entry.Network().IP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
entries[key] = entry
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove removes a RangerEntry identified by given network from ranger.
|
||||
func (b *bruteRanger) Remove(network net.IPNet) (RangerEntry, error) {
|
||||
networks, err := b.getEntriesByVersion(network.IP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key := network.String()
|
||||
if networkToDelete, found := networks[key]; found {
|
||||
delete(networks, key)
|
||||
return networkToDelete, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Contains returns bool indicating whether given ip is contained by any
|
||||
// network in ranger.
|
||||
func (b *bruteRanger) Contains(ip net.IP) (bool, error) {
|
||||
entries, err := b.getEntriesByVersion(ip)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, entry := range entries {
|
||||
network := entry.Network()
|
||||
if network.Contains(ip) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// ContainingNetworks returns all RangerEntry(s) that given ip contained in.
|
||||
func (b *bruteRanger) ContainingNetworks(ip net.IP) ([]RangerEntry, error) {
|
||||
entries, err := b.getEntriesByVersion(ip)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results := []RangerEntry{}
|
||||
for _, entry := range entries {
|
||||
network := entry.Network()
|
||||
if network.Contains(ip) {
|
||||
results = append(results, entry)
|
||||
}
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// CoveredNetworks returns the list of RangerEntry(s) the given ipnet
|
||||
// covers. That is, the networks that are completely subsumed by the
|
||||
// specified network.
|
||||
func (b *bruteRanger) CoveredNetworks(network net.IPNet) ([]RangerEntry, error) {
|
||||
entries, err := b.getEntriesByVersion(network.IP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var results []RangerEntry
|
||||
testNetwork := rnet.NewNetwork(network)
|
||||
for _, entry := range entries {
|
||||
entryNetwork := rnet.NewNetwork(entry.Network())
|
||||
if testNetwork.Covers(entryNetwork) {
|
||||
results = append(results, entry)
|
||||
}
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// Len returns number of networks in ranger.
|
||||
func (b *bruteRanger) Len() int {
|
||||
return len(b.ipV4Entries) + len(b.ipV6Entries)
|
||||
}
|
||||
|
||||
func (b *bruteRanger) getEntriesByVersion(ip net.IP) (map[string]RangerEntry, error) {
|
||||
if ip.To4() != nil {
|
||||
return b.ipV4Entries, nil
|
||||
}
|
||||
if ip.To16() != nil {
|
||||
return b.ipV6Entries, nil
|
||||
}
|
||||
return nil, ErrInvalidNetworkInput
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
Package cidranger provides utility to store CIDR blocks and perform ip
|
||||
inclusion tests against it.
|
||||
|
||||
To create a new instance of the path-compressed trie:
|
||||
|
||||
ranger := NewPCTrieRanger()
|
||||
|
||||
To insert or remove an entry (any object that satisfies the RangerEntry
|
||||
interface):
|
||||
|
||||
_, network, _ := net.ParseCIDR("192.168.0.0/24")
|
||||
ranger.Insert(NewBasicRangerEntry(*network))
|
||||
ranger.Remove(network)
|
||||
|
||||
If you desire for any value to be attached to the entry, simply
|
||||
create custom struct that satisfies the RangerEntry interface:
|
||||
|
||||
type RangerEntry interface {
|
||||
Network() net.IPNet
|
||||
}
|
||||
|
||||
To test whether an IP is contained in the constructed networks ranger:
|
||||
|
||||
// returns bool, error
|
||||
containsBool, err := ranger.Contains(net.ParseIP("192.168.0.1"))
|
||||
|
||||
To get a list of CIDR blocks in constructed ranger that contains IP:
|
||||
|
||||
// returns []RangerEntry, error
|
||||
entries, err := ranger.ContainingNetworks(net.ParseIP("192.168.0.1"))
|
||||
|
||||
To get a list of all IPv4/IPv6 rangers respectively:
|
||||
|
||||
// returns []RangerEntry, error
|
||||
entries, err := ranger.CoveredNetworks(*AllIPv4)
|
||||
entries, err := ranger.CoveredNetworks(*AllIPv6)
|
||||
|
||||
*/
|
||||
package cidranger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
// ErrInvalidNetworkInput is returned upon invalid network input.
|
||||
var ErrInvalidNetworkInput = fmt.Errorf("Invalid network input")
|
||||
|
||||
// ErrInvalidNetworkNumberInput is returned upon invalid network input.
|
||||
var ErrInvalidNetworkNumberInput = fmt.Errorf("Invalid network number input")
|
||||
|
||||
// AllIPv4 is a IPv4 CIDR that contains all networks
|
||||
var AllIPv4 = parseCIDRUnsafe("0.0.0.0/0")
|
||||
|
||||
// AllIPv6 is a IPv6 CIDR that contains all networks
|
||||
var AllIPv6 = parseCIDRUnsafe("0::0/0")
|
||||
|
||||
func parseCIDRUnsafe(s string) *net.IPNet {
|
||||
_, cidr, _ := net.ParseCIDR(s)
|
||||
return cidr
|
||||
}
|
||||
|
||||
// RangerEntry is an interface for insertable entry into a Ranger.
|
||||
type RangerEntry interface {
|
||||
Network() net.IPNet
|
||||
}
|
||||
|
||||
type basicRangerEntry struct {
|
||||
ipNet net.IPNet
|
||||
}
|
||||
|
||||
func (b *basicRangerEntry) Network() net.IPNet {
|
||||
return b.ipNet
|
||||
}
|
||||
|
||||
// NewBasicRangerEntry returns a basic RangerEntry that only stores the network
|
||||
// itself.
|
||||
func NewBasicRangerEntry(ipNet net.IPNet) RangerEntry {
|
||||
return &basicRangerEntry{
|
||||
ipNet: ipNet,
|
||||
}
|
||||
}
|
||||
|
||||
// Ranger is an interface for cidr block containment lookups.
|
||||
type Ranger interface {
|
||||
Insert(entry RangerEntry) error
|
||||
Remove(network net.IPNet) (RangerEntry, error)
|
||||
Contains(ip net.IP) (bool, error)
|
||||
ContainingNetworks(ip net.IP) ([]RangerEntry, error)
|
||||
CoveredNetworks(network net.IPNet) ([]RangerEntry, error)
|
||||
Len() int
|
||||
}
|
||||
|
||||
// NewPCTrieRanger returns a versionedRanger that supports both IPv4 and IPv6
|
||||
// using the path compressed trie implemention.
|
||||
func NewPCTrieRanger() Ranger {
|
||||
return newVersionedRanger(newRanger)
|
||||
}
|
|
@ -1,300 +0,0 @@
|
|||
/*
|
||||
Package net provides utility functions for working with IPs (net.IP).
|
||||
*/
|
||||
package net
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
)
|
||||
|
||||
// IPVersion is version of IP address.
|
||||
type IPVersion string
|
||||
|
||||
// Helper constants.
|
||||
const (
|
||||
IPv4Uint32Count = 1
|
||||
IPv6Uint32Count = 4
|
||||
|
||||
BitsPerUint32 = 32
|
||||
BytePerUint32 = 4
|
||||
|
||||
IPv4 IPVersion = "IPv4"
|
||||
IPv6 IPVersion = "IPv6"
|
||||
)
|
||||
|
||||
// ErrInvalidBitPosition is returned when bits requested is not valid.
|
||||
var ErrInvalidBitPosition = fmt.Errorf("bit position not valid")
|
||||
|
||||
// ErrVersionMismatch is returned upon mismatch in network input versions.
|
||||
var ErrVersionMismatch = fmt.Errorf("Network input version mismatch")
|
||||
|
||||
// ErrNoGreatestCommonBit is an error returned when no greatest common bit
|
||||
// exists for the cidr ranges.
|
||||
var ErrNoGreatestCommonBit = fmt.Errorf("No greatest common bit")
|
||||
|
||||
// NetworkNumber represents an IP address using uint32 as internal storage.
|
||||
// IPv4 usings 1 uint32, while IPv6 uses 4 uint32.
|
||||
type NetworkNumber []uint32
|
||||
|
||||
// NewNetworkNumber returns a equivalent NetworkNumber to given IP address,
|
||||
// return nil if ip is neither IPv4 nor IPv6.
|
||||
func NewNetworkNumber(ip net.IP) NetworkNumber {
|
||||
if ip == nil {
|
||||
return nil
|
||||
}
|
||||
coercedIP := ip.To4()
|
||||
parts := 1
|
||||
if coercedIP == nil {
|
||||
coercedIP = ip.To16()
|
||||
parts = 4
|
||||
}
|
||||
if coercedIP == nil {
|
||||
return nil
|
||||
}
|
||||
nn := make(NetworkNumber, parts)
|
||||
for i := 0; i < parts; i++ {
|
||||
idx := i * net.IPv4len
|
||||
nn[i] = binary.BigEndian.Uint32(coercedIP[idx : idx+net.IPv4len])
|
||||
}
|
||||
return nn
|
||||
}
|
||||
|
||||
// ToV4 returns ip address if ip is IPv4, returns nil otherwise.
|
||||
func (n NetworkNumber) ToV4() NetworkNumber {
|
||||
if len(n) != IPv4Uint32Count {
|
||||
return nil
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// ToV6 returns ip address if ip is IPv6, returns nil otherwise.
|
||||
func (n NetworkNumber) ToV6() NetworkNumber {
|
||||
if len(n) != IPv6Uint32Count {
|
||||
return nil
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// ToIP returns equivalent net.IP.
|
||||
func (n NetworkNumber) ToIP() net.IP {
|
||||
ip := make(net.IP, len(n)*BytePerUint32)
|
||||
for i := 0; i < len(n); i++ {
|
||||
idx := i * net.IPv4len
|
||||
binary.BigEndian.PutUint32(ip[idx:idx+net.IPv4len], n[i])
|
||||
}
|
||||
if len(ip) == net.IPv4len {
|
||||
ip = net.IPv4(ip[0], ip[1], ip[2], ip[3])
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
||||
// Equal is the equality test for 2 network numbers.
|
||||
func (n NetworkNumber) Equal(n1 NetworkNumber) bool {
|
||||
if len(n) != len(n1) {
|
||||
return false
|
||||
}
|
||||
if n[0] != n1[0] {
|
||||
return false
|
||||
}
|
||||
if len(n) == IPv6Uint32Count {
|
||||
return n[1] == n1[1] && n[2] == n1[2] && n[3] == n1[3]
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Next returns the next logical network number.
|
||||
func (n NetworkNumber) Next() NetworkNumber {
|
||||
newIP := make(NetworkNumber, len(n))
|
||||
copy(newIP, n)
|
||||
for i := len(newIP) - 1; i >= 0; i-- {
|
||||
newIP[i]++
|
||||
if newIP[i] > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return newIP
|
||||
}
|
||||
|
||||
// Previous returns the previous logical network number.
|
||||
func (n NetworkNumber) Previous() NetworkNumber {
|
||||
newIP := make(NetworkNumber, len(n))
|
||||
copy(newIP, n)
|
||||
for i := len(newIP) - 1; i >= 0; i-- {
|
||||
newIP[i]--
|
||||
if newIP[i] < math.MaxUint32 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return newIP
|
||||
}
|
||||
|
||||
// Bit returns uint32 representing the bit value at given position, e.g.,
|
||||
// "128.0.0.0" has bit value of 1 at position 31, and 0 for positions 30 to 0.
|
||||
func (n NetworkNumber) Bit(position uint) (uint32, error) {
|
||||
if int(position) > len(n)*BitsPerUint32-1 {
|
||||
return 0, ErrInvalidBitPosition
|
||||
}
|
||||
idx := len(n) - 1 - int(position/BitsPerUint32)
|
||||
// Mod 31 to get array index.
|
||||
rShift := position & (BitsPerUint32 - 1)
|
||||
return (n[idx] >> rShift) & 1, nil
|
||||
}
|
||||
|
||||
// LeastCommonBitPosition returns the smallest position of the preceding common
|
||||
// bits of the 2 network numbers, and returns an error ErrNoGreatestCommonBit
|
||||
// if the two network number diverges from the first bit.
|
||||
// e.g., if the network number diverges after the 1st bit, it returns 131 for
|
||||
// IPv6 and 31 for IPv4 .
|
||||
func (n NetworkNumber) LeastCommonBitPosition(n1 NetworkNumber) (uint, error) {
|
||||
if len(n) != len(n1) {
|
||||
return 0, ErrVersionMismatch
|
||||
}
|
||||
for i := 0; i < len(n); i++ {
|
||||
mask := uint32(1) << 31
|
||||
pos := uint(31)
|
||||
for ; mask > 0; mask >>= 1 {
|
||||
if n[i]&mask != n1[i]&mask {
|
||||
if i == 0 && pos == 31 {
|
||||
return 0, ErrNoGreatestCommonBit
|
||||
}
|
||||
return (pos + 1) + uint(BitsPerUint32)*uint(len(n)-i-1), nil
|
||||
}
|
||||
pos--
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Network represents a block of network numbers, also known as CIDR.
|
||||
type Network struct {
|
||||
Number NetworkNumber
|
||||
Mask NetworkNumberMask
|
||||
}
|
||||
|
||||
// NewNetwork returns Network built using given net.IPNet.
|
||||
func NewNetwork(ipNet net.IPNet) Network {
|
||||
ones, _ := ipNet.Mask.Size()
|
||||
return Network{
|
||||
Number: NewNetworkNumber(ipNet.IP),
|
||||
Mask: NetworkNumberMask(ones),
|
||||
}
|
||||
}
|
||||
|
||||
// Masked returns a new network conforming to new mask.
|
||||
func (n Network) Masked(ones int) Network {
|
||||
mask := NetworkNumberMask(ones)
|
||||
return Network{
|
||||
Number: mask.Mask(n.Number),
|
||||
Mask: mask,
|
||||
}
|
||||
}
|
||||
|
||||
func sub(a, b uint8) uint8 {
|
||||
res := a - b
|
||||
if res > a {
|
||||
res = 0
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func mask(m NetworkNumberMask) (mask1, mask2, mask3, mask4 uint32) {
|
||||
// We're relying on overflow here.
|
||||
const ones uint32 = 0xFFFFFFFF
|
||||
mask1 = ones << sub(1*32, uint8(m))
|
||||
mask2 = ones << sub(2*32, uint8(m))
|
||||
mask3 = ones << sub(3*32, uint8(m))
|
||||
mask4 = ones << sub(4*32, uint8(m))
|
||||
return
|
||||
}
|
||||
|
||||
// Contains returns true if NetworkNumber is in range of Network, false
|
||||
// otherwise.
|
||||
func (n Network) Contains(nn NetworkNumber) bool {
|
||||
if len(n.Number) != len(nn) {
|
||||
return false
|
||||
}
|
||||
const ones uint32 = 0xFFFFFFFF
|
||||
|
||||
mask1, mask2, mask3, mask4 := mask(n.Mask)
|
||||
switch len(n.Number) {
|
||||
case IPv4Uint32Count:
|
||||
return nn[0]&mask1 == n.Number[0]
|
||||
case IPv6Uint32Count:
|
||||
return nn[0]&mask1 == n.Number[0] &&
|
||||
nn[1]&mask2 == n.Number[1] &&
|
||||
nn[2]&mask3 == n.Number[2] &&
|
||||
nn[3]&mask4 == n.Number[3]
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Contains returns true if Network covers o, false otherwise
|
||||
func (n Network) Covers(o Network) bool {
|
||||
return n.Contains(o.Number) && n.Mask <= o.Mask
|
||||
}
|
||||
|
||||
// LeastCommonBitPosition returns the smallest position of the preceding common
|
||||
// bits of the 2 networks, and returns an error ErrNoGreatestCommonBit
|
||||
// if the two network number diverges from the first bit.
|
||||
func (n Network) LeastCommonBitPosition(n1 Network) (uint, error) {
|
||||
maskSize := n.Mask
|
||||
if n1.Mask < n.Mask {
|
||||
maskSize = n1.Mask
|
||||
}
|
||||
maskPosition := len(n1.Number)*BitsPerUint32 - int(maskSize)
|
||||
lcb, err := n.Number.LeastCommonBitPosition(n1.Number)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint(math.Max(float64(maskPosition), float64(lcb))), nil
|
||||
}
|
||||
|
||||
// Equal is the equality test for 2 networks.
|
||||
func (n Network) Equal(n1 Network) bool {
|
||||
return n.Number.Equal(n1.Number) && n.Mask == n1.Mask
|
||||
}
|
||||
|
||||
func (n Network) String() string {
|
||||
return fmt.Sprintf("%s/%d", n.Number.ToIP(), n.Mask)
|
||||
}
|
||||
|
||||
func (n Network) IPNet() net.IPNet {
|
||||
return net.IPNet{
|
||||
IP: n.Number.ToIP(),
|
||||
Mask: net.CIDRMask(int(n.Mask), len(n.Number)*32),
|
||||
}
|
||||
}
|
||||
|
||||
// NetworkNumberMask is an IP address.
|
||||
type NetworkNumberMask int
|
||||
|
||||
// Mask returns a new masked NetworkNumber from given NetworkNumber.
|
||||
func (m NetworkNumberMask) Mask(n NetworkNumber) NetworkNumber {
|
||||
mask1, mask2, mask3, mask4 := mask(m)
|
||||
|
||||
result := make(NetworkNumber, len(n))
|
||||
switch len(n) {
|
||||
case IPv4Uint32Count:
|
||||
result[0] = n[0] & mask1
|
||||
case IPv6Uint32Count:
|
||||
result[0] = n[0] & mask1
|
||||
result[1] = n[1] & mask2
|
||||
result[2] = n[2] & mask3
|
||||
result[3] = n[3] & mask4
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// NextIP returns the next sequential ip.
|
||||
func NextIP(ip net.IP) net.IP {
|
||||
return NewNetworkNumber(ip).Next().ToIP()
|
||||
}
|
||||
|
||||
// PreviousIP returns the previous sequential ip.
|
||||
func PreviousIP(ip net.IP) net.IP {
|
||||
return NewNetworkNumber(ip).Previous().ToIP()
|
||||
}
|
|
@ -1,404 +0,0 @@
|
|||
package cidranger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
rnet "github.com/libp2p/go-cidranger/net"
|
||||
)
|
||||
|
||||
// prefixTrie is a path-compressed (PC) trie implementation of the
|
||||
// ranger interface inspired by this blog post:
|
||||
// https://vincent.bernat.im/en/blog/2017-ipv4-route-lookup-linux
|
||||
//
|
||||
// CIDR blocks are stored using a prefix tree structure where each node has its
|
||||
// parent as prefix, and the path from the root node represents current CIDR
|
||||
// block.
|
||||
//
|
||||
// For IPv4, the trie structure guarantees max depth of 32 as IPv4 addresses are
|
||||
// 32 bits long and each bit represents a prefix tree starting at that bit. This
|
||||
// property also guarantees constant lookup time in Big-O notation.
|
||||
//
|
||||
// Path compression compresses a string of node with only 1 child into a single
|
||||
// node, decrease the amount of lookups necessary during containment tests.
|
||||
//
|
||||
// Level compression dictates the amount of direct children of a node by
|
||||
// allowing it to handle multiple bits in the path. The heuristic (based on
|
||||
// children population) to decide when the compression and decompression happens
|
||||
// is outlined in the prior linked blog, and will be experimented with in more
|
||||
// depth in this project in the future.
|
||||
//
|
||||
// Note: Can not insert both IPv4 and IPv6 network addresses into the same
|
||||
// prefix trie, use versionedRanger wrapper instead.
|
||||
//
|
||||
// TODO: Implement level-compressed component of the LPC trie.
|
||||
type prefixTrie struct {
|
||||
parent *prefixTrie
|
||||
children [2]*prefixTrie
|
||||
|
||||
numBitsSkipped uint
|
||||
numBitsHandled uint
|
||||
|
||||
network rnet.Network
|
||||
entry RangerEntry
|
||||
|
||||
size int // This is only maintained in the root trie.
|
||||
}
|
||||
|
||||
var ip4ZeroCIDR, ip6ZeroCIDR net.IPNet
|
||||
|
||||
func init() {
|
||||
_, v4, _ := net.ParseCIDR("0.0.0.0/0")
|
||||
_, v6, _ := net.ParseCIDR("0::0/0")
|
||||
ip4ZeroCIDR = *v4
|
||||
ip6ZeroCIDR = *v6
|
||||
}
|
||||
|
||||
func newRanger(version rnet.IPVersion) Ranger {
|
||||
return newPrefixTree(version)
|
||||
}
|
||||
|
||||
// newPrefixTree creates a new prefixTrie.
|
||||
func newPrefixTree(version rnet.IPVersion) *prefixTrie {
|
||||
rootNet := ip4ZeroCIDR
|
||||
if version == rnet.IPv6 {
|
||||
rootNet = ip6ZeroCIDR
|
||||
}
|
||||
return &prefixTrie{
|
||||
numBitsSkipped: 0,
|
||||
numBitsHandled: 1,
|
||||
network: rnet.NewNetwork(rootNet),
|
||||
}
|
||||
}
|
||||
|
||||
func newPathprefixTrie(network rnet.Network, numBitsSkipped uint) *prefixTrie {
|
||||
version := rnet.IPv4
|
||||
if len(network.Number) == rnet.IPv6Uint32Count {
|
||||
version = rnet.IPv6
|
||||
}
|
||||
path := newPrefixTree(version)
|
||||
path.numBitsSkipped = numBitsSkipped
|
||||
path.network = network.Masked(int(numBitsSkipped))
|
||||
return path
|
||||
}
|
||||
|
||||
func newEntryTrie(network rnet.Network, entry RangerEntry) *prefixTrie {
|
||||
leaf := newPathprefixTrie(network, uint(network.Mask))
|
||||
leaf.entry = entry
|
||||
return leaf
|
||||
}
|
||||
|
||||
// Insert inserts a RangerEntry into prefix trie.
|
||||
func (p *prefixTrie) Insert(entry RangerEntry) error {
|
||||
network := entry.Network()
|
||||
sizeIncreased, err := p.insert(rnet.NewNetwork(network), entry)
|
||||
if sizeIncreased {
|
||||
p.size++
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove removes RangerEntry identified by given network from trie.
|
||||
func (p *prefixTrie) Remove(network net.IPNet) (RangerEntry, error) {
|
||||
entry, err := p.remove(rnet.NewNetwork(network))
|
||||
if entry != nil {
|
||||
p.size--
|
||||
}
|
||||
return entry, err
|
||||
}
|
||||
|
||||
// Contains returns boolean indicating whether given ip is contained in any
|
||||
// of the inserted networks.
|
||||
func (p *prefixTrie) Contains(ip net.IP) (bool, error) {
|
||||
nn := rnet.NewNetworkNumber(ip)
|
||||
if nn == nil {
|
||||
return false, ErrInvalidNetworkNumberInput
|
||||
}
|
||||
return p.contains(nn)
|
||||
}
|
||||
|
||||
// ContainingNetworks returns the list of RangerEntry(s) the given ip is
|
||||
// contained in in ascending prefix order.
|
||||
func (p *prefixTrie) ContainingNetworks(ip net.IP) ([]RangerEntry, error) {
|
||||
nn := rnet.NewNetworkNumber(ip)
|
||||
if nn == nil {
|
||||
return nil, ErrInvalidNetworkNumberInput
|
||||
}
|
||||
return p.containingNetworks(nn)
|
||||
}
|
||||
|
||||
// CoveredNetworks returns the list of RangerEntry(s) the given ipnet
|
||||
// covers. That is, the networks that are completely subsumed by the
|
||||
// specified network.
|
||||
func (p *prefixTrie) CoveredNetworks(network net.IPNet) ([]RangerEntry, error) {
|
||||
net := rnet.NewNetwork(network)
|
||||
return p.coveredNetworks(net)
|
||||
}
|
||||
|
||||
// Len returns number of networks in ranger.
|
||||
func (p *prefixTrie) Len() int {
|
||||
return p.size
|
||||
}
|
||||
|
||||
// String returns string representation of trie, mainly for visualization and
|
||||
// debugging.
|
||||
func (p *prefixTrie) String() string {
|
||||
children := []string{}
|
||||
padding := strings.Repeat("| ", p.level()+1)
|
||||
for bits, child := range p.children {
|
||||
if child == nil {
|
||||
continue
|
||||
}
|
||||
childStr := fmt.Sprintf("\n%s%d--> %s", padding, bits, child.String())
|
||||
children = append(children, childStr)
|
||||
}
|
||||
return fmt.Sprintf("%s (target_pos:%d:has_entry:%t)%s", p.network,
|
||||
p.targetBitPosition(), p.hasEntry(), strings.Join(children, ""))
|
||||
}
|
||||
|
||||
func (p *prefixTrie) contains(number rnet.NetworkNumber) (bool, error) {
|
||||
if !p.network.Contains(number) {
|
||||
return false, nil
|
||||
}
|
||||
if p.hasEntry() {
|
||||
return true, nil
|
||||
}
|
||||
if p.targetBitPosition() < 0 {
|
||||
return false, nil
|
||||
}
|
||||
bit, err := p.targetBitFromIP(number)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
child := p.children[bit]
|
||||
if child != nil {
|
||||
return child.contains(number)
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (p *prefixTrie) containingNetworks(number rnet.NetworkNumber) ([]RangerEntry, error) {
|
||||
results := []RangerEntry{}
|
||||
if !p.network.Contains(number) {
|
||||
return results, nil
|
||||
}
|
||||
if p.hasEntry() {
|
||||
results = []RangerEntry{p.entry}
|
||||
}
|
||||
if p.targetBitPosition() < 0 {
|
||||
return results, nil
|
||||
}
|
||||
bit, err := p.targetBitFromIP(number)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
child := p.children[bit]
|
||||
if child != nil {
|
||||
ranges, err := child.containingNetworks(number)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(ranges) > 0 {
|
||||
if len(results) > 0 {
|
||||
results = append(results, ranges...)
|
||||
} else {
|
||||
results = ranges
|
||||
}
|
||||
}
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (p *prefixTrie) coveredNetworks(network rnet.Network) ([]RangerEntry, error) {
|
||||
var results []RangerEntry
|
||||
if network.Covers(p.network) {
|
||||
for entry := range p.walkDepth() {
|
||||
results = append(results, entry)
|
||||
}
|
||||
} else if p.targetBitPosition() >= 0 {
|
||||
bit, err := p.targetBitFromIP(network.Number)
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
child := p.children[bit]
|
||||
if child != nil {
|
||||
return child.coveredNetworks(network)
|
||||
}
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (p *prefixTrie) insert(network rnet.Network, entry RangerEntry) (bool, error) {
|
||||
if p.network.Equal(network) {
|
||||
sizeIncreased := p.entry == nil
|
||||
p.entry = entry
|
||||
return sizeIncreased, nil
|
||||
}
|
||||
|
||||
bit, err := p.targetBitFromIP(network.Number)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
existingChild := p.children[bit]
|
||||
|
||||
// No existing child, insert new leaf trie.
|
||||
if existingChild == nil {
|
||||
p.appendTrie(bit, newEntryTrie(network, entry))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Check whether it is necessary to insert additional path prefix between current trie and existing child,
|
||||
// in the case that inserted network diverges on its path to existing child.
|
||||
lcb, err := network.LeastCommonBitPosition(existingChild.network)
|
||||
divergingBitPos := int(lcb) - 1
|
||||
if divergingBitPos > existingChild.targetBitPosition() {
|
||||
pathPrefix := newPathprefixTrie(network, p.totalNumberOfBits()-lcb)
|
||||
err := p.insertPrefix(bit, pathPrefix, existingChild)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// Update new child
|
||||
existingChild = pathPrefix
|
||||
}
|
||||
return existingChild.insert(network, entry)
|
||||
}
|
||||
|
||||
func (p *prefixTrie) appendTrie(bit uint32, prefix *prefixTrie) {
|
||||
p.children[bit] = prefix
|
||||
prefix.parent = p
|
||||
}
|
||||
|
||||
func (p *prefixTrie) insertPrefix(bit uint32, pathPrefix, child *prefixTrie) error {
|
||||
// Set parent/child relationship between current trie and inserted pathPrefix
|
||||
p.children[bit] = pathPrefix
|
||||
pathPrefix.parent = p
|
||||
|
||||
// Set parent/child relationship between inserted pathPrefix and original child
|
||||
pathPrefixBit, err := pathPrefix.targetBitFromIP(child.network.Number)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pathPrefix.children[pathPrefixBit] = child
|
||||
child.parent = pathPrefix
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *prefixTrie) remove(network rnet.Network) (RangerEntry, error) {
|
||||
if p.hasEntry() && p.network.Equal(network) {
|
||||
entry := p.entry
|
||||
p.entry = nil
|
||||
|
||||
err := p.compressPathIfPossible()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return entry, nil
|
||||
}
|
||||
bit, err := p.targetBitFromIP(network.Number)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
child := p.children[bit]
|
||||
if child != nil {
|
||||
return child.remove(network)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (p *prefixTrie) qualifiesForPathCompression() bool {
|
||||
// Current prefix trie can be path compressed if it meets all following.
|
||||
// 1. records no CIDR entry
|
||||
// 2. has single or no child
|
||||
// 3. is not root trie
|
||||
return !p.hasEntry() && p.childrenCount() <= 1 && p.parent != nil
|
||||
}
|
||||
|
||||
func (p *prefixTrie) compressPathIfPossible() error {
|
||||
if !p.qualifiesForPathCompression() {
|
||||
// Does not qualify to be compressed
|
||||
return nil
|
||||
}
|
||||
|
||||
// Find lone child.
|
||||
var loneChild *prefixTrie
|
||||
for _, child := range p.children {
|
||||
if child != nil {
|
||||
loneChild = child
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Find root of currnt single child lineage.
|
||||
parent := p.parent
|
||||
for ; parent.qualifiesForPathCompression(); parent = parent.parent {
|
||||
}
|
||||
parentBit, err := parent.targetBitFromIP(p.network.Number)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parent.children[parentBit] = loneChild
|
||||
|
||||
// Attempts to furthur apply path compression at current lineage parent, in case current lineage
|
||||
// compressed into parent.
|
||||
return parent.compressPathIfPossible()
|
||||
}
|
||||
|
||||
func (p *prefixTrie) childrenCount() int {
|
||||
count := 0
|
||||
for _, child := range p.children {
|
||||
if child != nil {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func (p *prefixTrie) totalNumberOfBits() uint {
|
||||
return rnet.BitsPerUint32 * uint(len(p.network.Number))
|
||||
}
|
||||
|
||||
func (p *prefixTrie) targetBitPosition() int {
|
||||
return int(p.totalNumberOfBits()-p.numBitsSkipped) - 1
|
||||
}
|
||||
|
||||
func (p *prefixTrie) targetBitFromIP(n rnet.NetworkNumber) (uint32, error) {
|
||||
// This is a safe uint boxing of int since we should never attempt to get
|
||||
// target bit at a negative position.
|
||||
return n.Bit(uint(p.targetBitPosition()))
|
||||
}
|
||||
|
||||
func (p *prefixTrie) hasEntry() bool {
|
||||
return p.entry != nil
|
||||
}
|
||||
|
||||
func (p *prefixTrie) level() int {
|
||||
if p.parent == nil {
|
||||
return 0
|
||||
}
|
||||
return p.parent.level() + 1
|
||||
}
|
||||
|
||||
// walkDepth walks the trie in depth order, for unit testing.
|
||||
func (p *prefixTrie) walkDepth() <-chan RangerEntry {
|
||||
entries := make(chan RangerEntry)
|
||||
go func() {
|
||||
if p.hasEntry() {
|
||||
entries <- p.entry
|
||||
}
|
||||
childEntriesList := []<-chan RangerEntry{}
|
||||
for _, trie := range p.children {
|
||||
if trie == nil {
|
||||
continue
|
||||
}
|
||||
childEntriesList = append(childEntriesList, trie.walkDepth())
|
||||
}
|
||||
for _, childEntries := range childEntriesList {
|
||||
for entry := range childEntries {
|
||||
entries <- entry
|
||||
}
|
||||
}
|
||||
close(entries)
|
||||
}()
|
||||
return entries
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package cidranger
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
rnet "github.com/libp2p/go-cidranger/net"
|
||||
)
|
||||
|
||||
type rangerFactory func(rnet.IPVersion) Ranger
|
||||
|
||||
type versionedRanger struct {
|
||||
ipV4Ranger Ranger
|
||||
ipV6Ranger Ranger
|
||||
}
|
||||
|
||||
func newVersionedRanger(factory rangerFactory) Ranger {
|
||||
return &versionedRanger{
|
||||
ipV4Ranger: factory(rnet.IPv4),
|
||||
ipV6Ranger: factory(rnet.IPv6),
|
||||
}
|
||||
}
|
||||
|
||||
func (v *versionedRanger) Insert(entry RangerEntry) error {
|
||||
network := entry.Network()
|
||||
ranger, err := v.getRangerForIP(network.IP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ranger.Insert(entry)
|
||||
}
|
||||
|
||||
func (v *versionedRanger) Remove(network net.IPNet) (RangerEntry, error) {
|
||||
ranger, err := v.getRangerForIP(network.IP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ranger.Remove(network)
|
||||
}
|
||||
|
||||
func (v *versionedRanger) Contains(ip net.IP) (bool, error) {
|
||||
ranger, err := v.getRangerForIP(ip)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return ranger.Contains(ip)
|
||||
}
|
||||
|
||||
func (v *versionedRanger) ContainingNetworks(ip net.IP) ([]RangerEntry, error) {
|
||||
ranger, err := v.getRangerForIP(ip)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ranger.ContainingNetworks(ip)
|
||||
}
|
||||
|
||||
func (v *versionedRanger) CoveredNetworks(network net.IPNet) ([]RangerEntry, error) {
|
||||
ranger, err := v.getRangerForIP(network.IP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ranger.CoveredNetworks(network)
|
||||
}
|
||||
|
||||
// Len returns number of networks in ranger.
|
||||
func (v *versionedRanger) Len() int {
|
||||
return v.ipV4Ranger.Len() + v.ipV6Ranger.Len()
|
||||
}
|
||||
|
||||
func (v *versionedRanger) getRangerForIP(ip net.IP) (Ranger, error) {
|
||||
if ip.To4() != nil {
|
||||
return v.ipV4Ranger, nil
|
||||
}
|
||||
if ip.To16() != nil {
|
||||
return v.ipV6Ranger, nil
|
||||
}
|
||||
return nil, ErrInvalidNetworkNumberInput
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
# go-libp2p-asn-util
|
||||
===
|
||||
|
||||
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://protocol.ai)
|
||||
[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://github.com/libp2p/libp2p)
|
||||
|
@ -45,4 +44,4 @@ This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/c
|
|||
|
||||
MIT
|
||||
|
||||
---
|
||||
---
|
||||
|
|
|
@ -1,95 +1,93 @@
|
|||
package asnutil
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/libp2p/go-cidranger"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var Store *lazyAsnStore
|
||||
//go:embed sorted-network-list.bin
|
||||
var dataset string
|
||||
|
||||
const entrySize = 8*2 + 4 // start, end 8 bytes; asn 4 bytes
|
||||
|
||||
func readEntry(index uint) (start, end uint64, asn uint32) {
|
||||
base := entrySize * index
|
||||
b := dataset[base : base+entrySize]
|
||||
start = uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||
b = b[8:]
|
||||
end = uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||
b = b[8:]
|
||||
asn = uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||
return
|
||||
}
|
||||
|
||||
// AsnForIPv6 returns the AS number for the given IPv6 address.
|
||||
// If no mapping exists for the given network, this function will return a zero ASN number.
|
||||
func AsnForIPv6(ip net.IP) (asn uint32) {
|
||||
ip = ip.To16()
|
||||
if ip == nil {
|
||||
return
|
||||
}
|
||||
return AsnForIPv6Network(binary.BigEndian.Uint64(ip))
|
||||
}
|
||||
|
||||
func init() {
|
||||
Store = &lazyAsnStore{}
|
||||
if len(dataset) > math.MaxUint/2 {
|
||||
panic("list is too big and would overflow in binary search")
|
||||
}
|
||||
}
|
||||
|
||||
type networkWithAsn struct {
|
||||
nn net.IPNet
|
||||
asn string
|
||||
// AsnForIPv6Network returns the AS number for the given IPv6 network.
|
||||
// If no mapping exists for the given network, this function will return a zero ASN number.
|
||||
// network is the first 64 bits of the ip address interpreted as big endian.
|
||||
func AsnForIPv6Network(network uint64) (asn uint32) {
|
||||
n := uint(len(dataset)) / entrySize
|
||||
var i, j uint = 0, n
|
||||
for i < j {
|
||||
h := (i + j) / 2 // wont overflow since the list can't be that large
|
||||
start, end, asn := readEntry(h)
|
||||
if start <= network {
|
||||
if network <= end {
|
||||
return asn
|
||||
}
|
||||
i = h + 1
|
||||
} else {
|
||||
j = h
|
||||
}
|
||||
}
|
||||
if i >= n {
|
||||
return 0
|
||||
}
|
||||
start, end, asn := readEntry(i)
|
||||
if start <= network && network <= end {
|
||||
return asn
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *networkWithAsn) Network() net.IPNet {
|
||||
return e.nn
|
||||
}
|
||||
// Deprecated: use [AsnForIPv6] or [AsnForIPv6Network], they do not allocate.
|
||||
var Store backwardCompat
|
||||
|
||||
type asnStore struct {
|
||||
cr cidranger.Ranger
|
||||
}
|
||||
type backwardCompat struct{}
|
||||
|
||||
// AsnForIPv6 returns the AS number for the given IPv6 address.
|
||||
// If no mapping exists for the given IP, this function will
|
||||
// return an empty ASN and a nil error.
|
||||
func (a *asnStore) AsnForIPv6(ip net.IP) (string, error) {
|
||||
if ip.To16() == nil {
|
||||
return "", errors.New("ONLY IPv6 addresses supported for now")
|
||||
func (backwardCompat) AsnForIPv6(ip net.IP) (string, error) {
|
||||
ip = ip.To16()
|
||||
if ip == nil {
|
||||
return "", errors.New("ONLY IPv6 addresses supported")
|
||||
}
|
||||
|
||||
ns, err := a.cr.ContainingNetworks(ip)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to find matching networks for the given ip: %w", err)
|
||||
}
|
||||
|
||||
if len(ns) == 0 {
|
||||
asn := AsnForIPv6Network(binary.BigEndian.Uint64(ip))
|
||||
if asn == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// longest prefix match
|
||||
n := ns[len(ns)-1].(*networkWithAsn)
|
||||
return n.asn, nil
|
||||
return strconv.FormatUint(uint64(asn), 10), nil
|
||||
}
|
||||
|
||||
func newAsnStore() (*asnStore, error) {
|
||||
cr := cidranger.NewPCTrieRanger()
|
||||
|
||||
for _, v := range ipv6CidrToAsnPairList {
|
||||
_, nn, err := net.ParseCIDR(v.cidr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse CIDR %s: %w", v.cidr, err)
|
||||
}
|
||||
|
||||
if err := cr.Insert(&networkWithAsn{*nn, v.asn}); err != nil {
|
||||
return nil, fmt.Errorf("failed to insert CIDR %s in Trie store: %w", v.cidr, err)
|
||||
}
|
||||
}
|
||||
|
||||
return &asnStore{cr}, nil
|
||||
}
|
||||
|
||||
// lazyAsnStore builds the underlying trie on first call to AsnForIPv6.
|
||||
// Alternatively, Init can be called to manually trigger initialization.
|
||||
type lazyAsnStore struct {
|
||||
store *asnStore
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
// AsnForIPv6 returns the AS number for the given IPv6 address.
|
||||
// If no mapping exists for the given IP, this function will
|
||||
// return an empty ASN and a nil error.
|
||||
func (a *lazyAsnStore) AsnForIPv6(ip net.IP) (string, error) {
|
||||
a.once.Do(a.init)
|
||||
return a.store.AsnForIPv6(ip)
|
||||
}
|
||||
|
||||
func (a *lazyAsnStore) Init() {
|
||||
a.once.Do(a.init)
|
||||
}
|
||||
|
||||
func (a *lazyAsnStore) init() {
|
||||
store, err := newAsnStore()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
a.store = store
|
||||
}
|
||||
func (backwardCompat) Init() {}
|
||||
|
|
|
@ -2,4 +2,3 @@
|
|||
package asnutil
|
||||
|
||||
//go:generate go run ./generate/
|
||||
//go:generate go fmt ./...
|
||||
|
|
File diff suppressed because it is too large
Load Diff
BIN
vendor/github.com/libp2p/go-libp2p-asn-util/sorted-network-list.bin
generated
vendored
Normal file
BIN
vendor/github.com/libp2p/go-libp2p-asn-util/sorted-network-list.bin
generated
vendored
Normal file
Binary file not shown.
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"version": "v0.3.0"
|
||||
"version": "v0.4.1"
|
||||
}
|
||||
|
|
|
@ -9,12 +9,14 @@ import (
|
|||
|
||||
pb "github.com/libp2p/go-libp2p-pubsub/pb"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/event"
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/peerstore"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
"github.com/libp2p/go-libp2p/core/record"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -231,6 +233,7 @@ func DefaultGossipSubRouter(h host.Host) *GossipSubRouter {
|
|||
iasked: make(map[peer.ID]int),
|
||||
outbound: make(map[peer.ID]bool),
|
||||
connect: make(chan connectInfo, params.MaxPendingConnections),
|
||||
cab: pstoremem.NewAddrBook(),
|
||||
mcache: NewMessageCache(params.HistoryGossip, params.HistoryLength),
|
||||
protos: GossipSubDefaultProtocols,
|
||||
feature: GossipSubDefaultFeatures,
|
||||
|
@ -431,6 +434,7 @@ type GossipSubRouter struct {
|
|||
outbound map[peer.ID]bool // connection direction cache, marks peers with outbound connections
|
||||
backoff map[string]map[peer.ID]time.Time // prune backoff
|
||||
connect chan connectInfo // px connection requests
|
||||
cab peerstore.AddrBook
|
||||
|
||||
protos []protocol.ID
|
||||
feature GossipSubFeatureTest
|
||||
|
@ -509,6 +513,9 @@ func (gs *GossipSubRouter) Attach(p *PubSub) {
|
|||
go gs.connector()
|
||||
}
|
||||
|
||||
// Manage our address book from events emitted by libp2p
|
||||
go gs.manageAddrBook()
|
||||
|
||||
// connect to direct peers
|
||||
if len(gs.direct) > 0 {
|
||||
go func() {
|
||||
|
@ -522,6 +529,46 @@ func (gs *GossipSubRouter) Attach(p *PubSub) {
|
|||
}
|
||||
}
|
||||
|
||||
func (gs *GossipSubRouter) manageAddrBook() {
|
||||
sub, err := gs.p.host.EventBus().Subscribe([]interface{}{
|
||||
&event.EvtPeerIdentificationCompleted{},
|
||||
&event.EvtPeerConnectednessChanged{},
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("failed to subscribe to peer identification events: %v", err)
|
||||
return
|
||||
}
|
||||
defer sub.Close()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-gs.p.ctx.Done():
|
||||
return
|
||||
case ev := <-sub.Out():
|
||||
switch ev := ev.(type) {
|
||||
case event.EvtPeerIdentificationCompleted:
|
||||
if ev.SignedPeerRecord != nil {
|
||||
cab, ok := peerstore.GetCertifiedAddrBook(gs.cab)
|
||||
if ok {
|
||||
ttl := peerstore.RecentlyConnectedAddrTTL
|
||||
if gs.p.host.Network().Connectedness(ev.Peer) == network.Connected {
|
||||
ttl = peerstore.ConnectedAddrTTL
|
||||
}
|
||||
_, err := cab.ConsumePeerRecord(ev.SignedPeerRecord, ttl)
|
||||
if err != nil {
|
||||
log.Warnf("failed to consume signed peer record: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
case event.EvtPeerConnectednessChanged:
|
||||
if ev.Connectedness != network.Connected {
|
||||
gs.cab.UpdateAddrs(ev.Peer, peerstore.ConnectedAddrTTL, peerstore.RecentlyConnectedAddrTTL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (gs *GossipSubRouter) AddPeer(p peer.ID, proto protocol.ID) {
|
||||
log.Debugf("PEERUP: Add new peer %s using %s", p, proto)
|
||||
gs.tracer.AddPeer(p, proto)
|
||||
|
@ -534,7 +581,7 @@ loop:
|
|||
for _, c := range conns {
|
||||
stat := c.Stat()
|
||||
|
||||
if stat.Transient {
|
||||
if stat.Limited {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -951,7 +998,7 @@ func (gs *GossipSubRouter) connector() {
|
|||
}
|
||||
|
||||
log.Debugf("connecting to %s", ci.p)
|
||||
cab, ok := peerstore.GetCertifiedAddrBook(gs.p.host.Peerstore())
|
||||
cab, ok := peerstore.GetCertifiedAddrBook(gs.cab)
|
||||
if ok && ci.spr != nil {
|
||||
_, err := cab.ConsumePeerRecord(ci.spr, peerstore.TempAddrTTL)
|
||||
if err != nil {
|
||||
|
@ -960,7 +1007,7 @@ func (gs *GossipSubRouter) connector() {
|
|||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(gs.p.ctx, gs.params.ConnectionTimeout)
|
||||
err := gs.p.host.Connect(ctx, peer.AddrInfo{ID: ci.p})
|
||||
err := gs.p.host.Connect(ctx, peer.AddrInfo{ID: ci.p, Addrs: gs.cab.Addrs(ci.p)})
|
||||
cancel()
|
||||
if err != nil {
|
||||
log.Debugf("error connecting to %s: %s", ci.p, err)
|
||||
|
@ -1886,7 +1933,7 @@ func (gs *GossipSubRouter) makePrune(p peer.ID, topic string, doPX bool, isUnsub
|
|||
return p != xp && gs.score.Score(xp) >= 0
|
||||
})
|
||||
|
||||
cab, ok := peerstore.GetCertifiedAddrBook(gs.p.host.Peerstore())
|
||||
cab, ok := peerstore.GetCertifiedAddrBook(gs.cab)
|
||||
px = make([]*pb.PeerInfo, 0, len(peers))
|
||||
for _, p := range peers {
|
||||
// see if we have a signed peer record to send back; if we don't, just send
|
||||
|
|
|
@ -18,7 +18,7 @@ func (p *PubSubNotif) ClosedStream(n network.Network, s network.Stream) {
|
|||
|
||||
func (p *PubSubNotif) Connected(n network.Network, c network.Conn) {
|
||||
// ignore transient connections
|
||||
if c.Stat().Transient {
|
||||
if c.Stat().Limited {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ func (p *PubSubNotif) ListenClose(n network.Network, _ ma.Multiaddr) {
|
|||
func (p *PubSubNotif) Initialize() {
|
||||
isTransient := func(pid peer.ID) bool {
|
||||
for _, c := range p.host.Network().ConnsToPeer(pid) {
|
||||
if !c.Stat().Transient {
|
||||
if !c.Stat().Limited {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -303,7 +303,7 @@ func (pg *peerGater) getPeerIP(p peer.ID) string {
|
|||
// most streams; it's a nightmare to track multiple IPs per peer, so pick the best one.
|
||||
streams := make(map[string]int)
|
||||
for _, c := range conns {
|
||||
if c.Stat().Transient {
|
||||
if c.Stat().Limited {
|
||||
// ignore transient
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -990,7 +990,7 @@ func (ps *peerScore) getIPs(p peer.ID) []string {
|
|||
conns := ps.host.Network().ConnsToPeer(p)
|
||||
res := make([]string, 0, 1)
|
||||
for _, c := range conns {
|
||||
if c.Stat().Transient {
|
||||
if c.Stat().Limited {
|
||||
// ignore transient
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
<h1 align="center">
|
||||
<a href="libp2p.io"><img width="250" src="https://github.com/libp2p/libp2p/blob/master/logo/black-bg-2.png?raw=true" alt="libp2p hex logo" /></a>
|
||||
<a href="https://libp2p.io/"><img width="250" src="https://github.com/libp2p/libp2p/blob/master/logo/black-bg-2.png?raw=true" alt="libp2p hex logo" /></a>
|
||||
</h1>
|
||||
|
||||
<h3 align="center">The Go implementation of the libp2p Networking Stack.</h3>
|
||||
|
@ -83,7 +83,7 @@ There's a few things you can do right now to help out:
|
|||
## Supported Go Versions
|
||||
|
||||
We test against and support the two most recent major releases of Go. This is
|
||||
informed by Go's own [security policy](https://go.dev/security).
|
||||
informed by Go's own [security policy](https://go.dev/doc/security/policy).
|
||||
|
||||
# Notable Users
|
||||
Some notable users of go-libp2p are:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -23,7 +24,6 @@ import (
|
|||
"github.com/libp2p/go-libp2p/p2p/host/autonat"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/autorelay"
|
||||
bhost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
||||
blankhost "github.com/libp2p/go-libp2p/p2p/host/blank"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/eventbus"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem"
|
||||
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
|
||||
|
@ -38,6 +38,7 @@ import (
|
|||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
madns "github.com/multiformats/go-multiaddr-dns"
|
||||
"github.com/quic-go/quic-go"
|
||||
"go.uber.org/fx"
|
||||
"go.uber.org/fx/fxevent"
|
||||
)
|
||||
|
@ -128,6 +129,8 @@ type Config struct {
|
|||
DialRanker network.DialRanker
|
||||
|
||||
SwarmOpts []swarm.Option
|
||||
|
||||
DisableIdentifyAddressDiscovery bool
|
||||
}
|
||||
|
||||
func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (*swarm.Swarm, error) {
|
||||
|
@ -190,20 +193,11 @@ func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (*swarm.Swa
|
|||
return swarm.NewSwarm(pid, cfg.Peerstore, eventBus, opts...)
|
||||
}
|
||||
|
||||
func (cfg *Config) addTransports(h host.Host) error {
|
||||
swrm, ok := h.Network().(transport.TransportNetwork)
|
||||
if !ok {
|
||||
// Should probably skip this if no transports.
|
||||
return fmt.Errorf("swarm does not support transports")
|
||||
}
|
||||
|
||||
func (cfg *Config) addTransports() ([]fx.Option, error) {
|
||||
fxopts := []fx.Option{
|
||||
fx.WithLogger(func() fxevent.Logger { return getFXLogger() }),
|
||||
fx.Provide(fx.Annotate(tptu.New, fx.ParamTags(`name:"security"`))),
|
||||
fx.Supply(cfg.Muxers),
|
||||
fx.Supply(h.ID()),
|
||||
fx.Provide(func() host.Host { return h }),
|
||||
fx.Provide(func() crypto.PrivKey { return h.Peerstore().PrivKey(h.ID()) }),
|
||||
fx.Provide(func() connmgr.ConnectionGater { return cfg.ConnectionGater }),
|
||||
fx.Provide(func() pnet.PSK { return cfg.PSK }),
|
||||
fx.Provide(func() network.ResourceManager { return cfg.ResourceManager }),
|
||||
|
@ -265,12 +259,21 @@ func (cfg *Config) addTransports(h host.Host) error {
|
|||
if cfg.QUICReuse != nil {
|
||||
fxopts = append(fxopts, cfg.QUICReuse...)
|
||||
} else {
|
||||
fxopts = append(fxopts, fx.Provide(quicreuse.NewConnManager)) // TODO: close the ConnManager when shutting down the node
|
||||
fxopts = append(fxopts,
|
||||
fx.Provide(func(key quic.StatelessResetKey, tokenGenerator quic.TokenGeneratorKey, _ *swarm.Swarm, lifecycle fx.Lifecycle) (*quicreuse.ConnManager, error) {
|
||||
cm, err := quicreuse.NewConnManager(key, tokenGenerator)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lifecycle.Append(fx.StopHook(cm.Close))
|
||||
return cm, nil
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
fxopts = append(fxopts, fx.Invoke(
|
||||
fx.Annotate(
|
||||
func(tpts []transport.Transport) error {
|
||||
func(swrm *swarm.Swarm, tpts []transport.Transport) error {
|
||||
for _, t := range tpts {
|
||||
if err := swrm.AddTransport(t); err != nil {
|
||||
return err
|
||||
|
@ -278,63 +281,35 @@ func (cfg *Config) addTransports(h host.Host) error {
|
|||
}
|
||||
return nil
|
||||
},
|
||||
fx.ParamTags(`group:"transport"`),
|
||||
fx.ParamTags("", `group:"transport"`),
|
||||
)),
|
||||
)
|
||||
if cfg.Relay {
|
||||
fxopts = append(fxopts, fx.Invoke(circuitv2.AddTransport))
|
||||
}
|
||||
app := fx.New(fxopts...)
|
||||
if err := app.Err(); err != nil {
|
||||
h.Close()
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return fxopts, nil
|
||||
}
|
||||
|
||||
// NewNode constructs a new libp2p Host from the Config.
|
||||
//
|
||||
// This function consumes the config. Do not reuse it (really!).
|
||||
func (cfg *Config) NewNode() (host.Host, error) {
|
||||
// If possible check that the resource manager conn limit is higher than the
|
||||
// limit set in the conn manager.
|
||||
if l, ok := cfg.ResourceManager.(connmgr.GetConnLimiter); ok {
|
||||
err := cfg.ConnManager.CheckLimit(l)
|
||||
if err != nil {
|
||||
log.Warn(fmt.Sprintf("rcmgr limit conflicts with connmgr limit: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
eventBus := eventbus.NewBus(eventbus.WithMetricsTracer(eventbus.NewMetricsTracer(eventbus.WithRegisterer(cfg.PrometheusRegisterer))))
|
||||
swrm, err := cfg.makeSwarm(eventBus, !cfg.DisableMetrics)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !cfg.DisableMetrics {
|
||||
rcmgr.MustRegisterWith(cfg.PrometheusRegisterer)
|
||||
}
|
||||
|
||||
func (cfg *Config) newBasicHost(swrm *swarm.Swarm, eventBus event.Bus) (*bhost.BasicHost, error) {
|
||||
h, err := bhost.NewHost(swrm, &bhost.HostOpts{
|
||||
EventBus: eventBus,
|
||||
ConnManager: cfg.ConnManager,
|
||||
AddrsFactory: cfg.AddrsFactory,
|
||||
NATManager: cfg.NATManager,
|
||||
EnablePing: !cfg.DisablePing,
|
||||
UserAgent: cfg.UserAgent,
|
||||
ProtocolVersion: cfg.ProtocolVersion,
|
||||
EnableHolePunching: cfg.EnableHolePunching,
|
||||
HolePunchingOptions: cfg.HolePunchingOptions,
|
||||
EnableRelayService: cfg.EnableRelayService,
|
||||
RelayServiceOpts: cfg.RelayServiceOpts,
|
||||
EnableMetrics: !cfg.DisableMetrics,
|
||||
PrometheusRegisterer: cfg.PrometheusRegisterer,
|
||||
EventBus: eventBus,
|
||||
ConnManager: cfg.ConnManager,
|
||||
AddrsFactory: cfg.AddrsFactory,
|
||||
NATManager: cfg.NATManager,
|
||||
EnablePing: !cfg.DisablePing,
|
||||
UserAgent: cfg.UserAgent,
|
||||
ProtocolVersion: cfg.ProtocolVersion,
|
||||
EnableHolePunching: cfg.EnableHolePunching,
|
||||
HolePunchingOptions: cfg.HolePunchingOptions,
|
||||
EnableRelayService: cfg.EnableRelayService,
|
||||
RelayServiceOpts: cfg.RelayServiceOpts,
|
||||
EnableMetrics: !cfg.DisableMetrics,
|
||||
PrometheusRegisterer: cfg.PrometheusRegisterer,
|
||||
DisableIdentifyAddressDiscovery: cfg.DisableIdentifyAddressDiscovery,
|
||||
})
|
||||
if err != nil {
|
||||
swrm.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cfg.Relay {
|
||||
// If we've enabled the relay, we should filter out relay
|
||||
// addresses by default.
|
||||
|
@ -345,60 +320,144 @@ func (cfg *Config) NewNode() (host.Host, error) {
|
|||
return oldFactory(autorelay.Filter(addrs))
|
||||
}
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
if err := cfg.addTransports(h); err != nil {
|
||||
h.Close()
|
||||
return nil, err
|
||||
// NewNode constructs a new libp2p Host from the Config.
|
||||
//
|
||||
// This function consumes the config. Do not reuse it (really!).
|
||||
func (cfg *Config) NewNode() (host.Host, error) {
|
||||
if cfg.EnableAutoRelay && !cfg.Relay {
|
||||
return nil, fmt.Errorf("cannot enable autorelay; relay is not enabled")
|
||||
}
|
||||
// If possible check that the resource manager conn limit is higher than the
|
||||
// limit set in the conn manager.
|
||||
if l, ok := cfg.ResourceManager.(connmgr.GetConnLimiter); ok {
|
||||
err := cfg.ConnManager.CheckLimit(l)
|
||||
if err != nil {
|
||||
log.Warn(fmt.Sprintf("rcmgr limit conflicts with connmgr limit: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This method succeeds if listening on one address succeeds. We
|
||||
// should probably fail if listening on *any* addr fails.
|
||||
if err := h.Network().Listen(cfg.ListenAddrs...); err != nil {
|
||||
h.Close()
|
||||
if !cfg.DisableMetrics {
|
||||
rcmgr.MustRegisterWith(cfg.PrometheusRegisterer)
|
||||
}
|
||||
|
||||
fxopts := []fx.Option{
|
||||
fx.Provide(func() event.Bus {
|
||||
return eventbus.NewBus(eventbus.WithMetricsTracer(eventbus.NewMetricsTracer(eventbus.WithRegisterer(cfg.PrometheusRegisterer))))
|
||||
}),
|
||||
fx.Provide(func(eventBus event.Bus, lifecycle fx.Lifecycle) (*swarm.Swarm, error) {
|
||||
sw, err := cfg.makeSwarm(eventBus, !cfg.DisableMetrics)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lifecycle.Append(fx.StopHook(sw.Close))
|
||||
return sw, nil
|
||||
}),
|
||||
// Make sure the swarm constructor depends on the quicreuse.ConnManager.
|
||||
// That way, the ConnManager will be started before the swarm, and more importantly,
|
||||
// the swarm will be stopped before the ConnManager.
|
||||
fx.Decorate(func(sw *swarm.Swarm, _ *quicreuse.ConnManager, lifecycle fx.Lifecycle) *swarm.Swarm {
|
||||
lifecycle.Append(fx.Hook{
|
||||
OnStart: func(context.Context) error {
|
||||
// TODO: This method succeeds if listening on one address succeeds. We
|
||||
// should probably fail if listening on *any* addr fails.
|
||||
return sw.Listen(cfg.ListenAddrs...)
|
||||
},
|
||||
OnStop: func(context.Context) error {
|
||||
return sw.Close()
|
||||
},
|
||||
})
|
||||
return sw
|
||||
}),
|
||||
fx.Provide(cfg.newBasicHost),
|
||||
fx.Provide(func(bh *bhost.BasicHost) host.Host {
|
||||
return bh
|
||||
}),
|
||||
fx.Provide(func(h *swarm.Swarm) peer.ID { return h.LocalPeer() }),
|
||||
fx.Provide(func(h *swarm.Swarm) crypto.PrivKey { return h.Peerstore().PrivKey(h.LocalPeer()) }),
|
||||
}
|
||||
transportOpts, err := cfg.addTransports()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fxopts = append(fxopts, transportOpts...)
|
||||
|
||||
// Configure routing and autorelay
|
||||
var router routing.PeerRouting
|
||||
if cfg.Routing != nil {
|
||||
router, err = cfg.Routing(h)
|
||||
if err != nil {
|
||||
h.Close()
|
||||
return nil, err
|
||||
}
|
||||
fxopts = append(fxopts,
|
||||
fx.Provide(cfg.Routing),
|
||||
fx.Provide(func(h host.Host, router routing.PeerRouting) *routed.RoutedHost {
|
||||
return routed.Wrap(h, router)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
// Note: h.AddrsFactory may be changed by relayFinder, but non-relay version is
|
||||
// used by AutoNAT below.
|
||||
var ar *autorelay.AutoRelay
|
||||
addrF := h.AddrsFactory
|
||||
if cfg.EnableAutoRelay {
|
||||
if !cfg.Relay {
|
||||
h.Close()
|
||||
return nil, fmt.Errorf("cannot enable autorelay; relay is not enabled")
|
||||
}
|
||||
if !cfg.DisableMetrics {
|
||||
mt := autorelay.WithMetricsTracer(
|
||||
autorelay.NewMetricsTracer(autorelay.WithRegisterer(cfg.PrometheusRegisterer)))
|
||||
mtOpts := []autorelay.Option{mt}
|
||||
cfg.AutoRelayOpts = append(mtOpts, cfg.AutoRelayOpts...)
|
||||
}
|
||||
|
||||
ar, err = autorelay.NewAutoRelay(h, cfg.AutoRelayOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fxopts = append(fxopts,
|
||||
fx.Invoke(func(h *bhost.BasicHost, lifecycle fx.Lifecycle) (*autorelay.AutoRelay, error) {
|
||||
ar, err := autorelay.NewAutoRelay(h, cfg.AutoRelayOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lifecycle.Append(fx.StartStopHook(ar.Start, ar.Close))
|
||||
return ar, nil
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
var bh *bhost.BasicHost
|
||||
fxopts = append(fxopts, fx.Invoke(func(bho *bhost.BasicHost) { bh = bho }))
|
||||
fxopts = append(fxopts, fx.Invoke(func(h *bhost.BasicHost, lifecycle fx.Lifecycle) {
|
||||
lifecycle.Append(fx.StartHook(h.Start))
|
||||
}))
|
||||
|
||||
var rh *routed.RoutedHost
|
||||
if cfg.Routing != nil {
|
||||
fxopts = append(fxopts, fx.Invoke(func(bho *routed.RoutedHost) { rh = bho }))
|
||||
}
|
||||
|
||||
app := fx.New(fxopts...)
|
||||
if err := app.Start(context.Background()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := cfg.addAutoNAT(bh); err != nil {
|
||||
app.Stop(context.Background())
|
||||
if cfg.Routing != nil {
|
||||
rh.Close()
|
||||
} else {
|
||||
bh.Close()
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cfg.Routing != nil {
|
||||
return &closableRoutedHost{App: app, RoutedHost: rh}, nil
|
||||
}
|
||||
return &closableBasicHost{App: app, BasicHost: bh}, nil
|
||||
}
|
||||
|
||||
func (cfg *Config) addAutoNAT(h *bhost.BasicHost) error {
|
||||
addrF := h.AddrsFactory
|
||||
autonatOpts := []autonat.Option{
|
||||
autonat.UsingAddresses(func() []ma.Multiaddr {
|
||||
return addrF(h.AllAddrs())
|
||||
}),
|
||||
}
|
||||
if !cfg.DisableMetrics {
|
||||
autonatOpts = append(autonatOpts,
|
||||
autonat.WithMetricsTracer(
|
||||
autonat.NewMetricsTracer(autonat.WithRegisterer(cfg.PrometheusRegisterer))))
|
||||
autonatOpts = append(autonatOpts, autonat.WithMetricsTracer(
|
||||
autonat.NewMetricsTracer(autonat.WithRegisterer(cfg.PrometheusRegisterer)),
|
||||
))
|
||||
}
|
||||
if cfg.AutoNATConfig.ThrottleInterval != 0 {
|
||||
autonatOpts = append(autonatOpts,
|
||||
|
@ -408,16 +467,15 @@ func (cfg *Config) NewNode() (host.Host, error) {
|
|||
if cfg.AutoNATConfig.EnableService {
|
||||
autonatPrivKey, _, err := crypto.GenerateEd25519Key(rand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
ps, err := pstoremem.NewPeerstore()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
// Pull out the pieces of the config that we _actually_ care about.
|
||||
// Specifically, don't set up things like autorelay, listeners,
|
||||
// identify, etc.
|
||||
// Specifically, don't set up things like listeners, identify, etc.
|
||||
autoNatCfg := Config{
|
||||
Transports: cfg.Transports,
|
||||
Muxers: cfg.Muxers,
|
||||
|
@ -436,21 +494,40 @@ func (cfg *Config) NewNode() (host.Host, error) {
|
|||
},
|
||||
}
|
||||
|
||||
dialer, err := autoNatCfg.makeSwarm(eventbus.NewBus(), false)
|
||||
fxopts, err := autoNatCfg.addTransports()
|
||||
if err != nil {
|
||||
h.Close()
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
dialerHost := blankhost.NewBlankHost(dialer)
|
||||
if err := autoNatCfg.addTransports(dialerHost); err != nil {
|
||||
dialerHost.Close()
|
||||
h.Close()
|
||||
return nil, err
|
||||
var dialer *swarm.Swarm
|
||||
|
||||
fxopts = append(fxopts,
|
||||
fx.Provide(eventbus.NewBus),
|
||||
fx.Provide(func(lifecycle fx.Lifecycle, b event.Bus) (*swarm.Swarm, error) {
|
||||
lifecycle.Append(fx.Hook{
|
||||
OnStop: func(context.Context) error {
|
||||
return ps.Close()
|
||||
}})
|
||||
var err error
|
||||
dialer, err = autoNatCfg.makeSwarm(b, false)
|
||||
return dialer, err
|
||||
|
||||
}),
|
||||
fx.Provide(func(s *swarm.Swarm) peer.ID { return s.LocalPeer() }),
|
||||
fx.Provide(func() crypto.PrivKey { return autonatPrivKey }),
|
||||
)
|
||||
app := fx.New(fxopts...)
|
||||
if err := app.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
// NOTE: We're dropping the blank host here but that's fine. It
|
||||
// doesn't really _do_ anything and doesn't even need to be
|
||||
// closed (as long as we close the underlying network).
|
||||
autonatOpts = append(autonatOpts, autonat.EnableService(dialerHost.Network()))
|
||||
err = app.Start(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
<-dialer.Done() // The swarm used for autonat has closed, we can cleanup now
|
||||
app.Stop(context.Background())
|
||||
}()
|
||||
autonatOpts = append(autonatOpts, autonat.EnableService(dialer))
|
||||
}
|
||||
if cfg.AutoNATConfig.ForceReachability != nil {
|
||||
autonatOpts = append(autonatOpts, autonat.WithReachability(*cfg.AutoNATConfig.ForceReachability))
|
||||
|
@ -458,25 +535,10 @@ func (cfg *Config) NewNode() (host.Host, error) {
|
|||
|
||||
autonat, err := autonat.New(h, autonatOpts...)
|
||||
if err != nil {
|
||||
h.Close()
|
||||
return nil, fmt.Errorf("cannot enable autorelay; autonat failed to start: %v", err)
|
||||
return fmt.Errorf("cannot enable autorelay; autonat failed to start: %v", err)
|
||||
}
|
||||
h.SetAutoNat(autonat)
|
||||
|
||||
// start the host background tasks
|
||||
h.Start()
|
||||
|
||||
var ho host.Host
|
||||
ho = h
|
||||
if router != nil {
|
||||
ho = routed.Wrap(h, router)
|
||||
}
|
||||
if ar != nil {
|
||||
arh := autorelay.NewAutoRelayHost(ho, ar)
|
||||
arh.Start()
|
||||
ho = arh
|
||||
}
|
||||
return ho, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Option is a libp2p config option that can be given to the libp2p constructor
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
basichost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
||||
routed "github.com/libp2p/go-libp2p/p2p/host/routed"
|
||||
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
type closableBasicHost struct {
|
||||
*fx.App
|
||||
*basichost.BasicHost
|
||||
}
|
||||
|
||||
func (h *closableBasicHost) Close() error {
|
||||
_ = h.App.Stop(context.Background())
|
||||
return h.BasicHost.Close()
|
||||
}
|
||||
|
||||
type closableRoutedHost struct {
|
||||
*fx.App
|
||||
*routed.RoutedHost
|
||||
}
|
||||
|
||||
func (h *closableRoutedHost) Close() error {
|
||||
_ = h.App.Stop(context.Background())
|
||||
return h.RoutedHost.Close()
|
||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
|
@ -12,7 +13,6 @@ import (
|
|||
|
||||
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
"github.com/libp2p/go-libp2p/internal/sha256"
|
||||
)
|
||||
|
||||
// ECDSAPrivateKey is an implementation of an ECDSA private key
|
||||
|
|
|
@ -4,12 +4,10 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
|
@ -122,51 +120,6 @@ func GenerateKeyPairWithReader(typ, bits int, src io.Reader) (PrivKey, PubKey, e
|
|||
}
|
||||
}
|
||||
|
||||
// GenerateEKeyPair returns an ephemeral public key and returns a function that will compute
|
||||
// the shared secret key. Used in the identify module.
|
||||
//
|
||||
// Focuses only on ECDH now, but can be made more general in the future.
|
||||
func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
|
||||
var curve elliptic.Curve
|
||||
|
||||
switch curveName {
|
||||
case "P-256":
|
||||
curve = elliptic.P256()
|
||||
case "P-384":
|
||||
curve = elliptic.P384()
|
||||
case "P-521":
|
||||
curve = elliptic.P521()
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unknown curve name")
|
||||
}
|
||||
|
||||
priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pubKey := elliptic.Marshal(curve, x, y)
|
||||
|
||||
done := func(theirPub []byte) ([]byte, error) {
|
||||
// Verify and unpack node's public key.
|
||||
x, y := elliptic.Unmarshal(curve, theirPub)
|
||||
if x == nil {
|
||||
return nil, fmt.Errorf("malformed public key: %d %v", len(theirPub), theirPub)
|
||||
}
|
||||
|
||||
if !curve.IsOnCurve(x, y) {
|
||||
return nil, errors.New("invalid public key")
|
||||
}
|
||||
|
||||
// Generate shared secret.
|
||||
secret, _ := curve.ScalarMult(x, y, priv)
|
||||
|
||||
return secret.Bytes(), nil
|
||||
}
|
||||
|
||||
return pubKey, done, nil
|
||||
}
|
||||
|
||||
// UnmarshalPublicKey converts a protobuf serialized public key into its
|
||||
// representative object
|
||||
func UnmarshalPublicKey(data []byte) (PubKey, error) {
|
||||
|
|
|
@ -4,13 +4,13 @@ import (
|
|||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
"github.com/libp2p/go-libp2p/internal/sha256"
|
||||
)
|
||||
|
||||
// RsaPrivateKey is a rsa private key
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
|
@ -9,7 +10,6 @@ import (
|
|||
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
|
||||
"github.com/libp2p/go-libp2p/internal/sha256"
|
||||
)
|
||||
|
||||
// Secp256k1PrivateKey is a Secp256k1 private key
|
||||
|
|
|
@ -1,11 +1,40 @@
|
|||
package event
|
||||
|
||||
import "github.com/libp2p/go-libp2p/core/peer"
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
"github.com/libp2p/go-libp2p/core/record"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// EvtPeerIdentificationCompleted is emitted when the initial identification round for a peer is completed.
|
||||
type EvtPeerIdentificationCompleted struct {
|
||||
// Peer is the ID of the peer whose identification succeeded.
|
||||
Peer peer.ID
|
||||
|
||||
// Conn is the connection we identified.
|
||||
Conn network.Conn
|
||||
|
||||
// ListenAddrs is the list of addresses the peer is listening on.
|
||||
ListenAddrs []multiaddr.Multiaddr
|
||||
|
||||
// Protocols is the list of protocols the peer advertised on this connection.
|
||||
Protocols []protocol.ID
|
||||
|
||||
// SignedPeerRecord is the provided signed peer record of the peer. May be nil.
|
||||
SignedPeerRecord *record.Envelope
|
||||
|
||||
// AgentVersion is like a UserAgent string in browsers, or client version in
|
||||
// bittorrent includes the client name and client.
|
||||
AgentVersion string
|
||||
|
||||
// ProtocolVersion is the protocolVersion field in the identify message
|
||||
ProtocolVersion string
|
||||
|
||||
// ObservedAddr is the our side's connection address as observed by the
|
||||
// peer. This is not verified, the peer could return anything here.
|
||||
ObservedAddr multiaddr.Multiaddr
|
||||
}
|
||||
|
||||
// EvtPeerIdentificationFailed is emitted when the initial identification round for a peer failed.
|
||||
|
|
|
@ -13,12 +13,12 @@ var DialPeerTimeout = 60 * time.Second
|
|||
type noDialCtxKey struct{}
|
||||
type dialPeerTimeoutCtxKey struct{}
|
||||
type forceDirectDialCtxKey struct{}
|
||||
type useTransientCtxKey struct{}
|
||||
type allowLimitedConnCtxKey struct{}
|
||||
type simConnectCtxKey struct{ isClient bool }
|
||||
|
||||
var noDial = noDialCtxKey{}
|
||||
var forceDirectDial = forceDirectDialCtxKey{}
|
||||
var useTransient = useTransientCtxKey{}
|
||||
var allowLimitedConn = allowLimitedConnCtxKey{}
|
||||
var simConnectIsServer = simConnectCtxKey{}
|
||||
var simConnectIsClient = simConnectCtxKey{isClient: true}
|
||||
|
||||
|
@ -94,15 +94,35 @@ func WithDialPeerTimeout(ctx context.Context, timeout time.Duration) context.Con
|
|||
return context.WithValue(ctx, dialPeerTimeoutCtxKey{}, timeout)
|
||||
}
|
||||
|
||||
// WithUseTransient constructs a new context with an option that instructs the network
|
||||
// that it is acceptable to use a transient connection when opening a new stream.
|
||||
func WithUseTransient(ctx context.Context, reason string) context.Context {
|
||||
return context.WithValue(ctx, useTransient, reason)
|
||||
// WithAllowLimitedConn constructs a new context with an option that instructs
|
||||
// the network that it is acceptable to use a limited connection when opening a
|
||||
// new stream.
|
||||
func WithAllowLimitedConn(ctx context.Context, reason string) context.Context {
|
||||
return context.WithValue(ctx, allowLimitedConn, reason)
|
||||
}
|
||||
|
||||
// GetUseTransient returns true if the use transient option is set in the context.
|
||||
func GetUseTransient(ctx context.Context) (usetransient bool, reason string) {
|
||||
v := ctx.Value(useTransient)
|
||||
// WithUseTransient constructs a new context with an option that instructs the network
|
||||
// that it is acceptable to use a transient connection when opening a new stream.
|
||||
//
|
||||
// Deprecated: Use WithAllowLimitedConn instead.
|
||||
func WithUseTransient(ctx context.Context, reason string) context.Context {
|
||||
return context.WithValue(ctx, allowLimitedConn, reason)
|
||||
}
|
||||
|
||||
// GetAllowLimitedConn returns true if the allow limited conn option is set in the context.
|
||||
func GetAllowLimitedConn(ctx context.Context) (usetransient bool, reason string) {
|
||||
v := ctx.Value(allowLimitedConn)
|
||||
if v != nil {
|
||||
return true, v.(string)
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
// GetUseTransient returns true if the use transient option is set in the context.
|
||||
//
|
||||
// Deprecated: Use GetAllowLimitedConn instead.
|
||||
func GetUseTransient(ctx context.Context) (usetransient bool, reason string) {
|
||||
v := ctx.Value(allowLimitedConn)
|
||||
if v != nil {
|
||||
return true, v.(string)
|
||||
}
|
||||
|
|
|
@ -22,7 +22,13 @@ var ErrNoConn = errors.New("no usable connection to peer")
|
|||
|
||||
// ErrTransientConn is returned when attempting to open a stream to a peer with only a transient
|
||||
// connection, without specifying the UseTransient option.
|
||||
var ErrTransientConn = errors.New("transient connection to peer")
|
||||
//
|
||||
// Deprecated: Use ErrLimitedConn instead.
|
||||
var ErrTransientConn = ErrLimitedConn
|
||||
|
||||
// ErrLimitedConn is returned when attempting to open a stream to a peer with only a conn
|
||||
// connection, without specifying the AllowLimitedConn option.
|
||||
var ErrLimitedConn = errors.New("limited connection to peer")
|
||||
|
||||
// ErrResourceLimitExceeded is returned when attempting to perform an operation that would
|
||||
// exceed system resource limits.
|
||||
|
|
|
@ -55,16 +55,23 @@ const (
|
|||
// Connected means has an open, live connection to peer
|
||||
Connected
|
||||
|
||||
// Deprecated: CanConnect is deprecated and will be removed in a future release.
|
||||
//
|
||||
// CanConnect means recently connected to peer, terminated gracefully
|
||||
CanConnect
|
||||
|
||||
// Deprecated: CannotConnect is deprecated and will be removed in a future release.
|
||||
//
|
||||
// CannotConnect means recently attempted connecting but failed to connect.
|
||||
// (should signal "made effort, failed")
|
||||
CannotConnect
|
||||
|
||||
// Limited means we have a transient connection to the peer, but aren't fully connected.
|
||||
Limited
|
||||
)
|
||||
|
||||
func (c Connectedness) String() string {
|
||||
str := [...]string{"NotConnected", "Connected", "CanConnect", "CannotConnect"}
|
||||
str := [...]string{"NotConnected", "Connected", "CanConnect", "CannotConnect", "Limited"}
|
||||
if c < 0 || int(c) >= len(str) {
|
||||
return unrecognized
|
||||
}
|
||||
|
@ -111,8 +118,10 @@ type Stats struct {
|
|||
Direction Direction
|
||||
// Opened is the timestamp when this connection was opened.
|
||||
Opened time.Time
|
||||
// Transient indicates that this connection is transient and may be closed soon.
|
||||
Transient bool
|
||||
// Limited indicates that this connection is Limited. It maybe limited by
|
||||
// bytes or time. In practice, this is a connection formed over a circuit v2
|
||||
// relay.
|
||||
Limited bool
|
||||
// Extra stores additional metadata about this connection.
|
||||
Extra map[interface{}]interface{}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,10 @@ var (
|
|||
|
||||
// RecentlyConnectedAddrTTL is used when we recently connected to a peer.
|
||||
// It means that we are reasonably certain of the peer's address.
|
||||
RecentlyConnectedAddrTTL = time.Minute * 30
|
||||
RecentlyConnectedAddrTTL = time.Minute * 15
|
||||
|
||||
// OwnObservedAddrTTL is used for our own external addresses observed by peers.
|
||||
// Deprecated: observed addresses are maintained till we disconnect from the peer which provided it
|
||||
OwnObservedAddrTTL = time.Minute * 30
|
||||
)
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ type Routing interface {
|
|||
ValueStore
|
||||
|
||||
// Bootstrap allows callers to hint to the routing system to get into a
|
||||
// Boostrapped state and remain there. It is not a synchronous call.
|
||||
// Bootstrapped state and remain there. It is not a synchronous call.
|
||||
Bootstrap(context.Context) error
|
||||
|
||||
// TODO expose io.Closer or plain-old Close error
|
||||
|
|
|
@ -27,8 +27,8 @@ import (
|
|||
// Useful when you want to extend, but not replace, the supported transport
|
||||
// security protocols.
|
||||
var DefaultSecurity = ChainOptions(
|
||||
Security(noise.ID, noise.New),
|
||||
Security(tls.ID, tls.New),
|
||||
Security(noise.ID, noise.New),
|
||||
)
|
||||
|
||||
// DefaultMuxers configures libp2p to use the stream connection multiplexers.
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
//go:build go1.21
|
||||
|
||||
// This package use build tags to select between github.com/minio/sha256-simd
|
||||
// for go1.20 and bellow and crypto/sha256 for go1.21 and above.
|
||||
// This is used because a fast SHANI implementation of sha256 is only avaiable
|
||||
// in the std for go1.21 and above. See https://go.dev/issue/50543.
|
||||
// TODO: Once go1.22 releases remove this package and replace all uses
|
||||
// with crypto/sha256 because the two supported version of go will have the fast
|
||||
// implementation.
|
||||
package sha256
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"hash"
|
||||
)
|
||||
|
||||
func Sum256(b []byte) [sha256.Size]byte {
|
||||
return sha256.Sum256(b)
|
||||
}
|
||||
|
||||
func New() hash.Hash {
|
||||
return sha256.New()
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
//go:build !go1.21
|
||||
|
||||
// This package use build tags to select between github.com/minio/sha256-simd
|
||||
// for go1.20 and bellow and crypto/sha256 for go1.21 and above.
|
||||
// This is used because a fast SHANI implementation of sha256 is only avaiable
|
||||
// in the std for go1.21 and above. See https://go.dev/issue/50543.
|
||||
// TODO: Once go1.22 releases remove this package and replace all uses
|
||||
// with crypto/sha256 because the two supported version of go will have the fast
|
||||
// implementation.
|
||||
package sha256
|
||||
|
||||
import (
|
||||
"hash"
|
||||
|
||||
"github.com/minio/sha256-simd"
|
||||
)
|
||||
|
||||
func Sum256(b []byte) [sha256.Size]byte {
|
||||
return sha256.Sum256(b)
|
||||
}
|
||||
|
||||
func New() hash.Hash {
|
||||
return sha256.New()
|
||||
}
|
|
@ -42,13 +42,13 @@ func ChainOptions(opts ...Option) Option {
|
|||
// - If no security transport is provided, the host uses the go-libp2p's noise
|
||||
// and/or tls encrypted transport to encrypt all traffic;
|
||||
//
|
||||
// - If no peer identity is provided, it generates a random RSA 2048 key-pair
|
||||
// - If no peer identity is provided, it generates a random Ed25519 key-pair
|
||||
// and derives a new identity from it;
|
||||
//
|
||||
// - If no peerstore is provided, the host is initialized with an empty
|
||||
// peerstore.
|
||||
//
|
||||
// To stop/shutdown the returned libp2p node, the user needs to cancel the passed context and call `Close` on the returned Host.
|
||||
// To stop/shutdown the returned libp2p node, the user needs to call `Close` on the returned Host.
|
||||
func New(opts ...Option) (host.Host, error) {
|
||||
return NewWithoutDefaults(append(opts, FallbackDefaults)...)
|
||||
}
|
||||
|
|
|
@ -349,7 +349,7 @@ func EnableAutoRelayWithPeerSource(peerSource autorelay.PeerSource, opts ...auto
|
|||
// forcing the local node to believe it is reachable externally.
|
||||
func ForceReachabilityPublic() Option {
|
||||
return func(cfg *Config) error {
|
||||
public := network.Reachability(network.ReachabilityPublic)
|
||||
public := network.ReachabilityPublic
|
||||
cfg.AutoNATConfig.ForceReachability = &public
|
||||
return nil
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ func ForceReachabilityPublic() Option {
|
|||
// forceing the local node to believe it is behind a NAT and not reachable externally.
|
||||
func ForceReachabilityPrivate() Option {
|
||||
return func(cfg *Config) error {
|
||||
private := network.Reachability(network.ReachabilityPrivate)
|
||||
private := network.ReachabilityPrivate
|
||||
cfg.AutoNATConfig.ForceReachability = &private
|
||||
return nil
|
||||
}
|
||||
|
@ -598,3 +598,14 @@ func SwarmOpts(opts ...swarm.Option) Option {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DisableIdentifyAddressDiscovery disables address discovery using peer provided observed addresses
|
||||
// in identify. If you know your public addresses upfront, the recommended way is to use
|
||||
// AddressFactory to provide the external adddress to the host and use this option to disable
|
||||
// discovery from identify.
|
||||
func DisableIdentifyAddressDiscovery() Option {
|
||||
return func(cfg *Config) error {
|
||||
cfg.DisableIdentifyAddressDiscovery = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,14 +82,6 @@ func (c realClock) Now() time.Time {
|
|||
return time.Now()
|
||||
}
|
||||
|
||||
// withClock lets you override the default time.Now() call. Useful for tests.
|
||||
func withClock(c clock) BackoffDiscoveryOption {
|
||||
return func(b *BackoffDiscovery) error {
|
||||
b.clock = c
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type backoffCache struct {
|
||||
// strat is assigned on creation and not written to
|
||||
strat BackoffStrategy
|
||||
|
|
|
@ -431,7 +431,7 @@ func (as *AmbientAutoNAT) getPeerToProbe() peer.ID {
|
|||
func (as *AmbientAutoNAT) Close() error {
|
||||
as.ctxCancel()
|
||||
if as.service != nil {
|
||||
as.service.Disable()
|
||||
return as.service.Close()
|
||||
}
|
||||
<-as.backgroundRunning
|
||||
return nil
|
||||
|
@ -444,7 +444,7 @@ func (s *StaticAutoNAT) Status() network.Reachability {
|
|||
|
||||
func (s *StaticAutoNAT) Close() error {
|
||||
if s.service != nil {
|
||||
s.service.Disable()
|
||||
return s.service.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue