conn.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:22k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hlxclib/time.h"
  36. #include <string.h>
  37. #if defined(_UNIX)
  38. #include <sys/types.h>
  39. #endif
  40. #include "hlxclib/sys/socket.h"
  41. #include "hlxclib/netdb.h"
  42. #include "hxcom.h"
  43. #include "conn.h"
  44. #include "hxengin.h"
  45. #include "hxcom.h"
  46. #include "hxtick.h"
  47. #include "hxresult.h"
  48. #include "hxthread.h"
  49. #include "hxbuffer.h"
  50. #include "hxstrutl.h"
  51. #include "netbyte.h"
  52. #if defined( THREADS_SUPPORTED ) || defined(_UNIX_THREADED_NETWORK_IO)
  53. #include "thrdconn.h"
  54. #endif
  55. //#include "../dcondev/dcon.h"
  56. #include "hxheap.h"
  57. #ifdef _DEBUG
  58. #undef HX_THIS_FILE
  59. static const char HX_THIS_FILE[] = __FILE__;
  60. #endif  
  61. #define MAX_CONN_STARVINGTIME 1000
  62. // DNR cache
  63. DNR_cache conn::mCache[MAX_CACHE];
  64. UINT16 conn::mCacheCount = 0;
  65. // conn object list
  66. // XXXJR Really sorry this, but as an actual instance it doesn't get
  67. // initialized when linked into a shared library under unix.  Yuck.
  68. CHXMapPtrToPtr* conn::mConnectionList     = NULL;
  69. HXThread* conn::m_pNetworkThread     = NULL;
  70. UINT32   conn::m_ulMaxBandwidth     = MAX_UINT32;   // in bytes per sec
  71. UINT32 conn::m_ulTCPTotalBytesRead = 0;
  72. UINT32 conn::m_ulTCPReadTimeStamp  = 0;
  73. CHXSimpleList* conn::m_pTCPStarvingList    = NULL;
  74. BOOL            conn::m_bNetworkThreading   = FALSE;
  75. BOOL            conn::m_bThreadedDNS        = FALSE;
  76. static HXMutex* z_pConnectionListMutex = NULL;
  77. DestructConnGlobals selfConnGlobalDestructor;
  78. void
  79. conn::DestructGlobals()
  80. {
  81.     HX_DELETE(z_pConnectionListMutex);
  82. }
  83. // new_socket() creates the correct version of conn depending on the
  84. // defined platform and requested socket type
  85. conn* conn::new_socket (UINT16 type)
  86. {
  87.     conn *c = 0;
  88. #if defined(_UNIX_THREADED_NETWORK_IO)
  89.     if( conn::GetNetworkThreadingPref() )
  90.     {
  91.         c = ThreadedConn::new_socket(type);
  92.     }
  93.     else
  94.     {
  95.         c = actual_new_socket(type);
  96.     }
  97. #elif defined(THREADS_SUPPORTED)
  98.     c = ThreadedConn::new_socket(type);
  99. #else    
  100.     c = actual_new_socket(type);
  101. #endif
  102.     if ( c != NULL )
  103.     {
  104. conn::add_connection_to_list ( c );
  105. c->AddRef();
  106.     }
  107.     return(c);
  108. }
  109. conn::~conn (void)
  110. {
  111. //    dprintf("**Destructor** conn::conn(%X)n", this);
  112.     if (m_pUDPBuffer)
  113.     {
  114. delete [] m_pUDPBuffer;
  115. m_pUDPBuffer = 0;
  116.     }
  117.     if ( this != NULL )
  118.     conn::remove_connection_from_list ( this );
  119. }
  120. // platform specific constructor should set the socket to a value  
  121. // indicating the connection is not open
  122. conn::conn (void)
  123.     : m_bNoAsyncDNS( FALSE )
  124. {
  125. // if ( this != NULL )
  126. // dprintf("==Constructor== conn::conn(%X)n", this);
  127. mSock = HX_INVALID_SOCKET;
  128. mConnectionOpen = 0;
  129. mLastError = HXR_OK;
  130. mCallBack = 0;
  131. mHostIPAddr = 0;
  132. mHostIPValid = FALSE;
  133. mDNSDone  = FALSE;
  134. m_pUDPBuffer  = 0;
  135. m_ulLastStarvingTime = 0; 
  136. }
  137. /*  conn::is_cached searches the cached DNR for host and returns its inet address 
  138. in  addr and 1 if it was found, or 0 if it was not found */
  139. UINT16
  140. conn::is_cached(char *host,ULONG32 *addr)
  141. {
  142. UINT16 found = 0;
  143. for (UINT16 i=0; i < mCacheCount && !found; i++) 
  144. {
  145. if (mCache[i].domainName && (::strcmp(host, mCache[i].domainName) == 0)) 
  146. {
  147. *addr = mCache[i].addr;
  148. found = 1;
  149. }
  150. }
  151. return found;
  152. }
  153. /*  conn::add_to_cache adds the host and its inet addr to the cache. If the cache is
  154. full, the oldest entry is replaced with the new entry */
  155. void
  156. conn::add_to_cache(char *host,ULONG32 addr)
  157. {
  158. UINT16 found = 0;
  159. // search the cache to see if entry has already been entered
  160. for (UINT16 i=0; i < mCacheCount && !found; i++) 
  161. {
  162. DNR_cache_ptr p = &mCache[i];
  163. if(addr == p->addr && p->domainName && (::strcmp(host, p->domainName) == 0)) 
  164. {
  165. ::time(&p->cachetime); // refresh cache time
  166. found = 1;
  167. }
  168. }
  169. if(found) return;   // our work here is done
  170. if(mCacheCount < MAX_CACHE) // add the new entry to the end of the cache array
  171. {
  172. DNR_cache_ptr p = &mCache[mCacheCount];
  173. p->addr = addr;
  174. ::time(&p->cachetime);
  175. if (p->domainName != host)
  176. {
  177.     HX_VECTOR_DELETE(p->domainName);
  178.     p->domainName = ::new_string(host);
  179. }
  180. mCacheCount++;
  181. }
  182. else // search cache for oldest entry and replace it with the new data
  183. {
  184. time_t minTime = mCache[0].cachetime;
  185. UINT16 minPos = 0;
  186. for(UINT16 i = 1; i < mCacheCount; i++)
  187. {
  188. if(mCache[i].cachetime < minTime)
  189. {
  190. minTime = mCache[i].cachetime;
  191. minPos = i;
  192. }
  193. }
  194. DNR_cache_ptr p = &mCache[minPos];
  195. p->addr = addr;
  196. ::time(&p->cachetime); // time of caching
  197. if (p->domainName != host)
  198. {
  199.     HX_VECTOR_DELETE(p->domainName);
  200.     p->domainName = ::new_string(host);
  201. }
  202. }
  203. }
  204. void
  205. conn::remove_from_cache(const char *host)
  206. {
  207. UINT16 found = 0;
  208. // search the cache to see if entry has been entered
  209. for (UINT16 i = 0; i < mCacheCount && !found; i++) 
  210. {
  211. DNR_cache_ptr p = &mCache[i];
  212. if(p->domainName && ::strcmp(host, p->domainName) == 0) 
  213. {
  214. HX_VECTOR_DELETE(p->domainName);
  215. p->addr = 0;
  216. p->cachetime = 0; // reset time to 0
  217. found = 1;
  218. }
  219. }
  220. }
  221. void
  222. conn::clear_cache()
  223. {
  224.     mCacheCount = 0;
  225. }
  226. POSITION
  227. conn::get_first_connection_position ()
  228. {
  229.     if(!conn::mConnectionList)
  230.     {
  231. return NULL;
  232.     }
  233.     return conn::mConnectionList->GetStartPosition();
  234. }
  235. void
  236. conn::get_next_connection(POSITION& nextPos, conn*& rpConn)
  237. {
  238.     if(!conn::mConnectionList)
  239.     {
  240. nextPos = NULL;
  241. rpConn = NULL;
  242. return;
  243.     }
  244.     void* pVoid = NULL;
  245.     conn::mConnectionList->GetNextAssoc ( nextPos, (void *&)rpConn, pVoid );
  246. }
  247. void
  248. conn::add_connection_to_list ( conn *pConn )
  249. {
  250.     if (!z_pConnectionListMutex)
  251.     {
  252. #if defined(_UNIX_THREADED_NETWORK_IO)
  253.         if( conn::GetNetworkThreadingPref() )
  254.         {
  255.             HXMutex::MakeMutex(z_pConnectionListMutex);
  256.         }
  257.         else
  258.         {
  259.             HXMutex::MakeStubMutex(z_pConnectionListMutex);
  260.         }
  261. #elif defined(THREADS_SUPPORTED)
  262.         HXMutex::MakeMutex(z_pConnectionListMutex);
  263. #else    
  264.         HXMutex::MakeStubMutex(z_pConnectionListMutex);
  265. #endif
  266.     }
  267.     
  268.     HX_ASSERT( z_pConnectionListMutex);
  269.     z_pConnectionListMutex->Lock();
  270.     //fprintf(stderr, "==AddToList== conn::add_connection_to_list(%X)n", pConn);
  271.     if(!conn::mConnectionList)
  272.     {
  273. conn::mConnectionList = new CHXMapPtrToPtr;
  274.     }
  275.         
  276.     conn::mConnectionList->SetAt ( pConn, NULL );
  277.     z_pConnectionListMutex->Unlock();
  278. }
  279. void
  280. conn::remove_connection_from_list ( conn *pConn )
  281. {
  282.     LISTPOSITION    listpos = NULL;
  283.     CHXSimpleList::Iterator  i;
  284.     if(!conn::mConnectionList)
  285.     {
  286. return;
  287.     }
  288.     
  289.     HX_ASSERT(z_pConnectionListMutex);
  290.     if (z_pConnectionListMutex)
  291.     {
  292. z_pConnectionListMutex->Lock();
  293.     }
  294.     HX_VERIFY (conn::mConnectionList->RemoveKey ( pConn ) );
  295.     if (conn::m_pTCPStarvingList)
  296.     {
  297. listpos = conn::m_pTCPStarvingList->Find(pConn);
  298. if (listpos)
  299. {
  300.     conn::m_pTCPStarvingList->RemoveAt(listpos);
  301.     pConn->m_ulLastStarvingTime = 0;
  302. }
  303.     }
  304.     
  305.     if (conn::mConnectionList->IsEmpty())
  306.     {
  307. delete conn::mConnectionList;
  308. conn::mConnectionList = NULL;
  309. HX_ASSERT(!conn::m_pTCPStarvingList || conn::m_pTCPStarvingList->IsEmpty());
  310.     }
  311.     if (conn::m_pTCPStarvingList && conn::m_pTCPStarvingList->IsEmpty())
  312.     {
  313. HX_DELETE(conn::m_pTCPStarvingList);
  314.     }
  315.     if (z_pConnectionListMutex)
  316.     {
  317. z_pConnectionListMutex->Unlock();
  318.     }
  319. }
  320. UINT32
  321. conn::bytes_to_preparetcpread(conn* pConn)
  322. {
  323.     // no op. if EnforceMaxBandwidth is FALSE
  324.     if (conn::m_ulMaxBandwidth == MAX_UINT32)
  325.     {
  326. return MAX_UINT32;
  327.     }
  328.     UINT32     ulCurrentTime = HX_GET_TICKCOUNT();
  329.     UINT32     ulBytesToRead = 0;
  330.     LISTPOSITION    listpos = NULL;
  331.     conn*     pStarvingConn = NULL;
  332.     UINT32     ulTimeElapsed = CALCULATE_ELAPSED_TICKS(conn::m_ulTCPReadTimeStamp, ulCurrentTime);
  333.     // return 0 bytes if the current bandwidth >= max. bandwidth
  334.     if (ulTimeElapsed < 1000 && conn::m_ulTCPTotalBytesRead >= conn::m_ulMaxBandwidth)
  335.     {
  336. goto cleanup;
  337.     }
  338.     // reset the attributes every 1 sec
  339.     else if (ulTimeElapsed >= 1000)
  340.     {
  341. conn::m_ulTCPReadTimeStamp = ulCurrentTime;
  342. conn::m_ulTCPTotalBytesRead = 0;
  343.     }
  344.     // remove the conn from the starving list if it has been starving to death :)
  345.     // so other conn has chance to get the its share of bytes
  346.     while (conn::m_pTCPStarvingList && !conn::m_pTCPStarvingList->IsEmpty())
  347.     {
  348. pStarvingConn = (conn*)conn::m_pTCPStarvingList->GetHead();
  349. if (pStarvingConn != pConn &&
  350.     (CALCULATE_ELAPSED_TICKS(pStarvingConn->m_ulLastStarvingTime, ulCurrentTime) >=
  351.     MAX_CONN_STARVINGTIME))
  352. {     
  353.     conn::m_pTCPStarvingList->RemoveHead();
  354.     pStarvingConn->m_ulLastStarvingTime = 0;
  355. }
  356. else
  357. {
  358.     break;
  359. }
  360.     }
  361.     // return 0 bytes if there is starving conn AND pConn is not the starving conn
  362.     // at the top of the list
  363.     if (!pStarvingConn || pStarvingConn == pConn)
  364.     {
  365. // either there is no starving conn OR
  366. // pConn is the starving conn
  367. ulBytesToRead = conn::m_ulMaxBandwidth - conn::m_ulTCPTotalBytesRead;
  368. if (pStarvingConn)
  369. {
  370.     pStarvingConn->m_ulLastStarvingTime = 0;
  371.     conn::m_pTCPStarvingList->RemoveHead();
  372. }
  373.     }
  374. cleanup:
  375.     HX_ASSERT(conn::mConnectionList);
  376.     // if there is no bytes to read and more than 1 source
  377.     if (ulBytesToRead == 0 && conn::mConnectionList && conn::mConnectionList->GetCount() > 1)
  378.     {
  379. if (!conn::m_pTCPStarvingList)
  380. {
  381.     conn::m_pTCPStarvingList = new CHXSimpleList();
  382. }
  383. if (!pConn->m_ulLastStarvingTime)
  384. {
  385.     pConn->m_ulLastStarvingTime = ulCurrentTime;
  386.     conn::m_pTCPStarvingList->AddTail(pConn);
  387. }
  388.     }
  389.     return ulBytesToRead;
  390. }
  391. void
  392. conn::bytes_to_actualtcpread(conn* pConn, UINT32 ulBytesRead)
  393. {
  394.     if (conn::m_ulMaxBandwidth != MAX_UINT32)
  395.     {
  396. conn::m_ulTCPTotalBytesRead += ulBytesRead;
  397.     }
  398. }
  399. HX_RESULT
  400. conn::EnumerateInterfaces
  401.     (REF(UINT32*) pulInterfaces, REF(UINT32) ulNumInterfaces)
  402. {
  403.     HX_RESULT theErr = HXR_OK;
  404.     const UINT32 ulHostNameLen = 256;
  405.  
  406.     char pHostname[ulHostNameLen]; /* Flawfinder: ignore */
  407.     
  408. #ifndef _MACINTOSH
  409.     char **pptr;
  410. #endif
  411. #ifdef _MACINTOSH
  412.     return HXR_UNEXPECTED;
  413. #endif
  414.     theErr = init_drivers(NULL);
  415.     if (FAILED(theErr))
  416.     {
  417. // just retrun, no need to close_driver()
  418. return theErr;
  419.     }
  420.     theErr = get_host_name(pHostname, ulHostNameLen);
  421.     if (FAILED(theErr))
  422.     {
  423. goto bail;
  424.     }    
  425.     // get local host name
  426.     struct hostent* hptr;    
  427.     theErr = get_host_by_name(pHostname, hptr);
  428.     if (FAILED(theErr))
  429.     { 
  430. goto bail;
  431.     }
  432.     HX_ASSERT(hptr);
  433. #ifndef _MACINTOSH
  434.     if (hptr->h_addrtype == AF_INET) 
  435.     {
  436. // get # of interfaces
  437. UINT32 ulIFCount = 0;
  438.      for (pptr = hptr->h_addr_list; *pptr != NULL; pptr++) 
  439.      {
  440.     ulIFCount++;
  441. }
  442. if (ulIFCount > ulNumInterfaces)
  443. {
  444.     // tell the user how many it needs.
  445.     ulNumInterfaces = ulIFCount;
  446.     theErr = HXR_BUFFERTOOSMALL;
  447.     goto bail;
  448. }
  449. ulNumInterfaces= 0;
  450. for (pptr = hptr->h_addr_list; *pptr != NULL; pptr++)
  451. {
  452.     pulInterfaces[ulNumInterfaces++] = DwToHost(*(UINT32*)*pptr);
  453. }
  454. HX_ASSERT(ulNumInterfaces == ulIFCount);
  455. theErr = HXR_OK;
  456.     }
  457.     else
  458.     {
  459. theErr = HXR_UNEXPECTED;
  460.     }
  461. #endif
  462. bail:    
  463.     return theErr;    
  464. }
  465. #if defined(HELIX_FEATURE_SECURECONN)
  466. CHXMapPtrToPtr secureconnhelper::zm_ConnMap;
  467. // xxxbobclark yeesh, why this is required I'm still working on.
  468. // Yuck nonetheless.
  469. void WasteTime()
  470. {
  471. #ifdef _MACINTOSH
  472. ULONG32 startTix = HX_GET_TICKCOUNT();
  473. while (CALCULATE_ELAPSED_TICKS(startTix, HX_GET_TICKCOUNT()) < 200)
  474. {
  475. //     EventRecord er;
  476. //     ::EventAvail(everyEvent, &er);
  477. }
  478. #endif
  479. }
  480. conn*
  481. secureconnhelper::GetConn(LONG32 fakeFD)
  482. {
  483.     conn* pConn = (conn*)zm_ConnMap[(void*)fakeFD];
  484.     
  485.     HX_ASSERT(pConn != NULL);
  486.     
  487.     return pConn;
  488. }
  489. void
  490. secureconnhelper::SetConn(LONG32 fakeFD, conn* pConn)
  491. {
  492.     HX_ASSERT(zm_ConnMap[(void*)fakeFD] == NULL);
  493.     
  494.     zm_ConnMap[(void*)fakeFD] = pConn;
  495. }
  496. long secureconnhelper::readCallback(LONG32 fakeFD, void* buff, LONG32 len)
  497. {
  498.     conn* pConn = GetConn(fakeFD);
  499.     
  500.     HX_RESULT result = HXR_FAIL;
  501.     
  502.     if (pConn)
  503.     {
  504. UINT16 bytes = (UINT16) len;
  505. result = pConn->read(buff, &bytes);
  506. WasteTime();
  507. if (result == HXR_OK)
  508. {
  509.     return bytes;
  510. }
  511.     }
  512.     return -1;
  513. }
  514. long secureconnhelper::writeCallback(LONG32 fakeFD, void* buff, LONG32 len)
  515. {
  516.     conn* pConn = GetConn(fakeFD);
  517.     
  518.     HX_RESULT result = HXR_FAIL;
  519.     
  520.     if (pConn)
  521.     {
  522. UINT16 bytes = (UINT16) len;
  523. result = pConn->write(buff, &bytes);
  524. WasteTime();
  525. if (result == HXR_OK)
  526. {
  527.     return bytes;
  528. }
  529.     }
  530.     return -1;
  531. }
  532. void secureconnhelper::closeCallback(LONG32 fakeFD)
  533. {
  534.     conn* pConn = GetConn(fakeFD);
  535.     
  536.     if (pConn)
  537.     {
  538. pConn->done();
  539.     }
  540. }
  541. LONG32 secureconn::zm_Count = 0;
  542. secureconn::secureconn(IHXSSL* pHXSSL)
  543.   : m_lRefCount(0)
  544.   , m_pActualConn(0)
  545.   , m_FakeFD(-1)
  546.   , m_pHXSSL(NULL)
  547. {
  548.     m_pActualConn = conn::new_socket(HX_TCP_SOCKET);
  549.     m_FakeFD = ++zm_Count;
  550.     secureconnhelper::SetConn(m_FakeFD, m_pActualConn);
  551.     m_pHXSSL = pHXSSL;
  552.     HX_ASSERT(m_pHXSSL != NULL);
  553.     m_pHXSSL->AddRef();
  554.     
  555.     m_pHXSSL->SetCallbacks((void*)secureconnhelper::readCallback,
  556.                            (void*)secureconnhelper::writeCallback,
  557.                            (void*)secureconnhelper::closeCallback);
  558.     
  559.     m_pHXSSL->Initialize();
  560. }
  561. secureconn::~secureconn()
  562. {
  563.     HX_ASSERT(m_pActualConn != NULL);
  564.     m_pHXSSL->Shutdown();
  565.     
  566.     HX_RELEASE(m_pHXSSL);
  567.     if (m_pActualConn)
  568.     {
  569.         m_pActualConn->Release();
  570.         m_pActualConn = NULL;
  571.     }
  572. }
  573. ULONG32 secureconn::AddRef()
  574. {
  575.     return InterlockedIncrement(&m_lRefCount);
  576. }
  577. ULONG32 secureconn::Release()
  578. {
  579.     if (InterlockedDecrement(&m_lRefCount) > 0)
  580.     {
  581.         return m_lRefCount;
  582.     }
  583.     delete this;
  584.     return 0;
  585. }
  586. HX_RESULT
  587. secureconn::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform)
  588. {
  589.     HX_ASSERT(m_pActualConn != NULL);
  590.     HX_ASSERT(m_pHXSSL != NULL);
  591.     
  592.     HX_RESULT result = m_pActualConn->connect(host, port, blocking, ulPlatform);
  593.     WasteTime();
  594.     
  595.     if (result == HXR_OK)
  596.     {
  597. result = m_pHXSSL->PostConnect(m_FakeFD);
  598.     }
  599.     
  600.     return result;
  601. }
  602. HX_RESULT
  603. secureconn::read(void* buf, UINT16* size)
  604. {
  605.     HX_ASSERT(m_pActualConn != NULL);
  606.     
  607.     HX_ASSERT(m_pHXSSL != NULL);
  608.     
  609.     LONG32 len = *size;
  610.     
  611.     len = m_pHXSSL->Read(m_FakeFD, buf, len);
  612.     
  613.     if (len == -1) return HXR_FAIL;
  614.     
  615.     *size = (UINT16) len;
  616.     return HXR_OK;
  617. }
  618. HX_RESULT
  619. secureconn::write(void* buf, UINT16* size)
  620. {
  621.     HX_ASSERT(m_pActualConn != NULL);
  622.     HX_ASSERT(m_pHXSSL != NULL);
  623.     
  624.     LONG32 len = *size;
  625.     
  626.     len = m_pHXSSL->Write(m_FakeFD, buf, len);
  627.     
  628.     if (len == -1) return HXR_FAIL;
  629.     
  630.     *size = (UINT16) len;
  631.     return HXR_OK;
  632. }
  633. HX_RESULT secureconn::blocking()
  634. {
  635.     HX_ASSERT(m_pActualConn != NULL);
  636.     
  637.     return m_pActualConn->blocking();
  638. }
  639. HX_RESULT secureconn::nonblocking()
  640. {
  641.     HX_ASSERT(m_pActualConn != NULL);
  642.     
  643.     return m_pActualConn->nonblocking();
  644. }
  645. HX_RESULT secureconn::readfrom(REF(IHXBuffer*)   pBuffer,
  646.  REF(UINT32)     ulAddress,
  647.  REF(UINT16)     ulPort)
  648. {
  649.     HX_ASSERT(m_pActualConn != NULL);
  650.     
  651.     return m_pActualConn->readfrom(pBuffer, ulAddress, ulPort);
  652. }
  653. HX_RESULT secureconn::writeto(void  *buf,
  654.  UINT16  *len, 
  655.  ULONG32  addr,
  656.  UINT16  port)
  657. {
  658.     HX_ASSERT(m_pActualConn != NULL);
  659.     
  660.     return m_pActualConn->writeto(buf, len, addr, port);
  661. }
  662. ULONG32 secureconn::get_addr()
  663. {
  664.     HX_ASSERT(m_pActualConn != NULL);
  665.     
  666.     return m_pActualConn->get_addr();
  667. }
  668. UINT16 secureconn::get_local_port()
  669. {
  670.     HX_ASSERT(m_pActualConn != NULL);
  671.     
  672.     return m_pActualConn->get_local_port();
  673. }
  674. HX_RESULT
  675. secureconn::dns_find_ip_addr(const char * host, UINT16 blocking)
  676. {
  677.     HX_ASSERT(m_pActualConn != NULL);
  678.     
  679.     return m_pActualConn->dns_find_ip_addr(host, blocking);
  680. }
  681. BOOL
  682. secureconn::dns_ip_addr_found(BOOL * valid, ULONG32 *addr)
  683. {
  684.     HX_ASSERT(m_pActualConn != NULL);
  685.     
  686.     return m_pActualConn->dns_ip_addr_found(valid, addr);
  687. }
  688. void
  689. secureconn::done()
  690. {
  691.     HX_ASSERT(m_pActualConn != NULL);
  692.     
  693.     m_pActualConn->done();
  694. }
  695. HX_RESULT
  696. secureconn::init(UINT32 local_addr,
  697. UINT16  port, 
  698.  UINT16  blocking)
  699. {
  700.     HX_ASSERT(m_pActualConn != NULL);
  701.     
  702.     return m_pActualConn->init(local_addr, port, blocking);
  703. }
  704. HX_RESULT
  705. secureconn::listen(ULONG32 ulLocalAddr,
  706.  UINT16 port,
  707.  UINT16  backlog,
  708.  UINT16 blocking,
  709.  ULONG32 ulPlatform)
  710. {
  711.     HX_ASSERT(m_pActualConn != NULL);
  712.     
  713.     return m_pActualConn->listen(ulLocalAddr, port, backlog, blocking, ulPlatform);
  714. }
  715. HX_RESULT
  716. secureconn::join_multicast_group(ULONG32 addr, ULONG32 if_addr)
  717. {
  718.     HX_ASSERT(m_pActualConn != NULL);
  719.     
  720.     return m_pActualConn->join_multicast_group(addr, if_addr);
  721. }
  722. HX_RESULT
  723. secureconn::leave_multicast_group(ULONG32 addr, ULONG32 if_addr)
  724. {
  725.     HX_ASSERT(m_pActualConn != NULL);
  726.     
  727.     return m_pActualConn->leave_multicast_group(addr, if_addr);
  728. }
  729. HX_RESULT
  730. secureconn::set_broadcast(BOOL enable)
  731. {
  732.     HX_ASSERT(m_pActualConn != NULL);
  733.     
  734.     return m_pActualConn->set_broadcast(enable);
  735. }
  736. HX_RESULT
  737. secureconn::set_multicast_if(UINT32 ulInterface)
  738. {
  739.     HX_ASSERT(m_pActualConn != NULL);
  740.     
  741.     return m_pActualConn->set_multicast_if(ulInterface);
  742. }
  743. HX_RESULT
  744. secureconn::last_error()
  745. {
  746.     HX_ASSERT(m_pActualConn != NULL);
  747.     
  748.     return m_pActualConn->last_error();
  749. }
  750. #ifdef _MACINTOSH
  751. HX_RESULT
  752. secureconn::GetEndpoint(REF(void*) pRef)
  753. {
  754.     HX_ASSERT(m_pActualConn != NULL);
  755.     
  756.     return m_pActualConn->GetEndpoint(pRef);
  757. }
  758. HX_RESULT
  759. secureconn::SetupEndpoint(BOOL bWait)
  760. {
  761.     HX_ASSERT(m_pActualConn != NULL);
  762.     
  763.     return m_pActualConn->SetupEndpoint(bWait);
  764. }
  765. #endif
  766. void
  767. secureconn::set_callback(HXAsyncNetCallback* pCallback)
  768. {
  769.     HX_ASSERT(m_pActualConn != NULL);
  770.     
  771.     m_pActualConn->set_callback(pCallback);
  772. }
  773. UINT16
  774. secureconn::connection_open()
  775. {
  776.     HX_ASSERT(m_pActualConn != NULL);
  777.     
  778.     return m_pActualConn->connection_open();
  779. }
  780. int
  781. secureconn::get_sock()
  782. {
  783.     HX_ASSERT(m_pActualConn != NULL);
  784.     
  785.     return m_pActualConn->get_sock();
  786. }
  787. void
  788. secureconn::set_sock(int theSock)
  789. {
  790.     HX_ASSERT(m_pActualConn != NULL);
  791.     
  792.     m_pActualConn->set_sock(theSock);
  793. }
  794. BOOL
  795. secureconn::set_receive_buf_size(int DesiredSize)
  796. {
  797.     HX_ASSERT(m_pActualConn != NULL);
  798.     
  799.     return m_pActualConn->set_receive_buf_size(DesiredSize);
  800. }
  801. HX_RESULT
  802. secureconn::reuse_addr(BOOL enable)
  803. {
  804.     HX_ASSERT(m_pActualConn != NULL);
  805.     
  806.     return m_pActualConn->reuse_addr(enable);
  807. }
  808. HX_RESULT
  809. secureconn::reuse_port(BOOL enable)
  810. {
  811.     HX_ASSERT(m_pActualConn != NULL);
  812.     
  813.     return m_pActualConn->reuse_port(enable);
  814. }
  815. #endif /* HELIX_FEATURE_SECURECONN */
  816. #ifdef TESTING
  817. #include "conn.h"
  818. int opt_debug = 0xff;
  819. int main( int argc, char **argv )
  820. {
  821. conn *m_conn = 0;
  822. HX_RESULT theErr = HXR_OK;
  823. m_conn = conn::new_socket( HX_TCP_SOCKET );
  824. if ( m_conn )
  825. {
  826. // XXXAAK -- local addr binding stuff
  827. theErr = m_conn->init( INADDR_ANY, argc > 2 ? atoi(argv[2]) : 7071, 1);
  828. if ( !theErr )
  829. {
  830. theErr = m_conn->connect( argc > 1 ? argv[1] : "localhost",
  831. argc > 2 ? atoi(argv[2]) : 7071,
  832. 1);
  833. printf("connect(): %s, port: %d, theErr: %d, errno: %dn", 
  834. argc > 1 ? argv[1] : "localhost",
  835. argc > 2 ? atoi(argv[2]) : 7071,
  836. theErr, errno );
  837. }
  838. else
  839. printf("Couldn't init port: %d, theErr: %dn",
  840. argc > 2 ? atoi(argv[2]) : 7071,
  841. theErr);
  842. }
  843. else
  844. printf("Couldn't create a new TCP socket!n");
  845. exit(0);
  846. }
  847. #endif