--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk/net/sctp/sock.pyx Sun Aug 16 19:01:21 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 socket.addr
+
+cdef size_t addrsoup_len (object addrs) except -1 :
+ """
+ Calculate the length of the addr_buf required to store the given addrsoup
+ """
+
+ cdef socket.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 socket.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')
+