torrent

package
v0.0.0-...-52a38d9 Latest Latest
Warning

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

Go to latest
Published: Dec 22, 2014 License: BSD-3-Clause Imports: 30 Imported by: 1

Documentation

Overview

Compute missing pieces for a torrent.

Index

Constants

View Source
const (
	MAX_NUM_PEERS    = 60
	TARGET_NUM_PEERS = 15
)
View Source
const (
	CHOKE = iota
	UNCHOKE
	INTERESTED
	NOT_INTERESTED
	HAVE
	BITFIELD
	REQUEST
	PIECE
	CANCEL
	PORT      // Not implemented. For DHT support.
	EXTENSION = 20
)

BitTorrent message types. Sources: http://bittorrent.org/beps/bep_0003.html http://wiki.theory.org/BitTorrentSpecification

View Source
const (
	METADATA_REQUEST = iota
	METADATA_DATA
	METADATA_REJECT
)
View Source
const (
	EXTENSION_HANDSHAKE = iota
)
View Source
const HIGH_BANDWIDTH_SLOTS = 3
View Source
const MAX_OUR_REQUESTS = 2
View Source
const MAX_PEER_REQUESTS = 10
View Source
const MinimumPieceLength = 16 * 1024
View Source
const OPTIMISTIC_UNCHOKE_COUNT = 3

How many cycles of this algorithm before we pick a new optimistic

View Source
const OPTIMISTIC_UNCHOKE_INDEX = HIGH_BANDWIDTH_SLOTS
View Source
const STANDARD_BLOCK_LENGTH = 16 * 1024
View Source
const TargetPieceCountLog2 = 10
View Source
const TargetPieceCountMax = TargetPieceCountMin << 1

Target piece count should be < TargetPieceCountMax

View Source
const TargetPieceCountMin = 1 << TargetPieceCountLog2

Variables

This section is empty.

Functions

func CreateListener

func CreateListener(flags *TorrentFlags) (listener net.Listener, externalPort int, err error)

func ListenForPeerConnections

func ListenForPeerConnections(flags *TorrentFlags) (conChan chan *BtConn, listenPort int, err error)

listenForPeerConnections listens on a TCP port for incoming connections and demuxes them to the appropriate active torrentSession based on the InfoHash in the header.

func NewPeerState

func NewPeerState(conn net.Conn) *peerState

func RunTorrents

func RunTorrents(flags *TorrentFlags, torrentFiles []string) (err error)

func WriteMetaInfoBytes

func WriteMetaInfoBytes(root string, w io.Writer) (err error)

Types

type Accumulator

type Accumulator struct {
	// contains filtered or unexported fields
}

An accumulator that keeps track of the rate of increase.

func NewAccumulator

func NewAccumulator(now time.Time, maxRatePeriod time.Duration) (acc *Accumulator)

func (*Accumulator) Add

func (a *Accumulator) Add(now time.Time, amount int64)

func (*Accumulator) DurationUntilRate

func (a *Accumulator) DurationUntilRate(now time.Time, newRate float64) time.Duration

func (*Accumulator) GetRate

func (a *Accumulator) GetRate(now time.Time) float64

func (*Accumulator) GetRateNoUpdate

func (a *Accumulator) GetRateNoUpdate() float64

type ActivePiece

type ActivePiece struct {
	// contains filtered or unexported fields
}

type Announce

type Announce struct {
	Peer     string
	Infohash string
}

type Announcer

type Announcer struct {
	Announces chan *Announce
	// contains filtered or unexported fields
}

func NewAnnouncer

func NewAnnouncer(listenPort uint16) (lpd *Announcer, err error)

func (*Announcer) Announce

func (lpd *Announcer) Announce(ih string)

func (*Announcer) StopAnnouncing

func (lpd *Announcer) StopAnnouncing(ih string)

type Bitset

type Bitset struct {
	// contains filtered or unexported fields
}

func NewBitset

func NewBitset(n int) *Bitset

func NewBitsetFromBytes

func NewBitsetFromBytes(n int, data []byte) *Bitset

Creates a new bitset from a given byte stream. Returns nil if the data is invalid in some way.

func (*Bitset) AndNot

func (b *Bitset) AndNot(b2 *Bitset)

func (*Bitset) Bytes

func (b *Bitset) Bytes() []byte

func (*Bitset) Clear

func (b *Bitset) Clear(index int)

func (*Bitset) FindNextClear

func (b *Bitset) FindNextClear(index int) int

TODO: Make this fast

func (*Bitset) FindNextSet

func (b *Bitset) FindNextSet(index int) int

TODO: Make this fast

func (*Bitset) InRange

func (b *Bitset) InRange(index int) bool

func (*Bitset) IsEndValid

func (b *Bitset) IsEndValid() bool

func (*Bitset) IsSet

func (b *Bitset) IsSet(index int) bool

func (*Bitset) Len

func (b *Bitset) Len() int

func (*Bitset) Set

func (b *Bitset) Set(index int)

type BtConn

type BtConn struct {
	RemoteAddr net.Addr

	Infohash string
	// contains filtered or unexported fields
}

btConn wraps an incoming network connection and contains metadata that helps identify which active torrentSession it's relevant for.

type ByDownloadBPS

type ByDownloadBPS []Choker

func (ByDownloadBPS) Len

func (a ByDownloadBPS) Len() int

func (ByDownloadBPS) Less

func (a ByDownloadBPS) Less(i, j int) bool

func (ByDownloadBPS) Swap

func (a ByDownloadBPS) Swap(i, j int)

type ChokePolicy

type ChokePolicy interface {
	// Only pass in interested peers.
	// mutate the chokers into a list where the first N are to be unchoked.
	Choke(chokers []Choker) (unchokeCount int, err error)
}

type Choker

type Choker interface {
	DownloadBPS() float32 // bps
}

The choking policy's view of a peer. For current policies we only care about identity and download bandwidth.

type ClassicChokePolicy

type ClassicChokePolicy struct {
	// contains filtered or unexported fields
}

Our interpretation of the classic bittorrent choke policy. Expects to be called once every 10 seconds. See the section "Choking and optimistic unchoking" in https://wiki.theory.org/BitTorrentSpecification

func (*ClassicChokePolicy) Choke

func (ccp *ClassicChokePolicy) Choke(chokers []Choker) (unchokeCount int, err error)

type ClientStatusReport

type ClientStatusReport struct {
	Event      string
	InfoHash   string
	PeerId     string
	Port       uint16
	Uploaded   uint64
	Downloaded uint64
	Left       uint64
}

type Device

type Device struct {
	XMLName     xml.Name    `xml:"device"`
	DeviceType  string      `xml:"deviceType"`
	DeviceList  DeviceList  `xml:"deviceList"`
	ServiceList ServiceList `xml:"serviceList"`
}

type DeviceList

type DeviceList struct {
	Device []Device `xml:"device"`
}

type Dialer

type Dialer func(network, addr string) (net.Conn, error)

type Envelope

type Envelope struct {
	XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"`
	Soap    *SoapBody
}

type ExtensionHandshake

type ExtensionHandshake struct {
	M      map[string]int `bencode:"m"`
	P      uint16         `bencode:"p"`
	V      string         `bencode:"v"`
	Yourip string         `bencode:"yourip"`
	Ipv6   string         `bencode:"ipv6"`
	Ipv4   string         `bencode:"ipv4"`
	Reqq   uint16         `bencode:"reqq"`

	MetadataSize uint `bencode:"metadata_size"`
}

type ExternalIPAddress

type ExternalIPAddress struct {
	XMLName xml.Name `xml:"NewExternalIPAddress"`
	IP      string
}

type ExternalIPAddressResponse

type ExternalIPAddressResponse struct {
	XMLName   xml.Name `xml:"GetExternalIPAddressResponse"`
	IPAddress string   `xml:"NewExternalIPAddress"`
}

type File

type File interface {
	io.ReaderAt
	io.WriterAt
	io.Closer
}

Interface for a file. Multiple goroutines may access a File at the same time.

type FileDict

type FileDict struct {
	Length int64
	Path   []string
	Md5sum string
}

type FileStore

type FileStore interface {
	io.ReaderAt
	io.WriterAt
	io.Closer
}

A torrent file store.

func NewFileStore

func NewFileStore(info *InfoDict, fileSystem FileSystem) (f FileStore, totalSize int64, err error)

type FileStoreFileAdapter

type FileStoreFileAdapter struct {
	// contains filtered or unexported fields
}

func (*FileStoreFileAdapter) Close

func (f *FileStoreFileAdapter) Close() (err error)

func (*FileStoreFileAdapter) ReadAt

