111 |
113 |
112 else : |
114 else : |
113 # yay |
115 # yay |
114 yield sock |
116 yield sock |
115 |
117 |
|
118 |
|
119 def client_connect_next (sock_iter) : |
|
120 """ |
|
121 Attempt to run the given connect operation, on the given iterable of sockets. |
|
122 """ |
|
123 |
|
124 for sock in sock_iter : |
|
125 # pend for writing |
|
126 log_debug("client_connect_next: cb_event(%d, EV_WRITE, on_connect, %r)", sock.fd, sock) |
|
127 ev = cb_event(ev_base, sock.fd, EV_WRITE, on_connect, sock, sock_iter) |
|
128 |
|
129 # wait specified timeout |
|
130 log_debug("client_connect_next: %r: add(%s)", ev, options.timeout) |
|
131 ev.add(options.timeout) |
|
132 |
|
133 # ok |
|
134 break |
|
135 |
|
136 else : |
|
137 # fail, ran out of addresses to try |
|
138 log_err("client_connect_next: ran out of addresses to try") |
|
139 |
|
140 |
116 def on_connect (ev, events, sock, sock_iter) : |
141 def on_connect (ev, events, sock, sock_iter) : |
117 """ |
142 """ |
118 Outbound connect EV_WRITE callback, i.e. connection failed or was established |
143 Outbound connect EV_WRITE callback, i.e. connection failed or was established |
119 """ |
144 """ |
120 |
145 |
138 # keep trying |
163 # keep trying |
139 return client_connect_next(sock_iter) |
164 return client_connect_next(sock_iter) |
140 |
165 |
141 |
166 |
142 # ok, connected |
167 # ok, connected |
143 log_info("on_connect: connected") |
168 client_connected(sock) |
144 |
169 |
145 |
170 |
146 def client_connect_next (sock_iter) : |
171 def client_connected (sock) : |
147 """ |
172 """ |
148 Attempt to run the given connect operation, on the given iterable of sockets. |
173 Connection established, start shovelling data |
149 """ |
174 """ |
150 |
175 |
151 for sock in sock_iter : |
176 log_info("Client connected to %s (from %s)", sock.getpeername(), sock.getsockname()) |
152 # pend for writing |
177 |
153 log_debug("client_connect_next: cb_event(%d, EV_WRITE, on_connect, %r)", sock.fd, sock) |
178 # go! |
154 ev = cb_event(ev_base, sock.fd, EV_WRITE, on_connect, sock, sock_iter) |
179 start_sock(sock, sys.stdin.fileno(), sys.stdout.fileno()) |
155 |
180 |
156 # wait specified timeout |
181 |
157 log_debug("client_connect_next: %r: add(%s)", ev, options.timeout) |
182 def start_sock (sock, fd_in, fd_out) : |
158 ev.add(options.timeout) |
183 """ |
159 |
184 Start shipping data between sock and fin/fout. |
160 # ok |
185 """ |
161 break |
186 |
162 |
187 # event for each |
163 else : |
188 ev_in = cb_event(ev_base, fd_in, EV_READ, on_read_in, sock, fd_in) |
164 # fail, ran out of addresses to try |
189 ev_out = cb_event(ev_base, sock.fd, EV_READ, on_read_sock, sock, fd_out) |
165 log_err("client_connect_next: ran out of addresses to try") |
190 |
|
191 ev_in.add() |
|
192 ev_out.add() |
|
193 |
|
194 |
|
195 def on_read_in (ev, events, sock, fd_in) : |
|
196 """ |
|
197 Data readable on ev.fd, ship to sock |
|
198 """ |
|
199 |
|
200 # no timeouts yet |
|
201 assert events & EV_READ |
|
202 |
|
203 # try and read |
|
204 buf = os.read(fd_in, BUFSIZE) |
|
205 |
|
206 if buf : |
|
207 # pass on |
|
208 assert sock.write(buf) == len(buf) |
|
209 |
|
210 # keep going |
|
211 ev.add() |
|
212 |
|
213 else : |
|
214 # EOF |
|
215 sock.shutdown(SHUT_WR) |
|
216 |
|
217 |
|
218 def on_read_sock (ev, events, sock, fd_out) : |
|
219 """ |
|
220 Data readable on sock, ship to fd_out |
|
221 """ |
|
222 |
|
223 # no timeouts yet |
|
224 assert events & EV_READ |
|
225 |
|
226 # try and read |
|
227 buf = sock.read(BUFSIZE) |
|
228 |
|
229 if buf : |
|
230 # pass on |
|
231 assert os.write(fd_out, buf) == len(buf) |
|
232 |
|
233 # keep going |
|
234 ev.add() |
|
235 |
|
236 else : |
|
237 # EOF |
|
238 os.close(fd_out) |
|
239 |
|
240 log_info("EOF from %s", sock.getpeername()) |
166 |
241 |
167 def run_client (host, port) : |
242 def run_client (host, port) : |
168 """ |
243 """ |
169 Execute in client-mode |
244 Execute in client-mode |
170 """ |
245 """ |