socket type, mass rename
authorTero Marttila <terom@fixme.fi>
Sun, 16 Aug 2009 18:29:55 +0300
changeset 6 10bd48c9b6ce
parent 5 59bed837c265
child 7 74fde84264b1
socket type, mass rename
libc.pxd
libc.pyx
py.pxd
py.pyx
qmsk.net/sctp/__init__.py
qmsk.net/sctp/constants.pyx
qmsk.net/sctp/sock.pxd
qmsk.net/sctp/sock.pyx
qmsk.net/socket/__init__.py
qmsk.net/socket/addr.pxd
qmsk.net/socket/addr.pyx
qmsk.net/socket/sock.pxd
qmsk.net/socket/sock.pyx
sctp/__init__.py
sctp/constants.pyx
sctp/sock.pxd
sctp/sock.pyx
setup.py
sock/__init__.py
sock/addr.pxd
sock/addr.pyx
test.py
--- a/libc.pxd	Sun Aug 16 16:38:44 2009 +0300
+++ b/libc.pxd	Sun Aug 16 18:29:55 2009 +0300
@@ -2,7 +2,7 @@
     Libc stuff
 """
 
-cdef extern from "stdint.h":
+cdef extern from "stdint.h" :
     # yes, these are "wrong"
     ctypedef unsigned char uint8_t
     ctypedef unsigned short uint16_t
@@ -12,6 +12,10 @@
     ctypedef signed short int16_t
     ctypedef signed int int32_t
 
+cdef extern from "sys/types.h" :
+    # potentially wrong...
+    ctypedef signed long ssize_t
+
 # <linux/types.h>
 cdef extern from "linux/types.h" :
     ctypedef uint8_t __u8
@@ -34,48 +38,185 @@
 cdef extern from "alloca.h" :
     void* alloca (size_t size)
 
+cdef extern from "sys/uio.h" :
+    struct iovec :
+        void *iov_base
+        size_t iov_len
+
+cdef extern from "arpa/inet.h" :
+    # XXX: correct?!
+    ctypedef uint32_t socklen_t
+    
+    char* c_inet_ntop "inet_ntop" (int af, void *sockaddr, char *buf, socklen_t len)
+    int c_inet_pton "inet_pton" (int af, char *src, void *dst)
+
 # <sys/socket.h>
 cdef extern from "sys/socket.h" :
+    # socket types
     enum :
         SOCK_STREAM
         SOCK_DGRAM
+        SOCK_RAW
+        SOCK_RDM
         SOCK_SEQPACKET
-
+        SOCK_PACKET
+    
+    # packet/address families
     enum :
         PF_UNSPEC
         PF_LOCAL
+        PF_UNIX     # same as PF_LOCAL
+        PF_FILE     # same as PF_LOCAL
         PF_INET
         PF_INET6
+        PF_NETLINK
+        PF_ROUTE    # same as PF_NETLINK
+
     
-    # these are #defines
+    # aliases for PF_*
     enum :
-        PF_UNIX
-
         AF_UNSPEC
         AF_LOCAL
         AF_UNIX
+        AF_FILE
         AF_INET
         AF_INET6
-
+        AF_NETLINK
+        AF_ROUTE
+    
+    # base sockaddr stuff
     ctypedef uint16_t sa_family_t
+
+    struct sockaddr :
+        sa_family_t     sa_family
+
+    struct sockaddr_storage :
+        sa_family_t     ss_family
+
+    # flag values
+    enum :
+        MSG_OOB
+        MSG_PEEK
+        MSG_DONTROUTE
+        MSG_CTRUNC
+        MSG_PROXY
+        MSG_TRUNC
+        MSG_DONTWAIT
+        MSG_EOR
+        MSG_WAITALL
+        MSG_FIN
+        MSG_SYN
+        MSG_CONFIRM
+        MSG_RST
+        MSG_ERRQUEUE
+        MSG_NOSIGNAL
+        MSG_MORE
+        MSG_CMSG_CLOEXEC
+    
+    ## send/recv-msg
+    struct msghdr :
+        void *msg_name              # sockaddr
+        socklen_t msg_namelen
+
+        iovec *msg_iov              # message data
+        size_t msg_iovlen
+
+        void *msg_control           # aux data
+        size_t msg_controllen
+
+        int msg_flags               # flags
+
+    struct cmsghdr :
+        size_t cmsg_len             # length including this cmsghdr struct
+
+        int cmsg_level              # originating protocol (IPPROTO_* ???)
+        int cmsg_type               # protocol-specific type
+
+    ## socket-level cmsghdr types
+    enum :
+        SCM_RIGHTS
+        SCM_CREDENTIALS
+
+    #- ucred
+
+    # SO_LINGER parameters
+    struct linger :
+        int l_onoff
+        int l_linger
+
+
+    ## API
+    int socket (int domain, int socktype, int protocol)
+    int bind (int fd, sockaddr *addr, socklen_t len)
+    int connect (int fd, sockaddr *addr, socklen_t len)
+    int listen (int fd, int n)
+    int accept (int fd, sockaddr *addr, socklen_t *len)
+    int shutdown (int fd, int how)
+
+    int getsockname (int fd, sockaddr *addr, socklen_t *len)
+    int getpeername (int fd, sockaddr *addr, socklen_t *len)
+
+    ssize_t send (int fd, void *buf, size_t n, int flags)
+    ssize_t recv (int fd, void *buf, size_t n, int flags)
+    ssize_t sendto (int fd, void *buf, size_t n, int flags, sockaddr *addr, socklen_t addr_len)
+    ssize_t recvfrom (int fd, void *buf, size_t n, int flags, sockaddr *addr, socklen_t addr_len)
+    ssize_t sendmsg (int fd, msghdr *msg, int flags)
+    ssize_t recvmsg (int fd, msghdr *msg, int flags)
+
+    int getsockopt (int fd, int level, int optname, void *optval, socklen_t optlen)
+    int setsockopt (int fd, int level, int optname, void *optval, socklen_t optlen)
+
+    enum :
+        SHUT_RD
+        SHUT_WR
+        SHUT_RDWR
+
+cdef extern from "netinet/in.h" :
+    ## socket protocol types
+    enum :
+        IPPROTO_IP
+        IPPROTO_ICMP
+        IPPROTO_IGMP
+        IPPROTO_TCP
+        IPPROTO_UDP
+        IPPROTO_IPV6
+        IPPROTO_ICMPV6
+        IPPROTO_SCTP
+        IPPROTO_RAW
+
+    
+    ## ports
     ctypedef uint16_t in_port_t
-    ctypedef uint32_t in_addr_t
 
     ## AF_INET
+    ctypedef uint32_t in_addr_t
     struct in_addr :
         in_addr_t s_addr
-
-    struct sockaddr_in :
-        sa_family_t     sin_family
-        in_port_t       sin_port
-        in_addr         sin_addr
-
+    
     # XXX: should these be in another cdef?
     in_addr_t INADDR_ANY
 
     ## AF_INET6
     struct in6_addr :
-        pass
+        # XXX: check POSIX...
+        uint8_t s6_addr[16]
+        uint16_t s6_addr16[8]
+        uint32_t s6_addr32[4]
+
+    # common in6_addr's
+    in6_addr in6addr_any
+    in6_addr in6addr_loopback
+
+    ## constants
+    enum :
+        INET_ADDRSTRLEN
+        INET6_ADDRSTRLEN
+
+    ## sockaddrs
+    struct sockaddr_in :
+        sa_family_t     sin_family
+        in_port_t       sin_port
+        in_addr         sin_addr
 
     struct sockaddr_in6 :
         sa_family_t     sin6_family
@@ -84,33 +225,10 @@
         in6_addr        sin6_addr
         uint32_t        sin6_scope_id
 
-    # common in6_addr's
-    in6_addr in6addr_any
-    in6_addr in6addr_loopback
-
-    ## actually from bits/socket.h...
-    struct sockaddr :
-        sa_family_t     sa_family
-
-    struct sockaddr_storage :
-        sa_family_t     ss_family
-
-cdef extern from "arpa/inet.h" :
     uint16_t htons(uint16_t)
     uint32_t htonl(uint32_t)
     uint16_t ntohs(uint16_t)
     uint32_t ntohl(uint32_t)
-    
-    # XXX: correct?!
-    ctypedef size_t socklen_t
-
-    ## constants
-    enum :
-        INET_ADDRSTRLEN
-        INET6_ADDRSTRLEN
-    
-    char* c_inet_ntop "inet_ntop" (int af, void *sockaddr, char *buf, socklen_t len)
-    int c_inet_pton "inet_pton" (int af, char *src, void *dst)
 
 cdef extern from "netdb.h" :
     ## getaddrinfo
@@ -167,3 +285,31 @@
 
 # sockaddr, flags -> (host, service)
 cdef object getnameinfo (sockaddr *sa, socklen_t salen, int flags)
+
+## general errno-based errors
+#cdef class Errno (py.OSError) :
+#    """
+#        Some libc function returned an error code:
+#
+#            func        - the name of the function called
+#            err         - the system error code
+#            strerror    - human-readable error code -> message
+#    """
+#
+#    cdef readonly char *func
+#    cdef readonly int err
+#    cdef readonly object strerror
+#
+#cdef class GAIError (py.OSError) :
+#    """
+#        Some libc GAI function returnd an error code:
+#
+#            func        - the name of the function called
+#            err         - the GAI_* error code
+#            strerror    - human-readable error code -> message
+#    """
+#
+#    cdef readonly char *func
+#    cdef readonly int err
+#    cdef readonly object strerror
+#
--- a/libc.pyx	Sun Aug 16 16:38:44 2009 +0300
+++ b/libc.pyx	Sun Aug 16 18:29:55 2009 +0300
@@ -11,13 +11,20 @@
     cdef char buf[INET6_ADDRSTRLEN]
 
     if c_inet_ntop(af, sockaddr, buf, sizeof(buf)) == NULL :
-        raise_errno()
+        raise_errno('inet_ntop')
     
     # autoconvert -> str
     return buf
 
 cdef object inet_pton (int af, char *addr, void *sockaddr_out) :
-    if c_inet_pton(af, addr, sockaddr_out) <= 0 :
+    cdef int ret
+
+    ret = c_inet_pton(af, addr, sockaddr_out)
+    
+    if ret < 0 :
+        raise_errno('inet_pton')
+
+    elif ret == 0 :
         raise NameError("Invalid network address for specified address family: %r" % (addr, ))
 
 cdef object getnameinfo (sockaddr *sa, socklen_t salen, int flags) :
@@ -30,7 +37,26 @@
     if err :
         # XXX: raise a GAIError
         raise Exception(gai_strerror(err))
+#        raise GAIError('getnameinfo', err)
 
     else :
         return hostbuf, servbuf
 
+#cdef class Errno (py.OSError) :
+#    def __init__ (self, func) :
+#        self.func = func
+#        self.err = errno
+#        self.strerror = strerror(errno)
+#
+#    def __str__ (self) :
+#        return "%s: %s" % (self.func, self.strerror)
+#
+#cdef class GAIError (py.OSError) :
+#    def __init__ (self, func, err) :
+#        self.func = func
+#        self.err = err
+#        self.strerror = gai_strerror(err)
+#
+#    def __str__ (self) :
+#        return "%s: %s" % (self.func, self.strerror)
+#
--- a/py.pxd	Sun Aug 16 16:38:44 2009 +0300
+++ b/py.pxd	Sun Aug 16 18:29:55 2009 +0300
@@ -1,12 +1,18 @@
+cimport libc
+
 cdef extern from "Python.h" :
     struct PyObject :
         pass
 
-    PyObject* PyErr_SetFromErrno (PyObject *type)
+    ## string stuff
+    int PyObject_AsCharBuffer (object obj, char **buf, libc.ssize_t *len) except -1
     
-    ## built-in exceptions
-    PyObject* PyExc_OSError
+    ## except setting
+    PyObject* PyErr_SetFromErrno (PyObject *type)
 
+    PyObject *PyExc_OSError
+    
 # raise OSError with errno
-cdef int raise_errno () except -1
+# XXX: doesn't do anything with func
+cdef int raise_errno (char *func) except -1
 
--- a/py.pyx	Sun Aug 16 16:38:44 2009 +0300
+++ b/py.pyx	Sun Aug 16 18:29:55 2009 +0300
@@ -1,5 +1,5 @@
 
-cdef int raise_errno () except -1 :
+cdef int raise_errno (char *func) except -1 :
     PyErr_SetFromErrno(PyExc_OSError)
 
     return -1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk.net/sctp/constants.pyx	Sun Aug 16 18:29:55 2009 +0300