func (f *FileStoreFileAdapter) ReadAt(p []byte, off int64) (n int, err error)

func (*FileStoreFileAdapter) WriteAt

func (f *FileStoreFileAdapter) WriteAt(p []byte, off int64) (n int, err error)

type FileStoreFileSystemAdapter

type FileStoreFileSystemAdapter struct {
	// contains filtered or unexported fields
}

Adapt a MetaInfoFileSystem into a torrent file store FileSystem

func (*FileStoreFileSystemAdapter) Open

func (f *FileStoreFileSystemAdapter) Open(name []string, length int64) (file File, err error)

type FileSystem

type FileSystem interface {
	Open(name []string, length int64) (file File, err error)
}

Interface for a file system. A file system contains files.

func NewOSFileSystem

func NewOSFileSystem(directory string) (fs FileSystem, err error)

func NewRAMFileSystem

func NewRAMFileSystem() (fs FileSystem, err error)

type InfoDict

type InfoDict struct {
	PieceLength int64 `bencode:"piece length"`
	Pieces      string
	Private     int64
	Name        string
	// Single File Mode
	Length int64
	Md5sum string
	// Multiple File mode
	Files []FileDict
}

type Magnet

type Magnet struct {
	InfoHashes []string
	Names      []string
	Trackers   [][]string
}

type MetaDataExchange

type MetaDataExchange struct {
	Transferring bool
	Pieces       [][]byte
}

type MetaInfo

type MetaInfo struct {
	Info         InfoDict
	InfoHash     string
	Announce     string
	AnnounceList [][]string `bencode:"announce-list"`
	CreationDate string     `bencode:"creation date"`
	Comment      string
	CreatedBy    string `bencode:"created by"`
	Encoding     string
}

func CreateMetaInfoFromFileSystem

func CreateMetaInfoFromFileSystem(fs MetaInfoFileSystem, root string, pieceLength int64, wantMD5Sum bool) (metaInfo *MetaInfo, err error)

Create a MetaInfo for a given file and file system. If fs is nil then the OSMetaInfoFileSystem will be used. If pieceLength is 0 then an optimal piece length will be chosen.

func GetMetaInfo

func GetMetaInfo(dialer Dialer, torrent string) (metaInfo *MetaInfo, err error)

func (*MetaInfo) Bencode

func (m *MetaInfo) Bencode(w io.Writer) (err error)

Encode to Bencode, but only encode non-default values.

func (*MetaInfo) UpdateInfoHash

func (m *MetaInfo) UpdateInfoHash(metaInfo *MetaInfo) (err error)

Updates the InfoHash field. Call this after manually changing the Info data.

type MetaInfoFile

type MetaInfoFile interface {
	io.Closer
	io.Reader
	io.ReaderAt
	Readdirnames(n int) (names []string, err error)
	Stat() (os.FileInfo, error)
}

type MetaInfoFileSystem

type MetaInfoFileSystem interface {
	Open(name string) (MetaInfoFile, error)
	Stat(name string) (os.FileInfo, error)
}

type MetadataMessage

type MetadataMessage struct {
	MsgType   uint8 `bencode:"msg_type"`
	Piece     uint  `bencode:"piece"`
	TotalSize uint  `bencode:"total_size"`
}

type NAT

type NAT interface {
	GetExternalAddress() (addr net.IP, err error)
	AddPortMapping(protocol string, externalPort, internalPort int, description string, timeout int) (mappedExternalPort int, err error)
	DeletePortMapping(protocol string, externalPort, internalPort int) (err error)
}

protocol is either "udp" or "tcp"

func CreatePortMapping

func CreatePortMapping(flags *TorrentFlags) (nat NAT, err error)

createPortMapping creates a NAT port mapping, or nil if none requested or found.

func Discover

func Discover() (nat NAT, err error)

func NewNatPMP

func NewNatPMP(gateway net.IP) (nat NAT)

type NeverChokePolicy

type NeverChokePolicy struct{}

Our naive never-choke policy

func (*NeverChokePolicy) Choke

func (n *NeverChokePolicy) Choke(chokers []Choker) (unchokeCount int, err error)

type OSMetaInfoFileSystem

type OSMetaInfoFileSystem struct {
	// contains filtered or unexported fields
}

func (*OSMetaInfoFileSystem) Open

func (o *OSMetaInfoFileSystem) Open(name string) (MetaInfoFile, error)

func (*OSMetaInfoFileSystem) Stat

func (o *OSMetaInfoFileSystem) Stat(name string) (os.FileInfo, error)

type Root

type Root struct {
	Device Device
}

type Service

type Service struct {
	ServiceType string `xml:"serviceType"`
	ControlURL  string `xml:"controlURL"`
}

type ServiceList

type ServiceList struct {
	Service []Service `xml:"service"`
}

type SessionInfo

type SessionInfo struct {
	PeerId     string
	Port       uint16
	Uploaded   uint64
	Downloaded uint64
	Left       uint64

	UseDHT      bool
	FromMagnet  bool
	HaveTorrent bool

	OurExtensions map[int]string
	ME            *MetaDataExchange
}

type SoapBody

type SoapBody struct {
	XMLName    xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`
	ExternalIP *ExternalIPAddressResponse
}

type TorrentFlags

type TorrentFlags struct {
	Port                int
	FileDir             string
	SeedRatio           float64
	UseDeadlockDetector bool
	UseLPD              bool
	UseDHT              bool
	UseUPnP             bool
	UseNATPMP           bool
	TrackerlessMode     bool

	// The dial function to use. Nil means use net.Dial
	Dial Dialer

	// IP address of gateway used for NAT-PMP
	Gateway string
}

type TorrentSession

type TorrentSession struct {
	M *MetaInfo
	// contains filtered or unexported fields
}

func NewTorrentSession

func NewTorrentSession(flags *TorrentFlags, torrent string, listenPort uint16) (ts *TorrentSession, err error)

func (*TorrentSession) AcceptNewPeer

func (t *TorrentSession) AcceptNewPeer(btconn *BtConn)

func (*TorrentSession) AddPeer

func (t *TorrentSession) AddPeer(btconn *BtConn)

Can be called from any goroutine

func (*TorrentSession) ChoosePiece

func (t *TorrentSession) ChoosePiece(p *peerState) (piece int)

func (*TorrentSession) ClosePeer

func (t *TorrentSession) ClosePeer(peer *peerState)

func (*TorrentSession) DoExtension

func (t *TorrentSession) DoExtension(msg []byte, p *peerState) (err error)

func (*TorrentSession) DoMessage

func (t *TorrentSession) DoMessage(p *peerState, message []byte) (err error)

func (*TorrentSession) DoMetadata

func (t *TorrentSession) DoMetadata(msg []byte, p *peerState)

func (*TorrentSession) DoTorrent

func (t *TorrentSession) DoTorrent()

func (*TorrentSession) Header

func (ts *TorrentSession) Header() (header []byte)

func (*TorrentSession) HintNewPeer

func (ts *TorrentSession) HintNewPeer(peer string)

Try to connect if the peer is not already in our peers. Can be called from any goroutine.

func (*TorrentSession) Quit

func (t *TorrentSession) Quit() (err error)

func (*TorrentSession) RecordBlock

func (t *TorrentSession) RecordBlock(p *peerState, piece, begin, length uint32) (err error)

func (*TorrentSession) RequestBlock

func (t *TorrentSession) RequestBlock(p *peerState) (err error)

func (*TorrentSession) RequestBlock2

func (t *TorrentSession) RequestBlock2(p *peerState, piece int, endGame bool) (err error)

func (*TorrentSession) Shutdown

func (t *TorrentSession) Shutdown() (err error)

type TrackerResponse

type TrackerResponse struct {
	FailureReason  string `bencode:"failure reason"`
	WarningMessage string `bencode:"warning message"`
	Interval       uint
	MinInterval    uint   `bencode:"min interval"`
	TrackerId      string `bencode:"tracker id"`
	Complete       uint
	Incomplete     uint
	Peers          string
	Peers6         string
}

func QueryHTTPTracker

func QueryHTTPTracker(dialer Dialer, report ClientStatusReport, u *url.URL) (tr *TrackerResponse, err error)

func QueryTracker

func QueryTracker(dialer Dialer, report ClientStatusReport, trackerUrl string) (tr *TrackerResponse, err error)

func QueryTrackers

func QueryTrackers(dialer Dialer, announceList [][]string, report ClientStatusReport) (tr *TrackerResponse)

func QueryUDPTracker

func QueryUDPTracker(report ClientStatusReport, u *url.URL) (tr *TrackerResponse, err error)

Jump to

Keyboard shortcuts

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