]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Attempted fix for FreeBSD run-time socket error "(22) Invalid Object" on connects
authorAmos Jeffries <squid3@treenet.co.nz>
Thu, 3 Apr 2008 09:39:06 +0000 (21:39 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Thu, 3 Apr 2008 09:39:06 +0000 (21:39 +1200)
- Sets the ss_len / sin_len / sin6_len fields of sockaddr_* objects
  when retrieved for connection setup.
- Tests the OS at compile time for each of these fields existence to
  cope with some OS (ie Linux) not using or providing them.

configure.in
lib/IPAddress.cc

index 6df159b07e1ccc7fcb645475bd8c06704eea9d5e..348da3a5b00726c12337937cc4e8096ee6e95c21 100644 (file)
@@ -1798,6 +1798,60 @@ AC_ARG_WITH(dns-cname,
   [AC_DEFINE(DNS_CNAME, 0, [ 0 == Disable expermental CNAME recursion inside Squid DNS resolver stub]) AC_MSG_RESULT(no)]
 )
 
+dnl Check whether this OS defines ss_len as a member of sockaddr_storage
+AC_CACHE_CHECK([for ss_len field in struct sockaddr_storage],
+               ac_cv_have_ss_len_in_struct_ss, [
+       AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+               ],
+               [ struct sockaddr_storage s; s.ss_len = 1; ],
+               [ ac_cv_have_ss_len_in_struct_ss="yes" ],
+               [ ac_cv_have_ss_len_in_struct_ss="no" ]
+       )
+])
+if test "x$ac_cv_have_ss_len_in_struct_ss" = "xyes" ; then
+       AC_DEFINE(HAVE_SS_LEN_IN_SS, 1, [Does struct sockaddr_storage have ss_len? 1: Yes, 0: No])
+else
+       AC_DEFINE(HAVE_SS_LEN_IN_SS, 0, [Does struct sockaddr_storage have ss_len? 1: Yes, 0: No])
+fi
+
+dnl Check whether this OS defines sin_len as a member of sockaddr_in as a backup to ss_len
+AC_CACHE_CHECK([for sin_len field in struct sockaddr_in],
+                ac_cv_have_sin_len_in_struct_sai, [
+        AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+                ],
+                [ struct sockaddr_in s; s.sin_len = 1; ],
+                [ ac_cv_have_sin_len_in_struct_sai="yes" ],
+                [ ac_cv_have_sin_len_in_struct_sai="no" ]
+        )
+])
+if test "x$ac_cv_have_sin_len_in_struct_sai" = "xyes" ; then
+        AC_DEFINE(HAVE_SIN_LEN_IN_SAI, 1, [Does struct sockaddr_in have sin_len? 1: Yes, 0: No])
+else
+        AC_DEFINE(HAVE_SIN_LEN_IN_SAI, 0, [Does struct sockaddr_in have sin_len? 1: Yes, 0: No])
+fi
+
+dnl Check whether this OS defines sin6_len as a member of sockaddr_in6 as a backup to ss_len
+AC_CACHE_CHECK([for sin6_len field in struct sockaddr_in6],
+                ac_cv_have_sin6_len_in_struct_sai, [
+        AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+                ],
+                [ struct sockaddr_in6 s; s.sin6_len = 1; ],
+                [ ac_cv_have_sin6_len_in_struct_sai="yes" ],
+                [ ac_cv_have_sin6_len_in_struct_sai="no" ]
+        )
+])
+if test "x$ac_cv_have_sin6_len_in_struct_sai" = "xyes" ; then
+        AC_DEFINE(HAVE_SIN6_LEN_IN_SAI, 1, [Does struct sockaddr_in6 have sin6_len? 1: Yes, 0: No])
+else
+        AC_DEFINE(HAVE_SIN6_LEN_IN_SAI, 0, [Does struct sockaddr_in6 have sin6_len? 1: Yes, 0: No])
+fi
+
 
 AC_ARG_WITH(filedescriptors,
 [  --with-filedescriptors=NUMBER
index d0ca2fb5e082a867c3e5fd9a1a23359ce05b3f03..bad2403be76f9dcd13f04149721504174a64016f 100644 (file)
@@ -1100,20 +1100,40 @@ void IPAddress::GetSockAddr(struct sockaddr_storage &addr, const int family) con
         if(addr.ss_family == 0) {
             addr.ss_family = AF_INET6;
         }
+#if HAVE_SS_LEN_IN_SS
+        /* not all OS have this field, BUT when they do it can be a problem if set wrong */
+        addr.ss_len = htons(sizeof(struct sockaddr_in6));
+#elif HAVE_SIN6_LEN_IN_SAI
+        sin->sin6_len = htons(sizeof(struct sockaddr_in6));
+#endif
     } else if( family == AF_INET || family == AF_UNSPEC && IsIPv4() ) {
         sin = (struct sockaddr_in*)&addr;
         addr.ss_family = AF_INET;
         sin->sin_port = m_SocketAddr.sin6_port;
         Map6to4( m_SocketAddr.sin6_addr, sin->sin_addr);
+#if HAVE_SS_LEN_IN_SS
+        /* not all OS have this field, BUT when they do it can be a problem if set wrong */
+        addr.ss_len = htons(sizeof(struct sockaddr_in));
+#elif HAVE_SIN_LEN_IN_SAI
+        sin->sin_len = htons(sizeof(struct sockaddr_in));
+#endif
     } else {
         IASSERT("false",false);
     }
-#else
+#else /* not USE_IPV6 */
     sin = (struct sockaddr_in*)&addr;
     memcpy(sin, &m_SocketAddr, sizeof(struct sockaddr_in));
 
     addr.ss_family = AF_INET;
+
+#if HAVE_SS_LEN_IN_SS
+    /* not all OS have this field, BUT when they do it can be a problem if set wrong */
+    addr.ss_len = htons(sizeof(struct sockaddr_in));
+#elif HAVE_SIN_LEN_IN_SAI
+     sin->sin_len = htons(sizeof(struct sockaddr_in));
 #endif
+
+#endif /* USE_IPV6 */
 }
 
 void IPAddress::GetSockAddr(struct sockaddr_in &buf) const