2016-08-28 1 views
1

Я все еще получаю практическое применение в сетевом программировании для Linux, и, пожалуйста, не стесняйтесь очищать свое понимание, если вы чувствуете его расплывчатое или неправильное.2 пользовательских космических программы по туннелю с использованием multicast

Запрос:

Я испекла Linux изображение, используя Yocto проект, который похож на ядро ​​образа-минимален. Эта часть не имеет отношения к запросу. Я загружаю это изображение с помощью эмулятора QEMU, и когда QEMU загружается, он создает интерфейс sudo по имени tap0. IP-адрес QEMU равен 192.168.7.2, а tap0 - IP 192.168.7.1.

Теперь у меня есть другая программа пространства пользователя, написанная на простом C, которая пытается прослушивать все, что отправляет программа (узел) QEMU. Таким образом, я использую фрагмент, похожий на этот:

if ((fd = open("/dev/net/tun",O_RDWR)) < 0) PERROR("open"); 

memset(&ifr, 0, sizeof(ifr)); 
ifr.ifr_flags = TUNMODE; 
strncpy(ifr.ifr_name, "w-tap%d", IFNAMSIZ); 
if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) PERROR("ioctl"); 

printf("Allocated interface %s. Configure and use it\n", ifr.ifr_name); 

s = socket(PF_INET, SOCK_DGRAM, 0); 
sin.sin_family = AF_INET; 
sin.sin_addr.s_addr = htonl(INADDR_ANY); 
sin.sin_port = htons(PORT); 
if (bind(s,(struct sockaddr *)&sin, sizeof(sin)) < 0) PERROR("bind"); 

fromlen = sizeof(from); 
while(1) { 
    l = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen); 
    //print the data etc 
} 

Теперь если я начну этот C код сказать sudo ./tun_proxy 1534, я могу слушать сообщения на этот порт, посланного 192.168.7.2.

Далее

Я Загрузиться QEMU с дополнительной опцией -net socket,mcast=224.244.224.245:30490 поскольку запеченное изображение имеет небольшую программу, в ней, чтобы отправить несколько сообщений в эфире на группу многоадресной рассылки и порт. Кроме того, я должен уметь слушать это сообщение в предыдущем приложении tun_proxy. Я даже создал новый поток в том, что пытается прослушивать группу многоадресной рассылки, но я получаю сообщение об ошибке как «уже используемое»

Где именно мое понимание не так? Все, что мне нужно, это 2 программы пользовательского пространства, одна из которых - QEMU для связи через многоадресные сообщения.

ответ

1

Ваше понимание звука, есть только две проблемы, которые необходимо решить:

  • Если вы свяжете на INADDR_ANY вы блокируете порт для всех остальных адресов (в том числе и многоадресной рассылки), если вы не используете REUSEADDR. Ваш INADDR_ANY связанный сокет будет также получать многоадресную он блокирует доступ, за исключением:

  • Некоторые гнезда на «хозяина» должен использовать IP_ADD_MEMBERSHIP где запрос на членство соответствует трафик до того, как сокеты получит многоадресного трафика.

Эмуляция вашего текущий примера:

В качестве эквивалента, но довольно причудливых например, shell1 эквивалентно вашего слушателю и shell2 показывает, что, казалось бы, не связанным между собой сокет IP-надстройка членство (но для правильного адреса и все интерфейсы) заставляет его принимать трафик:

shell1$ socat UDP-RECVFROM:30490,bind=0.0.0.0 EXEC:date 

shell2$ echo hi | socat UDP-DATAGRAM:224.244.224.245:30490 STDIO 
shell1$ (socat is still waiting for a packet) 

shell2-add-membership$ socat UDP-RECVFROM:1044,reuseaddr,bind=127.0.0.1,ip-add-membership=224.244.224.245:0.0.0.0 EXEC:date& 
     [1] 16003 
shell2$ echo hi | socat UDP-DATAGRAM:224.244.224.245:30490 STDIO 
     Thu Sep 1 00:16:28 CEST 2016 
shell1$ (socat now exits cleanly) 

Крепление его для многоадресной рассылки:

Таким образом, для запуска 2+ клиентов, правильный метод будет:

shellclient1$ socat UDP-RECVFROM:30490,bind=0.0.0.0,reuseaddr,ip-add-membership=224.244.224.245:0.0.0.0 EXEC:date 
shellclient2$ socat UDP-RECVFROM:30490,bind=0.0.0.0,reuseaddr EXEC:date 
... 
shellclientn$ socat UDP-RECVFROM:30490,bind=0.0.0.0,reuseaddr EXEC:date 


shell2$ echo hi | socat UDP-DATAGRAM:224.244.224.245:30490 STDIO 
     Thu Sep 1 00:16:28 CEST 2016 
     ... 

Обратите внимание, что все должны использовать SO_REUSEADDR, но только один должен добавить членство.

Qemu's socket network uses SO_REUSEADDR и членство. Таким образом, код, блокирующий сокет, вероятно, является другим кодом, который необходимо изменить, чтобы быть похожим на Qemu.

+0

Я попытался использовать программу shell1 как средство для прослушивания сообщений многоадресной рассылки, отправленных QEMU. QEMU был загружен с помощью одного и того же -net-сокета, mcast = 224.244.224.245: 30490. Хотя, программа shell1 возвращает ошибку: адрес уже используется. Кроме того, одно интересное различие, которое я заметил, заключается в том, что при запуске QEMU с опцией многоадресной рассылки не создается сетевого сетевого интерфейса. Хотя, когда я использую стандартную команду, например «runqemu qemux86 my-image», он создает виртуальный интерфейс. Как я могу запустить QEMU с опцией многоадресной рассылки, а также с интерфейсом виртуальной сети? – HimanshuP2

+0

Я не думаю, что вы можете использовать параметры сокета для других типов сетей. Но вы хотели бы убедиться, что используете reuseaddr, и он находится во всех сокетах, используя порт 30490. Мой первый пример - это то, как подражать вашей текущей ситуации. – lossleader

+0

Большое спасибо. Я смог прослушать многоадресные сообщения, используя параметр reuseaddr. – HimanshuP2

Смежные вопросы