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

Comparing gvpe/src/vpn_dns.C (file contents):
Revision 1.24 by pcg, Mon Mar 7 01:31:26 2005 UTC vs.
Revision 1.47 by pcg, Thu Aug 7 17:54:27 2008 UTC

1/* 1/*
2 vpn_dns.C -- handle the dns tunnel part of the protocol. 2 vpn_dns.C -- handle the dns tunnel part of the protocol.
3 Copyright (C) 2003-2005 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de>
4 4
5 This file is part of GVPE. 5 This file is part of GVPE.
6 6
7 GVPE is free software; you can redistribute it and/or modify 7 GVPE is free software; you can redistribute it and/or modify it
8 it under the terms of the GNU General Public License as published by 8 under the terms of the GNU General Public License as published by the
9 the Free Software Foundation; either version 2 of the License, or 9 Free Software Foundation; either version 3 of the License, or (at your
10 (at your option) any later version. 10 option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful, but
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 GNU General Public License for more details. 15 Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License along
18 along with gvpe; if not, write to the Free Software 18 with this program; if not, see <http://www.gnu.org/licenses/>.
19 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19
20 Additional permission under GNU GPL version 3 section 7
21
22 If you modify this Program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a modified
24 version of that library), containing parts covered by the terms of the
25 OpenSSL or SSLeay licenses, the licensors of this Program grant you
26 additional permission to convey the resulting work. Corresponding
27 Source for a non-source form of such a combination shall include the
28 source code for the parts of OpenSSL used as well as that of the
29 covered work.
20*/ 30*/
31
32// TODO: EDNS0 option to increase dns mtu?
33// TODO: re-write dns packet parsing/creation using a safe mem-buffer
34// to ensure no buffer overflows or similar problems.
21 35
22#include "config.h" 36#include "config.h"
23 37
24#if ENABLE_DNS 38#if ENABLE_DNS
25 39
38#include <unistd.h> 52#include <unistd.h>
39#include <fcntl.h> 53#include <fcntl.h>
40 54
41#include <map> 55#include <map>
42 56
57#include <cstdio> /* bug in libgmp: gmp.h relies on cstdio being included */
43#include <gmp.h> 58#include <gmp.h>
44 59
45#include "netcompat.h" 60#include "netcompat.h"
46 61
47#include "vpn.h" 62#include "vpn.h"
48 63
49#define MIN_POLL_INTERVAL .02 // how often to poll minimally when the server has data
50#define MAX_POLL_INTERVAL 6. // how often to poll minimally when the server has no data 64#define MAX_POLL_INTERVAL 5. // how often to poll minimally when the server has no data
51#define ACTIVITY_INTERVAL 5. 65#define ACTIVITY_INTERVAL 5.
52 66
53#define INITIAL_TIMEOUT 0.1 // retry timeouts 67#define INITIAL_TIMEOUT 0.1 // retry timeouts
54#define INITIAL_SYN_TIMEOUT 10. // retry timeout for initial syn 68#define INITIAL_SYN_TIMEOUT 2. // retry timeout for initial syn
55 69
56#define MIN_SEND_INTERVAL 0.01 // wait at least this time between sending requests
57#define MAX_SEND_INTERVAL 0.5 // optimistic? 70#define MAX_SEND_INTERVAL 2. // optimistic?
58 71
59#define MAX_OUTSTANDING 10 // max. outstanding requests
60#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog 72#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog
61#define MAX_BACKLOG (100*1024) // size of gvpe protocol backlog (bytes), must be > MAXSIZE 73#define MAX_BACKLOG (64*1024) // size of gvpe protocol backlog (bytes), must be > MAXSIZE
62 74
63#define MAX_DOMAIN_SIZE 220 // 255 is legal limit, but bind doesn't compress well 75#define MAX_DOMAIN_SIZE 240 // 255 is legal limit, but bind doesn't compress well
64// 240 leaves about 4 bytes of server reply data 76// 240 leaves about 4 bytes of server reply data
65// every two request bytes less give room for one reply byte 77// every request byte less give room for two reply bytes
66 78
67#define SEQNO_MASK 0x3fff 79#define SEQNO_MASK 0x3fff
68#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) ) 80#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) )
69 81
70#define MAX_LBL_SIZE 63 82#define MAX_LBL_SIZE 63
423 u16 max_size; 435 u16 max_size;
424 u8 seq_cdc; 436 u8 seq_cdc;
425 u8 req_cdc; 437 u8 req_cdc;
426 438
427 u8 rep_cdc; 439 u8 rep_cdc;
440 u8 delay; // time in 0.01s units that the server may delay replying packets
428 u8 r2, r3, r4; 441 u8 r3, r4;
429 442
430 u8 r5, r6, r7, r8; 443 u8 r5, r6, r7, r8;
431 444
432 void reset (int clientid); 445 void reset (int clientid);
433 bool valid (); 446 bool valid ();
448 flags = 0; 461 flags = 0;
449 def_ttl = 0; 462 def_ttl = 0;
450 seq_cdc = 26; 463 seq_cdc = 26;
451 req_cdc = 62; 464 req_cdc = 62;
452 rep_cdc = 0; 465 rep_cdc = 0;
453 max_size = ntohs (MAX_PKT_SIZE); 466 max_size = htons (MAX_PKT_SIZE);
454 client = ntohs (clientid); 467 client = htons (clientid);
455 uid = next_uid++; 468 uid = next_uid++;
469 delay = 0;
456 470
457 r2 = r3 = r4 = 0; 471 r3 = r4 = 0;
458 r4 = r5 = r6 = r7 = 0; 472 r4 = r5 = r6 = r7 = 0;
459} 473}
460 474
461bool dns_cfg::valid () 475bool dns_cfg::valid ()
462{ 476{
477 // although the protocol itself allows for some configurability,
478 // only the following encoding/decoding settings are implemented.
463 return id1 == 'G' 479 return id1 == 'G'
464 && id2 == 'V' 480 && id2 == 'V'
465 && id3 == 'P' 481 && id3 == 'P'
466 && id4 == 'E' 482 && id4 == 'E'
467 && seq_cdc == 26 483 && seq_cdc == 26
468 && req_cdc == 62 484 && req_cdc == 62
469 && rep_cdc == 0 485 && rep_cdc == 0
470 && version == 1 486 && version == 1;
471 && max_size == ntohs (MAX_PKT_SIZE);
472} 487}
473 488
474struct dns_packet : net_packet 489struct dns_packet : net_packet
475{ 490{
476 u16 id; 491 u16 id;
547 562
548 bool established; 563 bool established;
549 564
550 tstamp last_received; 565 tstamp last_received;
551 tstamp last_sent; 566 tstamp last_sent;
552 double last_latency; 567 double min_latency;
553 double poll_interval, send_interval; 568 double poll_interval, send_interval;
554 569
555 vector<dns_rcv *> rcvpq; 570 vector<dns_rcv *> rcvpq;
556 571
557 byte_stream rcvdq; int rcvseq; 572 byte_stream rcvdq; int rcvseq; int repseq;
558 byte_stream snddq; int sndseq; 573 byte_stream snddq; int sndseq;
559 574
560 void time_cb (time_watcher &w); time_watcher tw; 575 inline void time_cb (ev::timer &w, int revents); ev::timer tw;
561 void receive_rep (dns_rcv *r); 576 void receive_rep (dns_rcv *r);
562 577
563 dns_connection (connection *c); 578 dns_connection (connection *c);
564 ~dns_connection (); 579 ~dns_connection ();
565}; 580};
584: dns (dns) 599: dns (dns)
585{ 600{
586 timeout = 0; 601 timeout = 0;
587 retry = 0; 602 retry = 0;
588 seqno = 0; 603 seqno = 0;
589 sent = NOW; 604 sent = ev_now ();
590 stdhdr = false; 605 stdhdr = false;
591 606
592 pkt = new dns_packet; 607 pkt = new dns_packet;
593 608
594 pkt->id = next_id (); 609 pkt->id = next_id ();
625void dns_snd::gen_stream_req (int seqno, byte_stream &stream) 640void dns_snd::gen_stream_req (int seqno, byte_stream &stream)
626{ 641{
627 stdhdr = true; 642 stdhdr = true;
628 this->seqno = seqno; 643 this->seqno = seqno;
629 644
630 timeout = NOW + INITIAL_TIMEOUT; 645 timeout = ev_now () + INITIAL_TIMEOUT;
631 646
632 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 647 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
633 pkt->qdcount = htons (1); 648 pkt->qdcount = htons (1);
634 649
635 int offs = 6*2; 650 int offs = 6*2;
670 pkt->len = offs; 685 pkt->len = offs;
671} 686}
672 687
673void dns_snd::gen_syn_req () 688void dns_snd::gen_syn_req ()
674{ 689{
675 timeout = NOW + INITIAL_SYN_TIMEOUT; 690 timeout = ev_now () + INITIAL_SYN_TIMEOUT;
676 691
677 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 692 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
678 pkt->qdcount = htons (1); 693 pkt->qdcount = htons (1);
679 694
680 int offs = 6 * 2; 695 int offs = 6 * 2;
719///////////////////////////////////////////////////////////////////////////// 734/////////////////////////////////////////////////////////////////////////////
720 735
721dns_connection::dns_connection (connection *c) 736dns_connection::dns_connection (connection *c)
722: c (c) 737: c (c)
723, rcvdq (MAX_BACKLOG * 2) 738, rcvdq (MAX_BACKLOG * 2)
724, snddq (MAX_BACKLOG * 2) 739, snddq (MAX_BACKLOG)
725, tw (this, &dns_connection::time_cb)
726{ 740{
741 tw.set<dns_connection, &dns_connection::time_cb> (this);
742
727 vpn = c->vpn; 743 vpn = c->vpn;
728 744
729 established = false; 745 established = false;
730 746
731 rcvseq = sndseq = 0; 747 rcvseq = repseq = sndseq = 0;
732 748
733 last_sent = last_received = 0; 749 last_sent = last_received = 0;
734 poll_interval = MIN_POLL_INTERVAL; 750 poll_interval = 0.5; // starting here
735 send_interval = 0.5; // starting rate 751 send_interval = 0.5; // starting rate
736 last_latency = INITIAL_TIMEOUT; 752 min_latency = INITIAL_TIMEOUT;
737} 753}
738 754
739dns_connection::~dns_connection () 755dns_connection::~dns_connection ()
740{ 756{
741 for (vector<dns_rcv *>::iterator i = rcvpq.begin (); 757 for (vector<dns_rcv *>::iterator i = rcvpq.begin ();
746 762
747void dns_connection::receive_rep (dns_rcv *r) 763void dns_connection::receive_rep (dns_rcv *r)
748{ 764{
749 if (r->datalen) 765 if (r->datalen)
750 { 766 {
751 last_received = NOW; 767 last_received = ev_now ();
752 tw.trigger (); 768 tw ();
753 769
754 poll_interval = send_interval; 770 poll_interval = send_interval;
755 } 771 }
756 else 772 else
757 { 773 {
758 poll_interval *= 1.5; 774 poll_interval *= 1.5;
775
759 if (poll_interval > MAX_POLL_INTERVAL) 776 if (poll_interval > MAX_POLL_INTERVAL)
760 poll_interval = MAX_POLL_INTERVAL; 777 poll_interval = MAX_POLL_INTERVAL;
761 } 778 }
762 779
763 rcvpq.push_back (r); 780 rcvpq.push_back (r);
766 783
767 // find next packet 784 // find next packet
768 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); ) 785 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); )
769 if (SEQNO_EQ (rcvseq, (*i)->seqno)) 786 if (SEQNO_EQ (rcvseq, (*i)->seqno))
770 { 787 {
788 //printf ("seqno eq %x %x\n", rcvseq, (*i)->seqno);//D
771 // enter the packet into our input stream 789 // enter the packet into our input stream
772 r = *i; 790 r = *i;
773 791
774 // remove the oldest packet, look forward, as it's oldest first 792 // remove the oldest packet, look forward, as it's oldest first
775 for (vector<dns_rcv *>::iterator j = rcvpq.begin (); j != rcvpq.end (); ++j) 793 for (vector<dns_rcv *>::iterator j = rcvpq.begin (); j != rcvpq.end (); ++j)
776 if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW)) 794 if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW))
777 { 795 {
796 //printf ("seqno RR %x %x\n", (*j)->seqno, rcvseq - MAX_WINDOW);//D
778 delete *j; 797 delete *j;
779 rcvpq.erase (j); 798 rcvpq.erase (j);
780 break; 799 break;
781 } 800 }
782 801
789 } 808 }
790 809
791 while (vpn_packet *pkt = rcvdq.get ()) 810 while (vpn_packet *pkt = rcvdq.get ())
792 { 811 {
793 sockinfo si; 812 sockinfo si;
794 si.host = 0x01010101; si.port = htons (c->conf->id); si.prot = PROT_DNSv4; 813 si.host = htonl (c->conf->id); si.port = 0; si.prot = PROT_DNSv4;
795 814
796 vpn->recv_vpn_packet (pkt, si); 815 vpn->recv_vpn_packet (pkt, si);
797 816
798 delete pkt; 817 delete pkt;
799 } 818 }
853 if (0 < client && client <= conns.size ()) 872 if (0 < client && client <= conns.size ())
854 { 873 {
855 connection *c = conns [client - 1]; 874 connection *c = conns [client - 1];
856 dns_connection *dns = c->dns; 875 dns_connection *dns = c->dns;
857 dns_rcv *rcv; 876 dns_rcv *rcv;
858 bool in_seq;
859 877
860 if (dns) 878 if (dns)
861 { 879 {
862 for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); ) 880 for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); )
863 if (SEQNO_EQ ((*i)->seqno, seqno)) 881 if (SEQNO_EQ ((*i)->seqno, seqno))
874 memcpy (pkt.at (0), r->pkt->at (0), offs = r->pkt->len); 892 memcpy (pkt.at (0), r->pkt->at (0), offs = r->pkt->len);
875 893
876 goto duplicate_request; 894 goto duplicate_request;
877 } 895 }
878 896
879 in_seq = dns->rcvseq == seqno;
880
881 // new packet, queue 897 // new packet, queue
882 rcv = new dns_rcv (seqno, data, datalen); 898 rcv = new dns_rcv (seqno, data, datalen);
883 dns->receive_rep (rcv); 899 dns->receive_rep (rcv);
884 } 900 }
885 901
892 pkt [offs++] = 0; pkt [offs++] = 0; 908 pkt [offs++] = 0; pkt [offs++] = 0;
893 pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL 909 pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL
894 910
895 int rdlen_offs = offs += 2; 911 int rdlen_offs = offs += 2;
896 912
897 int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs;
898 // bind doesn't compress well, so reduce further by one label length
899 dlen -= qlen;
900
901 if (dns) 913 if (dns)
902 { 914 {
915 int dlen = ntohs (dns->cfg.max_size) - offs;
916
917 // bind doesn't compress well, so reduce further by one label length
918 dlen -= qlen;
919
903 // only put data into in-order sequence packets, if 920 // only put data into in-order sequence packets, if
904 // we receive out-of-order packets we generate empty 921 // we receive out-of-order packets we generate empty
905 // replies 922 // replies
906 while (dlen > 1 && !dns->snddq.empty () && in_seq) 923 //printf ("%d - %d & %x (=%d) < %d\n", seqno, dns->repseq, SEQNO_MASK, (seqno - dns->repseq) & SEQNO_MASK, MAX_WINDOW);//D
924 if (((seqno - dns->repseq) & SEQNO_MASK) <= MAX_WINDOW)
907 { 925 {
926 dns->repseq = seqno;
927
928 while (dlen > 1 && !dns->snddq.empty ())
929 {
908 int txtlen = dlen <= 255 ? dlen - 1 : 255; 930 int txtlen = dlen <= 255 ? dlen - 1 : 255;
909 931
910 if (txtlen > dns->snddq.size ()) 932 if (txtlen > dns->snddq.size ())
911 txtlen = dns->snddq.size (); 933 txtlen = dns->snddq.size ();
912 934
913 pkt[offs++] = txtlen; 935 pkt[offs++] = txtlen;
914 memcpy (pkt.at (offs), dns->snddq.begin (), txtlen); 936 memcpy (pkt.at (offs), dns->snddq.begin (), txtlen);
915 offs += txtlen; 937 offs += txtlen;
916 dns->snddq.remove (txtlen); 938 dns->snddq.remove (txtlen);
917 939
918 dlen -= txtlen + 1; 940 dlen -= txtlen + 1;
941 }
919 } 942 }
920 943
921 // avoid empty TXT rdata 944 // avoid completely empty TXT rdata
922 if (offs == rdlen_offs) 945 if (offs == rdlen_offs)
923 pkt[offs++] = 0; 946 pkt[offs++] = 0;
924 947
925 slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ()); 948 slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ());
926 } 949 }
1006 { 1029 {
1007 dns_connection *dns = (*i)->dns; 1030 dns_connection *dns = (*i)->dns;
1008 connection *c = dns->c; 1031 connection *c = dns->c;
1009 int seqno = (*i)->seqno; 1032 int seqno = (*i)->seqno;
1010 u8 data[MAXSIZE], *datap = data; 1033 u8 data[MAXSIZE], *datap = data;
1034 //printf ("rcv pkt %x\n", seqno);//D
1011 1035
1012 if ((*i)->retry) 1036 if ((*i)->retry)
1013 { 1037 {
1014 dns->send_interval *= 1.01; 1038 dns->send_interval *= 1.01;
1015 if (dns->send_interval > MAX_SEND_INTERVAL) 1039 if (dns->send_interval > MAX_SEND_INTERVAL)
1016 dns->send_interval = MAX_SEND_INTERVAL; 1040 dns->send_interval = MAX_SEND_INTERVAL;
1017 } 1041 }
1018 else 1042 else
1019 { 1043 {
1020#if 1 1044#if 0
1021 dns->send_interval *= 0.999; 1045 dns->send_interval *= 0.999;
1022#endif 1046#endif
1023 if (dns->send_interval < MIN_SEND_INTERVAL)
1024 dns->send_interval = MIN_SEND_INTERVAL;
1025
1026 // the latency surely puts an upper bound on 1047 // the latency surely puts an upper bound on
1027 // the minimum send interval 1048 // the minimum send interval
1028 double latency = NOW - (*i)->sent; 1049 double latency = ev_now () - (*i)->sent;
1050
1051 if (latency < dns->min_latency)
1029 dns->last_latency = latency; 1052 dns->min_latency = latency;
1030 1053
1031 if (dns->send_interval > latency) 1054 if (dns->send_interval > dns->min_latency * conf.dns_overlap_factor)
1055 dns->send_interval = dns->min_latency * conf.dns_overlap_factor;
1056
1057 if (dns->send_interval < conf.dns_send_interval)
1032 dns->send_interval = latency; 1058 dns->send_interval = conf.dns_send_interval;
1033 } 1059 }
1034 1060
1035 delete *i; 1061 delete *i;
1036 dns_sndpq.erase (i); 1062 dns_sndpq.erase (i);
1037 1063
1142 break; 1168 break;
1143 } 1169 }
1144} 1170}
1145 1171
1146void 1172void
1147vpn::dnsv4_ev (io_watcher &w, short revents) 1173vpn::dnsv4_ev (ev::io &w, int revents)
1148{ 1174{
1149 if (revents & EVENT_READ) 1175 if (revents & EV_READ)
1150 { 1176 {
1151 dns_packet *pkt = new dns_packet; 1177 dns_packet *pkt = new dns_packet;
1152 struct sockaddr_in sa; 1178 struct sockaddr_in sa;
1153 socklen_t sa_len = sizeof (sa); 1179 socklen_t sa_len = sizeof (sa);
1154 1180
1170} 1196}
1171 1197
1172bool 1198bool
1173vpn::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 1199vpn::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
1174{ 1200{
1175 int client = ntohs (si.port); 1201 int client = ntohl (si.host);
1176 1202
1177 assert (0 < client && client <= conns.size ()); 1203 assert (0 < client && client <= conns.size ());
1178 1204
1179 connection *c = conns [client - 1]; 1205 connection *c = conns [client - 1];
1180 1206
1181 if (!c->dns) 1207 if (!c->dns)
1182 c->dns = new dns_connection (c); 1208 c->dns = new dns_connection (c);
1183 1209
1184 if (!c->dns->snddq.put (pkt)) 1210 if (c->dns->snddq.put (pkt))
1185 return false;
1186
1187 c->dns->tw.trigger (); 1211 c->dns->tw ();
1188 1212
1213 // always return true even if the buffer overflows
1189 return true; 1214 return true;
1190} 1215}
1191 1216
1192void 1217void
1193connection::dnsv4_reset_connection () 1218connection::dnsv4_reset_connection ()
1196} 1221}
1197 1222
1198#define NEXT(w) do { if (next > (w)) next = w; } while (0) 1223#define NEXT(w) do { if (next > (w)) next = w; } while (0)
1199 1224
1200void 1225void
1201dns_connection::time_cb (time_watcher &w) 1226dns_connection::time_cb (ev::timer &w, int revents)
1202{ 1227{
1203 // servers have to be polled 1228 // servers have to be polled
1204 if (THISNODE->dns_port) 1229 if (THISNODE->dns_port)
1205 return; 1230 return;
1206 1231
1207 // check for timeouts and (re)transmit 1232 // check for timeouts and (re)transmit
1208 tstamp next = NOW + poll_interval; 1233 tstamp next = ev::now () + poll_interval;
1209 dns_snd *send = 0; 1234 dns_snd *send = 0;
1210 1235
1211 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin (); 1236 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin ();
1212 i != vpn->dns_sndpq.end (); 1237 i != vpn->dns_sndpq.end ();
1213 ++i) 1238 ++i)
1214 { 1239 {
1215 dns_snd *r = *i; 1240 dns_snd *r = *i;
1216 1241
1217 if (r->timeout <= NOW) 1242 if (r->timeout <= ev_now ())
1218 { 1243 {
1219 if (!send) 1244 if (!send)
1220 { 1245 {
1221 send = r; 1246 send = r;
1222 1247
1223 r->retry++; 1248 r->retry++;
1224 r->timeout = NOW + (r->retry * last_latency * 8.); 1249 r->timeout = ev_now () + (r->retry * min_latency * conf.dns_timeout_factor);
1250 //printf ("RETRY %x (%d, %f)\n", r->seqno, r->retry, r->timeout - ev_now ());//D
1225 1251
1226 // the following code changes the query section a bit, forcing 1252 // the following code changes the query section a bit, forcing
1227 // the forwarder to generate a new request 1253 // the forwarder to generate a new request
1228 if (r->stdhdr) 1254 if (r->stdhdr)
1229 {
1230 //printf ("reencoded header for ID %d retry %d:%d:%d\n", htons (r->pkt->id), THISNODE->id, r->seqno, r->retry);printf ("reencoded header for ID %d retry %d:%d:%d\n", htons (r->pkt->id), THISNODE->id, r->seqno, r->retry);
1231 //encode_header ((char *)r->pkt->at (6 * 2 + 1), THISNODE->id, r->seqno, r->retry); 1255 encode_header ((char *)r->pkt->at (6 * 2 + 1), THISNODE->id, r->seqno, r->retry);
1232 }
1233 } 1256 }
1234 } 1257 }
1235 else 1258 else
1236 NEXT (r->timeout); 1259 NEXT (r->timeout);
1237 } 1260 }
1238 1261
1239 if (last_sent + send_interval <= NOW)
1240 {
1241 if (!send) 1262 if (!send)
1263 {
1264 // generate a new packet, if wise
1265
1266 if (!established)
1242 { 1267 {
1243 // generate a new packet, if wise 1268 if (vpn->dns_sndpq.empty ())
1244
1245 if (!established)
1246 { 1269 {
1247 if (vpn->dns_sndpq.empty ())
1248 {
1249 send = new dns_snd (this); 1270 send = new dns_snd (this);
1250 1271
1251 cfg.reset (THISNODE->id); 1272 cfg.reset (THISNODE->id);
1252 send->gen_syn_req (); 1273 send->gen_syn_req ();
1253 }
1254 } 1274 }
1255 else if (vpn->dns_sndpq.size () < MAX_OUTSTANDING 1275 }
1276 else if (vpn->dns_sndpq.size () < conf.dns_max_outstanding
1256 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1))) 1277 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1)))
1278 {
1279 if (last_sent + send_interval <= ev_now ())
1257 { 1280 {
1258 //printf ("sending data request etc.\n"); //D 1281 //printf ("sending data request etc.\n"); //D
1259 if (!snddq.empty ()) 1282 if (!snddq.empty () || last_received + 1. > ev_now ())
1260 { 1283 {
1261 poll_interval = send_interval; 1284 poll_interval = send_interval;
1262 NEXT (NOW + send_interval); 1285 NEXT (ev_now () + send_interval);
1263 } 1286 }
1264 1287
1265 send = new dns_snd (this); 1288 send = new dns_snd (this);
1266 send->gen_stream_req (sndseq, snddq); 1289 send->gen_stream_req (sndseq, snddq);
1267 send->timeout = NOW + last_latency * 8.; 1290 send->timeout = ev_now () + min_latency * conf.dns_timeout_factor;
1291 //printf ("SEND %x (%f)\n", send->seqno, send->timeout - ev_now (), min_latency, conf.dns_timeout_factor);//D
1268 1292
1269 sndseq = (sndseq + 1) & SEQNO_MASK; 1293 sndseq = (sndseq + 1) & SEQNO_MASK;
1270 } 1294 }
1271 1295 else
1272 if (send) 1296 NEXT (last_sent + send_interval);
1273 vpn->dns_sndpq.push_back (send);
1274 } 1297 }
1275 1298
1276 if (send) 1299 if (send)
1277 { 1300 vpn->dns_sndpq.push_back (send);
1278 last_sent = NOW; 1301 }
1302
1303 if (send)
1304 {
1305 last_sent = ev_now ();
1279 sendto (vpn->dnsv4_fd, 1306 sendto (vpn->dnsv4_fd,
1280 send->pkt->at (0), send->pkt->len, 0, 1307 send->pkt->at (0), send->pkt->len, 0,
1281 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ()); 1308 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ());
1282 }
1283 } 1309 }
1284 else
1285 NEXT (last_sent + send_interval);
1286 1310
1287 slog (L_NOISE, "DNS: pi %f si %f N %f (%d:%d)", 1311 slog (L_NOISE, "DNS: pi %f si %f N %f (%d:%d %d)",
1288 poll_interval, send_interval, next - NOW, 1312 poll_interval, send_interval, next - ev_now (),
1289 vpn->dns_sndpq.size (), snddq.size ()); 1313 vpn->dns_sndpq.size (), snddq.size (),
1314 rcvpq.size ());
1290 1315
1291 // TODO: no idea when this happens, but when next < NOW, we have a problem 1316 // TODO: no idea when this happens, but when next < ev_now (), we have a problem
1317 // doesn't seem to happen anymore
1292 if (next < NOW + 0.0001) 1318 if (next < ev_now () + 0.001)
1293 next = NOW + 0.1; 1319 next = ev_now () + 0.1;
1294 1320
1295 w.start (next); 1321 w.start (next - ev_now ());
1296} 1322}
1297 1323
1298#endif 1324#endif
1299 1325

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines