Leaked source code of windows server 2003
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.

503 lines
13 KiB

  1. /************************************************************************
  2. * *
  3. * INTEL CORPORATION PROPRIETARY INFORMATION *
  4. * *
  5. * This software is supplied under the terms of a license *
  6. * agreement or non-disclosure agreement with Intel Corporation *
  7. * and may not be copied or disclosed except in accordance *
  8. * with the terms of that agreement. *
  9. * *
  10. * Copyright (C) 1997 Intel Corp. All Rights Reserved *
  11. * *
  12. * $Archive: S:\sturgeon\src\gki\vcs\gksocket.cpv $
  13. * *
  14. * $Revision: 1.5 $
  15. * $Date: 28 Feb 1997 15:46:24 $
  16. * *
  17. * $Author: CHULME $
  18. * *
  19. * $Log: S:\sturgeon\src\gki\vcs\gksocket.cpv $
  20. //
  21. // Rev 1.5 28 Feb 1997 15:46:24 CHULME
  22. // Check additional return value on recvfrom for a closed socket
  23. //
  24. // Rev 1.4 17 Jan 1997 09:02:28 CHULME
  25. // Changed reg.h to gkreg.h to avoid name conflict with inc directory
  26. //
  27. // Rev 1.3 10 Jan 1997 16:15:48 CHULME
  28. // Removed MFC dependency
  29. //
  30. // Rev 1.2 18 Dec 1996 14:23:30 CHULME
  31. // Changed discovery to send broadcast and multicast GRQs - debug only disable
  32. //
  33. // Rev 1.1 22 Nov 1996 14:56:04 CHULME
  34. // Added detection of LastError = 0 for treatment on socket close
  35. *************************************************************************/
  36. // gksocket.cpp : Provides the implementation for the CGKSocket class
  37. //
  38. #include <precomp.h>
  39. #define IP_MULTICAST_TTL 3 /* set/get IP multicast timetolive */
  40. #include "dspider.h"
  41. #include "dgkilit.h"
  42. #include "DGKIPROT.H"
  43. #include "GATEKPR.H"
  44. #include "gksocket.h"
  45. #include "GKREG.H"
  46. #include "h225asn.h"
  47. #include "coder.hpp"
  48. #include "dgkiext.h"
  49. #if (defined(_DEBUG) || defined(PCS_COMPLIANCE))
  50. // INTEROP
  51. #include "interop.h"
  52. #include "rasplog.h"
  53. extern LPInteropLogger RasLogger;
  54. #endif
  55. #ifdef _DEBUG
  56. #undef THIS_FILE
  57. static char THIS_FILE[] = __FILE__;
  58. #endif
  59. /////////////////////////////////////////////////////////////////////////////
  60. // CGKSocket construction
  61. CGKSocket::CGKSocket()
  62. {
  63. #ifdef _DEBUG
  64. char szGKDebug[80];
  65. #endif
  66. SPIDER_TRACE(SP_CONDES, "CGKSocket::CGKSocket()\n", 0);
  67. m_hSocket = INVALID_SOCKET;
  68. m_nLastErr = 0;
  69. m_nAddrFam = 0;
  70. m_usPort = 0;
  71. }
  72. /////////////////////////////////////////////////////////////////////////////
  73. // CGKSocket destruction
  74. CGKSocket::~CGKSocket()
  75. {
  76. #ifdef _DEBUG
  77. char szGKDebug[80];
  78. #endif
  79. SPIDER_TRACE(SP_CONDES, "CGKSocket::~CGKSocket()\n", 0);
  80. if (m_hSocket != INVALID_SOCKET)
  81. Close();
  82. }
  83. int
  84. CGKSocket::Create(int nAddrFam, unsigned short usPort)
  85. {
  86. // ABSTRACT: Creates the socket for the supplied address family (transport)
  87. // and binds it to the specified port. This function returns 0
  88. // if successful, else it will return the winsock comm error code.
  89. // AUTHOR: Colin Hulme
  90. int nRet, nLen;
  91. SOCKADDR_IN sAddrIn;
  92. #ifdef _DEBUG
  93. char szGKDebug[80];
  94. #endif
  95. SPIDER_TRACE(SP_FUNC, "CGKSocket::Create(nAddrFam, %X)\n", usPort);
  96. // Create a socket for the supplied address family
  97. SPIDER_TRACE(SP_WSOCK, "socket(%X, SOCK_DGRAM, 0)\n", nAddrFam);
  98. if ((m_hSocket = socket(nAddrFam, SOCK_DGRAM, 0)) == INVALID_SOCKET)
  99. {
  100. m_nLastErr = WSAGetLastError(); // Get winsock error code
  101. SpiderWSErrDecode(m_nLastErr); // Debug print of error decode
  102. return (m_nLastErr);
  103. }
  104. m_nAddrFam = nAddrFam;
  105. // Bind socket to a local address
  106. switch (nAddrFam)
  107. {
  108. case PF_INET:
  109. sAddrIn.sin_family = AF_INET;
  110. break;
  111. case PF_IPX:
  112. sAddrIn.sin_family = AF_IPX;
  113. break;
  114. }
  115. sAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);
  116. sAddrIn.sin_port = htons(usPort);
  117. SPIDER_TRACE(SP_WSOCK, "bind(%X, &sAddrIn, sizeof(sAddrIn))\n", m_hSocket);
  118. nRet = bind(m_hSocket, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn));
  119. if (nRet != 0)
  120. {
  121. m_nLastErr = WSAGetLastError();
  122. SpiderWSErrDecode(m_nLastErr);
  123. Close(); // Close the socket
  124. return (m_nLastErr);
  125. }
  126. // Get dynamic port number - not actually guaranteed til after connect
  127. SPIDER_TRACE(SP_WSOCK, "getsockname(%X, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn))\n", m_hSocket);
  128. nLen = sizeof(sAddrIn);
  129. nRet = getsockname(m_hSocket, (LPSOCKADDR)&sAddrIn, &nLen);
  130. if (nRet == SOCKET_ERROR)
  131. {
  132. m_nLastErr = WSAGetLastError();
  133. SpiderWSErrDecode(m_nLastErr);
  134. Close(); // Close the socket
  135. return (SOCKET_ERROR);
  136. }
  137. SPIDER_DEBUG(sAddrIn.sin_port);
  138. m_usPort = ntohs(sAddrIn.sin_port);
  139. return (0);
  140. }
  141. int
  142. CGKSocket::Connect(PSOCKADDR_IN pAddr)
  143. {
  144. // ABSTRACT: This simulates a connect. It simply stores the relevant
  145. // information in a member variable that will be used by the
  146. // Send and Receive member functions.
  147. // AUTHOR: Colin Hulme
  148. m_sAddrIn = *pAddr;
  149. m_sAddrIn.sin_family = AF_INET;
  150. m_sAddrIn.sin_port = htons(GKIP_RAS_PORT);
  151. return (0);
  152. }
  153. int
  154. CGKSocket::Send(char *pBuffer, int nLen)
  155. {
  156. // ABSTRACT: This function will send a datagram on the connected socket.
  157. // AUTHOR: Colin Hulme
  158. int nRet;
  159. #ifdef _DEBUG
  160. char szGKDebug[80];
  161. #endif
  162. SPIDER_TRACE(SP_FUNC, "CGKSocket::Send(pBuffer, %X)\n", nLen);
  163. SPIDER_TRACE(SP_WSOCK, "sendto(%X, pBuffer, nLen, 0, &m_sAddrIn, sizeof(m_sAddrIn))\n", m_hSocket);
  164. #ifdef _DEBUG
  165. //INTEROP
  166. if (dwGKIDLLFlags & SP_LOGGER)
  167. InteropOutput((LPInteropLogger)RasLogger,
  168. (BYTE FAR *)pBuffer,
  169. nLen,
  170. RASLOG_SENT_PDU);
  171. #endif
  172. #ifdef PCS_COMPLIANCE
  173. //INTEROP
  174. InteropOutput((LPInteropLogger)RasLogger,
  175. (BYTE FAR *)pBuffer,
  176. nLen,
  177. RASLOG_SENT_PDU);
  178. #endif
  179. nRet = sendto(m_hSocket, pBuffer, nLen, 0, (LPSOCKADDR)&m_sAddrIn, sizeof(m_sAddrIn));
  180. SPIDER_DEBUG(nRet);
  181. if (nRet == SOCKET_ERROR)
  182. {
  183. m_nLastErr = WSAGetLastError();
  184. SpiderWSErrDecode(m_nLastErr);
  185. Close(); // Close the socket
  186. return (SOCKET_ERROR);
  187. }
  188. return (nRet);
  189. }
  190. int
  191. CGKSocket::SendTo(char *pBuffer, int nLen, const struct sockaddr FAR * to, int tolen)
  192. {
  193. // ABSTRACT: This function will send a datagram on the connected socket.
  194. // AUTHOR: Colin Hulme
  195. int nRet;
  196. #ifdef _DEBUG
  197. char szGKDebug[80];
  198. #endif
  199. SPIDER_TRACE(SP_FUNC, "CGKSocket::SendTo(pBuffer, %X, to, tolen)\n", nLen);
  200. SPIDER_TRACE(SP_WSOCK, "sendto(%X, pBuffer, nLen, 0, to, tolen)\n", m_hSocket);
  201. #ifdef _DEBUG
  202. //INTEROP
  203. if (dwGKIDLLFlags & SP_LOGGER)
  204. InteropOutput((LPInteropLogger)RasLogger,
  205. (BYTE FAR *)pBuffer,
  206. nLen,
  207. RASLOG_SENT_PDU);
  208. #endif
  209. #ifdef PCS_COMPLIANCE
  210. //INTEROP
  211. InteropOutput((LPInteropLogger)RasLogger,
  212. (BYTE FAR *)pBuffer,
  213. nLen,
  214. RASLOG_SENT_PDU);
  215. #endif
  216. nRet = sendto(m_hSocket, pBuffer, nLen, 0, to, tolen);
  217. SPIDER_DEBUG(nRet);
  218. if (nRet == SOCKET_ERROR)
  219. {
  220. m_nLastErr = WSAGetLastError();
  221. SpiderWSErrDecode(m_nLastErr);
  222. Close(); // Close the socket
  223. return (SOCKET_ERROR);
  224. }
  225. return (nRet);
  226. }
  227. int
  228. CGKSocket::Receive(char *pBuffer, int nLen)
  229. {
  230. // ABSTRACT: This function will post a receive for an incoming datagram.
  231. // AUTHOR: Colin Hulme
  232. int nRet;
  233. #ifdef _DEBUG
  234. char szGKDebug[80];
  235. #endif
  236. SPIDER_TRACE(SP_FUNC, "CGKSocket::Receive(pBuffer, %X)\n", nLen);
  237. SPIDER_TRACE(SP_WSOCK, "recvfrom(%X, pBuffer, nLen, 0, 0, 0)\n", m_hSocket);
  238. nRet = recvfrom(m_hSocket, pBuffer, nLen, 0, 0, 0);
  239. SPIDER_DEBUG(nRet);
  240. if (nRet == SOCKET_ERROR)
  241. {
  242. m_nLastErr = WSAGetLastError();
  243. if ((m_nLastErr == 2) || (m_nLastErr == 0) || (m_nLastErr == WSAEINVAL)) // Weird return values seen
  244. m_nLastErr = WSAEINTR; // occasionally when socket closed
  245. SpiderWSErrDecode(m_nLastErr);
  246. if (m_nLastErr != WSAEINTR)
  247. Close(); // Close the socket
  248. return (SOCKET_ERROR);
  249. }
  250. #ifdef _DEBUG
  251. //INTEROP
  252. if (dwGKIDLLFlags & SP_LOGGER)
  253. InteropOutput((LPInteropLogger)RasLogger,
  254. (BYTE FAR *)pBuffer,
  255. nLen,
  256. RASLOG_RECEIVED_PDU);
  257. #endif
  258. #ifdef PCS_COMPLIANCE
  259. //INTEROP
  260. InteropOutput((LPInteropLogger)RasLogger,
  261. (BYTE FAR *)pBuffer,
  262. nLen,
  263. RASLOG_RECEIVED_PDU);
  264. #endif
  265. return (nRet);
  266. }
  267. int
  268. CGKSocket::SendBroadcast(char *pBuffer, int nLen)
  269. {
  270. // ABSTRACT: This function will send a datagram to the broadcast address
  271. // and to the multicast address. In the case of a debug build,
  272. // a registry setting can be used to disable the multicast
  273. // transmission. Both transmissions will always occur in the
  274. // release build.
  275. // AUTHOR: Colin Hulme
  276. int nRet, nValue;
  277. struct sockaddr_in sAddrIn;
  278. #ifdef _DEBUG
  279. char szGKDebug[80];
  280. #endif
  281. SPIDER_TRACE(SP_FUNC, "CGKSocket::SendBroadcast(pBuffer, %X)\n", nLen);
  282. ASSERT(g_pGatekeeper);
  283. if(g_pGatekeeper == NULL)
  284. return SOCKET_ERROR;
  285. // Setup family and port information
  286. switch (m_nAddrFam)
  287. {
  288. case PF_INET:
  289. sAddrIn.sin_family = AF_INET;
  290. sAddrIn.sin_port = htons(GKIP_DISC_PORT);
  291. break;
  292. case PF_IPX:
  293. sAddrIn.sin_family = AF_IPX;
  294. sAddrIn.sin_port = htons(GKIPX_DISC_PORT);
  295. break;
  296. }
  297. // ================= SEND BROADCAST ===================
  298. //if ((nValue = (int)Gatekeeper.GetMCastTTL()) == 0)
  299. // Set socket options to allow broadcasting on this socket
  300. nValue = 1; // TRUE - for setting BOOLEAN
  301. SPIDER_TRACE(SP_WSOCK, "setsockopt(%X, SOL_SOCKET, SO_BROADCAST, &nValue, sizeof(nValue))\n", m_hSocket);
  302. nRet = setsockopt(m_hSocket, SOL_SOCKET, SO_BROADCAST, (const char *)&nValue, sizeof(nValue));
  303. // TBD - Don't know if SOL_SOCKET is going to work for other transports
  304. if (nRet == SOCKET_ERROR)
  305. {
  306. m_nLastErr = WSAGetLastError();
  307. SpiderWSErrDecode(m_nLastErr);
  308. Close(); // Close the socket
  309. return (SOCKET_ERROR);
  310. }
  311. sAddrIn.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  312. SPIDER_TRACE(SP_WSOCK, "sendto(%X, pBuffer, nLen, 0, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn))\n", m_hSocket);
  313. #ifdef _DEBUG
  314. //INTEROP
  315. if (dwGKIDLLFlags & SP_LOGGER)
  316. InteropOutput((LPInteropLogger)RasLogger,
  317. (BYTE FAR *)pBuffer,
  318. nLen,
  319. RASLOG_SENT_PDU);
  320. #endif
  321. #ifdef PCS_COMPLIANCE
  322. //INTEROP
  323. InteropOutput((LPInteropLogger)RasLogger,
  324. (BYTE FAR *)pBuffer,
  325. nLen,
  326. RASLOG_SENT_PDU);
  327. #endif
  328. nRet = sendto(m_hSocket, pBuffer, nLen, 0, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn));
  329. SPIDER_DEBUG(nRet);
  330. if (nRet == SOCKET_ERROR)
  331. {
  332. m_nLastErr = WSAGetLastError();
  333. SpiderWSErrDecode(m_nLastErr);
  334. Close(); // Close the socket
  335. return (SOCKET_ERROR);
  336. }
  337. #ifdef _DEBUG
  338. if ((nValue = (int)g_pGatekeeper->GetMCastTTL()) != 0)
  339. { // debug only conditional for avoiding sending multicast
  340. #endif
  341. // ================= SEND MULTICAST ===================
  342. // Set socket options for multicast time to live
  343. nValue = 16; //FMN
  344. SPIDER_TRACE(SP_WSOCK, "setsockopt(%X, IPPROTO_IP, IP_MULTICAST_TTL, &nValue, sizeof(nValue))\n", m_hSocket);
  345. nRet = setsockopt(m_hSocket, IPPROTO_IP, IP_MULTICAST_TTL,
  346. (const char *)&nValue, sizeof(nValue));
  347. // TBD - IP specific - handle IPX case with broadcast?
  348. if (nRet == SOCKET_ERROR)
  349. {
  350. m_nLastErr = WSAGetLastError();
  351. SpiderWSErrDecode(m_nLastErr);
  352. Close(); // Close the socket
  353. return (SOCKET_ERROR);
  354. }
  355. sAddrIn.sin_addr.s_addr = inet_addr(GKIP_DISC_MCADDR);
  356. SPIDER_TRACE(SP_WSOCK, "sendto(%X, pBuffer, nLen, 0, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn))\n", m_hSocket);
  357. #ifdef _DEBUG
  358. //INTEROP
  359. if (dwGKIDLLFlags & SP_LOGGER)
  360. InteropOutput((LPInteropLogger)RasLogger,
  361. (BYTE FAR *)pBuffer,
  362. nLen,
  363. RASLOG_SENT_PDU);
  364. #endif
  365. #ifdef PCS_COMPLIANCE
  366. //INTEROP
  367. InteropOutput((LPInteropLogger)RasLogger,
  368. (BYTE FAR *)pBuffer,
  369. nLen,
  370. RASLOG_SENT_PDU);
  371. #endif
  372. nRet = sendto(m_hSocket, pBuffer, nLen, 0, (LPSOCKADDR)&sAddrIn, sizeof(sAddrIn));
  373. SPIDER_DEBUG(nRet);
  374. if (nRet == SOCKET_ERROR)
  375. {
  376. m_nLastErr = WSAGetLastError();
  377. SpiderWSErrDecode(m_nLastErr);
  378. Close(); // Close the socket
  379. return (SOCKET_ERROR);
  380. }
  381. #ifdef _DEBUG
  382. } // End debug only conditional for avoiding sending multicast
  383. #endif
  384. return (nRet);
  385. }
  386. int
  387. CGKSocket::ReceiveFrom(char *pBuffer, int nLen)
  388. {
  389. // ABSTRACT: This function will post a receivefrom looking for a GCF or GRJ
  390. // AUTHOR: Colin Hulme
  391. int nRet;
  392. #ifdef _DEBUG
  393. char szGKDebug[80];
  394. #endif
  395. SPIDER_TRACE(SP_FUNC, "CGKSocket::ReceiveFrom(pBuffer, %X)\n", nLen);
  396. SPIDER_TRACE(SP_WSOCK, "recvfrom(%X, pBuffer, nLen, 0, 0, 0)\n", m_hSocket);
  397. nRet = recvfrom(m_hSocket, pBuffer, nLen, 0, 0, 0);
  398. SPIDER_DEBUG(nRet);
  399. if (nRet == SOCKET_ERROR)
  400. {
  401. m_nLastErr = WSAGetLastError();
  402. if ((m_nLastErr == 2) || (m_nLastErr == 0)) // Weird return values seen
  403. m_nLastErr = WSAEINTR; // occasionally when socket closed
  404. SpiderWSErrDecode(m_nLastErr);
  405. if (m_nLastErr != WSAEINTR)
  406. Close(); // Close the socket
  407. return (SOCKET_ERROR);
  408. }
  409. #ifdef _DEBUG
  410. //INTEROP
  411. if (dwGKIDLLFlags & SP_LOGGER)
  412. InteropOutput((LPInteropLogger)RasLogger,
  413. (BYTE FAR *)pBuffer,
  414. nLen,
  415. RASLOG_RECEIVED_PDU);
  416. #endif
  417. #ifdef PCS_COMPLIANCE
  418. //INTEROP
  419. InteropOutput((LPInteropLogger)RasLogger,
  420. (BYTE FAR *)pBuffer,
  421. nLen,
  422. RASLOG_RECEIVED_PDU);
  423. #endif
  424. return (nRet);
  425. }
  426. int
  427. CGKSocket::Close(void)
  428. {
  429. // ABSTRACT: This function will close the socket
  430. // AUTHOR: Colin Hulme
  431. int nRet;
  432. #ifdef _DEBUG
  433. char szGKDebug[80];
  434. #endif
  435. SPIDER_TRACE(SP_FUNC, "CGKSocket::Close()\n", 0);
  436. // Close the socket
  437. SPIDER_TRACE(SP_WSOCK, "closesocket(%X)\n", m_hSocket);
  438. nRet = closesocket(m_hSocket);
  439. m_hSocket = INVALID_SOCKET;
  440. return (0);
  441. }