@@ -0,0 +1,62 @@
+cimport sctp.sock as sctp
+
+SOL_SCTP = sctp.SOL_SCTP
+IPPROTO_SCTP = sctp.IPPROTO_SCTP
+
+SCTP_RTOINFO = sctp.SCTP_RTOINFO
+SCTP_ASSOCINFO = sctp.SCTP_ASSOCINFO
+SCTP_INITMSG = sctp.SCTP_INITMSG
+SCTP_NODELAY = sctp.SCTP_NODELAY
+SCTP_AUTOCLOSE = sctp.SCTP_AUTOCLOSE
+SCTP_SET_PEER_PRIMARY_ADDR = sctp.SCTP_SET_PEER_PRIMARY_ADDR
+SCTP_PRIMARY_ADDR = sctp.SCTP_PRIMARY_ADDR
+SCTP_ADAPTATION_LAYER = sctp.SCTP_ADAPTATION_LAYER
+SCTP_DISABLE_FRAGMENTS = sctp.SCTP_DISABLE_FRAGMENTS
+SCTP_PEER_ADDR_PARAMS = sctp.SCTP_PEER_ADDR_PARAMS
+SCTP_DEFAULT_SEND_PARAM = sctp.SCTP_DEFAULT_SEND_PARAM
+SCTP_EVENTS = sctp.SCTP_EVENTS
+SCTP_I_WANT_MAPPED_V4_ADDR = sctp.SCTP_I_WANT_MAPPED_V4_ADDR
+SCTP_MAXSEG = sctp.SCTP_MAXSEG
+SCTP_STATUS = sctp.SCTP_STATUS
+SCTP_GET_PEER_ADDR_INFO = sctp.SCTP_GET_PEER_ADDR_INFO
+SCTP_DELAYED_ACK_TIME = sctp.SCTP_DELAYED_ACK_TIME
+SCTP_CONTEXT = sctp.SCTP_CONTEXT
+SCTP_FRAGMENT_INTERLEAVE = sctp.SCTP_FRAGMENT_INTERLEAVE
+SCTP_PARTIAL_DELIVERY_POINT = sctp.SCTP_PARTIAL_DELIVERY_POINT
+SCTP_MAX_BURST = sctp.SCTP_MAX_BURST
+
+SCTP_ADDR_AVAILABLE = sctp.SCTP_ADDR_AVAILABLE
+SCTP_ADDR_UNREACHABLE = sctp.SCTP_ADDR_UNREACHABLE
+SCTP_ADDR_REMOVED = sctp.SCTP_ADDR_REMOVED
+SCTP_ADDR_ADDED = sctp.SCTP_ADDR_ADDED
+SCTP_ADDR_MADE_PRIM = sctp.SCTP_ADDR_MADE_PRIM
+SCTP_ADDR_CONFIRMED = sctp.SCTP_ADDR_CONFIRMED
+
+
+SCTP_DATA_UNSENT = sctp.SCTP_DATA_UNSENT
+SCTP_DATA_SENT = sctp.SCTP_DATA_SENT
+
+SCTP_PARTIAL_DELIVERY_ABORTED = sctp.SCTP_PARTIAL_DELIVERY_ABORTED
+
+# enum sctp_sn_type :
+SCTP_SN_TYPE_BASE = sctp.SCTP_SN_TYPE_BASE
+SCTP_ASSOC_CHANGE = sctp.SCTP_ASSOC_CHANGE
+SCTP_PEER_ADDR_CHANGE = sctp.SCTP_PEER_ADDR_CHANGE
+SCTP_SEND_FAILED = sctp.SCTP_SEND_FAILED
+SCTP_REMOTE_ERROR = sctp.SCTP_REMOTE_ERROR
+SCTP_SHUTDOWN_EVENT = sctp.SCTP_SHUTDOWN_EVENT
+SCTP_PARTIAL_DELIVERY_EVENT = sctp.SCTP_PARTIAL_DELIVERY_EVENT
+SCTP_ADAPTATION_INDICATION = sctp.SCTP_ADAPTATION_INDICATION
+
+# enum sctp_sn_error :
+SCTP_FAILED_THRESHOLD = sctp.SCTP_FAILED_THRESHOLD
+SCTP_RECEIVED_SACK = sctp.SCTP_RECEIVED_SACK
+SCTP_HEARTBEAT_SUCCESS = sctp.SCTP_HEARTBEAT_SUCCESS
+SCTP_RESPONSE_TO_USER_REQ = sctp.SCTP_RESPONSE_TO_USER_REQ
+SCTP_INTERNAL_ERROR = sctp.SCTP_INTERNAL_ERROR
+SCTP_SHUTDOWN_GUARD_EXPIRES = sctp.SCTP_SHUTDOWN_GUARD_EXPIRES
+SCTP_PEER_FAULTY = sctp.SCTP_PEER_FAULTY
+
+SCTP_BINDX_ADD_ADDR = sctp.SCTP_BINDX_ADD_ADDR
+SCTP_BINDX_REM_ADDR = sctp.SCTP_BINDX_REM_ADDR
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk.net/sctp/sock.pxd	Sun Aug 16 18:29:55 2009 +0300
@@ -0,0 +1,206 @@
+cimport libc
+
+from libc cimport __u8, __u16, __u32, __s8, __s16, __s32
+
+# <netinet/sctp.h>
+# this defines the kernel SCTP -> userspace API extensions, such as structure types etc.
+cdef extern from "netinet/sctp.h" :
+    ## types
+    ctypedef __s32 sctp_assoc_t
+
+    ## constants
+    # sockapi
+    enum :
+        SOL_SCTP
+        IPPROTO_SCTP
+
+    # sockopts
+    enum :
+        SCTP_RTOINFO
+        SCTP_ASSOCINFO
+        SCTP_INITMSG
+        SCTP_NODELAY
+        SCTP_AUTOCLOSE
+        SCTP_SET_PEER_PRIMARY_ADDR
+        SCTP_PRIMARY_ADDR
+        SCTP_ADAPTATION_LAYER
+        SCTP_DISABLE_FRAGMENTS
+        SCTP_PEER_ADDR_PARAMS
+        SCTP_DEFAULT_SEND_PARAM
+        SCTP_EVENTS
+        SCTP_I_WANT_MAPPED_V4_ADDR
+        SCTP_MAXSEG
+        SCTP_STATUS
+        SCTP_GET_PEER_ADDR_INFO
+        SCTP_DELAYED_ACK_TIME
+        SCTP_CONTEXT
+        SCTP_FRAGMENT_INTERLEAVE
+        SCTP_PARTIAL_DELIVERY_POINT
+        SCTP_MAX_BURST
+
+    ## send/recv-msg cmsghdr's
+    struct sctp_initmsg :
+        __u16 sinit_num_ostreams
+        __u16 sinit_max_instreams
+        __u16 sinit_max_attempts
+        __u16 sinit_max_init_timeo
+
+    struct sctp_sndrcvinfo :
+        __u16 sinfo_stream
+        __u16 sinfo_ssn
+        __u16 sinfo_flags
+        __u32 sinfo_ppid
+        __u32 sinfo_context
+        __u32 sinfo_timetolive
+        __u32 sinfo_tsn
+        __u32 sinfo_cumtsn
+        sctp_assoc_t sinfo_assoc_id
+
+    # sctp_sndrcvinfo.sinfo_flags values
+    enum sctp_sinfo_flags :
+        SCTP_UNORDERED          # Send/receive message unordered
+        SCTP_ADDR_OVER          # Override the primary destination
+        SCTP_ABORT              # Send an ABORT message to the peer
+        SCTP_EOF                # Initiate graceful shutdown process
+    
+    ## notifications
+    struct sctp_assoc_change :
+        __u16 sac_type
+        __u16 sac_flags
+        __u32 sac_length
+        __u16 sac_state
+        __u16 sac_error
+        __u16 sac_outbound_streams
+        __u16 sac_inbound_streams
+        sctp_assoc_t sac_assoc_id
+        __u8 sac_info[0]
+    
+    # sctp_assoc_change.sac_state
+    enum sctp_sac_state :
+        SCTP_COMM_UP
+        SCTP_COMM_LOST
+        SCTP_RESTART
+        SCTP_SHUTDOWN_COMP
+        SCTP_CANT_STR_ASSOC
+
+    struct sctp_paddr_change :
+        __u16 spc_type
+        __u16 spc_flags
+        __u32 spc_length
+        libc.sockaddr_storage spc_aaddr
+        int spc_state
+        int spc_error
+        sctp_assoc_t spc_assoc_id
+
+    enum sctp_spc_state :
+        SCTP_ADDR_AVAILABLE
+        SCTP_ADDR_UNREACHABLE
+        SCTP_ADDR_REMOVED
+        SCTP_ADDR_ADDED
+        SCTP_ADDR_MADE_PRIM
+        SCTP_ADDR_CONFIRMED
+
+    struct sctp_remote_error :
+        __u16 sre_type
+        __u16 sre_flags
+        __u32 sre_length
+        __u16 sre_error
+        sctp_assoc_t sre_assoc_id
+        __u8 sre_data[0]
+
+
+    struct sctp_send_failed :
+        __u16 ssf_type
+        __u16 ssf_flags
+        __u32 ssf_length
+        __u32 ssf_error
+        sctp_sndrcvinfo ssf_info
+        sctp_assoc_t ssf_assoc_id
+        __u8 ssf_data[0]
+
+    enum sctp_ssf_flags :
+        SCTP_DATA_UNSENT
+        SCTP_DATA_SENT
+
+    struct sctp_shutdown_event :
+        __u16 sse_type
+        __u16 sse_flags
+        __u32 sse_length
+        sctp_assoc_t sse_assoc_id
+
+    struct sctp_adaptation_event :
+        __u16 sai_type
+        __u16 sai_flags
+        __u32 sai_length
+        __u32 sai_adaptation_ind
+        sctp_assoc_t sai_assoc_id
+
+    struct sctp_pdapi_event :
+        __u16 pdapi_type
+        __u16 pdapi_flags
+        __u32 pdapi_length
+        __u32 pdapi_indication
+        sctp_assoc_t pdapi_assoc_id
+
+    enum :
+        SCTP_PARTIAL_DELIVERY_ABORTED
+
+    struct sctp_event_subscribe :
+        __u8 sctp_data_io_event
+        __u8 sctp_association_event
+        __u8 sctp_address_event
+        __u8 sctp_send_failure_event
+        __u8 sctp_peer_error_event
+        __u8 sctp_shutdown_event
+        __u8 sctp_partial_delivery_event
+        __u8 sctp_adaptation_layer_event
+
+    struct sn_header :
+        __u16 sn_type
+        __u16 sn_flags
+        __u32 sn_length
+
+    union sctp_notification :
+        sn_header sn_header
+
+        sctp_assoc_change sn_assoc_change
+        sctp_paddr_change sn_paddr_change
+        sctp_remote_error sn_remote_error
+        sctp_send_failed sn_send_failed
+        sctp_shutdown_event sn_shutdown_event
+        sctp_adaptation_event sn_adaptation_event
+        sctp_pdapi_event sn_pdapi_event
+
+    enum sctp_sn_type :
+        SCTP_SN_TYPE_BASE
+        SCTP_ASSOC_CHANGE
+        SCTP_PEER_ADDR_CHANGE
+        SCTP_SEND_FAILED
+        SCTP_REMOTE_ERROR
+        SCTP_SHUTDOWN_EVENT
+        SCTP_PARTIAL_DELIVERY_EVENT
+        SCTP_ADAPTATION_INDICATION
+
+    enum sctp_sn_error :
+        SCTP_FAILED_THRESHOLD
+        SCTP_RECEIVED_SACK
+        SCTP_HEARTBEAT_SUCCESS
+        SCTP_RESPONSE_TO_USER_REQ
+        SCTP_INTERNAL_ERROR
+        SCTP_SHUTDOWN_GUARD_EXPIRES
+        SCTP_PEER_FAULTY
+    
+    ctypedef sctp_sn_error sctp_sn_error_t
+    
+
+    ## sctp_bindx
+    enum :
+        SCTP_BINDX_ADD_ADDR
+        SCTP_BINDX_REM_ADDR
+
+    int c_sctp_bindx "sctp_bindx" (int sd, libc.sockaddr *addrs, int addrcnt, int flags)
+
+    # XXX: missing return-sctp_assoc_t-id argument!
+    int c_sctp_connectx "sctp_connectx" (int sd, libc.sockaddr *addrs, int addrcnt)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk.net/sctp/sock.pyx	Sun Aug 16 18:29:55 2009 +0300
@@ -0,0 +1,98 @@
+"""
+    This C(ython) extension module provides an interface to the libsctp library and associated socket API.
+    
+    >>> import socket
+    >>> from sock.addr import sockaddr_in
+    >>> s = socket.socket(socket.AF_INET, socket.SOCK_SEQPACKET, 132)
+    >>> sctp_bindx(s.fileno(), [sockaddr_in('127.0.0.1', 1337), sockaddr_in('127.0.0.2')], 0x01)
+    >>>
+
+"""
+
+from sctp.sock cimport *
+from py cimport raise_errno
+
+cimport libc
+cimport sock.addr
+
+cdef size_t addrsoup_len (object addrs) except -1 :
+    """
+        Calculate the length of the addr_buf required to store the given addrsoup
+    """
+
+    cdef sock.addr.sockaddr addr
+    cdef size_t addr_size = 0
+
+    # whoever decided that sctp_bindx takes an array of mixed sockaddr_in/sockaddr_in6's should be shot
+    for addr in addrs :
+        addr_size += addr._get_sockaddr_len()
+    
+    return addr_size
+
+cdef addrsoup_store (object addrs, char *addr_buf) :
+    """
+        Store the sockaddr_*'s for the given addresses into the given buffer, which should be addrsoup_len() bytes long
+    """
+
+    cdef sock.addr.sockaddr addr
+    cdef char *addr_ptr = addr_buf
+
+    # fill it
+    cdef libc.sockaddr *sa
+    cdef libc.socklen_t sa_len
+
+    for addr in addrs :
+        # get address's sockaddr info
+        addr._get_sockaddr(&sa, &sa_len)
+        
+        # copy to buffer
+        libc.memcpy(addr_ptr, sa, sa_len)
+        
+        # move to next
+        addr_ptr += sa_len
+
+def sctp_bindx (int sd, object addrs, int flags) :
+    """
+        Bind the given SOCK_SEQPACKET to the given set of sock.addr.sockaddr's.
+
+            sd          the system socket FD
+            addresses   the list of qmsk.net.sock.addr.sockaddr's
+            flags       one of SCTP_BINDX_ADD/REM_ADDR
+        
+    """
+
+    # ensure that addrs stays the same... ?
+    addrs = tuple(addrs)
+
+    # alloc buffer to hold all the sockaddr_*'s
+    cdef char *addr_buf = <char *> libc.alloca(addrsoup_len(addrs))
+
+    # store
+    addrsoup_store(addrs, addr_buf)
+
+    # then call
+    if c_sctp_bindx(sd, <libc.sockaddr *> addr_buf, len(addrs), flags) < 0 :
+        raise_errno('sctp_bindx')
+
+def sctp_connectx (int sd, object addrs) :
+    """
+        Connect the given SOCK_SEQPACKET to the given set of remote sock.addr.sockaddr's.
+
+            sd          the system socket FD
+            addresses   the list of qmsk.net.sock.addr.sockaddr's
+        
+    """
+
+    # ensure that addrs stays the same... ?
+    addrs = tuple(addrs)
+
+    # alloc buffer to hold all the sockaddr_*'s
+    cdef char *addr_buf = <char *> libc.alloca(addrsoup_len(addrs))
+
+    # store
+    addrsoup_store(addrs, addr_buf)
+
+    # then call
+    if c_sctp_connectx(sd, <libc.sockaddr *> addr_buf, len(addrs)) < 0 :
+        raise_errno('sctp_connectx')
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk.net/socket/addr.pxd	Sun Aug 16 18:29:55 2009 +0300
@@ -0,0 +1,95 @@
+"""
+    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 libc
+
+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 libc.sa_family_t family
+
+    cdef void _init_family (self, libc.sa_family_t family = ?)
+
+    # get the sockaddr/socklen
+    # each of these can be NULL to ignore it
+    cdef int _get_sockaddr (self, libc.sockaddr **sa_ptr, libc.socklen_t *sa_len) except -1
+
+    cdef libc.sockaddr* _get_sockaddr_ptr (self) except NULL
+    cdef libc.socklen_t _get_sockaddr_len (self) except -1
+    
+    # set the sockaddr, socklen must match
+    cdef int _set_sockaddr (self, libc.sockaddr *sa, size_t sa_len) except -1
+
+# build a sockaddr from the given sockaddr struct, based on sa_family
+cdef sockaddr build_sockaddr (libc.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, libc.addrinfo *c_ai)
+
+# build and return a new addrinfo instance
+cdef addrinfo build_addrinfo (libc.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.
+
+        >>> import 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 = ?)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk.net/socket/addr.pyx	Sun Aug 16 18:29:55 2009 +0300
@@ -0,0 +1,349 @@
+cimport libc
+
+from addr cimport *
+
+cdef class sockaddr :
+    cdef void _init_family (self, libc.sa_family_t family=libc.AF_UNSPEC) :
+        self.family = family
+
+    # XXX:use size_t
+    cdef int _get_sockaddr (self, libc.sockaddr **sa_ptr, libc.socklen_t *sa_len) except -1 :
+        """
+            Get the sockaddr pointer and sockaddr length for this address
+        """ 
+
+        raise NotImplementedError()
+
+    cdef libc.sockaddr* _get_sockaddr_ptr (self) except NULL :
+        """
+            Get the sockaddr pointer
+        """
+
+        cdef libc.sockaddr *sa
+        cdef libc.socklen_t sa_len
+
+        self._get_sockaddr(&sa, &sa_len)
+
+        return sa
+    
+    cdef libc.socklen_t _get_sockaddr_len (self) except -1 :
+        """
+            Get the sockaddr len
+        """
+
+        cdef libc.sockaddr *sa
+        cdef libc.socklen_t sa_len
+
+        self._get_sockaddr(&sa, &sa_len)
+
+        return sa_len
+
+    cdef int _set_sockaddr (self, libc.sockaddr *sa, size_t sa_len) except -1 :
+        """
+            Set the sockaddr value for this address; sa_len must match!
+        """
+
+        raise NotImplementedError()
+
+    def getnameinfo (self) :
+        """
+            Returns a (host, serv) tuple for this address à la getnameinfo
+        """
+
+        cdef libc.sockaddr *sa
+        cdef libc.socklen_t sa_len
+
+        # XXX: take as args?
+        cdef int flags = libc.NI_NUMERICHOST | libc.NI_NUMERICSERV
+        
+        # get our abstract sockaddr
+        self._get_sockaddr(&sa, &sa_len)
+
+        # get nice text format
+        return libc.getnameinfo(sa, sa_len, flags)
+
+    property addr :
+        """
+            The ASCII literal network address
+        """
+
+        def __get__ (self) :
+            """
+                Default implmentation using getnameinfo()
+            """
+
+            addr, port = self.getnameinfo()
+
+            return addr
+
+    property port :
+        """
+            The integer port number
+        """
+
+        def __get__ (self) :
+            """
+                Default implementation using getnameinfo() and int()
+            """
+
+            addr, port = self.getnameinfo()
+
+            return int(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'
+        >>> str(sockaddr_in())
+        '0.0.0.0:0'
+    """
+
+    # the struct sockaddr_in
+    cdef libc.sockaddr_in sockaddr
+
+    def __init__ (self, object addr=None, libc.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)
+        """
+
+        # store our family
+        # XXX: this should be a class attribute...
+        self._init_family(libc.AF_INET)
+
+        # constant af
+        self.sockaddr.sin_family = self.family
+        
+        # set the sin_port
+        self.sockaddr.sin_port = libc.htons(port)
+        
+        if addr :
+            # set the sin_addr
+            # this automatically converts the addr from str -> char *
+            libc.inet_pton(self.family, addr, &self.sockaddr.sin_addr)
+
+        else :
+            # set as INADDR_ANY
+            self.sockaddr.sin_addr.s_addr = libc.INADDR_ANY
+    
+    cdef int _get_sockaddr (self, libc.sockaddr **sa_ptr, libc.socklen_t *sa_len) except -1 :
+        if sa_ptr :
+            sa_ptr[0] = <libc.sockaddr *> &self.sockaddr
+
+        if sa_len :
+            sa_len[0] = sizeof(self.sockaddr)
+
+        return 0
+
+    cdef int _set_sockaddr (self, libc.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
+        """
+
+        def __get__ (self) :
+            return libc.ntohs(self.sockaddr.sin_port)
+
+    def __str__ (self) :
+        """
+            Return the literal ASCII representation for this sockaddr as an '<addr>:<port> string
+        """
+        
+        # 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'
+        >>> str(sockaddr_in6())
+        '[::]:0'
+    """
+
+    cdef libc.sockaddr_in6 sockaddr
+
+    def __init__ (self, object addr=None, libc.in_port_t port=0) :
+        """
+            Construct using given literal IPv6 address and TCP/UDP port
+
+                addr        - IPv6 address, defaults to in6addr_any (::)
+                port        - TCP/UDP port, defaults to 0 (ephemeral)
+        """
+
+        # store our family
+        # XXX: this should be a class attribute...
+        self._init_family(libc.AF_INET6)
+
+        # constant af
+        self.sockaddr.sin6_family = self.family
+        
+        # set the sin_port
+        self.sockaddr.sin6_port = libc.htons(port)
+        
+        if addr :
+            # set the sin_addr
+            # this automatically converts the addr from str -> char *
+            libc.inet_pton(self.family, addr, &self.sockaddr.sin6_addr)
+
+        else :
+            # set as INADDR_ANY
+            self.sockaddr.sin6_addr = libc.in6addr_any
+
+    cdef int _get_sockaddr (self, libc.sockaddr **sa_ptr, libc.socklen_t *sa_len) except -1 :
+        if sa_ptr :
+            sa_ptr[0] = <libc.sockaddr *> &self.sockaddr
+
+        if sa_len :
+            sa_len[0] = sizeof(self.sockaddr)
+
+        return 0
+
+    cdef int _set_sockaddr (self, libc.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
+        """
+
+        def __get__ (self) :
+            return libc.ntohs(self.sockaddr.sin6_port)
+
+
+    def __str__ (self) :
+        """
+            Return the literal ASCII representation for this sockaddr as a '[<addr>]:<port> string
+        """
+        
+        # format
+        return "[%s]:%s" % self.getnameinfo()
+
+# mapping of AF -> sockaddr, user-modifyable
+SOCKADDR_BY_FAMILY = {
+    libc.AF_INET:   sockaddr_in,
+    libc.AF_INET6:  sockaddr_in6,
+}
+
+# build a sockaddr from the given sockaddr struct, based on sa_family
+cdef sockaddr build_sockaddr (libc.sockaddr *sa, size_t sa_len) :
+    # lookup correct class to use
+    addr_type = SOCKADDR_BY_FAMILY[sa.sa_family]
+    
+    # construct with defaults
+    cdef sockaddr addr = addr_type()
+
+    # store
+    addr._set_sockaddr(sa, sa_len)
+
+    return addr
+
+cdef class addrinfo :
+    
+    cdef _init_addrinfo (self, libc.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
+
+    def __str__ (self) :
+        return "family=%d, socktype=%d, protocol=%d, addr=%s, canonname=%s" % (self.family, self.socktype, self.protocol, self.addr, self.canonname)
+
+cdef addrinfo build_addrinfo (libc.addrinfo *c_ai) :
+    cdef addrinfo ai = addrinfo()
+    
+    ai._init_addrinfo(c_ai)
+
+    return ai
+
+cdef class endpoint :
+
+    def __init__ (self, hostname=None, service=None) :
+        """
+            Construct with the given hostname/service, either of which may be None.
+
+            A hostname of None implies all valid local addresses (with AI_PASSIVE), and a service of None implies an
+            ephemeral port.
+
+                hostname        - the literal address or DNS hostname or anything else that GAI supports
+                service         - the numeric port or service name
+        """
+
+        self.hostname = str(hostname)
+        self.service = str(service)
+
+    cpdef getaddrinfo (self, int family, int socktype, int protocol = 0, int flags = libc.AI_PASSIVE) :
+        """
+            Look up our hostname/service using the given socket parameters, and return a sequence of addrinfo objects.
+        """
+        
+        # XXX: Cython doesn't support proper compound value literals...
+        cdef libc.addrinfo hints
+        
+        libc.memset(&hints, 0, sizeof(hints))
+        hints.ai_flags          = flags
+        hints.ai_family         = family
+        hints.ai_socktype       = socktype
+        hints.ai_protocol       = protocol
+
+        cdef libc.addrinfo *res, *r
+        cdef int err
+        cdef object ret = []
+
+        cdef char *hostname = NULL
+        cdef char *service = NULL
+
+        if self.hostname is not None :
+            hostname = self.hostname
+        
+        if self.service is not None :
+            service = self.service
+
+        # operate!
+        err = libc.c_getaddrinfo(hostname, service, &hints, &res)
+
+        try :
+            if err :
+                # XXX: raise a GAIError
+                raise Exception(libc.gai_strerror(err))
+            
+            # gather results
+            r = res
+
+            while r :
+                ret.append(build_addrinfo(r))
+
+                r = r.ai_next
+            
+            # ok
+            return ret
+
+        finally :
+            libc.c_freeaddrinfo(res)
+
+    def __str__ (self) :
+        return "hostname=%s, service=%s" % (self.hostname, self.service)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk.net/socket/sock.pxd	Sun Aug 16 18:29:55 2009 +0300
@@ -0,0 +1,26 @@
+"""
+    Sockect Object/API
+"""
+
+ctypedef int socket_t
+
+cdef class sock :
+    """
+        Represents a single OS-level socket
+        
+        >>> from socket import addr
+        >>> s = sock()
+        >>> s.send('foo')
+        Traceback (most recent call last):
+          ...
+        OSError: [Errno 9] Bad file descriptor
+        >>> s.socket()
+        >>> s.bind(addr.sockaddr_in('127.0.0.1', 1337))
+        >>> s.listen(1)
+        >>> s.listen(0)
+        >>> s.connect(addr.sockaddr_in('127.0.01.', 1338))
+        x
+    """
+
+    cdef readonly socket_t fd
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk.net/socket/sock.pyx	Sun Aug 16 18:29:55 2009 +0300
@@ -0,0 +1,149 @@
+from sock.sock cimport *
+from sock.addr cimport sockaddr, build_sockaddr
+
+cimport libc, py
+
+from py cimport raise_errno
+
+# XXX: do some GIL-releasin'
+cdef class sock :
+
+    def __init__ (self, int fd = -1) :
+        """
+            Construct this socket with the given fd, or -1 to mark it as fd-less
+        """
+
+        self.fd = fd
+
+    def socket (self, int family = libc.AF_INET, int socktype = libc.SOCK_STREAM, int protocol = 0) :
+        """
+            Create a new socket endpoint with the given family/domain, socktype and optionally, specific protocol.
+
+                family      - one of AF_*
+                socktype    - one of SOCK_*
+                protocol    - one of IPPROTO_* or zero to select default
+        """
+
+        if self.fd >= 0 :
+            raise Exception("Socket fd already exists")
+        
+        # socket()
+        self.fd = libc.socket(family, socktype, protocol)
+        
+        # trap
+        if self.fd < 0 :
+            raise_errno('socket')
+
+    def bind (self, sockaddr addr) :
+        """
+            Bind this socket to the given local socket address. The given sockaddr should be of the same or a
+            compatible address family.
+
+                addr        - the local address to bind to. The port may be zero to let the system choose an unused
+                              ephemeral port.
+        """
+
+        cdef libc.sockaddr *sa_ptr
+        cdef libc.socklen_t sa_len
+
+        # get the address
+        addr._get_sockaddr(&sa_ptr, &sa_len)
+
+        # bind()
+        if libc.bind(self.fd, sa_ptr, sa_len) :
+            raise_errno('bind')
+
+    def listen (self, int backlog) :
+        """
+            Listen for connections, marking this socket as a passive socket, which can accept incoming connection
+            requests using sock.accept().
+
+            It is customary to call .bind() before .listen().
+
+                backlog     - maximum number of pending connections (those not yet .accept()'d).
+        """
+        
+        # listen()
+        if libc.listen(self.fd, backlog) :
+            raise_errno('listen')
+
+    def connect (self, sockaddr addr) :
+        """
+            Initiate a connection, connecting this socket to the remote endpoint specified by `addr`. The given sockaddr
+            should be of the same or a compatible address family.
+
+            If the socket is in non-blocking mode, this will presumeably return errno.EINPROGRESS.
+
+            If the socket has not yet been bound (using .bind()), the system will pick an appropriate local address and
+            ephemeral port.
+
+                addr        - the remote address to connect to.
+        """
+
+        cdef libc.sockaddr *sa_ptr
+        cdef libc.socklen_t sa_len
+
+        # get the address
+        addr._get_sockaddr(&sa_ptr, &sa_len)
+        
+        # connect()
+        if libc.connect(self.fd, sa_ptr, sa_len) :
+            raise_errno('connect')
+
+    def accept (self) :
+        """
+            Accept a connection, dequeueing the first pending connection and returning a new sock object for it. This
+            socket must be a connection-based socket (SOCK_STREAM/SOCK_SEQPACKET) and in the passive listening mode
+            (.listen()).
+
+            This returns a (sock, sockaddr) tuple:
+                sock        - the newly created sock, corresponding to the incoming connection
+                sockaddr    - the remote address of the incoming connection
+        """
+        
+        # prep the sockaddr that we will return
+        cdef libc.sockaddr_storage ss
+        cdef libc.socklen_t ss_len = sizeof(ss)
+
+        cdef socket_t sock_fd
+
+        # accept()
+        sock_fd = libc.accept(self.fd, <libc.sockaddr *> &ss, &ss_len)
+
+        if sock_fd < 0 :
+            raise_errno('accept')
+
+        # prep the new socket
+        sock_obj = sock(sock_fd)
+
+        # prep the new addr
+        sock_addr = build_sockaddr(<libc.sockaddr *> &ss, ss_len)
+
+        return sock_obj, sock_addr
+
+    def send (self, object buf, int flags = 0) :
+        """
+            Transmit a message to the connected remote endpoint.
+
+                buf     - the data to send
+                flags   - MSG_* flags to send with
+
+            Returns the number of bytes sent, which may be less than the length of buf.
+        """
+
+        cdef char *buf_ptr
+        cdef libc.ssize_t buf_len, ret
+
+        # get buffer
+        # XXX: test that except works right
+        py.PyObject_AsCharBuffer(buf, &buf_ptr, &buf_len)
+        
+        # send()
+        ret = libc.send(self.fd, <void *> buf_ptr, buf_len, flags)
+        
+        if ret < 0 :
+            raise_errno('send')
+
+        else :
+            return ret
+
--- a/sctp/constants.pyx	Sun Aug 16 16:38:44 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-cimport sctp.sock as sctp
-
-SOL_SCTP = sctp.SOL_SCTP
-IPPROTO_SCTP = sctp.IPPROTO_SCTP
-
-SCTP_RTOINFO = sctp.SCTP_RTOINFO
-SCTP_ASSOCINFO = sctp.SCTP_ASSOCINFO
-SCTP_INITMSG = sctp.SCTP_INITMSG
-SCTP_NODELAY = sctp.SCTP_NODELAY
-SCTP_AUTOCLOSE = sctp.SCTP_AUTOCLOSE
-SCTP_SET_PEER_PRIMARY_ADDR = sctp.SCTP_SET_PEER_PRIMARY_ADDR
-SCTP_PRIMARY_ADDR = sctp.SCTP_PRIMARY_ADDR
-SCTP_ADAPTATION_LAYER = sctp.SCTP_ADAPTATION_LAYER
-SCTP_DISABLE_FRAGMENTS = sctp.SCTP_DISABLE_FRAGMENTS
-SCTP_PEER_ADDR_PARAMS = sctp.SCTP_PEER_ADDR_PARAMS
-SCTP_DEFAULT_SEND_PARAM = sctp.SCTP_DEFAULT_SEND_PARAM
-SCTP_EVENTS = sctp.SCTP_EVENTS
-SCTP_I_WANT_MAPPED_V4_ADDR = sctp.SCTP_I_WANT_MAPPED_V4_ADDR
-SCTP_MAXSEG = sctp.SCTP_MAXSEG
-SCTP_STATUS = sctp.SCTP_STATUS
-SCTP_GET_PEER_ADDR_INFO = sctp.SCTP_GET_PEER_ADDR_INFO
-SCTP_DELAYED_ACK_TIME = sctp.SCTP_DELAYED_ACK_TIME
-SCTP_CONTEXT = sctp.SCTP_CONTEXT
-SCTP_FRAGMENT_INTERLEAVE = sctp.SCTP_FRAGMENT_INTERLEAVE
-SCTP_PARTIAL_DELIVERY_POINT = sctp.SCTP_PARTIAL_DELIVERY_POINT
-SCTP_MAX_BURST = sctp.SCTP_MAX_BURST
-
-SCTP_ADDR_AVAILABLE = sctp.SCTP_ADDR_AVAILABLE
-SCTP_ADDR_UNREACHABLE = sctp.SCTP_ADDR_UNREACHABLE
-SCTP_ADDR_REMOVED = sctp.SCTP_ADDR_REMOVED
-SCTP_ADDR_ADDED = sctp.SCTP_ADDR_ADDED
-SCTP_ADDR_MADE_PRIM = sctp.SCTP_ADDR_MADE_PRIM
-SCTP_ADDR_CONFIRMED = sctp.SCTP_ADDR_CONFIRMED
-
-
-SCTP_DATA_UNSENT = sctp.SCTP_DATA_UNSENT
-SCTP_DATA_SENT = sctp.SCTP_DATA_SENT
-
-SCTP_PARTIAL_DELIVERY_ABORTED = sctp.SCTP_PARTIAL_DELIVERY_ABORTED
-
-# enum sctp_sn_type :
-SCTP_SN_TYPE_BASE = sctp.SCTP_SN_TYPE_BASE
-SCTP_ASSOC_CHANGE = sctp.SCTP_ASSOC_CHANGE
-SCTP_PEER_ADDR_CHANGE = sctp.SCTP_PEER_ADDR_CHANGE
-SCTP_SEND_FAILED = sctp.SCTP_SEND_FAILED
-SCTP_REMOTE_ERROR = sctp.SCTP_REMOTE_ERROR
-SCTP_SHUTDOWN_EVENT = sctp.SCTP_SHUTDOWN_EVENT
-SCTP_PARTIAL_DELIVERY_EVENT = sctp.SCTP_PARTIAL_DELIVERY_EVENT
-SCTP_ADAPTATION_INDICATION = sctp.SCTP_ADAPTATION_INDICATION
-
-# enum sctp_sn_error :
-SCTP_FAILED_THRESHOLD = sctp.SCTP_FAILED_THRESHOLD
-SCTP_RECEIVED_SACK = sctp.SCTP_RECEIVED_SACK
-SCTP_HEARTBEAT_SUCCESS = sctp.SCTP_HEARTBEAT_SUCCESS
-SCTP_RESPONSE_TO_USER_REQ = sctp.SCTP_RESPONSE_TO_USER_REQ
-SCTP_INTERNAL_ERROR = sctp.SCTP_INTERNAL_ERROR
-SCTP_SHUTDOWN_GUARD_EXPIRES = sctp.SCTP_SHUTDOWN_GUARD_EXPIRES
-SCTP_PEER_FAULTY = sctp.SCTP_PEER_FAULTY
-
-SCTP_BINDX_ADD_ADDR = sctp.SCTP_BINDX_ADD_ADDR
-SCTP_BINDX_REM_ADDR = sctp.SCTP_BINDX_REM_ADDR
-
--- a/sctp/sock.pxd	Sun Aug 16 16:38:44 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-cimport libc
-
-from libc cimport __u8, __u16, __u32, __s8, __s16, __s32
-
-# <netinet/sctp.h>
-# this defines the kernel SCTP -> userspace API extensions, such as structure types etc.
-cdef extern from "netinet/sctp.h" :
-    ## types
-    ctypedef __s32 sctp_assoc_t
-
-    ## constants
-    # sockapi
-    enum :
-        SOL_SCTP
-        IPPROTO_SCTP
-
-    # sockopts
-    enum :
-        SCTP_RTOINFO
-        SCTP_ASSOCINFO
-        SCTP_INITMSG
-        SCTP_NODELAY
-        SCTP_AUTOCLOSE
-        SCTP_SET_PEER_PRIMARY_ADDR
-        SCTP_PRIMARY_ADDR
-        SCTP_ADAPTATION_LAYER
-        SCTP_DISABLE_FRAGMENTS
-        SCTP_PEER_ADDR_PARAMS
-        SCTP_DEFAULT_SEND_PARAM
-        SCTP_EVENTS
-        SCTP_I_WANT_MAPPED_V4_ADDR
-        SCTP_MAXSEG
-        SCTP_STATUS
-        SCTP_GET_PEER_ADDR_INFO
-        SCTP_DELAYED_ACK_TIME
-        SCTP_CONTEXT
-        SCTP_FRAGMENT_INTERLEAVE
-        SCTP_PARTIAL_DELIVERY_POINT
-        SCTP_MAX_BURST
-
-    ## send/recv-msg cmsghdr's
-    struct sctp_initmsg :
-        __u16 sinit_num_ostreams
-        __u16 sinit_max_instreams
-        __u16 sinit_max_attempts
-        __u16 sinit_max_init_timeo
-
-    struct sctp_sndrcvinfo :
-        __u16 sinfo_stream
-        __u16 sinfo_ssn
-        __u16 sinfo_flags
-        __u32 sinfo_ppid
-        __u32 sinfo_context
-        __u32 sinfo_timetolive
-        __u32 sinfo_tsn
-        __u32 sinfo_cumtsn
-        sctp_assoc_t sinfo_assoc_id
-
-    # sctp_sndrcvinfo.sinfo_flags values
-    enum sctp_sinfo_flags :
-        SCTP_UNORDERED          # Send/receive message unordered
-        SCTP_ADDR_OVER          # Override the primary destination
-        SCTP_ABORT              # Send an ABORT message to the peer
-        SCTP_EOF                # Initiate graceful shutdown process
-    
-    ## notifications
-    struct sctp_assoc_change :
-        __u16 sac_type
-        __u16 sac_flags
-        __u32 sac_length
-        __u16 sac_state
-        __u16 sac_error
-        __u16 sac_outbound_streams
-        __u16 sac_inbound_streams
-        sctp_assoc_t sac_assoc_id
-        __u8 sac_info[0]
-    
-    # sctp_assoc_change.sac_state
-    enum sctp_sac_state :
-        SCTP_COMM_UP
-        SCTP_COMM_LOST
-        SCTP_RESTART
-        SCTP_SHUTDOWN_COMP
-        SCTP_CANT_STR_ASSOC
-
-    struct sctp_paddr_change :
-        __u16 spc_type
-        __u16 spc_flags
-        __u32 spc_length
-        libc.sockaddr_storage spc_aaddr
-        int spc_state
-        int spc_error
-        sctp_assoc_t spc_assoc_id
-
-    enum sctp_spc_state :
-        SCTP_ADDR_AVAILABLE
-        SCTP_ADDR_UNREACHABLE
-        SCTP_ADDR_REMOVED
-        SCTP_ADDR_ADDED
-        SCTP_ADDR_MADE_PRIM
-        SCTP_ADDR_CONFIRMED
-
-    struct sctp_remote_error :
-        __u16 sre_type
-        __u16 sre_flags
-        __u32 sre_length
-        __u16 sre_error
-        sctp_assoc_t sre_assoc_id
-        __u8 sre_data[0]
-
-
-    struct sctp_send_failed :
-        __u16 ssf_type
-        __u16 ssf_flags
-        __u32 ssf_length
-        __u32 ssf_error
-        sctp_sndrcvinfo ssf_info
-        sctp_assoc_t ssf_assoc_id
-        __u8 ssf_data[0]
-
-    enum sctp_ssf_flags :
-        SCTP_DATA_UNSENT
-        SCTP_DATA_SENT
-
-    struct sctp_shutdown_event :
-        __u16 sse_type
-        __u16 sse_flags
-        __u32 sse_length
-        sctp_assoc_t sse_assoc_id
-
-    struct sctp_adaptation_event :
-        __u16 sai_type
-        __u16 sai_flags
-        __u32 sai_length
-        __u32 sai_adaptation_ind
-        sctp_assoc_t sai_assoc_id
-
-    struct sctp_pdapi_event :
-        __u16 pdapi_type
-        __u16 pdapi_flags
-        __u32 pdapi_length
-        __u32 pdapi_indication
-        sctp_assoc_t pdapi_assoc_id
-
-    enum :
-        SCTP_PARTIAL_DELIVERY_ABORTED
-
-    struct sctp_event_subscribe :
-        __u8 sctp_data_io_event
-        __u8 sctp_association_event
-        __u8 sctp_address_event
-        __u8 sctp_send_failure_event
-        __u8 sctp_peer_error_event
-        __u8 sctp_shutdown_event
-        __u8 sctp_partial_delivery_event
-        __u8 sctp_adaptation_layer_event
-
-    struct sn_header :
-        __u16 sn_type
-        __u16 sn_flags
-        __u32 sn_length
-
-    union sctp_notification :
-        sn_header sn_header
-
-        sctp_assoc_change sn_assoc_change
-        sctp_paddr_change sn_paddr_change
-        sctp_remote_error sn_remote_error
-        sctp_send_failed sn_send_failed
-        sctp_shutdown_event sn_shutdown_event
-        sctp_adaptation_event sn_adaptation_event
-        sctp_pdapi_event sn_pdapi_event
-
-    enum sctp_sn_type :
-        SCTP_SN_TYPE_BASE
-        SCTP_ASSOC_CHANGE
-        SCTP_PEER_ADDR_CHANGE
-        SCTP_SEND_FAILED
-        SCTP_REMOTE_ERROR
-        SCTP_SHUTDOWN_EVENT
-        SCTP_PARTIAL_DELIVERY_EVENT
-        SCTP_ADAPTATION_INDICATION
-
-    enum sctp_sn_error :
-        SCTP_FAILED_THRESHOLD
-        SCTP_RECEIVED_SACK
-        SCTP_HEARTBEAT_SUCCESS
-        SCTP_RESPONSE_TO_USER_REQ
-        SCTP_INTERNAL_ERROR
-        SCTP_SHUTDOWN_GUARD_EXPIRES
-        SCTP_PEER_FAULTY
-    
-    ctypedef sctp_sn_error sctp_sn_error_t
-    
-
-    ## sctp_bindx
-    enum :
-        SCTP_BINDX_ADD_ADDR
-        SCTP_BINDX_REM_ADDR
-
-    int c_sctp_bindx "sctp_bindx" (int sd, libc.sockaddr *addrs, int addrcnt, int flags)
-
-    # XXX: missing return-sctp_assoc_t-id argument!
-    int c_sctp_connectx "sctp_connectx" (int sd, libc.sockaddr *addrs, int addrcnt)
-
-
--- a/sctp/sock.pyx	Sun Aug 16 16:38:44 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-"""
-    This C(ython) extension module provides an interface to the libsctp library and associated socket API.
-    
-    >>> import socket
-    >>> from sock.addr import sockaddr_in
-    >>> s = socket.socket(socket.AF_INET, socket.SOCK_SEQPACKET, 132)
-    >>> sctp_bindx(s.fileno(), [sockaddr_in('127.0.0.1', 1337), sockaddr_in('127.0.0.2')], 0x01)
-    >>>
-
-"""
-
-from sctp.sock cimport *
-from py cimport raise_errno
-
-cimport libc
-cimport sock.addr
-
-cdef size_t addrsoup_len (object addrs) except -1 :
-    """
-        Calculate the length of the addr_buf required to store the given addrsoup
-    """
-
-    cdef sock.addr.sockaddr addr
-    cdef size_t addr_size = 0
-
-    # whoever decided that sctp_bindx takes an array of mixed sockaddr_in/sockaddr_in6's should be shot
-    for addr in addrs :
-        addr_size += addr._get_sockaddr_len()
-    
-    return addr_size
-
-cdef addrsoup_store (object addrs, char *addr_buf) :
-    """
-        Store the sockaddr_*'s for the given addresses into the given buffer, which should be addrsoup_len() bytes long
-    """
-
-    cdef sock.addr.sockaddr addr
-    cdef char *addr_ptr = addr_buf
-
-    # fill it
-    cdef libc.sockaddr *sa
-    cdef libc.socklen_t sa_len
-
-    for addr in addrs :
-        # get address's sockaddr info
-        addr._get_sockaddr(&sa, &sa_len)
-        
-        # copy to buffer
-        libc.memcpy(addr_ptr, sa, sa_len)
-        
-        # move to next
-        addr_ptr += sa_len
-
-def sctp_bindx (int sd, object addrs, int flags) :
-    """
-        Bind the given SOCK_SEQPACKET to the given set of sock.addr.sockaddr's.
-
-            sd          the system socket FD
-            addresses   the list of qmsk.net.sock.addr.sockaddr's
-            flags       one of SCTP_BINDX_ADD/REM_ADDR
-        
-    """
-
-    # ensure that addrs stays the same... ?
-    addrs = tuple(addrs)
-
-    # alloc buffer to hold all the sockaddr_*'s
-    cdef char *addr_buf = <char *> libc.alloca(addrsoup_len(addrs))
-
-    # store
-    addrsoup_store(addrs, addr_buf)
-
-    # then call
-    if c_sctp_bindx(sd, <libc.sockaddr *> addr_buf, len(addrs), flags) < 0 :
-        raise_errno()
-
-def sctp_connectx (int sd, object addrs) :
-    """
-        Connect the given SOCK_SEQPACKET to the given set of remote sock.addr.sockaddr's.
-
-            sd          the system socket FD
-            addresses   the list of qmsk.net.sock.addr.sockaddr's
-        
-    """
-
-    # ensure that addrs stays the same... ?
-    addrs = tuple(addrs)
-
-    # alloc buffer to hold all the sockaddr_*'s
-    cdef char *addr_buf = <char *> libc.alloca(addrsoup_len(addrs))
-
-    # store
-    addrsoup_store(addrs, addr_buf)
-
-    # then call
-    if c_sctp_connectx(sd, <libc.sockaddr *> addr_buf, len(addrs)) < 0 :
-        raise_errno()
-
--- a/setup.py	Sun Aug 16 16:38:44 2009 +0300
+++ b/setup.py	Sun Aug 16 18:29:55 2009 +0300
@@ -10,7 +10,8 @@
     ext_modules = [
         cython_ext("libc", ["libc.pyx"]),
         cython_ext("py", ["py.pyx"]),
-        cython_ext("sock.addr", ["sock/addr.pyx"]),
+        cython_ext("socket.addr", ["socket/addr.pyx"]),
+        cython_ext("socket.sock", ["socket/sock.pyx"]),
         cython_ext("sctp.sock", ["sctp/sock.pyx"], libraries=['sctp']),
         cython_ext("sctp.constants", ["sctp/constants.pyx"]),
     ]
--- a/sock/addr.pxd	Sun Aug 16 16:38:44 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-cimport libc
-
-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 libc.sa_family_t family
-
-    cdef void _init_family (self, libc.sa_family_t family = ?)
-
-    # get the sockaddr/socklen
-    # each of these can be NULL to ignore it
-    cdef int _get_sockaddr (self, libc.sockaddr **sa_ptr, libc.socklen_t *sa_len) except -1
-
-    cdef libc.sockaddr* _get_sockaddr_ptr (self) except NULL
-    cdef libc.socklen_t _get_sockaddr_len (self) except -1
-    
-    # set the sockaddr, socklen must match
-    cdef int _set_sockaddr (self, libc.sockaddr *sa, size_t sa_len) except -1
-
-# build a sockaddr from the given sockaddr struct, based on sa_family
-cdef sockaddr build_sockaddr (libc.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, libc.addrinfo *c_ai)
-
-# build and return a new addrinfo instance
-cdef addrinfo build_addrinfo (libc.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.
-
-        >>> import 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 = ?)
--- a/sock/addr.pyx	Sun Aug 16 16:38:44 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,353 +0,0 @@
-"""
-    Socket addresses
-"""
-
-cimport libc
-
-from addr cimport *
-
-cdef class sockaddr :
-    cdef void _init_family (self, libc.sa_family_t family=libc.AF_UNSPEC) :
-        self.family = family
-
-    # XXX:use size_t
-    cdef int _get_sockaddr (self, libc.sockaddr **sa_ptr, libc.socklen_t *sa_len) except -1 :
-        """
-            Get the sockaddr pointer and sockaddr length for this address
-        """ 
-
-        raise NotImplementedError()
-
-    cdef libc.sockaddr* _get_sockaddr_ptr (self) except NULL :
-        """
-            Get the sockaddr pointer
-        """
-
-        cdef libc.sockaddr *sa
-        cdef libc.socklen_t sa_len
-
-        self._get_sockaddr(&sa, &sa_len)
-
-        return sa
-    
-    cdef libc.socklen_t _get_sockaddr_len (self) except -1 :
-        """
-            Get the sockaddr len
-        """
-
-        cdef libc.sockaddr *sa
-        cdef libc.socklen_t sa_len
-
-        self._get_sockaddr(&sa, &sa_len)
-
-        return sa_len
-
-    cdef int _set_sockaddr (self, libc.sockaddr *sa, size_t sa_len) except -1 :
-        """
-            Set the sockaddr value for this address; sa_len must match!
-        """
-
-        raise NotImplementedError()
-
-    def getnameinfo (self) :
-        """
-            Returns a (host, serv) tuple for this address à la getnameinfo
-        """
-
-        cdef libc.sockaddr *sa
-        cdef libc.socklen_t sa_len
-
-        # XXX: take as args?
-        cdef int flags = libc.NI_NUMERICHOST | libc.NI_NUMERICSERV
-        
-        # get our abstract sockaddr
-        self._get_sockaddr(&sa, &sa_len)
-
-        # get nice text format
-        return libc.getnameinfo(sa, sa_len, flags)
-
-    property addr :
-        """
-            The ASCII literal network address
-        """
-
-        def __get__ (self) :
-            """
-                Default implmentation using getnameinfo()
-            """
-
-            addr, port = self.getnameinfo()
-
-            return addr
-
-    property port :
-        """
-            The integer port number
-        """
-
-        def __get__ (self) :
-            """
-                Default implementation using getnameinfo() and int()
-            """
-
-            addr, port = self.getnameinfo()
-
-            return int(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'
-        >>> str(sockaddr_in())
-        '0.0.0.0:0'
-    """
-
-    # the struct sockaddr_in
-    cdef libc.sockaddr_in sockaddr
-
-    def __init__ (self, object addr=None, libc.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)
-        """
-
-        # store our family
-        # XXX: this should be a class attribute...
-        self._init_family(libc.AF_INET)
-
-        # constant af
-        self.sockaddr.sin_family = self.family
-        
-        # set the sin_port
-        self.sockaddr.sin_port = libc.htons(port)
-        
-        if addr :
-            # set the sin_addr
-            # this automatically converts the addr from str -> char *
-            libc.inet_pton(self.family, addr, &self.sockaddr.sin_addr)
-
-        else :
-            # set as INADDR_ANY
-            self.sockaddr.sin_addr.s_addr = libc.INADDR_ANY
-    
-    cdef int _get_sockaddr (self, libc.sockaddr **sa_ptr, libc.socklen_t *sa_len) except -1 :
-        if sa_ptr :
-            sa_ptr[0] = <libc.sockaddr *> &self.sockaddr
-
-        if sa_len :
-            sa_len[0] = sizeof(self.sockaddr)
-
-        return 0
-
-    cdef int _set_sockaddr (self, libc.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
-        """
-
-        def __get__ (self) :
-            return libc.ntohs(self.sockaddr.sin_port)
-
-    def __str__ (self) :
-        """
-            Return the literal ASCII representation for this sockaddr as an '<addr>:<port> string
-        """
-        
-        # 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'
-        >>> str(sockaddr_in6())
-        '[::]:0'
-    """
-
-    cdef libc.sockaddr_in6 sockaddr
-
-    def __init__ (self, object addr=None, libc.in_port_t port=0) :
-        """
-            Construct using given literal IPv6 address and TCP/UDP port
-
-                addr        - IPv6 address, defaults to in6addr_any (::)
-                port        - TCP/UDP port, defaults to 0 (ephemeral)
-        """
-
-        # store our family
-        # XXX: this should be a class attribute...
-        self._init_family(libc.AF_INET6)
-
-        # constant af
-        self.sockaddr.sin6_family = self.family
-        
-        # set the sin_port
-        self.sockaddr.sin6_port = libc.htons(port)
-        
-        if addr :
-            # set the sin_addr
-            # this automatically converts the addr from str -> char *
-            libc.inet_pton(self.family, addr, &self.sockaddr.sin6_addr)
-
-        else :
-            # set as INADDR_ANY
-            self.sockaddr.sin6_addr = libc.in6addr_any
-
-    cdef int _get_sockaddr (self, libc.sockaddr **sa_ptr, libc.socklen_t *sa_len) except -1 :
-        if sa_ptr :
-            sa_ptr[0] = <libc.sockaddr *> &self.sockaddr
-
-        if sa_len :
-            sa_len[0] = sizeof(self.sockaddr)
-
-        return 0
-
-    cdef int _set_sockaddr (self, libc.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
-        """
-
-        def __get__ (self) :
-            return libc.ntohs(self.sockaddr.sin6_port)
-
-
-    def __str__ (self) :
-        """
-            Return the literal ASCII representation for this sockaddr as a '[<addr>]:<port> string
-        """
-        
-        # format
-        return "[%s]:%s" % self.getnameinfo()
-
-# mapping of AF -> sockaddr, user-modifyable
-SOCKADDR_BY_FAMILY = {
-    libc.AF_INET:   sockaddr_in,
-    libc.AF_INET6:  sockaddr_in6,
-}
-
-# build a sockaddr from the given sockaddr struct, based on sa_family
-cdef sockaddr build_sockaddr (libc.sockaddr *sa, size_t sa_len) :
-    # lookup correct class to use
-    addr_type = SOCKADDR_BY_FAMILY[sa.sa_family]
-    
-    # construct with defaults
-    cdef sockaddr addr = addr_type()
-
-    # store
-    addr._set_sockaddr(sa, sa_len)
-
-    return addr
-
-cdef class addrinfo :
-    
-    cdef _init_addrinfo (self, libc.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
-
-    def __str__ (self) :
-        return "family=%d, socktype=%d, protocol=%d, addr=%s, canonname=%s" % (self.family, self.socktype, self.protocol, self.addr, self.canonname)
-
-cdef addrinfo build_addrinfo (libc.addrinfo *c_ai) :
-    cdef addrinfo ai = addrinfo()
-    
-    ai._init_addrinfo(c_ai)
-
-    return ai
-
-cdef class endpoint :
-
-    def __init__ (self, hostname=None, service=None) :
-        """
-            Construct with the given hostname/service, either of which may be None.
-
-            A hostname of None implies all valid local addresses (with AI_PASSIVE), and a service of None implies an
-            ephemeral port.
-
-                hostname        - the literal address or DNS hostname or anything else that GAI supports
-                service         - the numeric port or service name
-        """
-
-        self.hostname = str(hostname)
-        self.service = str(service)
-
-    cpdef getaddrinfo (self, int family, int socktype, int protocol = 0, int flags = libc.AI_PASSIVE) :
-        """
-            Look up our hostname/service using the given socket parameters, and return a sequence of addrinfo objects.
-        """
-        
-        # XXX: Cython doesn't support proper compound value literals...
-        cdef libc.addrinfo hints
-        
-        libc.memset(&hints, 0, sizeof(hints))
-        hints.ai_flags          = flags
-        hints.ai_family         = family
-        hints.ai_socktype       = socktype
-        hints.ai_protocol       = protocol
-
-        cdef libc.addrinfo *res, *r
-        cdef int err
-        cdef object ret = []
-
-        cdef char *hostname = NULL
-        cdef char *service = NULL
-
-        if self.hostname is not None :
-            hostname = self.hostname
-        
-        if self.service is not None :
-            service = self.service
-
-        # operate!
-        err = libc.c_getaddrinfo(hostname, service, &hints, &res)
-
-        try :
-            if err :
-                # XXX: raise a GAIError
-                raise Exception(libc.gai_strerror(err))
-            
-            # gather results
-            r = res
-
-            while r :
-                ret.append(build_addrinfo(r))
-
-                r = r.ai_next
-            
-            # ok
-            return ret
-
-        finally :
-            libc.c_freeaddrinfo(res)
-
-    def __str__ (self) :
-        return "hostname=%s, service=%s" % (self.hostname, self.service)
-
--- a/test.py	Sun Aug 16 16:38:44 2009 +0300
+++ b/test.py	Sun Aug 16 18:29:55 2009 +0300
@@ -1,10 +1,12 @@
 import doctest
 
-import sock.addr
+import socket.addr
+import socket.sock
 import sctp.sock
 
 for mod in (
-    sock.addr,
+    socket.addr,
+    socket.sock,
     sctp.sock,
 ) :
     doctest.testmod(mod)