219 |
219 |
220 ai._init_addrinfo(c_ai) |
220 ai._init_addrinfo(c_ai) |
221 |
221 |
222 return ai |
222 return ai |
223 |
223 |
|
224 def getaddrinfo (hostname, service, int family, int socktype, int protocol = 0, int flags = 0) : |
|
225 """ |
|
226 Look up given hostname/service using the given socket parameters, and return a sequence of addrinfo objects. |
|
227 |
|
228 hostname - internet address/hostname to look up, or None (for INADDR_ANY/localhost, see AI_PASSIVE) |
|
229 service - port/service to use, or None (for ephemeral) |
|
230 family - address family to use, one of AF_*. May be AF_UNSPEC. |
|
231 socktype - socket type to use, one of SOCK_*. |
|
232 protocol - protocol to use, one of IPPROTO_* or zero to pick the default protocol for the given |
|
233 socktype. |
|
234 flags - bitmask of AI_* flags for getaddrinfo() |
|
235 |
|
236 AI_NUMERICHOST - self.hostname is a literal address, do not perform any network host address lookups |
|
237 AI_NUMERICSERV - self.service is a literal port number, do not lookup service names |
|
238 AI_CANONNAME - return addrinfo objects with .canonname set to the official name of the host |
|
239 AI_PASSIVE - intended for use by server applications, return addrinfos with an unspecified |
|
240 .addr if no self.hostname is not given. |
|
241 AI_ADDRCONFIG - only return addrinfos with a .addrs of a given address family if the system has at |
|
242 least one local address of that address family configured. |
|
243 AI_V4MAPPED - if family=AF_INET6, and no matching IPv6 addresses could be found, return IPv4-mapped |
|
244 IPv6 addresses. |
|
245 AI_ALL - if used together with AI_V4MAPPED, then return both IPv6 and IPv4-mapped IPv6 |
|
246 addresses. |
|
247 |
|
248 """ |
|
249 |
|
250 # XXX: Cython doesn't support proper compound value literals... |
|
251 cdef platform.addrinfo hints |
|
252 |
|
253 libc.memset(&hints, 0, sizeof(hints)) |
|
254 hints.ai_flags = flags |
|
255 hints.ai_family = family |
|
256 hints.ai_socktype = socktype |
|
257 hints.ai_protocol = protocol |
|
258 |
|
259 cdef platform.addrinfo *res, *r |
|
260 cdef int err |
|
261 cdef object ret = [] |
|
262 |
|
263 cdef char *_hostname = NULL |
|
264 cdef char *_service = NULL |
|
265 |
|
266 if hostname is not None : |
|
267 _hostname = hostname |
|
268 |
|
269 if service is not None : |
|
270 _service = service |
|
271 |
|
272 # operate! |
|
273 err = platform.c_getaddrinfo(_hostname, _service, &hints, &res) |
|
274 |
|
275 if err : |
|
276 # XXX: raise a GAIError |
|
277 raise Exception(platform.gai_strerror(err)) |
|
278 |
|
279 try : |
|
280 # gather results from linked list to PyList |
|
281 r = res |
|
282 |
|
283 while r : |
|
284 ret.append(build_addrinfo(r)) |
|
285 |
|
286 r = r.ai_next |
|
287 |
|
288 # ok |
|
289 return ret |
|
290 |
|
291 finally : |
|
292 platform.c_freeaddrinfo(res) |
|
293 |
|
294 |
|
295 |
224 cdef class endpoint : |
296 cdef class endpoint : |
225 |
297 |
226 def __init__ (self, hostname=None, service=None) : |
298 def __init__ (self, hostname=None, service=None) : |
227 """ |
299 """ |
228 Construct with the given hostname/service, either of which may be None. |
300 Construct with the given hostname/service, either of which may be None. |
232 |
304 |
233 hostname - the literal address or DNS hostname or anything else that GAI supports |
305 hostname - the literal address or DNS hostname or anything else that GAI supports |
234 service - the numeric port or service name |
306 service - the numeric port or service name |
235 """ |
307 """ |
236 |
308 |
237 self.hostname = str(hostname) |
309 self.hostname = hostname |
238 self.service = str(service) |
310 self.service = service |
239 |
311 |
240 cpdef getaddrinfo (self, int family, int socktype, int protocol = 0, int flags = platform.AI_PASSIVE) : |
312 def getaddrinfo (self, int family, int socktype, int protocol = 0, int flags = platform.AI_PASSIVE) : |
241 """ |
313 """ |
242 Look up our hostname/service using the given socket parameters, and return a sequence of addrinfo objects. |
314 See getaddrinfo(). |
243 |
315 """ |
244 family - the address family to use, one of AF_*. May be AF_UNSPEC. |
316 |
245 socktype - the socket type to use, one of SOCK_*. |
317 return getaddrinfo(self.hostname, self.service, family, socktype, protocol, flags) |
246 protocol - the protocol to use, one of IPPROTO_* or zero to pick a suitable protocol |
|
247 for the given socktype. |
|
248 flags - bitmask of AI_* flags for getaddrinfo() |
|
249 |
|
250 AI_NUMERICHOST - self.hostname is a literal address, do not perform any network host address lookups |
|
251 AI_NUMERICSERV - self.service is a literal port number, do not lookup service names |
|
252 AI_CANONNAME - return addrinfo objects with .canonname set to the official name of the host |
|
253 AI_PASSIVE - intended for use by server applications, return addrinfos with an unspecified |
|
254 .addr if no self.hostname is not given. |
|
255 AI_ADDRCONFIG - only return addrinfos with a .addrs of a given address family if the system has at |
|
256 least one local address of that address family configured. |
|
257 AI_V4MAPPED - if family=AF_INET6, and no matching IPv6 addresses could be found, return IPv4-mapped |
|
258 IPv6 addresses. |
|
259 AI_ALL - if used together with AI_V4MAPPED, then return both IPv6 and IPv4-mapped IPv6 |
|
260 addresses. |
|
261 |
|
262 """ |
|
263 |
|
264 # XXX: Cython doesn't support proper compound value literals... |
|
265 cdef platform.addrinfo hints |
|
266 |
|
267 libc.memset(&hints, 0, sizeof(hints)) |
|
268 hints.ai_flags = flags |
|
269 hints.ai_family = family |
|
270 hints.ai_socktype = socktype |
|
271 hints.ai_protocol = protocol |
|
272 |
|
273 cdef platform.addrinfo *res, *r |
|
274 cdef int err |
|
275 cdef object ret = [] |
|
276 |
|
277 cdef char *hostname = NULL |
|
278 cdef char *service = NULL |
|
279 |
|
280 if self.hostname is not None : |
|
281 hostname = self.hostname |
|
282 |
|
283 if self.service is not None : |
|
284 service = self.service |
|
285 |
|
286 # operate! |
|
287 err = platform.c_getaddrinfo(hostname, service, &hints, &res) |
|
288 |
|
289 if err : |
|
290 # XXX: raise a GAIError |
|
291 raise Exception(platform.gai_strerror(err)) |
|
292 |
|
293 try : |
|
294 # gather results from linked list to PyList |
|
295 r = res |
|
296 |
|
297 while r : |
|
298 ret.append(build_addrinfo(r)) |
|
299 |
|
300 r = r.ai_next |
|
301 |
|
302 # ok |
|
303 return ret |
|
304 |
|
305 finally : |
|
306 platform.c_freeaddrinfo(res) |
|
307 |
318 |
308 def __str__ (self) : |
319 def __str__ (self) : |
309 return "hostname=%s, service=%s" % (self.hostname, self.service) |
320 return "hostname=%s, service=%s" % (self.hostname, self.service) |
310 |
321 |