зеркало из https://github.com/mozilla/pjs.git
Handle the sa_len field of struct sockaddr correctly on platforms
whose struct sockaddr has that field. Thanks to Bert Driehuis <driehuis@playbeing.org> for suggesting this fix.
This commit is contained in:
Родитель
46245659d4
Коммит
ffb79aaa1b
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче