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

Comparing gvpe/src/vpn.C (file contents):
Revision 1.2 by pcg, Wed Apr 2 05:15:00 2003 UTC vs.
Revision 1.4 by pcg, Fri Apr 4 05:26:45 2003 UTC

87 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 87 udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
88 88
89 if (udpv4_fd < 0) 89 if (udpv4_fd < 0)
90 return -1; 90 return -1;
91 91
92 // standard daemon practise...
93 {
94 int oval = 1;
95 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
96 }
97
92 sockinfo si (THISNODE, PROT_UDPv4); 98 sockinfo si (THISNODE, PROT_UDPv4);
93 99
94 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ())) 100 if (bind (udpv4_fd, si.sav4 (), si.salenv4 ()))
95 { 101 {
96 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno)); 102 slog (L_ERR, _("can't bind udpv4 on %s: %s"), (const char *)si, strerror (errno));
105 int oval = IP_PMTUDISC_DONT; 111 int oval = IP_PMTUDISC_DONT;
106 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval); 112 setsockopt (udpv4_fd, SOL_IP, IP_MTU_DISCOVER, &oval, sizeof oval);
107 } 113 }
108#endif 114#endif
109 115
110 // standard daemon practise...
111 {
112 int oval = 1;
113 setsockopt (udpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
114 }
115
116 udpv4_ev_watcher.start (udpv4_fd, POLLIN); 116 udpv4_ev_watcher.start (udpv4_fd, POLLIN);
117 } 117 }
118 118
119 ipv4_fd = -1; 119 ipv4_fd = -1;
120 if (THISNODE->protocols & PROT_IPv4) 120 if (THISNODE->protocols & PROT_IPv4)
151 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 151 tcpv4_fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
152 152
153 if (tcpv4_fd < 0) 153 if (tcpv4_fd < 0)
154 return -1; 154 return -1;
155 155
156 sockinfo si (THISNODE, PROT_TCPv4);
157
158 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
159 {
160 slog (L_ERR, _("can't bind tcpv4 on %s: %s"), (const char *)si, strerror (errno));
161 exit (1);
162 }
163
164 if (listen (tcpv4_fd, 5))
165 {
166 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno));
167 exit (1);
168 }
169
170 // standard daemon practise... 156 // standard daemon practise...
171 { 157 {
172 int oval = 1; 158 int oval = 1;
173 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval); 159 setsockopt (tcpv4_fd, SOL_SOCKET, SO_REUSEADDR, &oval, sizeof oval);
174 } 160 }
175 161
162 sockinfo si (THISNODE, PROT_TCPv4);
163
164 if (bind (tcpv4_fd, si.sav4 (), si.salenv4 ()))
165 {
166 slog (L_ERR, _("can't bind tcpv4 on %s: %s"), (const char *)si, strerror (errno));
167 exit (1);
168 }
169
170 if (listen (tcpv4_fd, 5))
171 {
172 slog (L_ERR, _("can't listen tcpv4 on %s: %s"), (const char *)si, strerror (errno));
173 exit (1);
174 }
175
176 tcpv4_accept_watcher.start (tcpv4_fd, POLLIN); 176 tcpv4_ev_watcher.start (tcpv4_fd, POLLIN);
177 } 177 }
178#endif 178#endif
179 179
180 tap = new tap_device (); 180 tap = new tap_device ();
181 if (!tap) //D this, of course, never catches 181 if (!tap) //D this, of course, never catches
239 c->recv_vpn_packet (pkt, rsi); 239 c->recv_vpn_packet (pkt, rsi);
240 } 240 }
241} 241}
242 242
243void 243void
244vpn::udpv4_ev (int fd, short revents) 244vpn::udpv4_ev (io_watcher &w, short revents)
245{ 245{
246 if (revents & (POLLIN | POLLERR)) 246 if (revents & (POLLIN | POLLERR))
247 { 247 {
248 vpn_packet *pkt = new vpn_packet; 248 vpn_packet *pkt = new vpn_packet;
249 struct sockaddr_in sa; 249 struct sockaddr_in sa;
250 socklen_t sa_len = sizeof (sa); 250 socklen_t sa_len = sizeof (sa);
251 int len; 251 int len;
252 252
253 len = recvfrom (fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); 253 len = recvfrom (w.p->fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
254 254
255 sockinfo si(sa); 255 sockinfo si(sa);
256 256
257 if (len > 0) 257 if (len > 0)
258 { 258 {
282 exit (1); 282 exit (1);
283 } 283 }
284} 284}
285 285
286void 286void
287vpn::ipv4_ev (int fd, short revents) 287vpn::ipv4_ev (io_watcher &w, short revents)
288{ 288{
289 if (revents & (POLLIN | POLLERR)) 289 if (revents & (POLLIN | POLLERR))
290 { 290 {
291 vpn_packet *pkt = new vpn_packet; 291 vpn_packet *pkt = new vpn_packet;
292 struct sockaddr_in sa; 292 struct sockaddr_in sa;
293 socklen_t sa_len = sizeof (sa); 293 socklen_t sa_len = sizeof (sa);
294 int len; 294 int len;
295 295
296 len = recvfrom (fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); 296 len = recvfrom (w.p->fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
297 297
298 sockinfo si(sa, PROT_IPv4); 298 sockinfo si(sa, PROT_IPv4);
299 299
300 if (len > 0) 300 if (len > 0)
301 { 301 {
330 } 330 }
331} 331}
332 332
333#if ENABLE_TCP 333#if ENABLE_TCP
334 334
335struct tcp_info { 335struct tcp_connection;
336 int fd; 336
337struct lt_sockinfo
338{
339 bool operator()(const sockinfo *a, const sockinfo *b) const
340 {
341 return *a < *b;
342 }
343};
344
345struct tcp_si_map : public map<const sockinfo *, tcp_connection *, lt_sockinfo> {
346 void cleaner_cb (time_watcher &w); time_watcher cleaner;
347
348 tcp_si_map ()
349 : cleaner(this, &tcp_si_map::cleaner_cb)
350 {
351 cleaner.start (0);
352 }
353} tcp_si;
354
355struct tcp_connection : io_watcher {
356 tstamp last_activity;
357 const sockinfo si;
358 vpn &v;
337 bool ok; 359 bool ok;
338 io_watcher r;
339 360
340 tcp_info (vpn *v) 361 vpn_packet *r_pkt;
341 : r(v, &vpn::tcpv4_ev) 362 u32 r_len, r_ofs;
342 { 363
343 fd = -1; 364 void tcpv4_ev (io_watcher &w, short revents);
365
366 operator tcp_si_map::value_type()
344 } 367 {
368 return tcp_si_map::value_type (&si, this);
369 }
345 370
346 ~tcp_info () { close (fd); } 371 tcp_connection (int fd, const sockinfo &si_, vpn &v_)
372 : v(v_), si(si_), io_watcher(this, &tcp_connection::tcpv4_ev)
373 {
374 last_activity = NOW;
375 ok = false;
376 r_pkt = 0;
377 start (fd, POLLOUT);
378 }
379
380 ~tcp_connection () { if (p) close (p->fd); }
347}; 381};
348 382
349typedef map<sockinfo, tcp_info *> tcp_si_map; 383void tcp_si_map::cleaner_cb (time_watcher &w)
350typedef map<int, tcp_info *> tcp_fd_map; // unneecssary if iom would be cooler 384{
351static tcp_si_map tcp_si; 385 w.at = NOW + 600;
352static tcp_fd_map tcp_fd; 386 tstamp to = NOW - ::conf.keepalive - 30;
387
388 for (iterator i = begin (); i != end(); )
389 if (i->second->last_activity >= to)
390 ++i;
391 else
392 {
393 erase (i);
394 i = begin ();
395 }
396}
353 397
354void 398void
355vpn::send_tcpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 399vpn::send_tcpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
356{ 400{
357 tcp_si_map::iterator info = tcp_si.find (si); 401 tcp_si_map::iterator info = tcp_si.find (&si);
358 402
359 if (info == tcp_si.end ()) 403 if (info == tcp_si.end ())
360 { 404 {
361 // woaw, the first lost packet ;) 405 // woaw, the first lost packet ;)
362 tcp_info *i = new tcp_info (this);
363
364 i->ok = false;
365 i->fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); 406 int fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
366 407
367 if (i->fd >= 0) 408 if (fd >= 0)
368 { 409 {
369 fcntl (i->fd, F_SETFL, O_NONBLOCK); 410 fcntl (fd, F_SETFL, O_NONBLOCK);
370 411
371 if (connect (i->fd, si.sav4 (), si.salenv4 ()) >= 0 412 if (connect (fd, si.sav4 (), si.salenv4 ()) >= 0
372 || errno == EINPROGRESS) 413 || errno == EINPROGRESS)
373 { 414 {
374 tcp_si.insert (tcp_si_map::value_type (si, i)); 415 tcp_connection *i = new tcp_connection (fd, si, *this);
375 tcp_fd.insert (tcp_fd_map::value_type (i->fd, i)); 416
376 return; 417 tcp_si.insert (*i);
377 } 418 }
378
379 delete i; 419 else
420 close (fd);
380 } 421 }
381 } 422 }
382 else 423 else
383 { 424 {
384 tcp_info *i = info->second; 425 tcp_connection *i = info->second;
426
427 i->last_activity = NOW;
385 428
386 if (i->ok) 429 if (i->ok)
387 { 430 {
388 setsockopt (i->fd, SOL_IP, IP_TOS, &tos, sizeof tos); 431 setsockopt (i->p->fd, SOL_IP, IP_TOS, &tos, sizeof tos);
389 432
433 // we use none of the advantages of tcp
390 if (write (i->fd, (void *)pkt, pkt->len + sizeof (u32)) != pkt->len + sizeof (u32)) 434 write (i->p->fd, (void *)pkt, pkt->len + sizeof (u32)) != pkt->len + sizeof (u32);
391 {
392 // error, close socket, forget it and retry immediately
393 tcp_si.erase (info);
394 tcp_fd.erase (i->fd);
395 delete i;
396
397 // tail recursion is... better than goto(?)
398 send_tcpv4_packet (pkt, si, tos);
399 }
400 } 435 }
401 } 436 }
402 437
403#if 0 438#if 0
404 setsockopt (udpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos); 439 setsockopt (udpv4_fd, SOL_IP, IP_TOS, &tos, sizeof tos);
405 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); 440 sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ());
406#endif 441#endif
407} 442}
408 443
409void 444void
445tcp_connection::tcpv4_ev (io_watcher &w, short revents)
446{
447 last_activity = NOW;
448
449 if (!ok) // just established?
450 {
451 ok = true;
452 set (POLLIN);
453 }
454
455 if (revents & (POLLIN | POLLERR))
456 {
457 u32 len;
458
459 if (sizeof (len) == read (p->fd, &len, sizeof (len)))
460 {
461 vpn_packet *pkt = new vpn_packet;
462
463 if (len == read (p->fd, &((*pkt)[0]), len))
464 {
465 pkt->len = len;
466
467 v.recv_vpn_packet (pkt, si);
468 return;
469 }
470
471 delete pkt;
472 }
473
474 tcp_si.erase (&si);
475
476 set (0);//D
477 }
478}
479
480void
410vpn::tcpv4_accept (int fd, short revents) 481vpn::tcpv4_ev (io_watcher &w, short revents)
411{ 482{
412 if (revents & (POLLIN | POLLERR)) 483 if (revents & (POLLIN | POLLERR))
413 { 484 {
414 struct sockaddr_in sa; 485 struct sockaddr_in sa;
415 socklen_t sa_len = sizeof (sa); 486 socklen_t sa_len = sizeof (sa);
416 int len; 487 int len;
417 488
418 fd = accept (fd, (sockaddr *)&sa, &sa_len); 489 int fd = accept (w.p->fd, (sockaddr *)&sa, &sa_len);
419 490
420 if (fd >= 0) 491 if (fd >= 0)
421 { 492 {
422 fcntl (fd, F_SETFL, O_NONBLOCK); 493 fcntl (fd, F_SETFL, O_NONBLOCK);
423 494
424 sockinfo si(sa, PROT_TCPv4); 495 sockinfo si(sa, PROT_TCPv4);
425 tcp_info *i = new tcp_info (this); 496 tcp_connection *i = new tcp_connection (fd, si, *this);
426 497
427 i->fd = fd; 498 slog (L_DEBUG, _("accepted tcp connection from %s\n"), (const char *)si);//D
428 i->ok = true;
429 i->r.start (fd, POLLIN);
430 499
431 tcp_si.insert (tcp_si_map::value_type (si, i));
432 tcp_fd.insert (tcp_fd_map::value_type (fd, i));
433 }
434 }
435}
436
437void
438vpn::tcpv4_ev (int fd, short revents)
439{
440 if (revents & (POLLIN | POLLERR))
441 {
442 tcp_fd_map::iterator info = tcp_fd.find (fd);
443
444 if (info != tcp_fd.end ())
445 {
446 tcp_info *i = info->second;
447
448 if (!i->ok) // not yet established
449 {
450 i->ok = true;
451 fcntl (i->fd, F_SETFL, 0);
452 }
453
454 u32 len;
455
456 if (sizeof (len) == read (fd, &len, sizeof (len)))
457 {
458 slog (L_ERR, "%d bytes received\n", len);
459 }
460
461 //tcp_si.erase (i); 500 tcp_si.insert (*i);
462 tcp_fd.erase (fd);
463 delete i;
464 } 501 }
465 } 502 }
466} 503}
467 504
468#endif 505#endif
469 506
470void 507void
471vpn::tap_ev (int fd, short revents) 508vpn::tap_ev (io_watcher &w, short revents)
472{ 509{
473 if (revents & POLLIN) 510 if (revents & POLLIN)
474 { 511 {
475 /* process data */ 512 /* process data */
476 tap_packet *pkt; 513 tap_packet *pkt;
526 else 563 else
527 abort (); 564 abort ();
528} 565}
529 566
530void 567void
531vpn::event_cb (tstamp &ts) 568vpn::event_cb (time_watcher &w)
532{ 569{
533 if (events) 570 if (events)
534 { 571 {
535 if (events & EVENT_SHUTDOWN) 572 if (events & EVENT_SHUTDOWN)
536 { 573 {
553 } 590 }
554 591
555 events = 0; 592 events = 0;
556 } 593 }
557 594
558 ts = TSTAMP_CANCEL; 595 w.at = TSTAMP_CANCEL;
559} 596}
560 597
561void 598void
562vpn::shutdown_all () 599vpn::shutdown_all ()
563{ 600{
649: event(this, &vpn::event_cb) 686: event(this, &vpn::event_cb)
650, udpv4_ev_watcher(this, &vpn::udpv4_ev) 687, udpv4_ev_watcher(this, &vpn::udpv4_ev)
651, ipv4_ev_watcher (this, &vpn::ipv4_ev) 688, ipv4_ev_watcher (this, &vpn::ipv4_ev)
652, tap_ev_watcher (this, &vpn::tap_ev) 689, tap_ev_watcher (this, &vpn::tap_ev)
653#if ENABLE_TCP 690#if ENABLE_TCP
654, tcpv4_accept_watcher(this, &vpn::tcpv4_accept) 691, tcpv4_ev_watcher(this, &vpn::tcpv4_ev)
655#endif 692#endif
656{ 693{
657} 694}
658 695
659vpn::~vpn () 696vpn::~vpn ()

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines