# HG changeset patch # User Tero Marttila # Date 1250527223 -10800 # Node ID 19d212c948e0e12b737710b5c539d3d221c7b77a # Parent 0e4933d5862e86159e0605119201d561d01fa208 fix up doctests diff -r 0e4933d5862e -r 19d212c948e0 qmsk/net/sctp/sock.pxd --- a/qmsk/net/sctp/sock.pxd Mon Aug 17 01:29:31 2009 +0300 +++ b/qmsk/net/sctp/sock.pxd Mon Aug 17 19:40:23 2009 +0300 @@ -1,6 +1,14 @@ -from qmsk.net.libc cimport __u8, __u16, __u32, __s8, __s16, __s32 +""" + The socket-based interface for SCTP. + + http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-15 +""" + +#from qmsk.net.libc cimport __u8, __u16, __u32, __s8, __s16, __s32, ssize_t +from qmsk.net.libc cimport * cimport qmsk.net.socket.platform as platform +cimport qmsk.net.socket.socket # # this defines the kernel SCTP -> userspace API extensions, such as structure types etc. @@ -56,6 +64,8 @@ __u32 sinfo_cumtsn sctp_assoc_t sinfo_assoc_id + # XXX: missing sctp_extrcvinfo + # sctp_sndrcvinfo.sinfo_flags values enum sctp_sinfo_flags : SCTP_UNORDERED # Send/receive message unordered @@ -192,15 +202,76 @@ ctypedef sctp_sn_error sctp_sn_error_t + + ### + ### 8 New Interfaces + ### - ## sctp_bindx + ## 8.1 sctp_bindx enum : SCTP_BINDX_ADD_ADDR SCTP_BINDX_REM_ADDR - int c_sctp_bindx "sctp_bindx" (int sd, platform.sockaddr *addrs, int addrcnt, int flags) + int sctp_bindx (int sd, platform.sockaddr *addrs, int addrcnt, int flags) - # XXX: missing return-sctp_assoc_t-id argument! - int c_sctp_connectx "sctp_connectx" (int sd, platform.sockaddr *addrs, int addrcnt) + ## 8.2 sctp_peeloff + int sctp_peeloff (int sd, sctp_assoc_t assoc_id) + + ## 8.3 sctp_getpaddrs + int sctp_getpaddrs (int sd, sctp_assoc_t assoc_id, platform.sockaddr **addrs) + ## 8.4 sctp_freepaddrs + void sctp_freepaddrs (platform.sockaddr *addrs) + + ## 8.5 sctp_getladdrs + int sctp_getladdrs (int sd, sctp_assoc_t id, platform.sockaddr **ss) + ## 8.6 sctp_freeladdrs + void sctp_freeladdrs (platform.sockaddr **ss) + + ## 8.7 sctp_sendmsg + ssize_t sctp_sendmsg ( + int sd, + void *msg, size_t len, + platform.sockaddr *dst, platform.socklen_t dstlen, + uint32_t ppid, uint32_t flags, uint16_t stream_no, uint32_t timetolive, uint32_t context + ) + + ## 8.8 sctp_Recvmsg + ssize_t sctp_recvmsg ( + int sd, + void *msg, size_t len, + platform.sockaddr *src, platform.socklen_t *srclen, + sctp_sndrcvinfo *sinfo, + int *msg_flags + ) + ## 8.9 sctp_connectx + # XXX: missing return-sctp_assoc_t-id argument from RFC! + int sctp_connectx (int sd, platform.sockaddr *addrs, int addrcnt) + + ## 8.10 sctp_send + int sctp_send ( + int sd, + void *msg, size_t len, + sctp_sndrcvinfo *sinfo, + int flags + ) + + ## 8.11 sctp_sendx + int sctp_sendx ( + int sd, + void *msg, size_t len, + platform.sockaddr *addrs, int addrcnt, + sctp_sndrcvinfo *sinfo, + int flags + ) + + ## 8.12 sctp_getaddrlen + int sctp_getaddrlen (platform.sa_family_t family) + +cdef class sctp_socket (qmsk.net.socket.socket.socket) : + """ + SCTP-specific methods and functionality, built on top of the generic socket interface. + """ + + diff -r 0e4933d5862e -r 19d212c948e0 qmsk/net/sctp/sock.pyx --- a/qmsk/net/sctp/sock.pyx Mon Aug 17 01:29:31 2009 +0300 +++ b/qmsk/net/sctp/sock.pyx Mon Aug 17 19:40:23 2009 +0300 @@ -1,10 +1,11 @@ """ This C(ython) extension module provides an interface to the libsctp library and associated socket API. - >>> from __future__ import absolute_import; import socket as _socket - >>> from qmsk.net.socket.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 __future__ import absolute_import; + >>> from qmsk.net.socket.address import sockaddr_in + >>> from qmsk.net.socket.constants import * + >>> s = sctp_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP) + >>> s.sctp_bindx([sockaddr_in('127.0.0.1', 1337), sockaddr_in('127.0.0.2')], 0x01) >>> """ @@ -53,48 +54,59 @@ # 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 = libc.alloca(addrsoup_len(addrs)) - - # store - addrsoup_store(addrs, addr_buf) +cdef class sctp_socket (qmsk.net.socket.socket.socket) : - # then call - if c_sctp_bindx(sd, 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 - - """ + def __init__ (self, int family = platform.AF_INET, int socktype = platform.SOCK_SEQPACKET, int protocol = IPPROTO_SCTP, int fd = -1) : + """ + Same behaviour as socket.__init__, but different defaults. + """ - # ensure that addrs stays the same... ? - addrs = tuple(addrs) - - # alloc buffer to hold all the sockaddr_*'s - cdef char *addr_buf = libc.alloca(addrsoup_len(addrs)) + qmsk.net.socket.socket.socket.__init__(self, family, socktype, protocol, fd) - # store - addrsoup_store(addrs, addr_buf) + def sctp_bindx (self, object addrs, int flags) : + """ + Bind this IPPROTO_SCTP socket to the given set of local addresses. - # then call - if c_sctp_connectx(sd, addr_buf, len(addrs)) < 0 : - raise_errno('sctp_connectx') + This may be called multiple times on a socket, even after bind(), to change the set of local addresses. + This may affect ongoing associations, or only new associations. + addresses the list of 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 = libc.alloca(addrsoup_len(addrs)) + + # store + addrsoup_store(addrs, addr_buf) + + # then call + if sctp_bindx(self.fd, addr_buf, len(addrs), flags) : + raise_errno('sctp_bindx') + + def sctp_connectx (self, int sd, object addrs) : + """ + Establish an association with the given set of remote sockaddr's. + + addresses the list of sockaddr's + + """ + + # ensure that addrs stays the same... ? + addrs = tuple(addrs) + + # alloc buffer to hold all the sockaddr_*'s + cdef char *addr_buf = libc.alloca(addrsoup_len(addrs)) + + # store + addrsoup_store(addrs, addr_buf) + + # then call + if sctp_connectx(self.fd, addr_buf, len(addrs)) : + raise_errno('sctp_connectx') + + diff -r 0e4933d5862e -r 19d212c948e0 qmsk/net/socket/socket.pxd --- a/qmsk/net/socket/socket.pxd Mon Aug 17 01:29:31 2009 +0300 +++ b/qmsk/net/socket/socket.pxd Mon Aug 17 19:40:23 2009 +0300 @@ -8,7 +8,7 @@ """ Represents a single OS-level socket - >>> from qmsk.net.socket import addr + >>> from qmsk.net.socket import address as addr >>> from qmsk.net.socket.constants import * >>> s = socket(1337) @@ -33,6 +33,15 @@ ... OSError: [Errno 111] Connection refused + + >>> s1 = socket(AF_INET, SOCK_STREAM); s2 = socket(AF_INET, SOCK_STREAM) + >>> s1.listen(1); + >>> s2.connect(s1.getsockname()) + >>> s12, s12_addr = s1.accept() + >>> s12_addr == s12.getpeername() == s2.getsockname() + True + >>> s1.close(); s2.close() + """ cdef readonly socket_t fd