diff --git a/mcstatus/protocol/connection.py b/mcstatus/protocol/connection.py index efc748a..413db26 100644 --- a/mcstatus/protocol/connection.py +++ b/mcstatus/protocol/connection.py @@ -1,6 +1,7 @@ import socket import struct +from ..scripts.address_tools import ip_type class Connection: def __init__(self): @@ -160,7 +161,7 @@ class UDPSocketConnection(Connection): def __init__(self, addr, timeout=3): Connection.__init__(self) self.addr = addr - self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.socket = socket.socket(socket.AF_INET if ip_type(addr[0]) == 4 else socket.AF_INET6, socket.SOCK_DGRAM) self.socket.settimeout(timeout) def flush(self): diff --git a/mcstatus/scripts/address_tools.py b/mcstatus/scripts/address_tools.py new file mode 100644 index 0000000..a14e135 --- /dev/null +++ b/mcstatus/scripts/address_tools.py @@ -0,0 +1,50 @@ +import socket + +def ip_type(address): + try: + socket.inet_pton(socket.AF_INET, address) + except AttributeError: + try: + socket.inet_aton(address) + except socket.error: + return False + return 4 if address.count('.') == 3 else None + except socket.error: + try: + socket.inet_pton(socket.AF_INET6, address) + return 6 + except socket.error: + return None + return 4 + +def parse_address(address): + parts = address.split(":") + if len(parts) == 1: + return (address, None) + elif len(parts) == 2: + try: + return (parts[0], int(parts[1])) + except: + raise ValueError("Invalid address '%s'" % address) + elif len(parts) < 10: + tmp = address + port = None + + if len(parts[0]) and len(parts[-2]) and "[" == parts[0][0] and "]" == parts[-2][-1] : + if not parts[-1].isdigit(): + raise ValueError("Invalid address '%s'" % address) + + port = int(parts[-1]) + parts[0] = parts[0][1:] + parts[-2] = parts[-2][:-1] + tmp = ':'.join(parts[0:-1]) + + if not ip_type(tmp) == 6: + raise ValueError("Invalid address '%s'" % address) + else: + return (tmp, port) + parts[0] = parts[0][1:] + parts[-2] = parts[0][:-1] + + else: + raise ValueError("Invalid address '%s'" % address) \ No newline at end of file diff --git a/mcstatus/server.py b/mcstatus/server.py index 9cc6d10..caf7f4b 100644 --- a/mcstatus/server.py +++ b/mcstatus/server.py @@ -1,6 +1,7 @@ from mcstatus.pinger import ServerPinger from mcstatus.protocol.connection import TCPSocketConnection, UDPSocketConnection from mcstatus.querier import ServerQuerier +from mcstatus.scripts.address_tools import parse_address import dns.resolver @@ -11,14 +12,7 @@ class MinecraftServer: @staticmethod def lookup(address): - host = address - port = None - if ":" in address: - parts = address.split(":") - if len(parts) > 2: - raise ValueError("Invalid address '%s'" % address) - host = parts[0] - port = int(parts[1]) + host, port = parse_address(address) if port is None: port = 25565 try: