--- a/inc/addr.pxd Sun Aug 16 03:12:46 2009 +0300
+++ b/inc/addr.pxd Sun Aug 16 03:38:01 2009 +0300
@@ -26,3 +26,6 @@
# 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
+
--- a/inc/libc.pxd Sun Aug 16 03:12:46 2009 +0300
+++ b/inc/libc.pxd Sun Aug 16 03:38:01 2009 +0300
@@ -22,6 +22,9 @@
ctypedef int16_t __s16
ctypedef int32_t __s32
+cdef extern from "string.h" :
+ void* memcpy (void *dest, void *src, size_t n)
+
cdef extern from "alloca.h" :
void* alloca (size_t size)
--- a/inc/sctp.pxd Sun Aug 16 03:12:46 2009 +0300
+++ b/inc/sctp.pxd Sun Aug 16 03:38:01 2009 +0300
@@ -195,7 +195,7 @@
int SCTP_BINDX_ADD_ADDR
int SCTP_BINDX_REM_ADDR
- int sctp_bindx (int sd, libc.sockaddr *addrs, int addrcnt, int flags)
+ int c_sctp_bindx "sctp_bindx" (int sd, libc.sockaddr *addrs, int addrcnt, int flags)
int sctp_connectx (int sd, libc.sockaddr *addrs, int addrcnt)
--- a/sctp/sock.pyx Sun Aug 16 03:12:46 2009 +0300
+++ b/sctp/sock.pyx Sun Aug 16 03:38:01 2009 +0300
@@ -5,39 +5,47 @@
from sctp cimport *
cimport libc
+cimport sock.addr
-def bindx (int sd, object addrs, int flags) :
+def sctp_bindx (int sd, object addrs, int flags) :
"""
- Bind the given SOCK_SEQPACKET to the given set of local addresses.
+ Bind the given SOCK_SEQPACKET to the given set of sock.addr.sockaddr's.
sd the system socket FD
- addresses the list of address tuples
+ addresses the list of qmsk.net.sock.addr.sockaddr's
flags one of SCTP_BINDX_ADD/REM_ADDR
"""
-
- # automatically allocated array of sockaddr_storage's for passing given addresses to sctp_bindx
- cdef libc.sockaddr_storage *addrs_out
-
- # used to iterate through addrs_out
- cdef libc.sockaddr_in *addr_in
-
- # number of addresses given
- cdef size_t addr_count = len(addrs)
-
- # alloc stack storage for converting addresses
- addrs_out = <libc.sockaddr_storage *> libc.alloca(addr_count * sizeof(libc.sockaddr_storage))
- for i, address in enumerate(addrs) :
- # XXX: assume socket-style IPv4 for now...
- addr, port = address
+ # ensure that addrs stays the same... ?
+ addrs = tuple(addrs)
- addr_in = <libc.sockaddr_in *>(&addrs_out[i])
+ cdef size_t addr_count = len(addrs)
+ cdef size_t addr_size = 0
+ cdef addr.sockaddr addr
+
+ # 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()
+
+ # alloc buffer to hold all the sockaddr_*'s
+ cdef char *addr_buf = <char *> libc.alloca(addr_size)
+ 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)
- addr_in.sin_family = libc.AF_INET
- addr_in.sin_port = libc.htons(port)
+ # copy to buffer
+ libc.memcpy(addr_ptr, sa, sa_len)
+
+ # move to next
+ addr_ptr += sa_len
- # XXX: known broken
- libc.inet_aton(addr, &addr_in.sin_addr)
-
- return sctp_bindx(sd, <libc.sockaddr *>addrs_out, addr_count, flags)
+ # then call
+ if c_sctp_bindx(sd, <libc.sockaddr *> addr_buf, addr_count, flags) < 0 :
+ raise OSError
--- a/sock/addr.pyx Sun Aug 16 03:12:46 2009 +0300
+++ b/sock/addr.pyx Sun Aug 16 03:38:01 2009 +0300
@@ -17,6 +17,30 @@
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
+
def getnameinfo (self) :
"""
Returns a (host, serv) tuple for this address à la getnameinfo