This repository has been archived by the owner on Jul 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
utils.py
65 lines (60 loc) · 2.61 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from socket import (AF_INET, AF_INET6, SOCK_DGRAM,
error as sockerr, getaddrinfo, gaierror)
try:
# I'm guessing the builtin inet_pton will be faster, but if it's not
# available we'll just have to use mine
from socket import inet_pton
except ImportError:
def inet_pton(af, ip):
'''inet_pton(af, ip) -> packed IP address string
Convert an IP address from string format to a packed string suitable
for use with low-level network functions.'''
if af == AF_INET:
try:
return ''.join(chr(int(b)) for b in ip.split('.'))
except ValueError:
raise sockerr('illegal IP address string passed to inet_pton')
elif af == AF_INET6:
bits = ip.split('::')
if len(bits) > 2:
raise sockerr('illegal IP address string passed to inet_pton')
try:
if len(bits) == 2:
# The filter(bool) replaces [''] with [] in the case that
# :: begins or ends a string (so bits[i] would be empty)
lead, trail = [filter(bool, s.split(':')) for s in bits]
full = [int(s, 16) for s in lead]
full += [0 for _ in range(8 - len(lead) - len(trail))]
full += [int(s, 16) for s in trail]
else:
full = [int(s, 16) for s in ip.split(':')]
except ValueError:
raise sockerr('illegal IP address string passed to inet_pton')
return ''.join([chr(b >> 8) + chr(b & 0xff) for b in full])
else:
# I don't know why 97, I'm just copying the observed behaviour of
# my system's inet_pton
raise sockerr(97, 'Address family not supported by protocol')
def valid_addr(addr, afs = (AF_INET, AF_INET6)):
'Return the address family of the given string, or None if it is invalid'
for af in afs:
try:
inet_pton(af, addr)
return af
except sockerr:
pass
return None
def parse_addrwport(addr):
# docstring TODO
sep = addr.rindex(':')
return (addr[:sep], int(addr[sep + 1:]))
def stringtosockaddr(str, family = None, socktype = SOCK_DGRAM):
# docstring TODO
if family == None:
try:
return getaddrinfo(*parse_addrwport(str) +
(AF_INET, socktype))[0][-1]
except gaierror:
return getaddrinfo(*parse_addrwport(str) +
(AF_INET6, socktype))[0][-1]
return getaddrinfo(*parse_addrwport(str) + (family, socktype))[0][-1]