UDP, Multiple IP Addresses
От: KaktusAgava  
Дата: 24.07.13 03:46
Оценка:
Привет всем.
Есть приложение — UDP сервер (Win, на IOCP, C++). Слушает соединения и отправляет результат с помощью WSASendTo.
Упрощенно это выглядит так:

addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(listen_port);

bind(s, reinterpret_cast<PSOCKADDR>(&addr), sizeof(addr));

...

WSARecvFrom(s, ...); //слушаем

...

WSASendTo(s, ...); //шлем

Все хорошо работает, но возникает проблемка, когда в свойствах TCP/IP прописано несколько IP адресов. Т.е. их, например, два: 192.168.0.10 и 192.168.0.11.
Когда клиент шлет запрос UDP-серверу на IP 192.168.0.10, то респонз обратно шлется с того же IP и все работает хорошо.
А вот когда клиент шлет запрос га IP 192.168.0.11, то респонз обратно шлется с IP 192.168.0.10 и клиент его не видит.
Не подскажете, если кто сталкивался, как это можно побороть? У WSASendTo нету к сож. параметра-ip с которого слать
У него есть только сокет,который слушает все интерфейсы (INADDR_ANY). Надо сделать так, чтобы ответ отправлялся с того же ip, на который пришел запрос.
Re: UDP, Multiple IP Addresses
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 24.07.13 04:38
Оценка:
Здравствуйте, KaktusAgava, Вы писали:

KA>Все хорошо работает, но возникает проблемка, когда в свойствах TCP/IP прописано несколько IP адресов. Т.е. их, например, два: 192.168.0.10 и 192.168.0.11.

KA>Когда клиент шлет запрос UDP-серверу на IP 192.168.0.10, то респонз обратно шлется с того же IP и все работает хорошо.
KA>А вот когда клиент шлет запрос га IP 192.168.0.11, то респонз обратно шлется с IP 192.168.0.10 и клиент его не видит.
KA>Не подскажете, если кто сталкивался, как это можно побороть? У WSASendTo нету к сож. параметра-ip с которого слать
KA>У него есть только сокет,который слушает все интерфейсы (INADDR_ANY). Надо сделать так, чтобы ответ отправлялся с того же ip, на который пришел запрос.

Проблема широко известна. Был бы это Unix, можно было бы решить опциями приёма и отправки.
Но на таких слабых API, как в Windows, единственный вариант — перебрав адреса на интерфейсах, создать на каждый адрес свой отдельный сокет. То есть в Вашем примере первый слушает на 192.168.0.10, второй — на 192.168.0.11 (и ещё один нужен, наверно, и на 127.0.0.1). API перебрать адреса на интерфейсах известно и доступно. Через какой сокет получен запрос, через такой и отправлять ответ.

Для сравнения, ISC named так делает (перебор адресов и по сокету на адрес) по умолчанию, не рассчитывая на конкретные флаворы (опции для этого в BSD, Linux и SysV взаимно несовместимы).
The God is real, unless declared integer.
Re[2]: UDP, Multiple IP Addresses
От: KaktusAgava  
Дата: 24.07.13 04:54
Оценка:
Здравствуйте, netch80, Вы писали:

N>Проблема широко известна. Был бы это Unix, можно было бы решить опциями приёма и отправки.

N>Но на таких слабых API, как в Windows, единственный вариант — перебрав адреса на интерфейсах, создать на каждый адрес свой отдельный сокет. То есть в Вашем примере первый слушает на 192.168.0.10, второй — на 192.168.0.11 (и ещё один нужен, наверно, и на 127.0.0.1). API перебрать адреса на интерфейсах известно и доступно. Через какой сокет получен запрос, через такой и отправлять ответ.

N>Для сравнения, ISC named так делает (перебор адресов и по сокету на адрес) по умолчанию, не рассчитывая на конкретные флаворы (опции для этого в BSD, Linux и SysV взаимно несовместимы).


Это да, можно завести сокет для каждого ip. Но возникают неприятные моменты:

1. Нужно получить как-то все адреса. Пока не знаю как, но наверно решаемо. В принципе, можно заставить пользователя в конфиге перечислить все ip, пока это рабочий вариант.
2. В случае изменения настроек tcp/ip (добавление/удаление ip) нужно не забыть перестартовать сервис (сервер выполнен в виде win-сервиса).
Re[3]: UDP, Multiple IP Addresses
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 24.07.13 07:54
Оценка: 1 (1)
Здравствуйте, KaktusAgava, Вы писали:

KA>Это да, можно завести сокет для каждого ip. Но возникают неприятные моменты:

KA>1. Нужно получить как-то все адреса. Пока не знаю как, но наверно решаемо. В принципе, можно заставить пользователя в конфиге перечислить все ip, пока это рабочий вариант.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365915%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365917%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365949%28v=vs.85%29.aspx

KA>2. В случае изменения настроек tcp/ip (добавление/удаление ip) нужно не забыть перестартовать сервис (сервер выполнен в виде win-сервиса).


Ну он может, например, каждую минуту переспрашивать состав IP.
Я не знаю, есть ли подписка на изменения.
The God is real, unless declared integer.
Re[4]: UDP, Multiple IP Addresses
От: KaktusAgava  
Дата: 24.07.13 08:24
Оценка:
Здравствуйте, netch80, Вы писали:

N>http://msdn.microsoft.com/en-us/library/windows/desktop/aa365915%28v=vs.85%29.aspx

N>http://msdn.microsoft.com/en-us/library/windows/desktop/aa365917%28v=vs.85%29.aspx
N>http://msdn.microsoft.com/en-us/library/windows/desktop/aa365949%28v=vs.85%29.aspx

Спасибо.

У меня возникла еще идея — попытаться определить ip-адрес, на который был отправлен udp пакет, и сделать кэш "исходящих" сокетов. Т.е.:
1. приходит пакет например на 192.168.0.10 -> кэш пустой -> создаем сокет s10 -> добавляем в кэш -> отправляем с него респонз.
2. приходит пакет на 192.168.0.11 -> в кэше сокета нет -> создаем сокет s11 -> добавляем в кэш -> отправляем с него респонз.
3. приходит пакет на 192.168.0.10 -> в кэше есть s10 -> отправляем с него респонз.

Но засада в том, что WSARecvFrom позволяет узнать только С какого ip пакет был отправлен, но не НА какой
Re[5]: UDP, Multiple IP Addresses
От: KaktusAgava  
Дата: 24.07.13 17:21
Оценка:
Здравствуйте, KaktusAgava, Вы писали:

KA>Но засада в том, что WSARecvFrom позволяет узнать только С какого ip пакет был отправлен, но не НА какой


В общем, получилось у меня реализовать свою идею. Вместо WSARecvFrom и WSASendTo пришлось задействовать соответственно WSARecvMsg (есть начиная с XP) и WSASendMsg (есть начиная с Vista).
Re[6]: UDP, Multiple IP Addresses
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 24.07.13 19:35
Оценка:
Здравствуйте, KaktusAgava, Вы писали:

KA>В общем, получилось у меня реализовать свою идею. Вместо WSARecvFrom и WSASendTo пришлось задействовать соответственно WSARecvMsg (есть начиная с XP) и WSASendMsg (есть начиная с Vista).


А примечание в MSDN, что desktop apps only, насколько существенно? У вас же сервис?
The God is real, unless declared integer.
Re[7]: UDP, Multiple IP Addresses
От: KaktusAgava  
Дата: 25.07.13 01:48
Оценка:
Здравствуйте, netch80, Вы писали:

N>А примечание в MSDN, что desktop apps only, насколько существенно? У вас же сервис?


Да. На сервере должно крутиться. Win Server 2008 или 2012.
Хотелось бы, конечно, чтобы и на 2003, но там WSASendMsg нет... Для такого случая сделаю вариант с несколькими сокетами — по одному на ip.
Re[7]: UDP, Multiple IP Addresses
От: Mиxa Украина  
Дата: 26.07.13 06:27
Оценка:
Здравствуйте, netch80, Вы писали:

N>А примечание в MSDN, что desktop apps only, насколько существенно? У вас же сервис?


Нагуглился на stackowerflow.com ответ. А точнее, комментарий к ответу:

"Desktop apps" refers to classic Console, GUI and Services that existed prior to Win8/Metro/Mobile. Metro/Mobile introduced a new API framework that does not apply to classic apps, and restricts some of those classic APIs for apps being migrated to Metro/Mobile.


P.S. Аналогичный вопрос на RSDN
Автор: okman
Дата: 17.03.12
остался без нормального ответа.
Re[3]: UDP, Multiple IP Addresses
От: Mиxa Украина  
Дата: 26.07.13 06:32
Оценка:
Здравствуйте, KaktusAgava, Вы писали:

KA>2. В случае изменения настроек tcp/ip (добавление/удаление ip) нужно не забыть перестартовать сервис (сервер выполнен в виде win-сервиса).


NotifyAddrChange function, ну и далее по Remark'ам, если надо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.