Documentation ¶
Index ¶
- Constants
- Variables
- func BytesOrPanic(peerMsg PeerMsg) []byte
- func DefaultPeerMsgFunc(peerConn *PeerConnection, peerMsg PeerMsg, errChan chan error)
- func DefaultSendHandshakeFunc(peerConn *PeerConnection, myMetainfo *metainfo.MetaInfo) error
- func DefaultWasBlockReceived(misfireChan chan bool) bool
- func IsPeerHandshakeMsg(msgBuf []byte) bool
- func MakePeerId() [20]byte
- func ParseRawPeerMsgLength(msgBuf []byte) (int, error)
- type BitfieldPeerMsg
- type BlockRequester
- type ChokedPeerMsg
- type ErrorWithID
- type HandshakePeerMsg
- func (self *HandshakePeerMsg) Bytes() ([]byte, error)
- func (self *HandshakePeerMsg) GetInfoHash() ([20]byte, error)
- func (self *HandshakePeerMsg) GetPayload() []byte
- func (self *HandshakePeerMsg) GetPeerId() ([20]byte, error)
- func (self *HandshakePeerMsg) SetPayload(b []byte)
- func (self *HandshakePeerMsg) String() string
- type HavePeerMsg
- type InterestedPeerMsg
- type KeepAlivePeerMsg
- type NotInterestedPeerMsg
- type OnConnectFunc
- type OnPeerErrorFunc
- type Peer
- func (self *Peer) Close() error
- func (self *Peer) ConnectWithAllPeers(myMetainfo *metainfo.MetaInfo, targetPeers []*Peer, maxPeerLimit int, ...) error
- func (p *Peer) FromDictInterface(d map[string]interface{})
- func (p *Peer) FromNodeAddr(na krpc.NodeAddr) *Peer
- func (self *Peer) IsDownloading() bool
- func (self *Peer) ListenForPeers(myMetainfo *metainfo.MetaInfo, errChan chan PeerAndError) error
- func (self *Peer) MakeWeak()
- func (self *Peer) MarkAsDownloading()
- func (self *Peer) MarkAsNotDownloading()
- func (p *Peer) String() string
- func (self *Peer) StringifyID() string
- type PeerAndError
- type PeerConnection
- func (self *PeerConnection) ReadPeerMsg() (PeerMsg, error)
- func (self *PeerConnection) RequestNextPiece(availablePeerPieces piece.SafePieces, errChan chan error) int
- func (self *PeerConnection) StartPeerMsgReaderLoop(peerMsgChan chan PeerMsg, errChan chan error)
- func (self *PeerConnection) String() string
- func (self *PeerConnection) WritePeerMsg(peerMsg PeerMsg)
- type PeerMsg
- func BuildPeerBitfieldMsg(pieces piece.SafePieces) (PeerMsg, error)
- func BuildPeerChokedMsg() PeerMsg
- func BuildPeerHandshakeMsg(peerId [20]byte, infohash [20]byte) PeerMsg
- func BuildPeerHandshakeMsgFromRawBytes(msgBuf []byte) (PeerMsg, error)
- func BuildPeerHaveMsg(pieceIdx uint32) PeerMsg
- func BuildPeerInterestedMsg() PeerMsg
- func BuildPeerKeepAliveMsg() PeerMsg
- func BuildPeerNotInterestedMsg() PeerMsg
- func BuildPeerPieceMsg(block *piece.Block) PeerMsg
- func BuildPeerRequestMsg(targetBlock *piece.Block) (PeerMsg, error)
- func BuildPeerUnchokedMsg() PeerMsg
- func GetRandomPeerMsgs(count int) []PeerMsg
- func NewPeerMsgFromBuffer(msgBuf []byte) (PeerMsg, error)
- type PeerMsgFunc
- type Peers
- type PiecePeerMsg
- func (self *PiecePeerMsg) Bytes() ([]byte, error)
- func (self *PiecePeerMsg) GetBlock() (*piece.Block, error)
- func (self *PiecePeerMsg) GetBlockBegin() (uint32, error)
- func (self *PiecePeerMsg) GetBlockBuff() ([]byte, error)
- func (self *PiecePeerMsg) GetPayload() []byte
- func (self *PiecePeerMsg) GetPieceIdx() (int, error)
- func (self *PiecePeerMsg) SetPayload(b []byte)
- func (self *PiecePeerMsg) String() string
- type RequestPeerMsg
- func (self *RequestPeerMsg) Bytes() ([]byte, error)
- func (self *RequestPeerMsg) GetBlock() (*piece.Block, error)
- func (self *RequestPeerMsg) GetBlockBegin() (uint32, error)
- func (self *RequestPeerMsg) GetBlockLength() (uint32, error)
- func (self *RequestPeerMsg) GetPayload() []byte
- func (self *RequestPeerMsg) GetPieceIdx() (int, error)
- func (self *RequestPeerMsg) SetPayload(b []byte)
- func (self *RequestPeerMsg) String() string
- type SendHandshakeFunc
- type UnchokedPeerMsg
- type WasBlockReceivedFunc
Constants ¶
const ( PEERMSG_HANDSHAKE = 99 PEERMSG_KEEP_ALIVE = 98 PEERMSG_CHOKED = 0 PEERMSG_UNCHOKED = 1 PEERMSG_INTERESTED = 2 PEERMSG_NOT_INTERESTED = 3 PEERMSG_HAVE = 4 PEERMSG_BITFIELD = 5 PEERMSG_REQUEST = 6 PEERMSG_PIECE = 7 MAX_PEERMSG_TYPES = 10 )
const BlockRequestReceiveTimeout = time.Duration(15 * time.Second)
const BlockRequestTotalAllowedMisfires = 3
const ReadTimeoutDuration = 20 * time.Second
Variables ¶
var ERR_ACCEPT_CONN = errors.New("ERR_ACCEPT_CONN")
var ERR_ACCEPT_CONN__CLOSED_CONN = errors.New("ERR_ACCEPT_CONN__CLOSED_CONN")
var ERR_BITFIELDPEERMSG = errors.New("ERR_BITFIELDPEERMSG")
var ERR_CONNECT_PEERS = errors.New("ERR_CONNECT_PEERS")
var ERR_DIAL_PEER = errors.New("ERR_DIAL_PEER")
var ERR_LISTEN_FOR_PEERS = errors.New("ERR_LISTEN_FOR_PEERS")
var ERR_PARSE_PEER = errors.New("ERR_PARSE_PEER")
var ERR_PEERCONN_WRITE = errors.New("ERR_PEERCONN_WRITE")
var ERR_PEERCONN_WRITE__CLOSED_CONN = errors.New("ERR_PEERCONN_WRITE__CLOSED_CONN")
var ERR_PEERMSG_BUILD = errors.New("ERR_PEERMSG_BUILD")
var ERR_PEERMSG_FUNC = errors.New("ERR_PEERMSG_FUNC")
var ERR_PEER_HANDSHAKE = errors.New("ERR_PEER_HANDSHAKE")
var ERR_PEER_LISTEN = errors.New("ERR_PEER_LISTEN")
var ERR_PEER_LISTEN_EOF = errors.New("ERR_PEER_LISTEN_EOF")
var ERR_PEER_LISTEN_RESET = errors.New("ERR_PEER_LISTEN_RESET")
var ERR_PEER_LISTEN_TIMEOUT = errors.New("ERR_PEER_LISTEN_TIMEOUT")
var ERR_REQUESTPEERMSG = errors.New("ERR_REQUESTPEERMSG")
var ERR_REQUEST_BLOCK = errors.New("ERR_REQUEST_BLOCK")
var ERR_SEND_HANDSHAKE = errors.New("ERR_SEND_HANDSHAKE")
var ERR_SEND_INTERESTED = errors.New("ERR_SEND_INTERESTED")
Functions ¶
func BytesOrPanic ¶
func DefaultPeerMsgFunc ¶
func DefaultPeerMsgFunc(peerConn *PeerConnection, peerMsg PeerMsg, errChan chan error)
DefaultPeerMsgFunc
func DefaultSendHandshakeFunc ¶
func DefaultSendHandshakeFunc(peerConn *PeerConnection, myMetainfo *metainfo.MetaInfo) error
func DefaultWasBlockReceived ¶
This is a blocking call: we'll either wait for when we receive some data from handlePeerPieceMsg(), or when a timeout occurs
func IsPeerHandshakeMsg ¶
func MakePeerId ¶
func MakePeerId() [20]byte
func ParseRawPeerMsgLength ¶
Types ¶
type BitfieldPeerMsg ¶
type BitfieldPeerMsg struct {
Payload []byte
}
func (*BitfieldPeerMsg) Bytes ¶
func (self *BitfieldPeerMsg) Bytes() ([]byte, error)
func (*BitfieldPeerMsg) GetPayload ¶
func (self *BitfieldPeerMsg) GetPayload() []byte
func (*BitfieldPeerMsg) GetPieceIndices ¶
func (self *BitfieldPeerMsg) GetPieceIndices(maxPieceIdx int) ([]int, error)
func (*BitfieldPeerMsg) SetPayload ¶
func (self *BitfieldPeerMsg) SetPayload(b []byte)
func (*BitfieldPeerMsg) String ¶
func (self *BitfieldPeerMsg) String() string
type BlockRequester ¶
type BlockRequester struct {
// contains filtered or unexported fields
}
func NewBlockRequester ¶
func NewBlockRequester( peerConn *PeerConnection, totalNumOfBlocks int, wasBlockReceivedFunc WasBlockReceivedFunc, fullPieceDownloadedChan chan int, ) *BlockRequester
func (*BlockRequester) BlocksLeft ¶
func (self *BlockRequester) BlocksLeft() int
type ChokedPeerMsg ¶
type ChokedPeerMsg struct {
Payload []byte
}
func (*ChokedPeerMsg) Bytes ¶
func (self *ChokedPeerMsg) Bytes() ([]byte, error)
func (*ChokedPeerMsg) GetPayload ¶
func (self *ChokedPeerMsg) GetPayload() []byte
func (*ChokedPeerMsg) SetPayload ¶
func (self *ChokedPeerMsg) SetPayload(b []byte)
func (*ChokedPeerMsg) String ¶
func (self *ChokedPeerMsg) String() string
type ErrorWithID ¶
type HandshakePeerMsg ¶
type HandshakePeerMsg struct {
Payload []byte
}
func (*HandshakePeerMsg) Bytes ¶
func (self *HandshakePeerMsg) Bytes() ([]byte, error)
func (*HandshakePeerMsg) GetInfoHash ¶
func (self *HandshakePeerMsg) GetInfoHash() ([20]byte, error)
func (*HandshakePeerMsg) GetPayload ¶
func (self *HandshakePeerMsg) GetPayload() []byte
func (*HandshakePeerMsg) GetPeerId ¶
func (self *HandshakePeerMsg) GetPeerId() ([20]byte, error)
func (*HandshakePeerMsg) SetPayload ¶
func (self *HandshakePeerMsg) SetPayload(b []byte)
func (*HandshakePeerMsg) String ¶
func (self *HandshakePeerMsg) String() string
type HavePeerMsg ¶
type HavePeerMsg struct {
Payload []byte
}
func (*HavePeerMsg) Bytes ¶
func (self *HavePeerMsg) Bytes() ([]byte, error)
func (*HavePeerMsg) GetPayload ¶
func (self *HavePeerMsg) GetPayload() []byte
func (*HavePeerMsg) GetPieceIdx ¶
func (self *HavePeerMsg) GetPieceIdx() int
func (*HavePeerMsg) SetPayload ¶
func (self *HavePeerMsg) SetPayload(b []byte)
func (*HavePeerMsg) String ¶
func (self *HavePeerMsg) String() string
type InterestedPeerMsg ¶
type InterestedPeerMsg struct {
Payload []byte
}
func (*InterestedPeerMsg) Bytes ¶
func (self *InterestedPeerMsg) Bytes() ([]byte, error)
func (*InterestedPeerMsg) GetPayload ¶
func (self *InterestedPeerMsg) GetPayload() []byte
func (*InterestedPeerMsg) SetPayload ¶
func (self *InterestedPeerMsg) SetPayload(b []byte)
func (*InterestedPeerMsg) String ¶
func (self *InterestedPeerMsg) String() string
type KeepAlivePeerMsg ¶
type KeepAlivePeerMsg struct {
Payload []byte
}
func (*KeepAlivePeerMsg) Bytes ¶
func (self *KeepAlivePeerMsg) Bytes() ([]byte, error)
func (*KeepAlivePeerMsg) GetPayload ¶
func (self *KeepAlivePeerMsg) GetPayload() []byte
func (*KeepAlivePeerMsg) SetPayload ¶
func (self *KeepAlivePeerMsg) SetPayload(b []byte)
func (*KeepAlivePeerMsg) String ¶
func (self *KeepAlivePeerMsg) String() string
type NotInterestedPeerMsg ¶
type NotInterestedPeerMsg struct {
Payload []byte
}
func (*NotInterestedPeerMsg) Bytes ¶
func (self *NotInterestedPeerMsg) Bytes() ([]byte, error)
func (*NotInterestedPeerMsg) GetPayload ¶
func (self *NotInterestedPeerMsg) GetPayload() []byte
func (*NotInterestedPeerMsg) SetPayload ¶
func (self *NotInterestedPeerMsg) SetPayload(b []byte)
func (*NotInterestedPeerMsg) String ¶
func (self *NotInterestedPeerMsg) String() string
type OnConnectFunc ¶
type OnConnectFunc func(*PeerConnection) error
type OnPeerErrorFunc ¶
type Peer ¶
type Peer struct { Name string // This is just for debugging purposes IP net.IP Port int ID [20]byte FileInfo *fileinfo.FileInfo PeerConnections []*PeerConnection PeerMsgFunc PeerMsgFunc OnConnectFunc OnConnectFunc SendHandshakeFunc SendHandshakeFunc IsWeak bool // contains filtered or unexported fields }
func NewClientPeer ¶
func NewClientPeer( fileInfo *fileinfo.FileInfo, onConnectFunc OnConnectFunc, peerMsgFunc PeerMsgFunc, sendHandshakeFunc SendHandshakeFunc, doTrackMsgs bool, ) (*Peer, error)
NewClientPeer makes a new "Client Peer" (which basically means us: the client) from a metainfo. This project makes the assumption that each peer is coupled to ONE torrent file
func NewTestPeer ¶
func NewTestPeer( idx int, fileInfo *fileinfo.FileInfo, onConnectFunc OnConnectFunc, peerMsgFunc PeerMsgFunc, sendHandshakeFunc SendHandshakeFunc, ) *Peer
func (*Peer) ConnectWithAllPeers ¶
func (self *Peer) ConnectWithAllPeers( myMetainfo *metainfo.MetaInfo, targetPeers []*Peer, maxPeerLimit int, onPeerErrorFunc OnPeerErrorFunc, ) error
ConnectWithAllPeers handshakes and starts the Bittorrent protocol with all 'peers' (limited by 'limit') using the info in 'myMetainfo' XXX Each peer connection is really coupled with ONE torrent file: this would mean that if we're working with more than one torrent file but talking to the same exact peer, there's zero optimization. That's fine for now
func (*Peer) FromDictInterface ¶
Set from the non-compact form in BEP 3.
func (*Peer) IsDownloading ¶
func (*Peer) ListenForPeers ¶
func (self *Peer) ListenForPeers( myMetainfo *metainfo.MetaInfo, errChan chan PeerAndError, ) error
listenForPeers will ASYNCHRONOUSLY establish a TCP socket and listen for new connections. When a new connection is established, it'll wrap it in a PeerConnection and start listening for messages.
XXX Contrary to connectWithPeer(), this function actually can spawn MORE THAN ONE PeerConnection for any peer that talks with it
func (*Peer) MarkAsDownloading ¶
func (self *Peer) MarkAsDownloading()
func (*Peer) MarkAsNotDownloading ¶
func (self *Peer) MarkAsNotDownloading()
func (*Peer) StringifyID ¶
StringifyID provides a simple way to print a peer's ID: since there might be non-ascii characters in a peer's ID, this can mess up a terminal's stdout when debugging things: things function uses an MD5 sum of the ID while retaining the client's information
type PeerAndError ¶
type PeerConnection ¶
type PeerConnection struct { Conn net.Conn ToPeer *Peer FromPeer *Peer // contains filtered or unexported fields }
func DialPeer ¶
func DialPeer( fromPeer *Peer, targetPeer *Peer, errChan chan PeerAndError) (*PeerConnection, error)
func NewPeerConnection ¶
func NewPeerConnection( fromPeer, toPeer *Peer, errChan chan PeerAndError) *PeerConnection
func (*PeerConnection) ReadPeerMsg ¶
func (self *PeerConnection) ReadPeerMsg() (PeerMsg, error)
func (*PeerConnection) RequestNextPiece ¶
func (self *PeerConnection) RequestNextPiece( availablePeerPieces piece.SafePieces, errChan chan error, ) int
RequestNextPiece dequeues self.piecesToDownloadQueue and tries to concurrently reserve and download it. It'll move on to the next piece if it is already reserved. "Downloading" a piece means it'll call 'requestBlockFunc' (AKA send a REQUEST peer msg) for all blocks in that piece, without waiting for the result.
func (*PeerConnection) StartPeerMsgReaderLoop ¶
func (self *PeerConnection) StartPeerMsgReaderLoop( peerMsgChan chan PeerMsg, errChan chan error)
func (*PeerConnection) String ¶
func (self *PeerConnection) String() string
func (*PeerConnection) WritePeerMsg ¶
func (self *PeerConnection) WritePeerMsg(peerMsg PeerMsg)
type PeerMsg ¶
type PeerMsg interface { String() string Bytes() ([]byte, error) GetPayload() []byte SetPayload([]byte) }
func BuildPeerBitfieldMsg ¶
func BuildPeerBitfieldMsg(pieces piece.SafePieces) (PeerMsg, error)
BuildPeerBitfieldMsg will: * Make a 'bitfield' struct of size = fileInfo.PieceLength[0].PieceLength * For each piece, check if it has been downloaded
- Do this by having a function func `(self Piece) isDownloaded()` that loops through all blocks and see their status
* Check the bitfield[pieceIdx] == 0 or 1 based on that * Serialize the bitfield struct to an actual bitfield * Store it in Payload
func BuildPeerChokedMsg ¶
func BuildPeerChokedMsg() PeerMsg
func BuildPeerHandshakeMsg ¶
func BuildPeerHaveMsg ¶
func BuildPeerInterestedMsg ¶
func BuildPeerInterestedMsg() PeerMsg
func BuildPeerKeepAliveMsg ¶
func BuildPeerKeepAliveMsg() PeerMsg
func BuildPeerNotInterestedMsg ¶
func BuildPeerNotInterestedMsg() PeerMsg
func BuildPeerPieceMsg ¶
func BuildPeerUnchokedMsg ¶
func BuildPeerUnchokedMsg() PeerMsg
func GetRandomPeerMsgs ¶
GetRandomPeerMsgs is a utility function to be run in tests: you can panic here
func NewPeerMsgFromBuffer ¶
NewPeerMsgFromBuffer parses 'msgBuf' to make a PeerMsg from the expected messages we can make
type PeerMsgFunc ¶
type PeerMsgFunc func(*PeerConnection, PeerMsg, chan error)
type PiecePeerMsg ¶
type PiecePeerMsg struct {
Payload []byte
}
func (*PiecePeerMsg) Bytes ¶
func (self *PiecePeerMsg) Bytes() ([]byte, error)
func (*PiecePeerMsg) GetBlock ¶
func (self *PiecePeerMsg) GetBlock() (*piece.Block, error)
GetBlock() basically makes a new Block out of the info we have in RequestPeerMsg
func (*PiecePeerMsg) GetBlockBegin ¶
func (self *PiecePeerMsg) GetBlockBegin() (uint32, error)
func (*PiecePeerMsg) GetBlockBuff ¶
func (self *PiecePeerMsg) GetBlockBuff() ([]byte, error)
func (*PiecePeerMsg) GetPayload ¶
func (self *PiecePeerMsg) GetPayload() []byte
func (*PiecePeerMsg) GetPieceIdx ¶
func (self *PiecePeerMsg) GetPieceIdx() (int, error)
func (*PiecePeerMsg) SetPayload ¶
func (self *PiecePeerMsg) SetPayload(b []byte)
func (*PiecePeerMsg) String ¶
func (self *PiecePeerMsg) String() string
type RequestPeerMsg ¶
type RequestPeerMsg struct {
Payload []byte
}
func (*RequestPeerMsg) Bytes ¶
func (self *RequestPeerMsg) Bytes() ([]byte, error)
func (*RequestPeerMsg) GetBlock ¶
func (self *RequestPeerMsg) GetBlock() (*piece.Block, error)
GetBlock() basically makes a new Block out of the info we have in RequestPeerMsg
func (*RequestPeerMsg) GetBlockBegin ¶
func (self *RequestPeerMsg) GetBlockBegin() (uint32, error)
func (*RequestPeerMsg) GetBlockLength ¶
func (self *RequestPeerMsg) GetBlockLength() (uint32, error)
func (*RequestPeerMsg) GetPayload ¶
func (self *RequestPeerMsg) GetPayload() []byte
func (*RequestPeerMsg) GetPieceIdx ¶
func (self *RequestPeerMsg) GetPieceIdx() (int, error)
func (*RequestPeerMsg) SetPayload ¶
func (self *RequestPeerMsg) SetPayload(b []byte)
func (*RequestPeerMsg) String ¶
func (self *RequestPeerMsg) String() string
type SendHandshakeFunc ¶
type SendHandshakeFunc func(*PeerConnection, *metainfo.MetaInfo) error
type UnchokedPeerMsg ¶
type UnchokedPeerMsg struct {
Payload []byte
}
func (*UnchokedPeerMsg) Bytes ¶
func (self *UnchokedPeerMsg) Bytes() ([]byte, error)
func (*UnchokedPeerMsg) GetPayload ¶
func (self *UnchokedPeerMsg) GetPayload() []byte
func (*UnchokedPeerMsg) SetPayload ¶
func (self *UnchokedPeerMsg) SetPayload(b []byte)
func (*UnchokedPeerMsg) String ¶
func (self *UnchokedPeerMsg) String() string