Skip to content

Instantly share code, notes, and snippets.

@cnjax
Last active October 4, 2025 05:23
Show Gist options
  • Save cnjax/8e96141f5a7ad395c23a5cf03b1bd599 to your computer and use it in GitHub Desktop.
Save cnjax/8e96141f5a7ad395c23a5cf03b1bd599 to your computer and use it in GitHub Desktop.
working public stun server
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
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