ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn_tcp.C
(Generate patch)

Comparing gvpe/src/vpn_tcp.C (file contents):
Revision 1.4 by pcg, Mon Apr 7 01:12:56 2003 UTC vs.
Revision 1.11 by pcg, Sat Jan 17 01:18:36 2004 UTC

1/* 1/*
2 vpn_tcp.C -- handle the tcp part of the protocol. 2 vpn_tcp.C -- handle the tcp part of the protocol.
3 Copyright (C) 2003-2004 Marc Lehmann <pcg@goof.com>
3 4
4 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version. 8 (at your option) any later version.
27 28
28#include <cstring> 29#include <cstring>
29 30
30#include <sys/types.h> 31#include <sys/types.h>
31#include <sys/socket.h> 32#include <sys/socket.h>
32#include <sys/poll.h>
33#include <sys/wait.h> 33#include <sys/wait.h>
34#include <netinet/in.h>
35#include <sys/uio.h> 34#include <sys/uio.h>
36#include <arpa/inet.h>
37#include <errno.h> 35#include <errno.h>
38#include <time.h> 36#include <time.h>
39#include <unistd.h> 37#include <unistd.h>
38#include <fcntl.h>
40 39
41#include <map> 40#include <map>
42#include <unistd.h> 41
43#include <fcntl.h> 42#include "netcompat.h"
44#include <sys/poll.h>
45 43
46#include "vpn.h" 44#include "vpn.h"
47 45
48#if ENABLE_HTTP_PROXY 46#if ENABLE_HTTP_PROXY
49# include "conf.h" 47# include "conf.h"
103 ~tcp_connection (); 101 ~tcp_connection ();
104}; 102};
105 103
106void tcp_si_map::cleaner_cb (time_watcher &w) 104void tcp_si_map::cleaner_cb (time_watcher &w)
107{ 105{
108 w.at = NOW + 600; 106 w.start (NOW + 600);
107
109 tstamp to = NOW - ::conf.keepalive - 30 - 60; 108 tstamp to = NOW - ::conf.keepalive - 30 - 60;
110 109
111 for (iterator i = begin (); i != end(); ) 110 for (iterator i = begin (); i != end(); )
112 if (i->second->last_activity >= to) 111 if (i->second->last_activity >= to)
113 ++i; 112 ++i;
119} 118}
120 119
121void 120void
122vpn::tcpv4_ev (io_watcher &w, short revents) 121vpn::tcpv4_ev (io_watcher &w, short revents)
123{ 122{
124 if (revents & (POLLIN | POLLERR)) 123 if (revents & EVENT_READ)
125 { 124 {
126 struct sockaddr_in sa; 125 struct sockaddr_in sa;
127 socklen_t sa_len = sizeof (sa); 126 socklen_t sa_len = sizeof (sa);
128 int len; 127 int len;
129 128
169 if (w_ofs < 2) 168 if (w_ofs < 2)
170 { 169 {
171 u16 plen = htons (w_pkt->len); 170 u16 plen = htons (w_pkt->len);
172 171
173 iovec vec[2]; 172 iovec vec[2];
173 //TODO: char* is the right type? hardly...
174 vec[0].iov_base = ((u8 *)&plen) + w_ofs; 174 vec[0].iov_base = (char *)((u8 *)&plen) + w_ofs;
175 vec[0].iov_len = 2 - w_ofs; 175 vec[0].iov_len = 2 - w_ofs;
176 vec[1].iov_base = &((*w_pkt)[0]); 176 vec[1].iov_base = (char *)&((*w_pkt)[0]);
177 vec[1].iov_len = w_len - 2; 177 vec[1].iov_len = w_len - 2;
178 178
179 len = writev (fd, vec, 2); 179 len = writev (fd, vec, 2);
180 } 180 }
181 else 181 else
200void 200void
201tcp_connection::tcpv4_ev (io_watcher &w, short revents) 201tcp_connection::tcpv4_ev (io_watcher &w, short revents)
202{ 202{
203 last_activity = NOW; 203 last_activity = NOW;
204 204
205 if (revents & (POLLERR | POLLHUP)) 205 if (revents & EVENT_WRITE)
206 {
207 error ();
208 return;
209 }
210
211 if (revents & POLLOUT)
212 { 206 {
213 if (state == CONNECTING) 207 if (state == CONNECTING)
214 { 208 {
215 state = ESTABLISHED; 209 state = ESTABLISHED;
216 set (POLLIN); 210 set (EVENT_READ);
217#if ENABLE_HTTP_PROXY 211#if ENABLE_HTTP_PROXY
218 if (::conf.proxy_host && ::conf.proxy_port) 212 if (::conf.proxy_host && ::conf.proxy_port)
219 { 213 {
220 state = CONNECTING_PROXY; 214 state = CONNECTING_PROXY;
215
221 write (fd, proxy_req, proxy_req_len); 216 if (write (fd, proxy_req, proxy_req_len) == 0)
217 {
218 error ();
219 return;
220 }
221
222 free (proxy_req); proxy_req = 0; 222 free (proxy_req); proxy_req = 0;
223 } 223 }
224#endif 224#endif
225 } 225 }
226 else if (state == ESTABLISHED) 226 else if (state == ESTABLISHED)
229 { 229 {
230 if (write_packet ()) 230 if (write_packet ())
231 { 231 {
232 delete w_pkt; w_pkt = 0; 232 delete w_pkt; w_pkt = 0;
233 233
234 set (POLLIN); 234 set (EVENT_READ);
235 } 235 }
236 } 236 }
237 else 237 else
238 set (POLLIN); 238 set (EVENT_READ);
239 } 239 }
240 else 240 else
241 set (POLLIN); 241 set (EVENT_READ);
242 } 242 }
243 243
244 if (revents & POLLIN) 244 if (revents & EVENT_READ)
245 { 245 {
246 if (state == ESTABLISHED) 246 if (state == ESTABLISHED)
247 for (;;) 247 for (;;)
248 { 248 {
249 if (!r_pkt) 249 if (!r_pkt)
283 break; 283 break;
284 } 284 }
285 else if (len < 0 && (errno == EINTR || errno == EAGAIN)) 285 else if (len < 0 && (errno == EINTR || errno == EAGAIN))
286 break; 286 break;
287 287
288 // len == 0 <-> EOF
288 error (); 289 error ();
289 break; 290 break;
290 } 291 }
291#if ENABLE_HTTP_PROXY 292#if ENABLE_HTTP_PROXY
292 else if (state == CONNECTING_PROXY) 293 else if (state == CONNECTING_PROXY)
320 321
321 fcntl (fd, F_SETFL, O_NONBLOCK); 322 fcntl (fd, F_SETFL, O_NONBLOCK);
322 323
323 if (i < 12) 324 if (i < 12)
324 { 325 {
325 slog (L_ERR, _("unable to do proxy-forwarding, short response")); 326 slog (L_ERR, _("(%s): unable to do proxy-forwarding, short response"),
327 (const char *)si);
326 error (); 328 error ();
327 } 329 }
328 else if (r[0] != 'H' || r[1] != 'T' || r[2] != 'T' || r[3] != 'P' || r[4] != '/' 330 else if (r[0] != 'H' || r[1] != 'T' || r[2] != 'T' || r[3] != 'P' || r[4] != '/'
329 || r[5] != '1' // http-major 331 || r[5] != '1' // http-major
330 || r[9] != '2') // response 332 || r[9] != '2') // response
331 { 333 {
332 slog (L_ERR, _("malformed or unexpected proxy response (%.12s)"), r); 334 slog (L_ERR, _("(%s): malformed or unexpected proxy response (%.12s)"),
335 (const char *)si, r);
333 error (); 336 error ();
334 } 337 }
335 else 338 else
336 state = ESTABLISHED; 339 state = ESTABLISHED;
337 } 340 }
385 388
386 if (connect (fd, csi->sav4 (), csi->salenv4 ()) >= 0 389 if (connect (fd, csi->sav4 (), csi->salenv4 ()) >= 0
387 || errno == EINPROGRESS) 390 || errno == EINPROGRESS)
388 { 391 {
389 state = CONNECTING; 392 state = CONNECTING;
390 start (fd, POLLOUT); 393 start (fd, EVENT_WRITE);
391 } 394 }
392 else 395 else
393 close (fd); 396 close (fd);
394 } 397 }
395 } 398 }
399 // right thing to do, not using tcp *is* the right thing to do. 402 // right thing to do, not using tcp *is* the right thing to do.
400 if (!w_pkt) 403 if (!w_pkt)
401 { 404 {
402 // how this maps to the underlying tcp packets we don't know 405 // how this maps to the underlying tcp packets we don't know
403 // and we don't care. at least we tried ;) 406 // and we don't care. at least we tried ;)
407#if defined(SOL_IP) && defined(IP_TOS)
404 setsockopt (fd, SOL_IP, IP_TOS, &tos, sizeof tos); 408 setsockopt (fd, SOL_IP, IP_TOS, &tos, sizeof tos);
409#endif
405 410
406 w_pkt = pkt; 411 w_pkt = pkt;
407 w_ofs = 0; 412 w_ofs = 0;
408 w_len = pkt->len + 2; // length + size header 413 w_len = pkt->len + 2; // length + size header
409 414
412 else 417 else
413 { 418 {
414 w_pkt = new vpn_packet; 419 w_pkt = new vpn_packet;
415 w_pkt->set (*pkt); 420 w_pkt->set (*pkt);
416 421
417 set (POLLIN | POLLOUT); 422 set (EVENT_READ | EVENT_WRITE);
418 } 423 }
419 } 424 }
420 } 425 }
421 426
422 return state != ERROR; 427 return state != ERROR;
458 } 463 }
459 else 464 else
460 { 465 {
461 active = false; 466 active = false;
462 state = ESTABLISHED; 467 state = ESTABLISHED;
463 start (fd, POLLIN); 468 start (fd, EVENT_READ);
464 } 469 }
465} 470}
466 471
467tcp_connection::~tcp_connection () 472tcp_connection::~tcp_connection ()
468{ 473{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines