无法在辅助接口上接收 UDP/IPv6 数据包
我有以下用于 UDP 服务器的 C 代码,它将绑定到辅助接口 tap0 的 ipv6 地址。
context_t *
new_context(const struct sockaddr *listen_addr, size_t addr_size) {
context_t *c = malloc( sizeof( context_t ) );
time_t now;
int reuse = 1;
if (!listen_addr) {
fprintf(stderr, "no listen address specified\n");
return NULL;
}
srand( getpid() ^ time(&now) );
if ( !c ) {
perror("init: malloc:");
return NULL;
}
memset(c, 0, sizeof( context_t ) );
c->sockfd = socket(listen_addr->sa_family, SOCK_DGRAM, 0);
if ( c->sockfd < 0 ) {
perror("new_context: socket");
goto onerror;
}
if ( setsockopt( c->sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse) ) < 0 )
perror("setsockopt SO_REUSEADDR");
if ( bind (c->sockfd, listen_addr, addr_size) < 0 ) {
perror("new_context: bind");
goto onerror;
}
return c;
onerror:
if ( c->sockfd >= 0 )
close ( c->sockfd );
free( c );
return NULL;
}
context_t *
get_context(const char *ipaddress, const char *port, unsigned int scopeId) {
int s;
context_t* ctx;
struct addrinfo hints;
struct addrinfo *result, *rp;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Coap uses UDP */
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV | AI_ALL;
s = getaddrinfo(ipaddress, port, &hints, &result);
if ( s != 0 ) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
return NULL;
}
/* iterate through results until success */
for (rp = result; rp != NULL; rp = rp->ai_next) {
ctx = new_context(rp->ai_addr, rp->ai_addrlen);
if (ctx) {
if ( rp->ai_family == PF_INET6 ) {
struct sockaddr_in6* pSadrIn6 = (struct sockaddr_in6*) rp->ai_addr;
if ( pSadrIn6->sin6_scope_id == 0 ) {
pSadrIn6->sin6_scope_id = scopeId;
} /* End IF the scope ID wasn't set. */
}
goto finish;
}
}
fprintf(stderr, "no context available for interface '%s'\n", node);
finish:
freeaddrinfo(result);
return ctx;
}
设备 tap0 具有以下详细信息:
tap0 Link encap:Ethernet HWaddr ce:23:fc:81:7f:65
inet6 addr: fe80::cc23:fcff:fe81:7f65/64 Scope:Link
inet6 addr: aaaa::1/64 Scope:Global
我使用以下命令运行上述代码:
./server -A aaaa::1
但它无法侦听来自 tap0 上地址 aaaa::1 的消息。我可以在 tap0 接口上的wireshark转储上看到数据包。有趣的是,从上述命令(和代码)运行的服务器可以通过本地主机接收消息。因此,如果我执行以下命令,服务器会收到消息:
nc -6 -vvv -u aaaa::1 61616 < /tmp/send_to_node_raw
上述命令发送和接收是通过 localhost 完成的。 有什么方法可以在辅助接口上以编程方式接收 UDP/IPv6 消息吗?
I have the following C code for UDP server which would bind to the ipv6 address of the secondary interface tap0.
context_t *
new_context(const struct sockaddr *listen_addr, size_t addr_size) {
context_t *c = malloc( sizeof( context_t ) );
time_t now;
int reuse = 1;
if (!listen_addr) {
fprintf(stderr, "no listen address specified\n");
return NULL;
}
srand( getpid() ^ time(&now) );
if ( !c ) {
perror("init: malloc:");
return NULL;
}
memset(c, 0, sizeof( context_t ) );
c->sockfd = socket(listen_addr->sa_family, SOCK_DGRAM, 0);
if ( c->sockfd < 0 ) {
perror("new_context: socket");
goto onerror;
}
if ( setsockopt( c->sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse) ) < 0 )
perror("setsockopt SO_REUSEADDR");
if ( bind (c->sockfd, listen_addr, addr_size) < 0 ) {
perror("new_context: bind");
goto onerror;
}
return c;
onerror:
if ( c->sockfd >= 0 )
close ( c->sockfd );
free( c );
return NULL;
}
context_t *
get_context(const char *ipaddress, const char *port, unsigned int scopeId) {
int s;
context_t* ctx;
struct addrinfo hints;
struct addrinfo *result, *rp;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Coap uses UDP */
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV | AI_ALL;
s = getaddrinfo(ipaddress, port, &hints, &result);
if ( s != 0 ) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
return NULL;
}
/* iterate through results until success */
for (rp = result; rp != NULL; rp = rp->ai_next) {
ctx = new_context(rp->ai_addr, rp->ai_addrlen);
if (ctx) {
if ( rp->ai_family == PF_INET6 ) {
struct sockaddr_in6* pSadrIn6 = (struct sockaddr_in6*) rp->ai_addr;
if ( pSadrIn6->sin6_scope_id == 0 ) {
pSadrIn6->sin6_scope_id = scopeId;
} /* End IF the scope ID wasn't set. */
}
goto finish;
}
}
fprintf(stderr, "no context available for interface '%s'\n", node);
finish:
freeaddrinfo(result);
return ctx;
}
Device tap0 has following details:
tap0 Link encap:Ethernet HWaddr ce:23:fc:81:7f:65
inet6 addr: fe80::cc23:fcff:fe81:7f65/64 Scope:Link
inet6 addr: aaaa::1/64 Scope:Global
I run the above code with the following command:
./server -A aaaa::1
But it's not able to listen to the messages coming to the address aaaa::1 on tap0. I can see the packets on the wireshark dump on tap0 interface. Interestingly, the server ran from the above command(and code) can receive the messages through the localhost. So, if I execute the following command, the server receives the messages:
nc -6 -vvv -u aaaa::1 61616 < /tmp/send_to_node_raw
The above command sending and reception is done through localhost.
Is there any way I can programatically receive UDP/IPv6 messages on secondary interfaces?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题一定出在其他地方。使用上面的代码,我可以分别使用 aaaa::1/64 和 aaaa::2/64 作为本地和远程地址成功接收来自另一个节点的数据包。
尝试绑定到 :: 并查看是否可以这样工作。还尝试使用 netcat6 绑定到 aaaa::1 并从另一个 netcat6 实例接收。
The problem must be somewhere else. Using the code above I can successfully receive packets from another node using aaaa::1/64 and aaaa::2/64 as the local and remote addresses, respectively.
Try to bind to :: and see if it works that way. Also try to use netcat6 to bind to aaaa::1 and receive from another netcat6 instance.