| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
20
|
|
|
20
|
|
235396
|
use v5.40; |
|
|
20
|
|
|
|
|
76
|
|
|
2
|
20
|
|
|
20
|
|
137
|
use feature 'class'; |
|
|
20
|
|
|
|
|
34
|
|
|
|
20
|
|
|
|
|
3250
|
|
|
3
|
20
|
|
|
20
|
|
131
|
no warnings 'experimental::class'; |
|
|
20
|
|
|
|
|
46
|
|
|
|
20
|
|
|
|
|
2385
|
|
|
4
|
20
|
|
|
20
|
|
10057
|
class Net::BitTorrent::Protocol::PeerHandler v2.0.1 : isa(Net::BitTorrent::Protocol::BEP06) { |
|
|
20
|
|
|
|
|
71
|
|
|
|
20
|
|
|
|
|
35755
|
|
|
5
|
|
|
|
|
|
|
field $peer : reader; |
|
6
|
|
|
|
|
|
|
field $features : param = {}; |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
method set_peer ($p) { |
|
9
|
|
|
|
|
|
|
$peer = $p; |
|
10
|
|
|
|
|
|
|
if ( defined $peer ) { |
|
11
|
|
|
|
|
|
|
builtin::weaken($peer); |
|
12
|
|
|
|
|
|
|
$self->set_parent_emitter($peer); |
|
13
|
|
|
|
|
|
|
} |
|
14
|
|
|
|
|
|
|
} |
|
15
|
|
|
|
|
|
|
ADJUST { |
|
16
|
|
|
|
|
|
|
# Default all features to 1 if not provided |
|
17
|
|
|
|
|
|
|
$features->{bep05} //= 1; # DHT |
|
18
|
|
|
|
|
|
|
$features->{bep06} //= 1; # Fast Extension |
|
19
|
|
|
|
|
|
|
$features->{bep09} //= 1; # Metadata |
|
20
|
|
|
|
|
|
|
$features->{bep10} //= 1; # Extension Protocol |
|
21
|
|
|
|
|
|
|
$features->{bep11} //= 1; # PEX |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# Populate local extensions for BEP 10 |
|
24
|
|
|
|
|
|
|
my $ext = $self->local_extensions; |
|
25
|
|
|
|
|
|
|
$ext->{ut_metadata} = 1 if $features->{bep09}; |
|
26
|
|
|
|
|
|
|
$ext->{ut_pex} = 2 if $features->{bep11}; |
|
27
|
|
|
|
|
|
|
$ext->{ut_holepunch} = 3; |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# Set bits for Extension Protocol (byte 5, 0x10), DHT (byte 7, 0x01), Fast (byte 7, 0x04) |
|
30
|
|
|
|
|
|
|
$self->set_reserved_bit( 5, 0x10 ) if $features->{bep10}; |
|
31
|
|
|
|
|
|
|
$self->set_reserved_bit( 7, 0x01 ) if $features->{bep05}; |
|
32
|
|
|
|
|
|
|
$self->set_reserved_bit( 7, 0x04 ) if $features->{bep06}; |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# Event Listeners |
|
35
|
|
|
|
|
|
|
$self->on( |
|
36
|
|
|
|
|
|
|
handshake => sub ( $self, $ih, $id ) { |
|
37
|
|
|
|
|
|
|
if ( $id eq $self->peer_id ) { |
|
38
|
|
|
|
|
|
|
$self->_emit( log => " [DEBUG] Closing self-connection and banning endpoint\n", level => 'debug' ) if $self->debug; |
|
39
|
|
|
|
|
|
|
if ( $peer && $peer->torrent ) { |
|
40
|
|
|
|
|
|
|
$peer->torrent->ban_peer( $peer->ip, $peer->port ); |
|
41
|
|
|
|
|
|
|
} |
|
42
|
|
|
|
|
|
|
$peer->disconnected() if $peer; |
|
43
|
|
|
|
|
|
|
return; |
|
44
|
|
|
|
|
|
|
} |
|
45
|
|
|
|
|
|
|
if ( $features->{bep10} ) { |
|
46
|
|
|
|
|
|
|
my $res = $self->reserved; |
|
47
|
|
|
|
|
|
|
if ( ord( substr( $res, 5, 1 ) ) & 0x10 ) { |
|
48
|
|
|
|
|
|
|
$self->_emit( log => " [DEBUG] Remote supports BEP 10, sending extended handshake\n", level => 'debug' ) if $self->debug; |
|
49
|
|
|
|
|
|
|
$self->send_ext_handshake(); |
|
50
|
|
|
|
|
|
|
} |
|
51
|
|
|
|
|
|
|
} |
|
52
|
|
|
|
|
|
|
$peer->_emit('handshake_complete') if $peer; |
|
53
|
|
|
|
|
|
|
} |
|
54
|
|
|
|
|
|
|
); |
|
55
|
|
|
|
|
|
|
$self->on( |
|
56
|
|
|
|
|
|
|
ext_handshake => sub ( $self, $data ) { |
|
57
|
|
|
|
|
|
|
$self->_emit( log => " [DEBUG] Received extended handshake from peer\n", level => 'debug' ) if $self->debug; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
); |
|
60
|
|
|
|
|
|
|
$self->on( metadata_request => sub ( $self, $piece ) { $peer->handle_metadata_request($piece) if $peer } ); |
|
61
|
|
|
|
|
|
|
$self->on( |
|
62
|
|
|
|
|
|
|
metadata_data => sub ( $self, $piece, $total_size, $data ) { |
|
63
|
|
|
|
|
|
|
$peer->handle_metadata_data( $piece, $total_size, $data ) if $peer; |
|
64
|
|
|
|
|
|
|
} |
|
65
|
|
|
|
|
|
|
); |
|
66
|
|
|
|
|
|
|
$self->on( metadata_reject => sub ( $self, $piece ) { $peer->handle_metadata_reject($piece) if $peer } ); |
|
67
|
|
|
|
|
|
|
$self->on( |
|
68
|
|
|
|
|
|
|
hash_request => sub ( $self, $root, $proof_layer, $base_layer, $index, $length ) { |
|
69
|
|
|
|
|
|
|
$peer->handle_hash_request( $root, $proof_layer, $base_layer, $index, $length ) if $peer; |
|
70
|
|
|
|
|
|
|
} |
|
71
|
|
|
|
|
|
|
); |
|
72
|
|
|
|
|
|
|
$self->on( |
|
73
|
|
|
|
|
|
|
hashes => sub ( $self, $root, $proof_layer, $base_layer, $index, $length, $hashes ) { |
|
74
|
|
|
|
|
|
|
$peer->handle_hashes( $root, $proof_layer, $base_layer, $index, $length, $hashes ) if $peer; |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
); |
|
77
|
|
|
|
|
|
|
$self->on( |
|
78
|
|
|
|
|
|
|
hash_reject => sub ( $self, $root, $proof_layer, $base_layer, $index, $length ) { |
|
79
|
|
|
|
|
|
|
$peer->handle_hash_reject( $root, $proof_layer, $base_layer, $index, $length ) if $peer; |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
); |
|
82
|
|
|
|
|
|
|
$self->on( |
|
83
|
|
|
|
|
|
|
pex => sub ( $self, $added, $dropped, $added6, $dropped6 ) { $peer->handle_pex( $added, $dropped, $added6, $dropped6 ) if $peer } ); |
|
84
|
|
|
|
|
|
|
$self->on( hp_rendezvous => sub ( $self, $id ) { $peer->handle_hp_rendezvous($id) if $peer && $peer->can('handle_hp_rendezvous') } ); |
|
85
|
|
|
|
|
|
|
$self->on( hp_connect => sub ( $self, $ip, $port ) { $peer->handle_hp_connect( $ip, $port ) if $peer && $peer->can('handle_hp_connect') } ); |
|
86
|
|
|
|
|
|
|
$self->on( hp_error => sub ( $self, $err ) { $peer->handle_hp_error($err) if $peer && $peer->can('handle_hp_error') } ); |
|
87
|
|
|
|
|
|
|
} |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
method _handle_message ( $id, $payload ) { |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# Feature check for Fast Extension (BEP 06) message IDs |
|
92
|
|
|
|
|
|
|
if ( !$features->{bep06} && ( $id >= 13 && $id <= 17 ) ) { |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
# Skip fast extension messages if disabled |
|
95
|
|
|
|
|
|
|
return; |
|
96
|
|
|
|
|
|
|
} |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# Feature check for Extension Protocol (BEP 10) |
|
99
|
|
|
|
|
|
|
if ( !$features->{bep10} && $id == 20 ) { |
|
100
|
|
|
|
|
|
|
return; |
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
if ($peer) { |
|
103
|
|
|
|
|
|
|
$peer->handle_message( $id, $payload ); |
|
104
|
|
|
|
|
|
|
} |
|
105
|
|
|
|
|
|
|
$self->SUPER::_handle_message( $id, $payload ); |
|
106
|
|
|
|
|
|
|
} |
|
107
|
|
|
|
|
|
|
} 1; |