1+ cdef __port_to_int(port, proto):
2+ if port is None or port == ' ' or port == b' ' :
3+ return 0
4+
5+ try :
6+ return int (port)
7+ except (ValueError , TypeError ):
8+ pass
9+
10+ if isinstance (port, bytes):
11+ port = port.decode()
12+
13+ if isinstance (port, str ) and proto is not None :
14+ if proto == uv.IPPROTO_TCP:
15+ return socket_getservbyname(port, ' tcp' )
16+ elif proto == uv.IPPROTO_UDP:
17+ return socket_getservbyname(port, ' udp' )
18+
19+ raise OSError (' service/proto not found' )
20+
21+
122cdef __convert_sockaddr_to_pyaddr(const system.sockaddr* addr):
223 # Converts sockaddr structs into what Python socket
324 # module can understand:
@@ -54,13 +75,11 @@ cdef __convert_pyaddr_to_sockaddr(int family, object addr,
5475 raise ValueError (' AF_INET address must be tuple of (host, port)' )
5576 host, port = addr
5677 if isinstance (host, str ):
57- host = host.encode()
78+ host = host.encode(' idna ' )
5879 if not isinstance (host, (bytes, bytearray)):
5980 raise TypeError (' host must be a string or bytes object' )
60- if isinstance (port, bytes):
61- port = port.decode()
62- if isinstance (port, str ):
63- port = int (port)
81+
82+ port = __port_to_int(port, None )
6483
6584 err = uv.uv_ip4_addr(host, < int > port, < system.sockaddr_in* > res)
6685 if err < 0 :
@@ -78,9 +97,10 @@ cdef __convert_pyaddr_to_sockaddr(int family, object addr,
7897
7998 host = addr[0 ]
8099 if isinstance (host, str ):
81- host = host.encode()
100+ host = host.encode(' idna' )
101+
102+ port = __port_to_int(addr[1 ], None )
82103
83- port = addr[1 ]
84104 if addr_len > 2 :
85105 flowinfo = addr[2 ]
86106 if addr_len > 3 :
@@ -98,6 +118,64 @@ cdef __convert_pyaddr_to_sockaddr(int family, object addr,
98118 ' epected AF_INET or AF_INET6 family, got {}' .format(family))
99119
100120
121+ cdef __static_getaddrinfo(object host, object port,
122+ int family, int type ,
123+ int proto,
124+ system.sockaddr * addr):
125+
126+ if proto not in {0 , uv.IPPROTO_TCP, uv.IPPROTO_UDP}:
127+ raise LookupError
128+
129+ type &= ~ _SOCKET_TYPE_MASK
130+ if type == uv.SOCK_STREAM:
131+ proto = uv.IPPROTO_TCP
132+ elif type == uv.SOCK_DGRAM:
133+ proto = uv.IPPROTO_UDP
134+ else :
135+ raise LookupError
136+
137+ try :
138+ port = __port_to_int(port, proto)
139+ except :
140+ raise LookupError
141+
142+ if family == uv.AF_UNSPEC:
143+ afs = [uv.AF_INET, uv.AF_INET6]
144+ else :
145+ afs = [family]
146+
147+ for af in afs:
148+ try :
149+ __convert_pyaddr_to_sockaddr(af, (host, port), addr)
150+ except :
151+ continue
152+ else :
153+ return (af, type , proto)
154+
155+ raise LookupError
156+
157+
158+ cdef __static_getaddrinfo_pyaddr(object host, object port,
159+ int family, int type ,
160+ int proto, int flags):
161+
162+ cdef:
163+ system.sockaddr addr
164+
165+ try :
166+ (af, type , proto) = __static_getaddrinfo(host, port, family, type ,
167+ proto, & addr)
168+ except LookupError :
169+ return
170+
171+ try :
172+ pyaddr = __convert_sockaddr_to_pyaddr(& addr)
173+ except :
174+ return
175+
176+ return af, type , proto, ' ' , pyaddr
177+
178+
101179@ cython.freelist (DEFAULT_FREELIST_SIZE)
102180cdef class AddrInfo:
103181 cdef:
0 commit comments