From: Sergey Matveev Date: Thu, 20 Apr 2023 07:55:41 +0000 (+0300) Subject: No Web* X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=refs%2Fheads%2Fbtrtrc2;p=btrtrc.git No Web* --- diff --git a/client.go b/client.go index cc328cc6..302cbc2b 100644 --- a/client.go +++ b/client.go @@ -23,8 +23,8 @@ import ( "github.com/anacrolix/chansync/events" "github.com/anacrolix/dht/v2" "github.com/anacrolix/dht/v2/krpc" - g "github.com/anacrolix/generics" . "github.com/anacrolix/generics" + g "github.com/anacrolix/generics" "github.com/anacrolix/log" "github.com/anacrolix/missinggo/perf" "github.com/anacrolix/missinggo/v2" @@ -34,7 +34,6 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/dustin/go-humanize" gbtree "github.com/google/btree" - "github.com/pion/datachannel" "golang.org/x/time/rate" "github.com/anacrolix/torrent/bencode" @@ -45,9 +44,7 @@ import ( pp "github.com/anacrolix/torrent/peer_protocol" request_strategy "github.com/anacrolix/torrent/request-strategy" "github.com/anacrolix/torrent/storage" - "github.com/anacrolix/torrent/tracker" "github.com/anacrolix/torrent/types/infohash" - "github.com/anacrolix/torrent/webtorrent" ) // Clients contain zero or more Torrents. A Client manages a blocklist, the @@ -84,8 +81,6 @@ type Client struct { dialRateLimiter *rate.Limiter numHalfOpen int - websocketTrackers websocketTrackers - activeAnnounceLimiter limiter.Instance httpClient *http.Client } @@ -286,37 +281,6 @@ func NewClient(cfg *ClientConfig) (cl *Client, err error) { } } - cl.websocketTrackers = websocketTrackers{ - PeerId: cl.peerID, - Logger: cl.logger, - GetAnnounceRequest: func(event tracker.AnnounceEvent, infoHash [20]byte) (tracker.AnnounceRequest, error) { - cl.lock() - defer cl.unlock() - t, ok := cl.torrents[infoHash] - if !ok { - return tracker.AnnounceRequest{}, errors.New("torrent not tracked by client") - } - return t.announceRequest(event), nil - }, - Proxy: cl.config.HTTPProxy, - WebsocketTrackerHttpHeader: cl.config.WebsocketTrackerHttpHeader, - DialContext: cl.config.TrackerDialContext, - OnConn: func(dc datachannel.ReadWriteCloser, dcc webtorrent.DataChannelContext) { - cl.lock() - defer cl.unlock() - t, ok := cl.torrents[dcc.InfoHash] - if !ok { - cl.logger.WithDefaultLevel(log.Warning).Printf( - "got webrtc conn for unloaded torrent with infohash %x", - dcc.InfoHash, - ) - dc.Close() - return - } - go t.onWebRtcConn(dc, dcc) - }, - } - return } diff --git a/cmd/torrent/serve.go b/cmd/torrent/serve.go index bdb15594..cb56f151 100644 --- a/cmd/torrent/serve.go +++ b/cmd/torrent/serve.go @@ -71,8 +71,6 @@ func serve() (cmd bargle.Command) { err = to.MergeSpec(&torrent.TorrentSpec{ InfoBytes: mi.InfoBytes, Trackers: [][]string{{ - `wss://tracker.btorrent.xyz`, - `wss://tracker.openwebtorrent.com`, "http://p4p.arenabg.com:1337/announce", "udp://tracker.opentrackr.org:1337/announce", "udp://tracker.openbittorrent.com:6969/announce", diff --git a/config.go b/config.go index 17641689..f983095a 100644 --- a/config.go +++ b/config.go @@ -117,9 +117,6 @@ type ClientConfig struct { // HttpRequestDirector modifies the request before it's sent. // Useful for adding authentication headers, for example HttpRequestDirector func(*http.Request) error - // WebsocketTrackerHttpHeader returns a custom header to be used when dialing a websocket connection - // to the tracker. Useful for adding authentication headers - WebsocketTrackerHttpHeader func() http.Header // Updated occasionally to when there's been some changes to client // behaviour in case other clients are assuming anything of us. See also // `bep20`. diff --git a/go.mod b/go.mod index 64e1d63a..2a2b26a3 100644 --- a/go.mod +++ b/go.mod @@ -34,12 +34,8 @@ require ( github.com/fsnotify/fsnotify v1.5.4 github.com/google/btree v1.1.2 github.com/google/go-cmp v0.5.9 - github.com/gorilla/websocket v1.5.0 github.com/jessevdk/go-flags v1.5.0 github.com/lispad/go-generics-tools v1.1.0 - github.com/pion/datachannel v1.5.2 - github.com/pion/logging v0.2.2 - github.com/pion/webrtc/v3 v3.1.42 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.12.2 github.com/stretchr/testify v1.8.1 @@ -49,6 +45,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.8.0 go.opentelemetry.io/otel/sdk v1.8.0 go.opentelemetry.io/otel/trace v1.8.0 + golang.org/x/term v0.7.0 golang.org/x/time v0.0.0-20220609170525-579cf78fd858 ) @@ -65,28 +62,12 @@ require ( github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/uuid v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/huandu/xstrings v1.3.2 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mschoch/smat v0.2.0 // indirect - github.com/pion/dtls/v2 v2.2.4 // indirect - github.com/pion/ice/v2 v2.2.6 // indirect - github.com/pion/interceptor v0.1.11 // indirect - github.com/pion/mdns v0.0.5 // indirect - github.com/pion/randutil v0.1.0 // indirect - github.com/pion/rtcp v1.2.9 // indirect - github.com/pion/rtp v1.7.13 // indirect - github.com/pion/sctp v1.8.2 // indirect - github.com/pion/sdp/v3 v3.0.5 // indirect - github.com/pion/srtp/v2 v2.0.9 // indirect - github.com/pion/stun v0.3.5 // indirect - github.com/pion/transport v0.13.1 // indirect - github.com/pion/transport/v2 v2.0.0 // indirect - github.com/pion/turn/v2 v2.0.8 // indirect - github.com/pion/udp v0.1.4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.35.0 // indirect @@ -97,11 +78,10 @@ require ( go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.8.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.8.0 // indirect go.opentelemetry.io/proto/otlp v0.18.0 // indirect - golang.org/x/crypto v0.5.0 // indirect golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d // indirect golang.org/x/net v0.7.0 // indirect golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect - golang.org/x/sys v0.5.0 // indirect + golang.org/x/sys v0.7.0 // indirect golang.org/x/text v0.7.0 // indirect golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect diff --git a/go.sum b/go.sum index aef4f0ee..d4b2c7d7 100644 --- a/go.sum +++ b/go.sum @@ -190,7 +190,6 @@ github.com/frankban/quicktest v1.9.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9 github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -217,7 +216,6 @@ github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV 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-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -281,8 +279,6 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -291,8 +287,6 @@ github.com/gopherjs/gopherjs v0.0.0-20190309154008-847fc94819f9/go.mod h1:wJfORR github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -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/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= @@ -348,63 +342,12 @@ github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 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 v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pion/datachannel v1.5.2 h1:piB93s8LGmbECrpO84DnkIVWasRMk3IimbcXkTQLE6E= -github.com/pion/datachannel v1.5.2/go.mod h1:FTGQWaHrdCwIJ1rw6xBIfZVkslikjShim5yr05XFuCQ= -github.com/pion/dtls/v2 v2.1.3/go.mod h1:o6+WvyLDAlXF7YiPB/RlskRoeK+/JtuaZa5emwQcWus= -github.com/pion/dtls/v2 v2.1.5/go.mod h1:BqCE7xPZbPSubGasRoDFJeTsyJtdD1FanJYL0JGheqY= -github.com/pion/dtls/v2 v2.2.4 h1:YSfYwDQgrxMYXLBc/m7PFY5BVtWlNm/DN4qoU2CbcWg= -github.com/pion/dtls/v2 v2.2.4/go.mod h1:WGKfxqhrddne4Kg3p11FUMJrynkOY4lb25zHNO49wuw= -github.com/pion/ice/v2 v2.2.6 h1:R/vaLlI1J2gCx141L5PEwtuGAGcyS6e7E0hDeJFq5Ig= -github.com/pion/ice/v2 v2.2.6/go.mod h1:SWuHiOGP17lGromHTFadUe1EuPgFh/oCU6FCMZHooVE= -github.com/pion/interceptor v0.1.11 h1:00U6OlqxA3FFB50HSg25J/8cWi7P6FbSzw4eFn24Bvs= -github.com/pion/interceptor v0.1.11/go.mod h1:tbtKjZY14awXd7Bq0mmWvgtHB5MDaRN7HV3OZ/uy7s8= -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.5 h1:Q2oj/JB3NqfzY9xGZ1fPzZzK7sDSD8rZPOvcIQ10BCw= -github.com/pion/mdns v0.0.5/go.mod h1:UgssrvdD3mxpi8tMxAXbsppL3vJ4Jipw1mTCW+al01g= -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.9 h1:1ujStwg++IOLIEoOiIQ2s+qBuJ1VN81KW+9pMPsif+U= -github.com/pion/rtcp v1.2.9/go.mod h1:qVPhiCzAm4D/rxb6XzKeyZiQK69yJpbUDJSF7TgrqNo= -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/sctp v1.8.0/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s= -github.com/pion/sctp v1.8.2 h1:yBBCIrUMJ4yFICL3RIvR4eh/H2BTTvlligmSTy+3kiA= -github.com/pion/sctp v1.8.2/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s= -github.com/pion/sdp/v3 v3.0.5 h1:ouvI7IgGl+V4CrqskVtr3AaTrPvPisEOxwgpdktctkU= -github.com/pion/sdp/v3 v3.0.5/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= -github.com/pion/srtp/v2 v2.0.9 h1:JJq3jClmDFBPX/F5roEb0U19jSU7eUhyDqR/NZ34EKQ= -github.com/pion/srtp/v2 v2.0.9/go.mod h1:5TtM9yw6lsH0ppNCehB/EjEUli7VkUgKSPJqWVqbhQ4= -github.com/pion/stun v0.3.5 h1:uLUCBCkQby4S1cf6CGuR9QrVOKcvUwFeemaC865QHDg= -github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2UA= -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/go.mod h1:yxm9uXpK9bpBBWkITk13cLo1y5/ur5VQpG22ny6EP7g= -github.com/pion/transport v0.13.1 h1:/UH5yLeQtwm2VZIPjxwnNFxjS4DFhyLfS4GlfuKUzfA= -github.com/pion/transport v0.13.1/go.mod h1:EBxbqzyv+ZrmDb82XswEE0BjfQFtuw1Nu6sjnjWCsGg= -github.com/pion/transport/v2 v2.0.0 h1:bsMYyqHCbkvHwj+eNCFBuxtlKndKfyGI2vaQmM3fIE4= -github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= -github.com/pion/turn/v2 v2.0.8 h1:KEstL92OUN3k5k8qxsXHpr7WWfrdp7iJZHx99ud8muw= -github.com/pion/turn/v2 v2.0.8/go.mod h1:+y7xl719J8bAEVpSXBXvTxStjJv3hbz9YFflvkpcGPw= -github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M= -github.com/pion/udp v0.1.4 h1:OowsTmu1Od3sD6i3fQUJxJn2fEvJO6L1TidgadtbTI8= -github.com/pion/udp v0.1.4/go.mod h1:G8LDo56HsFwC24LIcnT4YIDU5qcB6NepqqjP0keL2us= -github.com/pion/webrtc/v3 v3.1.42 h1:wJEQFIXVanptnQcHOLTuIo4AtGB2+mG2x4OhIhnITOA= -github.com/pion/webrtc/v3 v3.1.42/go.mod h1:ffD9DulDrPxyWvDPUIPAOSAWx9GUlOExiJPf7cCcMLA= 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= @@ -456,7 +399,6 @@ github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 h1:Lt9DzQALzHoDwMBGJ6v github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA= github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8= github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -475,7 +417,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -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= @@ -493,8 +434,6 @@ github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPy github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -526,12 +465,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -564,7 +497,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -592,28 +524,15 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220531201128-c960675eff93/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.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -632,7 +551,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -650,10 +568,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -677,7 +592,6 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -689,18 +603,12 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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-20220608164250-635b8c9b7f68/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.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= 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= @@ -709,8 +617,6 @@ golang.org/x/text v0.3.3/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.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -760,8 +666,6 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/torrent.go b/torrent.go index 637a9897..b15b9803 100644 --- a/torrent.go +++ b/torrent.go @@ -3,7 +3,6 @@ package torrent import ( "bytes" "container/heap" - "context" "crypto/sha1" "errors" "fmt" @@ -31,7 +30,6 @@ import ( "github.com/anacrolix/multiless" "github.com/anacrolix/sync" "github.com/davecgh/go-spew/spew" - "github.com/pion/datachannel" "github.com/anacrolix/torrent/bencode" "github.com/anacrolix/torrent/common" @@ -43,7 +41,6 @@ import ( "github.com/anacrolix/torrent/tracker" typedRoaring "github.com/anacrolix/torrent/typed-roaring" "github.com/anacrolix/torrent/webseed" - "github.com/anacrolix/torrent/webtorrent" ) // Maintains state of torrent within a Client. Many methods should not be called before the info is @@ -1574,52 +1571,6 @@ func (t *Torrent) seeding() bool { return true } -func (t *Torrent) onWebRtcConn( - c datachannel.ReadWriteCloser, - dcc webtorrent.DataChannelContext, -) { - defer c.Close() - netConn := webrtcNetConn{ - ReadWriteCloser: c, - DataChannelContext: dcc, - } - peerRemoteAddr := netConn.RemoteAddr() - //t.logger.Levelf(log.Critical, "onWebRtcConn remote addr: %v", peerRemoteAddr) - if t.cl.badPeerAddr(peerRemoteAddr) { - return - } - localAddrIpPort := missinggo.IpPortFromNetAddr(netConn.LocalAddr()) - pc, err := t.cl.initiateProtocolHandshakes( - context.Background(), - netConn, - t, - false, - newConnectionOpts{ - outgoing: dcc.LocalOffered, - remoteAddr: peerRemoteAddr, - localPublicAddr: localAddrIpPort, - network: webrtcNetwork, - connString: fmt.Sprintf("webrtc offer_id %x: %v", dcc.OfferId, regularNetConnPeerConnConnString(netConn)), - }, - ) - if err != nil { - t.logger.WithDefaultLevel(log.Error).Printf("error in handshaking webrtc connection: %v", err) - return - } - if dcc.LocalOffered { - pc.Discovery = PeerSourceTracker - } else { - pc.Discovery = PeerSourceIncoming - } - pc.conn.SetWriteDeadline(time.Time{}) - t.cl.lock() - defer t.cl.unlock() - err = t.cl.runHandshookConn(pc, t) - if err != nil { - t.logger.WithDefaultLevel(log.Debug).Printf("error running handshook webrtc conn: %v", err) - } -} - func (t *Torrent) logRunHandshookConn(pc *PeerConn, logAll bool, level log.Level) { err := t.cl.runHandshookConn(pc, t) if err != nil || logAll { @@ -1631,24 +1582,6 @@ func (t *Torrent) runHandshookConnLoggingErr(pc *PeerConn) { t.logRunHandshookConn(pc, false, log.Debug) } -func (t *Torrent) startWebsocketAnnouncer(u url.URL) torrentTrackerAnnouncer { - wtc, release := t.cl.websocketTrackers.Get(u.String(), t.infoHash) - // This needs to run before the Torrent is dropped from the Client, to prevent a new webtorrent.TrackerClient for - // the same info hash before the old one is cleaned up. - t.onClose = append(t.onClose, release) - wst := websocketTrackerStatus{u, wtc} - go func() { - err := wtc.Announce(tracker.Started, t.infoHash) - if err != nil { - t.logger.WithDefaultLevel(log.Warning).Printf( - "error in initial announce to %q: %v", - u.String(), err, - ) - } - }() - return wst -} - func (t *Torrent) startScrapingTracker(_url string) { if _url == "" { return @@ -1674,11 +1607,6 @@ func (t *Torrent) startScrapingTracker(_url string) { } sl := func() torrentTrackerAnnouncer { switch u.Scheme { - case "ws", "wss": - if t.cl.config.DisableWebtorrent { - return nil - } - return t.startWebsocketAnnouncer(*u) case "udp4": if t.cl.config.DisableIPv4Peers || t.cl.config.DisableIPv4 { return nil diff --git a/webrtc.go b/webrtc.go deleted file mode 100644 index ca4f80fb..00000000 --- a/webrtc.go +++ /dev/null @@ -1,85 +0,0 @@ -package torrent - -import ( - "net" - "strconv" - "time" - - "github.com/pion/datachannel" - "github.com/pion/webrtc/v3" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" - - "github.com/anacrolix/torrent/webtorrent" -) - -const webrtcNetwork = "webrtc" - -type webrtcNetConn struct { - datachannel.ReadWriteCloser - webtorrent.DataChannelContext -} - -type webrtcNetAddr struct { - *webrtc.ICECandidate -} - -var _ net.Addr = webrtcNetAddr{} - -func (webrtcNetAddr) Network() string { - // Now that we have the ICE candidate, we can tell if it's over udp or tcp. But should we use - // that for the network? - return webrtcNetwork -} - -func (me webrtcNetAddr) String() string { - return net.JoinHostPort(me.Address, strconv.FormatUint(uint64(me.Port), 10)) -} - -func (me webrtcNetConn) LocalAddr() net.Addr { - // I'm not sure if this evolves over time. It might also be unavailable if the PeerConnection is - // closed or closes itself. The same concern applies to RemoteAddr. - pair, err := me.DataChannelContext.GetSelectedIceCandidatePair() - if err != nil { - panic(err) - } - return webrtcNetAddr{pair.Local} -} - -func (me webrtcNetConn) RemoteAddr() net.Addr { - // See comments on LocalAddr. - pair, err := me.DataChannelContext.GetSelectedIceCandidatePair() - if err != nil { - panic(err) - } - return webrtcNetAddr{pair.Remote} -} - -// Do we need these for WebRTC connections exposed as net.Conns? Can we set them somewhere inside -// PeerConnection or on the channel or some transport? - -func (w webrtcNetConn) SetDeadline(t time.Time) error { - w.Span.AddEvent("SetDeadline", trace.WithAttributes(attribute.String("time", t.String()))) - return nil -} - -func (w webrtcNetConn) SetReadDeadline(t time.Time) error { - w.Span.AddEvent("SetReadDeadline", trace.WithAttributes(attribute.String("time", t.String()))) - return nil -} - -func (w webrtcNetConn) SetWriteDeadline(t time.Time) error { - w.Span.AddEvent("SetWriteDeadline", trace.WithAttributes(attribute.String("time", t.String()))) - return nil -} - -func (w webrtcNetConn) Read(b []byte) (n int, err error) { - _, span := otel.Tracer(tracerName).Start(w.Context, "Read") - defer span.End() - span.SetAttributes(attribute.Int("buf_len", len(b))) - n, err = w.ReadWriteCloser.Read(b) - span.RecordError(err) - span.SetAttributes(attribute.Int("bytes_read", n)) - return -} diff --git a/webtorrent/LICENSE b/webtorrent/LICENSE deleted file mode 100644 index 99d4f266..00000000 --- a/webtorrent/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Michiel De Backker - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/webtorrent/fuzz_test.go b/webtorrent/fuzz_test.go deleted file mode 100644 index 14638fa2..00000000 --- a/webtorrent/fuzz_test.go +++ /dev/null @@ -1,31 +0,0 @@ -//go:build go1.18 -// +build go1.18 - -package webtorrent - -import ( - "encoding/json" - "testing" - - qt "github.com/frankban/quicktest" -) - -func FuzzJsonBinaryStrings(f *testing.F) { - f.Fuzz(func(t *testing.T, in []byte) { - jsonBytes, err := json.Marshal(binaryToJsonString(in)) - if err != nil { - t.Fatal(err) - } - // t.Logf("%q", jsonBytes) - var jsonStr string - err = json.Unmarshal(jsonBytes, &jsonStr) - if err != nil { - t.Fatal(err) - } - // t.Logf("%q", jsonStr) - c := qt.New(t) - out, err := decodeJsonByteString(jsonStr, []byte{}) - c.Assert(err, qt.IsNil) - c.Assert(out, qt.DeepEquals, in) - }) -} diff --git a/webtorrent/otel.go b/webtorrent/otel.go deleted file mode 100644 index 2c099642..00000000 --- a/webtorrent/otel.go +++ /dev/null @@ -1,6 +0,0 @@ -package webtorrent - -const ( - tracerName = "anacrolix.torrent.webtorrent" - webrtcConnTypeKey = "webtorrent.webrtc.conn.type" -) diff --git a/webtorrent/setting-engine.go b/webtorrent/setting-engine.go deleted file mode 100644 index a84ee020..00000000 --- a/webtorrent/setting-engine.go +++ /dev/null @@ -1,24 +0,0 @@ -// These build constraints are copied from webrtc's settingengine.go. -//go:build !js -// +build !js - -package webtorrent - -import ( - "io" - - "github.com/pion/logging" - "github.com/pion/webrtc/v3" -) - -var s = webrtc.SettingEngine{ - // This could probably be done with better integration into anacrolix/log, but I'm not sure if - // it's worth the effort. - LoggerFactory: discardLoggerFactory{}, -} - -type discardLoggerFactory struct{} - -func (discardLoggerFactory) NewLogger(scope string) logging.LeveledLogger { - return logging.NewDefaultLeveledLoggerForScope(scope, logging.LogLevelInfo, io.Discard) -} diff --git a/webtorrent/setting-engine_js.go b/webtorrent/setting-engine_js.go deleted file mode 100644 index ea42d11a..00000000 --- a/webtorrent/setting-engine_js.go +++ /dev/null @@ -1,13 +0,0 @@ -// These build constraints are copied from webrtc's settingengine_js.go. -//go:build js && wasm -// +build js,wasm - -package webtorrent - -import ( - "github.com/pion/webrtc/v3" -) - -// I'm not sure what to do for logging for JS. See -// https://gophers.slack.com/archives/CAK2124AG/p1649651943947579. -var s = webrtc.SettingEngine{} diff --git a/webtorrent/testdata/fuzz/FuzzJsonBinaryStrings/195b11403204772a785dfc25a6f37ba920daf479f86bcfbbb880cd06cbb2ecf8 b/webtorrent/testdata/fuzz/FuzzJsonBinaryStrings/195b11403204772a785dfc25a6f37ba920daf479f86bcfbbb880cd06cbb2ecf8 deleted file mode 100644 index 9afa08b6..00000000 --- a/webtorrent/testdata/fuzz/FuzzJsonBinaryStrings/195b11403204772a785dfc25a6f37ba920daf479f86bcfbbb880cd06cbb2ecf8 +++ /dev/null @@ -1,2 +0,0 @@ -go test fuzz v1 -[]byte("\x93") diff --git a/webtorrent/testdata/fuzz/FuzzJsonBinaryStrings/582528ddfad69eb57775199a43e0f9fd5c94bba343ce7bb6724d4ebafe311ed4 b/webtorrent/testdata/fuzz/FuzzJsonBinaryStrings/582528ddfad69eb57775199a43e0f9fd5c94bba343ce7bb6724d4ebafe311ed4 deleted file mode 100644 index a96f5599..00000000 --- a/webtorrent/testdata/fuzz/FuzzJsonBinaryStrings/582528ddfad69eb57775199a43e0f9fd5c94bba343ce7bb6724d4ebafe311ed4 +++ /dev/null @@ -1,2 +0,0 @@ -go test fuzz v1 -[]byte("0") diff --git a/webtorrent/testdata/fuzz/FuzzJsonBinaryStrings/caf81e9797b19c76c1fc4dbf537d4d81f389524539f402d13aa01f93a65ac7e9 b/webtorrent/testdata/fuzz/FuzzJsonBinaryStrings/caf81e9797b19c76c1fc4dbf537d4d81f389524539f402d13aa01f93a65ac7e9 deleted file mode 100644 index 67322c70..00000000 --- a/webtorrent/testdata/fuzz/FuzzJsonBinaryStrings/caf81e9797b19c76c1fc4dbf537d4d81f389524539f402d13aa01f93a65ac7e9 +++ /dev/null @@ -1,2 +0,0 @@ -go test fuzz v1 -[]byte("") diff --git a/webtorrent/tracker-client.go b/webtorrent/tracker-client.go deleted file mode 100644 index 30a35be7..00000000 --- a/webtorrent/tracker-client.go +++ /dev/null @@ -1,395 +0,0 @@ -package webtorrent - -import ( - "context" - "crypto/rand" - "encoding/json" - "fmt" - "net/http" - "sync" - "time" - - g "github.com/anacrolix/generics" - "github.com/anacrolix/log" - "github.com/gorilla/websocket" - "github.com/pion/datachannel" - "github.com/pion/webrtc/v3" - "go.opentelemetry.io/otel/trace" - - "github.com/anacrolix/torrent/tracker" -) - -type TrackerClientStats struct { - Dials int64 - ConvertedInboundConns int64 - ConvertedOutboundConns int64 -} - -// Client represents the webtorrent client -type TrackerClient struct { - Url string - GetAnnounceRequest func(_ tracker.AnnounceEvent, infoHash [20]byte) (tracker.AnnounceRequest, error) - PeerId [20]byte - OnConn onDataChannelOpen - Logger log.Logger - Dialer *websocket.Dialer - - mu sync.Mutex - cond sync.Cond - outboundOffers map[string]outboundOfferValue // OfferID to outboundOfferValue - wsConn *websocket.Conn - closed bool - stats TrackerClientStats - pingTicker *time.Ticker - - WebsocketTrackerHttpHeader func() http.Header -} - -func (me *TrackerClient) Stats() TrackerClientStats { - me.mu.Lock() - defer me.mu.Unlock() - return me.stats -} - -func (me *TrackerClient) peerIdBinary() string { - return binaryToJsonString(me.PeerId[:]) -} - -type outboundOffer struct { - offerId string - outboundOfferValue -} - -// outboundOfferValue represents an outstanding offer. -type outboundOfferValue struct { - originalOffer webrtc.SessionDescription - peerConnection *wrappedPeerConnection - infoHash [20]byte - dataChannel *webrtc.DataChannel -} - -type DataChannelContext struct { - OfferId string - LocalOffered bool - InfoHash [20]byte - // This is private as some methods might not be appropriate with data channel context. - peerConnection *wrappedPeerConnection - Span trace.Span - Context context.Context -} - -func (me *DataChannelContext) GetSelectedIceCandidatePair() (*webrtc.ICECandidatePair, error) { - return me.peerConnection.SCTP().Transport().ICETransport().GetSelectedCandidatePair() -} - -type onDataChannelOpen func(_ datachannel.ReadWriteCloser, dcc DataChannelContext) - -func (tc *TrackerClient) doWebsocket() error { - metrics.Add("websocket dials", 1) - tc.mu.Lock() - tc.stats.Dials++ - tc.mu.Unlock() - - var header http.Header - if tc.WebsocketTrackerHttpHeader != nil { - header = tc.WebsocketTrackerHttpHeader() - } - - c, _, err := tc.Dialer.Dial(tc.Url, header) - if err != nil { - return fmt.Errorf("dialing tracker: %w", err) - } - defer c.Close() - tc.Logger.WithDefaultLevel(log.Info).Printf("connected") - tc.mu.Lock() - tc.wsConn = c - tc.cond.Broadcast() - tc.mu.Unlock() - tc.announceOffers() - closeChan := make(chan struct{}) - go func() { - for { - select { - case <-tc.pingTicker.C: - tc.mu.Lock() - err := c.WriteMessage(websocket.PingMessage, []byte{}) - tc.mu.Unlock() - if err != nil { - return - } - case <-closeChan: - return - - } - } - }() - err = tc.trackerReadLoop(tc.wsConn) - close(closeChan) - tc.mu.Lock() - c.Close() - tc.mu.Unlock() - return err -} - -// Finishes initialization and spawns the run routine, calling onStop when it completes with the -// result. We don't let the caller just spawn the runner directly, since then we can race against -// .Close to finish initialization. -func (tc *TrackerClient) Start(onStop func(error)) { - tc.pingTicker = time.NewTicker(60 * time.Second) - tc.cond.L = &tc.mu - go func() { - onStop(tc.run()) - }() -} - -func (tc *TrackerClient) run() error { - tc.mu.Lock() - for !tc.closed { - tc.mu.Unlock() - err := tc.doWebsocket() - level := log.Info - tc.mu.Lock() - if tc.closed { - level = log.Debug - } - tc.mu.Unlock() - tc.Logger.WithDefaultLevel(level).Printf("websocket instance ended: %v", err) - time.Sleep(time.Minute) - tc.mu.Lock() - } - tc.mu.Unlock() - return nil -} - -func (tc *TrackerClient) Close() error { - tc.mu.Lock() - tc.closed = true - if tc.wsConn != nil { - tc.wsConn.Close() - } - tc.closeUnusedOffers() - tc.pingTicker.Stop() - tc.mu.Unlock() - tc.cond.Broadcast() - return nil -} - -func (tc *TrackerClient) announceOffers() { - // tc.Announce grabs a lock on tc.outboundOffers. It also handles the case where outboundOffers - // is nil. Take ownership of outboundOffers here. - tc.mu.Lock() - offers := tc.outboundOffers - tc.outboundOffers = nil - tc.mu.Unlock() - - if offers == nil { - return - } - - // Iterate over our locally-owned offers, close any existing "invalid" ones from before the - // socket reconnected, reannounce the infohash, adding it back into the tc.outboundOffers. - tc.Logger.WithDefaultLevel(log.Info).Printf("reannouncing %d infohashes after restart", len(offers)) - for _, offer := range offers { - // TODO: Capture the errors? Are we even in a position to do anything with them? - offer.peerConnection.Close() - // Use goroutine here to allow read loop to start and ensure the buffer drains. - go tc.Announce(tracker.Started, offer.infoHash) - } -} - -func (tc *TrackerClient) closeUnusedOffers() { - for _, offer := range tc.outboundOffers { - offer.peerConnection.Close() - offer.dataChannel.Close() - } - tc.outboundOffers = nil -} - -func (tc *TrackerClient) CloseOffersForInfohash(infoHash [20]byte) { - tc.mu.Lock() - defer tc.mu.Unlock() - for key, offer := range tc.outboundOffers { - if offer.infoHash == infoHash { - offer.peerConnection.Close() - delete(tc.outboundOffers, key) - } - } -} - -func (tc *TrackerClient) Announce(event tracker.AnnounceEvent, infoHash [20]byte) error { - metrics.Add("outbound announces", 1) - if event == tracker.Stopped { - return tc.announce(event, infoHash, nil) - } - var randOfferId [20]byte - _, err := rand.Read(randOfferId[:]) - if err != nil { - return fmt.Errorf("generating offer_id bytes: %w", err) - } - offerIDBinary := binaryToJsonString(randOfferId[:]) - - pc, dc, offer, err := tc.newOffer(tc.Logger, offerIDBinary, infoHash) - if err != nil { - return fmt.Errorf("creating offer: %w", err) - } - - err = tc.announce(event, infoHash, []outboundOffer{ - { - offerId: offerIDBinary, - outboundOfferValue: outboundOfferValue{ - originalOffer: offer, - peerConnection: pc, - infoHash: infoHash, - dataChannel: dc, - }, - }, - }) - if err != nil { - dc.Close() - pc.Close() - } - return err -} - -func (tc *TrackerClient) announce(event tracker.AnnounceEvent, infoHash [20]byte, offers []outboundOffer) error { - request, err := tc.GetAnnounceRequest(event, infoHash) - if err != nil { - return fmt.Errorf("getting announce parameters: %w", err) - } - - req := AnnounceRequest{ - Numwant: len(offers), - Uploaded: request.Uploaded, - Downloaded: request.Downloaded, - Left: request.Left, - Event: request.Event.String(), - Action: "announce", - InfoHash: binaryToJsonString(infoHash[:]), - PeerID: tc.peerIdBinary(), - } - for _, offer := range offers { - req.Offers = append(req.Offers, Offer{ - OfferID: offer.offerId, - Offer: offer.originalOffer, - }) - } - - data, err := json.Marshal(req) - if err != nil { - return fmt.Errorf("marshalling request: %w", err) - } - - tc.mu.Lock() - defer tc.mu.Unlock() - err = tc.writeMessage(data) - if err != nil { - return fmt.Errorf("write AnnounceRequest: %w", err) - } - for _, offer := range offers { - g.MakeMapIfNilAndSet(&tc.outboundOffers, offer.offerId, offer.outboundOfferValue) - } - return nil -} - -func (tc *TrackerClient) writeMessage(data []byte) error { - for tc.wsConn == nil { - if tc.closed { - return fmt.Errorf("%T closed", tc) - } - tc.cond.Wait() - } - return tc.wsConn.WriteMessage(websocket.TextMessage, data) -} - -func (tc *TrackerClient) trackerReadLoop(tracker *websocket.Conn) error { - for { - _, message, err := tracker.ReadMessage() - if err != nil { - return fmt.Errorf("read message error: %w", err) - } - // tc.Logger.WithDefaultLevel(log.Debug).Printf("received message from tracker: %q", message) - - var ar AnnounceResponse - if err := json.Unmarshal(message, &ar); err != nil { - tc.Logger.WithDefaultLevel(log.Warning).Printf("error unmarshalling announce response: %v", err) - continue - } - switch { - case ar.Offer != nil: - ih, err := jsonStringToInfoHash(ar.InfoHash) - if err != nil { - tc.Logger.WithDefaultLevel(log.Warning).Printf("error decoding info_hash in offer: %v", err) - break - } - err = tc.handleOffer(offerContext{ - SessDesc: *ar.Offer, - Id: ar.OfferID, - InfoHash: ih, - }, ar.PeerID) - if err != nil { - tc.Logger.Levelf(log.Error, "handling offer for infohash %x: %v", ih, err) - } - case ar.Answer != nil: - tc.handleAnswer(ar.OfferID, *ar.Answer) - default: - tc.Logger.Levelf(log.Warning, "unhandled announce response %q", message) - } - } -} - -type offerContext struct { - SessDesc webrtc.SessionDescription - Id string - InfoHash [20]byte -} - -func (tc *TrackerClient) handleOffer( - offerContext offerContext, - peerId string, -) error { - peerConnection, answer, err := tc.newAnsweringPeerConnection(offerContext) - if err != nil { - return fmt.Errorf("creating answering peer connection: %w", err) - } - response := AnnounceResponse{ - Action: "announce", - InfoHash: binaryToJsonString(offerContext.InfoHash[:]), - PeerID: tc.peerIdBinary(), - ToPeerID: peerId, - Answer: &answer, - OfferID: offerContext.Id, - } - data, err := json.Marshal(response) - if err != nil { - peerConnection.Close() - return fmt.Errorf("marshalling response: %w", err) - } - tc.mu.Lock() - defer tc.mu.Unlock() - if err := tc.writeMessage(data); err != nil { - peerConnection.Close() - return fmt.Errorf("writing response: %w", err) - } - return nil -} - -func (tc *TrackerClient) handleAnswer(offerId string, answer webrtc.SessionDescription) { - tc.mu.Lock() - defer tc.mu.Unlock() - offer, ok := tc.outboundOffers[offerId] - if !ok { - tc.Logger.WithDefaultLevel(log.Warning).Printf("could not find offer for id %+q", offerId) - return - } - // tc.Logger.WithDefaultLevel(log.Debug).Printf("offer %q got answer %v", offerId, answer) - metrics.Add("outbound offers answered", 1) - err := offer.peerConnection.SetRemoteDescription(answer) - if err != nil { - err = fmt.Errorf("using outbound offer answer: %w", err) - offer.peerConnection.span.RecordError(err) - tc.Logger.LevelPrint(log.Error, err) - return - } - delete(tc.outboundOffers, offerId) - go tc.Announce(tracker.None, offer.infoHash) -} diff --git a/webtorrent/tracker-protocol.go b/webtorrent/tracker-protocol.go deleted file mode 100644 index 14be67e4..00000000 --- a/webtorrent/tracker-protocol.go +++ /dev/null @@ -1,76 +0,0 @@ -package webtorrent - -import ( - "fmt" - "math" - - "github.com/pion/webrtc/v3" -) - -type AnnounceRequest struct { - Numwant int `json:"numwant"` - Uploaded int64 `json:"uploaded"` - Downloaded int64 `json:"downloaded"` - Left int64 `json:"left"` - Event string `json:"event,omitempty"` - Action string `json:"action"` - InfoHash string `json:"info_hash"` - PeerID string `json:"peer_id"` - Offers []Offer `json:"offers"` -} - -type Offer struct { - OfferID string `json:"offer_id"` - Offer webrtc.SessionDescription `json:"offer"` -} - -type AnnounceResponse struct { - InfoHash string `json:"info_hash"` - Action string `json:"action"` - Interval *int `json:"interval,omitempty"` - Complete *int `json:"complete,omitempty"` - Incomplete *int `json:"incomplete,omitempty"` - PeerID string `json:"peer_id,omitempty"` - ToPeerID string `json:"to_peer_id,omitempty"` - Answer *webrtc.SessionDescription `json:"answer,omitempty"` - Offer *webrtc.SessionDescription `json:"offer,omitempty"` - OfferID string `json:"offer_id,omitempty"` -} - -// I wonder if this is a defacto standard way to decode bytes to JSON for webtorrent. I don't really -// care. -func binaryToJsonString(b []byte) string { - var seq []rune - for _, v := range b { - seq = append(seq, rune(v)) - } - return string(seq) -} - -func jsonStringToInfoHash(s string) (ih [20]byte, err error) { - b, err := decodeJsonByteString(s, ih[:0]) - if err != nil { - return - } - if len(b) != len(ih) { - err = fmt.Errorf("string decoded to %v bytes", len(b)) - } - return -} - -func decodeJsonByteString(s string, b []byte) ([]byte, error) { - defer func() { - r := recover() - if r == nil { - return - } - panic(fmt.Sprintf("%q", s)) - }() - for _, c := range []rune(s) { - if c < 0 || c > math.MaxUint8 { - return b, fmt.Errorf("rune out of bounds: %v", c) - } - b = append(b, byte(c)) - } - return b, nil -} diff --git a/webtorrent/transport.go b/webtorrent/transport.go deleted file mode 100644 index 610301db..00000000 --- a/webtorrent/transport.go +++ /dev/null @@ -1,263 +0,0 @@ -package webtorrent - -import ( - "context" - "expvar" - "fmt" - "io" - "sync" - "time" - - "github.com/anacrolix/log" - "github.com/anacrolix/missinggo/v2/pproffd" - "github.com/pion/datachannel" - "github.com/pion/webrtc/v3" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/trace" -) - -const ( - dataChannelLabel = "webrtc-datachannel" -) - -var ( - metrics = expvar.NewMap("webtorrent") - api = func() *webrtc.API { - // Enable the detach API (since it's non-standard but more idiomatic). - s.DetachDataChannels() - return webrtc.NewAPI(webrtc.WithSettingEngine(s)) - }() - config = webrtc.Configuration{ICEServers: []webrtc.ICEServer{{URLs: []string{"stun:stun.l.google.com:19302"}}}} - newPeerConnectionMu sync.Mutex -) - -type wrappedPeerConnection struct { - *webrtc.PeerConnection - closeMu sync.Mutex - pproffd.CloseWrapper - span trace.Span - ctx context.Context -} - -func (me *wrappedPeerConnection) Close() error { - me.closeMu.Lock() - defer me.closeMu.Unlock() - err := me.CloseWrapper.Close() - me.span.End() - return err -} - -func newPeerConnection(logger log.Logger) (*wrappedPeerConnection, error) { - newPeerConnectionMu.Lock() - defer newPeerConnectionMu.Unlock() - ctx, span := otel.Tracer(tracerName).Start(context.Background(), "PeerConnection") - pc, err := api.NewPeerConnection(config) - if err != nil { - span.SetStatus(codes.Error, err.Error()) - span.RecordError(err) - span.End() - return nil, err - } - wpc := &wrappedPeerConnection{ - PeerConnection: pc, - CloseWrapper: pproffd.NewCloseWrapper(pc), - ctx: ctx, - span: span, - } - // If the state change handler intends to call Close, it should call it on the wrapper. - wpc.OnConnectionStateChange(func(state webrtc.PeerConnectionState) { - logger.Levelf(log.Warning, "webrtc PeerConnection state changed to %v", state) - span.AddEvent("connection state changed", trace.WithAttributes(attribute.String("state", state.String()))) - }) - return wpc, nil -} - -func setAndGatherLocalDescription(peerConnection *wrappedPeerConnection, sdp webrtc.SessionDescription) (_ webrtc.SessionDescription, err error) { - gatherComplete := webrtc.GatheringCompletePromise(peerConnection.PeerConnection) - peerConnection.span.AddEvent("setting local description") - err = peerConnection.SetLocalDescription(sdp) - if err != nil { - err = fmt.Errorf("setting local description: %w", err) - return - } - <-gatherComplete - peerConnection.span.AddEvent("gathering complete") - return *peerConnection.LocalDescription(), nil -} - -// newOffer creates a transport and returns a WebRTC offer to be announced. See -// https://github.com/pion/webrtc/blob/master/examples/data-channels/jsfiddle/main.go for what this is modelled on. -func (tc *TrackerClient) newOffer( - logger log.Logger, - offerId string, - infoHash [20]byte, -) ( - peerConnection *wrappedPeerConnection, - dataChannel *webrtc.DataChannel, - offer webrtc.SessionDescription, - err error, -) { - peerConnection, err = newPeerConnection(logger) - if err != nil { - return - } - - peerConnection.span.SetAttributes(attribute.String(webrtcConnTypeKey, "offer")) - - dataChannel, err = peerConnection.CreateDataChannel(dataChannelLabel, nil) - if err != nil { - err = fmt.Errorf("creating data channel: %w", err) - peerConnection.Close() - } - initDataChannel(dataChannel, peerConnection, func(dc datachannel.ReadWriteCloser, dcCtx context.Context, dcSpan trace.Span) { - metrics.Add("outbound offers answered with datachannel", 1) - tc.mu.Lock() - tc.stats.ConvertedOutboundConns++ - tc.mu.Unlock() - tc.OnConn(dc, DataChannelContext{ - OfferId: offerId, - LocalOffered: true, - InfoHash: infoHash, - peerConnection: peerConnection, - Context: dcCtx, - Span: dcSpan, - }) - }) - - offer, err = peerConnection.CreateOffer(nil) - if err != nil { - dataChannel.Close() - peerConnection.Close() - return - } - - offer, err = setAndGatherLocalDescription(peerConnection, offer) - if err != nil { - dataChannel.Close() - peerConnection.Close() - } - return -} - -type onDetachedDataChannelFunc func(detached datachannel.ReadWriteCloser, ctx context.Context, span trace.Span) - -func (tc *TrackerClient) initAnsweringPeerConnection( - peerConn *wrappedPeerConnection, - offerContext offerContext, -) (answer webrtc.SessionDescription, err error) { - peerConn.span.SetAttributes(attribute.String(webrtcConnTypeKey, "answer")) - - timer := time.AfterFunc(30*time.Second, func() { - peerConn.span.SetStatus(codes.Error, "answer timeout") - metrics.Add("answering peer connections timed out", 1) - peerConn.Close() - }) - peerConn.OnDataChannel(func(d *webrtc.DataChannel) { - initDataChannel(d, peerConn, func(detached datachannel.ReadWriteCloser, ctx context.Context, span trace.Span) { - timer.Stop() - metrics.Add("answering peer connection conversions", 1) - tc.mu.Lock() - tc.stats.ConvertedInboundConns++ - tc.mu.Unlock() - tc.OnConn(detached, DataChannelContext{ - OfferId: offerContext.Id, - LocalOffered: false, - InfoHash: offerContext.InfoHash, - peerConnection: peerConn, - Context: ctx, - Span: span, - }) - }) - }) - - err = peerConn.SetRemoteDescription(offerContext.SessDesc) - if err != nil { - return - } - answer, err = peerConn.CreateAnswer(nil) - if err != nil { - return - } - - answer, err = setAndGatherLocalDescription(peerConn, answer) - return -} - -// newAnsweringPeerConnection creates a transport from a WebRTC offer and returns a WebRTC answer to be announced. -func (tc *TrackerClient) newAnsweringPeerConnection( - offerContext offerContext, -) ( - peerConn *wrappedPeerConnection, answer webrtc.SessionDescription, err error, -) { - peerConn, err = newPeerConnection(tc.Logger) - if err != nil { - err = fmt.Errorf("failed to create new connection: %w", err) - return - } - answer, err = tc.initAnsweringPeerConnection(peerConn, offerContext) - if err != nil { - peerConn.span.RecordError(err) - peerConn.Close() - } - return -} - -type datachannelReadWriter interface { - datachannel.Reader - datachannel.Writer - io.Reader - io.Writer -} - -type ioCloserFunc func() error - -func (me ioCloserFunc) Close() error { - return me() -} - -func initDataChannel( - dc *webrtc.DataChannel, - pc *wrappedPeerConnection, - onOpen onDetachedDataChannelFunc, -) { - var span trace.Span - dc.OnClose(func() { - span.End() - }) - dc.OnOpen(func() { - pc.span.AddEvent("data channel opened") - var ctx context.Context - ctx, span = otel.Tracer(tracerName).Start(pc.ctx, "DataChannel") - raw, err := dc.Detach() - if err != nil { - // This shouldn't happen if the API is configured correctly, and we call from OnOpen. - panic(err) - } - onOpen(hookDataChannelCloser(raw, pc, span, dc), ctx, span) - }) -} - -// Hooks the datachannel's Close to Close the owning PeerConnection. The datachannel takes ownership -// and responsibility for the PeerConnection. -func hookDataChannelCloser( - dcrwc datachannel.ReadWriteCloser, - pc *wrappedPeerConnection, - dataChannelSpan trace.Span, - originalDataChannel *webrtc.DataChannel, -) datachannel.ReadWriteCloser { - return struct { - datachannelReadWriter - io.Closer - }{ - dcrwc, - ioCloserFunc(func() error { - dcrwc.Close() - pc.Close() - originalDataChannel.Close() - dataChannelSpan.End() - return nil - }), - } -} diff --git a/webtorrent/transport_test.go b/webtorrent/transport_test.go deleted file mode 100644 index c17328e8..00000000 --- a/webtorrent/transport_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package webtorrent - -import ( - "testing" - - "github.com/anacrolix/log" - qt "github.com/frankban/quicktest" - "github.com/pion/webrtc/v3" -) - -func TestClosingPeerConnectionDoesNotCloseUnopenedDataChannel(t *testing.T) { - c := qt.New(t) - var tc TrackerClient - pc, dc, _, err := tc.newOffer(log.Default, "", [20]byte{}) - c.Assert(err, qt.IsNil) - defer pc.Close() - defer dc.Close() - peerConnClosed := make(chan struct{}) - pc.OnConnectionStateChange(func(state webrtc.PeerConnectionState) { - if state == webrtc.PeerConnectionStateClosed { - close(peerConnClosed) - } - }) - dc.OnClose(func() { - // This should not be called because the DataChannel is never opened. - t.Fatal("DataChannel.OnClose handler called") - }) - t.Logf("data channel ready state before close: %v", dc.ReadyState()) - dc.OnError(func(err error) { - t.Logf("data channel error: %v", err) - }) - pc.Close() - c.Check(dc.ReadyState(), qt.Equals, webrtc.DataChannelStateClosed) - <-peerConnClosed -} diff --git a/wstracker.go b/wstracker.go deleted file mode 100644 index c379dc31..00000000 --- a/wstracker.go +++ /dev/null @@ -1,90 +0,0 @@ -package torrent - -import ( - "context" - "fmt" - "net" - netHttp "net/http" - "net/url" - "sync" - - "github.com/anacrolix/log" - "github.com/gorilla/websocket" - "github.com/pion/datachannel" - - "github.com/anacrolix/torrent/tracker" - httpTracker "github.com/anacrolix/torrent/tracker/http" - "github.com/anacrolix/torrent/webtorrent" -) - -type websocketTrackerStatus struct { - url url.URL - tc *webtorrent.TrackerClient -} - -func (me websocketTrackerStatus) statusLine() string { - return fmt.Sprintf("%+v", me.tc.Stats()) -} - -func (me websocketTrackerStatus) URL() *url.URL { - return &me.url -} - -type refCountedWebtorrentTrackerClient struct { - webtorrent.TrackerClient - refCount int -} - -type websocketTrackers struct { - PeerId [20]byte - Logger log.Logger - GetAnnounceRequest func(event tracker.AnnounceEvent, infoHash [20]byte) (tracker.AnnounceRequest, error) - OnConn func(datachannel.ReadWriteCloser, webtorrent.DataChannelContext) - mu sync.Mutex - clients map[string]*refCountedWebtorrentTrackerClient - Proxy httpTracker.ProxyFunc - DialContext func(ctx context.Context, network, addr string) (net.Conn, error) - WebsocketTrackerHttpHeader func() netHttp.Header -} - -func (me *websocketTrackers) Get(url string, infoHash [20]byte) (*webtorrent.TrackerClient, func()) { - me.mu.Lock() - defer me.mu.Unlock() - value, ok := me.clients[url] - if !ok { - dialer := &websocket.Dialer{Proxy: me.Proxy, NetDialContext: me.DialContext, HandshakeTimeout: websocket.DefaultDialer.HandshakeTimeout} - value = &refCountedWebtorrentTrackerClient{ - TrackerClient: webtorrent.TrackerClient{ - Dialer: dialer, - Url: url, - GetAnnounceRequest: me.GetAnnounceRequest, - PeerId: me.PeerId, - OnConn: me.OnConn, - Logger: me.Logger.WithText(func(m log.Msg) string { - return fmt.Sprintf("tracker client for %q: %v", url, m) - }), - WebsocketTrackerHttpHeader: me.WebsocketTrackerHttpHeader, - }, - } - value.TrackerClient.Start(func(err error) { - if err != nil { - me.Logger.Printf("error running tracker client for %q: %v", url, err) - } - }) - if me.clients == nil { - me.clients = make(map[string]*refCountedWebtorrentTrackerClient) - } - me.clients[url] = value - } - value.refCount++ - return &value.TrackerClient, func() { - me.mu.Lock() - defer me.mu.Unlock() - value.TrackerClient.CloseOffersForInfohash(infoHash) - value.refCount-- - if value.refCount == 0 { - value.TrackerClient.Close() - delete(me.clients, url) - } - } -}