From: Matt Joiner Date: Mon, 25 Oct 2021 09:52:44 +0000 (+1100) Subject: Support minimum peer extensions X-Git-Tag: v1.34.0^2~6 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=3d49a29288cad7ee9e47a92e26fd01f0c9fae4b5;p=btrtrc.git Support minimum peer extensions --- diff --git a/client.go b/client.go index b4d3f17a..6e90fa75 100644 --- a/client.go +++ b/client.go @@ -932,6 +932,11 @@ func (cl *Client) runReceivedConn(c *PeerConn) { // Client lock must be held before entering this. func (cl *Client) runHandshookConn(c *PeerConn, t *Torrent) error { c.setTorrent(t) + for i, b := range cl.config.MinPeerExtensions { + if c.PeerExtensionBytes[i]&b != b { + return fmt.Errorf("peer did not meet minimum peer extensions: %x", c.PeerExtensionBytes) + } + } if c.PeerID == cl.peerID { if c.outgoing { connsToSelf.Add(1) diff --git a/cmd/torrent/main.go b/cmd/torrent/main.go index 06b76f6b..50604cf6 100644 --- a/cmd/torrent/main.go +++ b/cmd/torrent/main.go @@ -22,6 +22,7 @@ import ( "github.com/anacrolix/missinggo/v2" "github.com/anacrolix/tagflag" "github.com/anacrolix/torrent/bencode" + pp "github.com/anacrolix/torrent/peer_protocol" "github.com/anacrolix/torrent/version" "github.com/davecgh/go-spew/spew" "github.com/dustin/go-humanize" @@ -186,6 +187,9 @@ type DownloadCmd struct { UtpPeers bool `default:"true"` Webtorrent bool `default:"true"` DisableWebseeds bool + // Don't progress past handshake for peer connections where the peer doesn't offer the fast + // extension. + RequireFastExtension bool Ipv4 bool `default:"true"` Ipv6 bool `default:"true"` @@ -316,6 +320,9 @@ func downloadErr(flags downloadFlags) error { if flags.Quiet { clientConfig.Logger = log.Discard } + if flags.RequireFastExtension { + clientConfig.MinPeerExtensions.SetBit(pp.ExtensionBitFast, true) + } clientConfig.MaxUnverifiedBytes = flags.MaxUnverifiedBytes.Int64() var stop missinggo.SynchronizedEvent diff --git a/config.go b/config.go index 14c129cf..3d370d55 100644 --- a/config.go +++ b/config.go @@ -146,6 +146,8 @@ type ClientConfig struct { DHTOnQuery func(query *krpc.Msg, source net.Addr) (propagate bool) Extensions PeerExtensionBits + // Bits that peers must have set to proceed past handshakes. + MinPeerExtensions PeerExtensionBits DisableWebtorrent bool DisableWebseeds bool diff --git a/test/issue377_test.go b/test/issue377_test.go index 7456e9c4..01caaed6 100644 --- a/test/issue377_test.go +++ b/test/issue377_test.go @@ -51,6 +51,9 @@ func testReceiveChunkStorageFailure(t *testing.T, seederFast bool) { defer testutil.ExportStatusWriter(seederClient, "s", t)() leecherClientConfig := torrent.TestingConfig(t) leecherClientConfig.Debug = true + // Don't require fast extension, whether the seeder will provide it or not (so we can test mixed + // cases). + leecherClientConfig.MinPeerExtensions.SetBit(pp.ExtensionBitFast, false) justOneNetwork(leecherClientConfig) leecherClient, err := torrent.NewClient(leecherClientConfig) require.NoError(t, err) diff --git a/testing.go b/testing.go index 6a9d892d..d681796d 100644 --- a/testing.go +++ b/testing.go @@ -3,6 +3,8 @@ package torrent import ( "testing" "time" + + pp "github.com/anacrolix/torrent/peer_protocol" ) func TestingConfig(t testing.TB) *ClientConfig { @@ -15,6 +17,7 @@ func TestingConfig(t testing.TB) *ClientConfig { cfg.DisableAcceptRateLimiting = true cfg.ListenPort = 0 cfg.KeepAliveTimeout = time.Millisecond + cfg.MinPeerExtensions.SetBit(pp.ExtensionBitFast, true) //cfg.Debug = true //cfg.Logger = cfg.Logger.WithText(func(m log.Msg) string { // t := m.Text() diff --git a/torrent_test.go b/torrent_test.go index 02e56e2d..2b96f191 100644 --- a/torrent_test.go +++ b/torrent_test.go @@ -163,6 +163,8 @@ func TestPieceHashFailed(t *testing.T) { func TestTorrentMetainfoIncompleteMetadata(t *testing.T) { cfg := TestingConfig(t) cfg.Debug = true + // Disable this just because we manually initiate a connection without it. + cfg.MinPeerExtensions.SetBit(pp.ExtensionBitFast, false) cl, err := NewClient(cfg) require.NoError(t, err) defer cl.Close()