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.
238 lines
5.2 KiB
238 lines
5.2 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
caddrlst.hxx
|
|
|
|
Abstract:
|
|
|
|
Contains CAddressList class definition
|
|
|
|
Contents:
|
|
|
|
Author:
|
|
|
|
Richard L Firth (rfirth) 21-Apr-1997
|
|
|
|
Revision History:
|
|
|
|
21-Apr-1997 rfirth
|
|
Created
|
|
|
|
--*/
|
|
|
|
//
|
|
// manifests
|
|
//
|
|
|
|
#define CSADDR_BUFFER_LENGTH (sizeof(CSADDR_INFO) + 128)
|
|
|
|
//
|
|
// types
|
|
//
|
|
|
|
//
|
|
// RESOLVED_ADDRESS - a CSADDR_INFO with additional IsBad field which is set
|
|
// when we fail to connect to the address
|
|
//
|
|
|
|
typedef struct {
|
|
CSADDR_INFO AddrInfo;
|
|
BOOL IsValid;
|
|
} RESOLVED_ADDRESS, * LPRESOLVED_ADDRESS;
|
|
|
|
//
|
|
// forward references
|
|
//
|
|
|
|
class CFsm_ResolveHost;
|
|
|
|
//
|
|
// classes
|
|
//
|
|
|
|
//
|
|
// CAddressList - maintains list of resolved addresses for a host name/port
|
|
// combination
|
|
//
|
|
|
|
class CAddressList {
|
|
|
|
private:
|
|
|
|
CRITICAL_SECTION m_CritSec; // grab this before updating
|
|
DWORD m_ResolutionId; // determines when OK to resolve
|
|
INT m_CurrentAddress; // index of current (good) address
|
|
INT m_AddressCount; // number of addresses in list
|
|
INT m_BadAddressCount; // number addresses already tried & failed
|
|
LPRESOLVED_ADDRESS m_Addresses; // list of resolved addresses
|
|
|
|
DWORD
|
|
IPAddressToAddressList(
|
|
IN DWORD ipAddr
|
|
);
|
|
|
|
DWORD
|
|
HostentToAddressList(
|
|
IN LPHOSTENT lpHostent
|
|
);
|
|
|
|
DWORD
|
|
AddrInfoToAddressList(
|
|
IN struct addrinfo FAR *lpAddrInfo
|
|
);
|
|
|
|
public:
|
|
|
|
CAddressList() {
|
|
InitializeCriticalSection(&m_CritSec);
|
|
m_ResolutionId = 0;
|
|
m_CurrentAddress = 0;
|
|
m_AddressCount = 0;
|
|
m_BadAddressCount = 0;
|
|
m_Addresses = NULL;
|
|
}
|
|
|
|
~CAddressList() {
|
|
FreeList();
|
|
DeleteCriticalSection(&m_CritSec);
|
|
}
|
|
|
|
VOID Acquire(VOID) {
|
|
EnterCriticalSection(&m_CritSec);
|
|
}
|
|
|
|
VOID Release(VOID) {
|
|
LeaveCriticalSection(&m_CritSec);
|
|
}
|
|
|
|
VOID
|
|
FreeList(
|
|
VOID
|
|
);
|
|
|
|
DWORD
|
|
SetList(
|
|
IN DWORD dwIpAddress
|
|
);
|
|
|
|
DWORD
|
|
SetList(
|
|
IN LPHOSTENT lpHostent
|
|
);
|
|
|
|
DWORD
|
|
SetList(
|
|
IN struct addrinfo *lpAddrInfo
|
|
);
|
|
|
|
BOOL
|
|
GetNextAddress(
|
|
IN OUT LPDWORD lpdwResolutionId,
|
|
IN OUT LPDWORD lpdwIndex,
|
|
IN INTERNET_PORT nPort,
|
|
OUT LPCSADDR_INFO lpResolvedAddress
|
|
);
|
|
|
|
VOID
|
|
InvalidateAddress(
|
|
IN DWORD dwResolutionId,
|
|
IN DWORD dwAddressIndex
|
|
);
|
|
|
|
DWORD
|
|
ResolveHost(
|
|
IN LPSTR lpszHostName,
|
|
IN OUT LPDWORD lpdwResolutionId,
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
DWORD
|
|
ResolveHost_Fsm(
|
|
IN CFsm_ResolveHost * Fsm
|
|
);
|
|
|
|
VOID NextAddress(VOID) {
|
|
++m_CurrentAddress;
|
|
if (m_CurrentAddress == m_AddressCount) {
|
|
m_CurrentAddress = 0;
|
|
}
|
|
}
|
|
|
|
LPCSADDR_INFO CurrentAddress(VOID) {
|
|
return &m_Addresses[m_CurrentAddress].AddrInfo;
|
|
}
|
|
|
|
LPSOCKADDR LocalSockaddr() {
|
|
return CurrentAddress()->LocalAddr.lpSockaddr;
|
|
}
|
|
|
|
INT LocalSockaddrLength() {
|
|
return CurrentAddress()->LocalAddr.iSockaddrLength;
|
|
}
|
|
|
|
INT LocalFamily(VOID) {
|
|
return (INT)LocalSockaddr()->sa_family;
|
|
}
|
|
|
|
INT LocalPort() {
|
|
//
|
|
// The port number field is in the same location in both a
|
|
// sockaddr_in and a sockaddr_in6, so it is safe to cast the
|
|
// sockaddr to sockaddr_in here - this works for IPv4 or IPv6.
|
|
//
|
|
INET_ASSERT(offsetof(SOCKADDR_IN, sin_port) ==
|
|
offsetof(SOCKADDR_IN6, sin6_port));
|
|
return ((LPSOCKADDR_IN)LocalSockaddr())->sin_port;
|
|
}
|
|
|
|
VOID SetLocalPort(INTERNET_PORT Port) {
|
|
//
|
|
// The port number field is in the same location in both a
|
|
// sockaddr_in and a sockaddr_in6, so it is safe to cast the
|
|
// sockaddr to sockaddr_in here - this works for IPv4 or IPv6.
|
|
//
|
|
INET_ASSERT(offsetof(SOCKADDR_IN, sin_port) ==
|
|
offsetof(SOCKADDR_IN6, sin6_port));
|
|
((LPSOCKADDR_IN)LocalSockaddr())->sin_port = Port;
|
|
}
|
|
|
|
LPSOCKADDR RemoteSockaddr() {
|
|
return CurrentAddress()->RemoteAddr.lpSockaddr;
|
|
}
|
|
|
|
INT RemoteSockaddrLength() {
|
|
return CurrentAddress()->RemoteAddr.iSockaddrLength;
|
|
}
|
|
|
|
INT RemoteFamily(VOID) {
|
|
return (INT)RemoteSockaddr()->sa_family;
|
|
}
|
|
|
|
INT RemotePort() {
|
|
//
|
|
// The port number field is in the same location in both a
|
|
// sockaddr_in and a sockaddr_in6, so it is safe to cast the
|
|
// sockaddr to sockaddr_in here - this works for IPv4 or IPv6.
|
|
//
|
|
INET_ASSERT(offsetof(SOCKADDR_IN, sin_port) ==
|
|
offsetof(SOCKADDR_IN6, sin6_port));
|
|
return ((LPSOCKADDR_IN)RemoteSockaddr())->sin_port;
|
|
}
|
|
|
|
INT SocketType(VOID) {
|
|
return CurrentAddress()->iSocketType;
|
|
}
|
|
|
|
INT Protocol(VOID) {
|
|
return CurrentAddress()->iProtocol;
|
|
}
|
|
|
|
BOOL IsCurrentAddressValid(VOID) {
|
|
return m_Addresses[m_CurrentAddress].IsValid;
|
|
}
|
|
};
|
|
|
|
|