Bugzilla bug #40542: pass the correct size of struct sockaddr_in8 to
authorwtc%netscape.com
Fri, 09 Jun 2000 18:18:19 +0000
changeset 1418 71cf41906794c93c04f0731d66832638cdfe3303
parent 1412 bf34af0720a0c8612cabd9efaafe4fe9e71a2bc9
child 1420 0a18935b05b38a1efcbe50bd82abe573f3ab9689
push idunknown
push userunknown
push dateunknown
bugs40542
Bugzilla bug #40542: pass the correct size of struct sockaddr_in8 to native socket functions on Solaris 8 for Intel/x86. r=larryh@netscape.com. a=pdt. Thanks to dcran@us.ibm.com (Donnie Cranford) for the bug report. Modified files: _solaris.h, primpl.h
pr/include/md/_solaris.h
pr/include/private/primpl.h
--- a/pr/include/md/_solaris.h
+++ b/pr/include/md/_solaris.h
@@ -83,16 +83,34 @@
 #define _PR_HAVE_GETIPNODEBYADDR
 #define _PR_INET6_PROBE
 #define _PR_ACCEPT_INHERIT_NONBLOCK
 #ifndef _PR_INET6
 #define AF_INET6 26
 #define AI_V4MAPPED 0x0001 
 #define AI_ALL      0x0002
 #define AI_ADDRCONFIG   0x0004
+#define _PR_HAVE_MD_SOCKADDR_IN6
+/* isomorphic to struct in6_addr on Solaris 8 */
+struct _md_in6_addr {
+    union {
+        PRUint8  _S6_u8[16];
+        PRUint32 _S6_u32[4];
+        PRUint32 __S6_align;
+    } _S6_un;
+};
+/* isomorphic to struct sockaddr_in6 on Solaris 8 */
+struct _md_sockaddr_in6 {
+    PRUint16 sin6_family;
+    PRUint16 sin6_port;
+    PRUint32 sin6_flowinfo;
+    struct _md_in6_addr sin6_addr;
+    PRUint32 sin6_scope_id;
+    PRUint32 __sin6_src_id;
+};
 #endif
 #if defined(_PR_GLOBAL_THREADS_ONLY) || defined(_PR_PTHREADS)
 #define _PR_HAVE_GETHOST_R
 #define _PR_HAVE_GETHOST_R_POINTER
 #endif
 
 #include "prinrval.h"
 NSPR_API(PRIntervalTime) _MD_Solaris_GetInterval(void);
--- a/pr/include/private/primpl.h
+++ b/pr/include/private/primpl.h
@@ -1306,16 +1306,49 @@ extern PRIOMethods _pr_faulty_methods;
 */
 
 extern PRUintn _PR_NetAddrSize(const PRNetAddr* addr);
 
 #if defined(_PR_INET6)
 
 #define PR_NETADDR_SIZE(_addr) _PR_NetAddrSize(_addr)
 
+#elif defined(_PR_HAVE_MD_SOCKADDR_IN6)
+
+/*
+** Under the following conditions:
+** 1. _PR_INET6 is not defined;
+** 2. _PR_INET6_PROBE is defined;
+** 3. struct sockaddr_in6 has nonstandard fields at the end
+**    (e.g., on Solaris 8),
+** (_addr)->ipv6 is smaller than struct sockaddr_in6, and
+** hence we can't pass sizeof((_addr)->ipv6) to socket
+** functions such as connect because they would fail with
+** EINVAL.
+**
+** To pass the correct socket address length to socket
+** functions, define the macro _PR_HAVE_MD_SOCKADDR_IN6 and
+** define struct _md_sockaddr_in6 to be isomorphic to
+** struct sockaddr_in6.
+*/
+
+#if defined(XP_UNIX)
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : ((_addr)->raw.family == PR_AF_INET6	\
+        ? sizeof(struct _md_sockaddr_in6)		\
+        : sizeof((_addr)->local)))
+#else
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : sizeof(struct _md_sockaddr_in6)
+#endif /* defined(XP_UNIX) */
+
 #else
 
 #if defined(XP_UNIX)
 #define PR_NETADDR_SIZE(_addr) 					\
         ((_addr)->raw.family == PR_AF_INET		\
         ? sizeof((_addr)->inet)					\
         : ((_addr)->raw.family == PR_AF_INET6	\
         ? sizeof((_addr)->ipv6)					\