Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 6413 | ||||||||
Proposed branch: | lp:~ptman/hipl/nonetwork | ||||||||
Merge into: | lp:hipl | ||||||||
Diff against target: |
576 lines (+237/-228) 5 files modified
debian/hipl-dnsproxy.config (+3/-3) debian/hipl-dnsproxy.postinst (+0/-14) tools/hipdnsproxy/dnsproxy.py (+223/-204) tools/hipdnsproxy/resolvconf.py (+2/-3) tools/hipdnsproxy/resolvconf_test.py (+9/-4) |
||||||||
To merge this branch: | bzr merge lp:~ptman/hipl/nonetwork | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Miika Komu | Approve | ||
Review via email: mp+165785@code.launchpad.net |
Commit message
Description of the change
Fixes problems with hipdnsproxy when network is not present or changes.
Please comment before Friday 31st.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/hipl-dnsproxy.config' |
2 | --- debian/hipl-dnsproxy.config 2013-03-06 14:07:36 +0000 |
3 | +++ debian/hipl-dnsproxy.config 2013-05-26 15:39:25 +0000 |
4 | @@ -2,7 +2,7 @@ |
5 | |
6 | . /usr/share/debconf/confmodule |
7 | |
8 | -if pidof dnsmasq; then |
9 | - db_input high hipl-dnsproxy/dnsmasq |
10 | - db_go |
11 | +if pidof dnsmasq > /dev/null; then |
12 | + db_input high hipl-dnsproxy/dnsmasq || true |
13 | + db_go || true |
14 | fi |
15 | |
16 | === modified file 'debian/hipl-dnsproxy.postinst' |
17 | --- debian/hipl-dnsproxy.postinst 2013-02-22 15:16:12 +0000 |
18 | +++ debian/hipl-dnsproxy.postinst 2013-05-26 15:39:25 +0000 |
19 | @@ -8,18 +8,4 @@ |
20 | # Default run level (20) is problematic with hipl-dnsproxy in Ubuntu Lucid. |
21 | # Note: $bind did not entirely solve the problem (see lp:845677). |
22 | update-rc.d hipl-dnsproxy defaults 40 60 >/dev/null |
23 | - |
24 | - if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ]; then |
25 | - if [ -e /var/run/hipdnsproxy.pid ]; then |
26 | - ACTION=restart |
27 | - else |
28 | - ACTION=start |
29 | - fi |
30 | - |
31 | - if [ -x /usr/sbin/invoke-rc.d ] ; then |
32 | - invoke-rc.d hipl-dnsproxy $ACTION || true |
33 | - else |
34 | - /etc/init.d/hipl-dnsproxy $ACTION || true |
35 | - fi |
36 | - fi |
37 | fi |
38 | |
39 | === modified file 'tools/hipdnsproxy/dnsproxy.py' |
40 | --- tools/hipdnsproxy/dnsproxy.py 2013-02-22 15:16:12 +0000 |
41 | +++ tools/hipdnsproxy/dnsproxy.py 2013-05-26 15:39:25 +0000 |
42 | @@ -310,7 +310,8 @@ |
43 | logging.error('Error opening pid file: %s', ioe) |
44 | sys.exit(1) |
45 | ifile.readline() |
46 | - myid = ifile.readline().rstrip() |
47 | + global MYID |
48 | + MYID = ifile.readline().rstrip() |
49 | ifile.close() |
50 | self.resolvconf.restore() |
51 | |
52 | @@ -458,9 +459,13 @@ |
53 | |
54 | self.parameter_defaults() |
55 | |
56 | + if self.server_ip is None: |
57 | + logging.critical('No upstream DNS server, exiting...') |
58 | + return |
59 | + |
60 | # Default virtual interface and address for dnsproxy to |
61 | # avoid problems with other dns forwarders (e.g. dnsmasq) |
62 | - os.system("ifconfig lo:53 %s" % (self.bind_ip,)) |
63 | + os.system('ifconfig lo:53 %s' % (self.bind_ip,)) |
64 | |
65 | servsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
66 | try: |
67 | @@ -487,224 +492,238 @@ |
68 | |
69 | self.write_local_hits_to_hosts() |
70 | |
71 | + query_id = 1 |
72 | + |
73 | util.init_wantdown() |
74 | - util.init_wantdown_int() # Keyboard interrupts |
75 | - |
76 | - if self.server_ip.find(':') == -1: |
77 | - server_family = socket.AF_INET |
78 | - else: |
79 | - server_family = socket.AF_INET6 |
80 | - clisock = socket.socket(server_family, socket.SOCK_DGRAM) |
81 | - clisock.settimeout(self.dns_timeout) |
82 | - try: |
83 | - clisock.connect((self.server_ip, self.server_port)) |
84 | - connected = True |
85 | - except socket.error: |
86 | - connected = False |
87 | - |
88 | - query_id = 1 |
89 | + util.init_wantdown_int() # Keyboard interrupts |
90 | |
91 | while not util.wantdown(): |
92 | + logging.info('Connecting to upstream DNS server...') |
93 | + if ':' not in self.server_ip: |
94 | + server_family = socket.AF_INET |
95 | + else: |
96 | + server_family = socket.AF_INET6 |
97 | + clisock = socket.socket(server_family, socket.SOCK_DGRAM) |
98 | + clisock.settimeout(self.dns_timeout) |
99 | try: |
100 | - self.hosts_recheck() |
101 | - |
102 | - if connected: |
103 | - rlist, _, _ = select.select([servsock, clisock], [], [], |
104 | - 5.0) |
105 | - else: |
106 | - rlist, _, _ = select.select([servsock], [], [], 5.0) |
107 | - self.clean_queries() |
108 | - if servsock in rlist: # Incoming DNS request |
109 | - inbuf, from_a = servsock.recvfrom(2048) |
110 | - |
111 | - packet = DeSerialize(inbuf).get_dict() |
112 | - qtype = packet['questions'][0][1] |
113 | - |
114 | - sent_answer = False |
115 | - |
116 | - if qtype in (1, 28, 12): |
117 | - if self.hip_cache_lookup(packet): |
118 | + clisock.connect((self.server_ip, self.server_port)) |
119 | + connected = True |
120 | + logging.debug('... connected!') |
121 | + except socket.error: |
122 | + logging.error('Connecting to upstream DNS server failed!') |
123 | + time.sleep(3) |
124 | + connected = False |
125 | + |
126 | + while connected and (not util.wantdown()): |
127 | + try: |
128 | + self.hosts_recheck() |
129 | + |
130 | + if connected: |
131 | + rlist, _, _ = select.select([servsock, clisock], [], [], |
132 | + 5.0) |
133 | + else: |
134 | + rlist, _, _ = select.select([servsock], [], [], 5.0) |
135 | + self.clean_queries() |
136 | + if servsock in rlist: # Incoming DNS request |
137 | + inbuf, from_a = servsock.recvfrom(2048) |
138 | + |
139 | + packet = DeSerialize(inbuf).get_dict() |
140 | + qtype = packet['questions'][0][1] |
141 | + |
142 | + sent_answer = False |
143 | + |
144 | + if qtype in (1, 28, 12): |
145 | + if self.hip_cache_lookup(packet): |
146 | + try: |
147 | + outbuf = Serialize(packet).get_packet() |
148 | + servsock.sendto(outbuf, from_a) |
149 | + sent_answer = True |
150 | + except socket.error: |
151 | + logging.exception('Exception:') |
152 | + elif (self.prefix and |
153 | + packet['questions'][0][0].startswith( |
154 | + self.prefix)): |
155 | + # Query with HIP prefix for unsupported RR type. |
156 | + # Send empty response. |
157 | + packet['qr'] = 1 |
158 | try: |
159 | outbuf = Serialize(packet).get_packet() |
160 | servsock.sendto(outbuf, from_a) |
161 | sent_answer = True |
162 | except socket.error: |
163 | logging.exception('Exception:') |
164 | - elif (self.prefix and |
165 | - packet['questions'][0][0].startswith(self.prefix)): |
166 | - # Query with HIP prefix for unsupported RR type. |
167 | - # Send empty response. |
168 | - packet['qr'] = 1 |
169 | - try: |
170 | - outbuf = Serialize(packet).get_packet() |
171 | - servsock.sendto(outbuf, from_a) |
172 | - sent_answer = True |
173 | - except socket.error: |
174 | - logging.exception('Exception:') |
175 | - |
176 | - if connected and not sent_answer: |
177 | - logging.info('Query type %d for %s from %s', |
178 | - qtype, packet['questions'][0][0], |
179 | - (self.server_ip, self.server_port)) |
180 | - |
181 | - query = (packet, from_a[0], from_a[1], qtype) |
182 | - # FIXME: Should randomize for security |
183 | - query_id = (query_id % 65535) + 1 |
184 | - pckt = copy.copy(packet) |
185 | - pckt['id'] = query_id |
186 | - if ((qtype == 28 or |
187 | - (qtype == 1 and not self.disable_lsi)) and not |
188 | - is_reverse_hit_query(packet['questions'][0][0])): |
189 | - |
190 | - if not self.prefix: |
191 | - pckt['questions'][0][1] = 55 |
192 | - if (self.prefix and |
193 | - pckt['questions'][0][0].startswith( |
194 | - self.prefix)): |
195 | - pckt['questions'][0][0] = pckt[ |
196 | - 'questions'][0][0][len(self.prefix):] |
197 | - pckt['questions'][0][1] = 55 |
198 | - |
199 | - if qtype == 12 and not self.disable_lsi: |
200 | + |
201 | + if connected and not sent_answer: |
202 | + logging.info('Query type %d for %s from %s', |
203 | + qtype, packet['questions'][0][0], |
204 | + (self.server_ip, self.server_port)) |
205 | + |
206 | + query = (packet, from_a[0], from_a[1], qtype) |
207 | + # FIXME: Should randomize for security |
208 | + query_id = (query_id % 65535) + 1 |
209 | + pckt = copy.copy(packet) |
210 | + pckt['id'] = query_id |
211 | + if ((qtype == 28 or |
212 | + (qtype == 1 and not self.disable_lsi)) and not |
213 | + is_reverse_hit_query( |
214 | + packet['questions'][0][0])): |
215 | + |
216 | + if not self.prefix: |
217 | + pckt['questions'][0][1] = 55 |
218 | + if (self.prefix and |
219 | + pckt['questions'][0][0].startswith( |
220 | + self.prefix)): |
221 | + pckt['questions'][0][0] = pckt[ |
222 | + 'questions'][0][0][len(self.prefix):] |
223 | + pckt['questions'][0][1] = 55 |
224 | + |
225 | + if qtype == 12 and not self.disable_lsi: |
226 | + qname = packet['questions'][0][0] |
227 | + addr_str = hosts.ptr_to_addr(qname) |
228 | + if (addr_str is not None and |
229 | + hosts.valid_lsi(addr_str)): |
230 | + query = (packet, from_a[0], from_a[1], |
231 | + qname) |
232 | + hit_str = lsi_to_hit(addr_str) |
233 | + if hit_str is not None: |
234 | + pckt['questions'][0][0] = \ |
235 | + hosts.addr_to_ptr(hit_str) |
236 | + |
237 | + outbuf = Serialize(pckt).get_packet() |
238 | + clisock.sendto(outbuf, (self.server_ip, |
239 | + self.server_port)) |
240 | + |
241 | + self.add_query(self.server_ip, self.server_port, |
242 | + query_id, query) |
243 | + |
244 | + if connected and clisock in rlist: # Incoming DNS reply |
245 | + inbuf, from_a = clisock.recvfrom(2048) |
246 | + logging.info('Packet from DNS server %d bytes from %s', |
247 | + len(inbuf), from_a) |
248 | + packet = DeSerialize(inbuf).get_dict() |
249 | + |
250 | + # Find original query |
251 | + query_id_o = packet['id'] |
252 | + query_o = self.find_query(from_a[0], from_a[1], |
253 | + query_id_o) |
254 | + if query_o: |
255 | qname = packet['questions'][0][0] |
256 | - addr_str = hosts.ptr_to_addr(qname) |
257 | - if (addr_str is not None and |
258 | - hosts.valid_lsi(addr_str)): |
259 | - query = (packet, from_a[0], from_a[1], qname) |
260 | - hit_str = lsi_to_hit(addr_str) |
261 | - if hit_str is not None: |
262 | - pckt['questions'][0][0] = \ |
263 | - hosts.addr_to_ptr(hit_str) |
264 | - |
265 | - outbuf = Serialize(pckt).get_packet() |
266 | - clisock.sendto(outbuf, (self.server_ip, |
267 | - self.server_port)) |
268 | - |
269 | - self.add_query(self.server_ip, self.server_port, |
270 | - query_id, query) |
271 | - |
272 | - if connected and clisock in rlist: # Incoming DNS reply |
273 | - inbuf, from_a = clisock.recvfrom(2048) |
274 | - logging.info('Packet from DNS server %d bytes from %s', |
275 | - len(inbuf), from_a) |
276 | - packet = DeSerialize(inbuf).get_dict() |
277 | - |
278 | - # Find original query |
279 | - query_id_o = packet['id'] |
280 | - query_o = self.find_query(from_a[0], from_a[1], query_id_o) |
281 | - if query_o: |
282 | - qname = packet['questions'][0][0] |
283 | - qtype = packet['questions'][0][1] |
284 | - send_reply = True |
285 | - query_again = False |
286 | - hit_found = False |
287 | - packet_o = query_o[0] |
288 | - # Replace with the original query id |
289 | - packet['id'] = packet_o['id'] |
290 | - |
291 | - if qtype == 55 and query_o[3] in (1, 28): |
292 | - # Restore qtype |
293 | - packet['questions'][0][1] = query_o[3] |
294 | - self.hip_lookup(packet) |
295 | - if packet['ancount'] > 0: |
296 | - hit_found = True |
297 | - if (not self.prefix or |
298 | - (hit_found and not (self.getaaaa(qname) or |
299 | - self.geta(qname)))): |
300 | - query_again = True |
301 | - send_reply = False |
302 | - elif self.prefix: |
303 | - hit_found = True |
304 | - packet['questions'][0][0] = ( |
305 | - self.prefix + packet['questions'][0][0]) |
306 | - for answer in packet['answers']: |
307 | - answer[0] = self.prefix + answer[0] |
308 | - |
309 | - elif qtype in (1, 28): |
310 | - hit = self.getaaaa_hit(qname) |
311 | - ip6 = self.getaaaa(qname) |
312 | - ip4 = self.geta(qname) |
313 | - for answer in packet['answers']: |
314 | - if answer[1] in (1, 28): |
315 | - self.cache_name(qname, answer[4], |
316 | - answer[3]) |
317 | - if hit is not None: |
318 | - for answer in packet['answers']: |
319 | - if (answer[1] == 1 or |
320 | - (answer[1] == 28 and not |
321 | - hosts.valid_hit(answer[4]))): |
322 | - add_hit_ip_map(hit[0], answer[4]) |
323 | - # Reply with HIT/LSI once it's been mapped to |
324 | - # an IP |
325 | - if ip6 is None and ip4 is None: |
326 | - if (packet_o['ancount'] == 0 and |
327 | - not self.prefix): |
328 | - # No LSI available. Return IPv4 |
329 | - tmp = packet['answers'] |
330 | - packet = packet_o |
331 | - packet['answers'] = tmp |
332 | - packet['ancount'] = len( |
333 | - packet['answers']) |
334 | - else: |
335 | - packet = packet_o |
336 | - if self.prefix: |
337 | - packet['questions'][0][0] = \ |
338 | + qtype = packet['questions'][0][1] |
339 | + send_reply = True |
340 | + query_again = False |
341 | + hit_found = False |
342 | + packet_o = query_o[0] |
343 | + # Replace with the original query id |
344 | + packet['id'] = packet_o['id'] |
345 | + |
346 | + if qtype == 55 and query_o[3] in (1, 28): |
347 | + # Restore qtype |
348 | + packet['questions'][0][1] = query_o[3] |
349 | + self.hip_lookup(packet) |
350 | + if packet['ancount'] > 0: |
351 | + hit_found = True |
352 | + if (not self.prefix or |
353 | + (hit_found and not (self.getaaaa(qname) or |
354 | + self.geta(qname)))): |
355 | + query_again = True |
356 | + send_reply = False |
357 | + elif self.prefix: |
358 | + hit_found = True |
359 | + packet['questions'][0][0] = ( |
360 | + self.prefix + packet['questions'][0][0]) |
361 | + for answer in packet['answers']: |
362 | + answer[0] = self.prefix + answer[0] |
363 | + |
364 | + elif qtype in (1, 28): |
365 | + hit = self.getaaaa_hit(qname) |
366 | + ip6 = self.getaaaa(qname) |
367 | + ip4 = self.geta(qname) |
368 | + for answer in packet['answers']: |
369 | + if answer[1] in (1, 28): |
370 | + self.cache_name(qname, answer[4], |
371 | + answer[3]) |
372 | + if hit is not None: |
373 | + for answer in packet['answers']: |
374 | + if (answer[1] == 1 or |
375 | + (answer[1] == 28 and not |
376 | + hosts.valid_hit(answer[4]))): |
377 | + add_hit_ip_map(hit[0], answer[4]) |
378 | + # Reply with HIT/LSI once it's been mapped |
379 | + # to an IP |
380 | + if ip6 is None and ip4 is None: |
381 | + if (packet_o['ancount'] == 0 and |
382 | + not self.prefix): |
383 | + # No LSI available. Return IPv4 |
384 | + tmp = packet['answers'] |
385 | + packet = packet_o |
386 | + packet['answers'] = tmp |
387 | + packet['ancount'] = len( |
388 | + packet['answers']) |
389 | + else: |
390 | + packet = packet_o |
391 | + if self.prefix: |
392 | + packet['questions'][0][0] = \ |
393 | (self.prefix + |
394 | packet['questions'][0][0]) |
395 | - for answer in packet['answers']: |
396 | - answer[0] = (self.prefix + |
397 | - answer[0]) |
398 | - else: |
399 | + for answer in packet['answers']: |
400 | + answer[0] = (self.prefix + |
401 | + answer[0]) |
402 | + else: |
403 | + send_reply = False |
404 | + elif query_o[3] == 0: |
405 | + # Prefix is in use |
406 | + # IP was queried for cache only |
407 | send_reply = False |
408 | - elif query_o[3] == 0: |
409 | - # Prefix is in use |
410 | - # IP was queried for cache only |
411 | - send_reply = False |
412 | - |
413 | - elif qtype == 12 and isinstance(query_o[3], str): |
414 | - packet['questions'][0][0] = query_o[3] |
415 | - for answer in packet['answers']: |
416 | - answer[0] = query_o[3] |
417 | - |
418 | - if query_again: |
419 | - if hit_found: |
420 | - qtypes = [28, 1] |
421 | - pckt = copy.deepcopy(packet) |
422 | - else: |
423 | - qtypes = [query_o[3]] |
424 | - pckt = copy.copy(packet) |
425 | - pckt['qr'] = 0 |
426 | - pckt['answers'] = [] |
427 | - pckt['ancount'] = 0 |
428 | - pckt['nslist'] = [] |
429 | - pckt['nscount'] = 0 |
430 | - pckt['additional'] = [] |
431 | - pckt['arcount'] = 0 |
432 | - for qtype in qtypes: |
433 | - if self.prefix: |
434 | - query = (packet, query_o[1], query_o[2], 0) |
435 | + |
436 | + elif qtype == 12 and isinstance(query_o[3], str): |
437 | + packet['questions'][0][0] = query_o[3] |
438 | + for answer in packet['answers']: |
439 | + answer[0] = query_o[3] |
440 | + |
441 | + if query_again: |
442 | + if hit_found: |
443 | + qtypes = [28, 1] |
444 | + pckt = copy.deepcopy(packet) |
445 | else: |
446 | - query = (packet, query_o[1], query_o[2], |
447 | - qtype) |
448 | - query_id = (query_id % 65535) + 1 |
449 | - pckt['id'] = query_id |
450 | - pckt['questions'][0][1] = qtype |
451 | - outbuf = Serialize(pckt).get_packet() |
452 | - clisock.sendto(outbuf, (self.server_ip, |
453 | - self.server_port)) |
454 | - self.add_query(self.server_ip, |
455 | - self.server_port, |
456 | - query_id, query) |
457 | - packet['questions'][0][1] = query_o[3] |
458 | + qtypes = [query_o[3]] |
459 | + pckt = copy.copy(packet) |
460 | + pckt['qr'] = 0 |
461 | + pckt['answers'] = [] |
462 | + pckt['ancount'] = 0 |
463 | + pckt['nslist'] = [] |
464 | + pckt['nscount'] = 0 |
465 | + pckt['additional'] = [] |
466 | + pckt['arcount'] = 0 |
467 | + for qtype in qtypes: |
468 | + if self.prefix: |
469 | + query = (packet, query_o[1], query_o[2], |
470 | + 0) |
471 | + else: |
472 | + query = (packet, query_o[1], query_o[2], |
473 | + qtype) |
474 | + query_id = (query_id % 65535) + 1 |
475 | + pckt['id'] = query_id |
476 | + pckt['questions'][0][1] = qtype |
477 | + outbuf = Serialize(pckt).get_packet() |
478 | + clisock.sendto(outbuf, (self.server_ip, |
479 | + self.server_port)) |
480 | + self.add_query(self.server_ip, |
481 | + self.server_port, |
482 | + query_id, query) |
483 | + packet['questions'][0][1] = query_o[3] |
484 | |
485 | - if send_reply: |
486 | - outbuf = Serialize(packet).get_packet() |
487 | - servsock.sendto(outbuf, (query_o[1], query_o[2])) |
488 | - except (select.error, OSError), exc: |
489 | - if exc[0] == errno.EINTR: |
490 | - pass |
491 | - else: |
492 | - logging.exception('Exception:') |
493 | + if send_reply: |
494 | + outbuf = Serialize(packet).get_packet() |
495 | + servsock.sendto(outbuf, (query_o[1], |
496 | + query_o[2])) |
497 | + except (select.error, OSError), exc: |
498 | + if exc[0] == errno.EINTR: |
499 | + pass |
500 | + else: |
501 | + logging.exception('Exception:') |
502 | + except socket.error, exc: |
503 | + logging.info('Connection to upstream DNS server lost') |
504 | + connected = False |
505 | |
506 | logging.info('Wants down') |
507 | self.resolvconf.restore() |
508 | |
509 | === modified file 'tools/hipdnsproxy/resolvconf.py' |
510 | --- tools/hipdnsproxy/resolvconf.py 2013-03-24 10:07:13 +0000 |
511 | +++ tools/hipdnsproxy/resolvconf.py 2013-05-26 15:39:25 +0000 |
512 | @@ -93,7 +93,7 @@ |
513 | self.mtime = None |
514 | self.config = None |
515 | |
516 | - if isinstance(ResolvConf.FRAGMENT_DIR, list): |
517 | + if self.using_resolvconf and isinstance(ResolvConf.FRAGMENT_DIR, list): |
518 | ResolvConf.FRAGMENT_DIR = filter(os.path.exists, |
519 | ResolvConf.FRAGMENT_DIR)[0] |
520 | |
521 | @@ -242,8 +242,7 @@ |
522 | ResolvConf.DEFAULT_BIND_ADDR] |
523 | if nameservers: |
524 | return nameservers[0] |
525 | - else: |
526 | - return '8.8.8.8' # Google Public DNS, fallback |
527 | + return '8.8.8.8' # Google Public DNS, fallback |
528 | |
529 | @nameserver.setter |
530 | def nameserver(self, nameserver): |
531 | |
532 | === modified file 'tools/hipdnsproxy/resolvconf_test.py' |
533 | --- tools/hipdnsproxy/resolvconf_test.py 2012-12-31 14:54:20 +0000 |
534 | +++ tools/hipdnsproxy/resolvconf_test.py 2013-05-26 15:39:25 +0000 |
535 | @@ -33,8 +33,8 @@ |
536 | # resolv.conf |
537 | domain example.com |
538 | search example.com |
539 | +nameserver 8.8.4.4 |
540 | nameserver 8.8.8.8 |
541 | -nameserver 8.8.4.4 |
542 | ''' |
543 | |
544 | INVALID_RESOLV_CONF = ''' |
545 | @@ -54,7 +54,7 @@ |
546 | conf = rc.config |
547 | self.assertEqual(conf['domain'], 'example.com') |
548 | self.assertEqual(conf['search'], ['example.com']) |
549 | - self.assertEqual(conf['nameserver'], ['8.8.8.8', '8.8.4.4']) |
550 | + self.assertEqual(conf['nameserver'], ['8.8.4.4', '8.8.8.8']) |
551 | |
552 | def dont_test_parse_invalid_file(self): |
553 | rc = resolvconf.ResolvConf() |
554 | @@ -76,15 +76,20 @@ |
555 | rc.resolvconf = True |
556 | rc.config = {'domain': 'example.com', |
557 | 'search': ['example.com', 'example.net'], |
558 | - 'nameserver': ['8.8.8.8', '8.8.4.4']} |
559 | + 'nameserver': ['8.8.4.4', '8.8.8.8']} |
560 | rc.resolvconf_add = lambda x: None |
561 | ofile = StringIO.StringIO() |
562 | rc.write_file(ofile) |
563 | out = ofile.getvalue() |
564 | self.assertTrue('domain example.com' in out) |
565 | self.assertTrue('search example.com example.net' in out) |
566 | + self.assertTrue('nameserver 8.8.4.4' in out) |
567 | self.assertTrue('nameserver 8.8.8.8' in out) |
568 | - self.assertTrue('nameserver 8.8.4.4' in out) |
569 | + |
570 | + def test_prop_nameserver_noconfig(self): |
571 | + rc = resolvconf.ResolvConf() |
572 | + rc.parse_file(StringIO.StringIO('')) |
573 | + self.assertEqual(rc.nameserver, '8.8.8.8') |
574 | |
575 | |
576 | if __name__ == '__main__': |
As described in related the bug report, I have tested the branch. I suggest merging it on Friday unless there are other comments.
Writing of the main loop should be a separate task for somebody. The DNS proxy has been defunctional for far too long on Ubuntu systems, so this should be merged asap.
Thanks for the great work!