From ffb79aaa1bc59bf0eb6a0888bc8c701d0ac275d5 Mon Sep 17 00:00:00 2001 From: "wtc%netscape.com" Date: Mon, 23 Nov 1998 21:22:07 +0000 Subject: [PATCH] Handle the sa_len field of struct sockaddr correctly on platforms whose struct sockaddr has that field. Thanks to Bert Driehuis for suggesting this fix. --- nsprpub/pr/src/pthreads/ptio.c | 80 ++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/nsprpub/pr/src/pthreads/ptio.c b/nsprpub/pr/src/pthreads/ptio.c index 0233500420a..e4e94d80d38 100644 --- a/nsprpub/pr/src/pthreads/ptio.c +++ b/nsprpub/pr/src/pthreads/ptio.c @@ -1445,11 +1445,23 @@ static PRStatus pt_Connect( PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) { PRIntn rv = -1, syserrno; - PRSize addr_len = PR_NETADDR_SIZE(addr); + pt_SockLen addr_len; +#ifdef _PR_HAVE_SOCKADDR_LEN + PRNetAddr addrCopy; +#endif if (pt_TestAbort()) return PR_FAILURE; + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); + addr_len = PR_NETADDR_SIZE(addr); +#ifdef _PR_HAVE_SOCKADDR_LEN + addrCopy = *addr; + ((struct sockaddr*)&addrCopy)->sa_len = addr_len; + ((struct sockaddr*)&addrCopy)->sa_family = addr->raw.family; + rv = connect(fd->secret->md.osfd, (struct sockaddr*)&addrCopy, addr_len); +#else rv = connect(fd->secret->md.osfd, (struct sockaddr*)addr, addr_len); +#endif syserrno = errno; if ((-1 == rv) && (EINPROGRESS == syserrno) && (!fd->secret->nonblocking)) { @@ -1458,7 +1470,11 @@ static PRStatus pt_Connect( { pt_Continuation op; op.arg1.osfd = fd->secret->md.osfd; +#ifdef _PR_HAVE_SOCKADDR_LEN + op.arg2.buffer = (void*)&addrCopy; +#else op.arg2.buffer = (void*)addr; +#endif op.arg3.amount = addr_len; op.timeout = timeout; op.function = pt_connect_cont; @@ -1540,13 +1556,10 @@ static PRFileDesc* pt_Accept( } } #ifdef _PR_HAVE_SOCKADDR_LEN - /* mask off the first byte of struct sockaddr (the length field) */ + /* ignore the sa_len field of struct sockaddr */ if (addr) { - *((unsigned char *) addr) = 0; -#ifdef IS_LITTLE_ENDIAN - addr->raw.family = ntohs(addr->raw.family); -#endif + addr->raw.family = ((struct sockaddr*)addr)->sa_family; } #endif /* _PR_HAVE_SOCKADDR_LEN */ newfd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP); @@ -1567,6 +1580,10 @@ static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr) { PRIntn rv; PRInt32 one = 1; + pt_SockLen addr_len; +#ifdef _PR_HAVE_SOCKADDR_LEN + PRNetAddr addrCopy; +#endif if (pt_TestAbort()) return PR_FAILURE; @@ -1593,7 +1610,15 @@ static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr) } } - rv = bind(fd->secret->md.osfd, (struct sockaddr*)addr, PR_NETADDR_SIZE(addr)); + addr_len = PR_NETADDR_SIZE(addr); +#ifdef _PR_HAVE_SOCKADDR_LEN + addrCopy = *addr; + ((struct sockaddr*)&addrCopy)->sa_len = addr_len; + ((struct sockaddr*)&addrCopy)->sa_family = addr->raw.family; + rv = bind(fd->secret->md.osfd, (struct sockaddr*)&addrCopy, addr_len); +#else + rv = bind(fd->secret->md.osfd, (struct sockaddr*)addr, addr_len); +#endif if (rv == -1) { pt_MapError(_PR_MD_MAP_BIND_ERROR, errno); @@ -1762,13 +1787,27 @@ static PRInt32 pt_SendTo( { PRInt32 syserrno, bytes = -1; PRBool fNeedContinue = PR_FALSE; + pt_SockLen addr_len; +#ifdef _PR_HAVE_SOCKADDR_LEN + PRNetAddr addrCopy; +#endif if (pt_TestAbort()) return bytes; PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); + addr_len = PR_NETADDR_SIZE(addr); +#ifdef _PR_HAVE_SOCKADDR_LEN + addrCopy = *addr; + ((struct sockaddr*)&addrCopy)->sa_len = addr_len; + ((struct sockaddr*)&addrCopy)->sa_family = addr->raw.family; bytes = sendto( fd->secret->md.osfd, buf, amount, flags, - (struct sockaddr*)addr, PR_NETADDR_SIZE(addr)); + (struct sockaddr*)&addrCopy, addr_len); +#else + bytes = sendto( + fd->secret->md.osfd, buf, amount, flags, + (struct sockaddr*)addr, addr_len); +#endif syserrno = errno; if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN) && (!fd->secret->nonblocking) ) @@ -1783,7 +1822,11 @@ static PRInt32 pt_SendTo( op.arg2.buffer = (void*)buf; op.arg3.amount = amount; op.arg4.flags = flags; +#ifdef _PR_HAVE_SOCKADDR_LEN + op.arg5.addr = (PRNetAddr*)&addrCopy; +#else op.arg5.addr = (PRNetAddr*)addr; +#endif op.timeout = timeout; op.result.code = 0; /* initialize the number sent */ op.function = pt_sendto_cont; @@ -1834,13 +1877,10 @@ static PRInt32 pt_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, #ifdef _PR_HAVE_SOCKADDR_LEN if (bytes >= 0) { - /* mask off the first byte of struct sockaddr (the length field) */ + /* ignore the sa_len field of struct sockaddr */ if (addr) { - *((unsigned char *) addr) = 0; -#ifdef IS_LITTLE_ENDIAN - addr->raw.family = ntohs(addr->raw.family); -#endif + addr->raw.family = ((struct sockaddr*)addr)->sa_family; } } #endif /* _PR_HAVE_SOCKADDR_LEN */ @@ -2016,13 +2056,10 @@ static PRStatus pt_GetSockName(PRFileDesc *fd, PRNetAddr *addr) return PR_FAILURE; } else { #ifdef _PR_HAVE_SOCKADDR_LEN - /* mask off the first byte of struct sockaddr (the length field) */ + /* ignore the sa_len field of struct sockaddr */ if (addr) { - *((unsigned char *) addr) = 0; -#ifdef IS_LITTLE_ENDIAN - addr->raw.family = ntohs(addr->raw.family); -#endif + addr->raw.family = ((struct sockaddr*)addr)->sa_family; } #endif /* _PR_HAVE_SOCKADDR_LEN */ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); @@ -2046,13 +2083,10 @@ static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr) return PR_FAILURE; } else { #ifdef _PR_HAVE_SOCKADDR_LEN - /* mask off the first byte of struct sockaddr (the length field) */ + /* ignore the sa_len field of struct sockaddr */ if (addr) { - *((unsigned char *) addr) = 0; -#ifdef IS_LITTLE_ENDIAN - addr->raw.family = ntohs(addr->raw.family); -#endif + addr->raw.family = ((struct sockaddr*)addr)->sa_family; } #endif /* _PR_HAVE_SOCKADDR_LEN */ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);