=pod

=encoding utf-8

=head1 NAME

Net::BitTorrent::Protocol::BEP10 - Extension Protocol Implementation

=head1 SYNOPSIS

    # Inherits from Net::BitTorrent::Protocol::BEP52 (BitTorrent v2)
    use Net::BitTorrent::Protocol::BEP10;

    my $proto = Net::BitTorrent::Protocol::BEP10->new(
        local_extensions => { ut_metadata => 1, ut_pex => 2 }
    );

    # Once core handshake is done, send extension handshake
    $proto->send_ext_handshake();

    # Send an extension message by name
    $proto->send_ext_message( 'ut_pex', $bencoded_pex_data );

=head1 DESCRIPTION

C<Net::BitTorrent::Protocol::BEP10> implements the Extension Protocol (BEP 10). This is the standard mechanism modern
BitTorrent clients use to negotiate support for additional features (like PEX, Magnet links, and DHT security) without
needing to allocate new reserved bits in the foundational BitTorrent handshake.

=head1 METHODS

=head2 C<new( %params )>

Creates a new BEP10 protocol handler.

Expected parameters:

=over

=item C<local_extensions> - optional

A hash reference mapping extension names to local IDs.

=item C<metadata_size> - optional

The total size of the torrent metadata in bytes.

=back

=head2 C<send_ext_handshake( )>

Sends the extension protocol handshake.

    $proto->send_ext_handshake();

This method sends the C<EXTENDED> (ID 20) message with sub-ID 0, containing the local extension dictionary.

=head2 C<send_ext_message( $name, $payload )>

Sends an extended message.

    $proto->send_ext_message( 'ut_metadata', $data );

This method sends a message for a specific extension by its name.

Expected parameters:

=over

=item C<$name>

The string name of the extension (e.g., 'ut_metadata', 'ut_pex').

=item C<$payload>

The raw message payload.

=back

=head2 C<ext_handshake> event

Emitted when an extended handshake is received.

    $proto->on( ext_handshake => sub ( $self, $data ) { ... } );

Expected parameters:

=over

=item C<$data>

The decoded handshake dictionary (hash reference).

=back

=head2 C<extended_message> event

Emitted when an extended message is received.

    $proto->on( extended_message => sub ( $self, $name, $payload ) { ... } );

Expected parameters:

=over

=item C<$name>

The name of the extension.

=item C<$payload>

The raw message payload.

=back

=head2 C<local_extensions( )>

Returns the local extensions map.

    my $exts = $proto->local_extensions();

=head2 C<remote_extensions( )>

Returns the remote extensions map.

    my $exts = $proto->remote_extensions();

=head2 C<remote_version( )>

Returns the remote client's version string.

    say "Remote version: " . $proto->remote_version();

=head2 C<remote_ip( )>

Returns our external IP as seen by the remote peer.

    say "Remote says our IP is: " . $proto->remote_ip();

=head2 C<metadata_size( )>

Returns the total size of the metadata as reported by the peer.

    my $size = $proto->metadata_size();

=head2 C<remote_extensions_received( )>

Returns true if the remote extended handshake has been received.

    if ($proto->remote_extensions_received) { ... }

=head1 SPECIFICATIONS

=over

=item * BEP 10: Extension Protocol

=back

=head1 AUTHOR

Sanko Robinson E<lt>sanko@cpan.orgE<gt>

=head1 COPYRIGHT

Copyright (C) 2008-2026 by Sanko Robinson.

This library is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0.

=cut
