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.10 by pcg, Fri Mar 4 08:15:04 2005 UTC vs.
Revision 1.13 by pcg, Fri Mar 4 09:48:42 2005 UTC

43 43
44#include "netcompat.h" 44#include "netcompat.h"
45 45
46#include "vpn.h" 46#include "vpn.h"
47 47
48#define MIN_POLL_INTERVAL .2 // how often to poll minimally when the server is having data 48#define MIN_POLL_INTERVAL .02 // how often to poll minimally when the server is having data
49#define MAX_POLL_INTERVAL 6. // how often to poll minimally when the server has no data 49#define MAX_POLL_INTERVAL 6. // how often to poll minimally when the server has no data
50#define ACTIVITY_INTERVAL 5. 50#define ACTIVITY_INTERVAL 5.
51 51
52#define INITIAL_TIMEOUT 1. 52#define INITIAL_TIMEOUT 1.
53#define INITIAL_SYN_TIMEOUT 2. 53#define INITIAL_SYN_TIMEOUT 2.
54 54
55#define MIN_SEND_INTERVAL (1./1000.) 55#define MIN_SEND_INTERVAL 0.01
56#define MAX_SEND_INTERVAL 0.5 // optimistic? 56#define MAX_SEND_INTERVAL 0.5 // optimistic?
57 57
58#define MAX_OUTSTANDING 400 // max. outstanding requests 58#define MAX_OUTSTANDING 40 // max. outstanding requests
59#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING 59#define MAX_WINDOW 100 // max. for MAX_OUTSTANDING
60#define MAX_RATE 100 // requests/s
61#define MAX_BACKLOG (100*1024) // size of protocol backlog, must be > MAXSIZE 60#define MAX_BACKLOG (100*1024) // size of protocol backlog, must be > MAXSIZE
62 61
63#define MAX_DOMAIN_SIZE 220 // 255 is legal limit, but bind doesn't compress well 62#define MAX_DOMAIN_SIZE 220 // 255 is legal limit, but bind doesn't compress well
64// 240 leaves about 4 bytes of server reply data 63// 240 leaves about 4 bytes of server reply data
65// every two request byte sless give room for one reply byte 64// every two request byte sless give room for one reply byte
351 return true; 350 return true;
352} 351}
353 352
354vpn_packet *byte_stream::get () 353vpn_packet *byte_stream::get ()
355{ 354{
356 int len = (data [0] << 8) | data [1]; 355 unsigned int len = (data [0] << 8) | data [1];
357 356
358 if (len > MAXSIZE && fill >= 2) 357 if (len > MAXSIZE && fill >= 2)
359 abort (); // TODO handle this gracefully, connection reset 358 abort (); // TODO handle this gracefully, connection reset
360 359
361 if (fill < len + 2) 360 if (fill < len + 2)
501 tstamp timeout, sent; 500 tstamp timeout, sent;
502 int retry; 501 int retry;
503 struct dns_connection *dns; 502 struct dns_connection *dns;
504 int seqno; 503 int seqno;
505 504
506 dns_snd (dns_connection *dns);
507 void gen_stream_req (int seqno, byte_stream &stream); 505 void gen_stream_req (int seqno, byte_stream &stream);
508 void gen_syn_req (const dns_cfg &cfg); 506 void gen_syn_req (const dns_cfg &cfg);
507
508 dns_snd (dns_connection *dns);
509 ~dns_snd ();
509}; 510};
510 511
511static u16 dns_id = 12098; // TODO: should be per-vpn 512static u16 dns_id = 12098; // TODO: should be per-vpn
512 513
513static u16 next_id () 514static u16 next_id ()
526: dns (dns) 527: dns (dns)
527{ 528{
528 timeout = 0; 529 timeout = 0;
529 retry = 0; 530 retry = 0;
530 seqno = 0; 531 seqno = 0;
532 sent = NOW;
531 533
532 pkt = new dns_packet; 534 pkt = new dns_packet;
533 535
534 pkt->id = next_id (); 536 pkt->id = next_id ();
537}
538
539dns_snd::~dns_snd ()
540{
541 delete pkt;
535} 542}
536 543
537static void append_domain (dns_packet &pkt, int &offs, const char *domain) 544static void append_domain (dns_packet &pkt, int &offs, const char *domain)
538{ 545{
539 // add tunnel domain 546 // add tunnel domain
707 if (r->datalen) 714 if (r->datalen)
708 { 715 {
709 last_received = NOW; 716 last_received = NOW;
710 tw.trigger (); 717 tw.trigger ();
711 718
712 poll_interval *= 0.99; 719 poll_interval = send_interval;
713 if (poll_interval > MIN_POLL_INTERVAL)
714 poll_interval = MIN_POLL_INTERVAL;
715 } 720 }
716 else 721 else
717 { 722 {
718 poll_interval *= 1.1; 723 poll_interval *= 1.1;
719 if (poll_interval > MAX_POLL_INTERVAL) 724 if (poll_interval > MAX_POLL_INTERVAL)
749 { 754 {
750 sockinfo si; 755 sockinfo si;
751 si.host = 0; si.port = 0; si.prot = PROT_DNSv4; 756 si.host = 0; si.port = 0; si.prot = PROT_DNSv4;
752 757
753 vpn->recv_vpn_packet (pkt, si); 758 vpn->recv_vpn_packet (pkt, si);
759
760 delete pkt;
754 } 761 }
755 762
756 // check for further packets 763 // check for further packets
757 goto redo; 764 goto redo;
758 } 765 }
831 dns->receive_rep (rcv); 838 dns->receive_rep (rcv);
832 } 839 }
833 840
834 pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section 841 pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section
835 842
836 // type
837 int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A; 843 int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A;
838 pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; 844 pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type
839
840 // class
841 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; 845 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class
842
843 // TTL
844 pkt [offs++] = 0; pkt [offs++] = 0; 846 pkt [offs++] = 0; pkt [offs++] = 0;
845 pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; 847 pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL
846 848
847 int rdlen_offs = offs += 2; 849 int rdlen_offs = offs += 2;
848 850
849 int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs; 851 int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs;
850 // bind doesn't compress well, so reduce further by one label length 852 // bind doesn't compress well, so reduce further by one label length
949 i != dns_sndpq.end (); 951 i != dns_sndpq.end ();
950 ++i) 952 ++i)
951 if ((*i)->pkt->id == pkt.id) 953 if ((*i)->pkt->id == pkt.id)
952 { 954 {
953 dns_connection *dns = (*i)->dns; 955 dns_connection *dns = (*i)->dns;
956 connection *c = dns->c;
954 int seqno = (*i)->seqno; 957 int seqno = (*i)->seqno;
955 u8 data[MAXSIZE], *datap = data; 958 u8 data[MAXSIZE], *datap = data;
956 959
957 if ((*i)->retry) 960 if ((*i)->retry)
958 { 961 {
959 dns->send_interval *= 1.01; 962 dns->send_interval *= 1.001;
960 if (dns->send_interval < MAX_SEND_INTERVAL) 963 if (dns->send_interval > MAX_SEND_INTERVAL)
961 dns->send_interval = MAX_SEND_INTERVAL; 964 dns->send_interval = MAX_SEND_INTERVAL;
962 } 965 }
963 else 966 else
964 { 967 {
968#if 1
965 dns->send_interval *= 0.99; 969 dns->send_interval *= 0.9999;
970#endif
966 if (dns->send_interval < MIN_SEND_INTERVAL) 971 if (dns->send_interval < MIN_SEND_INTERVAL)
967 dns->send_interval = MIN_SEND_INTERVAL; 972 dns->send_interval = MIN_SEND_INTERVAL;
968 973
969 // the latency surely puts an upper bound on 974 // the latency surely puts an upper bound on
970 // the minimum send interval 975 // the minimum send interval
976 double latency = NOW - (*i)->sent;
977
971 if (dns->send_interval > NOW - (*i)->sent) 978 if (dns->send_interval > latency)
972 dns->send_interval = NOW - (*i)->sent; 979 dns->send_interval = latency;
973 } 980 }
974 981
975 delete *i; 982 delete *i;
976 dns_sndpq.erase (i); 983 dns_sndpq.erase (i);
977 984
1033 1040
1034 if (ip [3] == CMD_IP_RST) 1041 if (ip [3] == CMD_IP_RST)
1035 { 1042 {
1036 slog (L_DEBUG, _("got tunnel RST request")); 1043 slog (L_DEBUG, _("got tunnel RST request"));
1037 1044
1038 connection *c = dns->c;
1039 delete c->dns; c->dns = 0; 1045 delete dns; c->dns = 0;
1040 1046
1041 return; 1047 return;
1042 } 1048 }
1043 else if (ip [3] == CMD_IP_SYN) 1049 else if (ip [3] == CMD_IP_SYN)
1050 {
1051 slog (L_DEBUG, _("got tunnel SYN reply, server likes us."));
1044 dns->established = true; 1052 dns->established = true;
1053 }
1054 else if (ip [3] == CMD_IP_REJ)
1055 {
1056 slog (L_DEBUG, _("got tunnel REJ reply, server does not like us, aborting."));
1057 abort ();
1058 }
1045 else 1059 else
1046 slog (L_INFO, _("got unknown meta command %02x"), ip [3]); 1060 slog (L_INFO, _("got unknown meta command %02x"), ip [3]);
1047 } 1061 }
1048 else 1062 else
1049 slog (L_INFO, _("got spurious a record %d.%d.%d.%d"), 1063 slog (L_INFO, _("got spurious a record %d.%d.%d.%d"),
1114 dns->tw.trigger (); 1128 dns->tw.trigger ();
1115 1129
1116 return true; 1130 return true;
1117} 1131}
1118 1132
1133void
1134connection::dnsv4_reset_connection ()
1135{
1136 //delete dns; dns = 0; //TODO
1137}
1138
1119#define NEXT(w) do { if (next > (w)) next = w; } while (0) 1139#define NEXT(w) do { if (next > (w)) next = w; } while (0)
1120 1140
1121void 1141void
1122dns_connection::time_cb (time_watcher &w) 1142dns_connection::time_cb (time_watcher &w)
1123{ 1143{
1143 1163
1144 r->retry++; 1164 r->retry++;
1145 r->timeout = NOW + r->retry; 1165 r->timeout = NOW + r->retry;
1146 } 1166 }
1147 } 1167 }
1148 else if (r->timeout < next) 1168 else
1149 NEXT (r->timeout); 1169 NEXT (r->timeout);
1150 } 1170 }
1151 1171
1152 if (last_sent + send_interval <= NOW) 1172 if (last_sent + send_interval <= NOW)
1153 { 1173 {
1177 vpn->dns_sndpq.push_back (send); 1197 vpn->dns_sndpq.push_back (send);
1178 } 1198 }
1179 1199
1180 if (send) 1200 if (send)
1181 { 1201 {
1182 printf ("send pkt\n");
1183 last_sent = NOW; 1202 last_sent = NOW;
1184
1185 if (!send->retry)
1186 send->sent = NOW;
1187
1188 sendto (vpn->dnsv4_fd, 1203 sendto (vpn->dnsv4_fd,
1189 send->pkt->at (0), send->pkt->len, 0, 1204 send->pkt->at (0), send->pkt->len, 0,
1190 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ()); 1205 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ());
1191 } 1206 }
1192 } 1207 }
1193 else 1208 else
1194 NEXT (last_sent + send_interval); 1209 NEXT (last_sent + send_interval);
1195 1210
1196 printf ("pi %f si %f N %f (%d:%d)\n", poll_interval, send_interval, next - NOW, vpn->dns_sndpq.size (), snddq.size ()); 1211 slog (L_NOISE, "pi %f si %f N %f (%d:%d)",
1212 poll_interval, send_interval, next - NOW,
1213 vpn->dns_sndpq.size (), snddq.size ());
1214
1215 // TODO: no idea when this happens, but when next < NOW, we have a problem
1216 if (next < NOW + 0.0001)
1217 next = NOW + 0.1;
1197 1218
1198 w.start (next); 1219 w.start (next);
1199} 1220}
1200 1221
1201#endif 1222#endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines