Связано: Ошибка Нет такого устройства в вызове setsockopt
при отслеживании одного из процессов модульного тестирования (я не являюсь автором модульного теста) я сталкиваюсь
socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP) = 8
setsockopt(8, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(8, SOL_IPV6, IPV6_ADD_MEMBERSHIP, "\377\2\0\0\0\0\0\0\0\0\0\0\0\0\0\373\2\0\0\0", 20) = -1 ENODEV (No such device)
close(8) = 0
По связанному с этим вопросу предполагается, что MULTICAST не включен на машине.
Тем не менее, я считаю, что в моей среде он включен, поскольку я вижу MULTICAST.
eth0 Link encap:Ethernet HWaddr 02:42:AC:12:00:02
inet addr:172.18.0.2 Bcast:172.18.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:15 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1518 (1.4 KiB) TX bytes:0 (0.0 b)
eth1 Link encap:Ethernet HWaddr 02:42:0A:3C:73:A9
inet addr:10.60.115.169 Bcast:10.60.115.255 Mask:255.255.254.0
inet6 addr: fd20:8b1e:b255:8136:42:aff:fe3c:73a9/64 Scope:Global
inet6 addr: 2002:3984:3989::2/80 Scope:Global
inet6 addr: fe80::42:aff:fe3c:73a9/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:9000 Metric:1
RX packets:2797166513 errors:0 dropped:5 overruns:0 frame:0
TX packets:1847378326 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:5442226175566 (4.9 TiB) TX bytes:4392851979876 (3.9 TiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:861782 errors:0 dropped:0 overruns:0 frame:0
TX packets:861782 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:363667068 (346.8 MiB) TX bytes:363667068 (346.8 MiB)
а также
$ netstat -g
IPv6/IPv4 Group Memberships
Interface RefCnt Group
--------------- ------ ---------------------
lo 1 all-systems.mcast.net
eth0 1 all-systems.mcast.net
eth1 1 all-systems.mcast.net
lo 1 ff02::1
lo 1 ff01::1
eth0 1 ff02::1
eth0 1 ff01::1
eth1 1 ff02::202
eth1 2 ff02::1:ff3c:73a9
eth1 1 ff02::1:ff00:2
eth1 1 ff02::1
eth1 1 ff01::1
Любая идея, почему я получаю «Нет такого устройства» в вызове setsockopt?
мне не хватает некоторых опций в /etc/sysctl.conf? Я работаю на RHEL7.4.
Я верю коду, из которого я это вижу
static int
create_ipv6_listener_socket(ifi_info* ifi)
{
struct ipv6_mreq imr6;
int err = 0;
static const int kOn = 1;
int skt = -1;
std::string addr_str = sock_addr_to_string(ifi->ifi_ipv6_addr);
TLOG_INFO(plogger, "Creating listener socket on addr %s", addr_str.c_str());
skt = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (skt < 0) {
TLOG_ERROR(plogger,
"Failed to create listener socket on addr %s: %d",
addr_str.c_str(),
errno);
return -1;
}
err = setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
if (err < 0) {
TLOG_ERROR(plogger,
"For listener socket on %s, failed to set SO_REUSEADDR: %d",
addr_str.c_str(),
errno);
close(skt);
return -1;
}
imr6.ipv6mr_interface = ifi->ifi_index;
err = inet_pton(AF_INET6, "FF02::FB", &imr6.ipv6mr_multiaddr);
if (err < 1) {
TLOG_ERROR(plogger,
"For listener socket on %s, failed to assign dns-sd "
"multicast address: %d",
addr_str.c_str(),
errno);
close(skt);
return -1;
}
err = setsockopt(skt, IPPROTO_IPV6, IPV6_JOIN_GROUP, &imr6, sizeof(imr6));
if (err < 0) {
TLOG_ERROR(
plogger,
"For listener socket on %s, failed to join multicast group: %d",
addr_str.c_str(),
errno);
close(skt);
return -1;
}
static int
create_listener_socket(ifi_info* ifi)
{
if (ifi->ifi_family == AF_INET) {
return create_ipv4_listener_socket(ifi);
} else if (ifi->ifi_family == AF_INET6) {
return create_ipv6_listener_socket(ifi);
} else {
assert(false);
}
return -1;
}
static void
create_sockets()
{
int skt = -1;
std::vector<struct ifi_info*> interfaces;
ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
assert(ifi);
strcpy(ifi->ifi_name, "fake_ipv6_ifi_info");
ifi->ifi_family = AF_INET6;
ifi->ifi_index = 2;
interfaces.push_back(ifi);
for (uint32_t ii = 0; ii < interfaces.size(); ++ii) {
struct ifi_info* ifi = interfaces[ii];
while ((skt = create_listener_socket(ifi)) == -1) {
TLOG_ERROR(plogger,
"Failed to create a listener socket for interface %s; "
"will try again in 5 seconds",
ifi->ifi_name);
sleep(5);
}
listener_sockets.push_back(skt);
Я получаю сообщение об ошибке «Для сокета прослушивателя на INADDR_ANY не удалось присоединиться к группе многоадресной рассылки: 19»
IPV6_ADD_MEMBERSHIP
не принимает строку в качестве входных данных, он принимает указатель на структуруipv6_mreq
. Журнал просто отображает необработанные байты этой структуры в строковом формате. - person Remy Lebeau   schedule 25.07.2018setsockopt()
должен бытьIPPROTO_IPV6
. Но что более важно, вы пытаетесь присоединиться к многоадресной группеFF02::FB
(Multicast DNS) на интерфейсе индекс 2. Какой из ваших интерфейсов на самом деле имеет индекс 2? Это случайно неlo
(локальная петля)? Вы пытались использовать индекс 0 или 1 для доступа кeth0
/eth1
? - person Remy Lebeau   schedule 25.07.2018IPV6_ADD_MEMBERSHIP
и просмотрев байты, которые вы показали в своем журнале strace (которые записываются в восьмеричном формате).IPV6_ADD_MEMBERSHIP
принимает в качестве входных данных структуруipv6_mreq
, которая составляет 20 байтов и содержит 2 поля: 16-байтовыйin6_addr
для группового IPv6-адреса и 4-байтовый индекс интерфейса. Таким образом,\377\2\0\0\0\0\0\0\0\0\0\0\0\0\0\373
— это байтыFF 02 00 00 00 00 00 00 00 00 00 00 00 00 00 FB
в шестнадцатеричном формате, также известные какFF02::FB
в краткой нотации IPv6, а\2\0\0\0
— это байты02 00 00 00
в шестнадцатеричном виде, также известные как десятичные 2 в целочисленной форме. - person Remy Lebeau   schedule 25.07.2018ipv6mr_multiaddr
, к которому нужно присоединиться, но как насчетipv6mr_interface
, из которого происходит присоединение? Какой из ваших интерфейсов представляетifi
? Например, вы не можете присоединиться изlo
. Вы проверили, чтоifi
указывает наeth0
илиeth1
? И есть ли у этого интерфейса сетевой маршрут к многоадресному вещателю, к которому вы пытаетесь присоединиться? - person Remy Lebeau   schedule 26.07.2018ifi
. Кроме того, вы не можете присоединиться изINADDR_ANY
, как говорится в вашем предыдущем сообщении об ошибке. Вы должныbind()
подключить свой сокет к определенному интерфейсу, чтобы он мог получать пакеты, прежде чем присоединиться к группе, используя этот интерфейс. Вы вообще не звонитеbind()
. - person Remy Lebeau   schedule 26.07.2018