Ответ сокета UDP из виртуального интерфейса eth0:0
От: sakhnik Украина http://koresha.org/sakhnik
Дата: 11.11.09 15:09
Оценка:
Господа!

Наткнулся на неприятнй сюрприз. На машине работает физический интерфейс eth0, а также создано ещё одно имя для него eth0:0 в той же подсетке. Некое приложетие привязывается к UDP сокету и отвечает на входные пакеты с IPADDR_ANY. Как оказалось, если пакет приходит с адреса интерфейса eth0:0, сокет почему-то отвечает, заполняя src_addr с eth0. Отсюда начинается куча проблем.

Значит:

client         server
"hello" ------> eth0.0 (192.168.38.2)
        <--X--- eth0 (192.168.38.1)


В чём может быть дело? И как заставить сокет UDP использовать в качестве обратного адрес входящего пакета для отсылки ответа?

Жизнь — это чудо! Только вперёд: sakhnik@jabber.kiev.ua
Re: Ответ сокета UDP из виртуального интерфейса eth0:0
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.11.09 15:41
Оценка:
Здравствуйте, sakhnik, Вы писали:

S>Наткнулся на неприятнй сюрприз. На машине работает физический интерфейс eth0, а также создано ещё одно имя для него eth0:0 в той же подсетке. Некое приложетие привязывается к UDP сокету и отвечает на входные пакеты с IPADDR_ANY. Как оказалось, если пакет приходит с адреса интерфейса eth0:0, сокет почему-то отвечает, заполняя src_addr с eth0. Отсюда начинается куча проблем.


S>Значит:


S>
S>client         server
S>"hello" ------> eth0.0 (192.168.38.2)
S>        <--X--- eth0 (192.168.38.1)
S>


S>В чём может быть дело? И как заставить сокет UDP использовать в качестве обратного адрес входящего пакета для отсылки ответа?


Кроссплатформенно это решается только созданием отдельного UDP сокета на каждый локальный IP. Так делают named, ntpd и прочие.

В BSD есть опции IP_RECVDSTADDR и IP_SENDSRCADDR, но авторы Linux решили, что это моветон, но замены не дали.
The God is real, unless declared integer.
Re[2]: Ответ сокета UDP из виртуального интерфейса eth0:0
От: sakhnik Украина http://koresha.org/sakhnik
Дата: 12.11.09 16:48
Оценка:
Здравствуйте, netch80, Вы писали:

N>Кроссплатформенно это решается только созданием отдельного UDP сокета на каждый локальный IP. Так делают named, ntpd и прочие.


Это же я предложил нашему архитектору. Но он настоял на том, чтобы разрешить ситуацию с помощью sendmsg, покопавшись на более низком уровне в in_pktinfo (swan и netcat, к примеру, делают так). Как обламаюсь, вернёмся к первой мысли.

В любом случае благодарю!

Жизнь — это чудо! Только вперёд: sakhnik@jabber.kiev.ua
Re[2]: Ответ сокета UDP из виртуального интерфейса eth0:0
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.11.09 19:39
Оценка:
Здравствуйте, netch80, Вы писали:

N>В BSD есть опции IP_RECVDSTADDR и IP_SENDSRCADDR, но авторы Linux решили, что это моветон, но замены не дали.


В линухе можно указать адрес отправителя, если использовать sendmsg.
Re[3]: Ответ сокета UDP из виртуального интерфейса eth0:0
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 06.12.09 20:52
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, netch80, Вы писали:


N>>В BSD есть опции IP_RECVDSTADDR и IP_SENDSRCADDR, но авторы Linux решили, что это моветон, но замены не дали.


Pzz>В линухе можно указать адрес отправителя, если использовать sendmsg.


Какой именно опцией? Не могу найти ничего похожего.
The God is real, unless declared integer.
Re[4]: Ответ сокета UDP из виртуального интерфейса eth0:0
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.12.09 21:21
Оценка:
Здравствуйте, netch80, Вы писали:

Pzz>>В линухе можно указать адрес отправителя, если использовать sendmsg.


N>Какой именно опцией? Не могу найти ничего похожего.


struct msghdr       msg;
struct { struct cmsghdr cmsg; struct in_pktinfo pktinfo; } cmsg_pktinfo;

msg.msg_control = &cmsg_pktinfo;
msg.msg_controllen = sizeof( cmsg_pktinfo );
cmsg_pktinfo.cmsg.cmsg_level = SOL_IP;
cmsg_pktinfo.cmsg.cmsg_type = IP_PKTINFO;


после чего можно использовать либо cmsg_pktinfo.pktinfo.ipi_ifindex, либо cmsg_pktinfo.pktinfo.ipi_spec_dst.s_addr (не помню, кто из них побеждает, если поюзать оба)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.