author | Tero Marttila <terom@fixme.fi> |
Sun, 23 Aug 2009 22:59:40 +0300 | |
changeset 37 | 14db3fe42b6c |
parent 33 | c71de00715d6 |
child 45 | bb49bf8222ed |
permissions | -rw-r--r-- |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
1 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
2 |
Socket implementation helpers |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
3 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
4 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
5 |
from qmsk.net.socket import socket |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
6 |
from qmsk.net.socket.constants import * |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
7 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
8 |
class SocketError (Exception) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
9 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
10 |
Base class of errors raised by the Socket classes. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
11 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
12 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
13 |
class SocketBindAddrinfoError (SocketError) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
14 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
15 |
The socket was unable to socket()+bind() to the given addrinfo. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
16 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
17 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
18 |
def __init__ (self, addrinfo, error) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
19 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
20 |
addrinfo - the addrinfo we tried to use |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
21 |
error - the resulting error |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
22 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
23 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
24 |
self.addrinfo = addrinfo |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
25 |
self.error = error |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
26 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
27 |
def __str__ (self) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
28 |
return "Unable to bind() to %s: %s" % (self.addrinfo, self.error) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
29 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
30 |
class SocketBindEndpointError (SocketError) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
31 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
32 |
The socket was unable to bind() to the any of the given endpoint's addresses. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
33 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
34 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
35 |
def __init__ (self, endpoint, errors) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
36 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
37 |
endpoint - the endpoint we tried to bind to |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
38 |
errors - a sequence of ServiceBindAddrinfoErrors describing the failed bind attempts. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
39 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
40 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
41 |
self.endpoint = endpoint |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
42 |
self.errors = errors |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
43 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
44 |
def __str__ (self) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
45 |
# XXX: too verbose? |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
46 |
return "Unable to bind() to any addresses on endpoint %s:\n%s" % (self.endpoint, "\n".join( |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
47 |
"\t%s" % (error, ) for error in self.errors |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
48 |
)) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
49 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
50 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
51 |
class Base (object) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
52 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
53 |
Base class for all other socket-related classes, contains the underlying socket object. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
54 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
55 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
56 |
# the underlying socket object |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
57 |
sock = None |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
58 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
59 |
def _init_sock (self, sock) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
60 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
61 |
Initialize with the given pre-existing socket. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
62 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
63 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
64 |
self.sock = sock |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
65 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
66 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
67 |
class Common (Base) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
68 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
69 |
Common operations for Client/Service |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
70 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
71 |
|
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
72 |
# default socktype |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
73 |
_SOCKTYPE = 0 |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
74 |
|
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
75 |
@classmethod |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
76 |
def _socket (cls, family, socktype = None, protocol = 0) : |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
77 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
78 |
Construct and return a new socket object using the given parameters. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
79 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
80 |
|
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
81 |
if socktype is None : |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
82 |
socktype = cls._SOCKTYPE |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
83 |
|
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
84 |
return socket.socket(family, socktype, protocol) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
85 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
86 |
@classmethod |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
87 |
def _bind_addrinfo (cls, ai) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
88 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
89 |
This will attempt to create a new socket and bind it, based on the given addrinfo, returning the new socket. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
90 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
91 |
Raises a ServiceBindAddrinfoError if this fails |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
92 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
93 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
94 |
try : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
95 |
# socket() |
33 | 96 |
sock = cls._socket(ai.family, ai.socktype, ai.protocol) |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
97 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
98 |
# bind() |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
99 |
sock.bind(ai.addr) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
100 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
101 |
# XXX: except socket.error as e : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
102 |
except OSError, error : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
103 |
raise SocketBindAddrinfoError(ai, error) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
104 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
105 |
else : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
106 |
return sock |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
107 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
108 |
@classmethod |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
109 |
def _bind_endpoint (cls, endpoint, socktype = None, protocol=0) : |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
110 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
111 |
This will resolve the given endpoint, and attempt to create and bind a suitable socket and return it. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
112 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
113 |
endpoint - local Endpoint to bind() to. |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
114 |
socktype - (optiona) socket type to use, defaults to _SOCKTYPE |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
115 |
protocol - (optional) specific protocol |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
116 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
117 |
Raises a ServiceBindError if this is unable to create a bound socket. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
118 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
119 |
XXX: bind to all of the given endpoint's addresses instead of just one...? |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
120 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
121 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
122 |
errors = [] |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
123 |
|
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
124 |
if socktype is None : |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
125 |
socktype = cls._SOCKTYPE |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
126 |
|
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
127 |
# resolve the endpoint and try socket+bind |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
128 |
for ai in endpoint.resolve(socktype, protocol, AI_PASSIVE) : |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
129 |
try : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
130 |
# try to socket+bind this addrinfo |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
131 |
sock = cls._bind_addrinfo(ai) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
132 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
133 |
except SocketBindAddrinfoError, error : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
134 |
# collect |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
135 |
errors.append(error) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
136 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
137 |
# keep trying |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
138 |
continue |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
139 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
140 |
else : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
141 |
# got a working socket :) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
142 |
return sock |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
143 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
144 |
else : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
145 |
# no suitable address found :( |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
146 |
raise SocketBindEndpointError(endpoint, errors) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
147 |
|
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
148 |
def _init_endpoint (self, endpoint, socktype = None, protocol = 0, family = None) : |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
149 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
150 |
Initialize this socket by constructing a new socket with the given parameters, bound to the given endpoint, |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
151 |
if given. If no endpoint is given, this simply creates a socket with the given settings and does not bind |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
152 |
it anywhere. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
153 |
""" |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
154 |
|
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
155 |
if endpoint is not None : |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
156 |
# create a suitable socket bound to a the given endpoint |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
157 |
self.sock = self._bind_endpoint(endpoint, socktype, protocol) |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
158 |
|
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
159 |
else : |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
160 |
assert family |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
161 |
|
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
162 |
# simply create a socket |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
163 |
self.sock = self._socket(family, socktype, protocol) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
164 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
165 |
class Service (Common) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
166 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
167 |
Listener socket |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
168 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
169 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
170 |
def _listen (self, backlog) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
171 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
172 |
Puts this socket into listen() mode with the given backlog. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
173 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
174 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
175 |
self.sock.listen(backlog) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
176 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
177 |
class SocketConnectAddrinfoError (SocketError) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
178 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
179 |
The socket was unable to socket()+connect() to the given addrinfo. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
180 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
181 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
182 |
def __init__ (self, addrinfo, error) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
183 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
184 |
addrinfo - the addrinfo we tried to use |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
185 |
error - the resulting error |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
186 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
187 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
188 |
self.addrinfo = addrinfo |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
189 |
self.error = error |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
190 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
191 |
def __str__ (self) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
192 |
return "Unable to connect() to %s: %s" % (self.addrinfo, self.error) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
193 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
194 |
class SocketConnectEndpointError (SocketError) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
195 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
196 |
The socket was unable to connect() to the any of the given endpoint's addresses. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
197 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
198 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
199 |
def __init__ (self, endpoint, errors) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
200 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
201 |
endpoint - the endpoint we tried to connect to |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
202 |
errors - a sequence of ServiceBindAddrinfoErrors describing the failed connect attempts. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
203 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
204 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
205 |
self.endpoint = endpoint |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
206 |
self.errors = errors |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
207 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
208 |
def __str__ (self) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
209 |
# XXX: too verbose? |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
210 |
return "Unable to connect() to any addresses on endpoint %s:\n%s" % (self.endpoint, "\n".join( |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
211 |
"\t%s" % (error, ) for error in self.errors |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
212 |
)) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
213 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
214 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
215 |
class Client (Common) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
216 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
217 |
Connecting socket |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
218 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
219 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
220 |
@classmethod |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
221 |
def _connect_sock_addr (cls, sock, addr) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
222 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
223 |
Attempt to connect the given socket to the given address. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
224 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
225 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
226 |
sock.connect(addr) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
227 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
228 |
@classmethod |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
229 |
def _connect_sock_addrinfo (cls, sock, ai) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
230 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
231 |
Attempt to connect the given socket to the given addrinfo's address. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
232 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
233 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
234 |
try : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
235 |
cls._connect_sock_addr(sock, ai.addr) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
236 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
237 |
# XXX: except socket.error as e : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
238 |
except OSError, error : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
239 |
raise SocketConnectAddrinfoError(ai, error) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
240 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
241 |
@classmethod |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
242 |
def _connect_addrinfo (cls, ai) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
243 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
244 |
Attempt to create a socket and connect it based on the given addrinfo, returning the new socket is succesfull. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
245 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
246 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
247 |
try : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
248 |
# socket() |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
249 |
sock = cls._socket(ai.family, ai.socktype, ai.protocol) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
250 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
251 |
# XXX: except socket.error as e : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
252 |
except OSError, error : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
253 |
raise SocketConnectAddrinfoError(ai, error) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
254 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
255 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
256 |
# try and connect() it |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
257 |
cls._connect_sock_addrinfo(sock, ai) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
258 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
259 |
# return once succesfully |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
260 |
return sock |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
261 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
262 |
@classmethod |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
263 |
def _connect_sock_endpoint (cls, sock, endpoint, socktype = None, protocol = 0) : |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
264 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
265 |
Connect this socket to the given remote endpoint, using the given parameters to resolve the endpoint. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
266 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
267 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
268 |
errors = [] |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
269 |
|
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
270 |
if socktype is None : |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
271 |
socktype = cls._SOCKTYPE |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
272 |
|
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
273 |
# resolve the endpoint and try socket+bind |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
274 |
for ai in endpoint.resolve(socktype, protocol) : |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
275 |
try : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
276 |
# try to connect the socket to this addrinfo |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
277 |
cls._connect_sock_addrinfo(sock, ai) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
278 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
279 |
except SocketConnectAddrinfoError, error : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
280 |
# collect |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
281 |
errors.append(error) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
282 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
283 |
# keep trying |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
284 |
continue |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
285 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
286 |
else : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
287 |
# got a working socket :) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
288 |
return |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
289 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
290 |
else : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
291 |
# no suitable address found :( |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
292 |
raise SocketConnectEndpointError(endpoint, errors) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
293 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
294 |
@classmethod |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
295 |
def _connect_endpoint (cls, endpoint, socktype = None, protocol = 0) : |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
296 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
297 |
Create a new socket and connect it to the given remote endpoint, using the given parameters to resolve the |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
298 |
endpoint. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
299 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
300 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
301 |
errors = [] |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
302 |
|
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
303 |
if socktype is None : |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
304 |
socktype = cls._SOCKTYPE |
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
305 |
|
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
306 |
# resolve the endpoint and try socket+bind |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
307 |
for ai in endpoint.resolve(socktype, protocol) : |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
308 |
try : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
309 |
# try to socket+connect this addrinfo |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
310 |
sock = cls._connect_addrinfo(ai) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
311 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
312 |
except SocketConnectAddrinfoError, error : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
313 |
# collect |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
314 |
errors.append(error) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
315 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
316 |
# keep trying |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
317 |
continue |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
318 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
319 |
else : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
320 |
# got a working socket :) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
321 |
return sock |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
322 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
323 |
else : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
324 |
# no suitable address found :( |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
325 |
raise SocketConnectEndpointError(endpoint, errors) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
326 |
|
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
327 |
def _init_connect_endpoint (self, endpoint, socktype = None, protocol = 0): |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
328 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
329 |
If we already have an existing socket, connect it to the given endpoint, otherwise try and connect to the |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
330 |
given endpoint with a new socket. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
331 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
332 |
There is a subtle difference here, because if we have e.g. an IPv4 socket and try and connect it to an |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
333 |
endpoint with both IPv6 and IPv4 addresses, we will try to connect to an IPv6 address using the IPv4 socket, |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
334 |
and then to the IPv4 address using the IPv6 socket. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
335 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
336 |
If we do not yet have a socket, then we will attempt to connect to the IPv6 address using an IPv6 socket, |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
337 |
and to the IPv4 address using an IPv4 socket. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
338 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
339 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
340 |
if self.socket : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
341 |
# connect with existing socket |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
342 |
self._connect_sock_endpoint(self.socket, endpoint, socktype, protocol) |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
343 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
344 |
else : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
345 |
# connect with new socket |
37
14db3fe42b6c
move address-family from tcp/socket interface to endpoint interface. The address family of a socket is strictly a property of the address passed to it
Tero Marttila <terom@fixme.fi>
parents:
33
diff
changeset
|
346 |
self._connect_endpoint(endpoint, socktype, protocol) |
28
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
347 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
348 |
class Stream (Base) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
349 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
350 |
Unbuffered byte-stream interface. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
351 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
352 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
353 |
def read (self, iov) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
354 |
return self.sock.read(iov) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
355 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
356 |
def readv (self, iovecs) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
357 |
return self.sock.readv(iovecs) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
358 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
359 |
def write (self, buf) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
360 |
return self.sock.write(buf) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
361 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
362 |
def writev (self, iovecs) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
363 |
return self.sock.writev(iovecs) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
364 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
365 |
def close (self) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
366 |
self.sock.close() |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
367 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
368 |
def abort (self) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
369 |
# XXX: SO_LINGER magic |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
370 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
371 |
raise NotImplementedError() |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
372 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
373 |