# HG changeset patch # User Tero Marttila # Date 1250623476 -10800 # Node ID 15d8bb96b8d4785e0a512f9d2ae8d47d4ef9def8 # Parent f6e8d5e37998f95e45519c700356e5ad8249a46c fix up addrinfo to hold a real platform.addrinfo, storing ai_addr/ai_canonname as objects diff -r f6e8d5e37998 -r 15d8bb96b8d4 qmsk/net/socket/address.pxd --- a/qmsk/net/socket/address.pxd Mon Aug 17 20:24:12 2009 +0300 +++ b/qmsk/net/socket/address.pxd Tue Aug 18 22:24:36 2009 +0300 @@ -49,15 +49,32 @@ cdef class addrinfo : """ - A socket-level endpoint address, which contains the full socket parameters and an bind/connect address - """ + A socket-level endpoint address, which contains the full socket parameters and an bind/connect address. + + A full addrinfo struct is stored, but ai_canonname and ai_addr are stored as (optional) objects outside of the + addrinfo struct. -# cdef readonly int flags - cdef readonly int family, socktype, protocol - cdef readonly sockaddr addr - cdef readonly object canonname + >>> ai = addrinfo() + >>> ai.addr + >>> ai.canonname + >>> print addrinfo(addr=sockaddr_in()) + family=0, socktype=0, protocol=0, addr=0.0.0.0:0, canonname=None + """ + + # canonname is not stored + # may be NULL + cdef platform.addrinfo ai - cdef _init_addrinfo (self, platform.addrinfo *c_ai) + # may be NULL + cdef sockaddr ai_addr + cdef object ai_canonname + + # update self.ai.ai_* to reflect self.ai_* + cdef _init_ai_members (self) + + # set the contents of self.ai from the given real addrinfo + # this ignores the ai_canonname attribute + cdef _init_addrinfo (self, platform.addrinfo *ai) # build and return a new addrinfo instance cdef addrinfo build_addrinfo (platform.addrinfo *c_ai) diff -r f6e8d5e37998 -r 15d8bb96b8d4 qmsk/net/socket/address.pyx --- a/qmsk/net/socket/address.pyx Mon Aug 17 20:24:12 2009 +0300 +++ b/qmsk/net/socket/address.pyx Tue Aug 18 22:24:36 2009 +0300 @@ -51,6 +51,9 @@ def getnameinfo (self) : """ Returns a (host, serv) tuple for this address à la getnameinfo + + >>> addr = sockaddr_in() + >>> assert addr.getnameinfo() == (addr.addr, str(addr.port)) """ cdef platform.sockaddr *sa @@ -165,6 +168,9 @@ property port : """ The integer port number + + >>> sockaddr_in(port=1234).port + 1234 """ def __get__ (self) : @@ -273,6 +279,9 @@ The integer port number. This will represent it correctly in host byte order. + + >>> sockaddr_in6(port=1234).port + 1234 """ def __get__ (self) : @@ -284,6 +293,9 @@ The integer flowinfo XXX: byteorder? + + >>> sockaddr_in6().flowinfo + 0 """ def __get__ (self) : @@ -295,6 +307,9 @@ The scope ID - corresponds to an interface index for link-scope addresses. This should be in host byte order... + + >>> sockaddr_in6(scope_id=1337).scope_id + 1337 """ def __get__ (self) : @@ -372,14 +387,95 @@ return addr cdef class addrinfo : + + cdef _init_ai_members (self) : + """ + Update self.ai.ai_* to reflect self.ai_* + """ + + cdef platform.socklen_t addr_len + + if self.ai_addr is not None : + self.ai_addr._get_sockaddr(&self.ai.ai_addr, &addr_len) + self.ai.ai_addrlen = addr_len + + else : + self.ai.ai_addr = NULL + self.ai.ai_addrlen = 0 + + if self.ai_canonname is not None : + self.ai.ai_canonname = self.ai_canonname + + else : + self.ai.ai_canonname = NULL + def __init__ (self, int flags = 0, int family = 0, int socktype = 0, int protocol = 0, sockaddr addr = None, object canonname = None) : + """ + Construct a new addrinfo with the given parameters + """ + + + self.ai.ai_flags = flags + self.ai.ai_family = family + self.ai.ai_socktype = socktype + self.ai.ai_protocol = protocol + + self.ai_addr = addr + + if canonname is not None : + self.ai_canonname = str(canonname) + + else : + self.ai_canonname = None + + # update self.ai + self._init_ai_members() + cdef _init_addrinfo (self, platform.addrinfo *ai) : - #ai.flags = c_ai.ai_flags - self.family = ai.ai_family - self.socktype = ai.ai_socktype - self.protocol = ai.ai_protocol - self.addr = build_sockaddr(ai.ai_addr, ai.ai_addrlen) - self.canonname = ai.ai_canonname if ai.ai_canonname else None + """ + Re-initialize this addrinfo's parameters from the given addrinfo + """ + + # copy raw + self.ai = ai[0] + + # store copies of external objects + if ai.ai_addr : + # copy addr as object + self.ai_addr = build_sockaddr(ai.ai_addr, ai.ai_addrlen) + + else : + self.ai_addr = None + + if ai.ai_canonname : + # copy as object + self.ai_canonname = ai.ai_canonname + + else : + self.ai_canonname = None + + # update self.ai + self._init_ai_members() + + property flags : + def __get__ (self) : return self.ai.ai_flags + + property family : + def __get__ (self) : return self.ai.ai_family + + property socktype : + def __get__ (self) : return self.ai.ai_socktype + + property protocol : + def __get__ (self) : return self.ai.ai_protocol + + property addr : + # XXX: None? + def __get__ (self) : return self.ai_addr + + property canonname : + # XXX: None? + def __get__ (self) : return self.ai_canonname def __str__ (self) : return "family=%d, socktype=%d, protocol=%d, addr=%s, canonname=%s" % (self.family, self.socktype, self.protocol, self.addr, self.canonname) @@ -442,7 +538,7 @@ # XXX: raise a GAIError raise Exception(platform.gai_strerror(err)) - # gather results + # gather results from linked list to PyList r = res while r :