release 1.5.0: one panel in all channels; Apple apps (iOS, new macOS tab) only in beta/dev
- stable gets the beta panel and server features (new design, presets, firewall, monthly traffic, router failover over all ports/addresses + TCP, altip, HR tab, Windows tab, update banner); ios/ macos/ windows/ sources stay out of stable - menu item "Update to N" under Settings when a new version is out - mobile: top menu no longer stretches to 200px - urllib User-Agent: Cloudflare in front of git.bobyrev.com returns 403 to Python-urllib - docs: GitHub adleibzon-rgb as source, password/uninstall/devices sections, new screenshots, PORTS.md TCP fallback and second IP Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
54
server/phobos-v6relay.py
Normal file
54
server/phobos-v6relay.py
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python3
|
||||
"""IPv6 -> local IPv4 UDP relay for the obfuscator (it speaks IPv4 only).
|
||||
|
||||
Usage: phobos-v6relay.py LISTEN_PORT [TARGET_PORT] [TARGET_HOST]
|
||||
One upstream socket per IPv6 client, so the obfuscator sees a stable
|
||||
client address for the whole session. Idle clients are dropped after 300 s.
|
||||
"""
|
||||
import selectors
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
|
||||
IDLE = 300
|
||||
|
||||
listen_port = int(sys.argv[1])
|
||||
target = (sys.argv[3] if len(sys.argv) > 3 else "127.0.0.1",
|
||||
int(sys.argv[2]) if len(sys.argv) > 2 else listen_port)
|
||||
|
||||
down = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||
down.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
|
||||
down.bind(("::", listen_port))
|
||||
|
||||
sel = selectors.DefaultSelector()
|
||||
sel.register(down, selectors.EVENT_READ, None)
|
||||
clients = {} # v6 addr -> [upstream socket, last seen]
|
||||
|
||||
while True:
|
||||
for key, _ in sel.select(timeout=30):
|
||||
if key.data is None:
|
||||
data, addr = down.recvfrom(65535)
|
||||
c = clients.get(addr)
|
||||
if c is None:
|
||||
up = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
up.connect(target)
|
||||
sel.register(up, selectors.EVENT_READ, addr)
|
||||
c = clients[addr] = [up, 0]
|
||||
c[1] = time.monotonic()
|
||||
try:
|
||||
c[0].send(data)
|
||||
except OSError:
|
||||
pass
|
||||
else:
|
||||
addr = key.data
|
||||
try:
|
||||
down.sendto(key.fileobj.recv(65535), addr)
|
||||
clients[addr][1] = time.monotonic()
|
||||
except OSError:
|
||||
pass
|
||||
now = time.monotonic()
|
||||
for addr, (up, seen) in list(clients.items()):
|
||||
if now - seen > IDLE:
|
||||
sel.unregister(up)
|
||||
up.close()
|
||||
del clients[addr]
|
||||
Reference in New Issue
Block a user