| 102 | # [1:2::3]:456 or [1:2::3] or just [::]:567 |
| 103 | # example.com:123 or just example.com |
| 104 | def parse_ipport(s): |
| 105 | s = str(s) |
| 106 | if s.isdigit(): |
| 107 | rx = r'()(\d+)$' |
| 108 | elif ']' in s: |
| 109 | rx = r'(?:\[([^]]+)])(?::(\d+))?$' |
| 110 | else: |
| 111 | rx = r'([\w\.\-]+)(?::(\d+))?$' |
| 112 | |
| 113 | m = re.match(rx, s) |
| 114 | if not m: |
| 115 | raise Fatal('%r is not a valid IP:port format' % s) |
| 116 | |
| 117 | host, port = m.groups() |
| 118 | host = host or '0.0.0.0' |
| 119 | port = int(port or 0) |
| 120 | |
| 121 | try: |
| 122 | addrinfo = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM) |
| 123 | except socket.gaierror: |
| 124 | raise Fatal('Unable to resolve address: %s' % host) |
| 125 | |
| 126 | if len(addrinfo) > 1: |
| 127 | print("WARNING: Host %s has more than one IP, only using one of them." |
| 128 | % host) |
| 129 | |
| 130 | family, _, _, _, addr = min(addrinfo) |
| 131 | # Note: addr contains (ip, port) |
| 132 | return (family,) + addr[:2] |
| 133 | |
| 134 | |
| 135 | def parse_list(lst): |