Bug 1013: Don't assume errno is between 0 and 100000
[elinks.git] / src / protocol / bittorrent / peerwire.c
blobf631faff6b4d11ecd5c66e3a6361084f69c03d1a
1 /* BitTorrent peer-wire protocol implementation */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include <errno.h>
8 #include <sys/types.h>
9 #ifdef HAVE_SYS_SOCKET_H
10 #include <sys/socket.h> /* OS/2 needs this after sys/types.h */
11 #endif
12 #ifdef HAVE_NETINET_IN_H
13 #include <netinet/in.h>
14 #endif
15 #ifdef HAVE_ARPA_INET_H
16 #include <arpa/inet.h>
17 #endif
19 #include "elinks.h"
21 #include "config/options.h"
22 #include "main/select.h"
23 #include "main/timer.h"
24 #include "network/connection.h"
25 #include "network/socket.h"
26 #include "osdep/osdep.h"
27 #include "protocol/bittorrent/bittorrent.h"
28 #include "protocol/bittorrent/common.h"
29 #include "protocol/bittorrent/connection.h"
30 #include "protocol/bittorrent/peerconnect.h"
31 #include "protocol/bittorrent/peerwire.h"
32 #include "protocol/bittorrent/piececache.h"
33 #include "protocol/protocol.h"
34 #include "protocol/uri.h"
35 #include "util/bitfield.h"
36 #include "util/memory.h"
37 #include "util/string.h"
40 /* I give to you my sweet surrender. */
42 enum bittorrent_handshake_state {
43 BITTORRENT_PEER_HANDSHAKE_OK, /* Completely read and valid. */
44 BITTORRENT_PEER_HANDSHAKE_ERROR, /* The handshake was invalid. */
45 BITTORRENT_PEER_HANDSHAKE_INFO_HASH, /* All up to the hash was ok. */
46 BITTORRENT_PEER_HANDSHAKE_INCOMPLETE, /* All up to now was correct. */
49 /* The size of the handshake for version 1.0 is:
50 * <1:protocolstrlen> <19:protocolstr> <8:reserved> <20:info-hash> <20:peer-id>
51 * In total 68 bytes.*/
52 #define BITTORRENT_PEER_HANDSHAKE_SIZE (1 + 19 + 8 + 20 + 20)
54 /* Storing the version identification part of the handshake as one entity
55 * (length prefix and string) makes it much easier to verify and write. */
56 static const bittorrent_id_T BITTORRENT_ID = "\023BitTorrent protocol";
58 /* Has the last message written to the peer socket been sent or not? */
59 #define bittorrent_peer_is_sending(peer) ((peer)->socket->write_buffer)
62 static enum bittorrent_state
63 do_send_bittorrent_peer_message(struct bittorrent_peer_connection *peer,
64 struct bittorrent_peer_request *message);
66 static enum bittorrent_handshake_state
67 do_read_bittorrent_peer_handshake(struct socket *socket, struct read_buffer *buffer);
70 /* ************************************************************************** */
71 /* Peer state managing: */
72 /* ************************************************************************** */
74 /* Queue requests up to the configured limit. */
75 static void
76 queue_bittorrent_peer_connection_requests(struct bittorrent_peer_connection *peer)
78 int size = get_opt_int("protocol.bittorrent.request_queue_size");
79 int queue_size = list_size(&peer->local.requests);
81 for ( ; queue_size < size; queue_size++) {
82 struct bittorrent_peer_request *request;
84 request = find_bittorrent_peer_request(peer);
85 if (!request) break;
87 /* TODO: Insert rarest first? --jonas */
88 add_to_list_end(peer->local.requests, request);
91 /* Interest in the peer was lost if no request could be queued. */
92 if (list_empty(peer->local.requests))
93 set_bittorrent_peer_not_interested(peer);
96 /* Called both from the choke period handler of the main BitTorrent connection
97 * and upon completion of message sending this handles allocation of peer
98 * requests and sending of anything pending. */
99 /* XXX: Calling this function can cause the peer struct to disappear. */
100 void
101 update_bittorrent_peer_connection_state(struct bittorrent_peer_connection *peer)
103 struct bittorrent_connection *bittorrent = peer->bittorrent;
104 struct bittorrent_piece_cache *cache = bittorrent->cache;
105 struct bittorrent_peer_request *request, *next_request;
106 enum bittorrent_state state;
108 /* Drop connections to other seeders or when a partial download has been
109 * completed. */
110 if ((peer->remote.seeder && bittorrent->mode == BITTORRENT_MODE_SEEDER)
111 || (cache->partial && cache->partial_pieces == cache->completed_pieces)) {
112 done_bittorrent_peer_connection(peer);
113 return;
116 if (peer->local.interested && !peer->local.choked)
117 queue_bittorrent_peer_connection_requests(peer);
119 /* Is there a write in progress? */
120 if (bittorrent_peer_is_sending(peer)) {
121 assert(get_handler(peer->socket->fd, SELECT_HANDLER_WRITE));
122 return;
125 /* Send the shorter state messages first ... */
127 /* Send any peer state oriented messages. */
128 foreachsafe (request, next_request, peer->queue) {
129 state = do_send_bittorrent_peer_message(peer, request);
130 if (state == BITTORRENT_STATE_OK)
131 return;
134 /* Send local piece requests which has not already been requested. */
135 foreachsafe (request, next_request, peer->local.requests) {
136 if (request->requested)
137 continue;
139 request->id = BITTORRENT_MESSAGE_REQUEST;
141 state = do_send_bittorrent_peer_message(peer, request);
142 if (state == BITTORRENT_STATE_OK)
143 return;
146 /* Ship the longer piece data messages. */
147 foreachsafe (request, next_request, peer->remote.requests) {
148 request->id = BITTORRENT_MESSAGE_PIECE;
150 state = do_send_bittorrent_peer_message(peer, request);
151 if (state == BITTORRENT_STATE_OK)
152 return;
156 static inline double
157 get_bittorrent_rate(struct bittorrent_peer_stats *stats, time_t now,
158 double rate, uint32_t loaded)
160 return (rate * (stats->last_time - stats->age) + loaded)
161 / (now - stats->age);
164 void
165 update_bittorrent_peer_connection_stats(struct bittorrent_peer_connection *peer,
166 uint32_t downloaded, uint32_t have_piece,
167 uint32_t uploaded)
169 struct bittorrent_peer_stats *stats = &peer->stats;
170 time_t now = time(NULL);
172 stats->download_rate = get_bittorrent_rate(stats, now, stats->download_rate, downloaded);
173 stats->have_rate = get_bittorrent_rate(stats, now, stats->have_rate, have_piece);
175 stats->downloaded += downloaded;
176 stats->uploaded += uploaded;
177 stats->last_time = now;
179 /* Push the age along, so it will be no older than the requested number
180 * of seconds. */
181 if (stats->age < now - 20)
182 stats->age = stats->age ? now - 20 : now - 1;
186 /* ************************************************************************** */
187 /* Peer message handling: */
188 /* ************************************************************************** */
190 /* The layout of the length prefixed peer messages.
192 * - All indexes and offsets are encoded as 4-bytes big-endian.
193 * - Indexes are zero-based.
194 * - Variable length fields depends on the message length.
195 * - All messages begin with <4:message-length> <1:message-id>
196 * The only exception is the keep-alive message which has length set to zero
197 * and doesn't carry any message ID or payload.
199 * Message without payload:
200 * ------------------------
202 * - choke
203 * - unchoke
204 * - interested
205 * - not-interested
207 * Messages with payload:
208 * ----------------------
210 * - have: <4:piece-index>
211 * - bitfield: <x:bitfield-data>
212 * - request and cancel: <4:piece-index> <4:piece-offset> <4:block-length>
213 * - piece: <4:piece-index> <4:piece-offset> <x:block-data>
217 /* ************************************************************************** */
218 /* Peer message sending: */
219 /* ************************************************************************** */
221 /* Meesage write completion callback. */
222 static void
223 sent_bittorrent_peer_message(struct socket *socket)
225 assert(!socket->write_buffer);
226 /* Check if there are pending messages or requests. */
227 update_bittorrent_peer_connection_state(socket->conn);
230 static inline void
231 add_bittorrent_peer_integer(struct string *string, uint32_t integer)
233 uint32_t data = htonl(integer);
235 add_bytes_to_string(string, (unsigned char *) &data, sizeof(data));
238 /* Common lowlevel backend for composing a peer message and writing it to the
239 * socket. */
240 static enum bittorrent_state
241 do_send_bittorrent_peer_message(struct bittorrent_peer_connection *peer,
242 struct bittorrent_peer_request *message)
244 struct bittorrent_connection *bittorrent = peer->bittorrent;
245 struct string string;
246 unsigned char msgid_str[1] = { (unsigned char) message->id };
247 uint32_t msglen = 0;
249 assert(!bittorrent_peer_is_sending(peer));
250 assert(!get_handler(peer->socket->fd, SELECT_HANDLER_WRITE));
252 if (!init_string(&string))
253 return BITTORRENT_STATE_OUT_OF_MEM;
255 /* Reserve 4 bytes to the message length and add the message ID byte. */
256 add_bytes_to_string(&string, (unsigned char *) &msglen, sizeof(msglen));
258 /* XXX: Can't use add_char_to_string() here because the message ID
259 * can be zero. */
260 if (message->id != BITTORRENT_MESSAGE_KEEP_ALIVE)
261 add_bytes_to_string(&string, msgid_str, 1);
263 switch (message->id) {
264 case BITTORRENT_MESSAGE_HAVE:
266 add_bittorrent_peer_integer(&string, message->piece);
267 assert(string.length == 9);
268 break;
270 case BITTORRENT_MESSAGE_BITFIELD:
272 struct bitfield *bitfield = bittorrent->cache->bitfield;
273 size_t bytes = get_bitfield_byte_size(bitfield->bitsize);
275 /* Are bitfield messages allowed at this point? */
276 assert(!peer->local.bitfield);
278 add_bytes_to_string(&string, bitfield->bits, bytes);
280 assert(string.length == 5 + bytes);
281 break;
283 case BITTORRENT_MESSAGE_REQUEST:
284 case BITTORRENT_MESSAGE_CANCEL:
286 assert(!peer->local.choked);
288 add_bittorrent_peer_integer(&string, message->piece);
289 add_bittorrent_peer_integer(&string, message->offset);
290 add_bittorrent_peer_integer(&string, message->length);
292 message->requested = 1;
294 assert(string.length == 17);
295 break;
297 case BITTORRENT_MESSAGE_PIECE:
299 unsigned char *data;
301 assert(!peer->remote.choked);
302 assert(test_bitfield_bit(bittorrent->cache->bitfield, message->piece));
304 data = get_bittorrent_piece_cache_data(bittorrent, message->piece);
305 if (!data) {
306 done_string(&string);
307 return BITTORRENT_STATE_CACHE_FAILURE;
310 data += message->offset;
312 add_bittorrent_peer_integer(&string, message->piece);
313 add_bittorrent_peer_integer(&string, message->offset);
314 add_bytes_to_string(&string, data, message->length);
316 update_bittorrent_peer_connection_stats(peer, 0, 0,
317 message->length);
318 update_bittorrent_connection_stats(peer->bittorrent,
319 0, message->length, 0);
320 assert(string.length == 13 + message->length);
321 break;
323 case BITTORRENT_MESSAGE_KEEP_ALIVE:
324 assert(string.length == 4);
325 break;
327 case BITTORRENT_MESSAGE_CHOKE:
328 case BITTORRENT_MESSAGE_UNCHOKE:
329 case BITTORRENT_MESSAGE_INTERESTED:
330 case BITTORRENT_MESSAGE_NOT_INTERESTED:
331 assert(string.length == 5);
332 break;
334 default:
335 INTERNAL("Bad message ID");
338 /* Insert the real message length. */
339 msglen = string.length - sizeof(uint32_t);
340 msglen = htonl(msglen);
341 memcpy(string.source, (unsigned char *) &msglen, sizeof(msglen));
343 /* Any message will cause bitfield messages to become invalid. */
344 peer->local.bitfield = 1;
346 if (message->id != BITTORRENT_MESSAGE_REQUEST) {
347 del_from_list(message);
348 mem_free(message);
351 write_to_socket(peer->socket, string.source, string.length,
352 connection_state(S_TRANS),
353 sent_bittorrent_peer_message);
355 done_string(&string);
357 return BITTORRENT_STATE_OK;
360 /* Highlevel backend for sending peer messages. It handles queuing of messages.
361 * In order to make this function safe to call from any contexts, messages are
362 * NEVER directly written to the peer socket, since that could cause the peer
363 * connection struct to disappear from under us. */
364 void
365 send_bittorrent_peer_message(struct bittorrent_peer_connection *peer,
366 enum bittorrent_message_id message_id, ...)
368 struct bittorrent_peer_request message_store, *message = &message_store;
369 va_list args;
371 memset(message, 0, sizeof(*message));
372 message->id = message_id;
374 va_start(args, message_id);
376 switch (message_id) {
377 case BITTORRENT_MESSAGE_CANCEL:
378 message->piece = va_arg(args, uint32_t);
379 message->offset = va_arg(args, uint32_t);
380 message->length = va_arg(args, uint32_t);
381 break;
383 case BITTORRENT_MESSAGE_HAVE:
384 message->piece = va_arg(args, uint32_t);
385 break;
387 case BITTORRENT_MESSAGE_BITFIELD:
388 case BITTORRENT_MESSAGE_CHOKE:
389 case BITTORRENT_MESSAGE_INTERESTED:
390 case BITTORRENT_MESSAGE_KEEP_ALIVE:
391 case BITTORRENT_MESSAGE_NOT_INTERESTED:
392 case BITTORRENT_MESSAGE_UNCHOKE:
393 break;
395 case BITTORRENT_MESSAGE_REQUEST:
396 case BITTORRENT_MESSAGE_PIECE:
397 /* Piece and piece request messages are generated automaticalle
398 * from the request queue the local and remote peer status. */
399 default:
400 INTERNAL("Bad message ID");
403 va_end(args);
405 message = mem_alloc(sizeof(*message));
406 if (!message) return;
408 memcpy(message, &message_store, sizeof(*message));
410 /* Prioritize bitfield cancel messages by putting them in the start of
411 * the queue so that bandwidth is not wasted. This way bitfield messages
412 * will always be sent before anything else and cancel messages will
413 * always arrive before have messages, which our client prefers. */
414 if (message->id == BITTORRENT_MESSAGE_BITFIELD
415 || message->id == BITTORRENT_MESSAGE_CANCEL)
416 add_to_list(peer->queue, message);
417 else
418 add_to_list_end(peer->queue, message);
422 /* ************************************************************************** */
423 /* Peer message receiving: */
424 /* ************************************************************************** */
426 static inline uint32_t
427 get_bittorrent_peer_integer(struct read_buffer *buffer, int offset)
429 assert(offset + sizeof(uint32_t) <= buffer->length);
430 return ntohl(*((uint32_t *) (buffer->data + offset)));
433 static enum bittorrent_message_id
434 check_bittorrent_peer_message(struct bittorrent_peer_connection *peer,
435 struct read_buffer *buffer, uint32_t *length)
437 uint32_t message_length;
438 enum bittorrent_message_id message_id;
440 *length = 0;
442 assert(peer->remote.handshake);
444 if (buffer->length < sizeof(message_length))
445 return BITTORRENT_MESSAGE_INCOMPLETE;
447 message_length = get_bittorrent_peer_integer(buffer, 0);
449 if (message_length > get_bittorrent_peerwire_max_message_length())
450 return BITTORRENT_MESSAGE_ERROR;
452 if (buffer->length - sizeof(message_length) < message_length)
453 return BITTORRENT_MESSAGE_INCOMPLETE;
455 if (message_length == 0)
456 return BITTORRENT_MESSAGE_KEEP_ALIVE;
458 message_id = buffer->data[sizeof(message_length)];
460 *length = message_length;
462 return message_id;
465 static enum bittorrent_state
466 read_bittorrent_peer_message(struct bittorrent_peer_connection *peer,
467 enum bittorrent_message_id message_id,
468 struct read_buffer *buffer, uint32_t message_length,
469 int *write_errno)
471 struct bittorrent_connection *bittorrent = peer->bittorrent;
472 enum bittorrent_state state;
473 uint32_t piece, offset, length;
474 unsigned char *data;
476 assert(message_id != BITTORRENT_MESSAGE_INCOMPLETE);
478 *write_errno = 0;
480 switch (message_id) {
481 case BITTORRENT_MESSAGE_CHOKE:
482 /* Return all pending requests to the free list. */
483 peer->local.choked = 1;
484 add_requests_to_bittorrent_piece_cache(peer, &peer->local);
486 struct bittorrent_peer_request *message, *next;
488 foreachsafe (message, next, peer->queue) {
489 if (message->id == BITTORRENT_MESSAGE_CANCEL) {
490 del_from_list(message);
491 mem_free(message);
495 break;
497 case BITTORRENT_MESSAGE_UNCHOKE:
498 peer->local.choked = 0;
499 break;
501 case BITTORRENT_MESSAGE_INTERESTED:
502 peer->remote.interested = 1;
503 break;
505 case BITTORRENT_MESSAGE_NOT_INTERESTED:
506 peer->remote.interested = 0;
507 break;
509 case BITTORRENT_MESSAGE_HAVE:
510 if (message_length < sizeof(uint32_t))
511 return BITTORRENT_STATE_ERROR;
513 piece = get_bittorrent_peer_integer(buffer, 5);
514 /* Is piece out of bound? */
515 if (piece >= bittorrent->meta.pieces)
516 break;
518 /* Is the piece already recorded? */
519 if (test_bitfield_bit(peer->bitfield, piece))
520 break;
522 length = get_bittorrent_piece_length(&bittorrent->meta, piece);
523 update_bittorrent_peer_connection_stats(peer, 0, length, 0);
525 set_bitfield_bit(peer->bitfield, piece);
526 peer->remote.seeder = bitfield_is_set(peer->bitfield);
528 update_bittorrent_piece_cache(peer, piece);
530 if (peer->local.interested
531 || test_bitfield_bit(bittorrent->cache->bitfield, piece))
532 break;
534 set_bittorrent_peer_interested(peer);
535 break;
537 case BITTORRENT_MESSAGE_BITFIELD:
538 data = buffer->data + 5;
539 length = message_length - 1; /* Message ID byte. */
541 if (length > get_bitfield_byte_size(peer->bitfield->bitsize))
542 break;
544 /* Are bitfield messages allowed at this point? */
545 if (peer->remote.bitfield)
546 break;
548 /* XXX: The function tail will set the bitfield flag ... */
549 copy_bitfield(peer->bitfield, data, length);
550 peer->remote.seeder = bitfield_is_set(peer->bitfield);
552 update_bittorrent_piece_cache_from_bitfield(peer);
554 /* Force checking of the interested flag. */
555 foreach_bitfield_set (piece, peer->bitfield) {
556 if (test_bitfield_bit(bittorrent->cache->bitfield, piece))
557 continue;
559 set_bittorrent_peer_interested(peer);
560 break;
562 break;
564 case BITTORRENT_MESSAGE_REQUEST:
565 case BITTORRENT_MESSAGE_CANCEL:
566 if (message_length < sizeof(uint32_t) * 3)
567 return BITTORRENT_STATE_ERROR;
569 piece = get_bittorrent_peer_integer(buffer, 5);
570 offset = get_bittorrent_peer_integer(buffer, 9);
571 length = get_bittorrent_peer_integer(buffer, 13);
573 /* FIXME: Should requests be allowed to overlap pieces? */
574 if (peer->remote.choked
575 || piece >= bittorrent->meta.pieces
576 || offset + length > get_bittorrent_piece_length(&bittorrent->meta, piece)
577 || !test_bitfield_bit(bittorrent->cache->bitfield, piece))
578 break;
580 if (length > get_bittorrent_peerwire_max_request_length())
581 return BITTORRENT_STATE_ERROR;
583 if (message_id == BITTORRENT_MESSAGE_REQUEST) {
584 add_bittorrent_peer_request(&peer->remote, piece, offset, length);
585 } else {
586 del_bittorrent_peer_request(&peer->remote, piece, offset, length);
588 break;
590 case BITTORRENT_MESSAGE_PIECE:
591 if (message_length < sizeof(uint32_t) * 2)
592 return BITTORRENT_STATE_ERROR;
594 piece = get_bittorrent_peer_integer(buffer, 5);
595 offset = get_bittorrent_peer_integer(buffer, 9);
596 length = message_length - 9; /* Msg ID byte + 2 ints */
597 data = buffer->data + 13; /* Offset includes msg len */
599 if (peer->local.choked
600 || piece >= bittorrent->meta.pieces
601 || offset + length > get_bittorrent_piece_length(&bittorrent->meta, piece)
602 || length == 0)
603 break;
605 update_bittorrent_peer_connection_stats(peer, length, 0, 0);
606 state = add_to_bittorrent_piece_cache(peer, piece, offset, data, length, write_errno);
607 if (state != BITTORRENT_STATE_OK)
608 return state;
609 break;
611 case BITTORRENT_MESSAGE_KEEP_ALIVE:
612 default:
613 /* Keep-alive messages doesn't require any special handling.
614 * Unknown peer messages are simply dropped. */
615 break;
618 /* Any message will cause bitfield messages to become invalid. */
619 peer->remote.bitfield = 1;
621 return BITTORRENT_STATE_OK;
624 static void
625 read_bittorrent_peer_data(struct socket *socket, struct read_buffer *buffer)
627 struct bittorrent_peer_connection *peer = socket->conn;
629 if (!peer->remote.handshake) {
630 enum bittorrent_handshake_state state;
632 /* We still needs to read the peer ID from the handshake. */
633 state = do_read_bittorrent_peer_handshake(socket, buffer);
634 if (state != BITTORRENT_PEER_HANDSHAKE_OK)
635 return;
637 /* If the handshake was ok'ed see if there are any messages to
638 * read. */
639 assert(peer->remote.handshake);
642 /* All messages atleast contains an integer prefix. */
643 while (buffer->length > sizeof(uint32_t)) {
644 enum bittorrent_message_id message_id;
645 uint32_t length;
646 int write_errno = 0;
648 message_id = check_bittorrent_peer_message(peer, buffer, &length);
649 if (message_id == BITTORRENT_MESSAGE_INCOMPLETE)
650 break;
652 if (message_id == BITTORRENT_MESSAGE_ERROR) {
653 done_bittorrent_peer_connection(peer);
654 return;
657 switch (read_bittorrent_peer_message(peer, message_id, buffer, length, &write_errno)) {
658 case BITTORRENT_STATE_OK:
659 break;
661 case BITTORRENT_STATE_OUT_OF_MEM:
662 abort_connection(peer->bittorrent->conn,
663 connection_state(S_OUT_OF_MEM));
664 return;
666 case BITTORRENT_STATE_ERROR:
667 default:
668 if (!write_errno) {
669 done_bittorrent_peer_connection(peer);
670 return;
673 /* Shutdown on fatal errors! */
674 abort_connection(peer->bittorrent->conn,
675 connection_state_for_errno(write_errno));
676 return;
679 /* Remove the processed data from the input buffer. */
680 kill_buffer_data(buffer, length + sizeof(length));
681 update_bittorrent_connection_stats(peer->bittorrent, 0, 0,
682 length + sizeof(length));
685 update_bittorrent_peer_connection_state(peer);
689 /* ************************************************************************** */
690 /* Peer handshake exchanging: */
691 /* ************************************************************************** */
693 /* XXX: Note, handshake messages are also handled above in the function
694 * read_bittorrnt_peer_data() if it is incomplete when reading it below.
695 * Often, peers will only send up to and including the info hash, so that the
696 * peer ID arrives later. */
698 /* The handshake was sent, so notify the remote peer about completed piece in a
699 * bitfield message and start reading any remaining bits of the handshake or any
700 * other message. */
701 static void
702 sent_bittorrent_peer_handshake(struct socket *socket)
704 struct bittorrent_peer_connection *peer = socket->conn;
705 struct read_buffer *buffer = peer->socket->read_buffer;
707 assert(buffer);
709 /* Only send the bitfield message if there is anything interesting to
710 * report. */
711 if (peer->bittorrent->cache->completed_pieces) {
712 assert(list_empty(peer->queue));
713 send_bittorrent_peer_message(peer, BITTORRENT_MESSAGE_BITFIELD);
716 read_from_socket(peer->socket, buffer, connection_state(S_TRANS),
717 read_bittorrent_peer_data);
720 /* This function is called when a handhake has been read from an incoming
721 * connection and is used as a callback for when a new peer connection has
722 * successfully been established. */
723 void
724 send_bittorrent_peer_handshake(struct socket *socket)
726 struct bittorrent_peer_connection *peer = socket->conn;
727 struct bittorrent_connection *bittorrent = peer->bittorrent;
728 struct bittorrent_meta *meta = &bittorrent->meta;
729 unsigned char reserved[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
730 unsigned char handshake[BITTORRENT_PEER_HANDSHAKE_SIZE];
731 int i = 0;
733 #define add_to_handshake(handshake, i, data) \
734 do { \
735 memcpy((handshake) + (i), data, sizeof(data)); \
736 i += sizeof(data); \
737 } while (0)
739 add_to_handshake(handshake, i, BITTORRENT_ID);
740 add_to_handshake(handshake, i, reserved);
741 add_to_handshake(handshake, i, meta->info_hash);
742 add_to_handshake(handshake, i, bittorrent->peer_id);
744 #undef add_to_handshake
746 assert(handshake[0] == 19);
748 if (!peer->socket->read_buffer) {
749 /* Just return. Failure is handled by alloc_read_buffer(). */
750 peer->socket->read_buffer = alloc_read_buffer(peer->socket);
751 if (!peer->socket->read_buffer) {
752 done_bittorrent_peer_connection(peer);
753 return;
757 peer->local.handshake = 1;
759 /* Temporarily stop processing of all incoming messages while we send
760 * the handshake so that reading of especially the bitfield message
761 * won't cause any interested message to be queued _before_ we have a
762 * chance to send the bitfield message which MUST be first. */
763 clear_handlers(peer->socket->fd);
765 /* Can't use request_.. version because it will create a new read buffer
766 * and we might want to hold on to the old buffer if the peer ID of the
767 * handshake was not read. */
768 write_to_socket(peer->socket, handshake, sizeof(handshake),
769 connection_state(S_TRANS),
770 sent_bittorrent_peer_handshake);
773 #if 0
774 /* DHT is not supported, so commented out. */
775 /* Checks for the DHT flags used by atleast Brams client to indicate it supports
776 * trackerless BitTorrent. */
777 static inline int
778 bittorrent_peer_supports_dht(unsigned char flags[8])
780 return !!(flags[7] & 1);
782 #endif
784 /* This function is called each time there is something from the handshake
785 * message to read. */
786 static enum bittorrent_handshake_state
787 check_bittorrent_peer_handshake(struct bittorrent_peer_connection *peer,
788 struct read_buffer *buffer)
790 bittorrent_id_T info_hash;
791 struct bittorrent_peer *peer_info;
792 enum bittorrent_handshake_state state;
794 if (buffer->length < 20)
795 return BITTORRENT_PEER_HANDSHAKE_INCOMPLETE;
797 if (memcmp(buffer->data, BITTORRENT_ID, sizeof(BITTORRENT_ID)))
798 return BITTORRENT_PEER_HANDSHAKE_ERROR;
800 if (buffer->length < 28)
801 return BITTORRENT_PEER_HANDSHAKE_INCOMPLETE;
803 #if 0
804 /* DHT is not supported, so commented out. */
805 /* Check the reserved flags */
806 peer->remote.dht = bittorrent_peer_supports_dht(&buffer->data[20]);
807 #endif
809 if (buffer->length < 48)
810 return BITTORRENT_PEER_HANDSHAKE_INCOMPLETE;
812 memcpy(info_hash, &buffer->data[28], sizeof(info_hash));
814 if (peer->local.initiater) {
815 struct bittorrent_meta *meta = &peer->bittorrent->meta;
817 assert(peer->bittorrent);
819 /* Check if the info_hash matches the one in the associated
820 * bittorrent connection. */
821 if (memcmp(meta->info_hash, info_hash, sizeof(info_hash)))
822 return BITTORRENT_PEER_HANDSHAKE_ERROR;
824 if (buffer->length < BITTORRENT_PEER_HANDSHAKE_SIZE)
825 return BITTORRENT_PEER_HANDSHAKE_INFO_HASH;
827 /* If we got the peer info using the compact tracker flag there
828 * is no peer ID, so set it. Else check if the peer has sent the
829 * expected ID. */
830 if (bittorrent_id_is_empty(peer->id))
831 memcpy(peer->id, &buffer->data[48], sizeof(peer->id));
833 else if (memcmp(peer->id, &buffer->data[48], sizeof(peer->id)))
834 return BITTORRENT_PEER_HANDSHAKE_ERROR;
836 } else {
837 struct bittorrent_connection *bittorrent = peer->bittorrent;
839 /* If the peer ID is empty we didn't establish the connection. */
840 assert(bittorrent_id_is_empty(peer->id));
842 /* Look-up the bittorrent connection and drop peer connections
843 * to unknown torrents. */
844 if (!bittorrent) {
845 bittorrent = find_bittorrent_connection(info_hash);
846 if (!bittorrent)
847 return BITTORRENT_PEER_HANDSHAKE_ERROR;
849 peer->bittorrent = bittorrent;
851 /* Don't know if this is the right place to do this
852 * initialization, but it is the first time we know how
853 * many bits there should be room for. Also, it feels
854 * safer to have it created before the peer connection
855 * is moved to a bittorrent connection so all other code
856 * can assume it is always there. */
857 peer->bitfield = init_bitfield(bittorrent->meta.pieces);
858 if (!peer->bitfield)
859 return BITTORRENT_PEER_HANDSHAKE_ERROR;
862 /* FIXME: It would be possible to already add the peer to the
863 * neighbor list here. Should we? --jonas */
865 if (buffer->length < BITTORRENT_PEER_HANDSHAKE_SIZE)
866 return BITTORRENT_PEER_HANDSHAKE_INFO_HASH;
868 memcpy(peer->id, &buffer->data[48], sizeof(peer->id));
871 assert(peer->bittorrent);
873 /* Remove any recorded peer from the peer info list. */
874 /* XXX: This has to be done before checking if the peer is known. Since
875 * known in this case means whether the peer already has a connection
876 * associated. */
877 peer_info = get_peer_from_bittorrent_pool(peer->bittorrent, peer->id);
878 if (peer_info) {
879 del_from_list(peer_info);
880 mem_free(peer_info);
883 /* Even if the peer is already associated with a connection we still
884 * needs to check if the ID is known since we might have just gotten it.
885 * Removing it first makes that possible. */
886 del_from_list(peer);
888 /* Check if the peer is already connected to us. */
889 state = bittorrent_id_is_known(peer->bittorrent, peer->id)
890 ? BITTORRENT_PEER_HANDSHAKE_ERROR : BITTORRENT_PEER_HANDSHAKE_OK;
892 /* For unassociated connections; move the peer connection from the list
893 * of unknown pending peer connections to a bittorrent connection's list
894 * of active peers. */
895 add_to_list(peer->bittorrent->peers, peer);
897 return state;
900 /* Common backend for reading handshakes. */
901 static enum bittorrent_handshake_state
902 do_read_bittorrent_peer_handshake(struct socket *socket, struct read_buffer *buffer)
904 struct bittorrent_peer_connection *peer = socket->conn;
905 enum bittorrent_handshake_state state;
907 state = check_bittorrent_peer_handshake(peer, buffer);
909 switch (state) {
910 case BITTORRENT_PEER_HANDSHAKE_OK:
911 /* The whole handshake was successfully read. */
912 peer->remote.handshake = 1;
913 kill_buffer_data(buffer, BITTORRENT_PEER_HANDSHAKE_SIZE);
914 update_bittorrent_connection_stats(peer->bittorrent, 0, 0,
915 BITTORRENT_PEER_HANDSHAKE_SIZE);
917 switch (get_bittorrent_blacklist_flags(peer->id)) {
918 case BITTORRENT_BLACKLIST_PEER_POOL:
919 case BITTORRENT_BLACKLIST_NONE:
920 break;
922 case BITTORRENT_BLACKLIST_MALICIOUS:
923 case BITTORRENT_BLACKLIST_BEHAVIOUR:
924 default:
925 done_bittorrent_peer_connection(peer);
926 return BITTORRENT_PEER_HANDSHAKE_ERROR;
929 if (!peer->local.handshake)
930 send_bittorrent_peer_handshake(socket);
931 break;
933 case BITTORRENT_PEER_HANDSHAKE_INFO_HASH:
934 if (!peer->local.handshake) {
935 send_bittorrent_peer_handshake(socket);
936 /* XXX: The peer connection might have disappear from
937 * under us at this point so do not reregister the
938 * socket for reading. */
939 break;
942 read_from_socket(peer->socket, buffer,
943 connection_state(S_TRANS),
944 read_bittorrent_peer_handshake);
945 break;
947 case BITTORRENT_PEER_HANDSHAKE_ERROR:
948 done_bittorrent_peer_connection(peer);
949 break;
951 case BITTORRENT_PEER_HANDSHAKE_INCOMPLETE:
952 /* The whole handshake was not read so wait for more. */
953 read_from_socket(peer->socket, buffer,
954 connection_state(S_TRANS),
955 read_bittorrent_peer_handshake);
956 break;
959 return state;
962 void
963 read_bittorrent_peer_handshake(struct socket *socket, struct read_buffer *buffer)
965 do_read_bittorrent_peer_handshake(socket, buffer);