… | |
… | |
59 | |
59 | |
60 | vpn network; // THE vpn (bad design...) |
60 | vpn network; // THE vpn (bad design...) |
61 | |
61 | |
62 | ///////////////////////////////////////////////////////////////////////////// |
62 | ///////////////////////////////////////////////////////////////////////////// |
63 | |
63 | |
|
|
64 | // hopefully temporary workaround for rare buffer full conditions |
|
|
65 | // if it happens, usually instantly retrying or retrying ~5ms later |
|
|
66 | // is good enough with current network technologies/kernels |
|
|
67 | |
|
|
68 | static ssize_t |
|
|
69 | xsendto (int fd, const void *buf, size_t len, int flags, |
|
|
70 | const struct sockaddr *sa, socklen_t salen) |
|
|
71 | { |
|
|
72 | ssize_t res; |
|
|
73 | |
|
|
74 | for (int retry = 0; retry <= 13; ++retry) // ~100ms |
|
|
75 | { |
|
|
76 | res = sendto (fd, buf, len, flags, sa, salen); |
|
|
77 | |
|
|
78 | if (res >= 0 || errno != ENOBUFS) |
|
|
79 | break; |
|
|
80 | |
|
|
81 | struct timespec ts = { 0, 1000 * retry }; |
|
|
82 | nanosleep (&ts, 0); |
|
|
83 | } |
|
|
84 | |
|
|
85 | return res; |
|
|
86 | } |
|
|
87 | |
|
|
88 | ///////////////////////////////////////////////////////////////////////////// |
|
|
89 | |
64 | static void inline |
90 | static void inline |
65 | set_tos (int fd, int &tos_prev, int tos) |
91 | set_tos (int fd, int &tos_prev, int tos) |
66 | { |
92 | { |
67 | #if defined(SOL_IP) && defined(IP_TOS) |
93 | #if defined(SOL_IP) && defined(IP_TOS) |
68 | if (tos_prev == tos) |
94 | if (tos_prev == tos) |
… | |
… | |
460 | |
486 | |
461 | bool |
487 | bool |
462 | vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) |
488 | vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) |
463 | { |
489 | { |
464 | set_tos (ipv4_fd, ipv4_tos, tos); |
490 | set_tos (ipv4_fd, ipv4_tos, tos); |
465 | sendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); |
491 | xsendto (ipv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); |
466 | |
492 | |
467 | return true; |
493 | return true; |
468 | } |
494 | } |
469 | |
495 | |
470 | static u16 |
496 | static u16 |
… | |
… | |
501 | hdr->code = 255; |
527 | hdr->code = 255; |
502 | hdr->checksum = 0; |
528 | hdr->checksum = 0; |
503 | hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); |
529 | hdr->checksum = ipv4_checksum ((u16 *)hdr, pkt->len); |
504 | |
530 | |
505 | set_tos (icmpv4_fd, icmpv4_tos, tos); |
531 | set_tos (icmpv4_fd, icmpv4_tos, tos); |
506 | sendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); |
532 | xsendto (icmpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); |
507 | |
533 | |
508 | return true; |
534 | return true; |
509 | } |
535 | } |
510 | #endif |
536 | #endif |
511 | |
537 | |
512 | bool |
538 | bool |
513 | vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) |
539 | vpn::send_udpv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) |
514 | { |
540 | { |
515 | set_tos (udpv4_fd, udpv4_tos, tos); |
541 | set_tos (udpv4_fd, udpv4_tos, tos); |
516 | sendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); |
542 | xsendto (udpv4_fd, &((*pkt)[0]), pkt->len, 0, si.sav4 (), si.salenv4 ()); |
517 | |
543 | |
518 | return true; |
544 | return true; |
519 | } |
545 | } |
520 | |
546 | |
521 | void |
547 | void |