Должна ли служба UDP отвечать с подключенного IP-адреса?

StackOverflow https://stackoverflow.com/questions/1309370

Вопрос

Пызор использует UDP/IP в качестве протокола связи.Недавно мы переключили общедоступный сервер на новую машину и начали получать сообщения о множестве тайм-аутов.Я обнаружил, что могу решить проблему, если изменю IP-адрес, запрошенный с eth0:1 к eth0.

Я могу воспроизвести эту проблему на простом примере:

Это код сервера:

#! /usr/bin/env python

import SocketServer

class RequestHandler(SocketServer.DatagramRequestHandler):
    def handle(self):
        print self.packet
        self.wfile.write("Pong")

s = SocketServer.UDPServer(("0.0.0.0", 24440), RequestHandler)
s.serve_forever()

Это клиентский код (188.40.77.206 является eth0. 188.40.77.236 это тот же сервер, но eth0:1):

>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.sendto('ping', 0, ("188.40.77.206", 24440))
4
>>> s.recvfrom(1024)
('Pong', ('188.40.77.206', 24440))
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.sendto('ping', 0, ("188.40.77.236", 24440))
4
>>> s.recvfrom(1024)
[never gets anything]

Сервер получает пакет «ping» в обоих случаях (и, следовательно, отправляет пакет «pong» в обоих случаях).

Как ни странно, это делает работать из некоторых мест (т.е.Я получу ответ с обоих IP).Например, это работает от 188.40.37.137 (та же сеть/центр обработки данных, другой сервер), но и из 89.18.189.160 (другой датацентр).В этих случаях recvfrom ответ имеет eth0 IP, а не тот, к которому подключался.

Это просто правило UDP?Это проблема/ограничение с Питон UDPServer сорт?Это что-то я делаю неправильно?Есть ли какой-нибудь способ выполнить эту работу, кроме простого подключения к eth0 IP (или прослушивание конкретного IP, а не 0.0.0.0)?

Это было полезно?

Решение

Я столкнулся с этим с TFTP-сервером.У моего сервера было два IP-адреса, обращенных к одной и той же сети.Поскольку UDP не поддерживает соединение, в этой ситуации могут возникнуть проблемы с IP-адресами, установленными не так, как ожидалось.Последовательность у меня была такая:

  1. Клиент отправляет первоначальный пакет на сервер по определенному IP-адресу.
  2. Сервер считывает исходный адрес клиента из входящего пакета и отправляет ответ.
    1. Однако в ответе «исходный адрес» сервера устанавливается в соответствии с таблицами маршрутизации и ему присваивается значение другой Айпи адрес.
    2. Невозможно было контролировать «исходный» IP-адрес сервера, поскольку ОС не сообщала нам, через какой IP-адрес пришел запрос.
  3. Клиент получает ответ от «другого» IP-адреса и отклоняет его.

Решением в моем случае было специально привязать TFTP-сервер к IP-адресу, который я хотел прослушивать, а не привязывать ко всем интерфейсам.

Я нашел текст, который может иметь отношение к Справочная страница Linux для tftpd (TFTP-сервер).Вот:

 Unfortunately, on multi-homed systems, it is impossible for tftpd to
 determine the address on which a packet was received. As a result, tftpd
 uses two different mechanisms to guess the best source address to use for
 replies. If the socket that inetd(8) passed to tftpd is bound to a par‐
 ticular address, tftpd uses that address for replies. Otherwise, tftpd
 uses ‘‘UDP connect’’ to let the kernel choose the reply address based on
 the destination of the replies and the routing tables. This means that
 most setups will work transparently, while in cases where the reply
 address must be fixed, the virtual hosting feature of inetd(8) can be
 used to ensure that replies go out from the correct address.  These con‐
 siderations are important, because most tftp clients will reject reply
 packets that appear to come from an unexpected address.

Видеть этот ответ который показывает, что в Linux это является можно прочитать локальный адрес для входящих UDP-пакетов и установить его для исходящих пакетов.Это возможно в C;Хотя я не уверен насчет Python.

Другие советы

Это просто правило UDP?

Нет.

Это проблема/ограничение с классом Python Udpserver?

Сомнительно.

Это что-то я делаю неправильно?

Ваша программа выглядит правильно.

Существует множество причин, по которым дейтаграмма не доходит до сервера.UDP не поддерживает соединение, поэтому ваш клиент просто отправляет пинг в эфир, не зная, получил ли его кто-нибудь.

Посмотрите, разрешено ли вам привязываться к этому адресу.Есть замечательная маленькая программа под названием netcat, которая отлично подходит для низкоуровневого доступа к сети.Он не всегда доступен в каждой системе, но его легко загрузить и скомпилировать.

nc -l -s 188.40.77.236 -p 24440 -u

Если вы запустите клиентскую программу, как и раньше, вы должны увидеть на своем терминале надпись «Ping».(Вы можете ввести Pong и вернуть его своему клиенту.С этим весело играть.) Если вы получаете пинг, значит, проблемы с сетью не являются проблемой, а что-то не так с серверной программой или библиотеками Python.Если вы не получите пинг, вы не сможете установить соединение.«Обратитесь за помощью к своему сетевому администратору».

Вещи, которые следует проверить, включают в себя...

  1. Проблемы с брандмауэром?
  2. Проблемы конфигурации с псевдонимами сетевых интерфейсов.
  3. Проблемы с разрешениями пользователей.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top