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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
194323d0315bdeeaeb5ff3dbf8e73b6c569a3944fec8f314eef4dfc78056dd05
|
|
| MD5 |
af9a19f42e6571992741499a31d5f59a
|
|
| BLAKE2b-256 |
54bf11b9b2c9c61b94f4498e88d0933c95db0f251c66ed2b98b2f6e1822fa9ac
|
File details
Details for the file aio_network_forward-0.1.0-py3-none-any.whl.
File metadata
- Download URL: aio_network_forward-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b60fff00f6b8532dc40f440f58780bd26c779a0d670ac54d7d07a88b6ee33f1a
|
|
| MD5 |
d60540a93d76b9ca6ad84d7e0c98be37
|
|
| BLAKE2b-256 |
d810d904a6f48d4dccc16cd670aeec6e4f45d773a2bef6998f1e4e50774ea77b
|