activeAnnounceLimiter limiter.Instance
httpClient *http.Client
- undialableWithoutHolepunch map[netip.AddrPort]struct{}
- undialableWithoutHolepunchDialAttemptedAfterHolepunchConnect map[netip.AddrPort]struct{}
- dialableOnlyAfterHolepunch map[netip.AddrPort]struct{}
+ clientHolepunchAddrSets
}
type ipStr string
log.Fmsg("error accepting connection: %s", err).LogLevel(log.Debug, cl.logger)
continue
}
+ {
+ holepunchAddr, holepunchErr := addrPortFromPeerRemoteAddr(conn.RemoteAddr())
+ if holepunchErr == nil {
+ cl.lock()
+ if g.MapContains(
+ cl.undialableWithoutHolepunchDialedAfterHolepunchConnect,
+ holepunchAddr,
+ ) {
+ g.MakeMapIfNil(&cl.probablyOnlyConnectedDueToHolepunch)
+ g.MapInsert(cl.probablyOnlyConnectedDueToHolepunch, holepunchAddr, struct{}{})
+ }
+ cl.unlock()
+ }
+ }
go func() {
if reject != nil {
torrent.Add("rejected accepted connections", 1)
}
}
holepunchAddr, holepunchAddrErr := addrPortFromPeerRemoteAddr(addr)
- if holepunchAddrErr == nil && g.MapContains(cl.undialableWithoutHolepunch, holepunchAddr) && opts.receivedHolepunchConnect {
- g.MakeMapIfNilAndSet(
- &cl.undialableWithoutHolepunchDialAttemptedAfterHolepunchConnect,
- holepunchAddr,
- struct{}{},
- )
+ if holepunchAddrErr == nil && opts.receivedHolepunchConnect {
+ cl.lock()
+ if g.MapContains(cl.undialableWithoutHolepunch, holepunchAddr) {
+ g.MakeMapIfNilAndSet(
+ &cl.undialableWithoutHolepunchDialedAfterHolepunchConnect,
+ holepunchAddr,
+ struct{}{},
+ )
+ }
+ cl.unlock()
}
headerObfuscationPolicy := opts.HeaderObfuscationPolicy
obfuscatedHeaderFirst := headerObfuscationPolicy.Preferred
if firstDialResult.Conn == nil {
// No dialers worked. Try to initiate a holepunching rendezvous.
if holepunchAddrErr == nil {
+ cl.lock()
if !opts.receivedHolepunchConnect {
- cl.lock()
g.MakeMapIfNilAndSet(&cl.undialableWithoutHolepunch, holepunchAddr, struct{}{})
- cl.unlock()
}
opts.t.startHolepunchRendezvous(holepunchAddr)
+ cl.unlock()
}
err = fmt.Errorf("all initial dials failed")
return
}
- if opts.receivedHolepunchConnect && holepunchAddrErr == nil && g.MapContains(cl.undialableWithoutHolepunch, holepunchAddr) {
- g.MakeMapIfNilAndSet(&cl.dialableOnlyAfterHolepunch, holepunchAddr, struct{}{})
+ if opts.receivedHolepunchConnect && holepunchAddrErr == nil {
+ cl.lock()
+ if g.MapContains(cl.undialableWithoutHolepunch, holepunchAddr) {
+ g.MakeMapIfNilAndSet(&cl.dialableOnlyAfterHolepunch, holepunchAddr, struct{}{})
+ }
+ g.MakeMapIfNil(&cl.dialedSuccessfullyAfterHolepunchConnect)
+ g.MapInsert(cl.dialedSuccessfullyAfterHolepunchConnect, holepunchAddr, struct{}{})
+ cl.unlock()
}
c, err = doProtocolHandshakeOnDialResult(
opts.t,
defer cl.rUnlock()
return cl.statsLocked()
}
-
-func (cl *Client) statsLocked() (stats ClientStats) {
- stats.ConnStats = cl.connStats.Copy()
- stats.ActiveHalfOpenAttempts = cl.numHalfOpen
- stats.NumPeersUndialableWithoutHolepunchDialedAfterHolepunchConnect =
- len(cl.undialableWithoutHolepunchDialAttemptedAfterHolepunchConnect)
- stats.NumPeersDialableOnlyAfterHolepunch =
- len(cl.dialableOnlyAfterHolepunch)
- return
-}