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.

1380 lines
35 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. Module Name:
  4. trans.hxx
  5. Abstract:
  6. Commen base for all NT transport interfaces.
  7. Author:
  8. Mario Goertzel [MarioGo]
  9. Revision History:
  10. MarioGo 4/12/1996 Bits 'n pieces
  11. MarioGo 10/24/1996 Async RPC
  12. EdwardR 07/04/1997 Falcon/RPC
  13. --*/
  14. #ifndef __TRANS_HXX
  15. #define __TRANS_HXX
  16. #include "Dbg.hxx"
  17. //
  18. // Winsock address types.
  19. //
  20. union WS_SOCKADDR
  21. {
  22. SOCKADDR generic;
  23. SOCKADDR_IN inetaddr;
  24. #ifndef SPX_IPX_OFF
  25. SOCKADDR_IPX ipxaddr;
  26. #endif
  27. SOCKADDR_AT ataddr;
  28. #ifdef NETBIOS_ON
  29. SOCKADDR_NB nbaddr;
  30. #endif
  31. SOCKADDR_CLUSTER clusaddr;
  32. SOCKADDR_STORAGE ipaddr;
  33. };
  34. inline void
  35. RpcpSetIpPort (
  36. IN WS_SOCKADDR *SockAddress,
  37. IN USHORT Port
  38. )
  39. {
  40. SS_PORT(SockAddress) = Port;
  41. }
  42. inline USHORT
  43. RpcpGetIpPort (
  44. IN WS_SOCKADDR *SockAddress
  45. )
  46. {
  47. return SS_PORT(SockAddress);
  48. }
  49. inline void
  50. RpcpCopyIPv6Address (
  51. IN SOCKADDR_IN6 *SourceAddress,
  52. OUT SOCKADDR_IN6 *TargetAddress
  53. )
  54. {
  55. RpcpMemoryCopy(&TargetAddress->sin6_addr,
  56. &SourceAddress->sin6_addr,
  57. sizeof(in6_addr));
  58. }
  59. inline void
  60. RpcpCopyIPv4Address (
  61. IN SOCKADDR_IN *SourceAddress,
  62. OUT SOCKADDR_IN *TargetAddress
  63. )
  64. {
  65. TargetAddress->sin_addr.s_addr = SourceAddress->sin_addr.s_addr;
  66. }
  67. //
  68. //
  69. // Async object types
  70. //
  71. struct BASE_ASYNC_OBJECT;
  72. //
  73. // Every outstanding async IO has an overlapped structure associated
  74. // with it.
  75. //
  76. struct BASE_OVERLAPPED
  77. {
  78. //
  79. // Pointer to the transport object this IO is associated with.
  80. // This is needed since a single object may have more than one
  81. // pending IO request.
  82. //
  83. BASE_ASYNC_OBJECT *pAsyncObject;
  84. //
  85. // System overlapped structure associated with the async IO.
  86. //
  87. OVERLAPPED ol;
  88. //
  89. // RPC thread object of the thread which started the IO. This is used
  90. // when the IO completes to keep the count of IO pending on a thread.
  91. //
  92. PVOID thread;
  93. };
  94. typedef BASE_OVERLAPPED *PBASE_OVERLAPPED;
  95. #ifdef NCADG_MQ_ON
  96. struct MQ_OVERLAPPED : BASE_OVERLAPPED
  97. {
  98. // MSMQ Messages have there own structure which must be maintained
  99. // during the span of the async IO request:
  100. MQMSGPROPS msgProps;
  101. MSGPROPID aMsgPropID[MAX_RECV_VAR];
  102. MQPROPVARIANT aMsgPropVar[MAX_RECV_VAR];
  103. HRESULT aStatus[MAX_RECV_VAR];
  104. };
  105. typedef MQ_OVERLAPPED *PMQ_OVERLAPPED;
  106. #endif
  107. // BASE_ASYNC_OBJECT is the basis for all objects which
  108. // are used in async I/O.
  109. // There are three basic objects which are used in I/O,
  110. // addresses, connections and datagrams.
  111. //
  112. // BASE_ADDRESS is the basis for all I/O which is
  113. // used to listen for new client connections.
  114. //
  115. // BASE_CONNECTION is the basis for all I/O which is
  116. // used to read/write to a connection.
  117. //
  118. // There are currently three flavors of address and
  119. // and connections:
  120. // WS_ (winsock connection base protocols)
  121. // NB_ (not supported on Itaniums - winsock based, but unique historical reasons)
  122. // NMP_ (named pipes)
  123. //
  124. // BASE_DATAGRAM is the basis for all I/O which is pending
  125. // on a datagram port. The only flavor today is winsock.
  126. //
  127. //
  128. // BASE_ASYNC_OBJECT
  129. // |
  130. // +---------------------|-------------------------+
  131. // BASE_ADDRESS BASE_CONNECTION BASE_DATAGRAM
  132. // | | | | | | |
  133. // CO_ADDRESS | WS_DG_ADDR | WS_CONNECTION | WS_DATAGRAM
  134. // | | MQ_DG_ADDR | | MQ_DATAGRAM
  135. // NMP_ADDR | NMP_CONNECTION |
  136. // WS_ADDR |
  137. // | +---------+----------+
  138. // NB_ADDR | |
  139. // WS_CLIENT_CONNECTION WS_SAN_CONNECTION
  140. // |
  141. // |
  142. // WS_SAN_CLIENT_CONNECTION
  143. //
  144. struct BASE_ASYNC_OBJECT;
  145. struct BASE_ASYNC_OBJECT
  146. {
  147. //
  148. // a placeholder for the vtbl of derived objects
  149. // this makes casts safe and fast at the expense of some
  150. // memory waste. That's ok
  151. //
  152. virtual void DoNothing(void)
  153. {
  154. }
  155. //
  156. // The type of this object. Used in determining where
  157. // to send the completed I/O.
  158. //
  159. RPC_TRANSPORT_EVENT type;
  160. //
  161. // Identifies the protcol of the address/connection.
  162. //
  163. PROTOCOL_ID id;
  164. //
  165. // > 0 means that the object has been aborted
  166. //
  167. LONG fAborted;
  168. //
  169. // Used to chain objects belonging to the
  170. // same protocol.
  171. //
  172. LIST_ENTRY ObjectList;
  173. };
  174. typedef BASE_ASYNC_OBJECT *PREQUEST;
  175. struct BASE_ADDRESS;
  176. class BASE_CONNECTION;
  177. typedef void (*TRANS_ADDRESS_LISTEN)(BASE_ADDRESS *);
  178. enum ADDRESS_STATE {
  179. NotInList,
  180. InTheList,
  181. Inactive
  182. };
  183. #define TRANSPORT_POSTED_KEY UINT_PTR(0xFFFF0000)
  184. //
  185. // Address objects represent a connection oriented endpoint which
  186. // is connected to by a client at which time a connection object
  187. // is created for the specific client.
  188. // There are relatively few address objects in the system
  189. //
  190. struct BASE_ADDRESS : BASE_ASYNC_OBJECT
  191. {
  192. //
  193. // The endpoint this address is listening on.
  194. //
  195. RPC_CHAR *Endpoint;
  196. //
  197. // List of network addresses for this address
  198. //
  199. NETWORK_ADDRESS_VECTOR *pAddressVector;
  200. //
  201. // Function to call when a listen is aborted or when
  202. // an address doesn't have an outstanding listens.
  203. //
  204. TRANS_ADDRESS_LISTEN SubmitListen;
  205. //
  206. // NotInList is address in not in the AddressManager list
  207. // InTheList if the address has been inserted into the list
  208. // InActive if it is in the list, but it is inactive
  209. //
  210. ADDRESS_STATE InAddressList;
  211. //
  212. // Endpoint flags used in conjunction with firewalls
  213. //
  214. ULONG EndpointFlags;
  215. //
  216. // If an address is unable to (or has not yet) submitted
  217. // an listen request then it is stuck into a linked list.
  218. // This is the forward list pointer.
  219. //
  220. BASE_ADDRESS *pNext;
  221. //
  222. // In order to callback into the runtime we must pass the
  223. // first (runtime allocated) address when calling back.
  224. //
  225. struct BASE_ADDRESS *pFirstAddress;
  226. //
  227. // Each netbios address may represent several listen sockets (one
  228. // for each lana). A list of these is maintained to facilitate aborting
  229. // the setup of an entire address.
  230. //
  231. struct BASE_ADDRESS *pNextAddress;
  232. //
  233. // Static or dynamic ?
  234. //
  235. BOOL fDynamicEndpoint;
  236. };
  237. struct CO_ADDRESS;
  238. typedef RPC_STATUS (*TRANS_NEW_CONNECTION)(CO_ADDRESS *, BASE_CONNECTION **);
  239. struct CO_ADDRESS : BASE_ADDRESS
  240. {
  241. //
  242. // Overlapped object associated with the pending accept/connect
  243. //
  244. BASE_OVERLAPPED Listen;
  245. //
  246. // Function to call when a connection notification arrives.
  247. //
  248. TRANS_NEW_CONNECTION NewConnection;
  249. };
  250. typedef CO_ADDRESS *PADDRESS;
  251. struct NMP_ADDRESS : CO_ADDRESS
  252. {
  253. //
  254. // The handle of the pipe instance currently
  255. // avaliable for clients to connect to.
  256. //
  257. HANDLE hConnectPipe;
  258. //
  259. // When we disconnect a client we save an extra pipe instance here
  260. // to use on the next client connection. This is a performance optimization,
  261. // but also affects correctness. See NMP_ServerListen where the first
  262. // spare pipe is created.
  263. //
  264. HandleCache sparePipes;
  265. //
  266. // The self relative security descriptor associated with
  267. // this addresss.
  268. //
  269. PSECURITY_DESCRIPTOR SecurityDescriptor;
  270. //
  271. // The complete pipe name for this addresses
  272. // endpoint including "\\."
  273. //
  274. RPC_CHAR *LocalEndpoint;
  275. };
  276. typedef NMP_ADDRESS *PNMP_ADDRESS;
  277. struct WS_ADDRESS : CO_ADDRESS
  278. {
  279. //
  280. // The socket listening on this addresses port.
  281. //
  282. SOCKET ListenSocket;
  283. //
  284. // The socket of the next client to connect. It is waiting
  285. // in an AcceptEx for the client to connect.
  286. //
  287. SOCKET ConnectionSocket;
  288. //
  289. // Netbios requires that the a protocol be multiplied by the
  290. // lana number. For other protocols this should be one.
  291. //
  292. DWORD ProtocolMultiplier;
  293. //
  294. // The PendingQueueSize parameter supplied when the address
  295. // was created
  296. //
  297. INT QueueSize;
  298. //
  299. // Buffer for the address of the client which is part of the
  300. // outstanding AcceptEx call on the listen socket.
  301. //
  302. BYTE AcceptBuffer[sizeof(WS_SOCKADDR) + 16];
  303. //
  304. // the sockaddr used to setup this address
  305. //
  306. WS_SOCKADDR ListenAddr;
  307. union
  308. {
  309. struct
  310. {
  311. LPFN_ACCEPTEX pAcceptExFunction;
  312. LPFN_GETACCEPTEXSOCKADDRS pGetAcceptExSockaddressFunction;
  313. };
  314. void *ExtensionFunctionPointers[2];
  315. };
  316. static const int AcceptExFunctionId;
  317. static const int GetAcceptExSockAddressFunctionId;
  318. static const UUID ExtensionFunctionsUuids[];
  319. BOOL GetExtensionFunctionPointers(SOCKET sock);
  320. BOOL GetExtensionFunctionPointerForFunction(SOCKET sock, int nFunctionCode);
  321. // Set to TRUE if the address has been initialized.
  322. // May be FALSE when DHCP address has not yet been initialized and
  323. // the NIC that this address is listening on does not yet have an address.
  324. BOOL fAddressInitialized;
  325. // The number of addresses in the list defined by pNextAddress
  326. // that have been initialied with a particular network address
  327. // and are capable of listening.
  328. //
  329. // This field is initialized and used for FirstAddress only.
  330. // It is used on address change PnP events to determine whether
  331. // a given list of address objects is listening on all the available NICs.
  332. DWORD NumActiveAddresses;
  333. };
  334. inline DWORD
  335. GetProtocolMultiplier (
  336. IN WS_ADDRESS *Address
  337. )
  338. {
  339. #ifdef NETBIOS_ON
  340. return Address->ProtocolMultiplier;
  341. #else
  342. return 1;
  343. #endif
  344. }
  345. inline void
  346. SetProtocolMultiplier (
  347. IN WS_ADDRESS *Address,
  348. IN DWORD ProtocolMultiplier
  349. )
  350. {
  351. #ifdef NETBIOS_ON
  352. Address->ProtocolMultiplier = ProtocolMultiplier;
  353. #endif
  354. }
  355. typedef WS_ADDRESS *PWS_ADDRESS;
  356. struct WS_DATAGRAM;
  357. typedef WS_DATAGRAM *PWS_DATAGRAM;
  358. struct WS_DATAGRAM_ENDPOINT : BASE_ADDRESS
  359. {
  360. // WS_DATAGRAM_ENDPOINTs represent either a client or server
  361. // port. There will be a small number of these on servers and
  362. // O(N) active threads on sync clients.
  363. //
  364. // The socket we're listen on.
  365. //
  366. SOCKET Socket;
  367. //
  368. // Normally FALSE, set to true by a thread which is submitting
  369. // new IOs on the endpoint.
  370. //
  371. LONG fSubmittingIos;
  372. //
  373. // Current number of WS_DATAGRAM's submitted on this endpoint.
  374. // Must be changed via InterlockedInc/Dec. The count of
  375. // non-null entries in aIdleDatagrams.
  376. //
  377. LONG cPendingIos;
  378. //
  379. // If cPendingIos is less than the minimum then recvs on any idle
  380. // WS_DATAGRAMs should be posted.
  381. //
  382. // const after initialization.
  383. //
  384. LONG cMinimumIos;
  385. //
  386. // The number of WS_DATAGRAMs available for this endpoint to use.
  387. //
  388. // const after initialization.
  389. //
  390. LONG cMaximumIos;
  391. //
  392. // Array of cMaxIos datagrams. NULL in sync endpoints.
  393. //
  394. PWS_DATAGRAM aDatagrams;
  395. //
  396. // Client or Server ?
  397. //
  398. BOOL fClient;
  399. //
  400. // Sync or Async ?
  401. //
  402. BOOL fAsync;
  403. //
  404. // Sockaddr
  405. //
  406. WS_SOCKADDR ListenAddr;
  407. };
  408. #ifdef NCADG_MQ_ON
  409. struct MQ_DATAGRAM;
  410. typedef MQ_DATAGRAM *PMQ_DATAGRAM;
  411. struct MQ_DATAGRAM_ENDPOINT : BASE_ADDRESS
  412. {
  413. // MQ_DATAGRAM_ENDPOINTs represent either a client or server
  414. // port. There will be a small number of these on servers and
  415. // O(N) active threads on sync clients.
  416. //
  417. // The queue we're listen on.
  418. //
  419. UUID uuidQType; //
  420. QUEUEHANDLE hQueue;
  421. QUEUEHANDLE hAdminQueue;
  422. BOOL fAllowReceives;
  423. RPC_CHAR wsMachine[MAX_COMPUTERNAME_LEN];
  424. RPC_CHAR wsQName[MQ_MAX_Q_NAME_LEN];
  425. RPC_CHAR wsQPathName[MAX_PATHNAME_LEN];
  426. RPC_CHAR wsQFormat[MAX_FORMAT_LEN];
  427. RPC_CHAR wsAdminQFormat[MAX_FORMAT_LEN];
  428. ULONG ulDelivery;
  429. ULONG ulPriority;
  430. ULONG ulJournaling;
  431. ULONG ulTimeToReachQueue; // Seconds.
  432. ULONG ulTimeToReceive; // Seconds.
  433. BOOL fAck;
  434. BOOL fAuthenticate; // Server security tracking.
  435. BOOL fEncrypt;
  436. ULONG ulPrivacyLevel; // Server security tracking.
  437. //
  438. // Normally FALSE, set to true by a thread which is submitting
  439. // new IOs on the endpoint.
  440. //
  441. LONG fSubmittingIos;
  442. //
  443. // Current number of WS_DATAGRAM's submitted on this endpoint.
  444. // Must be changed via InterlockedInc/Dec. The count of
  445. // non-null entries in aIdleDatagrams.
  446. //
  447. LONG cPendingIos;
  448. //
  449. // If cPendingIos is less than the minimum then recvs on any idle
  450. // WS_DATAGRAMs should be posted.
  451. //
  452. // const after initialization.
  453. //
  454. LONG cMinimumIos;
  455. //
  456. // The number of WS_DATAGRAMs available for this endpoint to use.
  457. //
  458. // const after initialization.
  459. //
  460. LONG cMaximumIos;
  461. //
  462. // Array of cMaxIos datagrams. NULL in sync endpoints.
  463. //
  464. PMQ_DATAGRAM aDatagrams;
  465. };
  466. #endif
  467. //
  468. // Structure allocated by the runtime and associated with
  469. // a pending send operation.
  470. //
  471. struct CO_SEND_CONTEXT
  472. {
  473. //
  474. // Overlapped object associated with the pending async write.
  475. //
  476. BASE_OVERLAPPED Write;
  477. //
  478. // The buffer which is currently being written
  479. //
  480. BUFFER pWriteBuffer;
  481. //
  482. // Size of the write buffer (as far as we know)
  483. //
  484. DWORD maxWriteBuffer;
  485. };
  486. #if defined(_ALPHA_)
  487. #ifdef __cplusplus
  488. extern "C" { __int64 __asm(char *,...); };
  489. #pragma intrinsic(__asm)
  490. #endif
  491. #define MBInstruction __asm("mb")
  492. #endif
  493. //
  494. // Connection objects are used for async reads (future: writes)
  495. // from a single client based on that client's connection to
  496. // this server.
  497. //
  498. // There maybe 100's or 1000's of connection objects allocated.
  499. //
  500. class BASE_CONNECTION : public BASE_ASYNC_OBJECT
  501. {
  502. public:
  503. BASE_CONNECTION(void)
  504. {
  505. }
  506. void
  507. Initialize (
  508. void
  509. );
  510. //
  511. // The socket (or handle) of the client connection.
  512. // We use a union to avoid type casting this everywhere.
  513. //
  514. union {
  515. SOCKET Socket;
  516. HANDLE Handle;
  517. } Conn;
  518. private:
  519. //
  520. // Incremented when a thread is just about to start an IO, just
  521. // before it checks fAborted. The aborting thread must wait for
  522. // this to reach 0 before closing the connection.
  523. //
  524. LONG StartingWriteIo;
  525. LONG StartingReadIo;
  526. public:
  527. //
  528. // We use a heuristic for choosing the size of receives to post. This
  529. // starts are CO_MIN_RECV size and is increased as we see larger
  530. // IOs on the connection.
  531. UINT iPostSize;
  532. //
  533. // The size of the outstanding read buffer.
  534. //
  535. DWORD maxReadBuffer;
  536. //
  537. // The number of bytes in pReadBuffer that where read
  538. // as part of a previous read.
  539. //
  540. UINT iLastRead;
  541. //
  542. // Overlapped object associated with the pending async read
  543. //
  544. BASE_OVERLAPPED Read;
  545. //
  546. // A buffer for the outstanding read of maxReadBuffer bytes.
  547. // Also used a flag, if 0 then no read is pending.
  548. //
  549. BUFFER pReadBuffer;
  550. inline void StartingWriteIO(void)
  551. {
  552. InterlockedIncrement(&StartingWriteIo);
  553. }
  554. inline void StartingReadIO(void)
  555. {
  556. #if defined(i386) || defined (_ALPHA_)
  557. // if we are the first, we know there won't be other guys around
  558. if (StartingReadIo == 0)
  559. {
  560. StartingReadIo = 1;
  561. #if defined (_ALPHA_)
  562. MBInstruction;
  563. #endif
  564. }
  565. else
  566. {
  567. // there may be other guys around - be safe
  568. InterlockedIncrement(&StartingReadIo);
  569. }
  570. #else
  571. InterlockedIncrement(&StartingReadIo);
  572. #endif
  573. }
  574. inline void StartingOtherIO(void)
  575. {
  576. // we use the StartingWriteIo because it
  577. // doesn't shortcut transition from 0 to 1st
  578. InterlockedIncrement(&StartingWriteIo);
  579. }
  580. inline void WriteIOFinished(void)
  581. {
  582. InterlockedDecrement(&StartingWriteIo);
  583. }
  584. // ********************* NOTE *************************************
  585. // After you return from this function, if the read is successful, you
  586. // can no longer touch the connection (transport level or runtime) -
  587. // it may have been destroyed
  588. inline void ReadIOFinished(void)
  589. {
  590. InterlockedDecrement(&StartingReadIo);
  591. }
  592. inline void OtherIOFinished(void)
  593. {
  594. InterlockedDecrement(&StartingWriteIo);
  595. }
  596. inline BOOL IsIoStarting(void)
  597. {
  598. return StartingWriteIo || StartingReadIo;
  599. }
  600. inline void InitIoCounter(void)
  601. {
  602. StartingWriteIo = 0;
  603. StartingReadIo = 0;
  604. }
  605. virtual RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  606. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  607. LPOVERLAPPED lpOverlapped) = 0;
  608. virtual RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  609. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  610. LPOVERLAPPED lpOverlapped) = 0;
  611. virtual RPC_STATUS ProcessRead(IN DWORD bytes, OUT BUFFER *pBuffer,
  612. OUT PUINT pBufferLength);
  613. virtual RPC_STATUS Abort(void) = 0;
  614. };
  615. typedef BASE_CONNECTION *PCONNECTION;
  616. RPC_STATUS
  617. UTIL_ReadFile(
  618. IN HANDLE hFile,
  619. IN LPVOID lpBuffer,
  620. IN DWORD nNumberOfBytesToRead,
  621. OUT LPDWORD lpNumberOfBytesRead,
  622. IN OUT LPOVERLAPPED lpOverlapped
  623. );
  624. RPC_STATUS
  625. UTIL_WriteFile(
  626. IN HANDLE hFile,
  627. IN LPCVOID lpBuffer,
  628. IN DWORD nNumberOfBytesToWrite,
  629. OUT LPDWORD lpNumberOfBytesWritten,
  630. IN OUT LPOVERLAPPED lpOverlapped
  631. );
  632. class NMP_CONNECTION : public BASE_CONNECTION
  633. {
  634. public:
  635. //
  636. // Pointer to my address used to store any extra pipe
  637. // instance when closed.
  638. //
  639. PNMP_ADDRESS pAddress;
  640. RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  641. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  642. LPOVERLAPPED lpOverlapped)
  643. {
  644. return UTIL_ReadFile(hFile, lpBuffer, nNumberOfBytesToRead,
  645. lpNumberOfBytesRead, lpOverlapped);
  646. }
  647. RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  648. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  649. LPOVERLAPPED lpOverlapped)
  650. {
  651. return UTIL_WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite,
  652. lpNumberOfBytesWritten, lpOverlapped);
  653. }
  654. virtual RPC_STATUS Abort(void);
  655. };
  656. typedef NMP_CONNECTION *PNMP_CONNECTION;
  657. class WS_CONNECTION : public BASE_CONNECTION
  658. {
  659. public:
  660. WS_CONNECTION(void)
  661. {
  662. }
  663. //
  664. // The address of the client is returned as part of
  665. // the connection and saved here to support
  666. // *_QueryClientAddress().
  667. //
  668. WS_SOCKADDR saClientAddress;
  669. WS_ADDRESS *pAddress;
  670. virtual RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  671. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  672. LPOVERLAPPED lpOverlapped);
  673. virtual RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  674. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  675. LPOVERLAPPED lpOverlapped);
  676. virtual RPC_STATUS Abort(void);
  677. };
  678. typedef WS_CONNECTION *PWS_CONNECTION;
  679. class SAN_CONNECTION
  680. {
  681. public:
  682. SAN_CONNECTION(void)
  683. {
  684. }
  685. RPC_STATUS SANReceive(HANDLE hFile, LPVOID lpBuffer,
  686. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  687. LPOVERLAPPED lpOverlapped);
  688. RPC_STATUS SANSend(HANDLE hFile, LPCVOID lpBuffer,
  689. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  690. LPOVERLAPPED lpOverlapped);
  691. private:
  692. DWORD m_dwFlags;
  693. };
  694. class HTTP2SocketTransportChannel; // forward
  695. class WS_HTTP2_CONNECTION;
  696. typedef RPC_STATUS
  697. (RPC_ENTRY *HTTP2_READ_HEADER)
  698. (
  699. IN WS_HTTP2_CONNECTION *Connection,
  700. IN ULONG BytesRead,
  701. OUT ULONG *NewBytesRead
  702. );
  703. /*++
  704. Routine Description:
  705. Read a channel HTTP header (usually some string). In success
  706. case, there is real data in Connection->pReadBuffer. The
  707. number of bytes there is in NewBytesRead
  708. Arguments:
  709. Connection - the connection on which the header arrived.
  710. BytesRead - the bytes received from the net
  711. NewBytesRead - the bytes read from the channel (success only)
  712. Return Value:
  713. RPC_S_OK or other RPC_S_* errors for error
  714. --*/
  715. class WS_HTTP2_CONNECTION : public WS_CONNECTION, public SAN_CONNECTION
  716. {
  717. public:
  718. HTTP2SocketTransportChannel *Channel;
  719. RPC_STATUS ProcessReceiveFailed (IN RPC_STATUS EventStatus);
  720. virtual RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  721. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  722. LPOVERLAPPED lpOverlapped);
  723. virtual RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  724. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  725. LPOVERLAPPED lpOverlapped);
  726. RPC_STATUS ProcessSendComplete (
  727. IN RPC_STATUS EventStatus,
  728. IN CO_SEND_CONTEXT *SendContext
  729. );
  730. // no-op for compatibility with common transport layer
  731. virtual RPC_STATUS ProcessRead(
  732. IN DWORD bytes,
  733. OUT BUFFER *pBuffer,
  734. OUT PUINT pBufferLength
  735. );
  736. // the actual read
  737. RPC_STATUS ProcessReceiveComplete(
  738. IN DWORD bytes,
  739. OUT BUFFER *pBuffer,
  740. OUT PUINT pBufferLength
  741. );
  742. void Initialize (
  743. void
  744. );
  745. void Free (
  746. void
  747. );
  748. // no-op for HTTP2 connections. They get
  749. // aborted from RealAbort
  750. virtual RPC_STATUS Abort(void);
  751. // actual code to abort the connection
  752. void RealAbort(void);
  753. BOOL HeaderRead;
  754. HTTP2_READ_HEADER ReadHeaderFn;
  755. void *RuntimeConnectionPtr; // the transport connection from
  756. // runtime perspective. Never called
  757. // directly - just a token to pass
  758. // to runtime
  759. // In HTTP2ServerVirtualConnection::AllocateAndInitializeInChannel and ...OutChannel
  760. // we have very special code that parties on a connection aborting and freeing
  761. // the channel stack without freeing the connection. We use this flag there
  762. // to ensure that the free for the connection obejct is ignored.
  763. BOOL fIgnoreFree;
  764. };
  765. // WS_HTTP2_INITIAL_CONNECTION - a version of WS_HTTP2_CONNECTION that
  766. // is used before the type of connection HTTP2 or HTTP is known on the
  767. // server. It has the capability to recognize the first packet and morph
  768. // into WS_HTTP2_CONNECTION (for HTTP2) or WS_CONNECTION (for HTTP)
  769. class WS_HTTP2_INITIAL_CONNECTION : public WS_HTTP2_CONNECTION
  770. {
  771. public:
  772. virtual RPC_STATUS ProcessRead(
  773. IN DWORD bytes,
  774. OUT BUFFER *pBuffer,
  775. OUT PUINT pBufferLength
  776. );
  777. virtual RPC_STATUS Abort(void);
  778. };
  779. class WS_CLIENT_CONNECTION : public WS_CONNECTION
  780. {
  781. public:
  782. // Additional state needed in client-side sync calls on TCP/IP to
  783. // handle shutdowns.
  784. //
  785. // State of the connection, used to keep track of shutdowns for TCP/IP.
  786. // Reset after a recv() call so that the next send operation will
  787. // check for shutdowns.
  788. //
  789. BOOL fCallStarted;
  790. //
  791. // True if we received a shutdown packet during the last send operation.
  792. //
  793. BOOL fShutdownReceived;
  794. //
  795. // True if we posted a receive to check for a shutdown the receive
  796. // is (was) still pending.
  797. //
  798. BOOL fReceivePending;
  799. //
  800. // The time of the last RPC call finished on this connection. This
  801. // is used to determine if a shutdown check is needed.
  802. //
  803. DWORD dwLastCallTime;
  804. //
  805. // Com timeout
  806. //
  807. UINT Timeout;
  808. };
  809. typedef WS_CLIENT_CONNECTION *PWS_CCONNECTION;
  810. class WS_SAN_CONNECTION : public WS_CONNECTION, public SAN_CONNECTION
  811. {
  812. RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  813. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  814. LPOVERLAPPED lpOverlapped)
  815. {
  816. return SANReceive(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
  817. }
  818. RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  819. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  820. LPOVERLAPPED lpOverlapped)
  821. {
  822. return SANSend(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
  823. }
  824. };
  825. class WS_SAN_CLIENT_CONNECTION : public WS_CLIENT_CONNECTION, public SAN_CONNECTION
  826. {
  827. RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  828. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  829. LPOVERLAPPED lpOverlapped)
  830. {
  831. return SANReceive(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
  832. }
  833. RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  834. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  835. LPOVERLAPPED lpOverlapped)
  836. {
  837. return SANSend(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
  838. }
  839. };
  840. #ifdef NETBIOS_ON
  841. class NB_CONNECTION : public WS_CONNECTION
  842. {
  843. public:
  844. // In order to support the old Netbios (3.1/Dos) style programming
  845. // interface netbios fragments sent from the client to the server
  846. // must contain a sequence number. It allowed for in-order delivery
  847. // of fragments on such a system. While not required today it is still
  848. // part of the wire protocol. The sequence numbers must be incremented
  849. // on each fragment sent. The sequence number is reset after each call.
  850. // REVIEW: When multiple async calls are outstanding the sequence number
  851. // will be wrong.
  852. ULONG SequenceNumber;
  853. // the next members need to be aligned in a way that will ensure that
  854. // fReceivePending is at the same offset as fReceivePending in
  855. // WS_CLIENT_CONNECTION. Some functions manipulate them in the same
  856. // way and we need to make sure they are consistent. This is just
  857. // documenting an existing code idiosyncracy
  858. BOOL Reserved[1];
  859. BOOL fReceivePending;
  860. virtual RPC_STATUS ProcessRead(IN DWORD bytes, OUT BUFFER *pBuffer,
  861. OUT PUINT pBufferLength);
  862. };
  863. typedef NB_CONNECTION *PNB_CONNECTION;
  864. class NB_SAN_CONNECTION : public NB_CONNECTION, SAN_CONNECTION
  865. {
  866. RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  867. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  868. LPOVERLAPPED lpOverlapped)
  869. {
  870. return SANReceive(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
  871. }
  872. RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  873. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  874. LPOVERLAPPED lpOverlapped)
  875. {
  876. return SANSend(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
  877. }
  878. };
  879. #endif
  880. //
  881. // Datagram object represent both addresses and connections for
  882. // datagram. Since all client IO is multiplexed through a single
  883. // port there are not per client objects.
  884. //
  885. // There maybe O(# processors) of these objects allocated for
  886. // each address (endpoint). This is not very many.
  887. //
  888. struct BASE_DATAGRAM : BASE_ASYNC_OBJECT
  889. {
  890. //
  891. // The endpoint on which requests will be received. This will
  892. // actually be either a WS_DATAGRAM_ENDPOINT or a MQ_DATAGRAM_ENDPOINT.
  893. //
  894. BASE_ADDRESS *pEndpoint;
  895. };
  896. struct WS_DATAGRAM : BASE_DATAGRAM
  897. {
  898. // If FALSE then the datagram is available to submit a recv on.
  899. BOOL Busy;
  900. // Size of the address received (ignored but needs to be
  901. // writeable during the async IO completion.)
  902. INT cRecvAddr;
  903. // Address object to receive the remote/local address of the datagram.
  904. // The object itself is in the runtime packet object
  905. DatagramTransportPair *AddressPair;
  906. // The IO buffer used to receive the packet.
  907. WSABUF Packet;
  908. // Async IO control information
  909. BASE_OVERLAPPED Read;
  910. // The message used to control the operation
  911. WSAMSG Msg;
  912. // The control information for the message
  913. char MessageAncillaryData[WSA_CMSG_SPACE(sizeof(in_pktinfo))];
  914. };
  915. typedef WS_DATAGRAM *PWS_DATAGRAM;
  916. #ifdef NCADG_MQ_ON
  917. struct MQ_DATAGRAM : BASE_DATAGRAM
  918. {
  919. // If FALSE then the datagram is available to submit a recv on.
  920. BOOL Busy;
  921. // Size of the address received.
  922. INT cRecvAddr;
  923. // Address object to receive the source address of the datagram.
  924. MQ_ADDRESS *pAddress;
  925. // The IO buffer used to receive the packet.
  926. ULONG dwPacketSize;
  927. UCHAR *pPacket;
  928. // Async IO control information
  929. MQ_OVERLAPPED Read;
  930. };
  931. typedef MQ_DATAGRAM *PMQ_DATAGRAM;
  932. #endif
  933. //
  934. // Finds the async object based on the overlapped structure an io
  935. // completed on.
  936. //
  937. inline PBASE_OVERLAPPED FindOverlapped(LPOVERLAPPED pol)
  938. {
  939. return(CONTAINING_RECORD(pol, BASE_OVERLAPPED, ol));
  940. }
  941. inline PREQUEST FindRequest(LPOVERLAPPED pol)
  942. {
  943. return (pol) ? (FindOverlapped(pol)->pAsyncObject) : 0;
  944. }
  945. //
  946. // Connection protocol loaders
  947. //
  948. const RPC_CONNECTION_TRANSPORT *WS_TransportLoad(PROTOCOL_ID);
  949. #ifdef NETBIOS_ON
  950. const RPC_CONNECTION_TRANSPORT *NB_TransportLoad(PROTOCOL_ID);
  951. #endif
  952. const RPC_CONNECTION_TRANSPORT *NMP_TransportLoad();
  953. //
  954. // Datagram protocol loaders
  955. //
  956. const RPC_DATAGRAM_TRANSPORT *DG_TransportLoad(PROTOCOL_ID);
  957. //
  958. // Misc functions
  959. //
  960. extern RPC_STATUS IP_BuildAddressVector(
  961. OUT NETWORK_ADDRESS_VECTOR **,
  962. IN ULONG NICFlags,
  963. IN RPC_CHAR *NetworkAddress OPTIONAL,
  964. IN WS_ADDRESS *Address OPTIONAL);
  965. extern RPC_STATUS CDP_BuildAddressVector(NETWORK_ADDRESS_VECTOR **);
  966. extern RPC_ADDRESS_CHANGE_FN * SpxAddressChangeFn;
  967. //
  968. // IP name resolver
  969. //
  970. const int IP_RETAIL_BUFFER_SIZE = 3*0x38;
  971. const int IP_BUFFER_SIZE = DEBUG_MIN(1, IP_RETAIL_BUFFER_SIZE);
  972. typedef enum tagIPVersionToUse
  973. {
  974. ipvtuIPv4 = 0,
  975. ipvtuIPv6,
  976. ipvtuIPAny
  977. } IPVersionToUse;
  978. typedef enum tagClientOrServer
  979. {
  980. cosClient,
  981. cosServer
  982. } ClientOrServer;
  983. class IP_ADDRESS_RESOLVER
  984. /*++
  985. Class Description:
  986. Converts the string address to an IP address.
  987. --*/
  988. {
  989. public:
  990. IP_ADDRESS_RESOLVER(
  991. IN RPC_CHAR *Name,
  992. IN ClientOrServer cos,
  993. IN IPVersionToUse IPvToUse
  994. )
  995. /*++
  996. Arguments:
  997. Name - The name (dotted ip address or DNS name) to resolve.
  998. fUseIPv6 - if TRUE, an IPv6 address will be resolved. If
  999. FALSE, an IPv4 address will be resolved.
  1000. --*/
  1001. {
  1002. if (Name && (*Name == 0))
  1003. Name = 0;
  1004. this->Name = Name;
  1005. this->IPvToUse = IPvToUse;
  1006. this->cos = cos;
  1007. AddrInfo = NULL;
  1008. LoopbacksReturned = 0;
  1009. CurrentAddrInfo = NULL;
  1010. RpcpMemorySet(&Hint, 0, sizeof(ADDRINFO));
  1011. }
  1012. inline RPC_STATUS
  1013. NextAddress(
  1014. OUT SOCKADDR_IN *pAddress
  1015. )
  1016. {
  1017. ASSERT(IPvToUse == ipvtuIPv4);
  1018. return NextAddress((SOCKADDR_STORAGE *)pAddress);
  1019. }
  1020. RPC_STATUS
  1021. NextAddress(
  1022. OUT SOCKADDR_STORAGE *pAddress
  1023. );
  1024. ~IP_ADDRESS_RESOLVER();
  1025. private:
  1026. RPC_CHAR *Name;
  1027. IPVersionToUse IPvToUse;
  1028. ADDRINFO *AddrInfo; // the start of the addr info list. NULL if enumeration hasn't
  1029. // started
  1030. ADDRINFO *CurrentAddrInfo; // the current element in the addr info list enumeration. NULL
  1031. // if enumeration hasn't started or has finished.
  1032. ClientOrServer cos;
  1033. ADDRINFO Hint;
  1034. int LoopbacksReturned;
  1035. };
  1036. //
  1037. // Common functions exported by each protocol
  1038. //
  1039. extern RPC_STATUS RPC_ENTRY
  1040. COMMON_ProcessCalls(
  1041. IN INT Timeout,
  1042. OUT RPC_TRANSPORT_EVENT *pEvent,
  1043. OUT RPC_STATUS *pEventStatus,
  1044. OUT PVOID *ppEventContext,
  1045. OUT UINT *pBufferLength,
  1046. OUT BUFFER *pBuffer,
  1047. OUT PVOID *ppSourceContext
  1048. );
  1049. extern RPC_STATUS
  1050. COMMON_PostNonIoEvent(
  1051. RPC_TRANSPORT_EVENT Event,
  1052. DWORD Type,
  1053. PVOID Context
  1054. );
  1055. extern void
  1056. COMMON_RemoveAddress (
  1057. IN BASE_ADDRESS *Address
  1058. );
  1059. extern RPC_STATUS RPC_ENTRY
  1060. COMMON_TowerConstruct(
  1061. IN PCHAR Protseq,
  1062. IN PCHAR NetworkAddress,
  1063. IN PCHAR Endpoint,
  1064. OUT PUSHORT Floors,
  1065. OUT PULONG ByteCount,
  1066. OUT PUCHAR *Tower
  1067. );
  1068. extern RPC_STATUS
  1069. COMMON_TowerExplode(
  1070. IN BYTE *Tower,
  1071. IN BYTE *UpperBound,
  1072. IN ULONG RemainingFloors,
  1073. OUT PCHAR *Protseq,
  1074. OUT PCHAR *NetworkAddress,
  1075. OUT PCHAR *Endpoint
  1076. );
  1077. extern VOID RPC_ENTRY
  1078. COMMON_ServerCompleteListen(
  1079. IN RPC_TRANSPORT_ADDRESS
  1080. );
  1081. #ifndef NO_PLUG_AND_PLAY
  1082. extern VOID RPC_ENTRY
  1083. COMMON_ListenForPNPNotifications (
  1084. );
  1085. extern VOID RPC_ENTRY
  1086. COMMON_StartPnpNotifications (
  1087. );
  1088. #endif
  1089. // Internal to transport interface
  1090. extern RPC_STATUS
  1091. COMMON_PrepareNewHandle(
  1092. IN HANDLE hAdd
  1093. );
  1094. extern VOID
  1095. COMMON_AddressManager(
  1096. IN BASE_ADDRESS *
  1097. );
  1098. extern RPC_STATUS RPC_ENTRY
  1099. WS_Abort(
  1100. IN RPC_TRANSPORT_CONNECTION Connection
  1101. );
  1102. extern RPC_STATUS
  1103. WS_ReactivateAddress (
  1104. IN WS_ADDRESS *pAddress,
  1105. IN BOOL fResetAddressListEntries = TRUE OPTIONAL
  1106. );
  1107. extern VOID
  1108. WS_DeactivateAddress (
  1109. IN WS_ADDRESS *pAddress
  1110. );
  1111. extern RPC_STATUS
  1112. DG_ReactivateAddress (
  1113. IN WS_DATAGRAM_ENDPOINT *pAddress
  1114. );
  1115. extern VOID
  1116. DG_DeactivateAddress (
  1117. IN WS_DATAGRAM_ENDPOINT *pAddress
  1118. );
  1119. inline
  1120. void
  1121. TransConnectionFreePacket(
  1122. RPC_TRANSPORT_CONNECTION ThisConnection,
  1123. BUFFER Ptr
  1124. )
  1125. {
  1126. I_RpcTransConnectionFreePacket(ThisConnection, Ptr);
  1127. }
  1128. inline
  1129. BUFFER
  1130. TransConnectionAllocatePacket(
  1131. RPC_TRANSPORT_CONNECTION ThisConnection,
  1132. UINT Size
  1133. )
  1134. {
  1135. return (I_RpcTransConnectionAllocatePacket(ThisConnection, Size));
  1136. }
  1137. inline
  1138. RPC_STATUS
  1139. TransConnectionReallocPacket(
  1140. IN RPC_TRANSPORT_CONNECTION ThisConnection,
  1141. IN BUFFER *ppBuffer,
  1142. IN UINT OldSize,
  1143. IN UINT NewSize
  1144. )
  1145. {
  1146. return(I_RpcTransConnectionReallocPacket(ThisConnection, ppBuffer, OldSize, NewSize));
  1147. }
  1148. #define InitReadEvent(p) \
  1149. hEvent = I_RpcTransGetThreadEvent(); \
  1150. \
  1151. p->Read.ol.hEvent = (HANDLE)((ULONG_PTR)hEvent | 0x1)
  1152. #define ASSERT_READ_EVENT_IS_THERE(p) \
  1153. ASSERT( p->Read.ol.hEvent == (HANDLE) ((ULONG_PTR)I_RpcTransGetThreadEvent() | 0x1))
  1154. extern HMODULE hWinsock2;
  1155. #endif // __TRANS_HXX