4 sockaddr - specific network-level address for socket operations |
4 sockaddr - specific network-level address for socket operations |
5 addrinfo - information on a specific sockaddr including its socket parameters |
5 addrinfo - information on a specific sockaddr including its socket parameters |
6 endpoint - human-readable network address, corresponding to multiple sockaddr's |
6 endpoint - human-readable network address, corresponding to multiple sockaddr's |
7 """ |
7 """ |
8 |
8 |
9 cimport qmsk.net.libc as libc |
|
10 |
|
11 cimport qmsk.net.socket.platform as platform |
9 cimport qmsk.net.socket.platform as platform |
12 |
10 |
13 cdef class sockaddr : |
11 from qmsk.net.socket._address cimport sockaddr |
14 """ |
|
15 A network-level socket address |
|
16 |
|
17 XXX: not abstract enough. Functions/properties like getnameinfo/addr/port do not work for e.g. sockaddr_un |
|
18 |
|
19 >>> sockaddr().family |
|
20 0 |
|
21 >>> sockaddr().port |
|
22 Traceback (most recent call last): |
|
23 ... |
|
24 NotImplementedError |
|
25 >>> sockaddr().getnameinfo() |
|
26 Traceback (most recent call last): |
|
27 ... |
|
28 NotImplementedError |
|
29 """ |
|
30 |
|
31 # address family |
|
32 # XXX: this should be a class constant! It's part of our type safety! |
|
33 cdef readonly platform.sa_family_t family |
|
34 |
|
35 cdef void _init_family (self, platform.sa_family_t family = ?) |
|
36 |
|
37 # get the sockaddr/socklen |
|
38 # each of these can be NULL to ignore it |
|
39 cdef int _get_sockaddr (self, platform.sockaddr **sa_ptr, platform.socklen_t *sa_len) except -1 |
|
40 |
|
41 cdef platform.sockaddr* _get_sockaddr_ptr (self) except NULL |
|
42 cdef platform.socklen_t _get_sockaddr_len (self) except -1 |
|
43 |
|
44 # set the sockaddr, socklen must match |
|
45 cdef int _set_sockaddr (self, platform.sockaddr *sa, size_t sa_len) except -1 |
|
46 |
12 |
47 # build a sockaddr from the given sockaddr struct, based on sa_family |
13 # build a sockaddr from the given sockaddr struct, based on sa_family |
48 cdef sockaddr build_sockaddr (platform.sockaddr *sa, size_t sa_len) |
14 cdef sockaddr build_sockaddr (platform.sockaddr *sa, size_t sa_len) |
49 |
15 |
50 cdef class addrinfo : |
16 cdef class addrinfo : |
80 # build and return a new addrinfo instance |
46 # build and return a new addrinfo instance |
81 cdef addrinfo build_addrinfo (platform.addrinfo *c_ai) |
47 cdef addrinfo build_addrinfo (platform.addrinfo *c_ai) |
82 |
48 |
83 cdef class endpoint : |
49 cdef class endpoint : |
84 """ |
50 """ |
85 A network-level socket endpoint. This is the level that humans mostly work with, but the tricky bit is that |
51 XXX: silly abstraction, just use the getaddrinfo function |
86 an endpoint can map to more than one sockaddr... |
|
87 |
52 |
88 Hence, endpoints are stored as human-readable hostname/service strings, which are then translated to sockaddrs |
53 >>> from qmsk.net.socket.constants import * |
89 using getaddrinfo. |
|
90 |
|
91 >>> from __future__ import absolute_import; import socket as _socket |
|
92 >>> e = endpoint('127.0.0.1', 80) |
54 >>> e = endpoint('127.0.0.1', 80) |
93 >>> str(e) |
55 >>> str(e) |
94 'hostname=127.0.0.1, service=80' |
56 'hostname=127.0.0.1, service=80' |
95 >>> res = e.getaddrinfo(_socket.AF_UNSPEC, _socket.SOCK_STREAM) |
57 >>> res = e.getaddrinfo(AF_UNSPEC, SOCK_STREAM) |
96 >>> len(res) |
58 >>> len(res) |
97 1 |
59 1 |
98 >>> str(res[0]) |
60 >>> str(res[0]) |
99 'family=2, socktype=1, protocol=6, addr=127.0.0.1:80, canonname=None' |
61 'family=2, socktype=1, protocol=6, addr=127.0.0.1:80, canonname=None' |
100 >>> e = endpoint('2001::5', 80) |
62 >>> e = endpoint('2001::5', 80) |
101 >>> str(e) |
63 >>> str(e) |
102 'hostname=2001::5, service=80' |
64 'hostname=2001::5, service=80' |
103 >>> res = e.getaddrinfo(_socket.AF_UNSPEC, _socket.SOCK_STREAM) |
65 >>> res = e.getaddrinfo(AF_UNSPEC, SOCK_STREAM) |
104 >>> len(res) |
66 >>> len(res) |
105 1 |
67 1 |
106 >>> str(res[0]) |
68 >>> str(res[0]) |
107 'family=10, socktype=1, protocol=6, addr=[2001::5]:80, canonname=None' |
69 'family=10, socktype=1, protocol=6, addr=[2001::5]:80, canonname=None' |
108 |
70 |