Last active
October 4, 2025 05:23
-
-
Save cnjax/8e96141f5a7ad395c23a5cf03b1bd599 to your computer and use it in GitHub Desktop.
working public stun server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
193.22.17.97:3478 | |
69.20.59.115:3478 | |
stun.l.google.com:19302 | |
stun1.l.google.com:19302 | |
stun2.l.google.com:19302 | |
stun3.l.google.com:19302 | |
stun4.l.google.com:19302 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
import sys | |
import stun | |
from multiprocessing import Process, Queue | |
def stun_query_worker(server, port, result_queue): | |
""" | |
Worker function that performs the STUN query and puts result in queue. | |
""" | |
try: | |
nat_type, external_ip, external_port = stun.get_ip_info( | |
stun_host=server, stun_port=port | |
) | |
result_queue.put({ | |
'success': True, | |
'nat_type': nat_type, | |
'external_ip': external_ip, | |
'external_port': external_port | |
}) | |
except Exception as e: | |
result_queue.put({ | |
'success': False, | |
'error': str(e) | |
}) | |
def test_stun_server(server, port=3478, timeout=2): | |
""" | |
Tests a STUN server with a timeout using multiprocessing. | |
""" | |
print(f"Testing STUN server: {server}:{port} with a {timeout}s timeout...") | |
result_queue = Queue() | |
process = Process(target=stun_query_worker, args=(server, port, result_queue)) | |
try: | |
process.start() | |
process.join(timeout=timeout) | |
if process.is_alive(): | |
# Timeout occurred | |
print(f"Timeout testing STUN server {server}:{port} after {timeout} seconds.") | |
process.terminate() | |
process.join() | |
return False | |
# Process completed, check results | |
if not result_queue.empty(): | |
result = result_queue.get() | |
if result['success']: | |
print(f"STUN server: {server}:{port}") | |
print(f" NAT Type: {result['nat_type']}") | |
print(f" External IP: {result['external_ip']}") | |
print(f" External Port: {result['external_port']}") | |
return True | |
else: | |
print(f"Error with STUN server {server}:{port}: {result['error']}") | |
return False | |
else: | |
print(f"No result received from STUN server {server}:{port}") | |
return False | |
except Exception as e: | |
print(f"An unexpected error occurred with {server}:{port}: {e}") | |
if process.is_alive(): | |
process.terminate() | |
process.join() | |
return False | |
if __name__ == "__main__": | |
if len(sys.argv) < 2: | |
print("Usage: python stun_test.py <server[:port]> [timeout]") | |
print("\nExample:") | |
print(" python stun_test.py 111.121.193.61:3478 2") | |
print(" python stun_test.py 111.121.193.61 2") | |
# Example usage with default server | |
test_stun_server("111.121.193.61", 3478) | |
sys.exit(1) | |
server_address = sys.argv[1] | |
if ":" in server_address: | |
server, port_str = server_address.split(":") | |
try: | |
port = int(port_str) | |
except ValueError: | |
print("Invalid port number.") | |
sys.exit(1) | |
else: | |
server = server_address | |
port = 3478 | |
timeout = 2 # default timeout | |
if len(sys.argv) > 2: | |
try: | |
timeout = int(sys.argv[2]) | |
except ValueError: | |
print("Invalid timeout value. Please provide an integer.") | |
sys.exit(1) | |
test_stun_server(server, port, timeout=timeout) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment