client.go | 22 +++++++++++++++++----- torrent.go | 13 +++++++++++++ diff --git a/client.go b/client.go index 0ffd93019099eb4ca8f04aca5fbdd3bc66bd9e90..2dc4acfa4b624e78aa8b6b8d4594867af3480756 100644 --- a/client.go +++ b/client.go @@ -17,6 +17,7 @@ package torrent import ( "bufio" + "container/heap" "crypto/rand" "crypto/sha1" "errors" @@ -55,11 +56,15 @@ postedCancels = expvar.NewInt("postedCancels") duplicateConnsAvoided = expvar.NewInt("duplicateConnsAvoided") ) -// Justification for set bits follows. -// -// Extension protocol: http://www.bittorrent.org/beps/bep_0010.html -// DHT: http://www.bittorrent.org/beps/bep_0005.html -const extensionBytes = "\x00\x00\x00\x00\x00\x10\x00\x01" +const ( + // Justification for set bits follows. + // + // Extension protocol: http://www.bittorrent.org/beps/bep_0010.html + // DHT: http://www.bittorrent.org/beps/bep_0005.html + extensionBytes = "\x00\x00\x00\x00\x00\x10\x00\x01" + + socketsPerTorrent = 40 +) // Currently doesn't really queue, but should in the future. func (cl *Client) queuePieceCheck(t *torrent, pieceIndex pp.Integer) { @@ -969,6 +974,10 @@ return false } } t.Conns = append(t.Conns, c) + if len(t.Conns) > socketsPerTorrent { + wcs := t.worstConnsHeap() + heap.Pop(wcs).(*connection).Close() + } return true } @@ -982,6 +991,9 @@ } for len(t.Peers) != 0 { if me.halfOpen >= me.halfOpenLimit { return + } + if me.halfOpen+me.handshaking+len(t.Conns) >= socketsPerTorrent { + break } var ( k peersKey diff --git a/torrent.go b/torrent.go index 1dc6cd6c962fe173b1f8ad362eba40368ab629c0..8274091c65083b2d33705131484bcfbd365a4ed9 100644 --- a/torrent.go +++ b/torrent.go @@ -1,11 +1,13 @@ package torrent import ( + "container/heap" "container/list" "fmt" "io" "log" "net" + "sort" "sync" "bitbucket.org/anacrolix/go.torrent/util" @@ -65,6 +67,14 @@ Trackers [][]tracker.Client DisplayName string MetaData []byte metadataHave []bool +} + +func (t *torrent) worstConnsHeap() (wcs *worstConnsHeap) { + wcs = new(worstConnsHeap) + *wcs = make([]*connection, 0, len(t.Conns)) + *wcs = append(*wcs, t.Conns...) + heap.Init(wcs) + return } func (t *torrent) CeaseNetworking() { @@ -283,6 +293,9 @@ } fmt.Fprintln(w) fmt.Fprintf(w, "Pending peers: %d\n", len(t.Peers)) fmt.Fprintf(w, "Active peers: %d\n", len(t.Conns)) + wcs := new(worstConnsHeap) + *wcs = t.Conns + sort.Sort(wcs) for _, c := range t.Conns { c.WriteStatus(w) }