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
+
1
22
cdef __convert_sockaddr_to_pyaddr(const system.sockaddr* addr):
2
23
# Converts sockaddr structs into what Python socket
3
24
# module can understand:
@@ -54,13 +75,11 @@ cdef __convert_pyaddr_to_sockaddr(int family, object addr,
54
75
raise ValueError (' AF_INET address must be tuple of (host, port)' )
55
76
host, port = addr
56
77
if isinstance (host, str ):
57
- host = host.encode()
78
+ host = host.encode(' idna ' )
58
79
if not isinstance (host, (bytes, bytearray)):
59
80
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 )
64
83
65
84
err = uv.uv_ip4_addr(host, < int > port, < system.sockaddr_in* > res)
66
85
if err < 0 :
@@ -78,9 +97,10 @@ cdef __convert_pyaddr_to_sockaddr(int family, object addr,
78
97
79
98
host = addr[0 ]
80
99
if isinstance (host, str ):
81
- host = host.encode()
100
+ host = host.encode(' idna' )
101
+
102
+ port = __port_to_int(addr[1 ], None )
82
103
83
- port = addr[1 ]
84
104
if addr_len > 2 :
85
105
flowinfo = addr[2 ]
86
106
if addr_len > 3 :
@@ -98,6 +118,64 @@ cdef __convert_pyaddr_to_sockaddr(int family, object addr,
98
118
' epected AF_INET or AF_INET6 family, got {}' .format(family))
99
119
100
120
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
+
101
179
@ cython.freelist (DEFAULT_FREELIST_SIZE)
102
180
cdef class AddrInfo:
103
181
cdef:
0 commit comments