diff --git a/client.go b/client.go index 43a4c46f..98c87171 100644 --- a/client.go +++ b/client.go @@ -461,12 +461,17 @@ func (cl *Client) acceptConnections(l net.Listener) { } } +func regularConnString(nc net.Conn) string { + return fmt.Sprintf("%s-%s", nc.LocalAddr(), nc.RemoteAddr()) +} + func (cl *Client) incomingConnection(nc net.Conn) { defer nc.Close() if tc, ok := nc.(*net.TCPConn); ok { tc.SetLinger(0) } - c := cl.newConnection(nc, false, nc.RemoteAddr(), nc.RemoteAddr().Network()) + c := cl.newConnection(nc, false, nc.RemoteAddr(), nc.RemoteAddr().Network(), + regularConnString(nc)) c.Discovery = PeerSourceIncoming cl.runReceivedConn(c) } @@ -623,8 +628,10 @@ func (cl *Client) noLongerHalfOpen(t *Torrent, addr string) { // Performs initiator handshakes and returns a connection. Returns nil *connection if no connection // for valid reasons. -func (cl *Client) handshakesConnection(ctx context.Context, nc net.Conn, t *Torrent, encryptHeader bool, remoteAddr net.Addr, network string) (c *PeerConn, err error) { - c = cl.newConnection(nc, true, remoteAddr, network) +func (cl *Client) handshakesConnection(ctx context.Context, nc net.Conn, t *Torrent, encryptHeader bool, remoteAddr net.Addr, + network, connString string, +) (c *PeerConn, err error) { + c = cl.newConnection(nc, true, remoteAddr, network, connString) c.headerEncrypted = encryptHeader ctx, cancel := context.WithTimeout(ctx, cl.config.HandshakesTimeout) defer cancel() @@ -640,8 +647,7 @@ func (cl *Client) handshakesConnection(ctx context.Context, nc net.Conn, t *Torr return } -// Returns nil connection and nil error if no connection could be established -// for valid reasons. +// Returns nil connection and nil error if no connection could be established for valid reasons. func (cl *Client) establishOutgoingConnEx(t *Torrent, addr net.Addr, obfuscatedHeader bool) (*PeerConn, error) { dialCtx, cancel := context.WithTimeout(context.Background(), func() time.Duration { cl.rLock() @@ -657,7 +663,7 @@ func (cl *Client) establishOutgoingConnEx(t *Torrent, addr net.Addr, obfuscatedH } return nil, errors.New("dial failed") } - c, err := cl.handshakesConnection(context.Background(), nc, t, obfuscatedHeader, addr, dr.Network) + c, err := cl.handshakesConnection(context.Background(), nc, t, obfuscatedHeader, addr, dr.Network, regularConnString(nc)) if err != nil { nc.Close() } @@ -1228,7 +1234,7 @@ func (cl *Client) banPeerIP(ip net.IP) { cl.badPeerIPs[ip.String()] = struct{}{} } -func (cl *Client) newConnection(nc net.Conn, outgoing bool, remoteAddr net.Addr, network string) (c *PeerConn) { +func (cl *Client) newConnection(nc net.Conn, outgoing bool, remoteAddr net.Addr, network, connString string) (c *PeerConn) { c = &PeerConn{ conn: nc, outgoing: outgoing, @@ -1238,6 +1244,7 @@ func (cl *Client) newConnection(nc net.Conn, outgoing bool, remoteAddr net.Addr, writeBuffer: new(bytes.Buffer), remoteAddr: remoteAddr, network: network, + connString: connString, } c.logger = cl.logger.WithValues(c, log.Debug, // I want messages to default to debug, and can set it here as it's only used by new code diff --git a/peerconn.go b/peerconn.go index ee5cdfd9..45ad375e 100644 --- a/peerconn.go +++ b/peerconn.go @@ -43,6 +43,7 @@ type PeerConn struct { t *Torrent // The actual Conn, used for closing, and setting socket options. conn net.Conn + connString string outgoing bool network string remoteAddr net.Addr @@ -280,7 +281,7 @@ func (cn *PeerConn) downloadRate() float64 { func (cn *PeerConn) writeStatus(w io.Writer, t *Torrent) { // \t isn't preserved in
blocks? - fmt.Fprintf(w, "%+-55q %s %s-%s\n", cn.PeerID, cn.PeerExtensionBytes, cn.localAddr(), cn.remoteAddr) + fmt.Fprintf(w, "%+-55q %s %s\n", cn.PeerID, cn.PeerExtensionBytes, cn.connString) fmt.Fprintf(w, " last msg: %s, connected: %s, last helpful: %s, itime: %s, etime: %s\n", eventAgeString(cn.lastMessageReceived), eventAgeString(cn.completedHandshake), diff --git a/peerconn_test.go b/peerconn_test.go index da7c5bb3..e1d876f9 100644 --- a/peerconn_test.go +++ b/peerconn_test.go @@ -23,7 +23,7 @@ func TestSendBitfieldThenHave(t *testing.T) { config: TestingConfig(), } cl.initLogger() - c := cl.newConnection(nil, false, nil, "") + c := cl.newConnection(nil, false, nil, "", "") c.setTorrent(cl.newTorrent(metainfo.Hash{}, nil)) c.t.setInfo(&metainfo.Info{ Pieces: make([]byte, metainfo.HashSize*3), @@ -107,7 +107,7 @@ func BenchmarkConnectionMainReadLoop(b *testing.B) { t.setChunkSize(defaultChunkSize) t._pendingPieces.Set(0, PiecePriorityNormal.BitmapPriority()) r, w := net.Pipe() - cn := cl.newConnection(r, true, nil, "") + cn := cl.newConnection(r, true, nil, "", "") cn.setTorrent(t) mrlErr := make(chan error) msg := pp.Message{ diff --git a/torrent.go b/torrent.go index 81730ef8..4875bf5b 100644 --- a/torrent.go +++ b/torrent.go @@ -1276,6 +1276,7 @@ func (t *Torrent) onWebRtcConn( false, webrtcNetAddr{dcc.Remote}, webrtcNetwork, + fmt.Sprintf("webrtc offer_id %x", dcc.OfferId), ) if err != nil { t.logger.Printf("error in handshaking webrtc connection: %v", err) diff --git a/webtorrent/client.go b/webtorrent/client.go index 72c1d046..54ebf264 100644 --- a/webtorrent/client.go +++ b/webtorrent/client.go @@ -41,6 +41,7 @@ func binaryToJsonString(b []byte) string { type DataChannelContext struct { Local, Remote webrtc.SessionDescription + OfferId string LocalOffered bool } @@ -146,7 +147,7 @@ func (c *Client) trackerReadLoop() error { } switch { case ar.Offer != nil: - _, answer, err := NewTransportFromOffer(*ar.Offer, c.onConn) + _, answer, err := NewTransportFromOffer(*ar.Offer, c.onConn, ar.OfferID) if err != nil { return fmt.Errorf("write AnnounceResponse: %w", err) } @@ -184,6 +185,7 @@ func (c *Client) trackerReadLoop() error { c.onConn(dc, DataChannelContext{ Local: offer.originalOffer, Remote: *ar.Answer, + OfferId: ar.OfferID, LocalOffered: true, }) }) diff --git a/webtorrent/transport.go b/webtorrent/transport.go index efaf3157..db2a94c9 100644 --- a/webtorrent/transport.go +++ b/webtorrent/transport.go @@ -67,7 +67,7 @@ func NewTransport() (*Transport, webrtc.SessionDescription, error) { // NewTransportFromOffer creates a transport from a WebRTC offer and and returns a WebRTC answer to // be announced. -func NewTransportFromOffer(offer webrtc.SessionDescription, onOpen onDataChannelOpen) (*Transport, webrtc.SessionDescription, error) { +func NewTransportFromOffer(offer webrtc.SessionDescription, onOpen onDataChannelOpen, offerId string) (*Transport, webrtc.SessionDescription, error) { peerConnection, err := newPeerConnection() if err != nil { return nil, webrtc.SessionDescription{}, fmt.Errorf("failed to peer connection: %v", err) @@ -92,7 +92,7 @@ func NewTransportFromOffer(offer webrtc.SessionDescription, onOpen onDataChannel t.dc = d t.lock.Unlock() t.handleOpen(func(dc datachannel.ReadWriteCloser) { - onOpen(dc, DataChannelContext{answer, offer, false}) + onOpen(dc, DataChannelContext{answer, offer, offerId, false}) }) }) err = peerConnection.SetLocalDescription(answer)