mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1586 lines
31 KiB
1586 lines
31 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
intfc.h
|
|
|
|
Abstract:
|
|
Definitions of data types and corresponding methods used to provide
|
|
multiple-interface support in H.323/LDAP proxy.
|
|
|
|
|
|
Revision History:
|
|
03/01/2000 File creation. Ilya Kleyman (IlyaK)
|
|
|
|
--*/
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Include files //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#include "stdafx.h"
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Global Variables //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
PROXY_INTERFACE_ARRAY InterfaceArray;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Static definitions //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
static
|
|
int
|
|
__cdecl
|
|
CompareInterfacesByIndex (
|
|
IN PROXY_INTERFACE * const * InterfaceA,
|
|
IN PROXY_INTERFACE * const * InterfaceB
|
|
);
|
|
|
|
static
|
|
INT
|
|
SearchInterfaceByIndex (
|
|
IN const DWORD * Index,
|
|
IN PROXY_INTERFACE *const* Comparand
|
|
);
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Definitions //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// PROXY_INTERFACE ------------------------------------------------------------
|
|
|
|
|
|
PROXY_INTERFACE::PROXY_INTERFACE (
|
|
IN ULONG ArgIndex,
|
|
IN H323_INTERFACE_TYPE ArgInterfaceType,
|
|
IN PIP_ADAPTER_BINDING_INFO BindingInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Constructor for PROXY_INTERFACE class
|
|
|
|
Arguments:
|
|
ArgIndex - Index of the interface
|
|
ArgInterfaceType - Interface type (public or private)
|
|
BindingInfo - Binding information for the interface
|
|
|
|
Return Values:
|
|
None
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
Address = ntohl (BindingInfo -> Address[0].Address);
|
|
Mask = ntohl (BindingInfo -> Address[0].Mask);
|
|
Index = ArgIndex;
|
|
InterfaceType = ArgInterfaceType;
|
|
AdapterIndex = 0;
|
|
|
|
Q931RedirectHandle = NULL;
|
|
LdapRedirectHandle1 = NULL;
|
|
LdapRedirectHandle2 = NULL;
|
|
Q931LocalRedirectHandle = NULL;
|
|
LdapLocalRedirectHandle1 = NULL;
|
|
LdapLocalRedirectHandle2 = NULL;
|
|
|
|
::ZeroMemory (&Q931PortMapping, sizeof (Q931PortMapping));
|
|
::ZeroMemory (&LdapPortMapping, sizeof (LdapPortMapping));
|
|
::ZeroMemory (&LdapAltPortMapping, sizeof (LdapAltPortMapping));
|
|
|
|
} // PROXY_INTERFACE::PROXY_INTERFACE
|
|
|
|
|
|
PROXY_INTERFACE::~PROXY_INTERFACE (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Destructor for PROXY_INTERFACE class
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
None
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
assert (!Q931RedirectHandle);
|
|
assert (!LdapRedirectHandle1);
|
|
assert (!LdapRedirectHandle2);
|
|
assert (!Q931LocalRedirectHandle);
|
|
assert (!LdapLocalRedirectHandle1);
|
|
assert (!LdapLocalRedirectHandle2);
|
|
|
|
} // PROXY_INTERFACE::~PROXY_INTERFACE
|
|
|
|
|
|
ULONG
|
|
PROXY_INTERFACE::StartNatRedirects (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Creates two types of adapter-restricted NAT redirects:
|
|
Type 1 -- for connections incoming on the interface
|
|
Type 2 -- for locally-originated connections (NOT destined to
|
|
the local machine) through the interface
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
Win32 error indicating what (if anything) went wrong
|
|
when trying to set up the NAT redirects.
|
|
|
|
Notes:
|
|
Total number of redirects created is 6:
|
|
2 Type 1 redirects for LDAP
|
|
2 Type 2 redirects for LDAP
|
|
1 Type 1 redirect for Q.931
|
|
1 Type 2 redirect for Q.931
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
ULONG Status;
|
|
|
|
assert (!Q931RedirectHandle);
|
|
assert (!LdapRedirectHandle1);
|
|
assert (!LdapRedirectHandle2);
|
|
assert (!Q931LocalRedirectHandle);
|
|
assert (!LdapLocalRedirectHandle1);
|
|
assert (!LdapLocalRedirectHandle2);
|
|
|
|
// Type 1 redirects -- for redirecting inbound connections
|
|
|
|
if (!IsFirewalled () || HasQ931PortMapping ())
|
|
{
|
|
|
|
Status = StartQ931ReceiveRedirect ();
|
|
|
|
}
|
|
|
|
if (!IsFirewalled () || HasLdapPortMapping ())
|
|
{
|
|
|
|
Status = NatCreateDynamicAdapterRestrictedPortRedirect (
|
|
0,
|
|
IPPROTO_TCP,
|
|
htons (LDAP_STANDARD_PORT),
|
|
LdapListenSocketAddress.sin_addr.s_addr,
|
|
LdapListenSocketAddress.sin_port,
|
|
AdapterIndex,
|
|
MAX_LISTEN_BACKLOG,
|
|
&LdapRedirectHandle1
|
|
);
|
|
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
|
|
DebugError (Status, _T("LDAP: Failed to create receive redirect #1 for LDAP.\n"));
|
|
|
|
return Status;
|
|
}
|
|
|
|
DebugF (_T ("LDAP: Incoming connections to %08X:%04X will be redirected to %08X:%04X.\n"),
|
|
Address,
|
|
LDAP_STANDARD_PORT,
|
|
ntohl (LdapListenSocketAddress.sin_addr.s_addr),
|
|
ntohs (LdapListenSocketAddress.sin_port));
|
|
|
|
}
|
|
|
|
if (!IsFirewalled () || HasLdapAltPortMapping ())
|
|
{
|
|
|
|
Status = NatCreateDynamicAdapterRestrictedPortRedirect (
|
|
0,
|
|
IPPROTO_TCP,
|
|
htons (LDAP_ALTERNATE_PORT),
|
|
LdapListenSocketAddress.sin_addr.s_addr,
|
|
LdapListenSocketAddress.sin_port,
|
|
AdapterIndex,
|
|
MAX_LISTEN_BACKLOG,
|
|
&LdapRedirectHandle2
|
|
);
|
|
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
|
|
DebugError (Status, _T("LDAP: Failed to create receive redirect #2 for LDAP.\n"));
|
|
|
|
return Status;
|
|
}
|
|
|
|
DebugF (_T ("LDAP: Incoming connections to %08X:%04X will be redirected to %08X:%04X.\n"),
|
|
Address,
|
|
LDAP_ALTERNATE_PORT,
|
|
ntohl (LdapListenSocketAddress.sin_addr.s_addr),
|
|
ntohs (LdapListenSocketAddress.sin_port));
|
|
|
|
}
|
|
|
|
|
|
// Type 2 redirects (for locally-originated traffic, NOT destined to the local machine)
|
|
Status = NatCreateDynamicAdapterRestrictedPortRedirect (
|
|
NatRedirectFlagSendOnly,
|
|
IPPROTO_TCP,
|
|
htons (Q931_TSAP_IP_TCP),
|
|
Q931ListenSocketAddress.sin_addr.s_addr,
|
|
Q931ListenSocketAddress.sin_port,
|
|
AdapterIndex,
|
|
MAX_LISTEN_BACKLOG,
|
|
&Q931LocalRedirectHandle
|
|
);
|
|
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
|
|
DebugError (Status, _T("Q931: Failed to create send redirect for Q.931.\n"));
|
|
|
|
return Status;
|
|
}
|
|
|
|
DebugF (_T ("Q931: Locally-originated connections through %08X:%04X will be redirected to %08X:%04X.\n"),
|
|
Address,
|
|
Q931_TSAP_IP_TCP,
|
|
ntohl (Q931ListenSocketAddress.sin_addr.s_addr),
|
|
ntohs (Q931ListenSocketAddress.sin_port));
|
|
|
|
Status = NatCreateDynamicAdapterRestrictedPortRedirect (
|
|
NatRedirectFlagSendOnly,
|
|
IPPROTO_TCP,
|
|
htons (LDAP_STANDARD_PORT),
|
|
LdapListenSocketAddress.sin_addr.s_addr,
|
|
LdapListenSocketAddress.sin_port,
|
|
AdapterIndex,
|
|
MAX_LISTEN_BACKLOG,
|
|
&LdapLocalRedirectHandle1
|
|
);
|
|
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
|
|
DebugError (Status, _T("LDAP: Failed to create send redirect #1 for LDAP.\n"));
|
|
|
|
return Status;
|
|
}
|
|
|
|
DebugF (_T ("LDAP: Locally-originated connections through %08X:%04X will be redirected to %08X:%04X.\n"),
|
|
Address,
|
|
LDAP_STANDARD_PORT,
|
|
ntohl (LdapListenSocketAddress.sin_addr.s_addr),
|
|
ntohs (LdapListenSocketAddress.sin_port));
|
|
|
|
Status = NatCreateDynamicAdapterRestrictedPortRedirect (
|
|
NatRedirectFlagSendOnly,
|
|
IPPROTO_TCP,
|
|
htons (LDAP_ALTERNATE_PORT),
|
|
LdapListenSocketAddress.sin_addr.s_addr,
|
|
LdapListenSocketAddress.sin_port,
|
|
AdapterIndex,
|
|
MAX_LISTEN_BACKLOG,
|
|
&LdapLocalRedirectHandle2
|
|
);
|
|
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
|
|
DebugError (Status, _T("LDAP: Failed to create send redirect #2 for LDAP.\n"));
|
|
|
|
return Status;
|
|
}
|
|
|
|
DebugF (_T ("LDAP: Locally-originated connections through %08X:%04X will be redirected to %08X:%04X.\n"),
|
|
Address,
|
|
LDAP_ALTERNATE_PORT,
|
|
ntohl (LdapListenSocketAddress.sin_addr.s_addr),
|
|
ntohs (LdapListenSocketAddress.sin_port));
|
|
|
|
return Status;
|
|
|
|
} // PROXY_INTERFACE::StartNatRedirects
|
|
|
|
|
|
ULONG
|
|
PROXY_INTERFACE::Start (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Starts an interface
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
Win32 error indicating what (if anything) went wrong when
|
|
the interface was being started.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG Status;
|
|
|
|
assert (0 == AdapterIndex);
|
|
assert (0 == Q931PortMapping.PrivateAddress);
|
|
assert (0 == LdapPortMapping.PrivateAddress);
|
|
assert (0 == LdapAltPortMapping.PrivateAddress);
|
|
|
|
AdapterIndex = ::NhMapAddressToAdapter (htonl (Address));
|
|
|
|
if (INVALID_INTERFACE_INDEX == AdapterIndex)
|
|
{
|
|
AdapterIndex = 0;
|
|
|
|
Status = ERROR_CAN_NOT_COMPLETE;
|
|
|
|
DebugF (_T ("PROXY_INTERFACE: Unable to map %08X to an adapter index\n"),
|
|
Address);
|
|
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Load the port mappings for this interface. Since more often than not
|
|
// there won't be a port mapping, we expect these routines to return
|
|
// errors, and thus don't check for them. NatLookupPortMappingAdapter
|
|
// will modify the out parameter (i.e., the port mapping structure) only
|
|
// on success.
|
|
//
|
|
|
|
::NatLookupPortMappingAdapter (
|
|
AdapterIndex,
|
|
NAT_PROTOCOL_TCP,
|
|
IP_NAT_ADDRESS_UNSPECIFIED,
|
|
htons (Q931_TSAP_IP_TCP),
|
|
&Q931PortMapping
|
|
);
|
|
|
|
::NatLookupPortMappingAdapter (
|
|
AdapterIndex,
|
|
NAT_PROTOCOL_TCP,
|
|
IP_NAT_ADDRESS_UNSPECIFIED,
|
|
htons (LDAP_STANDARD_PORT),
|
|
&LdapPortMapping
|
|
);
|
|
|
|
::NatLookupPortMappingAdapter (
|
|
AdapterIndex,
|
|
NAT_PROTOCOL_TCP,
|
|
IP_NAT_ADDRESS_UNSPECIFIED,
|
|
htons (LDAP_ALTERNATE_PORT),
|
|
&LdapAltPortMapping
|
|
);
|
|
|
|
Status = StartNatRedirects ();
|
|
|
|
if (STATUS_SUCCESS != Status)
|
|
{
|
|
|
|
StopNatRedirects ();
|
|
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // PROXY_INTERFACE::Start
|
|
|
|
|
|
void
|
|
PROXY_INTERFACE::StopNatRedirects (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Removes all NAT redirects created for the interface
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
None
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
if (Q931RedirectHandle)
|
|
{
|
|
|
|
NatCancelDynamicRedirect (Q931RedirectHandle);
|
|
|
|
Q931RedirectHandle = NULL;
|
|
|
|
}
|
|
|
|
if (LdapRedirectHandle1)
|
|
{
|
|
|
|
NatCancelDynamicRedirect (LdapRedirectHandle1);
|
|
|
|
LdapRedirectHandle1 = NULL;
|
|
|
|
}
|
|
|
|
if (LdapRedirectHandle2)
|
|
{
|
|
|
|
NatCancelDynamicRedirect (LdapRedirectHandle2);
|
|
|
|
LdapRedirectHandle2 = NULL;
|
|
|
|
}
|
|
|
|
if (Q931LocalRedirectHandle)
|
|
{
|
|
|
|
NatCancelDynamicRedirect (Q931LocalRedirectHandle);
|
|
|
|
Q931LocalRedirectHandle = NULL;
|
|
|
|
}
|
|
|
|
if (LdapLocalRedirectHandle1)
|
|
{
|
|
|
|
NatCancelDynamicRedirect (LdapLocalRedirectHandle1);
|
|
|
|
LdapLocalRedirectHandle1 = NULL;
|
|
|
|
}
|
|
|
|
if (LdapLocalRedirectHandle2)
|
|
{
|
|
|
|
NatCancelDynamicRedirect (LdapLocalRedirectHandle2);
|
|
|
|
LdapLocalRedirectHandle2 = NULL;
|
|
|
|
}
|
|
|
|
} // PROXY_INTERFACE::StopNatRedirects
|
|
|
|
|
|
ULONG
|
|
PROXY_INTERFACE::StartQ931ReceiveRedirect (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Creates the type 1 (receive) redirect for Q931 traffic,
|
|
if this has not already been done on the interface.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
Win32 error indicating what (if anything) went wrong
|
|
when trying to set up the redirect.
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG Status = STATUS_SUCCESS;
|
|
|
|
if (NULL == Q931RedirectHandle)
|
|
{
|
|
|
|
Status = NatCreateDynamicAdapterRestrictedPortRedirect (
|
|
0,
|
|
IPPROTO_TCP,
|
|
htons (Q931_TSAP_IP_TCP),
|
|
Q931ListenSocketAddress.sin_addr.s_addr,
|
|
Q931ListenSocketAddress.sin_port,
|
|
AdapterIndex,
|
|
MAX_LISTEN_BACKLOG,
|
|
&Q931RedirectHandle
|
|
);
|
|
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
|
|
DebugError (Status, _T("Q931: Failed to create receive redirect for Q.931.\n"));
|
|
|
|
return Status;
|
|
}
|
|
|
|
DebugF (_T ("Q931: Incoming connections to %08X:%04X will be redirected to %08X:%04X.\n"),
|
|
Address,
|
|
Q931_TSAP_IP_TCP,
|
|
ntohl (Q931ListenSocketAddress.sin_addr.s_addr),
|
|
ntohs (Q931ListenSocketAddress.sin_port));
|
|
|
|
}
|
|
|
|
return Status;
|
|
|
|
} // PROXY_INTERFACE::StartQ931ReceiveRedirect
|
|
|
|
|
|
void
|
|
PROXY_INTERFACE::StopQ931ReceiveRedirect (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Stops the Q931 receive redirect, if it has been created.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
if (Q931RedirectHandle)
|
|
{
|
|
|
|
NatCancelDynamicRedirect (Q931RedirectHandle);
|
|
|
|
Q931RedirectHandle = NULL;
|
|
|
|
}
|
|
|
|
} // PROXY_INTERFACE::StopQ931ReceiveRedirect
|
|
|
|
|
|
|
|
void
|
|
PROXY_INTERFACE::Stop (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
1. Terminate all connections through the interface.
|
|
2. Remove all translation entries registered via the interface.
|
|
3. Stop all NAT redirects created for this interface.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
None
|
|
|
|
Notes:
|
|
The caller of this method should first remove the
|
|
interface from the global array.
|
|
|
|
--*/
|
|
|
|
{
|
|
CallBridgeList.OnInterfaceShutdown (Address);
|
|
|
|
LdapConnectionArray.OnInterfaceShutdown (Address);
|
|
|
|
LdapTranslationTable.OnInterfaceShutdown (Address);
|
|
|
|
StopNatRedirects ();
|
|
|
|
::ZeroMemory (&Q931PortMapping, sizeof (Q931PortMapping));
|
|
::ZeroMemory (&LdapPortMapping, sizeof (LdapPortMapping));
|
|
::ZeroMemory (&LdapAltPortMapping, sizeof (LdapAltPortMapping));
|
|
AdapterIndex = 0;
|
|
|
|
} // PROXY_INTERFACE::Stop
|
|
|
|
|
|
BOOL
|
|
PROXY_INTERFACE::IsFirewalled (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Determines whether the interface was created as firewalled.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
TRUE - if the interface was created as firewalled.
|
|
FALSE - if the interface was created as non-firewalled.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
return InterfaceType == H323_INTERFACE_PUBLIC_FIREWALLED;
|
|
|
|
} // PROXY_INTERFACE::IsFirewalled
|
|
|
|
|
|
BOOL
|
|
PROXY_INTERFACE::IsPrivate (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Determines whether the interface was created as private.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
TRUE if the interface was created as private
|
|
FALSE if the interface was created as non-private
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
return InterfaceType == H323_INTERFACE_PRIVATE;
|
|
|
|
} // PROXY_INTERFACE::IsPrivate
|
|
|
|
|
|
BOOL
|
|
PROXY_INTERFACE::IsPublic (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Determines whether the interface was created as public.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
TRUE - if the interface was created as public.
|
|
FALSE - if the interface was created as non-public.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
return InterfaceType == H323_INTERFACE_PUBLIC
|
|
|| InterfaceType == H323_INTERFACE_PUBLIC_FIREWALLED;
|
|
|
|
} // PROXY_INTERFACE::IsPublic
|
|
|
|
|
|
|
|
BOOL
|
|
PROXY_INTERFACE::HasQ931PortMapping (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Determines whether the interface has a valid Q931 port mapping.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
TRUE if the interface has a valid Q931 port mapping
|
|
FALSE if the interface does not have a valid Q931 port mapping
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
return Q931PortMapping.PrivateAddress != 0;
|
|
|
|
} // PROXY_INTERFACE::HasQ931PortMapping
|
|
|
|
|
|
BOOL
|
|
PROXY_INTERFACE::HasLdapPortMapping (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Determines whether the interface has a valid Ldap port mapping.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
TRUE if the interface has a valid Ldap port mapping
|
|
FALSE if the interface does not have a valid Ldap port mapping
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
return LdapPortMapping.PrivateAddress != 0;
|
|
|
|
} // PROXY_INTERFACE::HasLdapPortMapping
|
|
|
|
|
|
BOOL
|
|
PROXY_INTERFACE::HasLdapAltPortMapping (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Determines whether the interface has a valid Ldap (alt) port mapping.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
TRUE if the interface has a valid Ldap (alt) port mapping
|
|
FALSE if the interface does not have a valid Ldap (alt) port mapping
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
return LdapAltPortMapping.PrivateAddress != 0;
|
|
|
|
} // PROXY_INTERFACE::HasLdapAltPortMapping
|
|
|
|
|
|
ULONG
|
|
PROXY_INTERFACE::GetQ931PortMappingDestination (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Returns the destination address of the interfaces
|
|
Q931 port mapping.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
The destination address of the port mapping, in network
|
|
byte order. Returns 0 if no port mapping exists.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
|
|
return Q931PortMapping.PrivateAddress;
|
|
|
|
} // PROXY_INTERFACE::GetQ931PortMappingDestination
|
|
|
|
|
|
ULONG
|
|
PROXY_INTERFACE::GetLdapPortMappingDestination (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Returns the destination address of the interfaces
|
|
Ldap port mapping.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
The destination address of the port mapping, in network
|
|
byte order. Returns 0 if no port mapping exists.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
|
|
return LdapPortMapping.PrivateAddress;
|
|
|
|
} // PROXY_INTERFACE::GetLdapPortMappingDestination
|
|
|
|
|
|
ULONG
|
|
PROXY_INTERFACE::GetLdapAltPortMappingDestination (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Returns the destination address of the interfaces
|
|
Ldap-alt port mapping.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
The destination address of the port mapping, in network
|
|
byte order. Returns 0 if no port mapping exists.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
return LdapAltPortMapping.PrivateAddress;
|
|
|
|
} // PROXY_INTERFACE::GetLdapAltPortMappingDestination
|
|
|
|
// PROXY_INTERFACE_ARRAY ------------------------------------------------------
|
|
|
|
|
|
HRESULT
|
|
PROXY_INTERFACE_ARRAY::Add (
|
|
IN PROXY_INTERFACE* Interface
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Adds an interface to the array.
|
|
|
|
Arguments:
|
|
Interface - interface to be added.
|
|
|
|
Return Values:
|
|
Error code indicating whether the operation succeeded.
|
|
|
|
Notes:
|
|
To be called from locked context.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD ReturnIndex;
|
|
PROXY_INTERFACE** ElementPlaceholder;
|
|
|
|
assert (Interface);
|
|
|
|
if (Array.FindIndex (CompareInterfacesByIndex, &Interface, &ReturnIndex))
|
|
{
|
|
// Interface with this index already exists
|
|
return E_FAIL;
|
|
}
|
|
|
|
ElementPlaceholder = Array.AllocAtPos (ReturnIndex);
|
|
|
|
if (!ElementPlaceholder)
|
|
return E_OUTOFMEMORY;
|
|
|
|
*ElementPlaceholder = Interface;
|
|
|
|
return S_OK;
|
|
|
|
} // PROXY_INTERFACE_ARRAY::Add
|
|
|
|
|
|
PROXY_INTERFACE**
|
|
PROXY_INTERFACE_ARRAY::FindByIndex (
|
|
IN DWORD Index
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Finds an interface by the interface index.
|
|
|
|
Arguments:
|
|
Index - index of the interface being searched for.
|
|
|
|
Return Values:
|
|
Pointer to the entry associated with the interface, if interface
|
|
with the index is in the array.
|
|
NULL if the interface with the index is not in the array.
|
|
|
|
Notes:
|
|
1. To be called from locked context
|
|
2. Does not transfer ownership of the interface being searched for
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
BOOL SearchResult;
|
|
DWORD ArrayIndex;
|
|
|
|
SearchResult = Array.BinarySearch (
|
|
SearchInterfaceByIndex,
|
|
&Index,
|
|
&ArrayIndex);
|
|
|
|
if (SearchResult)
|
|
{
|
|
|
|
return &Array [ArrayIndex];
|
|
}
|
|
|
|
return NULL;
|
|
|
|
} // PROXY_INTERFACE_ARRAY::FindByIndex
|
|
|
|
|
|
PROXY_INTERFACE *
|
|
PROXY_INTERFACE_ARRAY::RemoveByIndex (
|
|
IN DWORD Index
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Removes an interface with given index from the array.
|
|
|
|
Arguments:
|
|
Index - index of the interface to be removed.
|
|
|
|
Return Values:
|
|
Pointer to the removed interface, if interface with the
|
|
index is in the array.
|
|
NULL if interface with this index cannot be found in the
|
|
array.
|
|
|
|
Notes:
|
|
1. To be called from locked context
|
|
2. Transfers ownership of the interface being removed
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PROXY_INTERFACE * ReturnInterface = NULL;
|
|
PROXY_INTERFACE ** Interface;
|
|
|
|
Interface = FindByIndex (Index);
|
|
|
|
if (Interface)
|
|
{
|
|
|
|
ReturnInterface = *Interface;
|
|
Array.DeleteEntry (Interface);
|
|
}
|
|
|
|
return ReturnInterface;
|
|
|
|
} // PROXY_INTERFACE_ARRAY::RemoveByIndex
|
|
|
|
|
|
HRESULT
|
|
PROXY_INTERFACE_ARRAY::IsPrivateAddress (
|
|
IN DWORD Address, // host order
|
|
OUT BOOL * IsPrivate
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Determines whether the address specified is
|
|
reachable through a private interface.
|
|
|
|
Arguments:
|
|
Address - IP address for which the determination
|
|
is to be made.
|
|
|
|
IsPrivate - Result of the determination (TRUE or FALSE)
|
|
|
|
Return Values:
|
|
Error code indicating whether the query succeeded.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
DWORD ArrayIndex;
|
|
PROXY_INTERFACE * Interface;
|
|
DWORD BestInterfaceAddress;
|
|
ULONG Error;
|
|
|
|
Error = GetBestInterfaceAddress (Address, &BestInterfaceAddress);
|
|
|
|
if (ERROR_SUCCESS != Error)
|
|
{
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
*IsPrivate = FALSE;
|
|
|
|
Lock ();
|
|
|
|
for (ArrayIndex = 0; ArrayIndex < Array.Length; ArrayIndex++)
|
|
{
|
|
|
|
Interface = Array [ArrayIndex];
|
|
|
|
if (Interface -> Address == BestInterfaceAddress && Interface -> IsPrivate ())
|
|
{
|
|
|
|
*IsPrivate = TRUE;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
Unlock ();
|
|
|
|
return S_OK;
|
|
|
|
} // PROXY_INTERFACE_ARRAY::IsPrivateAddress
|
|
|
|
|
|
HRESULT
|
|
PROXY_INTERFACE_ARRAY::IsPublicAddress (
|
|
IN DWORD Address, // host order
|
|
OUT BOOL * IsPublic
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Determines whether the address specified is
|
|
reachable through a public interface.
|
|
|
|
Arguments:
|
|
Address - IP address for which the determination
|
|
is to be made.
|
|
|
|
IsPrivate - Result of the determination (TRUE or FALSE)
|
|
|
|
Return Values:
|
|
Error code indicating whether the query succeded.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
DWORD ArrayIndex;
|
|
PROXY_INTERFACE * Interface;
|
|
DWORD BestInterfaceAddress;
|
|
ULONG Error;
|
|
|
|
Error = GetBestInterfaceAddress (Address, &BestInterfaceAddress);
|
|
|
|
if (ERROR_SUCCESS != Error)
|
|
{
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
*IsPublic = FALSE;
|
|
|
|
Lock ();
|
|
|
|
for (ArrayIndex = 0; ArrayIndex < Array.Length; ArrayIndex++)
|
|
{
|
|
|
|
Interface = Array [ArrayIndex];
|
|
|
|
if (Interface -> Address == BestInterfaceAddress && Interface -> IsPublic ())
|
|
{
|
|
|
|
*IsPublic = TRUE;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
Unlock ();
|
|
|
|
return S_OK;
|
|
|
|
} // PROXY_INTERFACE_ARRAY::IsPublicAddress
|
|
|
|
|
|
void
|
|
PROXY_INTERFACE_ARRAY::Stop (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Stops all interfaces (in the array) that were not previously stopped.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Values:
|
|
None
|
|
|
|
Notes:
|
|
Normally, all the interfaces should have been individually stopped
|
|
prior to calling this method, in which case it does nothing.
|
|
If some interfaces were not stopped, when the method is called, it
|
|
will issue a warning and stop them.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
DWORD Index;
|
|
|
|
Lock ();
|
|
|
|
if (Array.Length)
|
|
{
|
|
|
|
DebugF (_T("WARNING: Some interfaces are still active (should have already been deactivated). Starting deactivation procedures...\n"));
|
|
|
|
for (Index = 0; Index < Array.Length; Index++)
|
|
{
|
|
|
|
Array[Index] -> Stop ();
|
|
|
|
}
|
|
}
|
|
|
|
Array.Free ();
|
|
|
|
Unlock ();
|
|
|
|
} // PROXY_INTERFACE_ARRAY::Stop
|
|
|
|
|
|
ULONG
|
|
PROXY_INTERFACE_ARRAY::AddStartInterface (
|
|
IN ULONG Index,
|
|
IN H323_INTERFACE_TYPE ArgInterfaceType,
|
|
IN PIP_ADAPTER_BINDING_INFO BindingInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Creates new interface, adds it to the array, and starts it.
|
|
|
|
Arguments:
|
|
Index - Index of the interface to be created.
|
|
ArgInterfaceType - Type of the interface to be created (PRIVATE
|
|
or PUBLIC)
|
|
BindingInfo - Binding information for the interface (address, mask, and
|
|
adapter index)
|
|
|
|
Return Values:
|
|
Win32 error code indicating success or failure of any of
|
|
the above three operations.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
HRESULT Result;
|
|
ULONG Error = ERROR_NOT_READY; // anything but ERROR_SUCCESS
|
|
PROXY_INTERFACE * Interface;
|
|
|
|
Lock ();
|
|
|
|
if (FindByIndex (Index))
|
|
{
|
|
|
|
Error = ERROR_INTERFACE_ALREADY_EXISTS;
|
|
|
|
} else {
|
|
|
|
Interface = new PROXY_INTERFACE (Index, ArgInterfaceType, BindingInfo);
|
|
|
|
if (Interface)
|
|
{
|
|
|
|
Result = Add (Interface);
|
|
|
|
if (S_OK == Result)
|
|
{
|
|
|
|
Error = Interface -> Start ();
|
|
|
|
if (ERROR_SUCCESS == Error)
|
|
{
|
|
|
|
DebugF(_T("H323: Interface %S activated, index %d\n"),
|
|
INET_NTOA (BindingInfo -> Address[0].Address), Index);
|
|
|
|
if (Q931ReceiveRedirectStartCount > 0
|
|
&& Interface -> IsFirewalled ()
|
|
&& !Interface -> HasQ931PortMapping ())
|
|
{
|
|
|
|
Interface -> StartQ931ReceiveRedirect ();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
RemoveByIndex (Interface -> Index);
|
|
|
|
delete Interface;
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (Result) {
|
|
|
|
case E_FAIL:
|
|
Error = ERROR_INTERFACE_ALREADY_EXISTS;
|
|
break;
|
|
|
|
case E_OUTOFMEMORY:
|
|
Error = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
|
|
default:
|
|
Error = ERROR_CAN_NOT_COMPLETE;
|
|
break;
|
|
|
|
}
|
|
|
|
delete Interface;
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
Error = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
|
|
Unlock ();
|
|
|
|
return Error;
|
|
|
|
} // PROXY_INTERFACE_ARRAY::AddStartInterface
|
|
|
|
|
|
void
|
|
PROXY_INTERFACE_ARRAY::RemoveStopInterface (
|
|
IN DWORD Index
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Removes an interface from the array, and stops it.
|
|
|
|
Arguments:
|
|
Index - index of the interface to be removed and stopped.
|
|
|
|
Return Values:
|
|
None
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PROXY_INTERFACE* Interface;
|
|
|
|
Lock ();
|
|
|
|
Interface = RemoveByIndex (Index);
|
|
|
|
if (Interface)
|
|
{
|
|
|
|
Interface -> Stop ();
|
|
|
|
delete Interface;
|
|
Interface = NULL;
|
|
|
|
} else {
|
|
|
|
DebugF (_T("PROXY_INTERFACE_ARRAY::StopRemoveByIndex -- Tried to deactivate interface (index %d), but it does not exist.\n"),
|
|
Index);
|
|
}
|
|
|
|
Unlock ();
|
|
|
|
} // PROXY_INTERFACE_ARRAY::RemoveStopInterface
|
|
|
|
void
|
|
PROXY_INTERFACE_ARRAY::StartQ931ReceiveRedirects (
|
|
void
|
|
)
|
|
|
|
{
|
|
|
|
Lock();
|
|
|
|
if (0 == Q931ReceiveRedirectStartCount++)
|
|
{
|
|
|
|
for (DWORD dwIndex = 0; dwIndex < Array.Length; dwIndex++)
|
|
{
|
|
|
|
Array[dwIndex] -> StartQ931ReceiveRedirect ();
|
|
|
|
}
|
|
}
|
|
|
|
Unlock();
|
|
|
|
} // PROXY_INTERFACE_ARRAY::StartQ931ReceiveRedirects
|
|
|
|
void
|
|
PROXY_INTERFACE_ARRAY::StopQ931ReceiveRedirects (
|
|
void
|
|
)
|
|
|
|
{
|
|
|
|
Lock();
|
|
|
|
assert (Q931ReceiveRedirectStartCount > 0);
|
|
|
|
if (0 == --Q931ReceiveRedirectStartCount)
|
|
{
|
|
|
|
for (DWORD dwIndex = 0; dwIndex < Array.Length; dwIndex++)
|
|
{
|
|
|
|
if (Array[dwIndex] -> IsFirewalled ()
|
|
&& !Array[dwIndex] -> HasQ931PortMapping ())
|
|
{
|
|
|
|
Array[dwIndex] -> StopQ931ReceiveRedirect ();
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
Unlock();
|
|
|
|
} // PROXY_INTERFACE_ARRAY::StopQ931ReceiveRedirects
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Auxiliary Functions //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
static
|
|
int
|
|
__cdecl
|
|
CompareInterfacesByIndex (
|
|
IN PROXY_INTERFACE * const * InterfaceA,
|
|
IN PROXY_INTERFACE * const * InterfaceB
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Compares two interfaces by their corresponding indices.
|
|
|
|
Arguments:
|
|
InterfaceA - first comparand
|
|
InterfaceB - second comparand
|
|
|
|
Return Values:
|
|
1 if InterfaceA is considered to be greater than InterfaceB
|
|
0 if InterfaceA is considered to be equal to the InterfaceB
|
|
-1 if InterfaceA is considered to be equal to the InterfaceB
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
assert (InterfaceA);
|
|
assert (InterfaceB);
|
|
assert (*InterfaceA);
|
|
assert (*InterfaceB);
|
|
|
|
if ((*InterfaceA) -> GetIndex () > (*InterfaceB) -> GetIndex ())
|
|
{
|
|
|
|
return 1;
|
|
|
|
} else if ((*InterfaceA) -> GetIndex () < (*InterfaceB) -> GetIndex ()) {
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} // ::CompareInterfacesByIndex
|
|
|
|
|
|
static
|
|
INT
|
|
SearchInterfaceByIndex (
|
|
IN const DWORD * Index,
|
|
IN PROXY_INTERFACE * const * Comparand
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Compares an interface and a key (index of the interface)
|
|
|
|
Arguments:
|
|
Index - key to which the interface is to be compared
|
|
Comparand - interface to be compared with the key
|
|
|
|
Return Values:
|
|
1 if key is considered to be greater than the comparand
|
|
0 if key is considered to be equal to the comparand
|
|
-1 if key is considered to be less than the comparand
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
assert (Comparand);
|
|
assert (*Comparand);
|
|
assert (Index);
|
|
|
|
if (*Index > (*Comparand) -> GetIndex ())
|
|
{
|
|
|
|
return 1;
|
|
|
|
} else if (*Index < (*Comparand) -> GetIndex ()) {
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} // ::SearchInterfaceByIndex
|
|
|
|
|
|
HRESULT
|
|
IsPrivateAddress (
|
|
IN DWORD Address,
|
|
OUT BOOL * IsPrivate
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Determines whether the address specified is
|
|
reachable through a private interface.
|
|
|
|
Arguments:
|
|
Address - IP address for which the determination
|
|
is to be made.
|
|
|
|
IsPrivate - Result of the determination (TRUE or FALSE)
|
|
|
|
Return Values:
|
|
Error code indicating whether the query succeded.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
assert (IsPrivate);
|
|
|
|
return InterfaceArray.IsPrivateAddress (Address, IsPrivate);
|
|
|
|
} // ::IsPrivateAddress
|
|
|
|
|
|
HRESULT
|
|
IsPublicAddress (
|
|
IN DWORD Address,
|
|
OUT BOOL * IsPublic
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Determines whether the address specified is
|
|
reachable through a public interface.
|
|
|
|
Arguments:
|
|
Address - IP address for which the determination
|
|
is to be made.
|
|
|
|
IsPrivate - Result of the determination (TRUE or FALSE)
|
|
|
|
Return Values:
|
|
Error code indicating whether the query succeded.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
assert (IsPublic);
|
|
|
|
return InterfaceArray.IsPublicAddress (Address, IsPublic);
|
|
|
|
} // ::IsPublicAddress
|