NatPmp

class NatPmp(udp: UdpSocket, gateway: String, maxAttempts: Int = 9, retryStepMs: Long = 250)

A NAT-PMP client: the live half of libtorrent's natpmp (src/natpmp.cpp), speaking the NAT-PMP (RFC 6886) wire format over the proven UdpSocket. The fixed-layout packet build/parse lives in NatPmpCodec; this class owns the UDP round-trip to the gateway (always port 5351, the NAT-PMP server port udp::endpoint(*route, 5351) in natpmp::start) and the retransmission loop.

libtorrent retransmits a NAT-PMP request with a linear back-off (m_send_timer.expires_after(milliseconds(250 * m_retry_count))) and gives up after 9 attempts (m_retry_count >= 9 in resend_request). We reproduce that: each request is sent up to maxAttempts times, the n-th attempt waiting n * [retryStepMs] ms for a reply before retransmitting. Cancellation propagates through structured concurrency.

This class deliberately omits the full mapping table, expiry refresh timer and PCP fallback of the C++. Those belong to the engine's port-mapping manager. It exposes the two request/response transactions a caller needs: query the external address, and add (or, with lifetimeSeconds = 0, delete) a single mapping.

Constructors

Link copied to clipboard
constructor(udp: UdpSocket, gateway: String, maxAttempts: Int = 9, retryStepMs: Long = 250)

Types

Link copied to clipboard
data class MapGrant(val tcp: Boolean, val internalPort: Int, val externalPort: Int, val lifetimeSeconds: Long)

The outcome of a successful mapDetailed: the public port the gateway granted and the lease lifetime it actually assigned (which may differ from what was requested: on_reply adopts both public_port and lifetime from the response). The engine schedules its lease-refresh timer from lifetimeSeconds.

Functions

Link copied to clipboard
suspend fun externalAddress(): String?

Query the gateway for its external (public) IPv4 address (opcode 0). Mirrors natpmp::send_get_ip_address_request โ†’ the cmd == 128 branch of on_reply.

Link copied to clipboard
suspend fun map(internalPort: Int, externalPort: Int, tcp: Boolean, lifetimeSeconds: Int = 3600): Int?

Request a port mapping (opcode 1 for UDP, 2 for TCP). Mirrors the version_natpmp branch of natpmp::send_map_request โ†’ the map branch of on_reply.

Link copied to clipboard
suspend fun mapDetailed(internalPort: Int, externalPort: Int, tcp: Boolean, lifetimeSeconds: Int = 3600): NatPmp.MapGrant?

Like map, but returns the full grant (the granted external port and the lifetime the gateway assigned), so the engine can drive its refresh timer. Mirrors the same send_map_request โ†’ on_reply transaction.