📄 hxcloakedtcp.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: hxcloakedtcp.cpp,v 1.7.8.2 2004/07/13 18:06:24 bobclark Exp $ * * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. * * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks. You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL. Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. * * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. * * Technology Compatibility Kit Test Suite(s) Location: * http://www.helixcommunity.org/content/tck * * Contributor(s): * * ***** END LICENSE BLOCK ***** */#include "hlxclib/stdio.h" #include "hxcloakedtcp.h"#include "safestring.h"#include "hxnetutil.h"#include "ihxpckts.h"#include "hxccf.h" // IHXCommonClassFactory#include "hxthread.h" // HXMutex#include "hxbuffer.h" // CHXBuffer#include "conn.h" // TCP_BUF_SIZE#include "dbcs.h" // HXFindString#include "hxmarsh.h" // getshort()#include "chxuuid.h" // CHXuuid#include "hxtick.h" // HX_GET_TICKCOUNT#include "rtsputil.h" // BinTo64#include "hxfiles.h" // CLSID_IHXRequest#include "hxplnsp.h" // _CIHXObjectConfiguration_SP#include "hxcomsp.h" // _CIHXCommonClassFactory_SP// necessary for authentication#include "hxmon.h"#include "httppars.h"#include "hxplgns.h"#include "hxcore.h"#include "httpclk.h"#ifdef _MACINTOSH#include "hx_moreprocesses.h"#endif/******************* HTTP Cloaking*****************/#define QUEUE_START_SIZE 512#define HTTPCLOAK_PUTRESPONSE_TIMEOUT 2000#define MAX_HTTP_METHOD_BUFSIZE 2048#define HXGUID_SIZE 16 // 16 byte GUID plus \r\n#define ENQUEUE_DATA(x,y,z) (x)->EnQueue((y),(z))#define ENQUEUE_BYTE(x,y) {UCHAR uChar = (y); \ (x)->EnQueue(&uChar,sizeof(uChar));}#define ENQUEUE_WORD(x,y) {UINT16 wTemp = (y); \ wTemp = WToNet(wTemp); \ (x)->EnQueue(&wTemp,sizeof(UINT16));}#define ENQUEUE_DWORD(x,y) {ULONG32 dTemp = (y); \ dTemp = DwToNet(dTemp); \ (x)->EnQueue(&dTemp,sizeof(ULONG32));}#define DEFAULT_HTTP_HEADER_LENGTH 256#define DEFAULT_OPTION_PADDING_LENGTH 16381#ifdef _WINCE#define SCHED_GRANULARITY 10#else#define SCHED_GRANULARITY 50#endifenum{ HTTP_OK = 0, HTTP_GENERAL_ERROR, // for any error that is not defined below POST_NOT_RECEIVED, // POST message was not received INVALID_GUID // sent only if the GUID from the Player is already in use};/* HXClientCloakedTCPSocket */HXClientCloakedTCPSocket::HXClientCloakedTCPSocket(IUnknown* pContext): m_lRefCount(0) ,m_pContext(pContext) ,m_pTCPResponse(0) ,m_pNetworkServices(0) ,m_pGetCtrl(0) ,m_pPutCtrl(0) ,m_pGetCtrlResponse(0) ,m_pPutCtrlResponse(0) ,m_bGetReadPending(FALSE) ,m_bPutReadPending(FALSE) ,m_bPutWantWritePending(FALSE) ,m_lForeignAddress(0) ,m_nForeignPort(0) ,m_bReadPending(FALSE) ,m_nRequired(0) ,m_pSendTCP(0) ,m_pReceiveGetTCP(0) ,m_pReceivePutTCP(0) ,m_pPreEncodedSendHTTP(0) ,m_pPostEncodedSendHTTP(0) ,m_pOutBuf(0) ,m_pOutEncodedBuf(0) ,m_pInBuf(0) ,m_bConnected(FALSE) ,m_pForiegnHost(0) ,m_pGuid(0) ,m_bGetConnectDone(FALSE) ,m_bPutConnectDone(FALSE) ,m_bGetConnectSuccessful(FALSE) ,m_bPutConnectSuccessful(FALSE) ,m_bConnectResponsePending(TRUE) ,m_bOptionsReceived(FALSE) ,m_bUseExactContentLength(FALSE) ,m_bCloseHttpAfterWrite(FALSE) ,m_bMustCloseHTTP(FALSE) ,m_bHttpInitialized(FALSE) ,m_LastError(HXR_OK) ,m_pHTTPHeaderBuffer(0) ,m_nHTTPHeaderBufferLength(0) ,m_bHTTPGetHeaderReadDone(FALSE) ,m_bHTTPPutHeaderReadDone(FALSE) ,m_pProxyHostName(0) ,m_nProxyPortNumber(0) ,m_bInDestructor(FALSE) ,m_pScheduler(0) ,m_pSchedulerCallback(0) ,m_pNonInterruptCallback(0) ,m_bInDoRead(FALSE) ,m_bInDoGetWrite(FALSE) ,m_bInDoPutWrite(FALSE) ,m_bInTransferBuffers(FALSE) ,m_bInitComplete(FALSE) ,m_bDeletePadding(FALSE) ,m_uPadLength(10+DEFAULT_OPTION_PADDING_LENGTH) // 10 for the opts and 16381 for the padding ,m_pInterruptState(NULL) ,m_pResponseInterruptSafe(NULL) ,m_pMutex(NULL) ,m_pCloakValues(NULL) ,m_pCloakContext(NULL) ,m_bGetResponsed(FALSE) ,m_bPutResponsed(FALSE) ,m_pszGetServerIP(NULL) ,m_pszPutServerIP(NULL) ,m_bReconnectToSameServerIP(FALSE) ,m_bConnectToSameServerIP(FALSE) ,m_pPreferredTransport(NULL) ,m_pPreferredTransportManager(NULL)#ifdef _MACINTOSH ,m_pAuthenticationCallback(NULL)#endif ,m_bInAuthenticationKludge(FALSE){ if(m_pContext) { m_pContext->AddRef(); m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler); m_pContext->QueryInterface(IID_IHXNetworkServices, (void**) &m_pNetworkServices); m_pContext->QueryInterface(IID_IHXInterruptState, (void**) &m_pInterruptState); m_pContext->QueryInterface(IID_IHXPreferredTransportManager, (void**)&m_pPreferredTransportManager); }#if defined(THREADS_SUPPORTED) HXMutex::MakeMutex(m_pMutex);#elif defined(_UNIX_THREADED_NETWORK_IO) if( ReadNetworkThreadingPref((IUnknown*)pContext) ) { HXMutex::MakeMutex(m_pMutex); } else { HXMutex::MakeStubMutex(m_pMutex); }#else HXMutex::MakeStubMutex(m_pMutex);#endif#ifdef _MACINTOSH m_pAuthenticationCallback = new MacCloakedTCPSocketAuthenticationCallback(this); m_pAuthenticationCallback->AddRef();#endif}HXClientCloakedTCPSocket::~HXClientCloakedTCPSocket(){ m_bInDestructor = TRUE; m_pMutex->Lock();#ifdef _MACINTOSH if (m_pAuthenticationCallback && m_pAuthenticationCallback->m_ulPendingCallbackID && m_pScheduler) { m_pScheduler->Remove(m_pAuthenticationCallback->m_ulPendingCallbackID); m_pAuthenticationCallback->m_ulPendingCallbackID = NULL; } HX_RELEASE(m_pAuthenticationCallback);#endif while (m_PendingWriteBuffers.GetCount() > 0) { IHXBuffer* pBuffer = (IHXBuffer*) m_PendingWriteBuffers.RemoveHead(); pBuffer->Release(); } FlushQueues(); /* Send a final HTTP done message */ if (m_bHttpInitialized) { SendHTTPDone(); } if (m_pSchedulerCallback) { m_pSchedulerCallback->Unschedule(m_pScheduler); HX_RELEASE(m_pSchedulerCallback); } if (m_pNonInterruptCallback) { m_pNonInterruptCallback->Unschedule(m_pScheduler); HX_RELEASE(m_pNonInterruptCallback); } HX_RELEASE(m_pGetCtrl); HX_RELEASE(m_pPutCtrl); HX_RELEASE(m_pGetCtrlResponse); HX_RELEASE(m_pPutCtrlResponse); HX_RELEASE(m_pCloakValues); HX_RELEASE(m_pCloakContext); HX_RELEASE(m_pTCPResponse); HX_RELEASE(m_pNetworkServices); HX_DELETE(m_pSendTCP); HX_DELETE(m_pReceiveGetTCP); HX_DELETE(m_pReceivePutTCP); HX_DELETE(m_pPreEncodedSendHTTP); HX_DELETE(m_pPostEncodedSendHTTP); HX_VECTOR_DELETE(m_pInBuf); HX_VECTOR_DELETE(m_pOutBuf); HX_VECTOR_DELETE(m_pOutEncodedBuf); HX_VECTOR_DELETE(m_pForiegnHost); HX_VECTOR_DELETE(m_pGuid); HX_VECTOR_DELETE(m_pHTTPHeaderBuffer); HX_VECTOR_DELETE(m_pProxyHostName); HX_VECTOR_DELETE(m_pszGetServerIP); HX_VECTOR_DELETE(m_pszPutServerIP); HX_RELEASE(m_pPreferredTransport); HX_RELEASE(m_pPreferredTransportManager); HX_RELEASE(m_pInterruptState); HX_RELEASE(m_pResponseInterruptSafe); HX_RELEASE(m_pScheduler); HX_RELEASE(m_pContext); m_pMutex->Unlock(); HX_DELETE(m_pMutex);}STDMETHODIMP HXClientCloakedTCPSocket::QueryInterface(REFIID riid, void** ppvObj){ QInterfaceList qiList[] = { { GET_IIDHANDLE(IID_IHXTCPSocket), (IHXTCPSocket*)this }, { GET_IIDHANDLE(IID_IHXCloakedTCPSocket), (IHXCloakedTCPSocket*)this }, { GET_IIDHANDLE(IID_IHXHTTPProxy), (IHXHTTPProxy*)this }, { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXTCPSocket*)this }, }; return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);}STDMETHODIMP_(ULONG32) HXClientCloakedTCPSocket::AddRef(){ return InterlockedIncrement(&m_lRefCount);}STDMETHODIMP_(ULONG32) HXClientCloakedTCPSocket::Release(){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0;}STDMETHODIMP HXClientCloakedTCPSocket::Init(IHXTCPResponse* pTCPResponse){ HX_RESULT rc = HXR_OK; if (!pTCPResponse) { return HXR_UNEXPECTED; } if (!m_pSchedulerCallback) { m_pSchedulerCallback = new ScheduledSocketCallback(this, TRUE); m_pSchedulerCallback->AddRef(); } if (!m_pNonInterruptCallback) { m_pNonInterruptCallback = new ScheduledSocketCallback(this, TRUE); m_pNonInterruptCallback->AddRef(); } m_pTCPResponse = pTCPResponse; m_pTCPResponse->AddRef(); m_pTCPResponse->QueryInterface(IID_IHXInterruptSafe, (void**) &m_pResponseInterruptSafe); if (!m_pNetworkServices) { return HXR_FAILED; } if (HXR_OK != m_pNetworkServices->CreateTCPSocket(&m_pGetCtrl)) { return HXR_FAILED; } if (HXR_OK != m_pNetworkServices->CreateTCPSocket(&m_pPutCtrl)) { return HXR_FAILED; } m_pGetCtrlResponse = new HTTPCloakTCPResponse(this, TRUE); m_pPutCtrlResponse = new HTTPCloakTCPResponse(this, FALSE); if (!m_pGetCtrlResponse || !m_pPutCtrlResponse) { return HXR_OUTOFMEMORY; } m_pGetCtrlResponse->AddRef(); m_pPutCtrlResponse->AddRef(); if (HXR_OK != m_pGetCtrl->Init(m_pGetCtrlResponse) || HXR_OK != m_pPutCtrl->Init(m_pPutCtrlResponse)) { return HXR_FAILED; } if (HXR_OK != m_pGetCtrl->Bind(HXR_INADDR_ANY, 0) || HXR_OK != m_pPutCtrl->Bind(HXR_INADDR_ANY, 0)) { return HXR_FAILED; } // allocate TCP send and receive queue m_pSendTCP = new CByteGrowingQueue(QUEUE_START_SIZE,1); if (!m_pSendTCP || !m_pSendTCP->IsQueueValid()) { return HXR_OUTOFMEMORY; } m_pSendTCP->SetMaxSize(TCP_BUF_SIZE); m_pReceiveGetTCP = new CByteGrowingQueue(QUEUE_START_SIZE,1); if (!m_pReceiveGetTCP || !m_pReceiveGetTCP->IsQueueValid()) { return HXR_OUTOFMEMORY; } m_pReceiveGetTCP->SetMaxSize(TCP_BUF_SIZE); m_pPreEncodedSendHTTP = new CByteGrowingQueue(QUEUE_START_SIZE,1); if (!m_pPreEncodedSendHTTP || !m_pPreEncodedSendHTTP->IsQueueValid()) { return HXR_OUTOFMEMORY; } /* Approx. MAX POST header size : 3000*/ m_pPreEncodedSendHTTP ->SetMaxSize((TCP_BUF_SIZE-1)/2 - 3000); m_pPostEncodedSendHTTP = new CByteGrowingQueue(QUEUE_START_SIZE,1); if (!m_pPostEncodedSendHTTP || !m_pPostEncodedSendHTTP->IsQueueValid()) { return HXR_OUTOFMEMORY; } m_pPostEncodedSendHTTP->SetMaxSize(TCP_BUF_SIZE); m_pInBuf = new char[TCP_BUF_SIZE]; if (!m_pInBuf) { return HXR_OUTOFMEMORY; } m_pOutBuf = new char[TCP_BUF_SIZE]; if (!m_pOutBuf) { return HXR_OUTOFMEMORY; } m_pOutEncodedBuf = new char[TCP_BUF_SIZE]; if (!m_pOutEncodedBuf) { return HXR_OUTOFMEMORY; } CreateGuid(); return HXR_OK;}STDMETHODIMP HXClientCloakedTCPSocket::SetResponse(IHXTCPResponse* pTCPResponse){ m_pMutex->Lock(); HX_RELEASE(m_pTCPResponse); m_pTCPResponse = pTCPResponse; m_pTCPResponse->AddRef(); HX_RELEASE(m_pResponseInterruptSafe); m_pTCPResponse->QueryInterface(IID_IHXInterruptSafe, (void**) &m_pResponseInterruptSafe); m_pMutex->Unlock(); return HXR_OK;}STDMETHODIMP HXClientCloakedTCPSocket::Bind(UINT32 ulLocalAddr, UINT16 nPort){ return HXR_NOTIMPL;}STDMETHODIMP HXClientCloakedTCPSocket::Connect(const char* pDestination, UINT16 nPort){ m_nForeignPort = nPort; HX_VECTOR_DELETE(m_pForiegnHost); m_pForiegnHost = new char [strlen(pDestination) + 1]; if (!m_pForiegnHost) { return HXR_OUTOFMEMORY; } ::strcpy(m_pForiegnHost, pDestination); /* Flawfinder: ignore */ // m_pCloakValues is only set by RTSP if (m_pPreferredTransportManager && m_pCloakValues) { HX_RELEASE(m_pPreferredTransport); m_pPreferredTransportManager->GetPrefTransport(m_pForiegnHost, PTP_RTSP, m_pPreferredTransport); HX_ASSERT(m_pPreferredTransport); if (m_pPreferredTransport) { m_bConnectToSameServerIP = m_pPreferredTransport->GetHTTPNG(); } } return ActualConnect();}STDMETHODIMP HXClientCloakedTCPSocket::Read(UINT16 uSize){ HX_RESULT theErr = HXR_OK; HX_RESULT lResult = HXR_OK; if (m_bReadPending) { return HXR_UNEXPECTED; } m_bReadPending = TRUE; m_nRequired = uSize; m_pMutex->Lock(); theErr = DoRead(); m_pMutex->Unlock(); lResult = ConvertNetworkError(theErr); return lResult;}STDMETHODIMP HXClientCloakedTCPSocket::Write(IHXBuffer* pBuffer){ HX_RESULT theErr = HXR_OK; HX_RESULT lResult = HXR_OK; pBuffer->AddRef(); m_PendingWriteBuffers.AddTail((void*) pBuffer); m_pMutex->Lock(); theErr = DoPutWrite(); m_pMutex->Unlock(); lResult = ConvertNetworkError(theErr); return lResult;}STDMETHODIMP HXClientCloakedTCPSocket::WantWrite(){ m_pTCPResponse->WriteReady(HXR_OK); return HXR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -