From f45dac1e3884105a3c0fb4824205ff41542e1007 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 13 Apr 2020 14:04:34 +1000 Subject: [PATCH] Use offer_id for webrtc conn string --- client.go | 21 ++++++++++++++------- peerconn.go | 3 ++- peerconn_test.go | 4 ++-- torrent.go | 1 + webtorrent/client.go | 4 +++- webtorrent/transport.go | 4 ++-- 6 files changed, 24 insertions(+), 13 deletions(-) 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)