⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxy.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//

#include "proxy.h"
#include "proxydev.h"
#include "auth.h"
#include "proxydbg.h"
#include <iphlpapi.h>
#include <ws2tcpip.h>
#include "resource.h"
#include "parser.h"
#include "filter.h"

ProxySettings* g_pSettings;
ProxyErrors* g_pErrors;
SVSThreadPool* g_pThreadPool;


DWORD InitStrings(void);
void DeinitStrings(void);

//
// The following methods belong to the CHttpProxy class which is the central
// class for the Web Proxy.
//

CHttpProxy::CHttpProxy(void)
{
}

DWORD CHttpProxy::Init(void)
{
    DWORD dwRetVal = ERROR_SUCCESS;
    WSADATA wsadata;    
    
    svsutil_Initialize();
    WSAStartup(MAKEWORD(2, 2), &wsadata);

    g_pErrors = new ProxyErrors;
    if (! g_pErrors) {
        dwRetVal = ERROR_OUTOFMEMORY;
        IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Out of memory.\n")));
        goto exit;
    }

    g_pSettings = new ProxySettings;
    if (! g_pSettings) {
        dwRetVal = ERROR_OUTOFMEMORY;
        IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Out of memory.\n")));
        goto exit;
    }

    g_pParser = new CHttpParser;
    if (! g_pParser) {
        dwRetVal = ERROR_OUTOFMEMORY;
        IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Out of memory.\n")));
        goto exit;
    }

    g_pSessionMgr = new CSessionMgr;
    if (! g_pSessionMgr) {
        dwRetVal = ERROR_OUTOFMEMORY;
        IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Out of memory.\n")));
        goto exit;
    }

    g_pProxyFilter = new CProxyFilter;
    if (! g_pProxyFilter) {
        dwRetVal = ERROR_OUTOFMEMORY;
        IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Out of memory.\n")));
        goto exit;
    }

    dwRetVal = InitStrings();
    if (ERROR_SUCCESS != dwRetVal) {
        IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Error initializing proxy strings.\n")));
        goto exit;
    }
    
    m_fRunning = FALSE;
    IFDBG(DebugOut(ZONE_SERVICE, _T("WebProxy: Service has been initialized successfully.\n")));

exit:
    if (ERROR_SUCCESS != dwRetVal) {
        if (g_pProxyFilter) {
            delete g_pProxyFilter;
            g_pProxyFilter = NULL;
        }
        if (g_pParser) {
            delete g_pParser;
            g_pParser = NULL;
        }
        if (g_pSessionMgr) {
            delete g_pSessionMgr;
            g_pSessionMgr = NULL;
        }
    }
    
    return dwRetVal;
}

DWORD CHttpProxy::Deinit(void)
{    
    DeinitStrings();
    
    delete g_pProxyFilter;
    g_pProxyFilter = NULL;
    delete g_pSessionMgr;
    g_pSessionMgr = NULL;
    delete g_pParser;
    g_pParser = NULL;
    
    WSACleanup();    
    svsutil_DeInitialize();

    IFDBG(DebugOut(ZONE_SERVICE, _T("WebProxy: Service has been deinitialized successfully.\n")));
    return ERROR_SUCCESS;
}

DWORD CHttpProxy::InitSettings(void)
{
    DWORD dwRetVal = ERROR_SUCCESS;    
    CReg regWebProxy;    
    
    //
    // Set the default values for all registry configurable settings
    //

    DWORD cSessionThreads = DEFAULT_MAX_CONNECTIONS;

    g_pSettings->Reset();

    m_fRunning = FALSE;

    //
    // If we fail to open the registry key, that is ok as it is possible to desire all
    // the default settings.
    //
    
    if (regWebProxy.Open(HKEY_LOCAL_MACHINE, RK_WEBPROXY)) {
        WCHAR* pszTmp;

        g_pSettings->iMaxConnections = regWebProxy.ValueDW(RV_MAX_CONNECTIONS, DEFAULT_MAX_CONNECTIONS);
        g_pSettings->iPort = regWebProxy.ValueDW(RV_PORT, DEFAULT_PROXY_PORT);
        g_pSettings->fNTLMAuth = regWebProxy.ValueDW(RV_AUTH_NTLM, DEFAULT_AUTH_NTLM);
        g_pSettings->fBasicAuth = regWebProxy.ValueDW(RV_AUTH_BASIC, DEFAULT_AUTH_BASIC);
        g_pSettings->iSessionTimeout = regWebProxy.ValueDW(RV_SESSION_TIMEOUT, DEFAULT_SESSION_TIMEOUT);
        g_pSettings->iMaxBufferSize = regWebProxy.ValueDW(RV_MAXHEADERSSIZE, DEFAULT_MAX_BUFFER_SIZE);
        g_pSettings->iSecondProxyPort = regWebProxy.ValueDW(RV_SECOND_PROXY_PORT, DEFAULT_HTTP_PORT);

        cSessionThreads = regWebProxy.ValueDW(RV_SESSION_THREADS, g_pSettings->iMaxConnections);
  
        pszTmp = (WCHAR *) regWebProxy.ValueSZ(RV_SECOND_PROXY_HOST);
        if (pszTmp) {
            DWORD cchTmp = wcslen(pszTmp);
            g_pSettings->strSecondProxyHost.reserve(cchTmp+1);
            WideCharToMultiByte(CP_ACP, 0, pszTmp, -1, g_pSettings->strSecondProxyHost.get_buffer(), g_pSettings->strSecondProxyHost.capacity(), NULL, NULL);
        }
    }

    

    g_pThreadPool = new SVSThreadPool(cSessionThreads);
    if (! g_pThreadPool) {
        dwRetVal = ERROR_OUTOFMEMORY;
        IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Out of memory allocating SVSThreadPool.\n")));
        goto exit;
   }

    g_pSettings->strHostName.reserve(MAX_PATH);
    dwRetVal = gethostname(g_pSettings->strHostName.get_buffer(), g_pSettings->strHostName.capacity());
    if (ERROR_SUCCESS != dwRetVal) {
        g_pSettings->strHostName = DEFAULT_HOST_NAME_SZ;
    }

    g_pProxyFilter->LoadFilters();
    
    if (g_pSettings->fNTLMAuth) {
        dwRetVal = InitNTLMSecurityLib();
        if (ERROR_SUCCESS != dwRetVal) {
            goto exit;
        }
    }

    if (g_pSettings->fBasicAuth) {
        dwRetVal = InitBasicAuth();
        if (ERROR_SUCCESS != dwRetVal) {
            goto exit;
        }
    }

exit:
    if (ERROR_SUCCESS != dwRetVal) {
        g_pProxyFilter->RemoveAllFilters();
        
        if (g_pThreadPool) {
            delete g_pThreadPool;
            g_pThreadPool = NULL;
        }        
    }
    
    return dwRetVal;
}

DWORD CHttpProxy::DeinitSettings(void)
{   
    if (g_pSettings->fNTLMAuth) {
        DeinitNTLMSecurityLib();
    }
    if (g_pSettings->fBasicAuth) {
        DeinitBasicAuth();
    }

    g_pProxyFilter->RemoveAllFilters();

    delete g_pThreadPool;
    g_pThreadPool = NULL;
    
    return ERROR_SUCCESS;
}

DWORD CHttpProxy::Start(void)
{
    DWORD dwRetVal = ERROR_SUCCESS;

    Lock();

    InitSettings();
    m_fRunning = TRUE;

    UpdateAdapterInfo();

    m_hServerThread = CreateThread(NULL, 0, ServerThread, (LPVOID)this, 0, NULL);
    if (! m_hServerThread.valid()) {
        dwRetVal = GetLastError();
        IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Error creating ServerThread: %d.\n"), dwRetVal));
        goto exit;
    }
    
    IFDBG(DebugOut(ZONE_SERVICE, _T("WebProxy: Service has been started successfully.\n")));

exit:
    Unlock();
    return dwRetVal;
}

