Skip to content

Ports

airvpn.web.services.ports

PortManager

Bases: ClientService

Manages the authenticated user's forwarded ports on AirVPN.

Wraps the AJAX endpoints behind https://airvpn.org/ports/ to list, open, close, and edit forwarded ports, as well as inspect active sessions on a port. Any mutating action (open, close, edit) triggers a poll loop afterward, since AirVPN applies these changes asynchronously on the server side.

Attributes:

Name Type Description
session WebSession

The authenticated web session used for all requests made by this manager.

ecsrf str | None

CSRF token scraped from the ports page, used to authorize AJAX requests. Lazily fetched on first use.

pool str | None

Identifier of the port pool the user belongs to, as reported by the manifest.

ports list[Port]

All ports currently owned by the user.

keys list[Key]

Keys associated with the user's ports, as reported by the manifest.

check_propagation(ddns_name: str, services=['airvpn', 'dnsadvantage', 'cloudflare', 'google', 'opendns'])

Check which DNS services have propagated a dynamic DNS record.

Queries each service in services for the current IPv4/IPv6 resolution of ddns_name, and collects the names of services that have already propagated the record (i.e. return a non-empty address).

Parameters:

Name Type Description Default
ddns_name str

The dynamic DNS hostname to check propagation for.

required
services

Names of DNS services to check. Defaults to ["airvpn", "dnsadvantage", "cloudflare", "google", "opendns"].

['airvpn', 'dnsadvantage', 'cloudflare', 'google', 'opendns']

Returns:

Type Description

list[str]: Names of the services that have propagated the record.

close(port: int | Port)

Close (delete) an existing forwarded port.

Parameters:

Name Type Description Default
port int | Port

Port number or Port instance to close.

required

Raises:

Type Description
InvalidPort

If the given port does not exist.

edit(port: int | Port, device: str | None = None, note: str | None = None, protocol: Literal['both', 'udp', 'tcp'] | None = None, localport: int | None = None, ddns: str | None = None, layer: Literal['both', 'v6', 'v4'] | None = None)

Edit one or more attributes of an existing forwarded port.

Only fields that are not None are sent as edit requests. After submitting the requested edits, blocks until the server finishes applying them.

Parameters:

Name Type Description Default
port int | Port

Port number or Port instance to edit.

required
device str | None

New device name to associate with the port.

None
note str | None

New note/description for the port.

None
protocol Literal['both', 'udp', 'tcp'] | None

New protocol restriction ("both", "udp", or "tcp").

None
localport int | None

New local port to forward to.

None
ddns str | None

New dynamic DNS hostname for the port.

None
layer Literal['both', 'v6', 'v4'] | None

New IP layer restriction ("both", "v6", or "v4").

None

edit_request(name, value, **kwargs)

Send a generic edit_<name> action to the endpoint.

Convenience wrapper around request for the common pattern of editing a single field by name.

Parameters:

Name Type Description Default
name

Name of the field to edit; sent as the edit_{name} action.

required
value

New value to set for the field.

required
**kwargs

Additional form fields to send along with the request (e.g. an id or port identifying the target record).

{}

Returns:

Type Description

The parsed JSON response from the server.

Raises:

Type Description
APIError

If the response is a dict containing a non-None "error" field.

get_sessions(port: int | Port) -> list[PortSession]

Retrieve active sessions for a given port.

Parameters:

Name Type Description Default
port int | Port

Port number or Port instance to query.

required

Returns:

Type Description
list[PortSession]

list[PortSession]: Active sessions currently using the port.

get_used_ports() -> list[int]

Retrieve the list of currently used ports in the primary pool.

Fetches usage data via the "graph" action and returns the ports from the first pool in the response.

Returns:

Type Description
list[int]

list[int]: Port numbers currently in use in the primary pool, or an empty list if the response contains no pool data.

open(port: int | None = None) -> Port

Open (forward) a new port.

Parameters:

Name Type Description Default
port int | None

Port number to open. Must be >= 2048 and not already in use.

None

Returns:

Name Type Description
Port Port

The newly created Port instance.

Raises:

Type Description
InvalidPort

If port is below 2048, or is already in use.

request(action: str, is_act: bool = False, **kwargs)

Send an AJAX action request to the endpoint.

Automatically attaches the CSRF token (fetching it first if not already known) and requests an AJAX-rendered response.

Parameters:

Name Type Description Default
action str

Name of the action to perform.

required
is_act bool

If the action param is act instead.

False
**kwargs

Additional form fields to send along with the request.

{}

Returns:

Type Description

The parsed JSON response from the server.

Raises:

Type Description
APIError

If the response is a dict containing a non-None "error" field.

Search for a run of consecutive free ports.

Asks the server to find amount consecutive unused ports.

Parameters:

Name Type Description Default
amount int

Number of consecutive free ports to search for.

required

Returns:

Type Description
int

The starting port number of the free run, or 0 if no such

int

run of free ports was found.

test_open(port: int | Port) -> list[str]

Test which of a port's active TCP sessions are reachable.

Fetches the sessions for port and, for each non-UDP session, issues a connectivity test against the session's server IP and port.

Parameters:

Name Type Description Default
port int | Port

Port number or Port instance to test.

required

Returns:

Type Description
list[str]

list[Session]: The sessions that passed the connectivity test.

update()

Refresh the manager's state from the server manifest.

Fetches the current manifest and repopulates pool, ports, keys, and the internal port lookup map from the response.