2014-01-19 5 views
1

У меня есть две сети связи в сети Интернет, и у меня есть два маршрута по умолчанию Установка:Невозможно прослушивать несколько сокетов при использовании BINDTODEVICE?

Destination  Gateway   Genmask   Flags Metric Ref Use Iface 
default   gateway0  0.0.0.0   UG 0  0  eth0 
default   gateway1  0.0.0.0   UG 0  0  eth1 
... 

я создал два гнезда с BINDTODEVICE, так что я могу отправить данные из любой eth0 или eth1. Я также пытаюсь прослушивать оба сокета, используя recvfrom (только данные UDP), но я могу только успешно читать данные из того интерфейса, который указан первым в маршрутах. eth0 работает, например, но я ничего не получаю от сокета, связанного с eth1.

Запуск проводов на любом из интерфейсов показывает, что данные поступают успешно - то есть я могу видеть, что данные отправляются из Интернета на IP-адрес eth0 или eth1 в Wireshark (так что NAT тоже не проблема), но моя программа просто блоков на recvfrom без получения каких-либо данных.

Я попытался использовать bind на сокетах, чтобы заставить их прослушивать IP-адрес соответствующего интерфейса, а также попытался не использовать привязку, чтобы они прослушивали 0.0.0.0 (каждый на другом порту), но у меня все же есть то же самое проблема.

Как я могу убедиться, что оба сокета получают данные, которые они должны использовать?

Изменить: Пример кода:

int createDeviceBoundUDPSocket(uint32_t sip, uint16_t sport, const char* bind_dev) { 
    printf("bind_dev = %s", bind_dev); 
    int s = socket(AF_INET, SOCK_DGRAM, 0); 
    int result; 
    struct sockaddr_in my_ip_addr; 

    if (s < 0) { 
     perror("socket"); 
     return s; 
    } 

    memset(&my_ip_addr, 0, sizeof(my_ip_addr)); 

    my_ip_addr.sin_family = AF_INET; 
    my_ip_addr.sin_addr.s_addr = htonl(sip); 
    my_ip_addr.sin_port = htons(sport); 

    // commenting this section out doesn't seem to make a difference 
    // listening on 0.0.0.0 or the interface's IP both have the same problem 
    result = bind(s, (struct sockaddr*)(&my_ip_addr), sizeof(my_ip_addr)); 
    if (result < 0) { 
     perror("Error in bind"); 
     return result; 
    } 

    if (bind_dev) { 
     // Bind to specific device. 
     if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, 
        bind_dev, strlen(bind_dev) + 1)) { 
     perror("Error binding to device"); 
     return -1; 
     } 
    } 

    return s; 
} 
+0

Пожалуйста, покажите свой код. Скорее всего, вы не настроите привязки. –

+0

Привязки работают для отправки данных и для одного интерфейса работают для приема данных. Поэтому я сейчас не подозреваю эту часть. – erjiang

+0

Не смешивайте 'bind()' и 'SO_BINDTODEVICE'. Используйте один или другой. Как правило, вы должны использовать 'bind()'. –

ответ

0

Решение, как намекнул the Linux Advanced Routing and Traffic Control руководство, чтобы отключить фильтрацию обратного пути. Не уверен, какой из трех интерфейсов необходимо было отключить, но делать

echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter 

сделал это работу.

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

  • Нет связанных вопросов^_^