package module
v0.0.0-...-796776c Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2017 License: MPL-2.0 Imports: 48 Imported by: 1



CircleCI GoDoc

This repository implements BitTorrent-related packages and command-line utilities in Go. The emphasis is on use as a library from other projects. It's been used 24/7 in production by a downstream, private service since late 2014.

There is support for protocol encryption, DHT, PEX, uTP, and various extensions. See the package documentation for a more complete list. There are several data storage backends provided: blob, file, and mmap, and you can write your own, such as to store data on S3, or in a database. You can use the provided binaries in ./cmd, or use torrent as a library for your own applications.

Many of the sub-packages can be used for other purposes: bencode, and tracker, in particular.


Install the library package with go get, or the provided cmds with go get

Library example

There is a small example in the package documentation.

Other public projects using torrent


There's a branch called mobile that supports binding to torrent with the gomobile tool. It has some API changes as required by gomobile. Checkout the mobile branch, and bind as usual.


Here I'll describe what some of the provided commands in ./cmd do.

Note that the godo command which is invoked in the following examples builds and executes a Go import path, like go run. It's easier to use this convention than to spell out the install/invoke cycle for every single example.


Downloads torrents from the command-line. This first example does not use godo.

$ go get
# Now 'torrent' should be in $GOPATH/bin, which should be in $PATH.
$ torrent 'magnet:?xt=urn:btih:KRWPCX3SJUM4IMM4YF5RPHL6ANPYTQPU'
ubuntu-14.04.2-desktop-amd64.iso [===================================================================>]  99% downloading (1.0 GB/1.0 GB)
2015/04/01 02:08:20 main.go:137: downloaded ALL the torrents
$ md5sum ubuntu-14.04.2-desktop-amd64.iso
1b305d585b1918f297164add46784116  ubuntu-14.04.2-desktop-amd64.iso
$ echo such amaze

torrentfs mounts a FUSE filesystem at -mountDir. The contents are the torrents described by the torrent files and magnet links at -torrentPath. Data for read requests is fetched only as required from the torrent network, and stored at -downloadDir.

$ mkdir mnt torrents
$ godo -mountDir mnt -torrentPath torrents &
$ cd torrents
$ wget
$ cd ..
$ ls mnt
$ pv mnt/ubuntu-14.04.2-desktop-amd64.iso | md5sum
996MB 0:04:40 [3.55MB/s] [========================================>] 100%
1b305d585b1918f297164add46784116  -

Creates a magnet link from a torrent file. Note the extracted trackers, display name, and info hash.

$ godo < ubuntu-14.04.2-desktop-amd64.iso.torrent

Pings DHT nodes with the given network addresses.

