peer

package
v0.0.0-...-8cd3384 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2021 License: BSD-3-Clause Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
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
)
View Source
const BlockRequestReceiveTimeout = time.Duration(15 * time.Second)
View Source
const BlockRequestTotalAllowedMisfires = 3
View Source
const ReadTimeoutDuration = 20 * time.Second

Variables

View Source
var ERR_ACCEPT_CONN = errors.New("ERR_ACCEPT_CONN")
View Source
var ERR_ACCEPT_CONN__CLOSED_CONN = errors.New("ERR_ACCEPT_CONN__CLOSED_CONN")
View Source
var ERR_BITFIELDPEERMSG = errors.New("ERR_BITFIELDPEERMSG")
View Source
var ERR_CONNECT_PEERS = errors.New("ERR_CONNECT_PEERS")
View Source
var ERR_DIAL_PEER = errors.New("ERR_DIAL_PEER")
View Source
var ERR_LISTEN_FOR_PEERS = errors.New("ERR_LISTEN_FOR_PEERS")
View Source
var ERR_PARSE_PEER = errors.New("ERR_PARSE_PEER")
View Source
var ERR_PEERCONN_WRITE = errors.New("ERR_PEERCONN_WRITE")
View Source
var ERR_PEERCONN_WRITE__CLOSED_CONN = errors.New("ERR_PEERCONN_WRITE__CLOSED_CONN")
View Source
var ERR_PEERMSG_BUILD = errors.New("ERR_PEERMSG_BUILD")
View Source
var ERR_PEERMSG_FUNC = errors.New("ERR_PEERMSG_FUNC")
View Source
var ERR_PEER_HANDSHAKE = errors.New("ERR_PEER_HANDSHAKE")
View Source
var ERR_PEER_LISTEN = errors.New("ERR_PEER_LISTEN")
View Source
var ERR_PEER_LISTEN_EOF = errors.New("ERR_PEER_LISTEN_EOF")
View Source
var ERR_PEER_LISTEN_RESET = errors.New("ERR_PEER_LISTEN_RESET")
View Source
var ERR_PEER_LISTEN_TIMEOUT = errors.New("ERR_PEER_LISTEN_TIMEOUT")
View Source
var ERR_REQUESTPEERMSG = errors.New("ERR_REQUESTPEERMSG")
View Source
var ERR_REQUEST_BLOCK = errors.New("ERR_REQUEST_BLOCK")
View Source
var ERR_SEND_HANDSHAKE = errors.New("ERR_SEND_HANDSHAKE")
View Source
var ERR_SEND_INTERESTED = errors.New("ERR_SEND_INTERESTED")

Functions

func BytesOrPanic

func BytesOrPanic(peerMsg PeerMsg) []byte

func DefaultPeerMsgFunc

func DefaultPeerMsgFunc(peerConn *PeerConnection, peerMsg PeerMsg, errChan chan error)

DefaultPeerMsgFunc

func DefaultSendHandshakeFunc

func DefaultSendHandshakeFunc(peerConn *PeerConnection,
	myMetainfo *metainfo.MetaInfo) error

func DefaultWasBlockReceived

func DefaultWasBlockReceived(misfireChan chan bool) bool

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 IsPeerHandshakeMsg(msgBuf []byte) bool

func MakePeerId

func MakePeerId() [20]byte

func ParseRawPeerMsgLength

func ParseRawPeerMsgLength(msgBuf []byte) (int, error)

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 ErrorWithID struct {
	ID    string
	Error error
}

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 OnPeerErrorFunc func(*Peer, error)

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) Close

func (self *Peer) Close() error

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

func (p *Peer) FromDictInterface(d map[string]interface{})

Set from the non-compact form in BEP 3.

func (*Peer) FromNodeAddr

func (p *Peer) FromNodeAddr(na krpc.NodeAddr) *Peer

func (*Peer) IsDownloading

func (self *Peer) IsDownloading() bool

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) MakeWeak

func (self *Peer) MakeWeak()

func (*Peer) MarkAsDownloading

func (self *Peer) MarkAsDownloading()

func (*Peer) MarkAsNotDownloading

func (self *Peer) MarkAsNotDownloading()

func (*Peer) String

func (p *Peer) String() string

func (*Peer) StringifyID

func (self *Peer) StringifyID() string

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 PeerAndError struct {
	Peer  *Peer
	Error error
}

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 BuildPeerHandshakeMsg(peerId [20]byte, infohash [20]byte) PeerMsg

func BuildPeerHandshakeMsgFromRawBytes

func BuildPeerHandshakeMsgFromRawBytes(msgBuf []byte) (PeerMsg, error)

func BuildPeerHaveMsg

func BuildPeerHaveMsg(pieceIdx uint32) PeerMsg

func BuildPeerInterestedMsg

func BuildPeerInterestedMsg() PeerMsg

func BuildPeerKeepAliveMsg

func BuildPeerKeepAliveMsg() PeerMsg

func BuildPeerNotInterestedMsg

func BuildPeerNotInterestedMsg() PeerMsg

func BuildPeerPieceMsg

func BuildPeerPieceMsg(block *piece.Block) PeerMsg

func BuildPeerRequestMsg

func BuildPeerRequestMsg(targetBlock *piece.Block) (PeerMsg, error)

func BuildPeerUnchokedMsg

func BuildPeerUnchokedMsg() PeerMsg

func GetRandomPeerMsgs

func GetRandomPeerMsgs(count int) []PeerMsg

GetRandomPeerMsgs is a utility function to be run in tests: you can panic here

func NewPeerMsgFromBuffer

func NewPeerMsgFromBuffer(msgBuf []byte) (PeerMsg, error)

NewPeerMsgFromBuffer parses 'msgBuf' to make a PeerMsg from the expected messages we can make

type PeerMsgFunc

type PeerMsgFunc func(*PeerConnection, PeerMsg, chan error)

type Peers

type Peers []*Peer

func (*Peers) UnmarshalBencode

func (self *Peers) UnmarshalBencode(b []byte) (err 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

type WasBlockReceivedFunc

type WasBlockReceivedFunc func(chan bool) bool

Jump to

Keyboard shortcuts

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