* autoload.cc (GetExtendedTcpTable): Define.

* fhandler_socket.cc (address_in_use): Take const struct sockaddr
	pointer as argument.  Implement additional AF_INET6 table check.
	(fhandler_socket::bind): Drop AF_INET test before calling
	address_in_use.
	* net.cc (ipv4_getnameinfo): Return EAI_FAMILY instead of 1 if
	called with unsupported af_family.
This commit is contained in:
Corinna Vinschen 2008-07-14 15:56:11 +00:00
parent c0bb6b5bd6
commit 88d1b6df94
4 changed files with 68 additions and 20 deletions

View file

@ -1,3 +1,13 @@
2008-07-14 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (GetExtendedTcpTable): Define.
* fhandler_socket.cc (address_in_use): Take const struct sockaddr
pointer as argument. Implement additional AF_INET6 table check.
(fhandler_socket::bind): Drop AF_INET test before calling
address_in_use.
* net.cc (ipv4_getnameinfo): Return EAI_FAMILY instead of 1 if
called with unsupported af_family.
2008-07-12 Eric Blake <ebb9@byu.net>
Fix usage of recently fixed Interlocked* functions.

View file

@ -397,6 +397,7 @@ LoadDLLfunc (WSAWaitForMultipleEvents, 20, ws2_32)
// 50 = ERROR_NOT_SUPPORTED. Returned if OS doesn't supprot iphlpapi funcs
LoadDLLfuncEx2 (GetAdaptersAddresses, 20, iphlpapi, 1, 50)
LoadDLLfuncEx2 (GetExtendedTcpTable, 24, iphlpapi, 1, 50)
LoadDLLfuncEx2 (GetIfEntry, 4, iphlpapi, 1, 50)
LoadDLLfuncEx2 (GetIpAddrTable, 12, iphlpapi, 1, 50)
LoadDLLfuncEx2 (GetIpForwardTable, 12, iphlpapi, 1, 50)

View file

@ -769,24 +769,62 @@ fhandler_socket::link (const char *newpath)
}
static inline bool
address_in_use (struct sockaddr_in *addr)
address_in_use (const struct sockaddr *addr)
{
PMIB_TCPTABLE tab;
PMIB_TCPROW entry;
DWORD size = 0, i;
if (GetTcpTable (NULL, &size, FALSE) == ERROR_INSUFFICIENT_BUFFER)
switch (addr->sa_family)
{
tab = (PMIB_TCPTABLE) alloca (size);
if (!GetTcpTable (tab, &size, FALSE))
{
for (i = tab->dwNumEntries, entry = tab->table; i > 0; --i, ++entry)
if (entry->dwLocalAddr == addr->sin_addr.s_addr
&& entry->dwLocalPort == addr->sin_port
&& entry->dwState >= MIB_TCP_STATE_LISTEN
&& entry->dwState <= MIB_TCP_STATE_LAST_ACK)
return true;
}
case AF_INET:
{
PMIB_TCPTABLE tab;
PMIB_TCPROW entry;
DWORD size = 0, i;
struct sockaddr_in *in = (struct sockaddr_in *) addr;
if (GetTcpTable (NULL, &size, FALSE) == ERROR_INSUFFICIENT_BUFFER)
{
tab = (PMIB_TCPTABLE) alloca (size += 16 * sizeof (PMIB_TCPROW));
if (!GetTcpTable (tab, &size, FALSE))
for (i = tab->dwNumEntries, entry = tab->table; i > 0;
--i, ++entry)
if (entry->dwLocalAddr == in->sin_addr.s_addr
&& entry->dwLocalPort == in->sin_port
&& entry->dwState >= MIB_TCP_STATE_LISTEN
&& entry->dwState <= MIB_TCP_STATE_LAST_ACK)
return true;
}
}
break;
case AF_INET6:
{
/* This test works on XP SP2 and above which should cover almost
all IPv6 users... */
PMIB_TCP6TABLE_OWNER_PID tab;
PMIB_TCP6ROW_OWNER_PID entry;
DWORD size = 0, i;
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) addr;
if (GetExtendedTcpTable (NULL, &size, FALSE, AF_INET6,
TCP_TABLE_OWNER_PID_ALL, 0)
== ERROR_INSUFFICIENT_BUFFER)
{
tab = (PMIB_TCP6TABLE_OWNER_PID)
alloca (size += 16 * sizeof (PMIB_TCP6ROW_OWNER_PID));
if (!GetExtendedTcpTable (tab, &size, FALSE, AF_INET6,
TCP_TABLE_OWNER_PID_ALL, 0))
for (i = tab->dwNumEntries, entry = tab->table; i > 0;
--i, ++entry)
if (IN6_ARE_ADDR_EQUAL (entry->ucLocalAddr,
in6->sin6_addr.s6_addr)
/* FIXME: Is testing for the scope required. too?!? */
&& entry->dwLocalPort == in6->sin6_port
&& entry->dwState >= MIB_TCP_STATE_LISTEN
&& entry->dwState <= MIB_TCP_STATE_LAST_ACK)
return true;
}
}
break;
default:
break;
}
return false;
}
@ -932,10 +970,9 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen)
systems is never to set SO_REUSEADDR but only to note that
it has been set for the above SO_EXCLUSIVEADDRUSE setting.
See setsockopt() in net.cc. */
if (name->sa_family == AF_INET
&& get_socket_type () == SOCK_STREAM
if (get_socket_type () == SOCK_STREAM
&& wincap.has_ip_helper_lib ()
&& address_in_use ((struct sockaddr_in *) name))
&& address_in_use (name))
{
debug_printf ("Local address in use, don't bind");
set_errno (EADDRINUSE);

View file

@ -3765,7 +3765,7 @@ ipv4_getnameinfo (const struct sockaddr *sa, socklen_t salen,
#endif
default:
return (1);
return (EAI_FAMILY);
}
}