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.1.tar.gz (9.6 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.1-py3-none-any.whl (10.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: aio_network_forward-0.1.1.tar.gz
  • Upload date:
  • Size: 9.6 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.1.tar.gz
Algorithm Hash digest
SHA256 1191746628b6c5fc3cd082aeda54918f81ee650b854e34c5219a6a7eb8e6b909
MD5 712ff945eaa82a29639344079a7c62ad
BLAKE2b-256 37c011db2c40a47373fee5fcf4c102fd0e1bb82d48fb96054eee48c74584853b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aio_network_forward-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8dde3e0025b53600e99370bf05a84b40a69fb362cd67ea6f97fb15cab9caa40d
MD5 346931091140297b074ac959c2400cc2
BLAKE2b-256 93d1e214cf8835e5a37b866728fca4f608aebde279c8b39ed0defe904325bdf3

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