author | Tero Marttila <terom@fixme.fi> |
Mon, 17 Aug 2009 01:29:31 +0300 | |
changeset 20 | 0e4933d5862e |
parent 11 | 7ae92c2b433f |
child 21 | 19d212c948e0 |
permissions | -rw-r--r-- |
0 | 1 |
""" |
2 |
This C(ython) extension module provides an interface to the libsctp library and associated socket API. |
|
4 | 3 |
|
8 | 4 |
>>> from __future__ import absolute_import; import socket as _socket |
5 |
>>> from qmsk.net.socket.addr import sockaddr_in |
|
6 |
>>> s = _socket.socket(_socket.AF_INET, _socket.SOCK_SEQPACKET, 132) |
|
4 | 7 |
>>> sctp_bindx(s.fileno(), [sockaddr_in('127.0.0.1', 1337), sockaddr_in('127.0.0.2')], 0x01) |
8 |
>>> |
|
9 |
||
0 | 10 |
""" |
11 |
||
8 | 12 |
from qmsk.net.sctp.sock cimport * |
20
0e4933d5862e
rename qmsk.net.socket.addr -> qmsk.net.socket.address
Tero Marttila <terom@fixme.fi>
parents:
11
diff
changeset
|
13 |
from qmsk.net.socket.address cimport sockaddr |
0 | 14 |
|
20
0e4933d5862e
rename qmsk.net.socket.addr -> qmsk.net.socket.address
Tero Marttila <terom@fixme.fi>
parents:
11
diff
changeset
|
15 |
cimport qmsk.net.socket.platform as platform |
11
7ae92c2b433f
move libc+py back to qmsk.net.x
Tero Marttila <terom@fixme.fi>
parents:
10
diff
changeset
|
16 |
cimport qmsk.net.libc as libc |
20
0e4933d5862e
rename qmsk.net.socket.addr -> qmsk.net.socket.address
Tero Marttila <terom@fixme.fi>
parents:
11
diff
changeset
|
17 |
|
11
7ae92c2b433f
move libc+py back to qmsk.net.x
Tero Marttila <terom@fixme.fi>
parents:
10
diff
changeset
|
18 |
from qmsk.net.py cimport raise_errno |
0 | 19 |
|
5 | 20 |
cdef size_t addrsoup_len (object addrs) except -1 : |
0 | 21 |
""" |
5 | 22 |
Calculate the length of the addr_buf required to store the given addrsoup |
0 | 23 |
""" |
24 |
||
8 | 25 |
cdef sockaddr addr |
2
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
26 |
cdef size_t addr_size = 0 |
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
27 |
|
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
28 |
# whoever decided that sctp_bindx takes an array of mixed sockaddr_in/sockaddr_in6's should be shot |
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
29 |
for addr in addrs : |
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
30 |
addr_size += addr._get_sockaddr_len() |
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
31 |
|
5 | 32 |
return addr_size |
33 |
||
34 |
cdef addrsoup_store (object addrs, char *addr_buf) : |
|
35 |
""" |
|
36 |
Store the sockaddr_*'s for the given addresses into the given buffer, which should be addrsoup_len() bytes long |
|
37 |
""" |
|
38 |
||
8 | 39 |
cdef sockaddr addr |
2
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
40 |
cdef char *addr_ptr = addr_buf |
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
41 |
|
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
42 |
# fill it |
10 | 43 |
cdef platform.sockaddr *sa |
44 |
cdef platform.socklen_t sa_len |
|
2
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
45 |
|
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
46 |
for addr in addrs : |
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
47 |
# get address's sockaddr info |
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
48 |
addr._get_sockaddr(&sa, &sa_len) |
0 | 49 |
|
2
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
50 |
# copy to buffer |
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
51 |
libc.memcpy(addr_ptr, sa, sa_len) |
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
52 |
|
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
53 |
# move to next |
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
54 |
addr_ptr += sa_len |
1
0ca9278146d7
move pxd's to inc dir, split off sctp.pxd
Tero Marttila <terom@fixme.fi>
parents:
0
diff
changeset
|
55 |
|
5 | 56 |
def sctp_bindx (int sd, object addrs, int flags) : |
57 |
""" |
|
58 |
Bind the given SOCK_SEQPACKET to the given set of sock.addr.sockaddr's. |
|
59 |
||
60 |
sd the system socket FD |
|
61 |
addresses the list of qmsk.net.sock.addr.sockaddr's |
|
62 |
flags one of SCTP_BINDX_ADD/REM_ADDR |
|
63 |
||
64 |
""" |
|
65 |
||
66 |
# ensure that addrs stays the same... ? |
|
67 |
addrs = tuple(addrs) |
|
68 |
||
69 |
# alloc buffer to hold all the sockaddr_*'s |
|
70 |
cdef char *addr_buf = <char *> libc.alloca(addrsoup_len(addrs)) |
|
71 |
||
72 |
# store |
|
73 |
addrsoup_store(addrs, addr_buf) |
|
74 |
||
2
171e77f8d675
re-implement sctp_bindx using new sock_addr
Tero Marttila <terom@fixme.fi>
parents:
1
diff
changeset
|
75 |
# then call |
10 | 76 |
if c_sctp_bindx(sd, <platform.sockaddr *> addr_buf, len(addrs), flags) < 0 : |
6 | 77 |
raise_errno('sctp_bindx') |
0 | 78 |
|
5 | 79 |
def sctp_connectx (int sd, object addrs) : |
80 |
""" |
|
81 |
Connect the given SOCK_SEQPACKET to the given set of remote sock.addr.sockaddr's. |
|
82 |
||
83 |
sd the system socket FD |
|
84 |
addresses the list of qmsk.net.sock.addr.sockaddr's |
|
85 |
||
86 |
""" |
|
87 |
||
88 |
# ensure that addrs stays the same... ? |
|
89 |
addrs = tuple(addrs) |
|
90 |
||
91 |
# alloc buffer to hold all the sockaddr_*'s |
|
92 |
cdef char *addr_buf = <char *> libc.alloca(addrsoup_len(addrs)) |
|
93 |
||
94 |
# store |
|
95 |
addrsoup_store(addrs, addr_buf) |
|
96 |
||
97 |
# then call |
|
10 | 98 |
if c_sctp_connectx(sd, <platform.sockaddr *> addr_buf, len(addrs)) < 0 : |
6 | 99 |
raise_errno('sctp_connectx') |
5 | 100 |