diff --git a/constant/proxy.go b/constant/proxy.go index 17b74c5..4c016c9 100644 --- a/constant/proxy.go +++ b/constant/proxy.go @@ -1,11 +1,12 @@ package constant const ( - TypeAmnezia = "amnezia" - TypeALGeneva = "algeneva" - TypeOutline = "outline" - TypeSamizdat = "samizdat" - TypeWATER = "water" + TypeAmnezia = "amnezia" + TypeALGeneva = "algeneva" + TypeOutline = "outline" + TypeSamizdat = "samizdat" + TypeWATER = "water" + TypeUnbounded = "unbounded" ) const ( diff --git a/go.mod b/go.mod index 45d427e..b5de02a 100644 --- a/go.mod +++ b/go.mod @@ -12,10 +12,12 @@ replace github.com/tetratelabs/wazero => github.com/refraction-networking/wazero require ( github.com/getlantern/algeneva v0.0.0-20250307163401-1824e7b54f52 + github.com/getlantern/broflake v0.0.0-20260215213912-5f68e35de272 github.com/getlantern/geo v0.0.0-20241129152027-2fc88c10f91e github.com/getlantern/lantern-water v0.0.0-20260130212632-d5ea08838250 github.com/getlantern/samizdat v0.0.2 github.com/gobwas/ws v1.4.0 + github.com/pion/transport/v3 v3.0.7 github.com/refraction-networking/water v0.7.1-alpha github.com/sagernet/sing v0.7.18 github.com/sagernet/sing-box v1.12.22 @@ -34,6 +36,43 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) +require ( + github.com/cenkalti/backoff/v5 v5.0.3 // indirect + github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect + github.com/enobufs/go-nats v0.0.1 // indirect + github.com/getlantern/context v0.0.0-20220418194847-3d5e7a086201 // indirect + github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 // indirect + github.com/getlantern/hex v0.0.0-20220104173244-ad7e4b9194dc // indirect + github.com/getlantern/keepcurrent v0.0.0-20221014183517-fcee77376b89 // indirect + github.com/go-stack/stack v1.8.1 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect + github.com/klauspost/pgzip v1.2.5 // indirect + github.com/mholt/archiver/v3 v3.5.1 // indirect + github.com/nwaples/rardecode v1.1.2 // indirect + github.com/onsi/ginkgo/v2 v2.12.0 // indirect + github.com/oschwald/geoip2-golang v1.9.0 // indirect + github.com/oschwald/maxminddb-golang v1.13.1 // indirect + github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect + github.com/pion/dtls/v3 v3.0.6 // indirect + github.com/pion/ice/v4 v4.0.10 // indirect + github.com/pion/mdns/v2 v2.0.7 // indirect + github.com/pion/srtp/v3 v3.0.6 // indirect + github.com/pion/stun/v3 v3.0.0 // indirect + github.com/pion/turn v1.3.7 // indirect + github.com/pion/turn/v4 v4.0.2 // indirect + github.com/pion/webrtc/v4 v4.1.2 // indirect + github.com/quic-go/quic-go v0.51.0 // indirect + github.com/ulikunitz/xz v0.5.10 // indirect + github.com/wlynxg/anet v0.0.5 // indirect + github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect + go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect +) + require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/RoaringBitmap/roaring v1.2.3 // indirect @@ -67,7 +106,6 @@ require ( github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect github.com/caddyserver/certmagic v0.23.0 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect - github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coder/websocket v1.8.13 // indirect github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // indirect @@ -75,20 +113,15 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e // indirect - github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/edsrzf/mmap-go v1.1.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gaissmai/bart v0.11.1 // indirect github.com/gaukas/wazerofs v0.1.0 // indirect - github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // indirect - github.com/getlantern/errors v1.0.1 // indirect - github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 // indirect - github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 // indirect + github.com/getlantern/errors v1.0.4 // indirect github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 // indirect - github.com/getlantern/keepcurrent v0.0.0-20221014183517-fcee77376b89 // indirect - github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f // indirect + github.com/getlantern/ops v0.0.0-20230424193308-26325dfed3cf // indirect github.com/go-chi/chi/v5 v5.2.2 // indirect github.com/go-chi/render v1.0.3 // indirect github.com/go-json-experiment/json v0.0.0-20250103232110-6a9a0fde9288 // indirect @@ -97,14 +130,12 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-stack/stack v1.8.0 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect github.com/goccy/go-yaml v1.17.1 // indirect github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect github.com/gofrs/uuid/v5 v5.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 // indirect @@ -112,7 +143,6 @@ require ( github.com/gorilla/csrf v1.7.3-0.20250123201450-9dd6af1f6d30 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/websocket v1.5.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect github.com/hashicorp/yamux v0.1.2 // indirect github.com/hdevalence/ed25519consensus v0.2.0 // indirect github.com/huandu/xstrings v1.3.2 // indirect @@ -122,7 +152,6 @@ require ( github.com/jsimonetti/rtnetlink v1.4.0 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect - github.com/klauspost/pgzip v1.2.5 // indirect github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a // indirect github.com/libdns/alidns v1.0.5-libdns.v1.beta1 // indirect github.com/libdns/cloudflare v0.2.2-0.20250708034226-c574dccb31a6 // indirect @@ -136,29 +165,25 @@ require ( github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 // indirect github.com/metacubex/utls v1.8.4 // indirect github.com/mholt/acmez/v3 v3.1.2 // indirect - github.com/mholt/archiver/v3 v3.5.1 // indirect github.com/miekg/dns v1.1.67 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mschoch/smat v0.2.0 // indirect - github.com/nwaples/rardecode v1.1.2 // indirect - github.com/oschwald/geoip2-golang v1.9.0 // indirect - github.com/oschwald/maxminddb-golang v1.13.1 // indirect - github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect - github.com/pion/datachannel v1.5.5 // indirect - github.com/pion/dtls/v2 v2.2.7 // indirect + github.com/pion/datachannel v1.5.10 // indirect + github.com/pion/dtls/v2 v2.2.12 // indirect github.com/pion/ice/v2 v2.3.24 // indirect - github.com/pion/interceptor v0.1.25 // indirect - github.com/pion/logging v0.2.2 // indirect + github.com/pion/interceptor v0.1.40 // indirect + github.com/pion/logging v0.2.4 // indirect github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/rtcp v1.2.12 // indirect - github.com/pion/rtp v1.8.5 // indirect - github.com/pion/sctp v1.8.16 // indirect - github.com/pion/sdp/v3 v3.0.9 // indirect + github.com/pion/rtcp v1.2.15 // indirect + github.com/pion/rtp v1.8.19 // indirect + github.com/pion/sctp v1.8.39 // indirect + github.com/pion/sdp/v3 v3.0.14 // 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.4 // indirect + github.com/pion/transport v0.14.1 // indirect + github.com/pion/transport/v2 v2.2.10 // indirect github.com/pion/turn/v2 v2.1.3 // indirect github.com/pion/webrtc/v3 v3.2.40 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -201,20 +226,16 @@ require ( github.com/tevino/abool/v2 v2.1.0 // indirect github.com/tidwall/btree v1.6.0 // indirect github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect - github.com/ulikunitz/xz v0.5.10 // indirect github.com/vishvananda/netns v0.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/zeebo/blake3 v0.2.4 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect - go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect golang.org/x/crypto v0.47.0 // indirect golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect golang.org/x/mod v0.31.0 // indirect @@ -227,7 +248,6 @@ require ( golang.org/x/tools v0.40.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard/windows v0.5.3 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect google.golang.org/grpc v1.78.0 // indirect google.golang.org/protobuf v1.36.11 // indirect diff --git a/go.sum b/go.sum index 06ea5cd..e30d004 100644 --- a/go.sum +++ b/go.sum @@ -149,6 +149,8 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= +github.com/enobufs/go-nats v0.0.1 h1:uzC0mxan4hyGzUFG7cShFmk6c+XYgfoT8yTBgF5CJYw= +github.com/enobufs/go-nats v0.0.1/go.mod h1:ZF0vpSk02ALIMFsHkIO4MHXUN1v3nLZssTaG+fgX/io= github.com/frankban/quicktest v1.9.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= @@ -163,24 +165,31 @@ github.com/gaukas/wazerofs v0.1.0 h1:wIkW1bAxSnpaaVkQ5LOb1tm1BXdVap3eKjJpVWIqt2E github.com/gaukas/wazerofs v0.1.0/go.mod h1:+JECB9Fwt0taPqSgHckG9lmT3tcoVK+9VJozTsq9UlI= github.com/getlantern/algeneva v0.0.0-20250307163401-1824e7b54f52 h1:w2/RqYPw7PbTYfUMS2aToD5DMKLBnQed+fkTEYTKAqQ= github.com/getlantern/algeneva v0.0.0-20250307163401-1824e7b54f52/go.mod h1:PrNR8tMXO26YNs8K9653XCUH7u2Kv4OdfFC3Ke1GsX0= -github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4= +github.com/getlantern/broflake v0.0.0-20260215213912-5f68e35de272 h1:oKungK1zgRUTACFmIulNf7U/KahaIKNK0vubLINhnss= +github.com/getlantern/broflake v0.0.0-20260215213912-5f68e35de272/go.mod h1:hacSrhmDkUK8laEnfOp51e7PAfhFI/Lbie0MH8/uup4= github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY= -github.com/getlantern/errors v1.0.1 h1:XukU2whlh7OdpxnkXhNH9VTLVz0EVPGKDV5K0oWhvzw= +github.com/getlantern/context v0.0.0-20220418194847-3d5e7a086201 h1:oEZYEpZo28Wdx+5FZo4aU7JFXu0WG/4wJWese5reQSA= +github.com/getlantern/context v0.0.0-20220418194847-3d5e7a086201/go.mod h1:Y9WZUHEb+mpra02CbQ/QczLUe6f0Dezxaw5DCJlJQGo= github.com/getlantern/errors v1.0.1/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A= +github.com/getlantern/errors v1.0.4 h1:i2iR1M9GKj4WuingpNqJ+XQEw6i6dnAgKAmLj6ZB3X0= +github.com/getlantern/errors v1.0.4/go.mod h1:/Foq8jtSDGP8GOXzAjeslsC4Ar/3kB+UiQH+WyV4pzY= github.com/getlantern/geo v0.0.0-20241129152027-2fc88c10f91e h1:vpikNz6IzvEoqVYmiK5Uq+lE4TCzvMDqbZdxFbtGK1g= github.com/getlantern/geo v0.0.0-20241129152027-2fc88c10f91e/go.mod h1:RjQ0krF8NTCc5xo2Q1995/vZBnYg33h8svn15do7dLg= github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 h1:NlQedYmPI3pRAXJb+hLVVDGqfvvXGRPV8vp7XOjKAZ0= github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65/go.mod h1:+ZU1h+iOVqWReBpky6d5Y2WL0sF2Llxu+QcxJFs2+OU= -github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0= github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o= +github.com/getlantern/hex v0.0.0-20220104173244-ad7e4b9194dc h1:sue+aeVx7JF5v36H1HfvcGFImLpSD5goj8d+MitovDU= +github.com/getlantern/hex v0.0.0-20220104173244-ad7e4b9194dc/go.mod h1:D9RWpXy/EFPYxiKUURo2TB8UBosbqkiLhttRrZYtvqM= github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc= github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA= github.com/getlantern/keepcurrent v0.0.0-20221014183517-fcee77376b89 h1:gjlTAADW8ZUrIey+u1ZtbVlI91bqI0Bu+GBxvRlBBqo= github.com/getlantern/keepcurrent v0.0.0-20221014183517-fcee77376b89/go.mod h1:EtJEobtQH/HiQsZLyRjlrnq/fu7vfgnTMzhbmUqkZ3M= github.com/getlantern/lantern-water v0.0.0-20260130212632-d5ea08838250 h1:xculJyC6hS0kNSQKWBP1FQbpSVmeJyhUGID804jgKCA= github.com/getlantern/lantern-water v0.0.0-20260130212632-d5ea08838250/go.mod h1:ZpSOrcdJkmb8MvaQn6mxaidxshlyi+RJLUerhW4L5Lo= -github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA= github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= +github.com/getlantern/ops v0.0.0-20220713155959-1315d978fff7/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= +github.com/getlantern/ops v0.0.0-20230424193308-26325dfed3cf h1:q8nsH0Lx9fP8HY6T9rA1zogvOzO9JtbUI5BXkh7wxxI= +github.com/getlantern/ops v0.0.0-20230424193308-26325dfed3cf/go.mod h1:R7HfJVLsnSeqaDWkiUlU+ANBjac4oYmXGrrps8vW7CM= github.com/getlantern/samizdat v0.0.2 h1:PkMu6jsfUz7DLZUH2xh548XfzgPASmq5CajZyUKj/9Y= github.com/getlantern/samizdat v0.0.2/go.mod h1:uEeykQSW2/6rTjfPlj3MTTo59poSHXfAHTGgzYDkbr0= github.com/getlantern/sing v0.7.18-lantern h1:QKGgIUA3LwmKYP/7JlQTRkxj9jnP4cX2Q/B+nd8XEjo= @@ -212,14 +221,18 @@ github.com/go-llsqlite/crawshaw v0.4.0/go.mod h1:/YJdV7uBQaYDE0fwe4z3wwJIZBJxdYz github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= @@ -264,6 +277,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -273,6 +287,8 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 h1:wG8RYIyctLhdFk6Vl1yPGtSRtwGpVkWyZww1OCil2MI= github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806/go.mod h1:Beg6V6zZ3oEn0JuiUQ4wqwuyqqzasOltcoXPtgLbFp4= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -387,7 +403,11 @@ github.com/nwaples/rardecode v1.1.2 h1:Cj0yZY6T1Zx1R7AhTbyGSALm44/Mmq+BAPc4B/p/d github.com/nwaples/rardecode v1.1.2/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI= +github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrzN7IgKZc= github.com/oschwald/geoip2-golang v1.9.0/go.mod h1:BHK6TvDyATVQhKNbQBdrj9eAvuwOMi2zSFXizL3K81Y= @@ -400,50 +420,73 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -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/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/datachannel v1.5.10 h1:ly0Q26K1i6ZkGf42W7D4hQYR90pZwzFOjTq5AuCKk4o= +github.com/pion/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oLo8Rs4Py/M= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/dtls/v3 v3.0.6 h1:7Hkd8WhAJNbRgq9RgdNh1aaWlZlGpYTzdqjy9x9sK2E= +github.com/pion/dtls/v3 v3.0.6/go.mod h1:iJxNQ3Uhn1NZWOMWlLxEEHAN5yX7GyPvvKw04v9bzYU= 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.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc= -github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y= -github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/ice/v4 v4.0.10 h1:P59w1iauC/wPk9PdY8Vjl4fOFL5B+USq1+xbDcN6gT4= +github.com/pion/ice/v4 v4.0.10/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw= +github.com/pion/interceptor v0.1.40 h1:e0BjnPcGpr2CFQgKhrQisBU7V3GXK6wrfYrGYaU6Jq4= +github.com/pion/interceptor v0.1.40/go.mod h1:Z6kqH7M/FYirg3frjGJ21VLSRJGBXB/KqaTIrdqnOic= +github.com/pion/logging v0.2.1/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8= +github.com/pion/logging v0.2.4/go.mod h1:DffhXTKYdNZU+KtJ5pyQDjvOAh/GsNSyv1lbkFbe3so= 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/mdns/v2 v2.0.7 h1:c9kM8ewCgjslaAmicYMFQIde2H9/lrZpjBkN8VwoVtM= +github.com/pion/mdns/v2 v2.0.7/go.mod h1:vAdSYNAT0Jy3Ru0zl2YiW3Rm/fJCwIeM0nToenfOJKA= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= -github.com/pion/rtcp v1.2.12 h1:bKWiX93XKgDZENEXCijvHRU/wRifm6JV5DGcH6twtSM= github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/rtcp v1.2.15 h1:LZQi2JbdipLOj4eBjK4wlVoQWfrZbh3Q6eHtWtJBZBo= +github.com/pion/rtcp v1.2.15/go.mod h1:jlGuAjHMEXwMUHK78RgX0UmEJFV4zUKOFHR7OP+D3D0= github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/rtp v1.8.5 h1:uYzINfaK+9yWs7r537z/Rc1SvT8ILjBcmDOpJcTB+OU= -github.com/pion/rtp v1.8.5/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= -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/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/rtp v1.8.19 h1:jhdO/3XhL/aKm/wARFVmvTfq0lC/CvN1xwYKmduly3c= +github.com/pion/rtp v1.8.19/go.mod h1:bAu2UFKScgzyFqvUKmbvzSdPr+NGbZtv6UB2hesqXBk= +github.com/pion/sctp v1.8.39 h1:PJma40vRHa3UTO3C4MyeJDQ+KIobVYRZQZ0Nt7SjQnE= +github.com/pion/sctp v1.8.39/go.mod h1:cNiLdchXra8fHQwmIoqw0MbLLMs+f7uQ+dGMG2gWebE= +github.com/pion/sdp/v3 v3.0.14 h1:1h7gBr9FhOWH5GjWWY5lcw/U85MtdcibTyt/o6RxRUI= +github.com/pion/sdp/v3 v3.0.14/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E= 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/srtp/v3 v3.0.6 h1:E2gyj1f5X10sB/qILUGIkL4C2CqK269Xq167PbGCc/4= +github.com/pion/srtp/v3 v3.0.6/go.mod h1:BxvziG3v/armJHAaJ87euvkhHqWe9I7iiOy50K2QkhY= +github.com/pion/stun v0.3.1/go.mod h1:xrCld6XM+6GWDZdvjPlLMsTU21rNxnO6UO8XsAvHr/M= +github.com/pion/stun v0.3.2/go.mod h1:xrCld6XM+6GWDZdvjPlLMsTU21rNxnO6UO8XsAvHr/M= 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/stun/v3 v3.0.0 h1:4h1gwhWLWuZWOJIJR9s2ferRO+W3zA/b6ijOI6mKzUw= +github.com/pion/stun/v3 v3.0.0/go.mod h1:HvCN8txt8mwi4FBvS3EmDghW6aQJ24T+y+1TKjB5jyU= +github.com/pion/transport v0.8.6/go.mod h1:nAmRRnn+ArVtsoNuwktvAD+jrjSD7pA+H3iRmZwdUno= +github.com/pion/transport v0.8.8/go.mod h1:lpeSM6KJFejVtZf8k0fgeN7zE73APQpTF83WvA1FVP8= 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.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 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo= github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= 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/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= +github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= +github.com/pion/turn v1.3.5/go.mod h1:zGPB7YYB/HTE9MWn0Sbznz8NtyfeVeanZ834cG/MXu0= +github.com/pion/turn v1.3.7 h1:/nyM2XrlZILD7KKfnh0oYEBTRG5JlbH21ibjluRoCeo= +github.com/pion/turn v1.3.7/go.mod h1:js0LBFqMcKAlaWAXoYqNjefGI7kfJCrkCBfHGuTToXE= github.com/pion/turn/v2 v2.1.3 h1:pYxTVWG2gpC97opdRc5IGsQ1lJ9O/IlNhkzj7MMrGAA= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/turn/v4 v4.0.2 h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps= +github.com/pion/turn/v4 v4.0.2/go.mod h1:pMMKP/ieNAG/fN5cZiN4SDuyKsXtNTr0ccN7IToA1zs= 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/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54= +github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -472,6 +515,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.51.0 h1:K8exxe9zXxeRKxaXxi/GpUqYiTrtdiWP8bo1KFya6Wc= +github.com/quic-go/quic-go v0.51.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/refraction-networking/utls v1.8.2 h1:j4Q1gJj0xngdeH+Ox/qND11aEfhpgoEvV+S9iJ2IdQo= github.com/refraction-networking/utls v1.8.2/go.mod h1:jkSOEkLqn+S/jtpEHPOsVv/4V4EVnelwbMQl4vCWXAM= @@ -551,13 +596,12 @@ github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/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/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e h1:PtWT87weP5LWHEY//SWsYkSO3RWRZo4OSWagh3YD2vQ= @@ -598,6 +642,9 @@ github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zd github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= +github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= @@ -619,6 +666,7 @@ go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.9.0/go.mod h1:np4EoPGzoPs3O67xUVNoPPcmSvsfOxNlNA4F4AC+0Eo= go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0 h1:9y5sHvAxWzft1WQ4BwqcvA+IFVUJ1Ya75mSAUnFEVwE= @@ -629,6 +677,7 @@ go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ7 go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= +go.opentelemetry.io/otel/trace v1.9.0/go.mod h1:2737Q0MuG8q1uILYm2YYVkAyLtOofiTNGg6VODnOiPo= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= diff --git a/option/unbounded.go b/option/unbounded.go new file mode 100644 index 0000000..71c2679 --- /dev/null +++ b/option/unbounded.go @@ -0,0 +1,39 @@ +package option + +import ( + "github.com/sagernet/sing-box/option" +) + +// Note that values which map to time.Duration in Unbounded's options structs are +// represented here as int (which will be converted to seconds). This means you +// can't set a time.Duration of 0, because we can't disambiguate it from an unset +// value. You also can't set any of the other int types to 0. But you probably +// shouldn't be setting any of this stuff to 0! +type UnboundedOutboundOptions struct { + option.DialerOptions + option.ServerOptions + InsecureDoNotVerifyClientCert bool `json:"insecure_do_not_verify_client_cert,omitempty"` + EgressCA string `json:"egress_ca,omitempty"` + EgressServerName string `json:"egress_server_name,omitempty"` + // BroflakeOptions + CTableSize int `json:"c_table_size,omitempty"` + PTableSize int `json:"p_table_size,omitempty"` + BusBufferSz int `json:"bus_buffer_sz,omitempty"` + Netstated string `json:"netstated,omitempty"` + // WebRTCOptions + DiscoverySrv string `json:"discovery_srv,omitempty"` + DiscoveryEndpoint string `json:"discovery_endpoint,omitempty"` + GenesisAddr string `json:"genesis_addr,omitempty"` + NATFailTimeout int `json:"nat_fail_timeout,omitempty"` + STUNBatchSize int `json:"stun_batch_size,omitempty"` + STUNServers []string `json:"stun_servers,omitempty"` + Tag string `json:"tag,omitempty"` + Patience int `json:"patience,omitempty"` + ErrorBackoff int `json:"error_backoff,omitempty"` + ConsumerSessionID string `json:"consumer_session_id,omitempty"` + // EgressOptions + EgressAddr string `json:"egress_addr,omitempty"` + EgressEndpoint string `json:"egress_endpoint,omitempty"` + EgressConnectTimeout int `json:"egress_connect_timeout,omitempty"` + EgressErrorBackoff int `json:"egress_error_backoff,omitempty"` +} diff --git a/protocol/register.go b/protocol/register.go index 1578d0c..19b2a4f 100644 --- a/protocol/register.go +++ b/protocol/register.go @@ -14,6 +14,7 @@ import ( "github.com/getlantern/lantern-box/protocol/group" "github.com/getlantern/lantern-box/protocol/outline" "github.com/getlantern/lantern-box/protocol/samizdat" + "github.com/getlantern/lantern-box/protocol/unbounded" "github.com/getlantern/lantern-box/protocol/water" ) @@ -23,6 +24,8 @@ var supportedProtocols = []string{ "amnezia", "outline", "samizdat", + "unbounded", + "water", // sing-box built-in protocols "http", @@ -75,6 +78,7 @@ func registerOutbounds(registry *outbound.Registry) { outline.RegisterOutbound(registry) samizdat.RegisterOutbound(registry) water.RegisterOutbound(registry) + unbounded.RegisterOutbound(registry) // utility outbounds group.RegisterFallback(registry) diff --git a/protocol/unbounded/net.go b/protocol/unbounded/net.go new file mode 100644 index 0000000..4c48900 --- /dev/null +++ b/protocol/unbounded/net.go @@ -0,0 +1,130 @@ +package unbounded + +import ( + "context" + "net" + + "github.com/pion/transport/v3" + "github.com/pion/transport/v3/stdnet" + + "github.com/sagernet/sing-box/log" + "github.com/sagernet/sing/common/metadata" + N "github.com/sagernet/sing/common/network" +) + +var _ transport.Net = (*rtcNet)(nil) + +// rtcNet is a [transport.Net] implementation that uses a N.Dialer for dialing. +// It wraps the base [stdnet.Net] and overrides the Dial and ListenPacket methods +// to use the DefaultDialer. +type rtcNet struct { + *stdnet.Net + ctx context.Context + dialer N.Dialer + logger log.ContextLogger +} + +type logDialer struct { + d N.Dialer + logger log.ContextLogger +} + +func (d *logDialer) DialContext(ctx context.Context, network string, destination metadata.Socksaddr) (net.Conn, error) { + d.logger.Debug("dialing with sing-box dialer", "network", network, "destination", destination) + return d.d.DialContext(ctx, network, destination) +} + +func (d *logDialer) ListenPacket(ctx context.Context, destination metadata.Socksaddr) (net.PacketConn, error) { + d.logger.Debug("listening with sing-box dialer", "destination", destination) + return d.d.ListenPacket(ctx, destination) +} + +func newRTCNet(ctx context.Context, dialer N.Dialer, logger log.ContextLogger) (*rtcNet, error) { + snet, err := stdnet.NewNet() + if err != nil { + return nil, err + } + return &rtcNet{ + Net: snet, + ctx: ctx, + dialer: &logDialer{dialer, logger}, + logger: logger, + }, nil +} + +func (n *rtcNet) Dial(network string, address string) (net.Conn, error) { + destination := metadata.ParseSocksaddr(address) + return n.dialer.DialContext(n.ctx, network, destination) +} + +func (n *rtcNet) ListenPacket(network string, address string) (net.PacketConn, error) { + destination := metadata.ParseSocksaddr(address) + return n.dialer.ListenPacket(n.ctx, destination) +} + +func (n *rtcNet) DialUDP(network string, laddr *net.UDPAddr, raddr *net.UDPAddr) (transport.UDPConn, error) { + destination := metadata.SocksaddrFromNet(raddr) + conn, err := n.dialer.DialContext(n.ctx, network, destination) + if err != nil { + return nil, err + } + // the DefaultDialer should always return a net.UDPConn + if udpConn, ok := conn.(transport.UDPConn); ok { + return udpConn, nil + } + conn.Close() + return nil, &net.OpError{ + Op: "dial", + Net: network, + Addr: raddr, + Err: net.InvalidAddrError("not a UDP connection"), + } +} + +func (n *rtcNet) DialTCP(network string, laddr *net.TCPAddr, raddr *net.TCPAddr) (transport.TCPConn, error) { + destination := metadata.SocksaddrFromNet(raddr) + conn, err := n.dialer.DialContext(n.ctx, network, destination) + if err != nil { + return nil, err + } + // the DefaultDialer should always return a net.TCPConn + if tcpConn, ok := conn.(transport.TCPConn); ok { + return tcpConn, nil + } + conn.Close() + return nil, &net.OpError{ + Op: "dial", + Net: network, + Addr: raddr, + Err: net.InvalidAddrError("not a TCP connection"), + } +} + +// maybe well implement these later. might be useful +func (n *rtcNet) ResolveIPAddr(network string, address string) (*net.IPAddr, error) { + n.logger.Debug("resolving IP address", "network", network, "address", address) + return n.Net.ResolveIPAddr(network, address) +} + +func (n *rtcNet) ResolveUDPAddr(network string, address string) (*net.UDPAddr, error) { + n.logger.Debug("resolving UDP address", "network", network, "address", address) + return n.Net.ResolveUDPAddr(network, address) +} + +func (n *rtcNet) ResolveTCPAddr(network string, address string) (*net.TCPAddr, error) { + n.logger.Debug("resolving TCP address", "network", network, "address", address) + return n.Net.ResolveTCPAddr(network, address) +} + +func (n *rtcNet) CreateDialer(dialer *net.Dialer) transport.Dialer { + return &rtcDialer{dialer, n} +} + +type rtcDialer struct { + dialer *net.Dialer + net *rtcNet +} + +func (d *rtcDialer) Dial(network, address string) (net.Conn, error) { + return d.dialer.Dial(network, address) +} diff --git a/protocol/unbounded/outbound.go b/protocol/unbounded/outbound.go new file mode 100644 index 0000000..8b6b485 --- /dev/null +++ b/protocol/unbounded/outbound.go @@ -0,0 +1,374 @@ +package unbounded + +import ( + "context" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "fmt" + "log" + "math/big" + mathrand "math/rand" + "net" + "net/http" + "os" + "time" + + UBClientcore "github.com/getlantern/broflake/clientcore" + UBCommon "github.com/getlantern/broflake/common" + "github.com/sagernet/sing-box/adapter" + "github.com/sagernet/sing-box/adapter/outbound" + "github.com/sagernet/sing-box/common/dialer" + singlog "github.com/sagernet/sing-box/log" + "github.com/sagernet/sing/common/logger" + M "github.com/sagernet/sing/common/metadata" + N "github.com/sagernet/sing/common/network" + "github.com/sagernet/sing/common/uot" + + C "github.com/getlantern/lantern-box/constant" + "github.com/getlantern/lantern-box/option" +) + +type logAdapter struct { + singBoxLogger singlog.ContextLogger +} + +func (l logAdapter) Write(p []byte) (int, error) { + l.singBoxLogger.Info(string(p)) + return len(p), nil +} + +func RegisterOutbound(registry *outbound.Registry) { + outbound.Register[option.UnboundedOutboundOptions](registry, C.TypeUnbounded, NewOutbound) +} + +type Outbound struct { + outbound.Adapter + logger logger.ContextLogger + broflakeConn *UBClientcore.BroflakeConn + dial UBClientcore.SOCKS5Dialer + uotClient *uot.Client + ui UBClientcore.UI + ql *UBClientcore.QUICLayer + rtcOpt *UBClientcore.WebRTCOptions + bfOpt *UBClientcore.BroflakeOptions + egOpt *UBClientcore.EgressOptions + tlsConfig *tls.Config +} + +// unboundedDialer adapts the Unbounded SOCKS5 dialer to the N.Dialer interface for uot.Client. +type unboundedDialer struct { + outbound *Outbound +} + +func (d *unboundedDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { + if d.outbound.dial == nil { + return nil, fmt.Errorf("unbounded not ready") + } + return d.outbound.dial(ctx, network, destination.String()) +} + +func (d *unboundedDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { + return nil, os.ErrInvalid +} + +func NewOutbound( + ctx context.Context, + router adapter.Router, + logger singlog.ContextLogger, + tag string, + options option.UnboundedOutboundOptions, +) (adapter.Outbound, error) { + bfOpt := UBClientcore.NewDefaultBroflakeOptions() + if options.CTableSize != 0 { + bfOpt.CTableSize = options.CTableSize + } + + if options.PTableSize != 0 { + bfOpt.PTableSize = options.PTableSize + } + + if options.BusBufferSz != 0 { + bfOpt.BusBufferSz = options.BusBufferSz + } + + if options.Netstated != "" { + bfOpt.Netstated = options.Netstated + } + + rtcOpt := UBClientcore.NewDefaultWebRTCOptions() + if options.DiscoverySrv != "" { + rtcOpt.DiscoverySrv = options.DiscoverySrv + } + + if options.DiscoveryEndpoint != "" { + rtcOpt.Endpoint = options.DiscoveryEndpoint + } + + if options.GenesisAddr != "" { + rtcOpt.GenesisAddr = options.GenesisAddr + } + + if options.NATFailTimeout != 0 { + rtcOpt.NATFailTimeout = time.Duration(options.NATFailTimeout) * time.Second + } + + if options.STUNBatchSize != 0 { + rtcOpt.STUNBatchSize = uint32(options.STUNBatchSize) + } + + servers := make([]string, len(options.STUNServers)) + copy(servers, options.STUNServers) + + rtcOpt.STUNBatch = func(size uint32) (batch []string, err error) { + // At batch time, select N random servers from the list provided in the options + for i := 0; i < int(size) && len(servers) > 0; i++ { + idx := mathrand.Intn(len(servers)) + batch = append(batch, servers[idx]) + servers[idx] = servers[len(servers)-1] + servers = servers[:len(servers)-1] + } + + return batch, nil + } + + if options.Tag != "" { + rtcOpt.Tag = options.Tag + } + + if options.Patience != 0 { + rtcOpt.Patience = time.Duration(options.Patience) * time.Second + } + + if options.ErrorBackoff != 0 { + rtcOpt.ErrorBackoff = time.Duration(options.ErrorBackoff) * time.Second + } + + if options.ConsumerSessionID != "" { + rtcOpt.ConsumerSessionID = options.ConsumerSessionID + } + + // XXX: This sing-box outbound implements a "desktop" type Unbounded peer, and + // desktop peers don't connect to the egress server, so these egress settings + // have no effect. We plumb them through here for the sake of future extensibility. + egOpt := UBClientcore.NewDefaultEgressOptions() + if options.EgressAddr != "" { + egOpt.Addr = options.EgressAddr + } + + if options.EgressEndpoint != "" { + egOpt.Endpoint = options.EgressEndpoint + } + + if options.EgressConnectTimeout != 0 { + egOpt.ConnectTimeout = time.Duration(options.EgressConnectTimeout) * time.Second + } + + if options.EgressErrorBackoff != 0 { + egOpt.ErrorBackoff = time.Duration(options.EgressErrorBackoff) * time.Second + } + + la := logAdapter{ + singBoxLogger: logger, + } + + UBCommon.SetDebugLogger(log.New(la, "", 0)) + + // wrap sing-box dialer in transport.Net for pion/webrtc usage + outboundDialer, err := dialer.New(ctx, options.DialerOptions, options.ServerIsDomain()) + if err != nil { + return nil, err + } + rtcNet, err := newRTCNet(ctx, outboundDialer, logger) + if err != nil { + return nil, err + } + rtcOpt.Net = rtcNet + + dialContext := func(ctx context.Context, network, addr string) (net.Conn, error) { + return outboundDialer.DialContext(ctx, network, M.ParseSocksaddr(addr)) + } + rtcOpt.HTTPClient = &http.Client{ + Transport: &http.Transport{ + Dial: func(network, addr string) (net.Conn, error) { + return dialContext(ctx, network, addr) + }, + DialContext: dialContext, + }, + } + + tlsConfig, err := generateSelfSignedTLSConfig( + options.InsecureDoNotVerifyClientCert, + options.EgressCA, + options.EgressServerName, + ) + + if err != nil { + return nil, fmt.Errorf("generate TLS config: %w", err) + } + + o := &Outbound{ + Adapter: outbound.NewAdapterWithDialerOptions( + C.TypeUnbounded, + tag, + []string{N.NetworkTCP, N.NetworkUDP}, + options.DialerOptions, + ), + logger: logger, + rtcOpt: rtcOpt, + bfOpt: bfOpt, + egOpt: egOpt, + tlsConfig: tlsConfig, + } + + o.uotClient = &uot.Client{ + Dialer: &unboundedDialer{outbound: o}, + Version: uot.Version, + } + + return o, nil +} + +func (h *Outbound) DialContext( + ctx context.Context, + network string, + destination M.Socksaddr, +) (net.Conn, error) { + if h.dial == nil { + return nil, fmt.Errorf("unbounded not ready") + } + + switch N.NetworkName(network) { + case N.NetworkTCP: + h.logger.InfoContext(ctx, "outbound connection to ", destination) + return h.dial(ctx, network, destination.String()) + case N.NetworkUDP: + h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination) + return h.uotClient.DialContext(ctx, network, destination) + } + return nil, fmt.Errorf("unsupported network: %s", network) +} + +// ListenPacket creates a UoT packet connection through the Unbounded proxy. +func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { + ctx, metadata := adapter.ExtendContext(ctx) + metadata.Outbound = h.Tag() + metadata.Destination = destination + h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination) + return h.uotClient.ListenPacket(ctx, destination) +} + +func (h *Outbound) Start(stage adapter.StartStage) error { + if stage == adapter.StartStatePostStart { + BFConn, ui, err := UBClientcore.NewBroflake(h.bfOpt, h.rtcOpt, h.egOpt) + if err != nil { + return err + } + + QUICLayer, err := UBClientcore.NewQUICLayer(BFConn, h.tlsConfig) + if err != nil { + return err + } + + dialer := UBClientcore.CreateSOCKS5Dialer(QUICLayer) + + h.broflakeConn = BFConn + h.dial = dialer + h.ui = ui + h.ql = QUICLayer + + go h.ql.ListenAndMaintainQUICConnection() + } + return nil +} + +func (h *Outbound) Close() error { + if h.ql != nil { + h.ql.Close() + } + + if h.ui != nil { + h.ui.Stop() + } + + return nil +} + +// Reverse TLS, since the Unbounded client is the QUIC server +func generateSelfSignedTLSConfig( + insecureDoNotVerifyClientCert bool, + egressCA string, + egressServerName string, +) (*tls.Config, error) { + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, fmt.Errorf("generate ECDSA key: %w", err) + } + + template := x509.Certificate{SerialNumber: big.NewInt(1)} + certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key) + if err != nil { + return nil, fmt.Errorf("create certificate: %w", err) + } + + keyDER, err := x509.MarshalECPrivateKey(key) + if err != nil { + return nil, fmt.Errorf("marshal ECDSA key: %w", err) + } + keyPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: keyDER}) + certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) + + tlsCert, err := tls.X509KeyPair(certPEM, keyPEM) + if err != nil { + return nil, fmt.Errorf("load key pair: %w", err) + } + + caCertPool := x509.NewCertPool() + + if egressCA != "" { + ok := caCertPool.AppendCertsFromPEM([]byte(egressCA)) + if !ok { + return nil, fmt.Errorf("failed to append egress CA cert") + } + } + + clientAuth := tls.RequireAndVerifyClientCert + + if insecureDoNotVerifyClientCert { + clientAuth = tls.NoClientCert + } + + return &tls.Config{ + Certificates: []tls.Certificate{tlsCert}, + NextProtos: []string{"broflake"}, + ClientAuth: clientAuth, + ClientCAs: caCertPool, + VerifyConnection: func(cs tls.ConnectionState) error { + if len(cs.PeerCertificates) == 0 { + return fmt.Errorf("no egress server client certificate") + } + + cert := cs.PeerCertificates[0] + + // We assume the egress server will present a DNS or IP SAN, so we don't check + // against URI or Email SANs... + + for _, dns := range cert.DNSNames { + if dns == egressServerName { + return nil + } + } + + for _, ip := range cert.IPAddresses { + if ip.String() == egressServerName { + return nil + } + } + + return fmt.Errorf("egress server client SAN not authorized") + }, + }, nil +}