Bug 387954 fix NT version of PR_Accept on IPv6 listen socket. r=wtc
git-svn-id: svn://10.0.0.236/trunk@230916 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
95ba970f9d
commit
d824c01c5c
@ -101,6 +101,7 @@ struct ip_mreq {
|
||||
#define _PR_STAT_HAS_ONLY_ST_ATIME
|
||||
#define _PR_NO_LARGE_FILES
|
||||
#define _PR_STRICT_ADDR_LEN
|
||||
#define _PR_NEED_SECRET_AF
|
||||
|
||||
/* IPv6 support */
|
||||
#ifdef _SOCKADDR_LEN
|
||||
|
||||
@ -124,6 +124,7 @@ struct _md_sockaddr_in6 {
|
||||
#define _PR_PEEK_BUFFER_MAX (32 * 1024)
|
||||
#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) \
|
||||
(!(fd)->secret->nonblocking && (fd)->secret->inheritable != _PR_TRI_TRUE)
|
||||
#define _PR_NEED_SECRET_AF
|
||||
|
||||
/* --- Common User-Thread/Native-Thread Definitions --------------------- */
|
||||
|
||||
|
||||
@ -1745,12 +1745,10 @@ struct PRFilePrivate {
|
||||
* append mode. See Bugzilla 4090, 276330. */
|
||||
#endif
|
||||
_MDFileDesc md;
|
||||
#ifdef _PR_STRICT_ADDR_LEN
|
||||
PRUint16 af; /* If the platform requires passing the exact
|
||||
* length of the sockaddr structure for the
|
||||
* address family of the socket to socket
|
||||
* functions like accept(), we need to save
|
||||
* the address family of the socket. */
|
||||
#ifdef _PR_NEED_SECRET_AF
|
||||
PRUint16 af; /* If the platform's implementation of accept()
|
||||
* requires knowing the address family of the
|
||||
* socket, we save the address family here. */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -199,6 +199,13 @@ PRFileDesc *fd;
|
||||
if (fd != NULL) {
|
||||
_PR_MD_MAKE_NONBLOCK(fd);
|
||||
_PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
|
||||
#ifdef _PR_NEED_SECRET_AF
|
||||
/* this means we can only import IPv4 sockets here.
|
||||
* but this is what the function in ptio.c does.
|
||||
* We need a way to import IPv6 sockets, too.
|
||||
*/
|
||||
fd->secret->af = AF_INET;
|
||||
#endif
|
||||
} else
|
||||
_PR_MD_CLOSE_SOCKET(osfd);
|
||||
return(fd);
|
||||
@ -513,6 +520,9 @@ PRIntervalTime timeout)
|
||||
#ifdef _PR_INET6
|
||||
if (AF_INET6 == addr->raw.family)
|
||||
addr->raw.family = PR_AF_INET6;
|
||||
#endif
|
||||
#ifdef _PR_NEED_SECRET_AF
|
||||
fd2->secret->af = fd->secret->af;
|
||||
#endif
|
||||
}
|
||||
return fd2;
|
||||
@ -943,6 +953,9 @@ PRIntervalTime timeout)
|
||||
#ifdef _PR_INET6
|
||||
if (AF_INET6 == *raddr->raw.family)
|
||||
*raddr->raw.family = PR_AF_INET6;
|
||||
#endif
|
||||
#ifdef _PR_NEED_SECRET_AF
|
||||
(*nd)->secret->af = sd->secret->af;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -994,6 +1007,9 @@ void *callbackArg)
|
||||
#ifdef _PR_INET6
|
||||
if (AF_INET6 == *raddr->raw.family)
|
||||
*raddr->raw.family = PR_AF_INET6;
|
||||
#endif
|
||||
#ifdef _PR_NEED_SECRET_AF
|
||||
(*nd)->secret->af = sd->secret->af;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -1324,6 +1340,9 @@ PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
|
||||
fd = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef _PR_NEED_SECRET_AF
|
||||
fd->secret->af = domain;
|
||||
#endif
|
||||
} else
|
||||
_PR_MD_CLOSE_SOCKET(osfd);
|
||||
|
||||
@ -64,8 +64,10 @@ static PRThread *_pr_io_completion_thread;
|
||||
|
||||
#define RECYCLE_SIZE 512
|
||||
static struct _MDLock _pr_recycle_lock;
|
||||
static PRInt32 _pr_recycle_array[RECYCLE_SIZE];
|
||||
static PRInt32 _pr_recycle_tail = 0;
|
||||
static PRInt32 _pr_recycle_INET_array[RECYCLE_SIZE];
|
||||
static PRInt32 _pr_recycle_INET_tail = 0;
|
||||
static PRInt32 _pr_recycle_INET6_array[RECYCLE_SIZE];
|
||||
static PRInt32 _pr_recycle_INET6_tail = 0;
|
||||
|
||||
__declspec(thread) PRThread *_pr_io_restarted_io = NULL;
|
||||
DWORD _pr_io_restartedIOIndex; /* The thread local storage slot for each
|
||||
@ -965,15 +967,20 @@ _PR_MD_INIT_IO()
|
||||
* second argument.
|
||||
*/
|
||||
static SOCKET
|
||||
_md_get_recycled_socket()
|
||||
_md_get_recycled_socket(int af)
|
||||
{
|
||||
SOCKET rv;
|
||||
int af = AF_INET;
|
||||
|
||||
_MD_LOCK(&_pr_recycle_lock);
|
||||
if (_pr_recycle_tail) {
|
||||
_pr_recycle_tail--;
|
||||
rv = _pr_recycle_array[_pr_recycle_tail];
|
||||
if (af == AF_INET && _pr_recycle_INET_tail) {
|
||||
_pr_recycle_INET_tail--;
|
||||
rv = _pr_recycle_INET_array[_pr_recycle_INET_tail];
|
||||
_MD_UNLOCK(&_pr_recycle_lock);
|
||||
return rv;
|
||||
}
|
||||
if (af == AF_INET6 && _pr_recycle_INET6_tail) {
|
||||
_pr_recycle_INET6_tail--;
|
||||
rv = _pr_recycle_INET6_array[_pr_recycle_INET6_tail];
|
||||
_MD_UNLOCK(&_pr_recycle_lock);
|
||||
return rv;
|
||||
}
|
||||
@ -991,14 +998,19 @@ _md_get_recycled_socket()
|
||||
* Add a socket to the recycle bin.
|
||||
*/
|
||||
static void
|
||||
_md_put_recycled_socket(SOCKET newsock)
|
||||
_md_put_recycled_socket(SOCKET newsock, int af)
|
||||
{
|
||||
PR_ASSERT(_pr_recycle_tail >= 0);
|
||||
PR_ASSERT(_pr_recycle_INET_tail >= 0);
|
||||
PR_ASSERT(_pr_recycle_INET6_tail >= 0);
|
||||
|
||||
_MD_LOCK(&_pr_recycle_lock);
|
||||
if (_pr_recycle_tail < RECYCLE_SIZE) {
|
||||
_pr_recycle_array[_pr_recycle_tail] = newsock;
|
||||
_pr_recycle_tail++;
|
||||
if (af == AF_INET && _pr_recycle_INET_tail < RECYCLE_SIZE) {
|
||||
_pr_recycle_INET_array[_pr_recycle_INET_tail] = newsock;
|
||||
_pr_recycle_INET_tail++;
|
||||
_MD_UNLOCK(&_pr_recycle_lock);
|
||||
} else if (af == AF_INET6 && _pr_recycle_INET6_tail < RECYCLE_SIZE) {
|
||||
_pr_recycle_INET6_array[_pr_recycle_INET6_tail] = newsock;
|
||||
_pr_recycle_INET6_tail++;
|
||||
_MD_UNLOCK(&_pr_recycle_lock);
|
||||
} else {
|
||||
_MD_UNLOCK(&_pr_recycle_lock);
|
||||
@ -1327,7 +1339,7 @@ _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
|
||||
}
|
||||
}
|
||||
|
||||
accept_sock = _md_get_recycled_socket();
|
||||
accept_sock = _md_get_recycled_socket(fd->secret->af);
|
||||
if (accept_sock == INVALID_SOCKET)
|
||||
return -1;
|
||||
|
||||
@ -1357,7 +1369,7 @@ _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
|
||||
&bytes,
|
||||
&(me->md.overlapped.overlapped));
|
||||
|
||||
if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING)) {
|
||||
if ( (rv == 0) && ((err = WSAGetLastError()) != ERROR_IO_PENDING)) {
|
||||
/* Argh! The IO failed */
|
||||
closesocket(accept_sock);
|
||||
_PR_THREAD_LOCK(me);
|
||||
@ -1450,7 +1462,7 @@ _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, PRNetAddr **raddr,
|
||||
sd->secret->md.io_model_committed = PR_TRUE;
|
||||
}
|
||||
|
||||
*newSock = _md_get_recycled_socket();
|
||||
*newSock = _md_get_recycled_socket(sd->secret->af);
|
||||
if (*newSock == INVALID_SOCKET)
|
||||
return -1;
|
||||
|
||||
@ -1700,7 +1712,7 @@ _PR_MD_SENDFILE(PRFileDesc *sock, PRSendFileData *sfd,
|
||||
}
|
||||
|
||||
if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
|
||||
_md_put_recycled_socket(sock->secret->md.osfd);
|
||||
_md_put_recycled_socket(sock->secret->md.osfd, sock->secret->af);
|
||||
}
|
||||
|
||||
PR_ASSERT(me->io_pending == PR_FALSE);
|
||||
|
||||
@ -3465,7 +3465,7 @@ PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
|
||||
fd = pt_SetMethods(osfd, ftype, PR_FALSE, PR_FALSE);
|
||||
if (fd == NULL) close(osfd);
|
||||
}
|
||||
#ifdef _PR_STRICT_ADDR_LEN
|
||||
#ifdef _PR_NEED_SECRET_AF
|
||||
if (fd != NULL) fd->secret->af = domain;
|
||||
#endif
|
||||
#if defined(_PR_INET6_PROBE) || !defined(_PR_INET6)
|
||||
@ -4456,7 +4456,7 @@ PR_IMPLEMENT(PRFileDesc*) PR_ImportTCPSocket(PRInt32 osfd)
|
||||
if (!_pr_initialized) _PR_ImplicitInitialization();
|
||||
fd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_FALSE, PR_TRUE);
|
||||
if (NULL == fd) close(osfd);
|
||||
#ifdef _PR_STRICT_ADDR_LEN
|
||||
#ifdef _PR_NEED_SECRET_AF
|
||||
if (NULL != fd) fd->secret->af = PF_INET;
|
||||
#endif
|
||||
return fd;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user