* 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:
parent
c0bb6b5bd6
commit
88d1b6df94
|
@ -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>
|
2008-07-12 Eric Blake <ebb9@byu.net>
|
||||||
|
|
||||||
Fix usage of recently fixed Interlocked* functions.
|
Fix usage of recently fixed Interlocked* functions.
|
||||||
|
|
|
@ -397,6 +397,7 @@ LoadDLLfunc (WSAWaitForMultipleEvents, 20, ws2_32)
|
||||||
|
|
||||||
// 50 = ERROR_NOT_SUPPORTED. Returned if OS doesn't supprot iphlpapi funcs
|
// 50 = ERROR_NOT_SUPPORTED. Returned if OS doesn't supprot iphlpapi funcs
|
||||||
LoadDLLfuncEx2 (GetAdaptersAddresses, 20, iphlpapi, 1, 50)
|
LoadDLLfuncEx2 (GetAdaptersAddresses, 20, iphlpapi, 1, 50)
|
||||||
|
LoadDLLfuncEx2 (GetExtendedTcpTable, 24, iphlpapi, 1, 50)
|
||||||
LoadDLLfuncEx2 (GetIfEntry, 4, iphlpapi, 1, 50)
|
LoadDLLfuncEx2 (GetIfEntry, 4, iphlpapi, 1, 50)
|
||||||
LoadDLLfuncEx2 (GetIpAddrTable, 12, iphlpapi, 1, 50)
|
LoadDLLfuncEx2 (GetIpAddrTable, 12, iphlpapi, 1, 50)
|
||||||
LoadDLLfuncEx2 (GetIpForwardTable, 12, iphlpapi, 1, 50)
|
LoadDLLfuncEx2 (GetIpForwardTable, 12, iphlpapi, 1, 50)
|
||||||
|
|
|
@ -769,24 +769,62 @@ fhandler_socket::link (const char *newpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
address_in_use (struct sockaddr_in *addr)
|
address_in_use (const struct sockaddr *addr)
|
||||||
{
|
{
|
||||||
PMIB_TCPTABLE tab;
|
switch (addr->sa_family)
|
||||||
PMIB_TCPROW entry;
|
|
||||||
DWORD size = 0, i;
|
|
||||||
|
|
||||||
if (GetTcpTable (NULL, &size, FALSE) == ERROR_INSUFFICIENT_BUFFER)
|
|
||||||
{
|
{
|
||||||
tab = (PMIB_TCPTABLE) alloca (size);
|
case AF_INET:
|
||||||
if (!GetTcpTable (tab, &size, FALSE))
|
{
|
||||||
{
|
PMIB_TCPTABLE tab;
|
||||||
for (i = tab->dwNumEntries, entry = tab->table; i > 0; --i, ++entry)
|
PMIB_TCPROW entry;
|
||||||
if (entry->dwLocalAddr == addr->sin_addr.s_addr
|
DWORD size = 0, i;
|
||||||
&& entry->dwLocalPort == addr->sin_port
|
struct sockaddr_in *in = (struct sockaddr_in *) addr;
|
||||||
&& entry->dwState >= MIB_TCP_STATE_LISTEN
|
|
||||||
&& entry->dwState <= MIB_TCP_STATE_LAST_ACK)
|
if (GetTcpTable (NULL, &size, FALSE) == ERROR_INSUFFICIENT_BUFFER)
|
||||||
return true;
|
{
|
||||||
}
|
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;
|
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
|
systems is never to set SO_REUSEADDR but only to note that
|
||||||
it has been set for the above SO_EXCLUSIVEADDRUSE setting.
|
it has been set for the above SO_EXCLUSIVEADDRUSE setting.
|
||||||
See setsockopt() in net.cc. */
|
See setsockopt() in net.cc. */
|
||||||
if (name->sa_family == AF_INET
|
if (get_socket_type () == SOCK_STREAM
|
||||||
&& get_socket_type () == SOCK_STREAM
|
|
||||||
&& wincap.has_ip_helper_lib ()
|
&& 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");
|
debug_printf ("Local address in use, don't bind");
|
||||||
set_errno (EADDRINUSE);
|
set_errno (EADDRINUSE);
|
||||||
|
|
|
@ -3765,7 +3765,7 @@ ipv4_getnameinfo (const struct sockaddr *sa, socklen_t salen,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (1);
|
return (EAI_FAMILY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue