… | |
… | |
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 | |
354 | vpn_packet *byte_stream::get () |
353 | vpn_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 | |
511 | static u16 dns_id = 12098; // TODO: should be per-vpn |
512 | static u16 dns_id = 12098; // TODO: should be per-vpn |
512 | |
513 | |
513 | static u16 next_id () |
514 | static 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 | |
|
|
539 | dns_snd::~dns_snd () |
|
|
540 | { |
|
|
541 | delete pkt; |
535 | } |
542 | } |
536 | |
543 | |
537 | static void append_domain (dns_packet &pkt, int &offs, const char *domain) |
544 | static 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 | |
|
|
1133 | void |
|
|
1134 | connection::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 | |
1121 | void |
1141 | void |
1122 | dns_connection::time_cb (time_watcher &w) |
1142 | dns_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 |