From 02adc3f2ee1909831d897a74a3e36f432c35de6d Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Sat, 30 May 2020 10:14:20 +1000 Subject: [PATCH] Break peer out from PeerConn --- client.go | 21 ++++++++++++--------- client_test.go | 4 ++-- peerconn.go | 33 +++++++++++++++++++-------------- peerconn_test.go | 24 ++++++++++++------------ pex_test.go | 12 ++++++------ 5 files changed, 51 insertions(+), 43 deletions(-) diff --git a/client.go b/client.go index 37a25ae2..646abe55 100644 --- a/client.go +++ b/client.go @@ -1277,15 +1277,18 @@ func (cl *Client) banPeerIP(ip net.IP) { func (cl *Client) newConnection(nc net.Conn, outgoing bool, remoteAddr net.Addr, network, connString string) (c *PeerConn) { c = &PeerConn{ - conn: nc, - outgoing: outgoing, - choking: true, - peerChoking: true, - PeerMaxRequests: 250, - writeBuffer: new(bytes.Buffer), - remoteAddr: remoteAddr, - network: network, - connString: connString, + peer: peer{ + outgoing: outgoing, + choking: true, + peerChoking: true, + PeerMaxRequests: 250, + + remoteAddr: remoteAddr, + network: network, + connString: connString, + }, + conn: nc, + writeBuffer: new(bytes.Buffer), } c.logger = cl.logger.WithValues(c).WithDefaultLevel(log.Debug).WithText(func(m log.Msg) string { return fmt.Sprintf("%v: %s", c, m.Text()) diff --git a/client_test.go b/client_test.go index cf6aaf21..6822c328 100644 --- a/client_test.go +++ b/client_test.go @@ -546,9 +546,9 @@ func TestPeerInvalidHave(t *testing.T) { require.NoError(t, err) assert.True(t, _new) defer tt.Drop() - cn := &PeerConn{ + cn := &PeerConn{peer: peer{ t: tt, - } + }} assert.NoError(t, cn.peerSentHave(0)) assert.Error(t, cn.peerSentHave(1)) } diff --git a/peerconn.go b/peerconn.go index df395006..8c2d1ee1 100644 --- a/peerconn.go +++ b/peerconn.go @@ -35,22 +35,12 @@ const ( PeerSourcePex = "X" ) -// Maintains the state of a connection with a peer. -type PeerConn struct { - // First to ensure 64-bit alignment for atomics. See #262. - _stats ConnStats - - t *Torrent - // The actual Conn, used for closing, and setting socket options. - conn net.Conn +type peer struct { + t *Torrent connString string outgoing bool network string remoteAddr net.Addr - // The Reader and Writer for this Conn, with hooks installed for stats, - // limiting, deadlines etc. - w io.Writer - r io.Reader // True if the connection is operating over MSE obfuscation. headerEncrypted bool cryptoMethod mse.CryptoMethod @@ -116,11 +106,26 @@ type PeerConn struct { pieceInclination []int _pieceRequestOrder prioritybitmap.PriorityBitmap + logger log.Logger +} + +// Maintains the state of a connection with a peer. +type PeerConn struct { + // First to ensure 64-bit alignment for atomics. See #262. + _stats ConnStats + + peer + + // The actual Conn, used for closing, and setting socket options. + conn net.Conn + // The Reader and Writer for this Conn, with hooks installed for stats, + // limiting, deadlines etc. + w io.Writer + r io.Reader + writeBuffer *bytes.Buffer uploadTimer *time.Timer writerCond sync.Cond - - logger log.Logger } func (cn *PeerConn) updateExpectingChunks() { diff --git a/peerconn_test.go b/peerconn_test.go index 80950d5f..7ad4c41a 100644 --- a/peerconn_test.go +++ b/peerconn_test.go @@ -155,14 +155,14 @@ func TestConnPexPeerFlags(t *testing.T) { conn *PeerConn f pp.PexPeerFlags }{ - {&PeerConn{outgoing: false, PeerPrefersEncryption: false}, 0}, - {&PeerConn{outgoing: false, PeerPrefersEncryption: true}, pp.PexPrefersEncryption}, - {&PeerConn{outgoing: true, PeerPrefersEncryption: false}, pp.PexOutgoingConn}, - {&PeerConn{outgoing: true, PeerPrefersEncryption: true}, pp.PexOutgoingConn | pp.PexPrefersEncryption}, - {&PeerConn{remoteAddr: udpAddr}, pp.PexSupportsUtp}, - {&PeerConn{remoteAddr: udpAddr, outgoing: true}, pp.PexOutgoingConn | pp.PexSupportsUtp}, - {&PeerConn{remoteAddr: tcpAddr, outgoing: true}, pp.PexOutgoingConn}, - {&PeerConn{remoteAddr: tcpAddr}, 0}, + {&PeerConn{peer: peer{outgoing: false, PeerPrefersEncryption: false}}, 0}, + {&PeerConn{peer: peer{outgoing: false, PeerPrefersEncryption: true}}, pp.PexPrefersEncryption}, + {&PeerConn{peer: peer{outgoing: true, PeerPrefersEncryption: false}}, pp.PexOutgoingConn}, + {&PeerConn{peer: peer{outgoing: true, PeerPrefersEncryption: true}}, pp.PexOutgoingConn | pp.PexPrefersEncryption}, + {&PeerConn{peer: peer{remoteAddr: udpAddr}}, pp.PexSupportsUtp}, + {&PeerConn{peer: peer{remoteAddr: udpAddr, outgoing: true}}, pp.PexOutgoingConn | pp.PexSupportsUtp}, + {&PeerConn{peer: peer{remoteAddr: tcpAddr, outgoing: true}}, pp.PexOutgoingConn}, + {&PeerConn{peer: peer{remoteAddr: tcpAddr}}, 0}, } for i, tc := range testcases { f := tc.conn.pexPeerFlags() @@ -184,22 +184,22 @@ func TestConnPexEvent(t *testing.T) { }{ { pexAdd, - &PeerConn{remoteAddr: udpAddr}, + &PeerConn{peer: peer{remoteAddr: udpAddr}}, pexEvent{pexAdd, udpAddr, pp.PexSupportsUtp}, }, { pexDrop, - &PeerConn{remoteAddr: tcpAddr, outgoing: true, PeerListenPort: dialTcpAddr.Port}, + &PeerConn{peer: peer{remoteAddr: tcpAddr, outgoing: true, PeerListenPort: dialTcpAddr.Port}}, pexEvent{pexDrop, tcpAddr, pp.PexOutgoingConn}, }, { pexAdd, - &PeerConn{remoteAddr: tcpAddr, PeerListenPort: dialTcpAddr.Port}, + &PeerConn{peer: peer{remoteAddr: tcpAddr, PeerListenPort: dialTcpAddr.Port}}, pexEvent{pexAdd, dialTcpAddr, 0}, }, { pexDrop, - &PeerConn{remoteAddr: udpAddr, PeerListenPort: dialUdpAddr.Port}, + &PeerConn{peer: peer{remoteAddr: udpAddr, PeerListenPort: dialUdpAddr.Port}}, pexEvent{pexDrop, dialUdpAddr, pp.PexSupportsUtp}, }, } diff --git a/pex_test.go b/pex_test.go index 4967b5d9..828883c4 100644 --- a/pex_test.go +++ b/pex_test.go @@ -23,7 +23,7 @@ var ( func TestPexAdded(t *testing.T) { t.Run("noHold", func(t *testing.T) { s := new(pexState) - s.Add(&PeerConn{remoteAddr: addrs[0], outgoing: true}) + s.Add(&PeerConn{peer: peer{remoteAddr: addrs[0], outgoing: true}}) targ := &pexState{ ev: []pexEvent{ pexEvent{pexAdd, addrs[0], pp.PexOutgoingConn}, @@ -39,7 +39,7 @@ func TestPexAdded(t *testing.T) { }, nc: 0, } - s.Add(&PeerConn{remoteAddr: addrs[0]}) + s.Add(&PeerConn{peer: peer{remoteAddr: addrs[0]}}) targ := &pexState{ hold: []pexEvent{ pexEvent{pexDrop, addrs[1], 0}, @@ -59,7 +59,7 @@ func TestPexAdded(t *testing.T) { }, nc: pexTargAdded, } - s.Add(&PeerConn{remoteAddr: addrs[0]}) + s.Add(&PeerConn{peer: peer{remoteAddr: addrs[0]}}) targ := &pexState{ hold: []pexEvent{}, ev: []pexEvent{ @@ -75,7 +75,7 @@ func TestPexAdded(t *testing.T) { func TestPexDropped(t *testing.T) { t.Run("belowTarg", func(t *testing.T) { s := &pexState{nc: 1} - s.Drop(&PeerConn{remoteAddr: addrs[0], pex: pexConnState{Listed: true}}) + s.Drop(&PeerConn{peer: peer{remoteAddr: addrs[0], pex: pexConnState{Listed: true}}}) targ := &pexState{ hold: []pexEvent{pexEvent{pexDrop, addrs[0], 0}}, nc: 0, @@ -84,7 +84,7 @@ func TestPexDropped(t *testing.T) { }) t.Run("aboveTarg", func(t *testing.T) { s := &pexState{nc: pexTargAdded + 1} - s.Drop(&PeerConn{remoteAddr: addrs[0], pex: pexConnState{Listed: true}}) + s.Drop(&PeerConn{peer: peer{remoteAddr: addrs[0], pex: pexConnState{Listed: true}}}) targ := &pexState{ ev: []pexEvent{pexEvent{pexDrop, addrs[0], 0}}, nc: pexTargAdded, @@ -93,7 +93,7 @@ func TestPexDropped(t *testing.T) { }) t.Run("aboveTargNotListed", func(t *testing.T) { s := &pexState{nc: pexTargAdded + 1} - s.Drop(&PeerConn{remoteAddr: addrs[0], pex: pexConnState{Listed: false}}) + s.Drop(&PeerConn{peer: peer{remoteAddr: addrs[0], pex: pexConnState{Listed: false}}}) targ := &pexState{nc: pexTargAdded + 1} require.EqualValues(t, targ, s) })