qmsk/net/socket/addr.pxd
changeset 20 0e4933d5862e
parent 19 e6b670dbfe3b
child 21 19d212c948e0
equal deleted inserted replaced
19:e6b670dbfe3b 20:0e4933d5862e
     1 """
       
     2     Socket addresses at various levels:
       
     3 
       
     4         sockaddr    - specific network-level address for socket operations
       
     5         addrinfo    - information on a specific sockaddr including its socket parameters
       
     6         endpoint    - human-readable network address, corresponding to multiple sockaddr's
       
     7 """
       
     8 
       
     9 cimport qmsk.net.libc as libc
       
    10 
       
    11 cimport qmsk.net.socket.platform as platform
       
    12 
       
    13 cdef class sockaddr :
       
    14     """
       
    15         A network-level socket address
       
    16 
       
    17         XXX: rename to 'address'
       
    18 
       
    19         >>> sockaddr().family
       
    20         0
       
    21         >>> sockaddr().port
       
    22         Traceback (most recent call last):
       
    23           ...
       
    24         NotImplementedError
       
    25         >>> sockaddr().getnameinfo()
       
    26         Traceback (most recent call last):
       
    27           ...
       
    28         NotImplementedError
       
    29     """
       
    30     
       
    31     # address family
       
    32     # XXX: this should be a class constant! It's part of our type safety!
       
    33     cdef readonly platform.sa_family_t family
       
    34 
       
    35     cdef void _init_family (self, platform.sa_family_t family = ?)
       
    36 
       
    37     # get the sockaddr/socklen
       
    38     # each of these can be NULL to ignore it
       
    39     cdef int _get_sockaddr (self, platform.sockaddr **sa_ptr, platform.socklen_t *sa_len) except -1
       
    40 
       
    41     cdef platform.sockaddr* _get_sockaddr_ptr (self) except NULL
       
    42     cdef platform.socklen_t _get_sockaddr_len (self) except -1
       
    43     
       
    44     # set the sockaddr, socklen must match
       
    45     cdef int _set_sockaddr (self, platform.sockaddr *sa, size_t sa_len) except -1
       
    46 
       
    47 # build a sockaddr from the given sockaddr struct, based on sa_family
       
    48 cdef sockaddr build_sockaddr (platform.sockaddr *sa, size_t sa_len)
       
    49 
       
    50 cdef class addrinfo :
       
    51     """
       
    52         A socket-level endpoint address, which contains the full socket parameters and an bind/connect address
       
    53     """
       
    54 
       
    55 #    cdef readonly int flags
       
    56     cdef readonly int family, socktype, protocol
       
    57     cdef readonly sockaddr addr
       
    58     cdef readonly object canonname
       
    59 
       
    60     cdef _init_addrinfo (self, platform.addrinfo *c_ai)
       
    61 
       
    62 # build and return a new addrinfo instance
       
    63 cdef addrinfo build_addrinfo (platform.addrinfo *c_ai)
       
    64 
       
    65 cdef class endpoint :
       
    66     """
       
    67         A network-level socket endpoint. This is the level that humans mostly work with, but the tricky bit is that
       
    68         an endpoint can map to more than one sockaddr...
       
    69 
       
    70         Hence, endpoints are stored as human-readable hostname/service strings, which are then translated to sockaddrs
       
    71         using getaddrinfo.
       
    72 
       
    73         >>> from __future__ import absolute_import; import socket as _socket
       
    74         >>> e = endpoint('127.0.0.1', 80)
       
    75         >>> str(e)
       
    76         'hostname=127.0.0.1, service=80'
       
    77         >>> res = e.getaddrinfo(_socket.AF_UNSPEC, _socket.SOCK_STREAM)
       
    78         >>> len(res)
       
    79         1
       
    80         >>> str(res[0])
       
    81         'family=2, socktype=1, protocol=6, addr=127.0.0.1:80, canonname=None'
       
    82         >>> e = endpoint('2001::5', 80)
       
    83         >>> str(e)
       
    84         'hostname=2001::5, service=80'
       
    85         >>> res = e.getaddrinfo(_socket.AF_UNSPEC, _socket.SOCK_STREAM)
       
    86         >>> len(res)
       
    87         1
       
    88         >>> str(res[0])
       
    89         'family=10, socktype=1, protocol=6, addr=[2001::5]:80, canonname=None'
       
    90 
       
    91     """
       
    92     
       
    93     # our defining attributes, set via __init__
       
    94     cdef object hostname, service
       
    95 
       
    96     cpdef getaddrinfo (self, int family, int socktype, int protocol = ?, int flags = ?)
       
    97