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.

707 lines
15 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_PIPELINED 0x00080000 // set if connection is pipelined (HTTP 1.1)
  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. //
  54. // types
  55. //
  56. //
  57. // SOCKET_BUFFER_ID - which socket buffer we are dealing with
  58. //
  59. typedef enum {
  60. ReceiveBuffer = SO_RCVBUF,
  61. SendBuffer = SO_SNDBUF
  62. } SOCKET_BUFFER_ID;
  63. //
  64. // timeout types for SetSocketTimeout
  65. //
  66. #define SEND_TIMEOUT 1
  67. #define RECEIVE_TIMEOUT 0
  68. //
  69. // macros
  70. //
  71. #define IS_VALID_NON_LOOPBACK_IP_ADDRESS(address) \
  72. (((address) != HOST_INADDR_ANY) \
  73. && ((address) != HOST_INADDR_NONE) \
  74. && ((address) != HOST_INADDR_LOOPBACK))
  75. //
  76. // prototypes
  77. //
  78. LPSTR
  79. MapNetAddressToName(
  80. IN INTERNET_HANDLE_OBJECT * pSessionObject,
  81. IN LPSTR lpszAddress,
  82. OUT LPSTR * lplpszMappedName
  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. #if INET_DEBUG
  178. #define ICSOCKET_SIGNATURE 0x6b636f53 // "Sock"
  179. DWORD m_Signature;
  180. #define SIGN_ICSOCKET() \
  181. m_Signature = ICSOCKET_SIGNATURE
  182. #define CHECK_ICSOCKET() \
  183. INET_ASSERT((m_Signature == ICSOCKET_SIGNATURE) || (m_Signature == SECURE_SOCKET_SIGNATURE))
  184. #else
  185. #define SIGN_ICSOCKET() \
  186. /* NOTHING */
  187. #define CHECK_ICSOCKET() \
  188. /* NOTHING */
  189. #endif
  190. public:
  191. ICSocket();
  192. virtual ~ICSocket();
  193. VOID
  194. Destroy(
  195. VOID
  196. );
  197. PLIST_ENTRY List(VOID) {
  198. return &m_List;
  199. }
  200. PLIST_ENTRY Next(VOID) {
  201. return m_List.Flink;
  202. }
  203. BOOL IsOnList(VOID) {
  204. return ((m_List.Flink == NULL) && (m_List.Blink == NULL)) ? FALSE : TRUE;
  205. }
  206. CFsm* GetAndSetCurrentFsm(CFsm* pCurrent)
  207. {
  208. /*
  209. CFsm* pTemp = _pCurrentFsm;
  210. _pCurrentFsm = pCurrent;
  211. return pTemp;
  212. */
  213. // ICSocket race possible?
  214. return (CFsm *)InterlockedExchangePointer((PVOID*)&_pCurrentFsm, (PVOID)pCurrent);
  215. }
  216. VOID
  217. Reference(
  218. VOID
  219. );
  220. BOOL
  221. Dereference(
  222. VOID
  223. );
  224. LONG ReferenceCount(VOID) const {
  225. return m_ReferenceCount;
  226. }
  227. BOOL IsValid(VOID) {
  228. return (m_Socket != INVALID_SOCKET) ? TRUE : FALSE;
  229. }
  230. BOOL IsInvalid(VOID) {
  231. return !IsValid();
  232. }
  233. BOOL IsOpen(VOID) {
  234. return IsValid();
  235. }
  236. BOOL IsClosed(VOID) {
  237. return !IsOpen();
  238. }
  239. SOCKET GetSocket(VOID) const {
  240. return m_Socket;
  241. }
  242. VOID SetSocket(SOCKET Socket) {
  243. m_Socket = Socket;
  244. }
  245. BOOL IsNonBlocking(VOID) {
  246. return (m_dwFlags & SF_NON_BLOCKING) ? TRUE : FALSE;
  247. }
  248. BOOL IsSecure(VOID) const {
  249. return (m_dwFlags & SF_SECURE) ? TRUE : FALSE;
  250. }
  251. VOID SetEncryption(VOID) {
  252. m_dwFlags |= SF_ENCRYPT | SF_DECRYPT;
  253. }
  254. VOID ResetEncryption(VOID) {
  255. m_dwFlags &= ~(SF_ENCRYPT | SF_DECRYPT);
  256. }
  257. DWORD GetFlags(VOID) const {
  258. return m_dwFlags;
  259. }
  260. VOID SetAuthorized(VOID) {
  261. m_dwFlags |= SF_AUTHORIZED;
  262. }
  263. BOOL IsAuthorized(VOID) {
  264. return (m_dwFlags & SF_AUTHORIZED) ? TRUE : FALSE;
  265. }
  266. VOID SetAuthenticated(VOID) {
  267. m_dwFlags |= SF_AUTHENTICATED;
  268. }
  269. BOOL IsAuthenticated(VOID) {
  270. return (m_dwFlags & SF_AUTHENTICATED) ? TRUE : FALSE;
  271. }
  272. VOID SetPerUser (VOID) {
  273. m_dwFlags |= SF_PERUSER;
  274. }
  275. BOOL IsPerUser(VOID) {
  276. return (m_dwFlags & SF_PERUSER) ? TRUE : FALSE;
  277. }
  278. VOID SetKeepAlive(VOID) {
  279. m_dwFlags |= SF_KEEP_ALIVE;
  280. }
  281. VOID ResetKeepAlive(VOID) {
  282. m_dwFlags &= ~SF_KEEP_ALIVE;
  283. }
  284. BOOL IsKeepAlive(VOID) {
  285. return (m_dwFlags & SF_KEEP_ALIVE) ? TRUE : FALSE;
  286. }
  287. VOID SetPipelined(VOID) {
  288. m_dwFlags |= SF_PIPELINED;
  289. }
  290. VOID ResetPipelined(VOID) {
  291. m_dwFlags &= ~SF_PIPELINED;
  292. }
  293. BOOL IsPipelined(VOID) {
  294. return (m_dwFlags & SF_PIPELINED) ? TRUE : FALSE;
  295. }
  296. BOOL Match(DWORD dwFlags) {
  297. return ((m_dwFlags & dwFlags) == dwFlags) ? TRUE : FALSE;
  298. }
  299. virtual BOOL MatchTunnelSemantics(DWORD dwFlags, LPSTR pszHostName = NULL) {
  300. return (dwFlags & SF_TUNNEL) ? FALSE : TRUE;
  301. }
  302. VOID SetPort(INTERNET_PORT Port) {
  303. m_Port = Port;
  304. }
  305. INTERNET_PORT GetPort(VOID) const {
  306. return m_Port;
  307. }
  308. VOID SetSourcePort(VOID);
  309. VOID SetSourcePort(INTERNET_PORT Port) {
  310. m_SourcePort = Port;
  311. }
  312. INTERNET_PORT GetSourcePort(VOID) const {
  313. return m_SourcePort;
  314. }
  315. VOID SetAborted(VOID) {
  316. m_bAborted = TRUE;
  317. }
  318. BOOL IsAborted(VOID) const {
  319. return m_bAborted;
  320. }
  321. DWORD
  322. GetServiceAddress(
  323. IN LPSTR HostName,
  324. IN DWORD Port
  325. );
  326. virtual
  327. DWORD
  328. Connect(
  329. IN LONG Timeout,
  330. IN INT Retries,
  331. IN DWORD dwFlags
  332. );
  333. DWORD
  334. SocketConnect(
  335. IN LONG Timeout,
  336. IN INT Retries,
  337. IN DWORD dwFlags,
  338. IN CServerInfo *pServerInfo
  339. );
  340. DWORD
  341. Connect_Start(
  342. IN CFsm_SocketConnect * Fsm
  343. );
  344. DWORD
  345. Connect_Continue(
  346. IN CFsm_SocketConnect * Fsm
  347. );
  348. DWORD
  349. Connect_Error(
  350. IN CFsm_SocketConnect * Fsm
  351. );
  352. DWORD
  353. Connect_Finish(
  354. IN CFsm_SocketConnect * Fsm
  355. );
  356. int
  357. SocksConnect(
  358. IN LPSOCKADDR_IN pSockaddr,
  359. IN INT nLen
  360. );
  361. virtual
  362. DWORD
  363. Disconnect(
  364. IN DWORD dwFlags = 0
  365. );
  366. DWORD
  367. Close(
  368. VOID
  369. );
  370. DWORD
  371. Abort(
  372. VOID
  373. );
  374. DWORD
  375. Shutdown(
  376. IN DWORD dwControl
  377. );
  378. BOOL
  379. IsReset(
  380. VOID
  381. );
  382. virtual
  383. DWORD
  384. Send(
  385. IN LPVOID lpBuffer,
  386. IN DWORD dwBufferLength,
  387. IN DWORD dwFlags
  388. );
  389. DWORD
  390. Send_Start(
  391. IN CFsm_SocketSend * Fsm
  392. );
  393. virtual
  394. DWORD
  395. Receive(
  396. IN OUT LPVOID* lplpBuffer,
  397. IN OUT LPDWORD lpdwBufferLength,
  398. IN OUT LPDWORD lpdwBufferRemaining,
  399. IN OUT LPDWORD lpdwBytesReceived,
  400. IN DWORD dwExtraSpace,
  401. IN DWORD dwFlags,
  402. OUT LPBOOL lpbEof
  403. );
  404. DWORD
  405. Receive_Start(
  406. IN CFsm_SocketReceive * Fsm
  407. );
  408. DWORD
  409. Receive_Continue(
  410. IN CFsm_SocketReceive * Fsm
  411. );
  412. DWORD
  413. Receive_Finish(
  414. IN CFsm_SocketReceive * Fsm
  415. );
  416. DWORD
  417. SetTimeout(
  418. IN DWORD Type,
  419. IN int Timeout
  420. );
  421. DWORD
  422. SetLinger(
  423. IN BOOL Linger,
  424. IN int Timeout
  425. );
  426. DWORD
  427. SetNonBlockingMode(
  428. IN BOOL bNonBlocking
  429. );
  430. DWORD
  431. GetBufferLength(
  432. IN SOCKET_BUFFER_ID SocketBufferId
  433. );
  434. DWORD
  435. GetBufferLength(
  436. IN SOCKET_BUFFER_ID SocketBufferId,
  437. OUT LPDWORD lpdwBufferLength
  438. );
  439. DWORD
  440. SetBufferLength(
  441. IN SOCKET_BUFFER_ID SocketBufferId,
  442. IN DWORD dwBufferLength
  443. );
  444. DWORD
  445. SetSendCoalescing(
  446. IN BOOL bOnOff
  447. );
  448. // This code needs to handle system time roll over.
  449. // SetExpireTime is passed the duration, and we calculate the ultimate time
  450. // However, this may result in a rollover -- e.g. if the current time is
  451. // 0xffffff00, the ultimate time could be 0x000000fd
  452. // HasExpired is passed the current tick count, however, and in the past
  453. // would return TRUE immediately.
  454. // Thus we set a flag is we need to wait for system time rollover to happen,
  455. VOID
  456. SetExpiryTime(
  457. IN DWORD dwTimeout = GlobalKeepAliveSocketTimeout
  458. ) {
  459. DWORD dw = GetTickCountWrap();
  460. m_dwTimeout = dw + dwTimeout;
  461. m_fTimeoutWraps = (m_dwTimeout < dw);
  462. }
  463. DWORD GetExpiryTime(VOID) const {
  464. return m_dwTimeout;
  465. }
  466. BOOL HasExpired(
  467. IN DWORD dwTime = GetTickCountWrap()
  468. ) {
  469. if (m_fTimeoutWraps)
  470. {
  471. m_fTimeoutWraps = ((LONG)dwTime < 0);
  472. }
  473. return ((m_dwTimeout == 0) || m_fTimeoutWraps)
  474. ? FALSE
  475. : (dwTime > m_dwTimeout);
  476. }
  477. DWORD
  478. DataAvailable(
  479. OUT LPDWORD lpdwDataAvailable
  480. );
  481. DWORD
  482. DataAvailable2(
  483. OUT LPVOID lpBuffer,
  484. IN DWORD dwBufferLength,
  485. OUT LPDWORD lpdwBytesAvailable
  486. );
  487. DWORD
  488. WaitForReceive(
  489. IN DWORD Timeout
  490. );
  491. DWORD
  492. AllocateQueryBuffer(
  493. OUT LPVOID * lplpBuffer,
  494. OUT LPDWORD lpdwBufferLength
  495. );
  496. VOID
  497. FreeQueryBuffer(
  498. IN LPVOID lpBuffer
  499. );
  500. DWORD
  501. EnableSocks(
  502. IN LPSTR lpSocksHost,
  503. IN INTERNET_PORT ipSocksPort
  504. );
  505. BOOL IsSocks(VOID) {
  506. return m_SocksAddress != 0;
  507. }
  508. DWORD
  509. CreateSocket(
  510. IN DWORD dwFlags,
  511. IN int nFamily = AF_INET,
  512. IN int nType = SOCK_STREAM,
  513. IN int nProtocol = IPPROTO_TCP
  514. );
  515. DWORD
  516. GetSockName(
  517. PSOCKADDR psaSockName
  518. );
  519. DWORD
  520. Listen(
  521. VOID
  522. );
  523. DWORD
  524. DirectConnect(
  525. IN PSOCKADDR psaRemoteSock
  526. );
  527. DWORD
  528. SelectAccept(
  529. IN ICSocket & acceptSocket,
  530. IN DWORD dwTimeout
  531. );
  532. DWORD
  533. GetBytesAvailable(
  534. OUT LPDWORD lpdwBytesAvailable
  535. );
  536. //VOID
  537. //SetServiceAddress(
  538. // IN LPADDRESS_INFO_LIST AddressList
  539. // )
  540. //{
  541. // m_fOwnAddressList = FALSE;
  542. // m_AddressList.Addresses = AddressList->Addresses;
  543. // m_AddressList.AddressCount = AddressList->AddressCount;
  544. //}
  545. //DWORD
  546. //GetServiceAddress(
  547. // IN LPSTR HostName OPTIONAL,
  548. // IN LPSTR ServiceName OPTIONAL,
  549. // IN LPGUID ServiceGuid OPTIONAL,
  550. // IN DWORD NameSpace,
  551. // IN DWORD Port,
  552. // IN DWORD ProtocolCharacteristics
  553. // )
  554. //{
  555. // return ::GetServiceAddress(
  556. // HostName,
  557. // ServiceName,
  558. // ServiceGuid,
  559. // NameSpace,
  560. // Port,
  561. // ProtocolCharacteristics,
  562. // &m_AddressList
  563. // );
  564. //}
  565. //
  566. // friend functions
  567. //
  568. friend
  569. ICSocket *
  570. ContainingICSocket(
  571. LPVOID lpAddress
  572. );
  573. };