}(),
"v": extendedHandshakeClientVersion,
// No upload queue is implemented yet.
- "reqq": func() int {
- if me.config.NoUpload {
- // No need to look strange if it costs us nothing.
- return 250
- } else {
- return 1
- }
- }(),
+ "reqq": 64,
}
if !me.config.DisableEncryption {
d["e"] = 1
if me.config.NoUpload {
break
}
- if c.PeerRequests == nil {
- c.PeerRequests = make(map[request]struct{}, maxRequests)
- }
request := newRequest(msg.Index, msg.Begin, msg.Length)
// TODO: Requests should be satisfied from a dedicated upload
// routine.
// c.PeerRequests[request] = struct{}{}
+ // if c.PeerRequests == nil {
+ // c.PeerRequests = make(map[request]struct{}, maxRequests)
+ // }
p := make([]byte, msg.Length)
n, err := dataReadAt(t.data, p, int64(t.pieceLength(0))*int64(msg.Index)+int64(msg.Begin))
if err != nil {
Piece: p,
})
uploadChunksPosted.Add(1)
+ c.chunksSent++
case pp.Cancel:
req := newRequest(msg.Index, msg.Begin, msg.Length)
if !c.PeerCancel(req) {
return false
default:
}
- if len(t.Peers) < torrentPeersLowWater && t.needData() {
+ if len(t.Peers) > torrentPeersLowWater {
+ goto wait
+ }
+ if t.needData() || cl.seeding(t) {
return true
}
+ wait:
cl.mu.Unlock()
t.wantPeers.Wait()
t.stateMu.Unlock()
}
}
+// Returns whether the client should make effort to seed the torrent.
+func (cl *Client) seeding(t *torrent) bool {
+ return cl.config.Seed && !cl.config.NoUpload
+}
+
func (cl *Client) announceTorrentDHT(t *torrent, impliedPort bool) {
for cl.waitWantPeers(t) {
log.Printf("getting peers for %q from DHT", t)
log.SetFlags(log.LstdFlags | log.Lshortfile)
var rootGroup struct {
Client torrent.Config `group:"Client Options"`
- Seed bool `long:"seed" description:"continue seeding torrents after completed"`
TestPeers []string `long:"test-peer" description:"address of peer to inject to every torrent"`
}
// Don't pass flags.PrintError because it's inconsistent with printing.
os.Stdout.WriteString(progressLine(client))
}
}
- if rootGroup.Seed {
+ if rootGroup.Client.Seed {
select {}
}
}
NoDHT bool `long:"disable-dht"`
// Overrides the default DHT configuration.
DHTConfig *dht.ServerConfig
- // Don't send chunks to peers.
+ // Don't ever send chunks to peers.
NoUpload bool `long:"no-upload"`
+ // Upload even after there's nothing in it for us. By default uploading is
+ // not altruistic.
+ Seed bool `long:"seed"`
// User-provided Client peer ID. If not present, one is generated automatically.
PeerID string
// For the bittorrent protocol.
UnwantedChunksReceived int
UsefulChunksReceived int
+ chunksSent int
lastMessageReceived time.Time
completedHandshake time.Time
eventAgeString(cn.lastMessageReceived),
eventAgeString(cn.completedHandshake),
eventAgeString(cn.lastUsefulChunkReceived))
- fmt.Fprintf(w, " %s completed, good chunks: %d/%d reqs: %d-%d, flags: %s\n",
+ fmt.Fprintf(w,
+ " %s completed, good chunks: %d/%d-%d reqq: %d-%d, flags: %s\n",
cn.completedString(t),
cn.UsefulChunksReceived,
cn.UnwantedChunksReceived+cn.UsefulChunksReceived,
+ cn.chunksSent,
len(cn.Requests),
len(cn.PeerRequests),
- cn.statusFlags())
+ cn.statusFlags(),
+ )
}
func (c *connection) Close() {