$ godo ./cmd/dht-ping
2015/04/01 17:21:23 main.go:33: dht server on [::]:60058
32f54e697351ff4aec29cdbaabf2fbe3467cc267 ( 648.218621ms
ebff36697351ff4aec29cdbaabf2fbe3467cc267 ( 873.864706ms
2/2 responses (100.000000%)



Package torrent implements a torrent client. Goals include:

  • Configurable data storage, such as file, mmap, and piece-based.
  • Downloading on demand: torrent.Reader will request only the data required to satisfy Reads, which is ideal for streaming and torrentfs.

BitTorrent features implemented include:

  • Protocol obfuscation
  • DHT
  • uTP
  • PEX
  • Magnet links
  • IP Blocklists
  • Some IPv6
  • HTTP and UDP tracker clients
  • BEPs:
  • 3: Basic BitTorrent protocol
  • 5: DHT
  • 6: Fast Extension (have all/none only)
  • 7: IPv6 Tracker Extension
  • 9: ut_metadata
  • 10: Extension protocol
  • 11: PEX
  • 12: Multitracker metadata extension
  • 15: UDP Tracker Protocol
  • 20: Peer ID convention ("-GTnnnn-")
  • 23: Tracker Returns Compact Peer Lists
  • 27: Private torrents
  • 29: uTorrent transport protocol
  • 41: UDP Tracker Protocol Extensions
  • 42: DHT Security extension
  • 43: Read-only DHT Nodes
package main

import (


func main() {
	c, _ := torrent.NewClient(nil)
	defer c.Close()
	t, _ := c.AddMagnet("magnet:?xt=urn:btih:ZOCMZQIPFFW7OLLMIC5HUB6BPCSDEOQU")
	log.Print("ermahgerd, torrent downloaded")

Example (FileReader)
package main

import (


func main() {
	var (
		t *torrent.Torrent
		f torrent.File
	r := t.NewReader()
	defer r.Close()
	// Access the parts of the torrent pertaining to f. Data will be
	// downloaded as required, per the configuration of the torrent.Reader.
	_ = missinggo.NewSectionReadSeeker(r, f.Offset(), f.Length())




View Source
const (
	PiecePriorityNone      piecePriority = iota // Not wanted.
	PiecePriorityNormal                         // Wanted.
	PiecePriorityReadahead                      // May be required soon.
	// Succeeds a piece where a read occurred. Currently the same as Now, apparently due to issues with caching.
	PiecePriorityNow // A Reader is reading in this piece.


This section is empty.


This section is empty.


type Client

type Client struct {
	// contains filtered or unexported fields

Clients contain zero or more Torrents. A Client manages a blocklist, the TCP/UDP protocol ports, and DHT as desired.

func NewClient

func NewClient(cfg *Config) (cl *Client, err error)

Creates a new client.

func (*Client) AddDHTNodes

func (cl *Client) AddDHTNodes(nodes []string)

func (*Client) AddMagnet

func (cl *Client) AddMagnet(uri string) (T *Torrent, err error)

func (*Client) AddTorrent

func (cl *Client) AddTorrent(mi *metainfo.MetaInfo) (T *Torrent, err error)

func (*Client) AddTorrentFromFile

func (cl *Client) AddTorrentFromFile(filename string) (T *Torrent, err error)

func (*Client) AddTorrentInfoHash

func (cl *Client) AddTorrentInfoHash(infoHash metainfo.Hash) (t *Torrent, new bool)

func (*Client) AddTorrentInfoHashWithStorage

func (cl *Client) AddTorrentInfoHashWithStorage(infoHash metainfo.Hash, specStorage storage.ClientImpl) (t *Torrent, new bool)

Adds a torrent by InfoHash with a custom Storage implementation. If the torrent already exists then this Storage is ignored and the existing torrent returned with `new` set to `false`

func (*Client) AddTorrentSpec

func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (t *Torrent, new bool, err error)

Add or merge a torrent spec. If the torrent is already present, the trackers will be merged with the existing ones. If the Info isn't yet known, it will be set. The display name is replaced if the new spec provides one. Returns new if the torrent wasn't already in the client. Note that any `Storage` defined on the spec will be ignored if the torrent is already present (i.e. `new` return value is `true`)

func (*Client) BadPeerIPs

func (cl *Client) BadPeerIPs() []string

func (*Client) Close

func (cl *Client) Close()

Stops the client. All connections to peers are closed and all activity will come to a halt.

func (*Client) DHT

func (cl *Client) DHT() *dht.Server

func (*Client) IPBlockList

func (cl *Client) IPBlockList() iplist.Ranger

func (*Client) ListenAddr

func (cl *Client) ListenAddr() net.Addr

func (*Client) PeerID

func (cl *Client) PeerID() string

func (*Client) SetIPBlockList

func (cl *Client) SetIPBlockList(list iplist.Ranger)

func (*Client) Torrent

func (cl *Client) Torrent(ih metainfo.Hash) (t *Torrent, ok bool)

Returns a handle to the given torrent, if it's present in the client.

func (*Client) Torrents

func (cl *Client) Torrents() []*Torrent

Returns handles to all the torrents loaded in the Client.

func (*Client) WaitAll

func (cl *Client) WaitAll() bool

Returns true when all torrents are completely downloaded and false if the client is stopped before that.

func (*Client) WriteStatus

func (cl *Client) WriteStatus(_w io.Writer)

Writes out a human readable status of the client, such as for writing to a HTTP status page.

type Config

type Config struct {
	// Store torrent file data in this directory unless TorrentDataOpener is
	// specified.
	DataDir string `long:"data-dir" description:"directory to store downloaded torrent data"`
	// The address to listen for new uTP and TCP bittorrent protocol
	// connections. DHT shares a UDP socket with uTP unless configured
	// otherwise.
	ListenAddr string `long:"listen-addr" value-name:"HOST:PORT"`
	// Don't announce to trackers. This only leaves DHT to discover peers.
	DisableTrackers bool `long:"disable-trackers"`
	DisablePEX      bool `long:"disable-pex"`
	// Don't create a DHT.
	NoDHT bool `long:"disable-dht"`
	// Overrides the default DHT configuration.
	DHTConfig dht.ServerConfig

	// Never 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, we'll upload slightly more than we download from each
	// peer.
	Seed bool `long:"seed"`
	// Events are data bytes sent in pieces. The burst must be large enough to
	// fit a whole chunk.
	UploadRateLimiter *rate.Limiter
	// The events are bytes read from connections. The burst must be bigger
	// than the largest Read performed on a Conn minus one. This is likely to
	// be the larger of the main read loop buffer (~4096), and the requested
	// chunk size (~16KiB).
	DownloadRateLimiter *rate.Limiter

	// User-provided Client peer ID. If not present, one is generated automatically.
	PeerID string
	// For the bittorrent protocol.
	DisableUTP bool
	// For the bittorrent protocol.
	DisableTCP bool `long:"disable-tcp"`
	// Called to instantiate storage for each added torrent. Builtin backends
	// are in the storage package. If not set, the "file" implementation is
	// used.
	DefaultStorage storage.ClientImpl

	DisableEncryption  bool `long:"disable-encryption"`
	ForceEncryption    bool // Don't allow unobfuscated connections.
	PreferNoEncryption bool

	IPBlocklist iplist.Ranger
	DisableIPv6 bool `long:"disable-ipv6"`
	// Perform logging and any other behaviour that will help debug.
	Debug bool `help:"enable debug logging"`

Override Client defaults.

type ConnStats

type ConnStats struct {
	// Torrent "piece" messages, or data chunks.
	ChunksWritten int64 // Num piece messages sent.
	ChunksRead    int64
	// Total bytes on the wire. Includes handshakes and encryption.
	BytesWritten int64
	BytesRead    int64
	// Data bytes, actual torrent data.
	DataBytesWritten int64
	DataBytesRead    int64

type File

type File struct {
	// contains filtered or unexported fields

Provides access to regions of torrent data that correspond to its files.

func (*File) Cancel

func (f *File) Cancel()

func (*File) DisplayPath

func (f *File) DisplayPath() string

The relative file path for a multi-file torrent, and the torrent name for a single-file torrent.

func (*File) Download

func (f *File) Download()

Requests that all pieces containing data in the file be downloaded.

func (File) FileInfo

func (f File) FileInfo() metainfo.FileInfo

func (*File) Length

func (f *File) Length() int64

func (*File) Offset

func (f *File) Offset() int64

Data for this file begins this far into the torrent.

func (File) Path

func (f File) Path() string

func (*File) PrioritizeRegion

func (f *File) PrioritizeRegion(off, len int64)

Requests that torrent pieces containing bytes in the given region of the file be downloaded.

func (*File) State

func (f *File) State() (ret []FilePieceState)

Returns the state of pieces in this file.

func (*File) Torrent

func (f *File) Torrent() *Torrent

type FilePieceState

type FilePieceState struct {
	Bytes int64 // Bytes within the piece that are part of this File.

type Handle

type Handle interface {

A file-like handle to some torrent data resource.

type Peer

type Peer struct {
	Id     [20]byte
	IP     net.IP
	Port   int
	Source peerSource
	// Peer is known to support encryption.
	SupportsEncryption bool

type PieceState

type PieceState struct {
	Priority piecePriority
	// The piece is available in its entirety.
	Complete bool
	// The piece is being hashed, or is queued for hash.
	Checking bool
	// Some of the piece has been obtained.
	Partial bool

The current state of a piece.

type PieceStateChange

type PieceStateChange struct {
	Index int

type PieceStateRun

type PieceStateRun struct {
	Length int // How many consecutive pieces have this state.

Represents a series of consecutive pieces with the same state.

type Reader

type Reader struct {
	// contains filtered or unexported fields

Accesses Torrent data via a Client. Reads block until the data is available. Seeks and readahead also drive Client behaviour.

func (*Reader) Close

func (r *Reader) Close() error

func (*Reader) Read

func (r *Reader) Read(b []byte) (n int, err error)

func (*Reader) ReadContext

func (r *Reader) ReadContext(b []byte, ctx context.Context) (n int, err error)

func (*Reader) Seek

func (r *Reader) Seek(off int64, whence int) (ret int64, err error)

func (*Reader) SetReadahead

func (r *Reader) SetReadahead(readahead int64)

Configure the number of bytes ahead of a read that should also be prioritized in preparation for further reads.

func (*Reader) SetResponsive

func (r *Reader) SetResponsive()

Don't wait for pieces to complete and be verified. Read calls return as soon as they can when the underlying chunks become available.

func (*Reader) Torrent

func (r *Reader) Torrent() *Torrent

type Torrent

type Torrent struct {
	Status string
	Label  map[string]bool
	// contains filtered or unexported fields

Maintains state of torrent within a Client.

func (*Torrent) Activity

func (t *Torrent) Activity() map[string]bool

func (*Torrent) AddLabel

func (t *Torrent) AddLabel(label string)

func (*Torrent) AddPeers

func (t *Torrent) AddPeers(pp []Peer)

func (*Torrent) AddTrackers

func (t *Torrent) AddTrackers(announceList [][]string)

func (*Torrent) Announce

func (t *Torrent) Announce()

func (*Torrent) BytesCompleted

func (t *Torrent) BytesCompleted() int64

Number of bytes of the entire torrent we have completed.

func (*Torrent) BytesMissing

func (t *Torrent) BytesMissing() int64

func (*Torrent) CancelPieces

func (t *Torrent) CancelPieces(begin, end int)

func (*Torrent) Close

func (t *Torrent) Close() (err error)

func (*Torrent) Closed

func (t *Torrent) Closed() <-chan struct{}

Returns a channel that is closed when the Torrent is closed.

func (*Torrent) DelLabel

func (t *Torrent) DelLabel(label string)

func (*Torrent) DownloadAll

func (t *Torrent) DownloadAll()

Marks the entire torrent for download. Requires the info first, see GotInfo.

func (*Torrent) DownloadPieces

func (t *Torrent) DownloadPieces(begin, end int)

func (*Torrent) Drop

func (t *Torrent) Drop()

Drop the torrent from the client, and close it. It's always safe to do this. No data corruption can, or should occur to either the torrent's data, or connected peers.

func (*Torrent) Files

func (t *Torrent) Files() (ret []File)

Returns handles to the files in the torrent. This requires the metainfo is available first.

func (*Torrent) GetLabel

func (t *Torrent) GetLabel() []string

func (*Torrent) GetStatus

func (t *Torrent) GetStatus() string

func (*Torrent) GotInfo

func (t *Torrent) GotInfo() <-chan struct{}

Returns a channel that is closed when the info (.Info()) for the torrent has become available.

func (*Torrent) Info

func (t *Torrent) Info() *metainfo.Info

Returns the metainfo info dictionary, or nil if it's not yet available.

func (*Torrent) InfoHash

func (t *Torrent) InfoHash() metainfo.Hash

The torrent's infohash. This is fixed and cannot change. It uniquely identifies a torrent.

func (*Torrent) Length

func (t *Torrent) Length() int64

The completed length of all the torrent data, in all its files. This is derived from the torrent info, when it is available.

func (*Torrent) Metainfo

func (t *Torrent) Metainfo() metainfo.MetaInfo

Returns a run-time generated metainfo for the torrent that includes the info bytes and announce-list as currently known to the client.

func (*Torrent) Name

func (t *Torrent) Name() string

The current working name for the torrent. Either the name in the info dict, or a display name given such as by the dn value in a magnet link, or "".

func (*Torrent) NewReader

func (t *Torrent) NewReader() (ret *Reader)

Returns a Reader bound to the torrent's data. All read calls block until the data requested is actually available.

func (*Torrent) NumPieces

func (t *Torrent) NumPieces() int

The number of pieces in the torrent. This requires that the info has been obtained first.

func (*Torrent) PieceState

func (t *Torrent) PieceState(piece int) PieceState

func (*Torrent) PieceStateRuns

func (t *Torrent) PieceStateRuns() []PieceStateRun

Returns the state of pieces of the torrent. They are grouped into runs of same state. The sum of the state run lengths is the number of pieces in the torrent.

func (*Torrent) Reopen

func (t *Torrent) Reopen()

func (*Torrent) Seeding

func (t *Torrent) Seeding() bool

Returns true if the torrent is currently being seeded. This occurs when the client is willing to upload without wanting anything in return.

func (*Torrent) SetDisplayName

func (t *Torrent) SetDisplayName(dn string)

Clobbers the torrent display name. The display name is used as the torrent name if the metainfo is not available.

func (*Torrent) SetInfoBytes

func (t *Torrent) SetInfoBytes(b []byte) (err error)

func (*Torrent) SetMaxEstablishedConns

func (t *Torrent) SetMaxEstablishedConns(max int) (oldMax int)

func (*Torrent) SetStatus

func (t *Torrent) SetStatus(status string)

func (*Torrent) Stats

func (t *Torrent) Stats() TorrentStats

func (*Torrent) String

func (t *Torrent) String() string

func (*Torrent) SubscribePieceStateChanges

func (t *Torrent) SubscribePieceStateChanges() *pubsub.Subscription

The subscription emits as (int) the index of pieces as their state changes. A state change is when the PieceState for a piece alters in value.

type TorrentSpec

type TorrentSpec struct {
	// The tiered tracker URIs.
	Trackers  [][]string
	InfoHash  metainfo.Hash
	InfoBytes []byte
	// The name to use if the Name field from the Info isn't available.
	DisplayName string
	// The chunk size to use for outbound requests. Defaults to 16KiB if not
	// set.
	ChunkSize int
	Storage   storage.ClientImpl

Specifies a new torrent for adding to a client. There are helpers for magnet URIs and torrent metainfo files.

func TorrentSpecFromMagnetURI

func TorrentSpecFromMagnetURI(uri string) (spec *TorrentSpec, err error)

func TorrentSpecFromMetaInfo

func TorrentSpecFromMetaInfo(mi *metainfo.MetaInfo) (spec *TorrentSpec)

type TorrentStats

type TorrentStats struct {
	ConnStats // Aggregates stats over all connections past and present.

	ActivePeers   int
	HalfOpenPeers int
	PendingPeers  int
	TotalPeers    int


Path Synopsis
Pings DHT nodes with the given network addresses.
Pings DHT nodes with the given network addresses.
Converts magnet URIs and info hashes into torrent metainfo files.
Converts magnet URIs and info hashes into torrent metainfo files.
Downloads torrents from the command-line.
Downloads torrents from the command-line.
Downloads torrents from the command-line.
Downloads torrents from the command-line.
Mounts a FUSE filesystem backed by torrents and magnet links.
Mounts a FUSE filesystem backed by torrents and magnet links.
Package iplist handles the P2P Plaintext Format described by
Package iplist handles the P2P Plaintext Format described by
Takes P2P blocklist text format in stdin, and outputs the packed format from the iplist package.
Takes P2P blocklist text format in stdin, and outputs the packed format from the iplist package.
Package logonce implements an io.Writer facade that only performs distinct writes.
Package logonce implements an io.Writer facade that only performs distinct writes.
Package storage implements storage backends for package torrent.
Package storage implements storage backends for package torrent.
Package dirwatch provides filesystem-notification based tracking of torrent info files and magnet URIs in a directory.
Package dirwatch provides filesystem-notification based tracking of torrent info files and magnet URIs in a directory.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL