//+---------------------------------------------------------------------------- // // File: control.cpp // // Module: // // Description: Implement class CWlbsControl // // Copyright (C) Microsoft Corporation. All rights reserved. // // Author: Created 3/2/00 // //+---------------------------------------------------------------------------- #include "precomp.h" #include #include "cluster.h" #include "control.h" #include "param.h" #include "control.tmh" // for event tracing // // Global variable for the dll instance // HINSTANCE g_hInstCtrl; // // Helper functions // DWORD MapStateFromDriverToApi(DWORD dwDriverState); //+---------------------------------------------------------------------------- // // Function: IsLocalHost // // Description: // // Arguments: CWlbsCluster* pCluster - // DWORD dwHostID - // // Returns: inline bool - // // History: fengsun Created Header 3/2/00 // //+---------------------------------------------------------------------------- inline bool IsLocalHost(CWlbsCluster* pCluster, DWORD dwHostID) { if (pCluster == NULL) { return false; } return dwHostID == WLBS_LOCAL_HOST; // || pCluster->GetHostID() == dwHostID; } //+---------------------------------------------------------------------------- // // Function: QueryPortFromSocket // // Synopsis: // This routine retrieves the port number to which a socket is bound. // // Arguments: // Socket - the socket to be queried // // Return Value: // USHORT - the port number retrieved // // History: Created Header 2/10/99 // //+---------------------------------------------------------------------------- static USHORT QueryPortFromSocket(SOCKET Socket) { SOCKADDR_IN Address; int AddressLength; AddressLength = sizeof(Address); getsockname(Socket, (PSOCKADDR)&Address, &AddressLength); return Address.sin_port; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::CWlbsControl // // Description: // // Arguments: None // // Returns: Nothing // // History: fengsun Created Header 3/2/00 // //+---------------------------------------------------------------------------- CWlbsControl::CWlbsControl() { m_local_ctrl = FALSE; m_remote_ctrl = FALSE; m_hdl = INVALID_HANDLE_VALUE; m_registry_lock = INVALID_HANDLE_VALUE; m_def_dst_addr = 0; m_def_timeout = IOCTL_REMOTE_RECV_DELAY; m_def_port = CVY_DEF_RCT_PORT; m_def_passw = CVY_DEF_RCT_PASSWORD; m_dwNumCluster = 0; for (int i = 0; i < WLBS_MAX_CLUSTERS; i ++) { m_cluster_params [i] . cluster = 0; m_cluster_params [i] . passw = CVY_DEF_RCT_PASSWORD; m_cluster_params [i] . timeout = IOCTL_REMOTE_RECV_DELAY; m_cluster_params [i] . port = CVY_DEF_RCT_PORT; m_cluster_params [i] . dest = 0; } ZeroMemory(m_pClusterArray, sizeof(m_pClusterArray)); } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::~CWlbsControl // // Description: // // Arguments: None // // Returns: Nothing // // History: fengsun Created Header 3/2/00 // //+---------------------------------------------------------------------------- CWlbsControl::~CWlbsControl() { for (DWORD i=0; i< m_dwNumCluster; i++) { delete m_pClusterArray[i]; } if (m_hdl) { CloseHandle(m_hdl); } if (m_remote_ctrl) { WSACleanup(); // WSAStartup is called in Initialize() } } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::Initialize // // Description: Initialization // // Arguments: None // // Returns: bool - true if succeeded // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::Initialize() { WORD ver; int ret; if (IsInitialized()) { ReInitialize(); return GetInitResult(); } _tsetlocale (LC_ALL, _TEXT(".OCP")); /* open Winsock */ WSADATA data; if (WSAStartup (WINSOCK_VERSION, & data) == 0) { /* figure out client IP address */ CHAR buf [CVY_STR_SIZE]; ret = gethostname (buf, CVY_STR_SIZE); if (ret != SOCKET_ERROR) { struct hostent * host; host = gethostbyname (buf); m_dwSrcAddress = 0; if ( host && ((struct in_addr *) (host -> h_addr)) -> s_addr != 0) { m_remote_ctrl = TRUE; m_dwSrcAddress = ((struct in_addr *) (host -> h_addr)) -> s_addr; } } if (!m_remote_ctrl) { LOG_ERROR1("CWlbsControl::Initialize failed. gethostname return %d", ret); WSACleanup(); } } /* if succeeded querying local parameters - connect to device */ if (m_hdl != INVALID_HANDLE_VALUE) CloseHandle (m_hdl); m_hdl = CreateFile (_TEXT("\\\\.\\WLBS"), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); if (m_hdl == INVALID_HANDLE_VALUE) { LOG_ERROR1("CWlbsControl::Initialize failed to open wlbs device %d", GetLastError()); return GetInitResult(); } else { m_local_ctrl = TRUE; } // // enumerate clusters // HKEY hKeyWlbs; DWORD dwError; dwError = RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters\\Interface", 0L, KEY_READ, & hKeyWlbs); if (dwError != ERROR_SUCCESS) { return GetInitResult(); } m_dwNumCluster = 0; for (int index=0;;index++) { WCHAR szAdapterGuid[128]; DWORD dwSize = sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]); dwError = RegEnumKeyEx(hKeyWlbs, index, szAdapterGuid, &dwSize, NULL, NULL, NULL, NULL); if (dwError != ERROR_SUCCESS) { if (dwError != ERROR_NO_MORE_ITEMS) { LOG_ERROR1("CWlbsControl::Initialize failed at RegEnumKeyEx %d", dwError); } break; } GUID AdapterGuid; HRESULT hr = CLSIDFromString(szAdapterGuid, &AdapterGuid); if (FAILED(hr)) { LOG_ERROR1("CWlbsControl::Initialize failed at CLSIDFromString %s", szAdapterGuid); continue; } IOCTL_CVY_BUF in_buf; IOCTL_CVY_BUF out_buf; DWORD status = WlbsLocalControl (m_hdl, AdapterGuid, IOCTL_CVY_QUERY, & in_buf, & out_buf, 0); if (status == WLBS_IO_ERROR) { continue; } // // Use index instead of m_dwNumCluster as the cluster index // m_dwNumCluster will change is a adapter get unbound. // index will change only if an adapter get removed // m_pClusterArray[m_dwNumCluster] = new CWlbsCluster(index); if (m_pClusterArray[m_dwNumCluster] == NULL) { LOG_ERROR("CWlbsControl::Initialize failed to allocate memory"); ASSERT(m_pClusterArray[m_dwNumCluster]); } else { m_pClusterArray[m_dwNumCluster]->Initialize(AdapterGuid); m_dwNumCluster++; } } RegCloseKey(hKeyWlbs); return GetInitResult(); } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::ReInitialize // // Description: Re-Initialization to get the current cluster list // // Arguments: None // // Returns: bool - true if succeeded // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- bool CWlbsControl::ReInitialize() { ASSERT(m_hdl != INVALID_HANDLE_VALUE); if ( m_hdl == INVALID_HANDLE_VALUE ) { return false; } HKEY hKeyWlbs; DWORD dwError; dwError = RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters\\Interface", 0L, KEY_READ, & hKeyWlbs); if (dwError != ERROR_SUCCESS) { LOG_ERROR("CWlbsControl::Initialize failed at RegOpenKeyEx"); return false; } // // Re enumerate the clusters // DWORD dwNewNumCluster = 0; // the number of new clusters bool fClusterExists[WLBS_MAX_CLUSTERS]; CWlbsCluster* NewClusterArray[WLBS_MAX_CLUSTERS]; for (DWORD i=0;iGetAdapterGuid())) { ASSERT(fClusterExists[j] == false); fClusterExists[j] = true; // // Since adapter could be added or removed, since last time, // The index could be changed // m_pClusterArray[j]->m_dwConfigIndex = index; break; } } // // It is a new adapter // if (j == m_dwNumCluster) { CWlbsCluster* pCluster = new CWlbsCluster(index); if (pCluster == NULL) { LOG_ERROR("CWlbsControl::ReInitialize failed to allocate memory"); ASSERT(pCluster); } else { pCluster->Initialize(AdapterGuid); // // Add // NewClusterArray[dwNewNumCluster] = pCluster; dwNewNumCluster++; } } } RegCloseKey(hKeyWlbs); // // Create the new cluster array // for (i=0; i< m_dwNumCluster; i++) { if (!fClusterExists[i]) { delete m_pClusterArray[i]; } else { // // Reload settings // m_pClusterArray[i]->ReInitialize(); NewClusterArray[dwNewNumCluster] = m_pClusterArray[i]; dwNewNumCluster++; } m_pClusterArray[i] = NULL; } // // Copy the array back // m_dwNumCluster = dwNewNumCluster; CopyMemory(m_pClusterArray, NewClusterArray, m_dwNumCluster * sizeof(m_pClusterArray[0])); ASSERT(m_pClusterArray[m_dwNumCluster] == NULL); return true; } //+---------------------------------------------------------------------------- // // Function: MapStateFromDriverToApi // // Description: Map the state return from wlbs driver to the API state // // Arguments: DWORD dwDriverState - // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD MapStateFromDriverToApi(DWORD dwDriverState) { struct STATE_MAP { DWORD dwDriverState; DWORD dwApiState; } StateMap[] = { {IOCTL_CVY_ALREADY, WLBS_ALREADY}, {IOCTL_CVY_BAD_PARAMS, WLBS_BAD_PARAMS}, {IOCTL_CVY_NOT_FOUND, WLBS_NOT_FOUND}, {IOCTL_CVY_STOPPED, WLBS_STOPPED}, {IOCTL_CVY_SUSPENDED, WLBS_SUSPENDED}, {IOCTL_CVY_CONVERGING, WLBS_CONVERGING}, {IOCTL_CVY_SLAVE, WLBS_CONVERGED}, {IOCTL_CVY_MASTER, WLBS_DEFAULT}, {IOCTL_CVY_BAD_PASSWORD, WLBS_BAD_PASSW}, {IOCTL_CVY_DRAINING, WLBS_DRAINING}, {IOCTL_CVY_DRAINING_STOPPED, WLBS_DRAIN_STOP}, {IOCTL_CVY_DISCONNECTED, WLBS_DISCONNECTED}, }; for (int i=0; iGetClusterIp() == dwClusterIp) { return m_pClusterArray[i]; } } return NULL; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::GetClusterFromAdapter // // Description: Get the cluster object from adapter guid // // Arguments: GUID *pAdapterGuid -- GUID of the adapter. // // Returns: CWlbsCluster* - Caller can NOT free the return object // // History: JosephJ Created 4/20/01 // //+---------------------------------------------------------------------------- inline CWlbsCluster* CWlbsControl::GetClusterFromAdapter(IN const GUID &AdapterGuid) { for (DWORD i=0; i< m_dwNumCluster; i++) { const GUID& Guid = m_pClusterArray[i]->GetAdapterGuid(); if (IsEqualGUID(Guid, AdapterGuid)) { return m_pClusterArray[i]; } } return NULL; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::ValidateParam // // Description: Validate the specified WLBS cluster parameter. It has no side effects other to munge paramp, for example reformatting // IP addresses into canonical form. // // Arguments: paramp -- params to validate // // Returns: TRUE if params look valid, false otherwise. // // History: JosephJ Created 4/25/01 // //+---------------------------------------------------------------------------- BOOL CWlbsControl::ValidateParam( IN OUT PWLBS_REG_PARAMS paramp ) { return ::ParamValidate(paramp)!=0; } // // //+---------------------------------------------------------------------------- // // Function: CWlbsControl::LocalClusterControl // // Description: Performs local cluster-wide control operations on the // specified GUID. // // Arguments: AdapterGuid -- GUID of the adapter. // ioctl -- cluster control ioctl. // // Returns: WLBS return code // // History: JosephJ Created 4/25/01 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::LocalClusterControl( IN const GUID& AdapterGuid, IN LONG ioctl ) { DWORD status; IOCTL_CVY_BUF in_buf; IOCTL_CVY_BUF out_buf; status = GetInitResult(); if (status == WLBS_INIT_ERROR) { goto end; } // // We only support cluster-wide operations... // switch(ioctl) { case IOCTL_CVY_CLUSTER_ON: break; case IOCTL_CVY_CLUSTER_OFF: break; case IOCTL_CVY_CLUSTER_SUSPEND: break; case IOCTL_CVY_CLUSTER_RESUME: break; case IOCTL_CVY_CLUSTER_DRAIN: break; default: status = WLBS_BAD_PARAMS; goto end; } ZeroMemory(&in_buf, sizeof(in_buf)); status = WlbsLocalControl (m_hdl, AdapterGuid, ioctl, & in_buf, & out_buf, 0); if (status != WLBS_IO_ERROR) { status = MapStateFromDriverToApi (out_buf.ret_code); } end: return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControlWrapper::GetClusterFromIpOrIndex // // Description: // // Arguments: DWORD dwClusterIpOrIndex - // // Returns: CWlbsCluster* - // // History: fengsun Created Header 7/3/00 // //+---------------------------------------------------------------------------- CWlbsCluster* CWlbsControl::GetClusterFromIpOrIndex(DWORD dwClusterIpOrIndex) { for (DWORD i=0; iGetClusterIpOrIndex(this) == dwClusterIpOrIndex) { return m_pClusterArray[i]; } } return NULL; } /* * Function: CWlbsControlWrapper::IsClusterMember * Description: This function searches the list of known NLB clusters on this * host to determine whether or not this host is a member of a * given cluster. * Author: shouse, Created 4.16.01 */ BOOLEAN CWlbsControl::IsClusterMember (DWORD dwClusterIp) { for (DWORD i = 0; i < m_dwNumCluster; i++) { if (m_pClusterArray[i]->GetClusterIp() == dwClusterIp) return TRUE; } return FALSE; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::EnumClusterObjects // // Description: Get a list of cluster objects // // Arguments: OUT CWlbsCluster** &pdwClusters - The memory is internal to CWlbsControl /// Caller can NOT free the pdwClusters memory // OUT DWORD* pdwNum - // // Returns: DWORD - // // History: fengsun Created Header 3/3/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::EnumClusterObjects(OUT CWlbsCluster** &ppClusters, OUT DWORD* pdwNum) { ASSERT(pdwNum); ppClusters = m_pClusterArray; *pdwNum = m_dwNumCluster; return ERROR_SUCCESS; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::EnumClusters // // Description: Get a list of cluster IP or index // // Arguments: OUT DWORD* pdwAddresses - // IN OUT DWORD* pdwNum - IN size of the buffer, OUT element returned // // Returns: DWORD - WLBS error code. // // History: fengsun Created Header 3/3/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::EnumClusters(OUT DWORD* pdwAddresses, IN OUT DWORD* pdwNum) { if (pdwNum == NULL) { return WLBS_BAD_PARAMS; } if (pdwAddresses == NULL || *pdwNum < m_dwNumCluster) { *pdwNum = m_dwNumCluster; return ERROR_MORE_DATA; } *pdwNum = m_dwNumCluster; for (DWORD i=0; i< m_dwNumCluster; i++) { pdwAddresses[i] = m_pClusterArray[i]->GetClusterIpOrIndex(this); } return WLBS_OK; } //+---------------------------------------------------------------------------- // // Function: WlbsLocalControl // // Description: Send DeviceIoControl to local driver // // Arguments: HANDLE hDevice - // const GUID& AdapterGuid - the guid of the adapter // LONG ioctl - // PIOCTL_CVY_BUF in_bufp - // PIOCTL_CVY_BUF out_bufp - // // Returns: DWORD - // // History: fengsun Created Header 3/9/00 // //+---------------------------------------------------------------------------- DWORD WlbsLocalControl(HANDLE hDevice, const GUID& AdapterGuid, LONG ioctl, PIOCTL_CVY_BUF in_bufp, PIOCTL_CVY_BUF out_bufp, DWORD vip) { BOOLEAN res; DWORD act; // // Add adapter GUID // IOCTL_LOCAL_HDR inBuf; IOCTL_LOCAL_HDR outBuf; WCHAR szGuid[128]; StringFromGUID2(AdapterGuid, szGuid, sizeof(szGuid)/ sizeof(szGuid[0])); lstrcpy(inBuf.device_name, L"\\device\\"); lstrcat(inBuf.device_name, szGuid); inBuf.ctrl = *in_bufp; switch (ioctl) { case IOCTL_CVY_CLUSTER_ON: case IOCTL_CVY_CLUSTER_OFF: break; case IOCTL_CVY_PORT_ON: case IOCTL_CVY_PORT_OFF: case IOCTL_CVY_PORT_SET: case IOCTL_CVY_PORT_DRAIN: { /* Set the port options. */ inBuf.options.port.flags = 0; inBuf.options.port.virtual_ip_addr = vip; break; } case IOCTL_CVY_QUERY: break; case IOCTL_CVY_CLUSTER_DRAIN: case IOCTL_CVY_CLUSTER_SUSPEND: case IOCTL_CVY_CLUSTER_RESUME: break; case IOCTL_CVY_QUERY_STATE: break; default: break; } res = (BOOLEAN) DeviceIoControl (hDevice, ioctl, &inBuf, sizeof (inBuf), &outBuf, sizeof (outBuf), & act, NULL); *out_bufp = outBuf.ctrl; if (! res || act != sizeof (outBuf)) return WLBS_IO_ERROR; return WLBS_OK; } //+---------------------------------------------------------------------------- // // Function: NotifyDriverConfigChanges // // Description: Notify wlbs driver to pick up configuration changes from // registry // // Arguments: HANDLE hDeviceWlbs - The WLBS driver device handle // const GUID& - AdapterGuid Adapter guid // // // Returns: DWORD - Win32 Error code // // History: fengsun Created Header 2/3/00 // //+---------------------------------------------------------------------------- DWORD WINAPI NotifyDriverConfigChanges(HANDLE hDeviceWlbs, const GUID& AdapterGuid) { LONG status; IOCTL_CVY_BUF in_buf; IOCTL_CVY_BUF out_buf; status = WlbsLocalControl (hDeviceWlbs, AdapterGuid, IOCTL_CVY_RELOAD, & in_buf, & out_buf, 0); return ERROR_SUCCESS; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsRemoteControl // // Description: Send a remote control packet // // Arguments: ONG ioctl - // PIOCTL_CVY_BUF pin_bufp - // PIOCTL_CVY_BUF pout_bufp - // PWLBS_RESPONSE pcvy_resp - // PDWORD nump - // DWORD trg_addr - // DWORD hst_addr // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsRemoteControl ( LONG ioctl, PIOCTL_CVY_BUF pin_bufp, PIOCTL_CVY_BUF pout_bufp, PWLBS_RESPONSE pcvy_resp, PDWORD nump, DWORD trg_addr, DWORD hst_addr, DWORD vip ) { INT ret; BOOLEAN responded [WLBS_MAX_HOSTS], heard; BOOL broadcast; DWORD mode, num_sends, num_recvs; SOCKET sock = INVALID_SOCKET; SOCKADDR_IN caddr, saddr; DWORD i, hosts; IOCTL_REMOTE_HDR rct_req; IOCTL_REMOTE_HDR rct_rep; PIOCTL_CVY_BUF in_bufp = & rct_req . ctrl; DWORD timeout; WORD port; DWORD dst_addr; DWORD passw; * in_bufp = * pin_bufp; timeout = m_def_timeout; port = m_def_port; dst_addr = m_def_dst_addr; passw = m_def_passw; // LOCK(m_lock); // // Find parameters for the cluster // for (i = 0; i < WLBS_MAX_CLUSTERS; i ++) { if (m_cluster_params [i] . cluster == trg_addr) break; } if (i < WLBS_MAX_CLUSTERS) { timeout = m_cluster_params [i] . timeout; port = m_cluster_params [i] . port; dst_addr = m_cluster_params [i] . dest; passw = m_cluster_params [i] . passw; } CWlbsCluster* pCluster = GetClusterFromIp(trg_addr); /* if (pCluster) { // // Always uses password in registry for local cluster // passw = pCluster->GetPassword(); } */ // UNLOCK(m_lock); if (dst_addr == 0) dst_addr = trg_addr; rct_req . code = IOCTL_REMOTE_CODE; rct_req . version = CVY_VERSION_FULL; rct_req . id = GetTickCount (); rct_req . cluster = trg_addr; rct_req . host = hst_addr; rct_req . addr = m_dwSrcAddress; rct_req . password = passw; rct_req . ioctrl = ioctl; switch (ioctl) { case IOCTL_CVY_CLUSTER_ON: case IOCTL_CVY_CLUSTER_OFF: break; case IOCTL_CVY_PORT_ON: case IOCTL_CVY_PORT_OFF: case IOCTL_CVY_PORT_SET: case IOCTL_CVY_PORT_DRAIN: { /* Set the port options. */ rct_req.options.port.flags = 0; rct_req.options.port.virtual_ip_addr = vip; break; } case IOCTL_CVY_QUERY: { BOOLEAN bIsMember = IsClusterMember(trg_addr); /* Reset the flags. */ rct_req.options.query.flags = 0; /* Reset the hostname. */ rct_req.options.query.hostname[0] = 0; /* If I am myself a member of the target cluster, then set the query cluster flags appropriately. */ if (bIsMember) rct_req.options.query.flags |= IOCTL_OPTIONS_QUERY_CLUSTER_MEMBER; /* Request the hostname from each host. */ rct_req.options.query.flags |= IOCTL_OPTIONS_QUERY_HOSTNAME;; break; } case IOCTL_CVY_CLUSTER_DRAIN: case IOCTL_CVY_CLUSTER_SUSPEND: case IOCTL_CVY_CLUSTER_RESUME: break; case IOCTL_CVY_QUERY_STATE: break; default: break; } /* now create socket */ sock = socket (AF_INET, SOCK_DGRAM, 0); if (sock == INVALID_SOCKET) return WSAGetLastError(); /* set socket to nonblocking mode */ mode = 1; ret = ioctlsocket (sock, FIONBIO, & mode); if (ret == SOCKET_ERROR) { closesocket (sock); return WSAGetLastError(); } /* bind client's address to socket */ caddr . sin_family = AF_INET; caddr . sin_port = htons (0); BOOLEAN fBound = FALSE; if (pCluster) { // // For local cluster, always bind to the cluster IP. // Can not bind to the dedicated IP, which could be for a different NIC. // caddr . sin_addr . s_addr = trg_addr; if (bind (sock, (LPSOCKADDR) & caddr, sizeof (caddr)) != SOCKET_ERROR) { fBound = TRUE; } } if (!fBound) { // // For remote cluster, or fail to bind VIP/DIP, bind to the any IP // caddr . sin_addr . s_addr = htonl (INADDR_ANY); if (bind (sock, (LPSOCKADDR) & caddr, sizeof (caddr)) != SOCKET_ERROR) { fBound = TRUE; } } if (!fBound) { LOG_ERROR1("CWlbsControl::WlbsRemoteControl failed at bind %d", WSAGetLastError()); closesocket (sock); return WSAGetLastError(); } WORD wMyPort; wMyPort = QueryPortFromSocket(sock); // // The client is bound to the remote control server port // Let's get another port // if (wMyPort == htons (port)) { closesocket (sock); sock = socket (AF_INET, SOCK_DGRAM, 0); if (sock == INVALID_SOCKET) return WSAGetLastError(); /* set socket to nonblocking mode */ mode = 1; ret = ioctlsocket (sock, FIONBIO, & mode); if (ret == SOCKET_ERROR) { closesocket (sock); return WSAGetLastError(); } ret = bind (sock, (LPSOCKADDR) & caddr, sizeof (caddr)); if (ret == SOCKET_ERROR) { closesocket (sock); return WSAGetLastError(); } } /* setup server's address */ saddr . sin_family = AF_INET; saddr . sin_port = htons (port); if ( pCluster ) // local cluster { /* enable sending broadcast on the socket */ broadcast = TRUE; ret = setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *) & broadcast, sizeof (broadcast)); if (ret == SOCKET_ERROR) { closesocket (sock); return WSAGetLastError(); } saddr . sin_addr . s_addr = INADDR_BROADCAST; } else saddr . sin_addr . s_addr = dst_addr; for (i = 0; i < WLBS_MAX_HOSTS; i ++) responded [i] = FALSE; heard = FALSE; hosts = 0; for (num_sends = 0; num_sends < IOCTL_REMOTE_SEND_RETRIES; num_sends ++) { /* send remote control request message */ ret = sendto (sock, (PCHAR) & rct_req, sizeof (rct_req), 0, (LPSOCKADDR) & saddr, sizeof (saddr)); if (ret == SOCKET_ERROR) { LOG_ERROR1("CWlbsControl::WlbsRemoteControl failed at sendto %d", WSAGetLastError()); // // Sendto could fail if the adapter is too busy. Allow retry // Sleep (timeout); continue; // closesocket (sock); // return WSAGetLastError(); } if (ret != sizeof (rct_req)) continue; for (num_recvs = 0; num_recvs < IOCTL_REMOTE_RECV_RETRIES; num_recvs ++) { /* recv remote control reply message */ ret = recv (sock, (PCHAR) & rct_rep, sizeof (rct_rep), 0); if (ret == SOCKET_ERROR) { if (WSAGetLastError() == WSAEWOULDBLOCK) { Sleep (timeout); continue; } else if (WSAGetLastError() == WSAECONNRESET) { // // Remote control is disabled // continue; } else { closesocket (sock); return WSAGetLastError(); } } if (ret != sizeof (rct_rep)) { Sleep (timeout); continue; } if (rct_rep . cluster != trg_addr) { Sleep (timeout); continue; } if (rct_rep . code != IOCTL_REMOTE_CODE) { Sleep (timeout); continue; } if (rct_rep . id != rct_req . id) { Sleep (timeout); continue; } if (rct_rep . host > WLBS_MAX_HOSTS || rct_rep . host == 0 ) { Sleep (timeout); continue; } if (! responded [rct_rep . host - 1]) { if (hosts < WLBS_MAX_HOSTS) { pout_bufp [hosts] = rct_rep . ctrl; if (hosts < * nump && pcvy_resp != NULL) { pcvy_resp [hosts] . id = rct_rep . host; pcvy_resp [hosts] . address = rct_rep . addr; if (rct_req . ioctrl == IOCTL_CVY_QUERY) { pcvy_resp [hosts] . status = MapStateFromDriverToApi (rct_rep . ctrl . data . query . state); lstrcpy(pcvy_resp[hosts].hostname, rct_rep.options.query.hostname); } else { pcvy_resp [hosts] . status = MapStateFromDriverToApi (rct_rep . ctrl . ret_code); } } hosts ++; } } responded [rct_rep . host - 1] = TRUE; heard = TRUE; if (hst_addr != WLBS_ALL_HOSTS) { * nump = hosts; closesocket (sock); return WLBS_OK; } } } * nump = hosts; closesocket (sock); if (! heard) return WLBS_TIMEOUT; return WLBS_OK; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsQuery // // Description: // // Arguments: CWlbsCluster* pCluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts - // PDWORD host_map - // PVOID // reserved // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsQuery ( CWlbsCluster* pCluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts, PDWORD host_map, PVOID // reserved ) { LONG ioctl = IOCTL_CVY_QUERY; DWORD status; IOCTL_CVY_BUF in_buf; if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult(); /* The following condition is to take care of the case when num_hosts is null * and host_map contains some junk value. This could crash this function. */ if (num_hosts == NULL) response = NULL; else if (*num_hosts == 0) response = NULL; if (pCluster && IsLocalHost(pCluster, host)) { IOCTL_CVY_BUF out_buf; status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(), ioctl, & in_buf, & out_buf, 0); if (status == WLBS_IO_ERROR) return status; if (host_map != NULL) * host_map = out_buf . data . query . host_map; if (response != NULL) { response [0] . id = out_buf . data . query . host_id; response [0] . address = 0; response [0] . status = MapStateFromDriverToApi (out_buf . data . query . state); } if (num_hosts != NULL) * num_hosts = 1; status = MapStateFromDriverToApi (out_buf . data . query . state); } else { status = RemoteQuery(pCluster->GetClusterIp(), host, response, num_hosts, host_map); } return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsQuery // // Description: // // Arguments: WORD cluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts - // PDWORD host_map - // PVOID // reserved // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsQuery ( DWORD cluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts, PDWORD host_map, PVOID // reserved ) { DWORD ret; TRACE_INFO("> WlbsQuery: cluster=0x%lx, host=0x%lx", cluster, host); if (GetInitResult() == WLBS_INIT_ERROR) { ret = GetInitResult(); goto end; } if (cluster == WLBS_LOCAL_CLUSTER && (GetInitResult() == WLBS_REMOTE_ONLY)) { ret = GetInitResult(); goto end; } CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster); if (pCluster == NULL) { ret = RemoteQuery(cluster, host, response, num_hosts, host_map); goto end; } else { ret = WlbsQuery(pCluster, host, response, num_hosts, host_map, NULL); goto end; } end: TRACE_INFO("< WlbsQuery: return %d", ret); return ret; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::RemoteQuery // // Description: // // Arguments: DWORD cluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts - // PDWORD host_map - // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::RemoteQuery ( DWORD cluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts, PDWORD host_map ) { LONG ioctl = IOCTL_CVY_QUERY; DWORD status; IOCTL_CVY_BUF in_buf; IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS]; DWORD hosts; DWORD hmap = 0; DWORD active; DWORD i; if (GetInitResult() == WLBS_LOCAL_ONLY) return GetInitResult(); if (num_hosts != NULL) hosts = * num_hosts; else hosts = 0; status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts, cluster, host, 0); if (status >= WSABASEERR || status == WLBS_TIMEOUT) { if (num_hosts != NULL) * num_hosts = 0; return status; } if (host == WLBS_ALL_HOSTS) { for (status = WLBS_STOPPED, active = 0, i = 0; i < hosts; i ++) { switch (MapStateFromDriverToApi (out_buf [i] . data . query . state)) { case WLBS_SUSPENDED: if (status == WLBS_STOPPED) status = WLBS_SUSPENDED; break; case WLBS_CONVERGING: if (status != WLBS_BAD_PASSW) status = WLBS_CONVERGING; break; case WLBS_DRAINING: if (status == WLBS_STOPPED) status = WLBS_DRAINING; break; case WLBS_CONVERGED: if (status != WLBS_CONVERGING && status != WLBS_BAD_PASSW) status = WLBS_CONVERGED; hmap = out_buf [i] . data . query . host_map; active ++; break; case WLBS_BAD_PASSW: status = WLBS_BAD_PASSW; break; case WLBS_DEFAULT: if (status != WLBS_CONVERGING && status != WLBS_BAD_PASSW) status = WLBS_CONVERGED; hmap = out_buf [i] . data . query . host_map; active ++; break; case WLBS_STOPPED: default: break; } } if (status == WLBS_CONVERGED) status = active; } else { status = MapStateFromDriverToApi (out_buf [0] . data . query . state); hmap = out_buf [0] . data . query . host_map; } if (host_map != NULL) * host_map = hmap; if (num_hosts != NULL) * num_hosts = hosts; return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsSuspend // // Description: // // Arguments: WORD cluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsSuspend ( DWORD cluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts ) { LONG ioctl = IOCTL_CVY_CLUSTER_SUSPEND; DWORD status; IOCTL_CVY_BUF in_buf; if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult(); if (num_hosts == NULL) response = NULL; else if (*num_hosts == 0) response = NULL; CWlbsCluster* pCluster= GetClusterFromIpOrIndex(cluster); if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY)) return GetInitResult(); if (pCluster && IsLocalHost(pCluster, host)) { IOCTL_CVY_BUF out_buf; status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(), ioctl, & in_buf, & out_buf, 0); if (status == WLBS_IO_ERROR) return status; if (num_hosts != NULL) * num_hosts = 0; status = MapStateFromDriverToApi (out_buf . ret_code); } else { IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS]; DWORD hosts; DWORD i; if (GetInitResult() == WLBS_LOCAL_ONLY) return GetInitResult(); if (num_hosts != NULL) hosts = * num_hosts; else hosts = 0; status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts, cluster, host, 0); if (status >= WSABASEERR || status == WLBS_TIMEOUT) return status; if (host == WLBS_ALL_HOSTS) { for (status = WLBS_OK, i = 0; i < hosts; i ++) { switch (MapStateFromDriverToApi (out_buf [i] . ret_code)) { case WLBS_BAD_PASSW: status = WLBS_BAD_PASSW; break; case WLBS_OK: case WLBS_ALREADY: case WLBS_STOPPED: case WLBS_DRAIN_STOP: default: break; } } } else { status = MapStateFromDriverToApi (out_buf [0] . ret_code); } if (num_hosts != NULL) * num_hosts = hosts; } return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsResume // // Description: // // Arguments: WORD cluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsResume ( DWORD cluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts ) { LONG ioctl = IOCTL_CVY_CLUSTER_RESUME; DWORD status; IOCTL_CVY_BUF in_buf; if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult(); if (num_hosts == NULL) response = NULL; else if (*num_hosts == 0) response = NULL; CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster); if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY)) return GetInitResult(); if (pCluster && IsLocalHost(pCluster, host)) { IOCTL_CVY_BUF out_buf; status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(), ioctl, & in_buf, & out_buf, 0); if (status == WLBS_IO_ERROR) return status; if (num_hosts != NULL) * num_hosts = 0; status = MapStateFromDriverToApi (out_buf . ret_code); } else { IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS]; DWORD hosts; DWORD i; if (GetInitResult() == WLBS_LOCAL_ONLY) return GetInitResult(); if (num_hosts != NULL) hosts = * num_hosts; else hosts = 0; status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts, cluster, host, 0); if (status >= WSABASEERR || status == WLBS_TIMEOUT) return status; if (host == WLBS_ALL_HOSTS) { for (status = WLBS_OK, i = 0; i < hosts; i ++) { switch (MapStateFromDriverToApi (out_buf [i] . ret_code)) { case WLBS_BAD_PASSW: status = WLBS_BAD_PASSW; break; case WLBS_OK: case WLBS_ALREADY: default: break; } } } else { status = MapStateFromDriverToApi (out_buf [0] . ret_code); } if (num_hosts != NULL) * num_hosts = hosts; } return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsStart // // Description: // // Arguments: WORD cluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsStart ( DWORD cluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts ) { LONG ioctl = IOCTL_CVY_CLUSTER_ON; DWORD status; IOCTL_CVY_BUF in_buf; if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult(); if (num_hosts == NULL) response = NULL; else if (*num_hosts == 0) response = NULL; CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster); if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY)) return GetInitResult(); if (pCluster && IsLocalHost(pCluster, host)) { IOCTL_CVY_BUF out_buf; status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(), ioctl, & in_buf, & out_buf, 0); if (status == WLBS_IO_ERROR) return status; if (num_hosts != NULL) * num_hosts = 0; status = MapStateFromDriverToApi (out_buf . ret_code); } else { IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS]; DWORD hosts; DWORD i; if (GetInitResult() == WLBS_LOCAL_ONLY) return GetInitResult(); if (num_hosts != NULL) hosts = * num_hosts; else hosts = 0; status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts, cluster, host, 0); if (status >= WSABASEERR || status == WLBS_TIMEOUT) return status; if (host == WLBS_ALL_HOSTS) { for (status = WLBS_OK, i = 0; i < hosts; i ++) { switch (MapStateFromDriverToApi (out_buf [i] . ret_code)) { case WLBS_BAD_PARAMS: if (status != WLBS_BAD_PASSW) status = WLBS_BAD_PARAMS; break; case WLBS_BAD_PASSW: status = WLBS_BAD_PASSW; break; case WLBS_SUSPENDED: if (status != WLBS_BAD_PASSW && status != WLBS_BAD_PARAMS) status = WLBS_SUSPENDED; break; case WLBS_OK: case WLBS_ALREADY: case WLBS_DRAIN_STOP: break; default: break; } } } else { status = MapStateFromDriverToApi (out_buf [0] . ret_code); } if (num_hosts != NULL) * num_hosts = hosts; } return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsStop // // Description: // // Arguments: WORD cluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsStop ( DWORD cluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts ) { LONG ioctl = IOCTL_CVY_CLUSTER_OFF; DWORD status; IOCTL_CVY_BUF in_buf; if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult(); if (num_hosts == NULL) response = NULL; else if (*num_hosts == 0) response = NULL; CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster); if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY)) return GetInitResult(); if (pCluster && IsLocalHost(pCluster, host)) { IOCTL_CVY_BUF out_buf; status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(), ioctl, & in_buf, & out_buf, 0); if (status == WLBS_IO_ERROR) return status; if (num_hosts != NULL) * num_hosts = 0; status = MapStateFromDriverToApi (out_buf . ret_code); } else { IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS]; DWORD hosts; DWORD i; if (GetInitResult() == WLBS_LOCAL_ONLY) return GetInitResult(); if (num_hosts != NULL) hosts = * num_hosts; else hosts = 0; status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts, cluster, host, 0); if (status >= WSABASEERR || status == WLBS_TIMEOUT) return status; if (host == WLBS_ALL_HOSTS) { for (status = WLBS_OK, i = 0; i < hosts; i ++) { switch (MapStateFromDriverToApi (out_buf [i] . ret_code)) { case WLBS_BAD_PASSW: status = WLBS_BAD_PASSW; break; case WLBS_SUSPENDED: if (status != WLBS_BAD_PASSW) status = WLBS_SUSPENDED; break; case WLBS_OK: case WLBS_ALREADY: case WLBS_DRAIN_STOP: default: break; } } } else { status = MapStateFromDriverToApi (out_buf [0] . ret_code); } if (num_hosts != NULL) * num_hosts = hosts; } return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsDrainStop // // Description: // // Arguments: WORD cluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsDrainStop ( DWORD cluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts ) { LONG ioctl = IOCTL_CVY_CLUSTER_DRAIN; DWORD status; IOCTL_CVY_BUF in_buf; if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult(); if (num_hosts == NULL) response = NULL; else if (*num_hosts == 0) response = NULL; CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster); if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY)) return GetInitResult(); if (pCluster && IsLocalHost(pCluster, host)) { IOCTL_CVY_BUF out_buf; status = WlbsLocalControl (m_hdl,pCluster->GetAdapterGuid(), ioctl, & in_buf, & out_buf, 0); if (status == WLBS_IO_ERROR) return status; if (num_hosts != NULL) * num_hosts = 0; status = MapStateFromDriverToApi (out_buf . ret_code); } else { IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS]; DWORD hosts; DWORD i; if (GetInitResult() == WLBS_LOCAL_ONLY) return GetInitResult(); if (num_hosts != NULL) hosts = * num_hosts; else hosts = 0; status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts, cluster, host, 0); if (status >= WSABASEERR || status == WLBS_TIMEOUT) return status; if (host == WLBS_ALL_HOSTS) { for (status = WLBS_STOPPED, i = 0; i < hosts; i ++) { switch (MapStateFromDriverToApi (out_buf [i] . ret_code)) { case WLBS_BAD_PASSW: status = WLBS_BAD_PASSW; break; case WLBS_SUSPENDED: if (status != WLBS_BAD_PASSW) status = WLBS_SUSPENDED; break; case WLBS_OK: case WLBS_ALREADY: if (status != WLBS_BAD_PASSW && status != WLBS_SUSPENDED) status = WLBS_OK; case WLBS_STOPPED: default: break; } } } else { status = MapStateFromDriverToApi (out_buf [0] . ret_code); } if (num_hosts != NULL) * num_hosts = hosts; } return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsEnable // // Description: // // Arguments: WORD cluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts - // DWORD port // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsEnable ( DWORD cluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts, DWORD vip, DWORD port ) { LONG ioctl = IOCTL_CVY_PORT_ON; DWORD status; IOCTL_CVY_BUF in_buf; if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult(); if (num_hosts == NULL) response = NULL; else if (*num_hosts == 0) response = NULL; in_buf . data . port . num = port; CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster); if (pCluster&& (GetInitResult() == WLBS_REMOTE_ONLY)) return GetInitResult(); if (pCluster && IsLocalHost(pCluster, host)) { IOCTL_CVY_BUF out_buf; status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(), ioctl, & in_buf, & out_buf, vip); if (status == WLBS_IO_ERROR) return status; if (num_hosts != NULL) * num_hosts = 0; status = MapStateFromDriverToApi (out_buf . ret_code); } else { IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS]; DWORD hosts; DWORD i; if (GetInitResult() == WLBS_LOCAL_ONLY) return GetInitResult(); if (num_hosts != NULL) hosts = * num_hosts; else hosts = 0; status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts, cluster, host, vip); if (status >= WSABASEERR || status == WLBS_TIMEOUT) return status; if (host == WLBS_ALL_HOSTS) { for (status = WLBS_OK, i = 0; i < hosts; i ++) { switch (MapStateFromDriverToApi (out_buf [i] . ret_code)) { case WLBS_BAD_PASSW: status = WLBS_BAD_PASSW; break; case WLBS_NOT_FOUND: if (status != WLBS_BAD_PASSW) status = WLBS_NOT_FOUND; break; case WLBS_SUSPENDED: if (status != WLBS_BAD_PASSW && status != WLBS_NOT_FOUND) status = WLBS_SUSPENDED; break; case WLBS_OK: case WLBS_ALREADY: case WLBS_STOPPED: case WLBS_DRAINING: default: break; } } } else { status = MapStateFromDriverToApi (out_buf [0] . ret_code); } if (num_hosts != NULL) * num_hosts = hosts; } return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsDisable // // Description: // // Arguments: WORD cluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts - // DWORD port // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsDisable ( DWORD cluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts, DWORD vip, DWORD port ) { LONG ioctl = IOCTL_CVY_PORT_OFF; DWORD status; IOCTL_CVY_BUF in_buf; if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult(); if (num_hosts == NULL) response = NULL; else if (*num_hosts == 0) response = NULL; in_buf . data . port . num = port; CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster); if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY)) return GetInitResult(); if (pCluster && IsLocalHost(pCluster, host)) { IOCTL_CVY_BUF out_buf; status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(), ioctl, & in_buf, & out_buf, vip); if (status == WLBS_IO_ERROR) return status; if (num_hosts != NULL) * num_hosts = 0; status = MapStateFromDriverToApi (out_buf . ret_code); } else { IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS]; DWORD hosts; DWORD i; if (GetInitResult() == WLBS_LOCAL_ONLY) return GetInitResult(); if (num_hosts != NULL) hosts = * num_hosts; else hosts = 0; status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts, cluster, host, vip); if (status >= WSABASEERR || status == WLBS_TIMEOUT) return status; if (host == WLBS_ALL_HOSTS) { for (status = WLBS_OK, i = 0; i < hosts; i ++) { switch (MapStateFromDriverToApi (out_buf [i] . ret_code)) { case WLBS_BAD_PASSW: status = WLBS_BAD_PASSW; break; case WLBS_NOT_FOUND: if (status != WLBS_BAD_PASSW) status = WLBS_NOT_FOUND; break; case WLBS_SUSPENDED: if (status != WLBS_BAD_PASSW && status != WLBS_NOT_FOUND) status = WLBS_SUSPENDED; break; case WLBS_OK: case WLBS_ALREADY: case WLBS_STOPPED: case WLBS_DRAINING: default: break; } } } else { status = MapStateFromDriverToApi (out_buf [0] . ret_code); } if (num_hosts != NULL) * num_hosts = hosts; } return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsDrain // // Description: // // Arguments: WORD cluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts - // DWORD port // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsDrain ( DWORD cluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts, DWORD vip, DWORD port ) { LONG ioctl = IOCTL_CVY_PORT_DRAIN; DWORD status; IOCTL_CVY_BUF in_buf; if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult(); if (num_hosts == NULL) response = NULL; else if (*num_hosts == 0) response = NULL; in_buf . data . port . num = port; CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster); if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY)) return GetInitResult(); if (pCluster && IsLocalHost(pCluster, host)) { IOCTL_CVY_BUF out_buf; status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(), ioctl, & in_buf, & out_buf, vip); if (status == WLBS_IO_ERROR) return status; if (num_hosts != NULL) * num_hosts = 0; status = MapStateFromDriverToApi (out_buf . ret_code); } else { IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS]; DWORD hosts; DWORD i; if (GetInitResult() == WLBS_LOCAL_ONLY) return GetInitResult(); if (num_hosts != NULL) hosts = * num_hosts; else hosts = 0; status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts, cluster, host, vip); if (status >= WSABASEERR || status == WLBS_TIMEOUT) return status; if (host == WLBS_ALL_HOSTS) { for (status = WLBS_OK, i = 0; i < hosts; i ++) { switch (MapStateFromDriverToApi (out_buf [i] . ret_code)) { case WLBS_BAD_PASSW: status = WLBS_BAD_PASSW; break; case WLBS_NOT_FOUND: if (status != WLBS_BAD_PASSW) status = WLBS_NOT_FOUND; break; case WLBS_SUSPENDED: if (status != WLBS_BAD_PASSW && status != WLBS_NOT_FOUND) status = WLBS_SUSPENDED; break; case WLBS_OK: case WLBS_ALREADY: case WLBS_STOPPED: case WLBS_DRAINING: default: break; } } } else { status = MapStateFromDriverToApi (out_buf [0] . ret_code); } if (num_hosts != NULL) * num_hosts = hosts; } return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsAdjust // // Description: // // Arguments: WORD cluster - // DWORD host - // PWLBS_RESPONSE response - // PDWORD num_hosts - // DWORD port - // DWORD value // // Returns: DWORD - // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- DWORD CWlbsControl::WlbsAdjust ( DWORD cluster, DWORD host, PWLBS_RESPONSE response, PDWORD num_hosts, DWORD port, DWORD value ) { LONG ioctl = IOCTL_CVY_PORT_SET; DWORD status; IOCTL_CVY_BUF in_buf; if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult(); in_buf . data . port . num = port; in_buf . data . port . load = value; CWlbsCluster* pCluster = GetClusterFromIpOrIndex(cluster); if (pCluster && (GetInitResult() == WLBS_REMOTE_ONLY)) return GetInitResult(); if (pCluster && IsLocalHost(pCluster, host)) { IOCTL_CVY_BUF out_buf; status = WlbsLocalControl (m_hdl, pCluster->GetAdapterGuid(), ioctl, & in_buf, & out_buf, 0); if (status == WLBS_IO_ERROR) return status; if (num_hosts != NULL) * num_hosts = 0; status = MapStateFromDriverToApi (out_buf . ret_code); } else { IOCTL_CVY_BUF out_buf [WLBS_MAX_HOSTS]; DWORD hosts; DWORD i; if (GetInitResult() == WLBS_LOCAL_ONLY) return GetInitResult(); if (num_hosts != NULL) hosts = * num_hosts; else hosts = 0; status = WlbsRemoteControl (ioctl, & in_buf, out_buf, response, & hosts, cluster, host, 0); if (status >= WSABASEERR || status == WLBS_TIMEOUT) return status; if (host == WLBS_ALL_HOSTS) { for (status = WLBS_OK, i = 0; i < hosts; i ++) { switch (MapStateFromDriverToApi (out_buf [i] . ret_code)) { case WLBS_BAD_PASSW: status = WLBS_BAD_PASSW; break; case WLBS_NOT_FOUND: if (status != WLBS_BAD_PASSW) status = WLBS_NOT_FOUND; break; case WLBS_SUSPENDED: if (status != WLBS_BAD_PASSW && status != WLBS_NOT_FOUND) status = WLBS_SUSPENDED; break; case WLBS_OK: case WLBS_ALREADY: case WLBS_STOPPED: case WLBS_DRAINING: default: break; } } } else { status = MapStateFromDriverToApi (out_buf [0] . ret_code); } if (num_hosts != NULL) * num_hosts = hosts; } return status; } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsPortSet // // Description: // // Arguments: DWORD cluster - // WORD port - // // Returns: Nothing // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- VOID CWlbsControl::WlbsPortSet(DWORD cluster, WORD port) { DWORD i; DWORD j; WORD rct_port; // LOCK(global_info.lock); if (port == 0) rct_port = CVY_DEF_RCT_PORT; else rct_port = port; if (cluster == WLBS_ALL_CLUSTERS) { /* when all clusters are targeted - change the default and go through the entire parameter table setting new values */ m_def_port = rct_port; for (i = 0; i < WLBS_MAX_CLUSTERS; i ++) m_cluster_params [i] . port = rct_port; } else { for (i = 0, j = WLBS_MAX_CLUSTERS; i < WLBS_MAX_CLUSTERS; i ++) { /* mark an empty slot in case we will have to enter a new value */ if (j == WLBS_MAX_CLUSTERS && m_cluster_params [i] . cluster == 0) j = i; if (m_cluster_params [i] . cluster == cluster) { m_cluster_params [i] . port = rct_port; break; } } /* if we did not locate specified cluster in the table and there is an empty slot - enter new cluster info in the table */ if (i >= WLBS_MAX_CLUSTERS && j != WLBS_MAX_CLUSTERS) { m_cluster_params [j] . cluster = cluster; m_cluster_params [j] . port = rct_port; } } // UNLOCK(global_info.lock); } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsPasswordSet // // Description: // // Arguments: WORD cluster - // PTCHAR password // // Returns: Nothing // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- VOID CWlbsControl::WlbsPasswordSet ( DWORD cluster, const WCHAR* password ) { DWORD i; DWORD j; DWORD passw; // LOCK(global_info.lock); if (password != NULL) { #ifndef UNICODE passw = License_string_encode (password); #else passw = License_wstring_encode((WCHAR*)password); #endif } else passw = CVY_DEF_RCT_PASSWORD; if (cluster == WLBS_ALL_CLUSTERS) { /* when all clusters are targeted - change the default and go through the entire parameter table setting new values */ m_def_passw = passw; for (i = 0; i < WLBS_MAX_CLUSTERS; i ++) m_cluster_params [i] . passw = passw; } else { for (i = 0, j = WLBS_MAX_CLUSTERS; i < WLBS_MAX_CLUSTERS; i ++) { /* mark an empty slot in case we will have to enter a new value */ if (j == WLBS_MAX_CLUSTERS && m_cluster_params [i] . cluster == 0) j = i; if (m_cluster_params [i] . cluster == cluster) { m_cluster_params [i] . passw = passw; break; } } /* if we did not locate specified cluster in the table and there is an empty slot - enter new cluster info in the table */ if (i >= WLBS_MAX_CLUSTERS && j != WLBS_MAX_CLUSTERS) { m_cluster_params [j] . cluster = cluster; m_cluster_params [j] . passw = passw; } } // UNLOCK(global_info.lock); } /* end WlbsPasswordSet */ VOID CWlbsControl::WlbsCodeSet ( DWORD cluster, DWORD passw ) { DWORD i; DWORD j; // LOCK(global_info.lock); if (cluster == WLBS_ALL_CLUSTERS) { /* when all clusters are targeted - change the default and go through the entire parameter table setting new values */ m_def_passw = passw; for (i = 0; i < WLBS_MAX_CLUSTERS; i ++) m_cluster_params [i] . passw = passw; } else { for (i = 0, j = WLBS_MAX_CLUSTERS; i < WLBS_MAX_CLUSTERS; i ++) { /* mark an empty slot in case we will have to enter a new value */ if (j == WLBS_MAX_CLUSTERS && m_cluster_params [i] . cluster == 0) j = i; if (m_cluster_params [i] . cluster == cluster) { m_cluster_params [i] . passw = passw; break; } } /* if we did not locate specified cluster in the table and there is an empty slot - enter new cluster info in the table */ if (i >= WLBS_MAX_CLUSTERS && j != WLBS_MAX_CLUSTERS) { m_cluster_params [j] . cluster = cluster; m_cluster_params [j] . passw = passw; } } // UNLOCK(global_info.lock); } /* end WlbsCodeSet */ VOID CWlbsControl::WlbsDestinationSet ( DWORD cluster, DWORD dest ) { DWORD i; DWORD j; // LOCK(global_info.lock); if (cluster == WLBS_ALL_CLUSTERS) { /* when all clusters are targeted - change the default and go through the entire parameter table setting new values */ m_def_dst_addr = dest; for (i = 0; i < WLBS_MAX_CLUSTERS; i ++) m_cluster_params [i] . dest = dest; } else { for (i = 0, j = WLBS_MAX_CLUSTERS; i < WLBS_MAX_CLUSTERS; i ++) { /* mark an empty slot in case we will have to enter a new value */ if (j == WLBS_MAX_CLUSTERS && m_cluster_params [i] . cluster == 0) j = i; if (m_cluster_params [i] . cluster == cluster) { m_cluster_params [i] . dest = dest; break; } } /* if we did not locate specified cluster in the table and there is an empty slot - enter new cluster info in the table */ if (i >= WLBS_MAX_CLUSTERS && j != WLBS_MAX_CLUSTERS) { m_cluster_params [j] . cluster = cluster; m_cluster_params [j] . dest = dest; } } // UNLOCK(global_info.lock); } //+---------------------------------------------------------------------------- // // Function: CWlbsControl::WlbsTimeoutSet // // Description: // // Arguments: DWORD cluster - // DWORD milliseconds - // // Returns: Nothing // // History: fengsun Created Header 1/25/00 // //+---------------------------------------------------------------------------- VOID CWlbsControl::WlbsTimeoutSet(DWORD cluster, DWORD milliseconds) { DWORD i; DWORD j; DWORD timeout; // LOCK(global_info.lock); if (milliseconds == 0) timeout = IOCTL_REMOTE_RECV_DELAY; else timeout = milliseconds / (IOCTL_REMOTE_SEND_RETRIES * IOCTL_REMOTE_RECV_RETRIES); if (timeout < 10) timeout = 10; if (cluster == WLBS_ALL_CLUSTERS) { /* when all clusters are targeted - change the default and go through the entire parameter table setting new values */ m_def_timeout = timeout; for (i = 0; i < WLBS_MAX_CLUSTERS; i ++) m_cluster_params [i] . timeout = timeout; } else { for (i = 0, j = WLBS_MAX_CLUSTERS; i < WLBS_MAX_CLUSTERS; i ++) { /* mark an empty slot in case we will have to enter a new value */ if (j == WLBS_MAX_CLUSTERS && m_cluster_params [i] . cluster == 0) j = i; if (m_cluster_params [i] . cluster == cluster) { m_cluster_params [i] . timeout = timeout; break; } } /* if we did not locate specified cluster in the table and there is an empty slot - enter new cluster info in the table */ if (i >= WLBS_MAX_CLUSTERS && j < WLBS_MAX_CLUSTERS) { m_cluster_params [j] . cluster = cluster; m_cluster_params [j] . timeout = timeout; } } // UNLOCK(global_info.lock); } /* end WlbsTimeoutSet */ #if defined (SBH) DWORD CWlbsControl::WlbsQueryStateInfo (DWORD cluster, DWORD host, PIOCTL_QUERY_STATE bufp) { IOCTL_LOCAL_HDR Header; CWlbsCluster * pCluster = NULL; LONG Ioctl = IOCTL_CVY_QUERY_STATE; ULONG BufferSize = 0; WCHAR Guid[128]; ULONG Length; BOOLEAN Ret; if (GetInitResult() == WLBS_INIT_ERROR) return GetInitResult(); pCluster = GetClusterFromIpOrIndex(cluster); if (!pCluster) return WLBS_IO_ERROR; StringFromGUID2(pCluster->GetAdapterGuid(), Guid, sizeof(Guid)/ sizeof(Guid[0])); ZeroMemory((VOID *)&Header, sizeof(IOCTL_LOCAL_HDR)); lstrcpy(Header.device_name, L"\\device\\"); lstrcat(Header.device_name, Guid); Header.options.state.flags = 0; Header.options.state.query = *bufp; switch (bufp->Operation) { case NLB_QUERY_REG_PARAMS: case NLB_QUERY_PORT_RULE_STATE: case NLB_QUERY_BDA_TEAM_STATE: case NLB_QUERY_PACKET_STATISTICS: return WLBS_IO_ERROR; case NLB_QUERY_PACKET_FILTER: Ret = (BOOLEAN)DeviceIoControl(m_hdl, Ioctl, &Header, sizeof(IOCTL_LOCAL_HDR), &Header, sizeof(IOCTL_LOCAL_HDR), &Length, NULL); if (!Ret || (Length != sizeof(IOCTL_LOCAL_HDR))) return WLBS_IO_ERROR; break; default: return WLBS_IO_ERROR; } *bufp = Header.options.state.query; return WLBS_OK; } #endif //+---------------------------------------------------------------------------- // // Function: DllMain // // Description: Dll entry point // // Arguments: HINSTANCE handle - // DWORD reason - // LPVOID situation - // // Returns: BOOL WINAPI - // // History: fengsun Created Header 3/2/00 // //+---------------------------------------------------------------------------- BOOL WINAPI DllMain(HINSTANCE handle, DWORD reason, LPVOID situation) { switch (reason) { case DLL_PROCESS_ATTACH: _tsetlocale (LC_ALL, _TEXT(".OCP")); DisableThreadLibraryCalls(handle); g_hInstCtrl = handle; // // Enable tracing // WPP_INIT_TRACING(L"Microsoft\\NLB"); break; case DLL_THREAD_ATTACH: break; case DLL_PROCESS_DETACH: // // Disable tracing // WPP_CLEANUP(); break; case DLL_THREAD_DETACH: break; default: return FALSE; } return TRUE; }