DWORD CHttpProxy::Stop(void)
{
    DWORD dwRetVal = ERROR_SUCCESS;

    Lock();
    m_fRunning = FALSE;

    for (int i = 0; i < m_cSockets; i++) {
        m_sockServer[i].close();
    }
    m_cSockets = 0;

    // Need to shutdown each item in the list, then shutdown thread pool, 
    // then remove the items from the list.
    g_pSessionMgr->ShutdownAllSessions();
    g_pThreadPool->Shutdown();
    g_pSessionMgr->RemoveAllSessions();
    
    // If this function is being called from the ServerThread then we should not wait
    if ((HANDLE)GetCurrentThreadId() != m_hServerThread) {
        HANDLE h = m_hServerThread;
        Unlock();
        dwRetVal = WaitForSingleObject(h, INFINITE);
        Lock();
        if (WAIT_FAILED == dwRetVal) {
            dwRetVal = GetLastError();
            IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Error stopping ServerThread: %d.\n"), dwRetVal));
            ASSERT(0);
            goto exit;
        }
    }

    DeinitSettings();
    
    dwRetVal = ERROR_SUCCESS;
    IFDBG(DebugOut(ZONE_SERVICE, _T("WebProxy: Service has been stopped successfully.\n")));

exit:
    Unlock();
    return dwRetVal;
}

DWORD CHttpProxy::NotifyAddrChange(PBYTE pBufIn, DWORD cbBufIn)
{
    IFDBG(DebugOut(ZONE_SERVICE, _T("WebProxy: Received address change notification.\n")));
    
    UpdateAdapterInfo();
    return ERROR_SUCCESS;
}

DWORD CHttpProxy::SignalFilter(DWORD dwSignal)
{
    return g_pProxyFilter->Signal(dwSignal);
}

DWORD WINAPI CHttpProxy::ServerThread(LPVOID pv)
{
    CHttpProxy* pInst = reinterpret_cast<CHttpProxy*> (pv);
    pInst->Run();
    return 0;
}

void CHttpProxy::Run(void)
{
    DWORD dwErr = ERROR_SUCCESS;

    Lock();

    dwErr = SetupServerSockets();
    if (ERROR_SUCCESS != dwErr) {
        Stop();
        g_dwState = SERVICE_STATE_OFF;
        goto exit;
    }

    while (1) {
        int i = 0;
        fd_set sockSet;
        
        FD_ZERO(&sockSet);
        for (i = 0; i < m_cSockets; i++) {
            FD_SET(m_sockServer[i], &sockSet);
        }

        Unlock();

        if (SERVICE_STATE_ON != g_dwState) {
            // Another thread has indicated that the program should be terminated
            IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Web Proxy main thread will not continue because another thread has changed service state.\n")));
            // do not break out of loop or goto exit block, but quit immediatly.
            // Also no need to Stop() because the other thread shutting us down has performed this already
            return;  
        }

        int iSockets = select(0,&sockSet,NULL,NULL,NULL);
        Lock();

        // Check if service is being signalled to stop
        if (! m_fRunning) {
            IFDBG(DebugOut(ZONE_SERVICE, _T("WebProxy: Server thread is being signalled to stop, exiting...\n")));
            break;
        }

        if ((0 == iSockets) || (SOCKET_ERROR == iSockets)) {
            IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Error in call to select: %d\n"), WSAGetLastError()));
            goto exit;
        }

        for (i = 0; i < iSockets; i++) {
            SOCKADDR_STORAGE saClient;
            int cbsa = sizeof(saClient);
            
            auto_socket sockClient = accept(sockSet.fd_array[i], (SOCKADDR*)&saClient, &cbsa);

            if (INVALID_SOCKET == sockClient) {
                IFDBG(DebugOut(ZONE_ERROR, _T("WebProxy: Accept on server socket failed: %d\n"), WSAGetLastError()));
                continue;
            }

            // Check if we have exceeded the maximum number of connections
            if (g_pSessionMgr->GetSessionCount() > g_pSettings->iMaxConnections) {
                sockClient.close();
                IFDBG(DebugOut(ZONE_WARN, _T("WebProxy: Cannot accept any new connections - connection limit has been reached.\n")));
                continue;
            }

            SessionSettings settings;

            memset(&settings, 0, sizeof(settings));
            settings.sockClient = sockClient;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -