Ruby TCPServer всегда задерживает обратный поиск dns? — как отключить?

#ruby #sockets #tcpserver #reverse-lookup

#ruby #сокеты #tcpserver #обратный поиск

Вопрос:

Я создал TCPServer с ruby gserver.

Каждый раз, когда я удаленно подключаюсь к серверу, требуется 2-4 секунды, пока соединение не будет установлено.

Это происходит только при подключении с удаленного компьютера.

Соединение с того же компьютера, на котором запущена служба, отправит немедленный ответ.

Для соединения на том же компьютере нет разницы, подключаюсь ли я через localhost или через IP-адрес компьютера.


Я думаю, что задержка зависит от обратного поиска, но не могу определить, почему.

в gserver.rb это строка 263

 client = @tcpServer.accept
  

Здесь возникает задержка, я не знаю, что в этом методе.


Я добавил все машины, которые используются во время тестов, в локальный файл hosts. Но это ничего не изменило.

То же самое происходит при использовании Webrick, я попытался установить также

 BasicSocket.do_not_reverse_lookup = true
  

а также прямой доступ к результирующему сокету сервера

 Socket.do_not_reverse_lookup = true
  

а также в сокете клиентского подключения

 client.do_not_reverse_lookup = true
  

Но это также ничего не изменило в отношении задержки.


Всякий раз, когда устанавливается соединение, значения remote_host и remote_ip разрешаются и определяются в файле hosts.


Я попробовал запустить ruby 2.2.1 на ubuntu 14.04, а также ruby 1.9.3 под управлением debian wheezy.

То же поведение — (длительная) задержка при подключении службы.

Вопрос: Как это исправить / отключить поиск на TCPServer?

Комментарии:

1. Я провел тот же тест с webrick — то же поведение, при подключении с пульта дистанционного управления задержка составляет 2-4 секунды.

2. Я также настроил свои системы nsswitch.conf один раз, чтобы использовать только файлы, но опять никакого эффекта — все равно задержка

Ответ №1:

Проблема зависит от моего клиентского компьютера, на котором я запускаю MAC OSX Mav.

Используемый клиент telnet пытается открыть соединение IPv6, а затем IPv4.

Чтобы устранить задержку, просто откройте соединение с

 telnet -4 my-server 3333
  

Я создал небольшой эхо-сервер connect, где вы можете проверять разрешения и тайминги.

Если вы измените NO_REVERSE_LOOKUP, вы получите IP-адреса или адреса, а если это невозможно, разное время отклика.

 require 'socket'

NO_REVERSE_LOOKUP = true
CONNECT_PORT = 3333

puts "#{Time.now} Starting service on port: #{CONNECT_PORT}"

# the full hell - just to test if anything meets what we want
TCPServer.do_not_reverse_lookup = NO_REVERSE_LOOKUP
BasicSocket.do_not_reverse_lookup = NO_REVERSE_LOOKUP
Socket.do_not_reverse_lookup = NO_REVERSE_LOOKUP

srv = TCPServer.open(CONNECT_PORT)

puts "#{Time.now} Waiting for client"

client = srv.accept

puts "#{Time.now} Client connected"

client.do_not_reverse_lookup = NO_REVERSE_LOOKUP

client.print "Hello connectedn"

# in case that we disabled reverse lookup, we should only receive IP Adresses

puts "#{Time.now} Getting server address infos" 

puts "SERVER INFO:"
puts NO_REVERSE_LOOKUP ? client.addr(:numeric) : client.addr(:hostname)

puts ""

puts "#{Time.now} Getting remote client infos"

puts "REMOTE INFO:"
puts NO_REVERSE_LOOKUP ? client.peeraddr(:numeric) : client.peeraddr(:hostname)

###

puts "#{Time.now} Closing connection"

client.close

puts "#{Time.now} End"
  

Спасибо drbrain из #ruby-lang irc за указание мне на проблему IPv6.