65
67
typedef ProtocolBase ProtocolRead;
66
68
typedef ProtocolBase ProtocolWrite;
70
#if USE_EXTRA_DEBUG == 666
71
// For testing, use a really small buffer.
72
typedef ProtocolBuffer<256> EncryptBuffer;
74
typedef ProtocolBuffer<16384> EncryptBuffer;
68
77
// Find an optimal number for this.
69
78
static const uint32_t read_size = 64;
71
80
PeerConnectionBase();
72
81
virtual ~PeerConnectionBase();
74
void initialize(DownloadMain* download, PeerInfo* p, SocketFd fd, Bitfield* bitfield);
83
void initialize(DownloadMain* download, PeerInfo* p, SocketFd fd, Bitfield* bitfield, EncryptionInfo* encryptionInfo);
77
bool is_up_choked() { return m_up->choked(); }
78
bool is_up_interested() { return m_up->interested(); }
79
bool is_down_choked() { return m_down->choked(); }
80
bool is_down_interested() { return m_down->interested(); }
82
bool is_upload_wanted() const { return m_down->interested() && !m_peerChunks.is_snubbed(); }
86
bool is_up_choked() { return m_upChoke.choked(); }
87
bool is_up_interested() { return m_upChoke.queued(); }
88
bool is_up_snubbed() { return m_upChoke.snubbed(); }
90
bool is_down_queued() { return m_downChoke.queued(); }
91
bool is_down_local_unchoked() { return m_downChoke.unchoked(); }
92
bool is_down_remote_unchoked() { return m_downUnchoked; }
93
bool is_down_interested() { return m_downInterested; }
95
void set_upload_snubbed(bool v);
84
97
bool is_seeder() const { return m_peerChunks.is_seeder(); }
99
bool is_encrypted() const { return m_encryption.is_encrypted(); }
100
bool is_obfuscated() const { return m_encryption.is_obfuscated(); }
86
102
PeerInfo* peer_info() { return m_peerInfo; }
87
103
const PeerInfo* c_peer_info() const { return m_peerInfo; }
88
104
PeerChunks* peer_chunks() { return &m_peerChunks; }
106
DownloadMain* download() { return m_download; }
90
107
RequestList* download_queue() { return &m_downloadQueue; }
92
// Make sure you choke the peer when snubbing. Snubbing a peer will
93
// only cause it not to be unchoked.
95
// Move this stuff to PeerChunks.
96
void set_snubbed(bool v);
98
rak::timer time_last_choked() const { return m_timeLastChoked; }
100
109
// These must be implemented by the child class.
101
110
virtual void initialize_custom() = 0;
103
111
virtual void update_interested() = 0;
105
virtual void receive_finished_chunk(int32_t i) = 0;
106
112
virtual bool receive_keepalive() = 0;
107
void receive_choke(bool v);
114
bool receive_upload_choke(bool choke);
115
bool receive_download_choke(bool choke);
109
117
virtual void event_error();
111
119
void push_unread(const void* data, uint32_t size);
121
void cancel_transfer(BlockTransfer* transfer);
114
124
inline bool read_remaining();
115
125
inline bool write_remaining();
168
174
ChunkHandle m_upChunk;
176
// The interested state no longer follows the spec's wording as it
179
// Thus the same ProtocolBase object now groups the same choke and
180
// interested states togheter, thus for m_up 'interested' means the
181
// remote peer wants upload and 'choke' means we've choked upload to
184
// In the downlod object, 'queued' now means the same as the spec's
185
// 'unchoked', while 'unchoked' means we start requesting pieces.
186
ChokeManagerNode m_upChoke;
187
ChokeManagerNode m_downChoke;
189
bool m_downInterested;
170
192
bool m_sendChoked;
171
193
bool m_sendInterested;
173
rak::timer m_timeLastChoked;
174
196
rak::timer m_timeLastRead;
198
EncryptBuffer* m_encryptBuffer;
199
EncryptionInfo m_encryption;
180
205
m_down->buffer()->move_end(size);
184
PeerConnectionBase::read_remaining() {
185
m_down->buffer()->move_position(read_stream_throws(m_down->buffer()->position(), m_down->buffer()->remaining()));
187
return !m_down->buffer()->remaining();
191
PeerConnectionBase::write_remaining() {
192
m_up->buffer()->move_position(write_stream_throws(m_up->buffer()->position(), m_up->buffer()->remaining()));
194
return !m_up->buffer()->remaining();
198
209
PeerConnectionBase::read_insert_poll_safe() {
199
210
if (m_down->get_state() != ProtocolRead::IDLE)