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.

747 lines
16 KiB

  1. /*++
  2. Copyright (c) 1995-1997 Microsoft Corporation
  3. Module Name:
  4. icsocket.hxx
  5. Abstract:
  6. Contains types, manifests, prototypes for Internet Socket Class (ICSocket)
  7. functions and methods (in common\icsocket.cxx)
  8. Author:
  9. Richard L Firth (rfirth) 24-May-1995
  10. Revision History:
  11. 24-May-1995 rfirth
  12. Created
  13. 20-March-1996 arthurbi
  14. Created the CSOCKET class.
  15. 08-Apr-1997 rfirth
  16. Changed to ICSocket class (Internet CSocket to avoid issues with MFC).
  17. Base socket implementation. Secure sockets is a derived class in
  18. ssocket.hxx/.cxx
  19. --*/
  20. //
  21. // manifests
  22. //
  23. #define HOST_INADDR_ANY 0x00000000
  24. #define HOST_INADDR_NONE 0xffffffff
  25. #define HOST_INADDR_LOOPBACK 0x0100007f
  26. //
  27. // common flags for ConnectSocket(), SocketSend(), SocketReceive(),
  28. // SocketDataAvailable()
  29. //
  30. #define SF_ENCRYPT 0x00000001 // encrypt data (send)
  31. #define SF_DECRYPT 0x00000002 // decrypt data (receive)
  32. #define SF_EXPAND 0x00000004 // input buffer can be expanded to fit (receive)
  33. #define SF_COMPRESS 0x00000008 // input buffer can be compressed to fit (receive)
  34. #define SF_RECEIVE_ALL 0x00000010 // loop until buffer full/all data received (receive)
  35. #define SF_INDICATE 0x00000020 // provide status callbacks
  36. #define SF_NON_BLOCKING 0x00000040 // socket is non-blocking
  37. #define SF_WAIT 0x00000080 // wait for data if non-blocking
  38. #define SF_IGNORE_CONNRESET 0x00000100 // SPX_SUPPORT
  39. #define SF_SENDING_DATA 0x00000200 // data is being sent through the socket, errors may now apply.
  40. #define SF_SCH_REDO 0x00000400 // schannel is redone.
  41. #define SF_CONNECTIONLESS 0x00000800 // send/receive datagrams
  42. #define SF_EXPEDITED 0x00001000 // function expected to complete quickly (test with select())
  43. #define SF_AUTHORIZED 0x00002000 // set if we added an authorization header
  44. #define SF_RANDOM 0x00004000 // set if we connect to address list entry chosen at random
  45. #define SF_FORCE 0x00008000 // set if the name must be resolved (ResolveHost)
  46. #define SF_SECURE 0x00010000 // set if this is a secure (SSL/PCT) socket object
  47. #define SF_NO_WAIT 0x00020000 // set if one-shot operation required (Receive)
  48. #define SF_KEEP_ALIVE 0x00040000 // set if connection is keep-alive
  49. #define SF_GLOBAL_KA_POOL 0x00080000 // set if connection is in the global keep-alive pool
  50. #define SF_PERUSER 0x00100000 // set if authorization header is added so response marked per-user in shared cache
  51. #define SF_AUTHENTICATED 0x00200000 // set if authentication was successful on this socket.
  52. #define SF_TUNNEL 0x00400000 // set if this connection is a nested CONNECT directly to a proxy
  53. #define SF_OVERLAPPED 0x00800000 // set if overlapped socket
  54. //
  55. // types
  56. //
  57. //
  58. // SOCKET_BUFFER_ID - which socket buffer we are dealing with
  59. //
  60. typedef enum {
  61. ReceiveBuffer = SO_RCVBUF,
  62. SendBuffer = SO_SNDBUF
  63. } SOCKET_BUFFER_ID;
  64. //
  65. // timeout types for SetSocketTimeout
  66. //
  67. #define SEND_TIMEOUT 1
  68. #define RECEIVE_TIMEOUT 0
  69. //
  70. // macros
  71. //
  72. #define IS_VALID_NON_LOOPBACK_IP_ADDRESS(address) \
  73. (((address) != HOST_INADDR_ANY) \
  74. && ((address) != HOST_INADDR_NONE) \
  75. && ((address) != HOST_INADDR_LOOPBACK))
  76. //
  77. // prototypes
  78. //
  79. LPSTR
  80. MapNetAddressToName(
  81. IN INTERNET_HANDLE_OBJECT* pSessionObject,
  82. IN LPSOCKADDR lpSockAddr
  83. );
  84. //DWORD
  85. //GetServiceAddress(
  86. // IN LPSTR HostName,
  87. // IN DWORD Port,
  88. // OUT LPADDRESS_INFO_LIST AddressList
  89. // );
  90. //
  91. //BOOL
  92. //IsNetAddress(
  93. // IN LPSTR lpszAddress
  94. // );
  95. //
  96. //#if INET_DEBUG
  97. //
  98. //DEBUG_FUNCTION
  99. //VOID
  100. //InitializeAddressList(
  101. // IN LPADDRESS_INFO_LIST AddressList
  102. // );
  103. //
  104. //DEBUG_FUNCTION
  105. //VOID
  106. //FreeAddressList(
  107. // IN LPADDRESS_INFO_LIST AddressList
  108. // );
  109. //
  110. //DEBUG_FUNCTION
  111. //BOOL
  112. //IsAddressListEmpty(
  113. // IN LPADDRESS_INFO_LIST AddressList
  114. // );
  115. //
  116. //#else
  117. //
  118. //#define InitializeAddressList(AddressList) \
  119. // (AddressList)->AddressCount = 0; \
  120. // (AddressList)->Addresses = NULL
  121. //
  122. //#define FreeAddressList(AddressList) \
  123. // if ((AddressList)->AddressCount != 0) { \
  124. // (AddressList)->Addresses = (LPCSADDR_INFO)FREE_MEMORY((HLOCAL)((AddressList)->Addresses)); \
  125. // (AddressList)->AddressCount = 0; \
  126. // }
  127. //
  128. //#define IsAddressListEmpty(AddressList) \
  129. // (((AddressList)->AddressCount == 0) ? TRUE : FALSE)
  130. //
  131. //#endif // INET_DEBUG
  132. //
  133. //DWORD
  134. //DestinationAddressFromAddressList(
  135. // IN LPADDRESS_INFO_LIST lpAddressList,
  136. // IN DWORD dwIndex,
  137. // OUT LPBYTE lpbDestinationAddress,
  138. // IN OUT LPDWORD lpdwDestinationAddressLength
  139. // );
  140. //
  141. //DWORD
  142. //InterfaceAddressFromSocket(
  143. // IN SOCKET Socket,
  144. // OUT LPBYTE lpbInterfaceAddress,
  145. // IN OUT LPDWORD lpdwInterfaceAddressLength
  146. // );
  147. //
  148. // classes
  149. //
  150. //
  151. // forward references
  152. //
  153. class CFsm_SocketConnect;
  154. class CFsm_SocketSend;
  155. class CFsm_SocketReceive;
  156. class CServerInfo;
  157. //
  158. // ICSocket - abstracts a TCP/IP connection
  159. //
  160. class ICSocket {
  161. protected:
  162. LIST_ENTRY m_List; // keep-alive list
  163. DWORD m_dwTimeout; // keep-alive expiry
  164. BOOL m_fTimeoutWraps;
  165. LONG m_ReferenceCount;
  166. SOCKET m_Socket;
  167. DWORD m_dwFlags;
  168. INTERNET_PORT m_Port; // needed for keep-alive
  169. INTERNET_PORT m_SourcePort;
  170. BOOL m_bAborted;
  171. DWORD m_SocksAddress;
  172. INTERNET_PORT m_SocksPort;
  173. //HINTERNET m_hRequest;
  174. CFsm* _pCurrentFsm;
  175. CWrapOverlapped* _lpWrapOverlappedSend;
  176. CWrapOverlapped* _lpWrapOverlappedRecv;
  177. BOOL m_fIsSecureSocket;
  178. #if INET_DEBUG
  179. #define ICSOCKET_SIGNATURE 0x6b636f53 // "Sock"
  180. DWORD m_Signature;
  181. #define SIGN_ICSOCKET() \
  182. m_Signature = ICSOCKET_SIGNATURE
  183. #define CHECK_ICSOCKET() \
  184. INET_ASSERT((m_Signature == ICSOCKET_SIGNATURE) || (m_Signature == SECURE_SOCKET_SIGNATURE))
  185. #else
  186. #define SIGN_ICSOCKET() \
  187. /* NOTHING */
  188. #define CHECK_ICSOCKET() \
  189. /* NOTHING */
  190. #endif
  191. public:
  192. ICSocket();
  193. virtual ~ICSocket();
  194. VOID
  195. Destroy(
  196. VOID
  197. );
  198. PLIST_ENTRY List(VOID) {
  199. return &m_List;
  200. }
  201. PLIST_ENTRY Next(VOID) {
  202. return m_List.Flink;
  203. }
  204. BOOL IsOnList(VOID) {
  205. return ((m_List.Flink == NULL) && (m_List.Blink == NULL)) ? FALSE : TRUE;
  206. }
  207. CFsm* GetAndSetCurrentFsm(CFsm* pCurrent)
  208. {
  209. /*
  210. CFsm* pTemp = _pCurrentFsm;
  211. _pCurrentFsm = pCurrent;
  212. return pTemp;
  213. */
  214. // ICSocket race possible?
  215. return (CFsm *)InterlockedExchangePointer((PVOID*)&_pCurrentFsm, (PVOID)pCurrent);
  216. }
  217. VOID
  218. Reference(
  219. VOID
  220. );
  221. BOOL
  222. Dereference(
  223. VOID
  224. );
  225. LONG ReferenceCount(VOID) const {
  226. return m_ReferenceCount;
  227. }
  228. BOOL IsValid(VOID) {
  229. return (m_Socket != INVALID_SOCKET) ? TRUE : FALSE;
  230. }
  231. BOOL IsInvalid(VOID) {
  232. return !IsValid();
  233. }
  234. BOOL IsOpen(VOID) {
  235. return IsValid();
  236. }
  237. BOOL IsClosed(VOID) {
  238. return !IsOpen();
  239. }
  240. SOCKET GetSocket(VOID) const {
  241. return m_Socket;
  242. }
  243. VOID SetSocket(SOCKET Socket) {
  244. m_Socket = Socket;
  245. }
  246. BOOL IsSecureSocket(VOID) const {
  247. return m_fIsSecureSocket;
  248. }
  249. BOOL IsNonBlocking(VOID) {
  250. return (m_dwFlags & SF_NON_BLOCKING) ? TRUE : FALSE;
  251. }
  252. BOOL IsSecure(VOID) const {
  253. return (m_dwFlags & SF_SECURE) ? TRUE : FALSE;
  254. }
  255. VOID SetEncryption(VOID) {
  256. m_dwFlags |= SF_ENCRYPT | SF_DECRYPT;
  257. }
  258. VOID ResetEncryption(VOID) {
  259. m_dwFlags &= ~(SF_ENCRYPT | SF_DECRYPT);
  260. }
  261. DWORD GetFlags(VOID) const {
  262. return m_dwFlags;
  263. }
  264. VOID SetAuthorized(VOID) {
  265. m_dwFlags |= SF_AUTHORIZED;
  266. }
  267. BOOL IsAuthorized(VOID) {
  268. return (m_dwFlags & SF_AUTHORIZED) ? TRUE : FALSE;
  269. }
  270. VOID SetAuthenticated(VOID) {
  271. m_dwFlags |= SF_AUTHENTICATED;
  272. }
  273. BOOL IsAuthenticated(VOID) {
  274. return (m_dwFlags & SF_AUTHENTICATED) ? TRUE : FALSE;
  275. }
  276. VOID SetPerUser (VOID) {
  277. m_dwFlags |= SF_PERUSER;
  278. }
  279. BOOL IsPerUser(VOID) {
  280. return (m_dwFlags & SF_PERUSER) ? TRUE : FALSE;
  281. }
  282. VOID SetKeepAlive(VOID) {
  283. m_dwFlags |= SF_KEEP_ALIVE;
  284. }
  285. VOID ResetKeepAlive(VOID) {
  286. m_dwFlags &= ~SF_KEEP_ALIVE;
  287. }
  288. BOOL IsKeepAlive(VOID) {
  289. return (m_dwFlags & SF_KEEP_ALIVE) ? TRUE : FALSE;
  290. }
  291. VOID SetInGlobalKeepAlivePool(VOID) {
  292. m_dwFlags |= SF_GLOBAL_KA_POOL;
  293. }
  294. VOID ResetInGlobalKeepAlivePool(VOID) {
  295. m_dwFlags &= ~SF_GLOBAL_KA_POOL;
  296. }
  297. BOOL IsInGlobalKeepAlivePool(VOID) const {
  298. return (m_dwFlags & SF_GLOBAL_KA_POOL) ? TRUE : FALSE;
  299. }
  300. // check if desired flags are a subset of the socket flags
  301. BOOL Match(DWORD dwFlags) {
  302. return ((m_dwFlags & dwFlags) == dwFlags) ? TRUE : FALSE;
  303. }
  304. virtual BOOL MatchSecureProtocolSemantics(
  305. DWORD dwFlags,
  306. LPSTR pszHostName = NULL,
  307. DWORD dwSecureProtocols = 0,
  308. DWORD dwSecureFlags = 0) {
  309. UNREFERENCED_PARAMETER(pszHostName);
  310. UNREFERENCED_PARAMETER(dwSecureProtocols);
  311. UNREFERENCED_PARAMETER(dwSecureFlags);
  312. return (dwFlags & (SF_TUNNEL | SF_SECURE)) ? FALSE : TRUE;
  313. }
  314. VOID SetPort(INTERNET_PORT Port) {
  315. m_Port = Port;
  316. }
  317. INTERNET_PORT GetPort(VOID) const {
  318. return m_Port;
  319. }
  320. VOID SetSourcePort(VOID);
  321. VOID SetSourcePort(INTERNET_PORT Port) {
  322. m_SourcePort = Port;
  323. }
  324. INTERNET_PORT GetSourcePort(VOID) const {
  325. return m_SourcePort;
  326. }
  327. VOID SetAborted(VOID) {
  328. m_bAborted = TRUE;
  329. }
  330. BOOL IsAborted(VOID) const {
  331. return m_bAborted;
  332. }
  333. DWORD
  334. GetServiceAddress(
  335. IN LPSTR HostName,
  336. IN DWORD Port
  337. );
  338. DWORD
  339. Connect(
  340. IN LONG ConnectTimeout,
  341. IN INT Retries,
  342. IN DWORD dwFlags
  343. );
  344. virtual
  345. DWORD
  346. Connect(
  347. IN LONG ConnectTimeout,
  348. IN INT Retries,
  349. IN LONG, // SendTimeout
  350. IN LONG, // RecvTimeout
  351. IN DWORD dwFlags
  352. )
  353. {
  354. return Connect(ConnectTimeout, Retries, dwFlags);
  355. }
  356. DWORD
  357. SocketConnect(
  358. IN LONG Timeout,
  359. IN INT Retries,
  360. IN DWORD dwFlags,
  361. IN CServerInfo *pServerInfo
  362. );
  363. DWORD
  364. Connect_Start(
  365. IN CFsm_SocketConnect * Fsm
  366. );
  367. DWORD
  368. Connect_Continue(
  369. IN CFsm_SocketConnect * Fsm
  370. );
  371. DWORD
  372. Connect_Error(
  373. IN CFsm_SocketConnect * Fsm
  374. );
  375. DWORD
  376. Connect_Finish(
  377. IN CFsm_SocketConnect * Fsm
  378. );
  379. int
  380. SocksConnect(
  381. IN LPSOCKADDR_IN pSockaddr,
  382. IN INT nLen
  383. );
  384. virtual
  385. DWORD
  386. Disconnect(
  387. IN DWORD dwFlags = 0
  388. );
  389. DWORD
  390. Close(
  391. VOID
  392. );
  393. DWORD
  394. Abort(
  395. VOID
  396. );
  397. DWORD
  398. Shutdown(
  399. IN DWORD dwControl
  400. );
  401. BOOL
  402. IsReset(
  403. VOID
  404. );
  405. virtual
  406. DWORD
  407. Send(
  408. IN LPVOID lpBuffer,
  409. IN DWORD dwBufferLength,
  410. IN DWORD dwFlags
  411. );
  412. DWORD
  413. Send_Start(
  414. IN CFsm_SocketSend * Fsm
  415. );
  416. virtual
  417. DWORD
  418. Receive(
  419. IN OUT LPVOID* lplpBuffer,
  420. IN OUT LPDWORD lpdwBufferLength,
  421. IN OUT LPDWORD lpdwBufferRemaining,
  422. IN OUT LPDWORD lpdwBytesReceived,
  423. IN DWORD dwExtraSpace,
  424. IN DWORD dwFlags,
  425. OUT LPBOOL lpbEof
  426. );
  427. DWORD
  428. Receive_Start(
  429. IN CFsm_SocketReceive * Fsm
  430. );
  431. DWORD
  432. Receive_Continue(
  433. IN CFsm_SocketReceive * Fsm
  434. );
  435. DWORD
  436. Receive_Finish(
  437. IN CFsm_SocketReceive * Fsm
  438. );
  439. DWORD
  440. SetTimeout(
  441. IN DWORD Type,
  442. IN int Timeout
  443. );
  444. DWORD
  445. SetLinger(
  446. IN BOOL Linger,
  447. IN int Timeout
  448. );
  449. DWORD
  450. SetNonBlockingMode(
  451. IN BOOL bNonBlocking
  452. );
  453. DWORD
  454. GetBufferLength(
  455. IN SOCKET_BUFFER_ID SocketBufferId
  456. );
  457. DWORD
  458. GetBufferLength(
  459. IN SOCKET_BUFFER_ID SocketBufferId,
  460. OUT LPDWORD lpdwBufferLength
  461. );
  462. DWORD
  463. SetBufferLength(
  464. IN SOCKET_BUFFER_ID SocketBufferId,
  465. IN DWORD dwBufferLength
  466. );
  467. DWORD
  468. SetSendCoalescing(
  469. IN BOOL bOnOff
  470. );
  471. // This code needs to handle system time roll over.
  472. // SetExpireTime is passed the duration, and we calculate the ultimate time
  473. // However, this may result in a rollover -- e.g. if the current time is
  474. // 0xffffff00, the ultimate time could be 0x000000fd
  475. // HasExpired is passed the current tick count, however, and in the past
  476. // would return TRUE immediately.
  477. // Thus we set a flag is we need to wait for system time rollover to happen,
  478. VOID
  479. SetExpiryTime(
  480. IN DWORD dwTimeout = GlobalKeepAliveSocketTimeout
  481. ) {
  482. DWORD dw = GetTickCountWrap();
  483. m_dwTimeout = dw + dwTimeout;
  484. m_fTimeoutWraps = (m_dwTimeout < dw);
  485. }
  486. DWORD GetExpiryTime(VOID) const {
  487. return m_dwTimeout;
  488. }
  489. BOOL HasExpired(
  490. IN DWORD dwTime = GetTickCountWrap()
  491. ) {
  492. if (m_fTimeoutWraps)
  493. {
  494. m_fTimeoutWraps = ((LONG)dwTime < 0);
  495. }
  496. return ((m_dwTimeout == 0) || m_fTimeoutWraps)
  497. ? FALSE
  498. : (dwTime > m_dwTimeout);
  499. }
  500. DWORD
  501. DataAvailable(
  502. OUT LPDWORD lpdwDataAvailable
  503. );
  504. DWORD
  505. DataAvailable2(
  506. OUT LPVOID lpBuffer,
  507. IN DWORD dwBufferLength,
  508. OUT LPDWORD lpdwBytesAvailable
  509. );
  510. DWORD
  511. WaitForReceive(
  512. IN DWORD Timeout
  513. );
  514. DWORD
  515. AllocateQueryBuffer(
  516. OUT LPVOID * lplpBuffer,
  517. OUT LPDWORD lpdwBufferLength
  518. );
  519. VOID
  520. FreeQueryBuffer(
  521. IN LPVOID lpBuffer
  522. );
  523. DWORD
  524. EnableSocks(
  525. IN LPSTR lpSocksHost,
  526. IN INTERNET_PORT ipSocksPort
  527. );
  528. BOOL IsSocks(VOID) {
  529. return m_SocksAddress != 0;
  530. }
  531. #if 0
  532. DWORD
  533. CreateSocket(
  534. IN DWORD dwFlags,
  535. IN int nFamily,
  536. IN int nType,
  537. IN int nProtocol
  538. );
  539. #endif
  540. DWORD
  541. GetSockName(
  542. IN PSOCKADDR psaSockName,
  543. IN int SockNameSize
  544. );
  545. DWORD
  546. Listen(
  547. VOID
  548. );
  549. DWORD
  550. DirectConnect(
  551. IN PSOCKADDR psaRemoteSock
  552. );
  553. DWORD
  554. SelectAccept(
  555. IN ICSocket & acceptSocket,
  556. IN DWORD dwTimeout
  557. );
  558. DWORD
  559. GetBytesAvailable(
  560. OUT LPDWORD lpdwBytesAvailable
  561. );
  562. //VOID
  563. //SetServiceAddress(
  564. // IN LPADDRESS_INFO_LIST AddressList
  565. // )
  566. //{
  567. // m_fOwnAddressList = FALSE;
  568. // m_AddressList.Addresses = AddressList->Addresses;
  569. // m_AddressList.AddressCount = AddressList->AddressCount;
  570. //}
  571. //DWORD
  572. //GetServiceAddress(
  573. // IN LPSTR HostName OPTIONAL,
  574. // IN LPSTR ServiceName OPTIONAL,
  575. // IN LPGUID ServiceGuid OPTIONAL,
  576. // IN DWORD NameSpace,
  577. // IN DWORD Port,
  578. // IN DWORD ProtocolCharacteristics
  579. // )
  580. //{
  581. // return ::GetServiceAddress(
  582. // HostName,
  583. // ServiceName,
  584. // ServiceGuid,
  585. // NameSpace,
  586. // Port,
  587. // ProtocolCharacteristics,
  588. // &m_AddressList
  589. // );
  590. //}
  591. //
  592. // friend functions
  593. //
  594. friend
  595. ICSocket *
  596. ContainingICSocket(
  597. LPVOID lpAddress
  598. );
  599. DWORD
  600. AssociateWithCompletionPort(
  601. VOID
  602. );
  603. BOOL
  604. MatchOverlappedSemantics(
  605. IN DWORD dwSocketFlags
  606. );
  607. };