Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1918 lines
50 KiB

  1. /*******************************************************************************
  2. ********************************************************************************
  3. **
  4. ** The RSIP implementation
  5. **
  6. ********************************************************************************
  7. *******************************************************************************/
  8. #include <winsock2.h>
  9. #include <MMSystem.h>
  10. #include <WSIPX.h>
  11. #include <stdlib.h>
  12. #include <malloc.h>
  13. #include "RSIPdefs.h"
  14. #include "ICSutils.h"
  15. #include "rsip.h"
  16. /*******************************************************************************
  17. ********************************************************************************
  18. **
  19. ** LOCAL variables used by this module
  20. **
  21. ********************************************************************************
  22. *******************************************************************************/
  23. CRITICAL_SECTION g_CritSec;
  24. SOCKET g_sRsip;
  25. SOCKADDR_IN g_saddrGateway;
  26. SOCKADDR g_saddrPublic;
  27. int g_iPort;
  28. DWORD g_ClientID;
  29. HANDLE g_hThreadEvent=NULL;
  30. HANDLE g_hAlertEvent=NULL;
  31. RSIP_LEASE_RECORD *g_pRsipLeaseRecords; // list of leases.
  32. ADDR_ENTRY *g_pAddrEntry; // cache of mappings.
  33. DWORD g_tuRetry; // microseconds starting retry time.
  34. LONG g_MsgID = 0;
  35. //**********************************************************************
  36. // the mark of the beast...
  37. #define NO_ICS_HANDLE 0x666
  38. #define DPN_OK S_OK
  39. #define DPNERR_GENERIC E_FAIL
  40. #define DPNERR_INVALIDPARAM E_INVALIDARG
  41. void Lock( void )
  42. {
  43. EnterCriticalSection( &g_CritSec );
  44. }
  45. void Unlock( void )
  46. {
  47. LeaveCriticalSection( &g_CritSec );
  48. }
  49. /*=============================================================================
  50. Initialize - Initialize RSIP support. If this function succeeds then there
  51. is an RSIP gateway on the network and the SP should call the
  52. RSIP services when creating and destroying sockets that need
  53. to be accessed from machines outside the local realm.
  54. Description:
  55. Looks for the Gateway, then check to see if it is RSIP enabled.
  56. Parameters:
  57. Pointer to base socket address
  58. Used to take SP guid to look up gateway on Win95. Since this
  59. only works on Win9x, the GUID is hard-coded in the function call
  60. because old DPlay is guaranteed to be available on a Win9x system.
  61. Any new systems won't care because they'll support the GetAdaptersInfo
  62. call.
  63. Boolean indicating that this is an Rsip host
  64. Return Values:
  65. TRUE - found and RSIP gateway and initialized.
  66. FALSE - no RSIP gateway found.
  67. -----------------------------------------------------------------------------*/
  68. BOOL Initialize( SOCKADDR *pBaseSocketAddress,
  69. BOOL fIsRsipServer )
  70. {
  71. BOOL bReturn = TRUE;
  72. BOOL fBroadcastFlag;
  73. INT_PTR iReturnValue;
  74. SOCKADDR_IN saddr;
  75. TRIVIAL_MSG((L"Initialize(%S)", fIsRsipServer?"TRUE":"FALSE" ));
  76. // create a SOCKADDR to address the RSIP service on the gateway
  77. memset(&g_saddrGateway, 0, sizeof( g_saddrGateway ) );
  78. g_saddrGateway.sin_family = AF_INET;
  79. g_saddrGateway.sin_port = htons( RSIP_HOST_PORT );
  80. // create an address to specify the port to bind our datagram socket to.
  81. memset(&saddr,0,sizeof(SOCKADDR_IN));
  82. saddr.sin_family = AF_INET;
  83. saddr.sin_port = htons(0);
  84. //
  85. // if this is the Rsip server, bind to all adapters and talk via loopback.
  86. // If not, bind to the particular adapter and use broadcast to find the
  87. // Rsip server
  88. //
  89. if ( fIsRsipServer != FALSE )
  90. {
  91. g_saddrGateway.sin_addr.S_un.S_addr = htonl( INADDR_LOOPBACK );
  92. saddr.sin_addr.s_addr = htonl( INADDR_ANY );
  93. }
  94. else
  95. {
  96. g_saddrGateway.sin_addr.S_un.S_addr = htonl( INADDR_BROADCAST );
  97. saddr.sin_addr.s_addr = ((SOCKADDR_IN*)( pBaseSocketAddress ))->sin_addr.s_addr;
  98. }
  99. // create a datagram socket for talking to the RSIP facility on the gateway
  100. if( ( g_sRsip = socket( AF_INET, SOCK_DGRAM, 0 ) ) == INVALID_SOCKET ){
  101. IMPORTANT_MSG((L"ERROR: rsipInit() socket call for RSIP listener failed\n"));
  102. bReturn = FALSE;
  103. goto Exit;
  104. }
  105. //
  106. // set socket to allow broadcasts
  107. //
  108. fBroadcastFlag = TRUE;
  109. iReturnValue = setsockopt( g_sRsip, // socket
  110. SOL_SOCKET, // level (set socket options)
  111. SO_BROADCAST, // set broadcast option
  112. (char *)( &fBroadcastFlag ), // allow broadcast
  113. sizeof( fBroadcastFlag ) // size of parameter
  114. );
  115. if ( iReturnValue == SOCKET_ERROR )
  116. {
  117. DWORD dwErrorCode;
  118. dwErrorCode = WSAGetLastError();
  119. IMPORTANT_MSG((L"Unable to set socket options!"));
  120. bReturn = FALSE;
  121. goto Exit;
  122. }
  123. // bind the datagram socket to any local address and port.
  124. if( bind(g_sRsip, (PSOCKADDR)&saddr, sizeof(saddr) ) != 0){
  125. IMPORTANT_MSG((L"ERROR: rsipInit() bind for RSIP listener failed\n"));
  126. bReturn=FALSE;
  127. goto Exit;
  128. }
  129. g_tuRetry=12500; // start retry timer at 12.5 ms
  130. // find out if there is an rsip service and register with it.
  131. if ( Register() != DPN_OK )
  132. {
  133. bReturn=FALSE;
  134. goto Exit;
  135. }
  136. Exit:
  137. if( bReturn == FALSE )
  138. {
  139. if( g_sRsip != INVALID_SOCKET )
  140. {
  141. closesocket( g_sRsip );
  142. g_sRsip = INVALID_SOCKET;
  143. }
  144. }
  145. return bReturn;
  146. }
  147. /*=============================================================================
  148. Deinitialize - Shut down RSIP support
  149. All threads that might access RSIP MUST be stopped before this
  150. is called.
  151. Description:
  152. Deregisters with the Rsip Agent on the gateway, and cleans up
  153. the list of lease records.
  154. Parameters:
  155. Pointer to thread pool
  156. Return Values:
  157. None.
  158. -----------------------------------------------------------------------------*/
  159. void Deinitialize( void )
  160. {
  161. RSIP_LEASE_RECORD *pLeaseWalker;
  162. RSIP_LEASE_RECORD *pNextLease;
  163. ADDR_ENTRY *pAddrWalker;
  164. ADDR_ENTRY *pNextAddr;
  165. if(g_sRsip!=INVALID_SOCKET){
  166. Deregister();
  167. closesocket(g_sRsip);
  168. g_sRsip=INVALID_SOCKET;
  169. }
  170. // free the leases
  171. pLeaseWalker = g_pRsipLeaseRecords;
  172. while( pLeaseWalker ){
  173. pNextLease = pLeaseWalker->pNext;
  174. free(pLeaseWalker);
  175. pLeaseWalker=pNextLease;
  176. }
  177. g_pRsipLeaseRecords=NULL;
  178. // free the cached address mappings
  179. pAddrWalker=g_pAddrEntry;
  180. while(pAddrWalker){
  181. pNextAddr=pAddrWalker->pNext;
  182. free(pAddrWalker);
  183. pAddrWalker=pNextAddr;
  184. }
  185. g_pAddrEntry=NULL;
  186. g_MsgID = 0;
  187. g_tuRetry = 0;
  188. memset( &g_saddrGateway, 0x00, sizeof( g_saddrGateway ) );
  189. }
  190. //**********************************************************************
  191. // ------------------------------
  192. // RsipIsRunningOnThisMachine - return Boolean indicating whether this machine
  193. // is an Rsip machine.
  194. //
  195. // Entry: Pointer to socket address to be filled in with public address
  196. //
  197. // Exit: Boolean
  198. // TRUE = this is Rsip machine
  199. // FALSE = this is not Rsip machine
  200. // ------------------------------
  201. BOOL RsipIsRunningOnThisMachine( SOCKADDR *pPublicSocketAddress )
  202. {
  203. SOCKET Socket;
  204. BOOL fReturn;
  205. Socket = INVALID_SOCKET;
  206. fReturn = FALSE;
  207. TRIVIAL_MSG((L"RsipIsRunningOnThisMachine begins"));
  208. //
  209. // Attempt to bind to the Rsip port. If we can't bind to it, assume that
  210. // Rsip is running on this machine.
  211. //
  212. Socket = socket( AF_INET, SOCK_DGRAM, 0 );
  213. if ( Socket != INVALID_SOCKET )
  214. {
  215. SOCKADDR_IN addr;
  216. memset( &addr, 0, sizeof(SOCKADDR_IN ) );
  217. addr.sin_family = AF_INET;
  218. addr.sin_addr.S_un.S_addr = htonl( INADDR_LOOPBACK );
  219. addr.sin_port = htons( RSIP_HOST_PORT );
  220. if ( bind( Socket, (SOCKADDR*)( &addr ), sizeof( addr ) ) != 0 )
  221. {
  222. fReturn = TRUE;
  223. TRIVIAL_MSG((L"bind successfull"));
  224. }
  225. closesocket( Socket );
  226. Socket = INVALID_SOCKET;
  227. }
  228. //
  229. // This is an Rsip server, create a local socket and bind it to the server
  230. // to find out what the public address is.
  231. //
  232. if ( fReturn != FALSE )
  233. {
  234. HRESULT hr;
  235. SOCKADDR_IN SocketAddress;
  236. INT iBoundAddressSize;
  237. SOCKADDR_IN BoundAddress;
  238. SOCKADDR RsipAssignedAddress;
  239. DWORD dwBindID;
  240. Socket = socket( AF_INET, SOCK_DGRAM, 0 );
  241. if ( Socket == INVALID_SOCKET )
  242. {
  243. fReturn = FALSE;
  244. TRIVIAL_MSG((L"socket choked"));
  245. goto Failure;
  246. }
  247. memset( &SocketAddress, 0x00, sizeof( SocketAddress ) );
  248. SocketAddress.sin_family = AF_INET;
  249. SocketAddress.sin_addr.S_un.S_addr = htonl( INADDR_ANY );
  250. SocketAddress.sin_port = htons( ANY_PORT );
  251. if ( bind( Socket, (SOCKADDR*)( &SocketAddress ), sizeof( SocketAddress ) ) != 0 )
  252. {
  253. TRIVIAL_MSG((L"bind failed in query"));
  254. fReturn = FALSE;
  255. goto Failure;
  256. }
  257. iBoundAddressSize = sizeof( BoundAddress );
  258. if ( getsockname( Socket, (SOCKADDR*)( &BoundAddress ), &iBoundAddressSize ) != 0 )
  259. {
  260. TRIVIAL_MSG((L"failed in getsockname"));
  261. fReturn = FALSE;
  262. goto Failure;
  263. }
  264. if ( Initialize((SOCKADDR*)( &SocketAddress ), TRUE ) == FALSE )
  265. {
  266. TRIVIAL_MSG((L"failed in Initialize"));
  267. fReturn = FALSE;
  268. goto Failure;
  269. }
  270. hr = AssignPort( FALSE, BoundAddress.sin_port, &RsipAssignedAddress, &dwBindID );
  271. if ( hr != DPN_OK )
  272. {
  273. fReturn = FALSE;
  274. IMPORTANT_MSG((L"Failed to assign port when attempting to determine public network address!" ));
  275. goto Failure;
  276. }
  277. memcpy( pPublicSocketAddress, &RsipAssignedAddress, sizeof( *pPublicSocketAddress ) );
  278. FreePort( dwBindID );
  279. }
  280. Exit:
  281. if ( Socket != INVALID_SOCKET )
  282. {
  283. closesocket( Socket );
  284. Socket = INVALID_SOCKET;
  285. }
  286. TRIVIAL_MSG((L"RsipIsRunningOnThisMachine ends, returning %S", fReturn?"TRUE":"FALSE"));
  287. return fReturn;
  288. Failure:
  289. goto Exit;
  290. }
  291. /*=============================================================================
  292. ExchangeAndParse - send a request to the rsip server and
  293. wait for and parse the reply
  294. Description:
  295. Since there is almost no scenario where we don't immediately need to know
  296. the response to an rsipExchange, there is no point in doing this
  297. asynchronously. The assumption is that an RSIP server is sufficiently
  298. local that long retries are not necessary. We use the approach suggested
  299. in the IETF draft protocol specification, that is 12.5ms retry timer
  300. with 7-fold exponential backoff. This can lead to up to a total 1.5
  301. second wait in the worst case. (Note this section may no longer be
  302. available since the rsip working group decided to drop UDP support)
  303. Parameters:
  304. pRequest - a fully formatted RSIP request buffer
  305. cbReq - size of request buffer
  306. pRespInfo - structure that returns response parameters
  307. messageid - the message id of this request
  308. bConnect - whether this is the register request, we use a different
  309. timer strategy on initial connect because we really
  310. don't want to miss it if there is a gateway.
  311. pRecvSocketAddress - pointer to recv address destination (needed for connect)
  312. Return Values:
  313. DPN_OK - exchange succeeded, reply is in the reply buffer.
  314. otw, failed, RespInfo is bogus.
  315. -----------------------------------------------------------------------------*/
  316. #define MAX_RSIP_RETRY 6
  317. struct timeval tv0={0,0};
  318. DWORD ExchangeAndParse( PCHAR pRequest,
  319. UINT cbReq,
  320. RSIP_RESPONSE_INFO *pRespInfo,
  321. DWORD messageid,
  322. BOOL bConnect,
  323. SOCKADDR *pRecvSocketAddress )
  324. {
  325. CHAR RespBuffer[ RESP_BUF_SIZE ];
  326. DWORD dwRespLen = sizeof( RespBuffer );
  327. INT iRecvSocketAddressSize = sizeof( *pRecvSocketAddress );
  328. struct timeval tv;
  329. FD_SET readfds;
  330. INT nRetryCount=0;
  331. int rc;
  332. int cbReceived;
  333. HRESULT hr=DPN_OK;
  334. if ( pRequest == NULL ||
  335. pRespInfo == NULL ||
  336. pRecvSocketAddress == NULL )
  337. {
  338. IMPORTANT_MSG((L"RsipExchangeAndParse bad params passed (0x%x, 0x%x, 0x%x)",pRequest,pRespInfo,pRecvSocketAddress));
  339. return DPNERR_INVALIDPARAM;
  340. }
  341. INTERESTING_MSG((L"==>RsipExchangeAndParse msgid %d", messageid ));
  342. memset(RespBuffer, 0, RESP_BUF_SIZE);
  343. memset(pRespInfo, 0, sizeof(RSIP_RESPONSE_INFO));
  344. if(!bConnect){
  345. tv.tv_usec = g_tuRetry;
  346. tv.tv_sec = 0;
  347. nRetryCount = 0;
  348. } else {
  349. // on a connect request we try twice with a 1 second total timeout
  350. tv.tv_usec = 500000; // 0.5 seconds
  351. tv.tv_sec = 0;
  352. nRetryCount = MAX_RSIP_RETRY-2;
  353. }
  354. FD_ZERO(&readfds);
  355. FD_SET(g_sRsip, &readfds);
  356. rc=0;
  357. // First clear out any extraneous responses.
  358. while( select( 0, &readfds, NULL, NULL, &tv0 ) )
  359. {
  360. cbReceived = recvfrom( g_sRsip, RespBuffer, dwRespLen, 0, NULL, NULL );
  361. switch ( cbReceived )
  362. {
  363. //
  364. // nothing received, try again
  365. //
  366. case 0:
  367. {
  368. break;
  369. }
  370. //
  371. // read failure, bail!
  372. //
  373. case SOCKET_ERROR:
  374. {
  375. rc = WSAGetLastError();
  376. IMPORTANT_MSG((L"Got sockets error %d trying to receive (clear incoming queue) on RSIP socket", rc ));
  377. hr = DPNERR_GENERIC;
  378. break;
  379. }
  380. default:
  381. {
  382. TRIVIAL_MSG((L"Found extra response from previous RSIP request" ));
  383. if( g_tuRetry < RSIP_tuRETRY_MAX )
  384. {
  385. // don't re-try so quickly
  386. g_tuRetry *= 2;
  387. TRIVIAL_MSG((L"rsip Set g_tuRetry to %d usec", g_tuRetry ));
  388. }
  389. break;
  390. }
  391. }
  392. FD_ZERO(&readfds);
  393. FD_SET(g_sRsip, &readfds);
  394. }
  395. // Now do the exchange, get a response to the request, does retries too.
  396. do{
  397. if(++nRetryCount > MAX_RSIP_RETRY) {
  398. break;
  399. }
  400. TRIVIAL_MSG((L"Sending RSIP Request to gateway, RetryCount=%d", nRetryCount ));
  401. DumpSocketAddress( 0, (SOCKADDR*)( &g_saddrGateway ), AF_INET);
  402. // First send off the request
  403. rc=sendto(g_sRsip, pRequest, cbReq, 0, (SOCKADDR *)&g_saddrGateway, sizeof(SOCKADDR) );
  404. if( rc == SOCKET_ERROR )
  405. {
  406. rc = WSAGetLastError();
  407. IMPORTANT_MSG((L"Got sockets error %d on sending to RSIP gateway", rc ));
  408. hr = DPNERR_GENERIC;
  409. goto exit;
  410. }
  411. if( rc != (int)cbReq )
  412. {
  413. IMPORTANT_MSG((L"Didn't send entire datagram? shouldn't happen" ));
  414. hr=DPNERR_GENERIC;
  415. goto exit;
  416. }
  417. // Now see if we get a response.
  418. select_again:
  419. FD_ZERO(&readfds);
  420. FD_SET(g_sRsip, &readfds);
  421. rc=select(0,&readfds,NULL,NULL,&tv);
  422. if(rc==SOCKET_ERROR){
  423. rc=WSAGetLastError();
  424. IMPORTANT_MSG((L"Got sockets error %d trying to select on RSIP socket",rc));
  425. hr=DPNERR_GENERIC;
  426. }
  427. TRIVIAL_MSG((L"Return From Select %d",rc));
  428. //
  429. // there's only one item in the set, make sure of this, and if there
  430. // was a signalled socket, make sure it's our socket.
  431. //
  432. if( LocalFDIsSet(g_sRsip, &readfds)){
  433. break;
  434. }
  435. if(!bConnect){
  436. IMPORTANT_MSG((L"Didn't get response, increasing timeout value" ));
  437. // don't use exponential backoff on initial connect
  438. tv.tv_usec *= 2; // exponential backoff.
  439. }
  440. } while (rc==0); // keep retrying...
  441. if(rc == SOCKET_ERROR){
  442. IMPORTANT_MSG((L"GotSocketError on select, extended error %d",WSAGetLastError()));
  443. hr=DPNERR_GENERIC;
  444. goto exit;
  445. }
  446. if(rc)
  447. {
  448. // We Got Mail, err data....
  449. dwRespLen=RESP_BUF_SIZE;
  450. TRIVIAL_MSG((L"Receiving Data" ));
  451. memset( pRecvSocketAddress, 0x00, sizeof( *pRecvSocketAddress ) );
  452. cbReceived=recvfrom(g_sRsip, RespBuffer, dwRespLen, 0, pRecvSocketAddress, &iRecvSocketAddressSize);
  453. TRIVIAL_MSG((L"cbReceived = %d", cbReceived ));
  454. if( ( cbReceived == 0 ) || ( cbReceived == SOCKET_ERROR ) )
  455. {
  456. rc=WSAGetLastError();
  457. IMPORTANT_MSG((L"Got sockets error %d trying to receive on RSIP socket", rc ));
  458. hr=DPNERR_GENERIC;
  459. }
  460. else
  461. {
  462. TRIVIAL_MSG((L"Parsing Receive Buffer" ));
  463. Parse( RespBuffer, cbReceived, pRespInfo );
  464. if(pRespInfo->messageid != messageid)
  465. {
  466. // Got a dup from a previous retry, go try again.
  467. IMPORTANT_MSG((L"Got messageid %d, expecting messageid %d", pRespInfo->messageid, messageid ));
  468. goto select_again;
  469. }
  470. }
  471. }
  472. INTERESTING_MSG((L"<==RsipExchangeAndParse hr=%x, Resp msgid %d", hr, pRespInfo->messageid ));
  473. exit:
  474. return hr;
  475. }
  476. /*=============================================================================
  477. Parse - parses an RSIP request and puts fields into a struct.
  478. Description:
  479. This parser parses and RSIP request or response and extracts
  480. out the codes into a standard structure. This is not completely
  481. general, as we know that we will only operate with v4 addresses
  482. and our commands will never deal with more than 1 address at a
  483. time. If you need to handle multiple address requests
  484. and responses, then you will need to change this function.
  485. Limitations:
  486. This function only deals with single address/port responses.
  487. Rsip allows for multiple ports to be allocated in a single
  488. request, but we do not take advantage of this feature.
  489. Parameters:
  490. pBuf - buffer containing an RSIP request or response
  491. cbBuf - size of buffer in bytes
  492. pRespInfo - a structure that is filled with the parameters
  493. from the RSIP buffer.
  494. Return Values:
  495. DPN_OK - connected to the RSIP server.
  496. -----------------------------------------------------------------------------*/
  497. HRESULT Parse( CHAR *pBuf, DWORD cbBuf, PRSIP_RESPONSE_INFO pRespInfo )
  498. {
  499. // character pointer version of parameter pointer.
  500. BOOL bGotlAddress=FALSE;
  501. BOOL bGotlPort =FALSE;
  502. DWORD code;
  503. DWORD codelen;
  504. PRSIP_MSG_HDR pHeader;
  505. PRSIP_PARAM pParam,pNextParam;
  506. CHAR *pc;
  507. CHAR *pBufEnd = pBuf+cbBuf;
  508. if(cbBuf < 2){
  509. return DPNERR_INVALIDPARAM;
  510. }
  511. pHeader=(PRSIP_MSG_HDR)pBuf;
  512. pRespInfo->version = pHeader->version;
  513. pRespInfo->msgtype = pHeader->msgtype;
  514. INTERESTING_MSG((L"rsipParse: version %d msgtype %d",pRespInfo->version, pRespInfo->msgtype));
  515. pParam = (PRSIP_PARAM)(pHeader+1);
  516. while((CHAR*)(pParam+1) < pBufEnd)
  517. {
  518. pc=(CHAR *)(pParam+1);
  519. pNextParam = (PRSIP_PARAM)(pc + pParam->len);
  520. if((CHAR *)pNextParam > pBufEnd){
  521. break;
  522. }
  523. switch(pParam->code){
  524. case RSIP_ADDRESS_CODE:
  525. // Addresses are type[1]|addr[?]
  526. switch(*pc){
  527. case 1:
  528. if(!bGotlAddress){
  529. TRIVIAL_MSG((L"rsipParse: lAddress %S",inet_ntoa(*((PIN_ADDR)(pc+1)))));
  530. memcpy((char *)&pRespInfo->lAddressV4, pc+1, 4);
  531. bGotlAddress=TRUE;
  532. } else {
  533. bGotlPort=TRUE; // just in case there wasn't a local port
  534. TRIVIAL_MSG((L"rsipParse: rAddress %S,",inet_ntoa(*((PIN_ADDR)(pc+1)))));
  535. memcpy((char *)&pRespInfo->rAddressV4, pc+1, 4);
  536. }
  537. break;
  538. case 0:
  539. case 2:
  540. case 3:
  541. case 4:
  542. case 5:
  543. TRIVIAL_MSG((L"Unexpected RSIP address code type %d",*pc));
  544. break;
  545. }
  546. break;
  547. case RSIP_PORTS_CODE:
  548. // Ports are Number[1]|Port[2]....Port[2]
  549. if(!bGotlPort){
  550. TRIVIAL_MSG((L"rsipParse lPort: %d", *((WORD *)(pc+1))));
  551. memcpy((char *)&pRespInfo->lPort, pc+1,2);
  552. } else {
  553. TRIVIAL_MSG((L"rsipParse rPort: %d", *((WORD *)(pc+1))));
  554. memcpy((char *)&pRespInfo->rPort, pc+1,2);
  555. bGotlPort=TRUE;
  556. }
  557. break;
  558. case RSIP_LEASE_CODE:
  559. if(pParam->len == 4){
  560. memcpy((char *)&pRespInfo->leasetime,pc,4);
  561. TRIVIAL_MSG((L"rsipParse Lease: %d",pRespInfo->leasetime));
  562. }
  563. break;
  564. case RSIP_CLIENTID_CODE:
  565. if(pParam->len==4){
  566. memcpy((char *)&pRespInfo->clientid,pc,4);
  567. TRIVIAL_MSG((L"rsipParse clientid: %d",pRespInfo->clientid));
  568. }
  569. break;
  570. case RSIP_BINDID_CODE:
  571. if(pParam->len==4){
  572. memcpy((char *)&pRespInfo->bindid,pc,4);
  573. TRIVIAL_MSG((L"rsipParse bindid: %x",pRespInfo->bindid));
  574. }
  575. break;
  576. case RSIP_MESSAGEID_CODE:
  577. if(pParam->len==4){
  578. memcpy((char *)&pRespInfo->messageid,pc,4);
  579. TRIVIAL_MSG((L"rsipParse messageid: %d",pRespInfo->messageid));
  580. }
  581. break;
  582. case RSIP_TUNNELTYPE_CODE:
  583. TRIVIAL_MSG((L"rsipParse Got Tunnel Type %d, ignoring",*pc));
  584. break;
  585. case RSIP_RSIPMETHOD_CODE:
  586. TRIVIAL_MSG((L"rsipParse Got RSIP Method %d, ignoring",*pc));
  587. break;
  588. case RSIP_ERROR_CODE:
  589. if(pParam->len==2){
  590. memcpy((char *)&pRespInfo->error,pc,2);
  591. }
  592. TRIVIAL_MSG((L"rsipParse Got RSIP error %d",pRespInfo->error));
  593. break;
  594. case RSIP_FLOWPOLICY_CODE:
  595. TRIVIAL_MSG((L"rsipParse Got RSIP Flow Policy local %d remote %d, ignoring",*pc,*(pc+1)));
  596. break;
  597. case RSIP_VENDOR_CODE:
  598. break;
  599. default:
  600. TRIVIAL_MSG((L"Got unknown parameter code %d, ignoring",pParam->code));
  601. break;
  602. }
  603. pParam=pNextParam;
  604. }
  605. return DPN_OK;
  606. }
  607. /*=============================================================================
  608. Register - register with the RSIP server on the gateway (if present)
  609. Description:
  610. Trys to contact the RSIP service on the gateway.
  611. Doesn't require lock since this is establishing the link during
  612. startup. So no-one is racing with us.
  613. Parameters:
  614. None.
  615. Return Values:
  616. DPN_OK - connected to the RSIP server.
  617. DPNERR_GENERIC - can't find the RSIP service on the gateway.
  618. -----------------------------------------------------------------------------*/
  619. HRESULT Register( void )
  620. {
  621. HRESULT hr;
  622. SOCKADDR RecvSocketAddress;
  623. MSG_RSIP_REGISTER RegisterReq;
  624. RSIP_RESPONSE_INFO RespInfo;
  625. INTERESTING_MSG((L"==>RSIP Register" ));
  626. // Initialize the message sequencing. Each message response pair
  627. // is numbered sequentially to allow differentiation over UDP link.
  628. g_MsgID = 0;
  629. // Build the request
  630. RegisterReq.version = RSIP_VERSION;
  631. RegisterReq.command = RSIP_REGISTER_REQUEST;
  632. RegisterReq.msgid.code = RSIP_MESSAGEID_CODE;
  633. RegisterReq.msgid.len = sizeof(DWORD);
  634. RegisterReq.msgid.msgid = InterlockedIncrement( &g_MsgID );
  635. hr = ExchangeAndParse( (PCHAR)&RegisterReq,
  636. sizeof(RegisterReq),
  637. &RespInfo,
  638. RegisterReq.msgid.msgid,
  639. TRUE,
  640. &RecvSocketAddress );
  641. if(hr!=DPN_OK){
  642. goto exit;
  643. }
  644. if(RespInfo.msgtype != RSIP_REGISTER_RESPONSE){
  645. TRIVIAL_MSG((L"Failing registration, response was message type %d",RespInfo.msgtype));
  646. goto error_exit;
  647. }
  648. g_ClientID = RespInfo.clientid;
  649. memcpy( &g_saddrGateway, &RecvSocketAddress, sizeof( g_saddrGateway ) );
  650. INTERESTING_MSG((L"<==RSIP Register, ClientId %d", g_ClientID ));
  651. exit:
  652. return hr;
  653. error_exit:
  654. IMPORTANT_MSG((L"<==RSIP Register FAILED" ));
  655. return DPNERR_GENERIC;
  656. }
  657. /*=============================================================================
  658. Deregister - close connection to RSIP gateway.
  659. Description:
  660. Shuts down the registration of this application with the RSIP
  661. gateway. All port assignments are implicitly freed as a result
  662. of this operation.
  663. - must be called with lock held.
  664. Parameters:
  665. None.
  666. Return Values:
  667. DPN_OK - successfully deregistered with the RSIP service.
  668. -----------------------------------------------------------------------------*/
  669. HRESULT Deregister( void )
  670. {
  671. HRESULT hr;
  672. SOCKADDR RecvSocketAddress;
  673. MSG_RSIP_DEREGISTER DeregisterReq;
  674. RSIP_RESPONSE_INFO RespInfo;
  675. INTERESTING_MSG((L"==>RSIP Deregister" ));
  676. // Build the request
  677. DeregisterReq.version = RSIP_VERSION;
  678. DeregisterReq.command = RSIP_DEREGISTER_REQUEST;
  679. DeregisterReq.clientid.code = RSIP_CLIENTID_CODE;
  680. DeregisterReq.clientid.len = sizeof(DWORD);
  681. DeregisterReq.clientid.clientid = g_ClientID;
  682. DeregisterReq.msgid.code = RSIP_MESSAGEID_CODE;
  683. DeregisterReq.msgid.len = sizeof(DWORD);
  684. DeregisterReq.msgid.msgid = InterlockedIncrement( &g_MsgID );
  685. hr=ExchangeAndParse( (PCHAR)&DeregisterReq,
  686. sizeof(DeregisterReq),
  687. &RespInfo,
  688. DeregisterReq.msgid.msgid,
  689. FALSE,
  690. &RecvSocketAddress );
  691. if(hr!=DPN_OK){
  692. goto exit;
  693. }
  694. if(RespInfo.msgtype != RSIP_DEREGISTER_RESPONSE){
  695. TRIVIAL_MSG((L"Failing registration, response was message type %d",RespInfo.msgtype));
  696. goto error_exit;
  697. }
  698. TRIVIAL_MSG((L"<==RSIP Deregister Succeeded" ));
  699. exit:
  700. g_ClientID = 0;
  701. return hr;
  702. error_exit:
  703. TRIVIAL_MSG((L"<==RSIP Deregister Failed" ));
  704. hr = DPNERR_GENERIC;
  705. goto exit;
  706. }
  707. /*=============================================================================
  708. AssignPort - assign a port mapping with the rsip server
  709. Description:
  710. Asks for a public realm port that is an alias for the local port on
  711. this local realm node. After this request succeeds, all traffic
  712. directed to the gateway on the public side at the allocated public
  713. port, which the gateway provides and specifies in the response, will
  714. be directed to the specified local port.
  715. This function also adds the lease for the port binding to a list of
  716. leases and will renew the lease before it expires if the binding
  717. hasn't been released by a call to rsipFree first.
  718. Parameters:
  719. WORD port - local port to get a remote port for (big endian)
  720. BOOL ftcp_udp - whether we are assigning a UDP or TCP port
  721. SOCKADDR psaddr - place to return assigned global realm address
  722. PDWORD pBindid - identifier for this binding, used to extend
  723. lease and/or release the binding (OPTIONAL).
  724. Return Values:
  725. DPN_OK - assigned succeeded, psaddr contains public realm address,
  726. *pBindid is the binding identifier.
  727. DPNERR_GENERIC - assignment of a public port could not be made.
  728. -----------------------------------------------------------------------------*/
  729. HRESULT AssignPort( BOOL fTCP_UDP, WORD wPort, SOCKADDR *psaddr, DWORD *pdwBindid )
  730. {
  731. #define psaddr_in ((SOCKADDR_IN *)psaddr)
  732. HRESULT hr;
  733. MSG_RSIP_ASSIGN_PORT AssignReq;
  734. RSIP_RESPONSE_INFO RespInfo;
  735. PRSIP_LEASE_RECORD pLeaseRecord;
  736. SOCKADDR RecvSocketAddress;
  737. Lock();
  738. TRIVIAL_MSG((L"==>RSIP Assign Port %d\n", htons( wPort ) ));
  739. if(g_sRsip == INVALID_SOCKET){
  740. IMPORTANT_MSG((L"rsipAssignPort: g_sRsip is invalid, bailing...\n"));
  741. Unlock();
  742. return DPNERR_GENERIC;
  743. }
  744. if(pLeaseRecord=FindLease( fTCP_UDP, wPort )){
  745. // hey, we've already got a lease for this port, so use it.
  746. pLeaseRecord->dwRefCount++;
  747. if(psaddr_in){
  748. psaddr_in->sin_family = AF_INET;
  749. psaddr_in->sin_addr.s_addr = pLeaseRecord->addrV4;
  750. psaddr_in->sin_port = pLeaseRecord->rport;
  751. }
  752. if(pdwBindid != NULL )
  753. {
  754. *pdwBindid = pLeaseRecord->bindid;
  755. }
  756. TRIVIAL_MSG((L"<==Rsip Assign, already have lease Bindid %d\n", pLeaseRecord->bindid ));
  757. Unlock();
  758. hr=DPN_OK;
  759. goto exit;
  760. }
  761. // Build the request.
  762. AssignReq.version = RSIP_VERSION;
  763. AssignReq.command = RSIP_ASSIGN_REQUEST_RSAP_IP;
  764. AssignReq.clientid.code = RSIP_CLIENTID_CODE;
  765. AssignReq.clientid.len = sizeof(DWORD);
  766. AssignReq.clientid.clientid = g_ClientID;
  767. // Local Address (will be returned by RSIP server, us don't care value)
  768. AssignReq.laddress.code = RSIP_ADDRESS_CODE;
  769. AssignReq.laddress.len = sizeof(RSIP_ADDRESS)-sizeof(RSIP_PARAM);
  770. AssignReq.laddress.version = 1; // IPv4
  771. AssignReq.laddress.addr = 0; // Don't care
  772. // Local Port, this is a port we have opened that we are assigning a
  773. // global alias for.
  774. AssignReq.lport.code = RSIP_PORTS_CODE;
  775. AssignReq.lport.len = sizeof(RSIP_PORT)-sizeof(RSIP_PARAM);
  776. AssignReq.lport.nports = 1;
  777. AssignReq.lport.port = htons( wPort );
  778. // Remote Address (not used with our flow control policy, use don't care value)
  779. AssignReq.raddress.code = RSIP_ADDRESS_CODE;
  780. AssignReq.raddress.len = sizeof(RSIP_ADDRESS)-sizeof(RSIP_PARAM);
  781. AssignReq.raddress.version = 1; // IPv4
  782. AssignReq.raddress.addr = 0; // Don't care
  783. AssignReq.rport.code = RSIP_PORTS_CODE;
  784. AssignReq.rport.len = sizeof(RSIP_PORT)-sizeof(RSIP_PARAM);
  785. AssignReq.rport.nports = 1;
  786. AssignReq.rport.port = 0; // Don't care
  787. // Following parameters are optional according to RSIP spec...
  788. // Lease code, ask for an hour, but don't count on it.
  789. AssignReq.lease.code = RSIP_LEASE_CODE;
  790. AssignReq.lease.len = sizeof(RSIP_LEASE)-sizeof(RSIP_PARAM);
  791. AssignReq.lease.leasetime = 3600;
  792. // Tunnell Type is IP-IP
  793. AssignReq.tunnel.code = RSIP_TUNNELTYPE_CODE;
  794. AssignReq.tunnel.len = sizeof(RSIP_TUNNEL)-sizeof(RSIP_PARAM);
  795. AssignReq.tunnel.tunneltype = TUNNEL_IP_IP;
  796. // Message ID is optional, but we use it since we use UDP xport it is required.
  797. AssignReq.msgid.code = RSIP_MESSAGEID_CODE;
  798. AssignReq.msgid.len = sizeof(DWORD);
  799. AssignReq.msgid.msgid = InterlockedIncrement( &g_MsgID );
  800. // Vendor specific - need to specify port type and no-tunneling
  801. AssignReq.porttype.code = RSIP_VENDOR_CODE;
  802. AssignReq.porttype.len = sizeof(RSIP_MSVENDOR_CODE)-sizeof(RSIP_PARAM);
  803. AssignReq.porttype.vendorid = RSIP_MS_VENDOR_ID;
  804. AssignReq.porttype.option = (fTCP_UDP)?RSIP_TCP_PORT:RSIP_UDP_PORT;
  805. AssignReq.tunneloptions.code = RSIP_VENDOR_CODE;
  806. AssignReq.tunneloptions.len = sizeof(RSIP_MSVENDOR_CODE)-sizeof(RSIP_PARAM);
  807. AssignReq.tunneloptions.vendorid = RSIP_MS_VENDOR_ID;
  808. AssignReq.tunneloptions.option = RSIP_NO_TUNNEL;
  809. hr=ExchangeAndParse( (PCHAR)&AssignReq,
  810. sizeof(AssignReq),
  811. &RespInfo,
  812. AssignReq.msgid.msgid,
  813. FALSE,
  814. &RecvSocketAddress );
  815. Unlock();
  816. if(hr!=DPN_OK){
  817. goto exit;
  818. }
  819. if(RespInfo.msgtype != RSIP_ASSIGN_RESPONSE_RSAP_IP){
  820. IMPORTANT_MSG((L"Assignment failed? Response was %d",RespInfo.msgtype));
  821. goto error_exit;
  822. }
  823. if(psaddr_in){
  824. psaddr_in->sin_family = AF_INET;
  825. psaddr_in->sin_addr.s_addr = RespInfo.lAddressV4;
  826. psaddr_in->sin_port = htons(RespInfo.lPort);
  827. }
  828. if( pdwBindid != NULL )
  829. {
  830. *pdwBindid = RespInfo.bindid;
  831. }
  832. AddLease( RespInfo.bindid,
  833. fTCP_UDP,
  834. RespInfo.lAddressV4,
  835. htons(RespInfo.lPort),
  836. wPort,
  837. RespInfo.leasetime);
  838. if(psaddr_in){
  839. TRIVIAL_MSG((L"RSIP Port Assigned: " ));
  840. DumpSocketAddress( 8, (SOCKADDR*)( psaddr_in ), psaddr_in->sin_family );
  841. TRIVIAL_MSG((L"<== BindId %d, leasetime=%d", RespInfo.bindid, RespInfo.leasetime ));
  842. }
  843. exit:
  844. return hr;
  845. error_exit:
  846. IMPORTANT_MSG((L"<==Assign Port Failed" ));
  847. return DPNERR_GENERIC;
  848. #undef psaddr_in
  849. }
  850. /*=============================================================================
  851. ExtendPort - extend a port mapping
  852. Description:
  853. Extends the lease on a port mapping.
  854. Parameters:
  855. DWORD Bindid - binding identifier specified by the rsip service.
  856. DWORD ptExtend - amount of extra lease time granted.
  857. Return Values:
  858. DPN_OK - lease extended.
  859. DPNERR_GENERIC - couldn't extend the lease.
  860. -----------------------------------------------------------------------------*/
  861. HRESULT ExtendPort( DWORD Bindid, DWORD *ptExtend )
  862. {
  863. HRESULT hr;
  864. MSG_RSIP_EXTEND_PORT ExtendReq;
  865. RSIP_RESPONSE_INFO RespInfo;
  866. SOCKADDR RecvSocketAddress;
  867. Lock();
  868. TRIVIAL_MSG((L"==>Extend Port, Bindid %d\n", Bindid ));
  869. if(g_sRsip == INVALID_SOCKET){
  870. IMPORTANT_MSG((L"rsipExtendPort: g_sRsip is invalid, bailing...\n"));
  871. Unlock();
  872. return DPNERR_GENERIC;
  873. }
  874. // Build the request
  875. ExtendReq.version = RSIP_VERSION;
  876. ExtendReq.command = RSIP_EXTEND_REQUEST;
  877. ExtendReq.clientid.code = RSIP_CLIENTID_CODE;
  878. ExtendReq.clientid.len = sizeof(DWORD);
  879. ExtendReq.clientid.clientid = g_ClientID;
  880. ExtendReq.bindid.code = RSIP_BINDID_CODE;
  881. ExtendReq.bindid.len = sizeof(DWORD);
  882. ExtendReq.bindid.bindid = Bindid;
  883. // Lease code, ask for an hour, but don't count on it.
  884. ExtendReq.lease.code = RSIP_LEASE_CODE;
  885. ExtendReq.lease.len = sizeof(RSIP_LEASE)-sizeof(RSIP_PARAM);
  886. ExtendReq.lease.leasetime = 3600;
  887. ExtendReq.msgid.code = RSIP_MESSAGEID_CODE;
  888. ExtendReq.msgid.len = sizeof(DWORD);
  889. ExtendReq.msgid.msgid = InterlockedIncrement( &g_MsgID );
  890. hr=ExchangeAndParse( (PCHAR)&ExtendReq,
  891. sizeof(ExtendReq),
  892. &RespInfo,
  893. ExtendReq.msgid.msgid,
  894. FALSE,
  895. &RecvSocketAddress );
  896. Unlock();
  897. if(hr!=DPN_OK){
  898. goto exit;
  899. }
  900. if(RespInfo.msgtype != RSIP_EXTEND_RESPONSE){
  901. IMPORTANT_MSG((L"Failing registration, response was message type %d\n",RespInfo.msgtype));
  902. goto error_exit;
  903. }
  904. *ptExtend=RespInfo.leasetime;
  905. TRIVIAL_MSG((L"<==Extend Port, Bindid %d Succeeded, extra lease time %d\n", Bindid, *ptExtend ));
  906. exit:
  907. return hr;
  908. error_exit:
  909. IMPORTANT_MSG((L"<==Extend Port, Failed" ));
  910. return DPNERR_GENERIC;
  911. }
  912. /*=============================================================================
  913. FreePort - release a port binding
  914. Description:
  915. Removes the lease record for our port binding (so we don't renew it
  916. after we actually release the binding from the gateway). Then informs
  917. the gateway that we are done with the binding.
  918. Parameters:
  919. DWORD Bindid - gateway supplied identifier for the binding
  920. Return Values:
  921. DPN_OK - port binding released.
  922. DPNERR_GENERIC - failed.
  923. -----------------------------------------------------------------------------*/
  924. HRESULT FreePort( DWORD dwBindid )
  925. {
  926. HRESULT hr;
  927. MSG_RSIP_FREE_PORT FreeReq;
  928. RSIP_RESPONSE_INFO RespInfo;
  929. SOCKADDR RecvSocketAddress;
  930. Lock();
  931. TRIVIAL_MSG((L"==>Release Port, Bindid %d\n", dwBindid ));
  932. if(g_sRsip == INVALID_SOCKET){
  933. IMPORTANT_MSG((L"rsipFreePort: g_sRsip is invalid, bailing...\n"));
  934. Unlock();
  935. return DPNERR_GENERIC;
  936. }
  937. RemoveLease( dwBindid );
  938. FreeReq.version = RSIP_VERSION;
  939. FreeReq.command = RSIP_FREE_REQUEST;
  940. FreeReq.clientid.code = RSIP_CLIENTID_CODE;
  941. FreeReq.clientid.len = sizeof(DWORD);
  942. FreeReq.clientid.clientid = g_ClientID;
  943. FreeReq.bindid.code = RSIP_BINDID_CODE;
  944. FreeReq.bindid.len = sizeof(DWORD);
  945. FreeReq.bindid.bindid = dwBindid;
  946. FreeReq.msgid.code = RSIP_MESSAGEID_CODE;
  947. FreeReq.msgid.len = sizeof(DWORD);
  948. FreeReq.msgid.msgid = InterlockedIncrement( &g_MsgID );
  949. hr=ExchangeAndParse( (PCHAR)&FreeReq,
  950. sizeof(FreeReq),
  951. &RespInfo,
  952. FreeReq.msgid.msgid,
  953. FALSE,
  954. &RecvSocketAddress );
  955. Unlock();
  956. if(hr!=DPN_OK){
  957. goto exit;
  958. }
  959. if(RespInfo.msgtype != RSIP_FREE_RESPONSE){
  960. IMPORTANT_MSG((L"Failing registration, response was message type %d\n",RespInfo.msgtype));
  961. goto error_exit;
  962. }
  963. exit:
  964. TRIVIAL_MSG((L"<==Release Port, Succeeded" ));
  965. return hr;
  966. error_exit:
  967. IMPORTANT_MSG((L"<==Release Port, Failed" ));
  968. return DPNERR_GENERIC;
  969. }
  970. /*=============================================================================
  971. QueryLocalAddress - get the local address of a public address
  972. Description:
  973. Before connecting to anyone we need to see if there is a local
  974. alias for its global address. This is because the gateway will
  975. not loopback if we try and connect to the global address, so
  976. we need to know the local alias.
  977. Parameters:
  978. BOOL ftcp_udp - whether we are querying a UDP or TCP port
  979. SOCKADDR saddrquery - the address to look up
  980. SOCKADDR saddrlocal - local alias if one exists
  981. Return Values:
  982. DPN_OK - got a local address.
  983. other - no mapping exists.
  984. -----------------------------------------------------------------------------*/
  985. HRESULT QueryLocalAddress( BOOL ftcp_udp, SOCKADDR *saddrquery, SOCKADDR *saddrlocal )
  986. {
  987. #define saddrquery_in ((const SOCKADDR_IN *)saddrquery)
  988. #define saddrlocal_in ((SOCKADDR_IN *)saddrlocal)
  989. HRESULT hr;
  990. MSG_RSIP_QUERY QueryReq;
  991. RSIP_RESPONSE_INFO RespInfo;
  992. PADDR_ENTRY pAddrEntry;
  993. SOCKADDR RecvSocketAddress;
  994. Lock();
  995. TRIVIAL_MSG((L"==>RSIP QueryLocalAddress" ));
  996. DumpSocketAddress( 8, saddrquery, saddrquery->sa_family );
  997. if(g_sRsip == INVALID_SOCKET){
  998. IMPORTANT_MSG((L"rsipQueryLocalAddress: g_sRsip is invalid, bailing...\n"));
  999. Unlock();
  1000. return DPNERR_GENERIC;
  1001. }
  1002. // see if we have a cached entry.
  1003. if(pAddrEntry=FindCacheEntry(ftcp_udp,saddrquery_in->sin_addr.s_addr,saddrquery_in->sin_port)){
  1004. if(pAddrEntry->raddr){
  1005. saddrlocal_in->sin_family = AF_INET;
  1006. saddrlocal_in->sin_addr.s_addr = pAddrEntry->raddr;
  1007. saddrlocal_in->sin_port = pAddrEntry->rport;
  1008. Unlock();
  1009. TRIVIAL_MSG((L"<==Found Local address in cache.\n" ));
  1010. return DPN_OK;
  1011. } else {
  1012. TRIVIAL_MSG((L"<==Found lack of local address in cache\n" ));
  1013. Unlock();
  1014. return DPNERR_GENERIC;
  1015. }
  1016. }
  1017. // Build the request
  1018. QueryReq.version = RSIP_VERSION;
  1019. QueryReq.command = RSIP_QUERY_REQUEST;
  1020. QueryReq.clientid.code = RSIP_CLIENTID_CODE;
  1021. QueryReq.clientid.len = sizeof(DWORD);
  1022. QueryReq.clientid.clientid = g_ClientID;
  1023. QueryReq.address.code = RSIP_ADDRESS_CODE;
  1024. QueryReq.address.len = sizeof(RSIP_ADDRESS)-sizeof(RSIP_PARAM);
  1025. QueryReq.address.version = 1; // IPv4
  1026. QueryReq.address.addr = saddrquery_in->sin_addr.s_addr;
  1027. QueryReq.port.code = RSIP_PORTS_CODE;
  1028. QueryReq.port.len = sizeof(RSIP_PORT)-sizeof(RSIP_PARAM);
  1029. QueryReq.port.nports = 1;
  1030. QueryReq.port.port = htons(saddrquery_in->sin_port);
  1031. QueryReq.porttype.code = RSIP_VENDOR_CODE;
  1032. QueryReq.porttype.len = sizeof(RSIP_MSVENDOR_CODE)-sizeof(RSIP_PARAM);
  1033. QueryReq.porttype.vendorid = RSIP_MS_VENDOR_ID;
  1034. QueryReq.porttype.option = (ftcp_udp)?RSIP_TCP_PORT:RSIP_UDP_PORT;
  1035. QueryReq.querytype.code = RSIP_VENDOR_CODE;
  1036. QueryReq.querytype.len = sizeof(RSIP_MSVENDOR_CODE)-sizeof(RSIP_PARAM);
  1037. QueryReq.querytype.vendorid = RSIP_MS_VENDOR_ID;
  1038. QueryReq.querytype.option = RSIP_QUERY_MAPPING;
  1039. QueryReq.msgid.code = RSIP_MESSAGEID_CODE;
  1040. QueryReq.msgid.len = sizeof(DWORD);
  1041. QueryReq.msgid.msgid = InterlockedIncrement( &g_MsgID );
  1042. hr=ExchangeAndParse( (PCHAR)&QueryReq,
  1043. sizeof(QueryReq),
  1044. &RespInfo,
  1045. QueryReq.msgid.msgid,
  1046. FALSE,
  1047. &RecvSocketAddress );
  1048. Unlock();
  1049. if(hr!=DPN_OK){
  1050. goto exit;
  1051. }
  1052. if(RespInfo.msgtype != RSIP_QUERY_RESPONSE){
  1053. IMPORTANT_MSG((L"Failing query, response was message type %d\n",RespInfo.msgtype));
  1054. goto error_exit;
  1055. }
  1056. saddrlocal_in->sin_family = AF_INET;
  1057. saddrlocal_in->sin_addr.s_addr = RespInfo.lAddressV4;
  1058. saddrlocal_in->sin_port = htons(RespInfo.lPort);
  1059. //rsipAddCacheEntry(pgd,ftcp_udp,saddrquery_in->sin_addr.s_addr,saddrquery_in->sin_port,RespInfo.lAddressV4,p_htons(RespInfo.lPort));
  1060. TRIVIAL_MSG((L"<==RSIP QueryLocalAddress, local alias is" ));
  1061. DumpSocketAddress( 8, (SOCKADDR*)( saddrlocal_in ), saddrlocal_in->sin_family );
  1062. exit:
  1063. return hr;
  1064. error_exit:
  1065. AddCacheEntry(ftcp_udp,saddrquery_in->sin_addr.s_addr,saddrquery_in->sin_port,0,0);
  1066. INTERESTING_MSG((L"<==RSIP QueryLocalAddress, NO Local alias\n" ));
  1067. return DPNERR_GENERIC;
  1068. #undef saddrlocal_in
  1069. #undef saddrquery_in
  1070. }
  1071. /*=============================================================================
  1072. ListenPort - assign a port mapping with the rsip server with a fixed
  1073. port.
  1074. Description:
  1075. Only used for the host server port (the one that is used for enums).
  1076. Other than the fixed port this works the same as an rsipAssignPort.
  1077. Since the port is fixed, the local and public port address are
  1078. obviously the same.
  1079. Parameters:
  1080. WORD port - local port to get a remote port for (big endian)
  1081. BOOL ftcp_udp - whether we are assigning a UDP or TCP port
  1082. SOCKADDR psaddr - place to return assigned global realm address
  1083. PDWORD pBindid - identifier for this binding, used to extend
  1084. lease and/or release the binding (OPTIONAL).
  1085. Return Values:
  1086. DPN_OK - assigned succeeded, psaddr contains public realm address,
  1087. *pBindid is the binding identifier.
  1088. DPNERR_GENERIC - assignment of a public port could not be made.
  1089. -----------------------------------------------------------------------------*/
  1090. HRESULT ListenPort( BOOL ftcp_udp, WORD port, SOCKADDR *psaddr, DWORD *pBindid )
  1091. {
  1092. #define psaddr_in ((SOCKADDR_IN *)psaddr)
  1093. HRESULT hr;
  1094. SOCKADDR RecvSocketAddress;
  1095. MSG_RSIP_LISTEN_PORT ListenReq;
  1096. RSIP_RESPONSE_INFO RespInfo;
  1097. Lock();
  1098. TRIVIAL_MSG((L"RSIP Listen Port %d\n", htons( port ) ));
  1099. if(g_sRsip == INVALID_SOCKET){
  1100. IMPORTANT_MSG((L"rsipListenPort: g_sRsip is invalid, bailing...\n"));
  1101. Unlock();
  1102. return DPNERR_GENERIC;
  1103. }
  1104. // Build the request
  1105. ListenReq.version = RSIP_VERSION;
  1106. ListenReq.command = RSIP_LISTEN_REQUEST;
  1107. ListenReq.clientid.code = RSIP_CLIENTID_CODE;
  1108. ListenReq.clientid.len = sizeof(DWORD);
  1109. ListenReq.clientid.clientid = g_ClientID;
  1110. // Local Address (will be returned by RSIP server, us don't care value)
  1111. ListenReq.laddress.code = RSIP_ADDRESS_CODE;
  1112. ListenReq.laddress.len = sizeof(RSIP_ADDRESS)-sizeof(RSIP_PARAM);
  1113. ListenReq.laddress.version = 1; // IPv4
  1114. ListenReq.laddress.addr = 0; // Don't care
  1115. // Local Port, this is a port we have opened that we are assigning a
  1116. // global alias for.
  1117. ListenReq.lport.code = RSIP_PORTS_CODE;
  1118. ListenReq.lport.len = sizeof(RSIP_PORT)-sizeof(RSIP_PARAM);
  1119. ListenReq.lport.nports = 1;
  1120. ListenReq.lport.port = htons(port);//->little endian for wire
  1121. // Remote Address (not used with our flow control policy, use don't care value)
  1122. ListenReq.raddress.code = RSIP_ADDRESS_CODE;
  1123. ListenReq.raddress.len = sizeof(RSIP_ADDRESS)-sizeof(RSIP_PARAM);
  1124. ListenReq.raddress.version = 1; // IPv4
  1125. ListenReq.raddress.addr = 0; // Don't care
  1126. ListenReq.rport.code = RSIP_PORTS_CODE;
  1127. ListenReq.rport.len = sizeof(RSIP_PORT)-sizeof(RSIP_PARAM);
  1128. ListenReq.rport.nports = 1;
  1129. ListenReq.rport.port = 0; // Don't care
  1130. // Following parameters are optional according to RSIP spec...
  1131. // Lease code, ask for an hour, but don't count on it.
  1132. ListenReq.lease.code = RSIP_LEASE_CODE;
  1133. ListenReq.lease.len = sizeof(RSIP_LEASE)-sizeof(RSIP_PARAM);
  1134. ListenReq.lease.leasetime = 3600;
  1135. // Tunnell Type is IP-IP
  1136. ListenReq.tunnel.code = RSIP_TUNNELTYPE_CODE;
  1137. ListenReq.tunnel.len = sizeof(RSIP_TUNNEL)-sizeof(RSIP_PARAM);
  1138. ListenReq.tunnel.tunneltype = TUNNEL_IP_IP;
  1139. // Message ID is optional, but we use it since we use UDP xport it is required.
  1140. ListenReq.msgid.code = RSIP_MESSAGEID_CODE;
  1141. ListenReq.msgid.len = sizeof(DWORD);
  1142. ListenReq.msgid.msgid = InterlockedIncrement( &g_MsgID );
  1143. // Vendor specific - need to specify port type and no-tunneling
  1144. ListenReq.porttype.code = RSIP_VENDOR_CODE;
  1145. ListenReq.porttype.len = sizeof(RSIP_MSVENDOR_CODE)-sizeof(RSIP_PARAM);
  1146. ListenReq.porttype.vendorid = RSIP_MS_VENDOR_ID;
  1147. ListenReq.porttype.option = (ftcp_udp)?(RSIP_TCP_PORT):(RSIP_UDP_PORT);
  1148. ListenReq.tunneloptions.code = RSIP_VENDOR_CODE;
  1149. ListenReq.tunneloptions.len = sizeof(RSIP_MSVENDOR_CODE)-sizeof(RSIP_PARAM);
  1150. ListenReq.tunneloptions.vendorid = RSIP_MS_VENDOR_ID;
  1151. ListenReq.tunneloptions.option = RSIP_NO_TUNNEL;
  1152. ListenReq.listentype.code = RSIP_VENDOR_CODE;
  1153. ListenReq.listentype.len = sizeof(RSIP_MSVENDOR_CODE)-sizeof(RSIP_PARAM);
  1154. ListenReq.listentype.vendorid = RSIP_MS_VENDOR_ID;
  1155. ListenReq.listentype.option = RSIP_SHARED_UDP_LISTENER;
  1156. hr=ExchangeAndParse( (PCHAR)&ListenReq,
  1157. sizeof(ListenReq),
  1158. &RespInfo,
  1159. ListenReq.msgid.msgid,
  1160. FALSE,
  1161. &RecvSocketAddress );
  1162. Unlock();
  1163. if(hr!=DPN_OK){
  1164. goto exit;
  1165. }
  1166. if(RespInfo.msgtype != RSIP_LISTEN_RESPONSE){
  1167. IMPORTANT_MSG((L"Assignment failed? Response was %d\n",RespInfo.msgtype));
  1168. goto error_exit;
  1169. }
  1170. if(psaddr_in){
  1171. psaddr_in->sin_family = AF_INET;
  1172. psaddr_in->sin_addr.s_addr = RespInfo.lAddressV4;
  1173. psaddr_in->sin_port = htons(RespInfo.lPort);// currently little endian on wire
  1174. TRIVIAL_MSG((L"RSIP Listen, public address is" ));
  1175. DumpSocketAddress( 8, (SOCKADDR*)( psaddr_in ), psaddr_in->sin_family );
  1176. }
  1177. if(pBindid){
  1178. *pBindid = RespInfo.bindid;
  1179. }
  1180. // remember the lease so we will renew it when necessary.
  1181. AddLease(RespInfo.bindid,ftcp_udp,RespInfo.lAddressV4,htons(RespInfo.lPort),port,RespInfo.leasetime);
  1182. exit:
  1183. TRIVIAL_MSG((L"<==RSIP Listen succeeded\n" ));
  1184. return hr;
  1185. error_exit:
  1186. IMPORTANT_MSG((L"<==RSIP Listen failed\n"));
  1187. return DPNERR_GENERIC;
  1188. #undef psaddr_in
  1189. }
  1190. /*=============================================================================
  1191. FindLease - see if we already have a lease for a local port.
  1192. Description:
  1193. Parameters:
  1194. Return Values:
  1195. -----------------------------------------------------------------------------*/
  1196. PRSIP_LEASE_RECORD FindLease( BOOL ftcp_udp, WORD port)
  1197. {
  1198. PRSIP_LEASE_RECORD pLeaseWalker;
  1199. pLeaseWalker = g_pRsipLeaseRecords;
  1200. while(pLeaseWalker){
  1201. if( ( pLeaseWalker->ftcp_udp == ftcp_udp ) && ( pLeaseWalker->port == port ) )
  1202. {
  1203. break;
  1204. }
  1205. pLeaseWalker=pLeaseWalker->pNext;
  1206. }
  1207. return pLeaseWalker;
  1208. }
  1209. /*=============================================================================
  1210. AddLease - adds a lease record to our list of leases
  1211. Description:
  1212. Parameters:
  1213. Return Values:
  1214. -----------------------------------------------------------------------------*/
  1215. void AddLease( DWORD bindid, BOOL ftcp_udp, DWORD addrV4, WORD rport, WORD port, DWORD tLease)
  1216. {
  1217. RSIP_LEASE_RECORD *pLeaseWalker;
  1218. RSIP_LEASE_RECORD *pNewLease;
  1219. DWORD tNow;
  1220. tNow=timeGetTime();
  1221. // First see if we already have a lease for this port;
  1222. Lock();
  1223. // first make sure there isn't already a lease for this port
  1224. pLeaseWalker = g_pRsipLeaseRecords;
  1225. while(pLeaseWalker){
  1226. if(pLeaseWalker->ftcp_udp == ftcp_udp &&
  1227. pLeaseWalker->port == port &&
  1228. pLeaseWalker->bindid == bindid
  1229. )
  1230. {
  1231. break;
  1232. }
  1233. pLeaseWalker=pLeaseWalker->pNext;
  1234. }
  1235. if(pLeaseWalker){
  1236. pLeaseWalker->dwRefCount++;
  1237. pLeaseWalker->tExpiry = tNow+(tLease*1000);
  1238. } else {
  1239. pNewLease = (RSIP_LEASE_RECORD*)( malloc( sizeof( *pNewLease ) ) );
  1240. if(pNewLease){
  1241. pNewLease->dwRefCount = 1;
  1242. pNewLease->ftcp_udp = ftcp_udp;
  1243. pNewLease->tExpiry = tNow+(tLease*1000);
  1244. pNewLease->bindid = bindid;
  1245. pNewLease->port = port;
  1246. pNewLease->rport = rport;
  1247. pNewLease->addrV4 = addrV4;
  1248. pNewLease->pNext = g_pRsipLeaseRecords;
  1249. g_pRsipLeaseRecords= pNewLease;
  1250. } else {
  1251. IMPORTANT_MSG((L"rsip: Couldn't allocate new lease block for port %x\n",port));
  1252. }
  1253. }
  1254. Unlock();
  1255. }
  1256. /*=============================================================================
  1257. RemoveLease - removes a lease record from our list of leases
  1258. Description:
  1259. Parameters:
  1260. Return Values:
  1261. -----------------------------------------------------------------------------*/
  1262. void RemoveLease( DWORD bindid )
  1263. {
  1264. PRSIP_LEASE_RECORD pLeaseWalker, pLeasePrev;
  1265. TRIVIAL_MSG((L"==>rsipRemoveLease bindid %d\n", bindid));
  1266. Lock();
  1267. pLeaseWalker = g_pRsipLeaseRecords;
  1268. pLeasePrev=(PRSIP_LEASE_RECORD)&g_pRsipLeaseRecords; //sneaky.
  1269. while(pLeaseWalker){
  1270. if(pLeaseWalker->bindid==bindid){
  1271. --pLeaseWalker->dwRefCount;
  1272. if(!pLeaseWalker->dwRefCount){
  1273. // link over it
  1274. pLeasePrev->pNext=pLeaseWalker->pNext;
  1275. TRIVIAL_MSG((L"rsipRemove: removing bindid %d\n", bindid ));
  1276. free(pLeaseWalker);
  1277. } else {
  1278. TRIVIAL_MSG((L"Remove: refcount on bindid %d is %d\n", bindid, pLeaseWalker->dwRefCount ));
  1279. }
  1280. break;
  1281. }
  1282. pLeasePrev=pLeaseWalker;
  1283. pLeaseWalker=pLeaseWalker->pNext;
  1284. }
  1285. Unlock();
  1286. TRIVIAL_MSG((L"<==rsipRemoveLease bindid %d\n", bindid ));
  1287. }
  1288. /*=============================================================================
  1289. PortExtend - checks if port leases needs extension and extends
  1290. them if necessary
  1291. Description:
  1292. Parameters:
  1293. Return Values:
  1294. -----------------------------------------------------------------------------*/
  1295. BOOL PortExtend( DWORD time )
  1296. {
  1297. BOOL bRet = TRUE;
  1298. PRSIP_LEASE_RECORD pLeaseWalker;
  1299. DWORD tExtend;
  1300. HRESULT hr;
  1301. Lock();
  1302. pLeaseWalker = g_pRsipLeaseRecords;
  1303. while(pLeaseWalker)
  1304. {
  1305. if((int)(pLeaseWalker->tExpiry - time) < 180000)
  1306. {
  1307. // less than 3 minutes left on lease.
  1308. hr=ExtendPort(pLeaseWalker->bindid, &tExtend);
  1309. if(hr != DPN_OK)
  1310. {
  1311. // this binding is now gone!
  1312. IMPORTANT_MSG((L"Couldn't renew lease on bindid %d, port %x\n",pLeaseWalker->bindid, pLeaseWalker->port));
  1313. bRet = FALSE;
  1314. }
  1315. else
  1316. {
  1317. pLeaseWalker->tExpiry=time+(tExtend*1000);
  1318. TRIVIAL_MSG((L"rsip: Extended Lease of Port %x by %d seconds\n", pLeaseWalker->bindid, tExtend ));
  1319. // assert(tExtend > 180);
  1320. }
  1321. }
  1322. pLeaseWalker=pLeaseWalker->pNext;
  1323. }
  1324. Unlock();
  1325. return bRet;
  1326. }
  1327. /*=============================================================================
  1328. FindCacheEntry
  1329. Description:
  1330. Parameters:
  1331. Return Values:
  1332. -----------------------------------------------------------------------------*/
  1333. PADDR_ENTRY FindCacheEntry( BOOL ftcp_udp, DWORD addr, WORD port)
  1334. {
  1335. PADDR_ENTRY pAddrWalker;
  1336. pAddrWalker = g_pAddrEntry;
  1337. while(pAddrWalker){
  1338. if(pAddrWalker->ftcp_udp == ftcp_udp &&
  1339. pAddrWalker->port == port &&
  1340. pAddrWalker->addr == addr
  1341. )
  1342. {
  1343. // if he looked it up, give it another minute to time out.
  1344. pAddrWalker->tExpiry=timeGetTime()+60*1000;
  1345. // 7/28/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers, addresses, and handles.
  1346. TRIVIAL_MSG((L"Returning Cache Entry Addr:Port (%p:%d) Alias Addr:(Port %p:%d)\n", \
  1347. pAddrWalker->addr, \
  1348. htons(pAddrWalker->port), \
  1349. pAddrWalker->raddr, \
  1350. htons(pAddrWalker->rport)));
  1351. break;
  1352. }
  1353. pAddrWalker=pAddrWalker->pNext;
  1354. }
  1355. return pAddrWalker;
  1356. }
  1357. /*=============================================================================
  1358. AddCacheEntry - adds a cache entry or updates timeout on existing one.
  1359. Description:
  1360. Adds an address mapping from public realm to local realm (or the
  1361. lack of such a mapping) to the cache of mappings.
  1362. Parameters:
  1363. Return Values:
  1364. -----------------------------------------------------------------------------*/
  1365. void AddCacheEntry( BOOL ftcp_udp, DWORD addr, WORD port, DWORD raddr, WORD rport)
  1366. {
  1367. ADDR_ENTRY *pAddrWalker;
  1368. ADDR_ENTRY *pNewAddr;
  1369. DWORD tNow;
  1370. tNow=timeGetTime();
  1371. // First see if we already have a lease for this port;
  1372. Lock();
  1373. // first make sure there isn't already a lease for this port
  1374. pAddrWalker = g_pAddrEntry;
  1375. while(pAddrWalker){
  1376. if(pAddrWalker->ftcp_udp == ftcp_udp &&
  1377. pAddrWalker->port == port &&
  1378. pAddrWalker->addr == addr
  1379. )
  1380. {
  1381. break;
  1382. }
  1383. pAddrWalker=pAddrWalker->pNext;
  1384. }
  1385. if(pAddrWalker){
  1386. pAddrWalker->tExpiry = tNow+(60*1000); // keep for 60 seconds or 60 seconds from last reference
  1387. } else {
  1388. pNewAddr = (ADDR_ENTRY*)( malloc( sizeof( *pNewAddr ) ) );
  1389. if(pNewAddr){
  1390. // 7/28/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers and handles.
  1391. TRIVIAL_MSG((L"Added Cache Entry Addr:Port (%p:%d) Alias Addr:(Port %p:%d)\n", addr, htons( port ), raddr, htons( rport ) ));
  1392. pNewAddr->ftcp_udp = ftcp_udp;
  1393. pNewAddr->tExpiry = tNow+(60*1000);
  1394. pNewAddr->port = port;
  1395. pNewAddr->addr = addr;
  1396. pNewAddr->rport = rport;
  1397. pNewAddr->raddr = raddr;
  1398. pNewAddr->pNext = g_pAddrEntry;
  1399. g_pAddrEntry = pNewAddr;
  1400. } else {
  1401. IMPORTANT_MSG((L"rsip: Couldn't allocate new lease block for port %x\n",port));
  1402. }
  1403. }
  1404. Unlock();
  1405. }
  1406. /*=============================================================================
  1407. CacheClear - checks if cached mappings are old and deletes them.
  1408. Description:
  1409. Parameters:
  1410. Return Values:
  1411. -----------------------------------------------------------------------------*/
  1412. void CacheClear( DWORD time )
  1413. {
  1414. PADDR_ENTRY pAddrWalker, pAddrPrev;
  1415. Lock();
  1416. pAddrWalker = g_pAddrEntry;
  1417. pAddrPrev=(PADDR_ENTRY)&g_pAddrEntry; //sneaky.
  1418. while(pAddrWalker){
  1419. if((int)(pAddrWalker->tExpiry - time) < 0){
  1420. // cache entry expired.
  1421. pAddrPrev->pNext=pAddrWalker->pNext;
  1422. // 7/28/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers and handles.
  1423. TRIVIAL_MSG((L"rsipRemove: removing cached address entry %p\n", pAddrWalker ));
  1424. free(pAddrWalker);
  1425. } else {
  1426. pAddrPrev=pAddrWalker;
  1427. }
  1428. pAddrWalker=pAddrPrev->pNext;
  1429. }
  1430. Unlock();
  1431. }