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.

711 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 LPSTR lpszAddress,
  81. OUT LPSTR * lplpszMappedName
  82. );
  83. //DWORD
  84. //GetServiceAddress(
  85. // IN LPSTR HostName,
  86. // IN DWORD Port,
  87. // OUT LPADDRESS_INFO_LIST AddressList
  88. // );
  89. //
  90. //BOOL
  91. //IsNetAddress(
  92. // IN LPSTR lpszAddress
  93. // );
  94. //
  95. //#if INET_DEBUG
  96. //
  97. //DEBUG_FUNCTION
  98. //VOID
  99. //InitializeAddressList(
  100. // IN LPADDRESS_INFO_LIST AddressList
  101. // );
  102. //
  103. //DEBUG_FUNCTION
  104. //VOID
  105. //FreeAddressList(
  106. // IN LPADDRESS_INFO_LIST AddressList
  107. // );
  108. //
  109. //DEBUG_FUNCTION
  110. //BOOL
  111. //IsAddressListEmpty(
  112. // IN LPADDRESS_INFO_LIST AddressList
  113. // );
  114. //
  115. //#else
  116. //
  117. //#define InitializeAddressList(AddressList) \
  118. // (AddressList)->AddressCount = 0; \
  119. // (AddressList)->Addresses = NULL
  120. //
  121. //#define FreeAddressList(AddressList) \
  122. // if ((AddressList)->AddressCount != 0) { \
  123. // (AddressList)->Addresses = (LPCSADDR_INFO)FREE_MEMORY((HLOCAL)((AddressList)->Addresses)); \
  124. // (AddressList)->AddressCount = 0; \
  125. // }
  126. //
  127. //#define IsAddressListEmpty(AddressList) \
  128. // (((AddressList)->AddressCount == 0) ? TRUE : FALSE)
  129. //
  130. //#endif // INET_DEBUG
  131. //
  132. //DWORD
  133. //DestinationAddressFromAddressList(
  134. // IN LPADDRESS_INFO_LIST lpAddressList,
  135. // IN DWORD dwIndex,
  136. // OUT LPBYTE lpbDestinationAddress,
  137. // IN OUT LPDWORD lpdwDestinationAddressLength
  138. // );
  139. //
  140. //DWORD
  141. //InterfaceAddressFromSocket(
  142. // IN SOCKET Socket,
  143. // OUT LPBYTE lpbInterfaceAddress,
  144. // IN OUT LPDWORD lpdwInterfaceAddressLength
  145. // );
  146. //
  147. // classes
  148. //
  149. //
  150. // forward references
  151. //
  152. class CFsm_SocketConnect;
  153. class CFsm_SocketSend;
  154. class CFsm_SocketReceive;
  155. class CServerInfo;
  156. //
  157. // ICSocket - abstracts a TCP/IP connection
  158. //
  159. class ICSocket {
  160. protected:
  161. LIST_ENTRY m_List; // keep-alive list
  162. DWORD m_dwTimeout; // keep-alive expiry
  163. BOOL m_fTimeoutWraps;
  164. LONG m_ReferenceCount;
  165. SOCKET m_Socket;
  166. DWORD m_dwFlags;
  167. INTERNET_PORT m_Port; // needed for keep-alive
  168. INTERNET_PORT m_SourcePort;
  169. BOOL m_bAborted;
  170. DWORD m_SocksAddress;
  171. INTERNET_PORT m_SocksPort;
  172. //HINTERNET m_hRequest;
  173. BOOL m_fExemptConnLImit;
  174. #if INET_DEBUG
  175. #define ICSOCKET_SIGNATURE 0x6b636f53 // "Sock"
  176. DWORD m_Signature;
  177. #define SIGN_ICSOCKET() \
  178. m_Signature = ICSOCKET_SIGNATURE
  179. #define CHECK_ICSOCKET() \
  180. INET_ASSERT((m_Signature == ICSOCKET_SIGNATURE) || (m_Signature == SECURE_SOCKET_SIGNATURE))
  181. #else
  182. #define SIGN_ICSOCKET() \
  183. /* NOTHING */
  184. #define CHECK_ICSOCKET() \
  185. /* NOTHING */
  186. #endif
  187. public:
  188. ICSocket();
  189. virtual ~ICSocket();
  190. void ExemptConnLimit(void) {
  191. m_fExemptConnLImit = TRUE;
  192. }
  193. BOOL ConnLimitExempted(void) const {
  194. return m_fExemptConnLImit;
  195. }
  196. void ResetExemptFlag(void) {
  197. m_fExemptConnLImit = FALSE;
  198. }
  199. VOID
  200. Destroy(
  201. VOID
  202. );
  203. PLIST_ENTRY List(VOID) {
  204. return &m_List;
  205. }
  206. PLIST_ENTRY Next(VOID) {
  207. return m_List.Flink;
  208. }
  209. BOOL IsOnList(VOID) {
  210. return ((m_List.Flink == NULL) && (m_List.Blink == NULL)) ? FALSE : TRUE;
  211. }
  212. VOID
  213. Reference(
  214. VOID
  215. );
  216. BOOL
  217. Dereference(
  218. VOID
  219. );
  220. LONG ReferenceCount(VOID) const {
  221. return m_ReferenceCount;
  222. }
  223. BOOL IsValid(VOID) {
  224. return (m_Socket != INVALID_SOCKET) ? TRUE : FALSE;
  225. }
  226. BOOL IsInvalid(VOID) {
  227. return !IsValid();
  228. }
  229. BOOL IsOpen(VOID) {
  230. return IsValid();
  231. }
  232. BOOL IsClosed(VOID) {
  233. return !IsOpen();
  234. }
  235. SOCKET GetSocket(VOID) const {
  236. return m_Socket;
  237. }
  238. VOID SetSocket(SOCKET Socket) {
  239. m_Socket = Socket;
  240. }
  241. BOOL IsNonBlocking(VOID) {
  242. return (m_dwFlags & SF_NON_BLOCKING) ? TRUE : FALSE;
  243. }
  244. BOOL IsSecure(VOID) const {
  245. return (m_dwFlags & SF_SECURE) ? TRUE : FALSE;
  246. }
  247. VOID SetEncryption(VOID) {
  248. m_dwFlags |= SF_ENCRYPT | SF_DECRYPT;
  249. }
  250. VOID ResetEncryption(VOID) {
  251. m_dwFlags &= ~(SF_ENCRYPT | SF_DECRYPT);
  252. }
  253. DWORD GetFlags(VOID) const {
  254. return m_dwFlags;
  255. }
  256. VOID SetAuthorized(VOID) {
  257. m_dwFlags |= SF_AUTHORIZED;
  258. }
  259. BOOL IsAuthorized(VOID) {
  260. return (m_dwFlags & SF_AUTHORIZED) ? TRUE : FALSE;
  261. }
  262. VOID SetAuthenticated(VOID) {
  263. m_dwFlags |= SF_AUTHENTICATED;
  264. }
  265. BOOL IsAuthenticated(VOID) {
  266. return (m_dwFlags & SF_AUTHENTICATED) ? TRUE : FALSE;
  267. }
  268. VOID SetPerUser (VOID) {
  269. m_dwFlags |= SF_PERUSER;
  270. }
  271. BOOL IsPerUser(VOID) {
  272. return (m_dwFlags & SF_PERUSER) ? TRUE : FALSE;
  273. }
  274. VOID SetKeepAlive(VOID) {
  275. m_dwFlags |= SF_KEEP_ALIVE;
  276. }
  277. VOID ResetKeepAlive(VOID) {
  278. m_dwFlags &= ~SF_KEEP_ALIVE;
  279. }
  280. BOOL IsKeepAlive(VOID) {
  281. return (m_dwFlags & SF_KEEP_ALIVE) ? TRUE : FALSE;
  282. }
  283. VOID SetPipelined(VOID) {
  284. m_dwFlags |= SF_PIPELINED;
  285. }
  286. VOID ResetPipelined(VOID) {
  287. m_dwFlags &= ~SF_PIPELINED;
  288. }
  289. BOOL IsPipelined(VOID) {
  290. return (m_dwFlags & SF_PIPELINED) ? TRUE : FALSE;
  291. }
  292. BOOL Match(DWORD dwFlags) {
  293. return ((m_dwFlags & dwFlags) == dwFlags) ? TRUE : FALSE;
  294. }
  295. virtual BOOL MatchTunnelSemantics(DWORD dwFlags, LPSTR pszHostName = NULL) {
  296. return ((m_dwFlags & SF_TUNNEL) == (dwFlags & SF_TUNNEL)) ? TRUE : FALSE;
  297. }
  298. VOID SetPort(INTERNET_PORT Port) {
  299. m_Port = Port;
  300. }
  301. INTERNET_PORT GetPort(VOID) const {
  302. return m_Port;
  303. }
  304. VOID SetSourcePort(VOID);
  305. VOID SetSourcePort(INTERNET_PORT Port) {
  306. m_SourcePort = Port;
  307. }
  308. INTERNET_PORT GetSourcePort(VOID) const {
  309. return m_SourcePort;
  310. }
  311. VOID SetAborted(VOID) {
  312. m_bAborted = TRUE;
  313. }
  314. BOOL IsAborted(VOID) const {
  315. return m_bAborted;
  316. }
  317. DWORD
  318. GetServiceAddress(
  319. IN LPSTR HostName,
  320. IN DWORD Port
  321. );
  322. virtual
  323. DWORD
  324. Connect(
  325. IN LONG Timeout,
  326. IN INT Retries,
  327. IN DWORD dwFlags
  328. );
  329. DWORD
  330. SocketConnect(
  331. IN LONG Timeout,
  332. IN INT Retries,
  333. IN DWORD dwFlags,
  334. IN CServerInfo *pServerInfo
  335. );
  336. DWORD
  337. Connect_Start(
  338. IN CFsm_SocketConnect * Fsm
  339. );
  340. DWORD
  341. Connect_Continue(
  342. IN CFsm_SocketConnect * Fsm
  343. );
  344. DWORD
  345. Connect_Error(
  346. IN CFsm_SocketConnect * Fsm
  347. );
  348. DWORD
  349. Connect_Finish(
  350. IN CFsm_SocketConnect * Fsm
  351. );
  352. int
  353. SocksConnect(
  354. IN LPSOCKADDR_IN pSockaddr,
  355. IN INT nLen
  356. );
  357. virtual
  358. DWORD
  359. Disconnect(
  360. IN DWORD dwFlags = 0
  361. );
  362. DWORD
  363. Close(
  364. VOID
  365. );
  366. DWORD
  367. Abort(
  368. VOID
  369. );
  370. DWORD
  371. Shutdown(
  372. IN DWORD dwControl
  373. );
  374. BOOL
  375. IsReset(
  376. VOID
  377. );
  378. virtual
  379. DWORD
  380. Send(
  381. IN LPVOID lpBuffer,
  382. IN DWORD dwBufferLength,
  383. IN DWORD dwFlags
  384. );
  385. DWORD
  386. Send_Start(
  387. IN CFsm_SocketSend * Fsm
  388. );
  389. virtual
  390. DWORD
  391. Receive(
  392. IN OUT LPVOID* lplpBuffer,
  393. IN OUT LPDWORD lpdwBufferLength,
  394. IN OUT LPDWORD lpdwBufferRemaining,
  395. IN OUT LPDWORD lpdwBytesReceived,
  396. IN DWORD dwExtraSpace,
  397. IN DWORD dwFlags,
  398. OUT LPBOOL lpbEof
  399. );
  400. DWORD
  401. Receive_Start(
  402. IN CFsm_SocketReceive * Fsm
  403. );
  404. DWORD
  405. Receive_Continue(
  406. IN CFsm_SocketReceive * Fsm
  407. );
  408. DWORD
  409. Receive_Finish(
  410. IN CFsm_SocketReceive * Fsm
  411. );
  412. DWORD
  413. SetTimeout(
  414. IN DWORD Type,
  415. IN int Timeout
  416. );
  417. DWORD
  418. SetLinger(
  419. IN BOOL Linger,
  420. IN int Timeout
  421. );
  422. DWORD
  423. SetNonBlockingMode(
  424. IN BOOL bNonBlocking
  425. );
  426. DWORD
  427. GetBufferLength(
  428. IN SOCKET_BUFFER_ID SocketBufferId
  429. );
  430. DWORD
  431. GetBufferLength(
  432. IN SOCKET_BUFFER_ID SocketBufferId,
  433. OUT LPDWORD lpdwBufferLength
  434. );
  435. DWORD
  436. SetBufferLength(
  437. IN SOCKET_BUFFER_ID SocketBufferId,
  438. IN DWORD dwBufferLength
  439. );
  440. DWORD
  441. SetSendCoalescing(
  442. IN BOOL bOnOff
  443. );
  444. // This code needs to handle system time roll over.
  445. // SetExpireTime is passed the duration, and we calculate the ultimate time
  446. // However, this may result in a rollover -- e.g. if the current time is
  447. // 0xffffff00, the ultimate time could be 0x000000fd
  448. // HasExpired is passed the current tick count, however, and in the past
  449. // would return TRUE immediately.
  450. // Thus we set a flag is we need to wait for system time rollover to happen,
  451. VOID
  452. SetExpiryTime(
  453. IN DWORD dwTimeout = GlobalKeepAliveSocketTimeout
  454. ) {
  455. DWORD dw = GetTickCountWrap();
  456. m_dwTimeout = dw + dwTimeout;
  457. m_fTimeoutWraps = (m_dwTimeout < dw);
  458. }
  459. DWORD GetExpiryTime(VOID) const {
  460. return m_dwTimeout;
  461. }
  462. BOOL HasExpired(
  463. IN DWORD dwTime = GetTickCountWrap()
  464. ) {
  465. if (m_fTimeoutWraps)
  466. {
  467. m_fTimeoutWraps = ((LONG)dwTime < 0);
  468. }
  469. return ((m_dwTimeout == 0) || m_fTimeoutWraps)
  470. ? FALSE
  471. : (dwTime > m_dwTimeout);
  472. }
  473. DWORD
  474. DataAvailable(
  475. OUT LPDWORD lpdwDataAvailable
  476. );
  477. DWORD
  478. DataAvailable2(
  479. OUT LPVOID lpBuffer,
  480. IN DWORD dwBufferLength,
  481. OUT LPDWORD lpdwBytesAvailable
  482. );
  483. DWORD
  484. WaitForReceive(
  485. IN DWORD Timeout
  486. );
  487. DWORD
  488. AllocateQueryBuffer(
  489. OUT LPVOID * lplpBuffer,
  490. OUT LPDWORD lpdwBufferLength
  491. );
  492. VOID
  493. FreeQueryBuffer(
  494. IN LPVOID lpBuffer
  495. );
  496. DWORD
  497. EnableSocks(
  498. IN LPSTR lpSocksHost,
  499. IN INTERNET_PORT ipSocksPort
  500. );
  501. BOOL IsSocks(VOID) {
  502. return m_SocksAddress != 0;
  503. }
  504. DWORD
  505. CreateSocket(
  506. IN DWORD dwFlags,
  507. IN int nFamily,
  508. IN int nType,
  509. IN int nProtocol
  510. );
  511. DWORD
  512. GetSockName(
  513. IN PSOCKADDR psaSockName,
  514. IN int SockNameSize
  515. );
  516. DWORD
  517. GetPeerName(
  518. IN PSOCKADDR psaSockName,
  519. IN int SockNameSize
  520. );
  521. DWORD
  522. Listen(
  523. VOID
  524. );
  525. DWORD
  526. DirectConnect(
  527. IN PSOCKADDR psaRemoteSock
  528. );
  529. DWORD
  530. SelectAccept(
  531. IN ICSocket & acceptSocket,
  532. IN DWORD dwTimeout
  533. );
  534. DWORD
  535. GetBytesAvailable(
  536. OUT LPDWORD lpdwBytesAvailable
  537. );
  538. //VOID
  539. //SetServiceAddress(
  540. // IN LPADDRESS_INFO_LIST AddressList
  541. // )
  542. //{
  543. // m_fOwnAddressList = FALSE;
  544. // m_AddressList.Addresses = AddressList->Addresses;
  545. // m_AddressList.AddressCount = AddressList->AddressCount;
  546. //}
  547. //DWORD
  548. //GetServiceAddress(
  549. // IN LPSTR HostName OPTIONAL,
  550. // IN LPSTR ServiceName OPTIONAL,
  551. // IN LPGUID ServiceGuid OPTIONAL,
  552. // IN DWORD NameSpace,
  553. // IN DWORD Port,
  554. // IN DWORD ProtocolCharacteristics
  555. // )
  556. //{
  557. // return ::GetServiceAddress(
  558. // HostName,
  559. // ServiceName,
  560. // ServiceGuid,
  561. // NameSpace,
  562. // Port,
  563. // ProtocolCharacteristics,
  564. // &m_AddressList
  565. // );
  566. //}
  567. //
  568. // friend functions
  569. //
  570. friend
  571. ICSocket *
  572. ContainingICSocket(
  573. LPVOID lpAddress
  574. );
  575. };