Bug #11443
Updated by nemski (Patrick Robinson) over 9 years ago
On linux /etc/resolv.conf can be configured to set the timeout of a nameserver before trying the next one (defaults to 5 seconds). So in the event of a failed name server we expect the time taken to resolve a hostname will be timeout + query time. However testing shows it takes (2 * timeout) + query time. Example resolv.conf to replicate the problem of a failed name server: ~~~ nameserver 1.1.1.1 nameserver 8.8.8.8 nameserver 8.8.4.4 ~~~ Example ruby code to test: ``` require 'net/protocol' require 'uri' require 'benchmark' uri = URI.parse("http://google.com") Benchmark.measure { TCPSocket.new(uri.host, uri.port) }.real ``` Example benchmark with a above resolv.conf: ``` irb(main):005:0> Benchmark.measure { TCPSocket.new(uri.host, uri.port) }.real => 10.593100978 ``` Example benchmark with timeout set to 3 in resolv.conf (options timeout:3): ``` irb(main):005:0> Benchmark.measure { TCPSocket.new(uri.host, uri.port) }.real => 6.262138267 ``` and without the invalid nameserver: ``` irb(main):005:0> Benchmark.measure { TCPSocket.new(uri.host, uri.port) }.real => 0.243385728 ``` Example C code that proves the resolver is behaving as expected: ``` #include <stdio.h> #include <netdb.h> int main(int argc, char *argv[]) { struct hostent *hstnm; if (argc != 2) { fprintf(stderr, "usage: %s hostname\n", argv[0]); return 1; } hstnm = gethostbyname (argv[1]); if (!hstnm) return 1; printf ("Name: %s\n", hstnm->h_name); return 0; } ``` Benchmark of C code with failed nameserver: ~~~ $ time ./gethostbyname google.com Name: google.com real 0m5.189s user 0m0.000s sys 0m0.000s ~~~ Benchmark of C code without failed nameserver: ~~~ $ time ./gethostbyname google.com Name: google.com real 0m0.040s user 0m0.000s sys 0m0.000s ~~~