diff -r e6b670dbfe3b -r 0e4933d5862e qmsk/net/socket/address.pxd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmsk/net/socket/address.pxd Mon Aug 17 01:29:31 2009 +0300 @@ -0,0 +1,97 @@ +""" + Socket addresses at various levels: + + sockaddr - specific network-level address for socket operations + addrinfo - information on a specific sockaddr including its socket parameters + endpoint - human-readable network address, corresponding to multiple sockaddr's +""" + +cimport qmsk.net.libc as libc + +cimport qmsk.net.socket.platform as platform + +cdef class sockaddr : + """ + A network-level socket address + + XXX: rename to 'address' + + >>> sockaddr().family + 0 + >>> sockaddr().port + Traceback (most recent call last): + ... + NotImplementedError + >>> sockaddr().getnameinfo() + Traceback (most recent call last): + ... + NotImplementedError + """ + + # address family + # XXX: this should be a class constant! It's part of our type safety! + cdef readonly platform.sa_family_t family + + cdef void _init_family (self, platform.sa_family_t family = ?) + + # get the sockaddr/socklen + # each of these can be NULL to ignore it + cdef int _get_sockaddr (self, platform.sockaddr **sa_ptr, platform.socklen_t *sa_len) except -1 + + cdef platform.sockaddr* _get_sockaddr_ptr (self) except NULL + cdef platform.socklen_t _get_sockaddr_len (self) except -1 + + # set the sockaddr, socklen must match + cdef int _set_sockaddr (self, platform.sockaddr *sa, size_t sa_len) except -1 + +# build a sockaddr from the given sockaddr struct, based on sa_family +cdef sockaddr build_sockaddr (platform.sockaddr *sa, size_t sa_len) + +cdef class addrinfo : + """ + A socket-level endpoint address, which contains the full socket parameters and an bind/connect address + """ + +# cdef readonly int flags + cdef readonly int family, socktype, protocol + cdef readonly sockaddr addr + cdef readonly object canonname + + cdef _init_addrinfo (self, platform.addrinfo *c_ai) + +# build and return a new addrinfo instance +cdef addrinfo build_addrinfo (platform.addrinfo *c_ai) + +cdef class endpoint : + """ + A network-level socket endpoint. This is the level that humans mostly work with, but the tricky bit is that + an endpoint can map to more than one sockaddr... + + Hence, endpoints are stored as human-readable hostname/service strings, which are then translated to sockaddrs + using getaddrinfo. + + >>> from __future__ import absolute_import; import socket as _socket + >>> e = endpoint('127.0.0.1', 80) + >>> str(e) + 'hostname=127.0.0.1, service=80' + >>> res = e.getaddrinfo(_socket.AF_UNSPEC, _socket.SOCK_STREAM) + >>> len(res) + 1 + >>> str(res[0]) + 'family=2, socktype=1, protocol=6, addr=127.0.0.1:80, canonname=None' + >>> e = endpoint('2001::5', 80) + >>> str(e) + 'hostname=2001::5, service=80' + >>> res = e.getaddrinfo(_socket.AF_UNSPEC, _socket.SOCK_STREAM) + >>> len(res) + 1 + >>> str(res[0]) + 'family=10, socktype=1, protocol=6, addr=[2001::5]:80, canonname=None' + + """ + + # our defining attributes, set via __init__ + cdef object hostname, service + + cpdef getaddrinfo (self, int family, int socktype, int protocol = ?, int flags = ?) +