From d7e3c9d1e968a1229f5a1fabb547605a42d59d3c Mon Sep 17 00:00:00 2001 From: Rsclub2_2 Date: Mon, 24 Jun 2024 21:38:02 +0200 Subject: [PATCH] =?UTF-8?q?udp=5Frelay.py=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- udp_relay.py | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 udp_relay.py diff --git a/udp_relay.py b/udp_relay.py new file mode 100644 index 0000000..17a7dfd --- /dev/null +++ b/udp_relay.py @@ -0,0 +1,86 @@ +import socket +import threading +import time +import argparse +import hashlib + +# Konfigurationsparameter +LOOPBACK_TIMEOUT = 1 # Zeit in Sekunden, um Loopback zu verhindern + +# Speichert gesendete Nachrichten-Hashes für eine kurze Zeit, um Loopback zu verhindern +recent_messages = {} + +def create_socket(port, bind_ip=''): + """Erstellt und konfiguriert den UDP-Socket zum Lauschen auf Broadcast-Nachrichten.""" + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + sock.bind((bind_ip, port)) + return sock + +def hash_message(message): + """Erzeugt einen Hash-Wert für eine Nachricht.""" + return hashlib.sha256(message).hexdigest() + +def should_forward_message(message): + """Überprüft, ob eine Nachricht innerhalb des Zeitlimits bereits gesendet wurde.""" + current_time = time.time() + message_hash = hash_message(message) + + # Entferne alte Nachrichten + for msg_hash in list(recent_messages): + if current_time - recent_messages[msg_hash] > LOOPBACK_TIMEOUT: + del recent_messages[msg_hash] + + if message_hash in recent_messages: + print(f"Message already forwarded recently: {message}") + return False + + recent_messages[message_hash] = current_time + return True + +def relay_messages(listen_ip, listen_port, relay_ip, relay_port): + sock = create_socket(listen_port, listen_ip) + print(f"Listening for UDP broadcasts on {listen_ip}:{listen_port}...") + + while True: + data, addr = sock.recvfrom(1024) # Puffergröße 1024 Bytes + print(f"Received message on {listen_ip}:{listen_port} from {addr}: {data}") + + # Prüfen, ob die Nachricht mit "RCVDPKT: \"TELNET\" \"\" \"DX de", "GAB:" oder "SpotUdp" beginnt + if (data.startswith(b'RCVDPKT: "TELNET" "" "DX de') or data.startswith(b'GAB:') or data.startswith(b'SpotUdp')): + if should_forward_message(data): + print(f"Forwarding message to {relay_ip}:{relay_port}") + relay_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + relay_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + relay_socket.sendto(data, (relay_ip, relay_port)) + relay_socket.close() + else: + print(f"Skipped forwarding message due to recent forwarding: {data}") + +def main(): + parser = argparse.ArgumentParser(description="Bidirektionales UDP-Relay mit zeitbasierter Loopback-Prüfung") + parser.add_argument('--ip1', type=str, required=True, help='Erste IP-Adresse') + parser.add_argument('--port1', type=int, required=True, help='Erster Port') + parser.add_argument('--ip2', type=str, required=True, help='Zweite IP-Adresse') + parser.add_argument('--port2', type=int, required=True, help='Zweiter Port') + + args = parser.parse_args() + + ip1 = args.ip1 + port1 = args.port1 + ip2 = args.ip2 + port2 = args.port2 + + # Starten von zwei Threads für bidirektionales Relay mit zeitbasierter Loopback-Prüfung + thread1 = threading.Thread(target=relay_messages, args=(ip1, port1, ip2, port2)) + thread2 = threading.Thread(target=relay_messages, args=(ip2, port2, ip1, port1)) + + thread1.start() + thread2.start() + + thread1.join() + thread2.join() + +if __name__ == "__main__": + main()