diff -r 15d8bb96b8d4 -r f18b5787c46c qmsk/net/socket/address.pyx --- a/qmsk/net/socket/address.pyx Tue Aug 18 22:24:36 2009 +0300 +++ b/qmsk/net/socket/address.pyx Tue Aug 18 23:02:30 2009 +0300 @@ -99,278 +99,12 @@ def __repr__ (self) : return "sockaddr(%d, %s, %d)" % (self.family, self.addr, self.port) -cdef class sockaddr_in (sockaddr) : - """ - AF_INET struct sockaddr_in - - >>> sa = sockaddr_in("127.0.0.1", 80) - >>> sa.addr - '127.0.0.1' - >>> sa.port - 80 - >>> str(sa) - '127.0.0.1:80' - - >>> sockaddr_in('2001::5') - Traceback (most recent call last): - ... - NameError: Invalid network address for specified address family: '2001::5' - - """ - - # the struct sockaddr_in - cdef platform.sockaddr_in sockaddr - - def __init__ (self, object addr=None, platform.in_port_t port=0) : - """ - Construct using given literal IPv4 address and TCP/UDP port - - addr - IPv4 address, defaults to INADDR_ANY (0.0.0.0) - port - TCP/UDP port, defaults to 0 (ephemeral) - """ - - # zero - libc.memset(&self.sockaddr, 0, sizeof(self.sockaddr)) - - # store our family - # XXX: this should be a class attribute... - self._init_family(platform.AF_INET) - - # constant af - self.sockaddr.sin_family = self.family - - # set the sin_port - self.sockaddr.sin_port = platform.htons(port) - - if addr : - # set the sin_addr - # this automatically converts the addr from str -> char * - platform.inet_pton(self.family, addr, &self.sockaddr.sin_addr) - - else : - # set as INADDR_ANY - self.sockaddr.sin_addr.s_addr = platform.INADDR_ANY - - cdef int _get_sockaddr (self, platform.sockaddr **sa_ptr, platform.socklen_t *sa_len) except -1 : - if sa_ptr : - sa_ptr[0] = &self.sockaddr - - if sa_len : - sa_len[0] = sizeof(self.sockaddr) - - return 0 - - cdef int _set_sockaddr (self, platform.sockaddr *sa, size_t sa_len) except -1 : - assert sa_len == sizeof(self.sockaddr) - - libc.memcpy(&self.sockaddr, sa, sa_len) - - property port : - """ - The integer port number - - >>> sockaddr_in(port=1234).port - 1234 - """ - - def __get__ (self) : - return platform.ntohs(self.sockaddr.sin_port) - - def __cmp__ (self, other_obj) : - """ - A sockaddr_in is equal to any other sockaddr_in which has the same addr and port - - >>> assert sockaddr_in() == sockaddr_in() - >>> assert sockaddr_in('127.0.0.1', 80) == sockaddr_in('127.0.0.1', 80) - >>> addr = sockaddr_in(); assert addr == addr - """ - - if not isinstance(other_obj, sockaddr_in) : - return py.Py_NotImplemented - - cdef sockaddr_in other = other_obj - cdef platform.sockaddr_in *sa1 = &self.sockaddr, *sa2 = &other.sockaddr - - if other is self : - return 0 - - return ( - libc.memcmp( &sa1.sin_port, &sa2.sin_port, sizeof(sa1.sin_port)) - or libc.memcmp( &sa1.sin_addr, &sa2.sin_addr, sizeof(sa1.sin_addr)) - ) - - def __str__ (self) : - """ - Return the literal ASCII representation for this sockaddr as an ': string - - >>> str(sockaddr_in()) - '0.0.0.0:0' - """ - - # format - return "%s:%s" % self.getnameinfo() - -cdef class sockaddr_in6 (sockaddr) : - """ - AF_INET6 struct sockaddr_in6 - - >>> sa6 = sockaddr_in6("::1", 80) - >>> sa6.addr - '::1' - >>> sa6.port - 80 - >>> str(sa6) - '[::1]:80' - - """ - - cdef platform.sockaddr_in6 sockaddr - - def __init__ (self, object addr=None, platform.in_port_t port=0, unsigned int scope_id = 0) : - """ - Construct using given literal IPv6 address and TCP/UDP port - - addr - IPv6 address, defaults to platform.in6addr_any (::) - port - TCP/UDP port, defaults to 0 (ephemeral) - scope_id - (optional) scope ID representing interface index for link-local addresses - """ +# mapping of AF -> sockaddr, user-modifyable +cimport qmsk.net.socket.af_inet, qmsk.net.socket.af_inet6 - # zero - libc.memset(&self.sockaddr, 0, sizeof(self.sockaddr)) - - # store our family - # XXX: this should be a class attribute... - self._init_family(platform.AF_INET6) - - # constant af - self.sockaddr.sin6_family = self.family - - # set the sin_port - self.sockaddr.sin6_port = platform.htons(port) - - if addr : - # set the sin_addr - # this automatically converts the addr from str -> char * - platform.inet_pton(self.family, addr, &self.sockaddr.sin6_addr) - - else : - # set as INADDR_ANY - self.sockaddr.sin6_addr = platform.in6addr_any - - # scope ID - self.sockaddr.sin6_scope_id = scope_id - - cdef int _get_sockaddr (self, platform.sockaddr **sa_ptr, platform.socklen_t *sa_len) except -1 : - if sa_ptr : - sa_ptr[0] = &self.sockaddr - - if sa_len : - sa_len[0] = sizeof(self.sockaddr) - - return 0 - - cdef int _set_sockaddr (self, platform.sockaddr *sa, size_t sa_len) except -1 : - assert sa_len == sizeof(self.sockaddr) - - libc.memcpy(&self.sockaddr, sa, sa_len) - - property port : - """ - The integer port number. - - This will represent it correctly in host byte order. - - >>> sockaddr_in6(port=1234).port - 1234 - """ - - def __get__ (self) : - return platform.ntohs(self.sockaddr.sin6_port) - - - property flowinfo : - """ - The integer flowinfo - - XXX: byteorder? - - >>> sockaddr_in6().flowinfo - 0 - """ - - def __get__ (self) : - return self.sockaddr.sin6_flowinfo - - - property scope_id : - """ - 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) : - return self.sockaddr.sin6_scope_id - - def __cmp__ (self, other_obj) : - """ - A sockaddr_in6 is equal to any other sockaddr_in6 which has the same addr, port and scope ID. - - XXX: flowinfo? - - XXX: A sockaddr_in6 is also equal to a sockaddr_in if the sockaddr_in6 represents the given v4-mapped address. - - >>> assert sockaddr_in6() == sockaddr_in6() - >>> assert sockaddr_in6('0:0:0::1', 80) == sockaddr_in6('::1', 80) - >>> assert sockaddr_in6('::127.0.0.1') == sockaddr_in('127.0.0.1') - """ - - if not isinstance(other_obj, sockaddr_in6) : - return py.Py_NotImplemented - - cdef sockaddr_in6 other = other_obj - cdef platform.sockaddr_in6 *sa1 = &self.sockaddr, *sa2 = &other.sockaddr - - if other is self : - return 0 - - return ( - libc.memcmp( &sa1.sin6_port, &sa2.sin6_port, sizeof(sa1.sin6_port)) - or libc.memcmp( &sa1.sin6_addr, &sa2.sin6_addr, sizeof(sa1.sin6_addr)) - or libc.memcmp( &sa1.sin6_scope_id, &sa2.sin6_scope_id, sizeof(sa1.sin6_scope_id)) - ) - - def __str__ (self) : - """ - Return the literal ASCII representation for this sockaddr as a '[]: string - - >>> str(sockaddr_in6()) - '[::]:0' - - >>> str(sockaddr_in6('2001:0::05:1')) - '[2001::5:1]' - - >>> str(sockaddr_in6('fe80::abcd', scope_id=5)) - '[fe80::abcd%5]' - """ - - addr, port = self.getnameinfo() - scope_id = self.scope_id - - # format with scope_id - return "[%s%s]:%s" % ( - addr, - "%%%d" % scope_id if scope_id else "", - port - ) - -# mapping of AF -> sockaddr, user-modifyable SOCKADDR_BY_FAMILY = { - platform.AF_INET: sockaddr_in, - platform.AF_INET6: sockaddr_in6, + platform.AF_INET: qmsk.net.socket.af_inet.sockaddr_in, + platform.AF_INET6: qmsk.net.socket.af_inet6.sockaddr_in6, } # build a sockaddr from the given sockaddr struct, based on sa_family