Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1794,27 +1794,6 @@ AC_LINK_IFELSE([
AC_MSG_RESULT([no])
])

# BSD-derived systems populate the socket length in the structure itself. It's
# redundant to check all of these, but hey, I need the typing practice.
AC_CHECK_MEMBER([struct sockaddr.sa_len], [], [], [#include <netinet/in.h>])
AC_CHECK_MEMBER([struct sockaddr_in.sin_len], [], [], [#include <netinet/in.h>])
AC_CHECK_MEMBER([struct sockaddr_in6.sin6_len], [], [], [#include <netinet/in.h>])

if test "x${ac_cv_member_struct_sockaddr_sa_len}" = "xyes"; then
AC_DEFINE(HAVE_STRUCT_SOCKADDR_SA_LEN, 1,
[Whether struct sockaddr_in has the sa_len member])
fi

if test "x${ac_cv_member_struct_sockaddr_in_sin_len}" = "xyes"; then
AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN_SIN_LEN, 1,
[Whether struct sockaddr_in has the sin_len member])
fi

if test "x${ac_cv_member_struct_sockaddr_in6_sin6_len}" = "xyes"; then
AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN, 1,
[Whether struct sockaddr_in6 has the sin6_len member])
fi

if test "x${with_profiler}" = "xyes"; then
AC_CHECK_HEADERS([google/profiler.h \
], [], [])
Expand Down
58 changes: 37 additions & 21 deletions include/tscore/ink_inet.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <sys/socket.h>
#include <string_view>

#include "tscore/ts_meta.h"
#include "tscore/ink_memory.h"
#include "tscore/ink_apidefs.h"
#include "tscore/BufferWriterForward.h"
Expand Down Expand Up @@ -61,6 +62,36 @@ extern const std::string_view IP_PROTO_TAG_HTTP_2_0;

struct IpAddr; // forward declare.

namespace ts
{
namespace detail
{
// Handle FreeBSD and similar systems that have a length field in sockaddrs.
template <typename T>
auto
ip_update_sockaddr_len(T *, ts::meta::CaseTag<0>) -> void
{ // base case, no length, do nothing.
}
template <typename T>
auto
ip_update_sockaddr_len(T *sa, ts::meta::CaseTag<1>) -> decltype(T::sin_len, ts::meta::CaseVoidFunc())
{
sa->sin_len = sizeof(T); // set the length to the size of the sockaddr type.
}
// Declare these such that a specific sockaddr type is used at the call site to get the size correct.
inline void
ip_update_sockaddr_len(sockaddr_in *addr)
{
ip_update_sockaddr_len(addr, ts::meta::CaseArg);
}
inline void
ip_update_sockaddr_len(sockaddr_in6 *addr)
{
ip_update_sockaddr_len(addr, ts::meta::CaseArg);
}
} // namespace detail
} // namespace ts

/** A union to hold the standard IP address structures.
By standard we mean @c sockaddr compliant.

Expand Down Expand Up @@ -723,9 +754,6 @@ ats_ip_copy(sockaddr *dst, ///< Destination object.
if (n) {
if (src != dst) {
memcpy(dst, src, n);
#if HAVE_STRUCT_SOCKADDR_SA_LEN
dst->sa_len = n;
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does the template approach deal with sa_len?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here.

}
} else {
ats_ip_invalidate(dst);
Expand Down Expand Up @@ -909,9 +937,7 @@ ats_ip4_set(sockaddr_in *dst, ///< Destination storage.
)
{
ink_zero(*dst);
#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
dst->sin_len = sizeof(sockaddr_in);
#endif
ts::detail::ip_update_sockaddr_len(dst);
dst->sin_family = AF_INET;
dst->sin_addr.s_addr = addr;
dst->sin_port = port;
Expand Down Expand Up @@ -953,9 +979,7 @@ ats_ip6_set(sockaddr_in6 *dst, ///< Destination storage.
)
{
ink_zero(*dst);
#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
dst->sin6_len = sizeof(sockaddr_in6);
#endif
ts::detail::ip_update_sockaddr_len(dst);
dst->sin6_family = AF_INET6;
memcpy(&dst->sin6_addr, &addr, sizeof addr);
dst->sin6_port = port;
Expand Down Expand Up @@ -1516,14 +1540,10 @@ IpEndpoint::setToAnyAddr(int family)
sa.sa_family = family;
if (AF_INET == family) {
sin.sin_addr.s_addr = INADDR_ANY;
#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
sin.sin_len = sizeof(sockaddr_in);
#endif
ts::detail::ip_update_sockaddr_len(&sin);
} else if (AF_INET6 == family) {
sin6.sin6_addr = in6addr_any;
#if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
sin6.sin6_len = sizeof(sockaddr_in6);
#endif
ts::detail::ip_update_sockaddr_len(&sin6);
}
return *this;
}
Expand All @@ -1535,15 +1555,11 @@ IpEndpoint::setToLoopback(int family)
sa.sa_family = family;
if (AF_INET == family) {
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
sin.sin_len = sizeof(sockaddr_in);
#endif
ts::detail::ip_update_sockaddr_len(&sin);
} else if (AF_INET6 == family) {
static const struct in6_addr init = IN6ADDR_LOOPBACK_INIT;
sin6.sin6_addr = init;
#if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
sin6.sin6_len = sizeof(sockaddr_in6);
#endif
ts::detail::ip_update_sockaddr_len(&sin6);
}
return *this;
}
Expand Down