qmsk/net/socket/address.pxd
author Tero Marttila <terom@fixme.fi>
Mon, 17 Aug 2009 01:29:31 +0300
changeset 20 0e4933d5862e
parent 11 qmsk/net/socket/addr.pxd@7ae92c2b433f
child 23 15d8bb96b8d4
permissions -rw-r--r--
rename qmsk.net.socket.addr -> qmsk.net.socket.address
"""
    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 = ?)