Changeset eb0bf4
- Timestamp:
- 09/20/09 23:10:38 (4 years ago)
- Branches:
- iodine-0.6
- Children:
- 92ea46
- Parents:
- ed36bb
- git-author:
- Erik Ekman <yarrick@…> (09/20/09 23:10:38)
- git-committer:
- Erik Ekman <yarrick@…> (09/20/09 23:10:38)
- Files:
-
- 4 edited
-
README (modified) (2 diffs)
-
doc/proto_00000501.txt (modified) (2 diffs)
-
src/common.c (modified) (1 diff)
-
src/common.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
README
r370348 reb0bf4 95 95 fragment size autoprobe. 96 96 97 Normal operation now is for the server to _not_ answer a DNS request until 98 the next DNS request has come in, a.k.a. being "lazy". This way, the server 99 will always have a DNS request handy when new downstream data has to be sent. 100 This greatly improves (interactive) performance and latency, and allows to 101 slow down the quiescent ping requests to 4 second intervals by default. 102 In fact, the main purpose of the pings now is to force a reply to the previous 103 ping, and prevent DNS server timeouts (usually 5-10 seconds per RFC1035). 104 In the unlikely case that you do experience DNS server timeouts (SERVFAIL), 105 decrease the -I option to 1. If you are running on a local network without 106 any DNS server in-between, try -I 50 (iodine and iodined time out after 60 107 seconds). The only time you'll notice a slowdown, is when DNS reply packets 108 go missing; the iodined server then has to wait for a new ping to re-send the 109 data. You can speed this up by generating some upstream traffic (keypress, 110 ping). If this happens often, check your network for bottlenecks and/or run 111 with -I1 . 112 113 Some DNS servers appear to be quite impatient and start retrying DNS requests 114 (with _different_ DNS ids!) when an answer does not appear within a few 115 milliseconds. Usually they scale back retries when iodined's lazy mode 116 repeatedly takes several seconds to answer; and they scale up retries again 117 when iodined answers fast during heavy data transfer. Some commercial DNS 118 servers advertise this as "carrier-grade adaptive retransmission techniques". 119 The effect will only be visible in the network traffic at the iodined server, 120 and will not affect the client's connection. Iodined has rather elaborate 121 logic to deal with (i.e., ignore) these unwanted duplicates. 122 123 Other DNS servers, notably the opendns.com network, seem to regard iodined's 124 lazyness as incompetency, and will start shuffling requests around, possibly 125 in an attempt to reduce iodined's workload. The resulting out-of-sequence DNS 126 traffic works quite badly for lazy mode. The iodine client will detect this, 127 and switch back to legacy mode ("immediate ping-pong") automatically. In these 128 cases, start the iodine client with -L0 to prevent it from operating in lazy 129 mode altogether. Note that this will negatively affect interactive performance 130 and latency, especially in the downstream direction. 131 97 132 If you have problems, try inspecting the traffic with network monitoring tools 98 133 and make sure that the relaying DNS server has not cached the response. A … … 110 145 111 146 Iodined will reject data from clients that have not been active (data/pings) 112 for more than 60 seconds. In case of a long network outage or similar, just 113 stop iodine and restart (re-login), possibly multiple times until you get 147 for more than 60 seconds. Similarly, iodine will exit when no downstream 148 data has been received for 60 seconds. In case of a long network outage or 149 similar, just restart iodine (re-login), possibly multiple times until you get 114 150 your old IP address back. Once that's done, just wait a while, and you'll 115 151 eventually see the tunneled TCP traffic continue to flow from where it left 116 152 off before the outage. 153 154 With the introduction of the downstream packet queue in the server, its memory 155 usage has increased with several megabytes in the default configuration. 156 For use in low-memory environments (e.g. running on your DSL router), you can 157 decrease USERS and undefine OUTPACKETQ_LEN in user.h without any ill conse- 158 quence, assuming at most one client will be connected at any time. A small 159 DNSCACHE_LEN is still advised, preferably 2 or higher, however you can also 160 undefine it to save a few more kilobytes. 161 162 163 PERFORMANCE: 164 165 This section tabulates some performance measurements. To view properly, use 166 a fixed-width font like Courier. 167 168 Measurements were done in protocol 00000500 with lazy mode unless indicated 169 otherwise. Upstream encoding always Base64. 170 Upstream/downstream throughput was measured by scp'ing a file previously 171 read from /dev/urandom (i.e. incompressible), and measuring size with 172 "ls -l ; sleep 30 ; ls -l" on a separate non-tunneled connection. Given the 173 large scp block size of 16 kB, this gives a resolution of 4.3 kbit/s, which 174 explains why many values are exactly equal. 175 Ping round-trip times measured with "ping -c100", presented are average rtt 176 and mean deviation (indicating spread around the average), in milliseconds. 177 178 179 Situation 1: 180 Laptop -> Wifi AP -> Home server -> DSL provider -> Datacenter 181 iodine DNS "relay" bind9 DNS cache iodined 182 183 downstr. upstream downstr. ping-up ping-down 184 fragsize kbit/s kbit/s avg +/-mdev avg +/-mdev 185 ------------------------------------------------------------------------------ 186 187 iodine -> Wifi AP :53 188 -Tnull (= -Oraw) 982 39.3 148.5 26.7 3.1 26.6 3.0 189 190 iodine -> Home server :53 191 -Tnull (= -Oraw) 1174 43.6 174.7 25.2 4.0 25.5 3.4 192 193 iodine -> DSL provider :53 194 -Tnull (= -Oraw) 1174 52.4 200.9 20.3 3.2 20.3 2.7 195 -Ttxt -Obase32 730 52.4 192.2* 196 -Ttxt -Obase64 874 52.4 192.2 197 -Ttxt -Oraw 1162 52.4 192.2 198 -Tcname -Obase32 148 52.4 48.0 199 -Tcname -Obase64 181 52.4 61.1 200 201 iodine -> DSL provider :53 202 wired (no Wifi) -Tnull 1174 65.5 244.6 17.7 1.9 17.8 1.6 203 204 [192.2* : nice, because still 2frag/packet] 205 206 207 Situation 2: 208 Laptop -> (wire) -> (Home server) -> (DSL) -> opendns.com -> Datacenter 209 iodine DNS cache iodined 210 211 downstr. upstream downstr. ping-up ping-down 212 fragsize kbit/s kbit/s avg +/-mdev avg +/-mdev 213 ------------------------------------------------------------------------------ 214 215 iodine -> opendns.com :53 216 -Tnull -L1 (lazy mode) 230 - - 404.4 196.2 663.8 679.6 217 (20% lost) (2% lost) 218 219 -Tnull -L0 (legacy mode) 230 5.6 7.4 197.3 4.7 610.8 323.5 220 221 [Note: Throughput measured over 300 seconds to get better resolution] 222 223 224 Situation 3: 225 Laptop -> Wifi+vpn / wired -> Home server 226 iodine iodined 227 228 downstr. upstream downstr. ping-up ping-down 229 fragsize kbit/s kbit/s avg +/-mdev avg +/-mdev 230 ------------------------------------------------------------------------------ 231 232 wifi + openvpn -Tnull 1186 183.5 611.6 5.7 1.4 7.0 2.7 233 234 wired -Tnull 1186 685.9 2350.5 1.3 0.1 1.4 0.4 235 236 237 Performance is strongly coupled to low ping times, as iodine requires 238 confirmation for every data fragment before moving on to the next. Allowing 239 multiple fragments in-flight like TCP could possibly increase performance, 240 but it would likely cause serious overload for the intermediary DNS servers. 241 The current protocol scales performance with DNS responsivity, since the 242 DNS servers are on average handling at most one DNS request per client. 117 243 118 244 -
doc/proto_00000501.txt
r3940f4 reb0bf4 83 83 Server may disregard this option; client must always use the downstream 84 84 encoding type indicated in every downstream DNS packet. 85 86 l or L: Lazy mode, server will keep one request unanswered until the 87 next one comes in. Applies only to data transfer; handshake is always 88 answered immediately. 89 i or I: Immediate (non-lazy) mode, server will answer all requests 90 (nearly) immediately. 85 91 86 92 Probe downstream fragment size: … … 161 167 If server has something to send, it will send a downstream data packet, 162 168 prefixed with 2 bytes header as shown above. 169 170 171 "Lazy-mode" operation 172 ===================== 173 174 Client-server DNS traffic sequence has been reordered to provide increased 175 (interactive) performance and greatly reduced latency. 176 177 Idea taken from Lucas Nussbaum's slides (24th IFIP International Security 178 Conference, 2009) at http://www.loria.fr/~lnussbau/tuns.html. Current 179 implementation is original to iodine, no code or documentation from any other 180 project was consulted during development. 181 182 Server: 183 Upstream data is acked immediately*, to keep the slow upstream data flowing 184 as fast as possible (client waits for ack to send next frag). 185 186 Upstream pings are answered _only_ when 1) downstream data arrives from tun, 187 OR 2) new upstream ping/data arrives from client. 188 In most cases, this means we answer the previous DNS query instead of the 189 current one. The current query is kept in queue and used as soon as 190 downstream data has to be sent. 191 192 *: upstream data ack is usually done as reply on the previous ping packet, 193 and the upstream-data packet itself is kept in queue. 194 195 Client: 196 Downstream data is acked immediately, to keep it flowing fast (includes a 197 ping after last downstream frag). 198 199 Also, after all available upstream data is sent & acked by the server (which 200 in some cases uses up the last query), send an additional ping to prime the 201 server for the next downstream data. 163 202 164 203 -
src/common.c
r7ca260 reb0bf4 334 334 #endif 335 335 336 337 int recent_seqno(int ourseqno, int gotseqno) 338 /* Return 1 if we've seen gotseqno recently (current or up to 3 back). 339 Return 0 if gotseqno is new (or very old). 340 */ 341 { 342 int i; 343 for (i = 0; i < 4; i++, ourseqno--) { 344 if (ourseqno < 0) 345 ourseqno = 7; 346 if (gotseqno == ourseqno) 347 return 1; 348 } 349 return 0; 350 } -
src/common.h
r2c3fdf reb0bf4 89 89 unsigned short type; 90 90 unsigned short id; 91 unsigned short iddupe; /* only used for dupe checking */ 91 92 struct in_addr destination; 92 93 struct sockaddr from; … … 122 123 #endif 123 124 125 int recent_seqno(int , int); 126 124 127 #endif
Note: See TracChangeset
for help on using the changeset viewer.
