From: Matt Joiner Date: Fri, 21 Jun 2019 04:50:49 +0000 (+1000) Subject: Refactor Client.dialFirst X-Git-Tag: v1.3.0~3 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=12958ad384503e32990bd8ad879b204c11038025;p=btrtrc.git Refactor Client.dialFirst --- diff --git a/client.go b/client.go index 91db1da7..8180c14b 100644 --- a/client.go +++ b/client.go @@ -513,51 +513,19 @@ func (cl *Client) dialFirst(ctx context.Context, addr string) dialResult { cl.lock() defer cl.unlock() cl.eachListener(func(s socket) bool { - network := s.Addr().Network() - if peerNetworkEnabled(parseNetworkString(network), cl.config) { + func() { + network := s.Addr().Network() + if !peerNetworkEnabled(parseNetworkString(network), cl.config) { + return + } left++ go func() { - cte := cl.config.ConnTracker.Wait( - ctx, - conntrack.Entry{network, s.Addr().String(), addr}, - "dial torrent client", - 0, - ) - // Try to avoid committing to a dial if the context is complete as it's - // difficult to determine which dial errors allow us to forget the connection - // tracking entry handle. - if ctx.Err() != nil { - if cte != nil { - cte.Forget() - } - resCh <- dialResult{} - return - } - c, err := s.dial(ctx, addr) - // This is a bit optimistic, but it looks non-trivial to thread - // this through the proxy code. Set it now in case we close the - // connection forthwith. - if tc, ok := c.(*net.TCPConn); ok { - tc.SetLinger(0) + resCh <- dialResult{ + cl.dialFromSocket(ctx, s, addr), + network, } - countDialResult(err) - dr := dialResult{c, network} - if c == nil { - if err != nil && forgettableDialError(err) { - cte.Forget() - } else { - cte.Done() - } - } else { - dr.Conn = closeWrapper{c, func() error { - err := c.Close() - cte.Done() - return err - }} - } - resCh <- dr }() - } + }() return true }) }() @@ -584,6 +552,44 @@ func (cl *Client) dialFirst(ctx context.Context, addr string) dialResult { return res } +func (cl *Client) dialFromSocket(ctx context.Context, s socket, addr string) net.Conn { + network := s.Addr().Network() + cte := cl.config.ConnTracker.Wait( + ctx, + conntrack.Entry{network, s.Addr().String(), addr}, + "dial torrent client", + 0, + ) + // Try to avoid committing to a dial if the context is complete as it's difficult to determine + // which dial errors allow us to forget the connection tracking entry handle. + if ctx.Err() != nil { + if cte != nil { + cte.Forget() + } + return nil + } + c, err := s.dial(ctx, addr) + // This is a bit optimistic, but it looks non-trivial to thread this through the proxy code. Set + // it now in case we close the connection forthwith. + if tc, ok := c.(*net.TCPConn); ok { + tc.SetLinger(0) + } + countDialResult(err) + if c == nil { + if err != nil && forgettableDialError(err) { + cte.Forget() + } else { + cte.Done() + } + return nil + } + return closeWrapper{c, func() error { + err := c.Close() + cte.Done() + return err + }} +} + func forgettableDialError(err error) bool { return strings.Contains(err.Error(), "no suitable address found") }