File Coverage

blib/lib/Net/BitTorrent/Protocol/BEP23.pm
Criterion Covered Total %
statement 58 58 100.0
branch 6 8 75.0
condition n/a
subroutine 11 11 100.0
pod 4 4 100.0
total 79 81 97.5


line stmt bran cond sub pod time code
1 26     26   260034 use v5.40;
  26         248  
2 26     26   365 use feature 'class';
  26         118  
  26         3597  
3 26     26   251 no warnings 'experimental::class';
  26         93  
  26         1483  
4 26     26   890 use Net::BitTorrent::Emitter;
  26         56  
  26         2860  
5             class Net::BitTorrent::Protocol::BEP23 v2.0.0 : isa(Net::BitTorrent::Emitter) {
6 26     26   16882 use Socket qw[inet_pton inet_ntop AF_INET];
  26         137161  
  26         20594  
7              
8 4     4 1 269634 sub pack_peers_ipv4 (@peers) {
  4         11  
  4         7  
9 4         9 my $packed = '';
10 4         12 for my $peer (@peers) {
11              
12             # $peer is { ip => '...', port => ... }
13 4         39 my $ip = inet_pton( AF_INET, $peer->{ip} );
14 4 100       27 die "Invalid IPv4 address: $peer->{ip}" unless defined $ip;
15 3         29 $packed .= $ip . pack( 'n', $peer->{port} );
16             }
17 3         13 return $packed;
18             }
19              
20 6     6 1 5171 sub unpack_peers_ipv4 ($data) {
  6         14  
  6         22  
21 6 100       60 die 'Compact peer list must be a multiple of 6 bytes' if length($data) % 6 != 0;
22 5         12 my @peers;
23 5         46 for ( my $i = 0; $i < length($data); $i += 6 ) {
24 5         19 my $chunk = substr( $data, $i, 6 );
25 5         33 my ( $ip_raw, $port ) = unpack( 'a4 n', $chunk );
26 5         84 push @peers, { ip => inet_ntop( AF_INET, $ip_raw ), port => $port };
27             }
28 5         20 return \@peers;
29             }
30              
31 2     2 1 4 sub pack_peers_ipv6 (@peers) {
  2         4  
  2         4  
32 26     26   366 use Socket qw[inet_pton AF_INET6];
  26         58  
  26         5634  
33 2         4 my $packed = '';
34 2         9 for my $peer (@peers) {
35 1         5 my $ip = inet_pton( AF_INET6, $peer->{ip} );
36 1 50       4 die "Invalid IPv6 address: $peer->{ip}" unless defined $ip;
37 1         5 $packed .= $ip . pack( 'n', $peer->{port} );
38             }
39 2         7 return $packed;
40             }
41              
42 1     1 1 12 sub unpack_peers_ipv6 ($data) {
  1         3  
  1         3  
43 26     26   170 use Socket qw[inet_ntop AF_INET6];
  26         47  
  26         7227  
44 1 50       4 die 'Compact IPv6 peer list must be a multiple of 18 bytes' if length($data) % 18 != 0;
45 1         2 my @peers;
46 1         4 for ( my $i = 0; $i < length($data); $i += 18 ) {
47 1         4 my $chunk = substr( $data, $i, 18 );
48 1         4 my ( $ip_raw, $port ) = unpack( 'a16 n', $chunk );
49 1         25 push @peers, { ip => inet_ntop( AF_INET6, $ip_raw ), port => $port };
50             }
51 1         5 return \@peers;
52             }
53             } 1;