qmsk/net/socket/address.pyx
changeset 46 64b4ffb44754
parent 43 9fdef438e3a2
child 49 e2f79e68418a
equal deleted inserted replaced
44:01ac7755b15a 46:64b4ffb44754
   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