diff --git a/tracker/client.go b/tracker/client.go index ee444e2b..1df0aa43 100644 --- a/tracker/client.go +++ b/tracker/client.go @@ -4,6 +4,7 @@ import ( "context" "net/url" + "github.com/anacrolix/log" trHttp "github.com/anacrolix/torrent/tracker/http" "github.com/anacrolix/torrent/tracker/udp" ) @@ -19,6 +20,7 @@ type NewClientOpts struct { Http trHttp.NewClientOpts // Overrides the network in the scheme. Probably a legacy thing. UdpNetwork string + Logger log.Logger } func NewClient(urlStr string, opts NewClientOpts) (Client, error) { @@ -37,6 +39,7 @@ func NewClient(urlStr string, opts NewClientOpts) (Client, error) { cc, err := udp.NewConnClient(udp.NewConnClientOpts{ Network: network, Host: _url.Host, + Logger: opts.Logger, }) if err != nil { return nil, err diff --git a/tracker/tracker.go b/tracker/tracker.go index f058f63b..7c3a5f6d 100644 --- a/tracker/tracker.go +++ b/tracker/tracker.go @@ -3,11 +3,13 @@ package tracker import ( "context" "errors" + "fmt" "net/http" "net/url" "time" "github.com/anacrolix/dht/v2/krpc" + "github.com/anacrolix/log" trHttp "github.com/anacrolix/torrent/tracker/http" "github.com/anacrolix/torrent/tracker/shared" "github.com/anacrolix/torrent/tracker/udp" @@ -43,6 +45,7 @@ type Announce struct { // If the port is zero, it's assumed to be the same as the Request.Port. ClientIp6 krpc.NodeAddr Context context.Context + Logger log.Logger } // The code *is* the documentation. @@ -55,6 +58,7 @@ func (me Announce) Do() (res AnnounceResponse, err error) { ServerName: me.ServerName, }, UdpNetwork: me.UdpNetwork, + Logger: me.Logger.WithContextValue(fmt.Sprintf("tracker client for %q", me.TrackerUrl)), }) if err != nil { return diff --git a/tracker/udp/conn-client.go b/tracker/udp/conn-client.go index 1958c659..f07ae69c 100644 --- a/tracker/udp/conn-client.go +++ b/tracker/udp/conn-client.go @@ -2,9 +2,10 @@ package udp import ( "context" - "log" "net" + "github.com/anacrolix/log" + "github.com/anacrolix/missinggo/v2" ) @@ -15,6 +16,8 @@ type NewConnClientOpts struct { Host string // If non-nil, forces either IPv4 or IPv6 in the UDP tracker wire protocol. Ipv6 *bool + // Logger to use for internal errors. + Logger log.Logger } // Manages a Client with a specific connection. @@ -42,7 +45,7 @@ func (cc *ConnClient) reader() { } err = cc.d.Dispatch(b[:n], addr) if err != nil { - log.Printf("dispatching packet received on %v: %v", cc.conn.LocalAddr(), err) + cc.newOpts.Logger.WithLevel(log.Debug).Printf("dispatching packet received on %v: %v", cc.conn.LocalAddr(), err) } } } @@ -81,6 +84,9 @@ func NewConnClient(opts NewConnClientOpts) (cc *ConnClient, err error) { if err != nil { return } + if opts.Logger.IsZero() { + opts.Logger = log.Default + } cc = &ConnClient{ Client: Client{ Writer: clientWriter{ @@ -97,17 +103,21 @@ func NewConnClient(opts NewConnClientOpts) (cc *ConnClient, err error) { return } -func (c *ConnClient) Close() error { - c.closed = true - return c.conn.Close() +func (cc *ConnClient) Close() error { + cc.closed = true + return cc.conn.Close() } -func (c *ConnClient) Announce( +func (cc *ConnClient) Announce( ctx context.Context, req AnnounceRequest, opts Options, ) ( h AnnounceResponseHeader, nas AnnounceResponsePeers, err error, ) { - return c.Client.Announce(ctx, req, opts, func(addr net.Addr) bool { - return ipv6(c.newOpts.Ipv6, c.newOpts.Network, addr) + return cc.Client.Announce(ctx, req, opts, func(addr net.Addr) bool { + return ipv6(cc.newOpts.Ipv6, cc.newOpts.Network, addr) }) } + +func (cc *ConnClient) LocalAddr() net.Addr { + return cc.conn.LocalAddr() +} diff --git a/tracker/udp/udp_test.go b/tracker/udp/udp_test.go index 862aec73..cbb41778 100644 --- a/tracker/udp/udp_test.go +++ b/tracker/udp/udp_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/anacrolix/dht/v2/krpc" + qt "github.com/frankban/quicktest" "github.com/stretchr/testify/require" ) @@ -73,3 +74,20 @@ func TestConvertInt16ToInt(t *testing.T) { t.FailNow() } } + +func TestConnClientLogDispatchUnknownTransactionId(t *testing.T) { + const network = "udp" + cc, err := NewConnClient(NewConnClientOpts{ + Network: network, + }) + c := qt.New(t) + c.Assert(err, qt.IsNil) + defer cc.Close() + pc, err := net.ListenPacket(network, ":0") + c.Assert(err, qt.IsNil) + defer pc.Close() + ccAddr := *cc.LocalAddr().(*net.UDPAddr) + ccAddr.IP = net.IPv6loopback + _, err = pc.WriteTo(make([]byte, 30), &ccAddr) + c.Assert(err, qt.IsNil) +} diff --git a/tracker_scraper.go b/tracker_scraper.go index 93b3ebca..b441efb9 100644 --- a/tracker_scraper.go +++ b/tracker_scraper.go @@ -166,6 +166,7 @@ func (me *trackerScraper) announce(ctx context.Context, event tracker.AnnounceEv UdpNetwork: me.u.Scheme, ClientIp4: krpc.NodeAddr{IP: me.t.cl.config.PublicIp4}, ClientIp6: krpc.NodeAddr{IP: me.t.cl.config.PublicIp6}, + Logger: me.t.logger, }.Do() me.t.logger.WithDefaultLevel(log.Debug).Printf("announce to %q returned %#v: %v", me.u.String(), res, err) if err != nil {