Skip to main content

Lightweight async TCP/UDP port forwarding utility built on asyncio

Project description

aio-network-forward

💡 Overview

aio-network-forward is a lightweight and user-friendly library for creating asynchronous TCP and UDP port forwards in Python. Built on top of asyncio and aio-sockets, it exposes a very small API for starting and stopping local forwarding endpoints without dealing with the low-level socket lifecycle yourself.

This library is useful when you want to proxy a local port to another TCP or UDP service, build small tunneling utilities, or embed simple forwarding behavior directly into your own async applications.

✨ Features

Simple Port Forwarding API: Start or stop TCP and UDP forwarding with just a few coroutine calls.

Automatic Port Fallback: If the requested local port is already in use, the library can fall back to a random available port.

Bidirectional Relay: TCP traffic is proxied in both directions, and UDP replies are relayed back to the original sender automatically.

IPv4 and IPv6 Support: Address family is selected automatically from the target address.

Embeddable Design: The library is easy to integrate into existing asyncio applications and lets you customize logging and listening addresses.

📦 Installation

Install from PyPI:

pip install aio-network-forward aio-sockets

Minimum supported version: Python 3.8

Usage

Basic Forward Example

The example below shows both TCP and UDP usage. Replace the startup line depending on which protocol you want to forward.

import asyncio
import aio_sockets as aio
import aio_network_forward as aionf


async def main():
    forward_to = ("127.0.0.1", 8686)

    # TCP
    local_port = await aionf.start_forward_tcp(forward_to, 8080)

    # UDP
    # local_port = await aionf.start_forward_udp(forward_to, 8080)

    print(f"forwarding started on 0.0.0.0:{local_port} -> {forward_to[0]}:{forward_to[1]}")
    await aio.wait_all_tasks_done()


asyncio.run(main())

Bind to a Random Local Port

If the preferred local port is unavailable, the library will automatically retry with a random available port. You can also pass 0 directly if you always want the OS to choose one.

import asyncio
import aio_sockets as aio
import aio_network_forward as aionf


async def main():
    forward_to = ("127.0.0.1", 8686)
    local_port = await aionf.start_forward_tcp(forward_to, 0)
    print(f"allocated local port: {local_port}")
    await aio.wait_all_tasks_done()


asyncio.run(main())

Limit Listening Address to Localhost

By default, the module listens on 0.0.0.0 for IPv4 and :: for IPv6. You can change that behavior before starting the forward.

import asyncio
import aio_sockets as aio
import aio_network_forward as aionf


async def main():
    aionf.aio_network_forward._listen_ipv4 = "127.0.0.1"
    aionf.aio_network_forward._listen_ipv6 = "::1"

    forward_to = ("127.0.0.1", 8686)
    local_port = await aionf.start_forward_tcp(forward_to, 8585)
    print(f"listening on localhost:{local_port}")
    await aio.wait_all_tasks_done()


asyncio.run(main())

HTTP Forward Demo

This repository includes network_forward_demo.py, which starts a local HTTP server on 127.0.0.1:8686, then exposes it through a forwarding port.

python network_forward_demo.py

After startup, you can open the forwarded address shown in the logs, for example:

http://127.0.0.1:8585

API

start_forward_tcp(forward_to_addr, local_port) -> int

Start a local TCP forward to forward_to_addr and return the actual listening port.

stop_forward_tcp(forward_to_addr) -> None

Stop the TCP forward associated with forward_to_addr and close related forwarded sockets.

start_forward_udp(forward_to_addr, local_port) -> int

Start a local UDP forward to forward_to_addr and return the actual listening port.

stop_forward_udp(forward_to_addr) -> None

Stop the UDP forward associated with forward_to_addr.

Notes

This project depends on aio-sockets for its socket wrapper utilities.

start_forward_tcp() and start_forward_udp() create background tasks only. In a standalone script, you should keep the main coroutine alive with await aio.wait_all_tasks_done(), otherwise the program will exit immediately after startup.

UDP forwarding keeps a temporary per-client forwarding socket and closes it automatically after a period of inactivity.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aio_network_forward-0.1.0.tar.gz (9.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aio_network_forward-0.1.0-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file aio_network_forward-0.1.0.tar.gz.

File metadata

  • Download URL: aio_network_forward-0.1.0.tar.gz
  • Upload date:
  • Size: 9.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for aio_network_forward-0.1.0.tar.gz
Algorithm Hash digest
SHA256 194323d0315bdeeaeb5ff3dbf8e73b6c569a3944fec8f314eef4dfc78056dd05
MD5 af9a19f42e6571992741499a31d5f59a
BLAKE2b-256 54bf11b9b2c9c61b94f4498e88d0933c95db0f251c66ed2b98b2f6e1822fa9ac

See more details on using hashes here.

File details

Details for the file aio_network_forward-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for aio_network_forward-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b60fff00f6b8532dc40f440f58780bd26c779a0d670ac54d7d07a88b6ee33f1a
MD5 d60540a93d76b9ca6ad84d7e0c98be37
BLAKE2b-256 d810d904a6f48d4dccc16cd670aeec6e4f45d773a2bef6998f1e4e50774ea77b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page