From ee80f4e255c4e032c964669f806f559d092dcd2c Mon Sep 17 00:00:00 2001 From: Daniel Freiermuth Date: Wed, 2 Oct 2024 16:41:12 +0200 Subject: [PATCH 1/2] Use IP_RECVDSTADDR in absence of IP_PKTINFO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On FreeBSD-like network stacks, the socket option IP_PKTINFO is unavailable, but the option IP_RECVDSTADDR can be used instead. This enables vsomeip for the new io-sock network stack on QNX 7.1+. Co-author: Eric Sjöström @EriComic --- .../endpoints/src/udp_server_endpoint_impl.cpp | 6 ++++++ .../boost/asio/detail/impl/socket_ops_ext.ipp | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index 587fb94c2..a45860a6d 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -862,7 +862,13 @@ udp_server_endpoint_impl::set_multicast_option( int its_pktinfo_option(1); ::setsockopt(multicast_socket_->native_handle(), (is_v4_ ? IPPROTO_IP : IPPROTO_IPV6), +#if defined(IP_PKTINFO) (is_v4_ ? IP_PKTINFO : IPV6_RECVPKTINFO), +#elif defined(IP_RECVDSTADDR) + (is_v4_ ? IP_RECVDSTADDR : IPV6_RECVPKTINFO), +#else + #error "Platform not supported. Neither IP_PKTINFO nor IP_RECVDSTADDR is defined."; +#endif &its_pktinfo_option, sizeof(its_pktinfo_option)); #endif diff --git a/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp index fe90e83e9..260d09b85 100644 --- a/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp +++ b/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp @@ -96,6 +96,7 @@ signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { +#if defined(IP_PKTINFO) if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) continue; @@ -104,6 +105,18 @@ signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, { da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); } +#elif defined(IP_RECVDSTADDR) + if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_RECVDSTADDR) + continue; + + struct in_addr *addr = (struct in_addr*) CMSG_DATA(cmsg); + if (addr) + { + da = boost::asio::ip::address_v4(ntohl(addr->s_addr)); + } +#else + #error "Platform not supported. Neither IP_PKTINFO nor IP_RECVDSTADDR is defined."; +#endif } } return result; From d9bd1200d957308f02c29911715c8abbde726740 Mon Sep 17 00:00:00 2001 From: Daniel Freiermuth Date: Mon, 21 Oct 2024 09:51:47 +0200 Subject: [PATCH 2/2] Add OS annotations to socket option checks to enhance maintainability. --- .../endpoints/include/udp_server_endpoint_impl_receive_op.hpp | 4 ++-- implementation/endpoints/src/udp_server_endpoint_impl.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp b/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp index ad5564321..059dc3cf0 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp @@ -309,7 +309,7 @@ receive_cb (std::shared_ptr _data) { cmsg != NULL; cmsg = CMSG_NXTHDR(&its_header, cmsg)) { -#if defined(IP_PKTINFO) +#if defined(IP_PKTINFO) # Linux, QNX io-pkt struct in_pktinfo *its_pktinfo_v4; if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO @@ -322,7 +322,7 @@ receive_cb (std::shared_ptr _data) { break; } } -#elif defined(IP_RECVDSTADDR) +#elif defined(IP_RECVDSTADDR) # FreeBSD, QNX io-sock struct in_addr *its_pktinfo_v4; if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index 35940a7c4..cf6a60616 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -801,9 +801,9 @@ udp_server_endpoint_impl::set_multicast_option(const boost::asio::ip::address& _ int its_pktinfo_option(1); ::setsockopt(multicast_socket_->native_handle(), (is_v4_ ? IPPROTO_IP : IPPROTO_IPV6), -#if defined(IP_PKTINFO) +#if defined(IP_PKTINFO) # Linux, QNX io-pkt (is_v4_ ? IP_PKTINFO : IPV6_RECVPKTINFO), -#elif defined(IP_RECVDSTADDR) +#elif defined(IP_RECVDSTADDR) # FreeBSD, QNX io-sock (is_v4_ ? IP_RECVDSTADDR : IPV6_RECVPKTINFO), #else #error "Platform not supported. Neither IP_PKTINFO nor IP_RECVDSTADDR is defined.";