Source code of Windows XP (NT5)
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.

1357 lines
33 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. };
  322. inline DWORD
  323. GetProtocolMultiplier (
  324. IN WS_ADDRESS *Address
  325. )
  326. {
  327. #ifdef NETBIOS_ON
  328. return Address->ProtocolMultiplier;
  329. #else
  330. return 1;
  331. #endif
  332. }
  333. inline void
  334. SetProtocolMultiplier (
  335. IN WS_ADDRESS *Address,
  336. IN DWORD ProtocolMultiplier
  337. )
  338. {
  339. #ifdef NETBIOS_ON
  340. Address->ProtocolMultiplier = ProtocolMultiplier;
  341. #endif
  342. }
  343. typedef WS_ADDRESS *PWS_ADDRESS;
  344. struct WS_DATAGRAM;
  345. typedef WS_DATAGRAM *PWS_DATAGRAM;
  346. struct WS_DATAGRAM_ENDPOINT : BASE_ADDRESS
  347. {
  348. // WS_DATAGRAM_ENDPOINTs represent either a client or server
  349. // port. There will be a small number of these on servers and
  350. // O(N) active threads on sync clients.
  351. //
  352. // The socket we're listen on.
  353. //
  354. SOCKET Socket;
  355. //
  356. // Normally FALSE, set to true by a thread which is submitting
  357. // new IOs on the endpoint.
  358. //
  359. LONG fSubmittingIos;
  360. //
  361. // Current number of WS_DATAGRAM's submitted on this endpoint.
  362. // Must be changed via InterlockedInc/Dec. The count of
  363. // non-null entries in aIdleDatagrams.
  364. //
  365. LONG cPendingIos;
  366. //
  367. // If cPendingIos is less than the minimum then recvs on any idle
  368. // WS_DATAGRAMs should be posted.
  369. //
  370. // const after initialization.
  371. //
  372. LONG cMinimumIos;
  373. //
  374. // The number of WS_DATAGRAMs available for this endpoint to use.
  375. //
  376. // const after initialization.
  377. //
  378. LONG cMaximumIos;
  379. //
  380. // Array of cMaxIos datagrams. NULL in sync endpoints.
  381. //
  382. PWS_DATAGRAM aDatagrams;
  383. //
  384. // Client or Server ?
  385. //
  386. BOOL fClient;
  387. //
  388. // Sync or Async ?
  389. //
  390. BOOL fAsync;
  391. //
  392. // Sockaddr
  393. //
  394. WS_SOCKADDR ListenAddr;
  395. };
  396. #ifdef NCADG_MQ_ON
  397. struct MQ_DATAGRAM;
  398. typedef MQ_DATAGRAM *PMQ_DATAGRAM;
  399. struct MQ_DATAGRAM_ENDPOINT : BASE_ADDRESS
  400. {
  401. // MQ_DATAGRAM_ENDPOINTs represent either a client or server
  402. // port. There will be a small number of these on servers and
  403. // O(N) active threads on sync clients.
  404. //
  405. // The queue we're listen on.
  406. //
  407. UUID uuidQType; //
  408. QUEUEHANDLE hQueue;
  409. QUEUEHANDLE hAdminQueue;
  410. BOOL fAllowReceives;
  411. RPC_CHAR wsMachine[MAX_COMPUTERNAME_LEN];
  412. RPC_CHAR wsQName[MQ_MAX_Q_NAME_LEN];
  413. RPC_CHAR wsQPathName[MAX_PATHNAME_LEN];
  414. RPC_CHAR wsQFormat[MAX_FORMAT_LEN];
  415. RPC_CHAR wsAdminQFormat[MAX_FORMAT_LEN];
  416. ULONG ulDelivery;
  417. ULONG ulPriority;
  418. ULONG ulJournaling;
  419. ULONG ulTimeToReachQueue; // Seconds.
  420. ULONG ulTimeToReceive; // Seconds.
  421. BOOL fAck;
  422. BOOL fAuthenticate; // Server security tracking.
  423. BOOL fEncrypt;
  424. ULONG ulPrivacyLevel; // Server security tracking.
  425. //
  426. // Normally FALSE, set to true by a thread which is submitting
  427. // new IOs on the endpoint.
  428. //
  429. LONG fSubmittingIos;
  430. //
  431. // Current number of WS_DATAGRAM's submitted on this endpoint.
  432. // Must be changed via InterlockedInc/Dec. The count of
  433. // non-null entries in aIdleDatagrams.
  434. //
  435. LONG cPendingIos;
  436. //
  437. // If cPendingIos is less than the minimum then recvs on any idle
  438. // WS_DATAGRAMs should be posted.
  439. //
  440. // const after initialization.
  441. //
  442. LONG cMinimumIos;
  443. //
  444. // The number of WS_DATAGRAMs available for this endpoint to use.
  445. //
  446. // const after initialization.
  447. //
  448. LONG cMaximumIos;
  449. //
  450. // Array of cMaxIos datagrams. NULL in sync endpoints.
  451. //
  452. PMQ_DATAGRAM aDatagrams;
  453. };
  454. #endif
  455. //
  456. // Structure allocated by the runtime and associated with
  457. // a pending send operation.
  458. //
  459. struct CO_SEND_CONTEXT
  460. {
  461. //
  462. // Overlapped object associated with the pending async write.
  463. //
  464. BASE_OVERLAPPED Write;
  465. //
  466. // The buffer which is currently being written
  467. //
  468. BUFFER pWriteBuffer;
  469. //
  470. // Size of the write buffer (as far as we know)
  471. //
  472. DWORD maxWriteBuffer;
  473. };
  474. #if defined(_ALPHA_)
  475. #ifdef __cplusplus
  476. extern "C" { __int64 __asm(char *,...); };
  477. #pragma intrinsic(__asm)
  478. #endif
  479. #define MBInstruction __asm("mb")
  480. #endif
  481. //
  482. // Connection objects are used for async reads (future: writes)
  483. // from a single client based on that client's connection to
  484. // this server.
  485. //
  486. // There maybe 100's or 1000's of connection objects allocated.
  487. //
  488. class BASE_CONNECTION : public BASE_ASYNC_OBJECT
  489. {
  490. public:
  491. BASE_CONNECTION(void)
  492. {
  493. }
  494. void
  495. Initialize (
  496. void
  497. );
  498. //
  499. // The socket (or handle) of the client connection.
  500. // We use a union to avoid type casting this everywhere.
  501. //
  502. union {
  503. SOCKET Socket;
  504. HANDLE Handle;
  505. } Conn;
  506. private:
  507. //
  508. // Incremented when a thread is just about to start an IO, just
  509. // before it checks fAborted. The aborting thread must wait for
  510. // this to reach 0 before closing the connection.
  511. //
  512. LONG StartingWriteIo;
  513. LONG StartingReadIo;
  514. public:
  515. //
  516. // We use a heuristic for choosing the size of receives to post. This
  517. // starts are CO_MIN_RECV size and is increased as we see larger
  518. // IOs on the connection.
  519. UINT iPostSize;
  520. //
  521. // The size of the outstanding read buffer.
  522. //
  523. DWORD maxReadBuffer;
  524. //
  525. // The number of bytes in pReadBuffer that where read
  526. // as part of a previous read.
  527. //
  528. UINT iLastRead;
  529. //
  530. // Overlapped object associated with the pending async read
  531. //
  532. BASE_OVERLAPPED Read;
  533. //
  534. // A buffer for the outstanding read of maxReadBuffer bytes.
  535. // Also used a flag, if 0 then no read is pending.
  536. //
  537. BUFFER pReadBuffer;
  538. inline void StartingWriteIO(void)
  539. {
  540. InterlockedIncrement(&StartingWriteIo);
  541. }
  542. inline void StartingReadIO(void)
  543. {
  544. #if defined(i386) || defined (_ALPHA_)
  545. // if we are the first, we know there won't be other guys around
  546. if (StartingReadIo == 0)
  547. {
  548. StartingReadIo = 1;
  549. #if defined (_ALPHA_)
  550. MBInstruction;
  551. #endif
  552. }
  553. else
  554. {
  555. // there may be other guys around - be safe
  556. InterlockedIncrement(&StartingReadIo);
  557. }
  558. #else
  559. InterlockedIncrement(&StartingReadIo);
  560. #endif
  561. }
  562. inline void StartingOtherIO(void)
  563. {
  564. // we use the StartingWriteIo because it
  565. // doesn't shortcut transition from 0 to 1st
  566. InterlockedIncrement(&StartingWriteIo);
  567. }
  568. inline void WriteIOFinished(void)
  569. {
  570. InterlockedDecrement(&StartingWriteIo);
  571. }
  572. // ********************* NOTE *************************************
  573. // After you return from this function, if the read is successful, you
  574. // can no longer touch the connection (transport level or runtime) -
  575. // it may have been destroyed
  576. inline void ReadIOFinished(void)
  577. {
  578. InterlockedDecrement(&StartingReadIo);
  579. }
  580. inline void OtherIOFinished(void)
  581. {
  582. InterlockedDecrement(&StartingWriteIo);
  583. }
  584. inline BOOL IsIoStarting(void)
  585. {
  586. return StartingWriteIo || StartingReadIo;
  587. }
  588. inline void InitIoCounter(void)
  589. {
  590. StartingWriteIo = 0;
  591. StartingReadIo = 0;
  592. }
  593. virtual RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  594. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  595. LPOVERLAPPED lpOverlapped) = 0;
  596. virtual RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  597. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  598. LPOVERLAPPED lpOverlapped) = 0;
  599. virtual RPC_STATUS ProcessRead(IN DWORD bytes, OUT BUFFER *pBuffer,
  600. OUT PUINT pBufferLength);
  601. virtual RPC_STATUS Abort(void) = 0;
  602. };
  603. typedef BASE_CONNECTION *PCONNECTION;
  604. RPC_STATUS
  605. UTIL_ReadFile(
  606. IN HANDLE hFile,
  607. IN LPVOID lpBuffer,
  608. IN DWORD nNumberOfBytesToRead,
  609. OUT LPDWORD lpNumberOfBytesRead,
  610. IN OUT LPOVERLAPPED lpOverlapped
  611. );
  612. RPC_STATUS
  613. UTIL_WriteFile(
  614. IN HANDLE hFile,
  615. IN LPCVOID lpBuffer,
  616. IN DWORD nNumberOfBytesToWrite,
  617. OUT LPDWORD lpNumberOfBytesWritten,
  618. IN OUT LPOVERLAPPED lpOverlapped
  619. );
  620. class NMP_CONNECTION : public BASE_CONNECTION
  621. {
  622. public:
  623. //
  624. // Pointer to my address used to store any extra pipe
  625. // instance when closed.
  626. //
  627. PNMP_ADDRESS pAddress;
  628. RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  629. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  630. LPOVERLAPPED lpOverlapped)
  631. {
  632. return UTIL_ReadFile(hFile, lpBuffer, nNumberOfBytesToRead,
  633. lpNumberOfBytesRead, lpOverlapped);
  634. }
  635. RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  636. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  637. LPOVERLAPPED lpOverlapped)
  638. {
  639. return UTIL_WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite,
  640. lpNumberOfBytesWritten, lpOverlapped);
  641. }
  642. virtual RPC_STATUS Abort(void);
  643. };
  644. typedef NMP_CONNECTION *PNMP_CONNECTION;
  645. class WS_CONNECTION : public BASE_CONNECTION
  646. {
  647. public:
  648. WS_CONNECTION(void)
  649. {
  650. }
  651. //
  652. // The address of the client is returned as part of
  653. // the connection and saved here to support
  654. // *_QueryClientAddress().
  655. //
  656. WS_SOCKADDR saClientAddress;
  657. WS_ADDRESS *pAddress;
  658. virtual RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  659. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  660. LPOVERLAPPED lpOverlapped);
  661. virtual RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  662. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  663. LPOVERLAPPED lpOverlapped);
  664. virtual RPC_STATUS Abort(void);
  665. };
  666. typedef WS_CONNECTION *PWS_CONNECTION;
  667. class SAN_CONNECTION
  668. {
  669. public:
  670. SAN_CONNECTION(void)
  671. {
  672. }
  673. RPC_STATUS SANReceive(HANDLE hFile, LPVOID lpBuffer,
  674. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  675. LPOVERLAPPED lpOverlapped);
  676. RPC_STATUS SANSend(HANDLE hFile, LPCVOID lpBuffer,
  677. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  678. LPOVERLAPPED lpOverlapped);
  679. private:
  680. DWORD m_dwFlags;
  681. };
  682. class HTTP2SocketTransportChannel; // forward
  683. class WS_HTTP2_CONNECTION;
  684. typedef RPC_STATUS
  685. (RPC_ENTRY *HTTP2_READ_HEADER)
  686. (
  687. IN WS_HTTP2_CONNECTION *Connection,
  688. IN ULONG BytesRead,
  689. OUT ULONG *NewBytesRead
  690. );
  691. /*++
  692. Routine Description:
  693. Read a channel HTTP header (usually some string). In success
  694. case, there is real data in Connection->pReadBuffer. The
  695. number of bytes there is in NewBytesRead
  696. Arguments:
  697. Connection - the connection on which the header arrived.
  698. BytesRead - the bytes received from the net
  699. NewBytesRead - the bytes read from the channel (success only)
  700. Return Value:
  701. RPC_S_OK or other RPC_S_* errors for error
  702. --*/
  703. class WS_HTTP2_CONNECTION : public WS_CONNECTION, public SAN_CONNECTION
  704. {
  705. public:
  706. HTTP2SocketTransportChannel *Channel;
  707. RPC_STATUS ProcessReceiveFailed (IN RPC_STATUS EventStatus);
  708. virtual RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  709. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  710. LPOVERLAPPED lpOverlapped);
  711. virtual RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  712. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  713. LPOVERLAPPED lpOverlapped);
  714. RPC_STATUS ProcessSendComplete (
  715. IN RPC_STATUS EventStatus,
  716. IN CO_SEND_CONTEXT *SendContext
  717. );
  718. // no-op for compatibility with common transport layer
  719. virtual RPC_STATUS ProcessRead(
  720. IN DWORD bytes,
  721. OUT BUFFER *pBuffer,
  722. OUT PUINT pBufferLength
  723. );
  724. // the actual read
  725. RPC_STATUS ProcessReceiveComplete(
  726. IN DWORD bytes,
  727. OUT BUFFER *pBuffer,
  728. OUT PUINT pBufferLength
  729. );
  730. void Initialize (
  731. void
  732. );
  733. void Free (
  734. void
  735. );
  736. // no-op for HTTP2 connections. They get
  737. // aborted from RealAbort
  738. virtual RPC_STATUS Abort(void);
  739. // actual code to abort the connection
  740. void RealAbort(void);
  741. BOOL HeaderRead;
  742. HTTP2_READ_HEADER ReadHeaderFn;
  743. void *RuntimeConnectionPtr; // the transport connection from
  744. // runtime perspective. Never called
  745. // directly - just a token to pass
  746. // to runtime
  747. };
  748. // WS_HTTP2_INITIAL_CONNECTION - a version of WS_HTTP2_CONNECTION that
  749. // is used before the type of connection HTTP2 or HTTP is known on the
  750. // server. It has the capability to recognize the first packet and morph
  751. // into WS_HTTP2_CONNECTION (for HTTP2) or WS_CONNECTION (for HTTP)
  752. class WS_HTTP2_INITIAL_CONNECTION : public WS_HTTP2_CONNECTION
  753. {
  754. public:
  755. virtual RPC_STATUS ProcessRead(
  756. IN DWORD bytes,
  757. OUT BUFFER *pBuffer,
  758. OUT PUINT pBufferLength
  759. );
  760. virtual RPC_STATUS Abort(void);
  761. };
  762. class WS_CLIENT_CONNECTION : public WS_CONNECTION
  763. {
  764. public:
  765. // Additional state needed in client-side sync calls on TCP/IP to
  766. // handle shutdowns.
  767. //
  768. // State of the connection, used to keep track of shutdowns for TCP/IP.
  769. // Reset after a recv() call so that the next send operation will
  770. // check for shutdowns.
  771. //
  772. BOOL fCallStarted;
  773. //
  774. // True if we received a shutdown packet during the last send operation.
  775. //
  776. BOOL fShutdownReceived;
  777. //
  778. // True if we posted a receive to check for a shutdown the receive
  779. // is (was) still pending.
  780. //
  781. BOOL fReceivePending;
  782. //
  783. // The time of the last RPC call finished on this connection. This
  784. // is used to determine if a shutdown check is needed.
  785. //
  786. DWORD dwLastCallTime;
  787. //
  788. // Com timeout
  789. //
  790. UINT Timeout;
  791. };
  792. typedef WS_CLIENT_CONNECTION *PWS_CCONNECTION;
  793. class WS_SAN_CONNECTION : public WS_CONNECTION, public SAN_CONNECTION
  794. {
  795. RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  796. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  797. LPOVERLAPPED lpOverlapped)
  798. {
  799. return SANReceive(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
  800. }
  801. RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  802. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  803. LPOVERLAPPED lpOverlapped)
  804. {
  805. return SANSend(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
  806. }
  807. };
  808. class WS_SAN_CLIENT_CONNECTION : public WS_CLIENT_CONNECTION, public SAN_CONNECTION
  809. {
  810. RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  811. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  812. LPOVERLAPPED lpOverlapped)
  813. {
  814. return SANReceive(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
  815. }
  816. RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  817. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  818. LPOVERLAPPED lpOverlapped)
  819. {
  820. return SANSend(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
  821. }
  822. };
  823. #ifdef NETBIOS_ON
  824. class NB_CONNECTION : public WS_CONNECTION
  825. {
  826. public:
  827. // In order to support the old Netbios (3.1/Dos) style programming
  828. // interface netbios fragments sent from the client to the server
  829. // must contain a sequence number. It allowed for in-order delivery
  830. // of fragments on such a system. While not required today it is still
  831. // part of the wire protocol. The sequence numbers must be incremented
  832. // on each fragment sent. The sequence number is reset after each call.
  833. // REVIEW: When multiple async calls are outstanding the sequence number
  834. // will be wrong.
  835. ULONG SequenceNumber;
  836. // the next members need to be aligned in a way that will ensure that
  837. // fReceivePending is at the same offset as fReceivePending in
  838. // WS_CLIENT_CONNECTION. Some functions manipulate them in the same
  839. // way and we need to make sure they are consistent. This is just
  840. // documenting an existing code idiosyncracy
  841. BOOL Reserved[1];
  842. BOOL fReceivePending;
  843. virtual RPC_STATUS ProcessRead(IN DWORD bytes, OUT BUFFER *pBuffer,
  844. OUT PUINT pBufferLength);
  845. };
  846. typedef NB_CONNECTION *PNB_CONNECTION;
  847. class NB_SAN_CONNECTION : public NB_CONNECTION, SAN_CONNECTION
  848. {
  849. RPC_STATUS Receive(HANDLE hFile, LPVOID lpBuffer,
  850. DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
  851. LPOVERLAPPED lpOverlapped)
  852. {
  853. return SANReceive(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
  854. }
  855. RPC_STATUS Send(HANDLE hFile, LPCVOID lpBuffer,
  856. DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
  857. LPOVERLAPPED lpOverlapped)
  858. {
  859. return SANSend(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
  860. }
  861. };
  862. #endif
  863. //
  864. // Datagram object represent both addresses and connections for
  865. // datagram. Since all client IO is multiplexed through a single
  866. // port there are not per client objects.
  867. //
  868. // There maybe O(# processors) of these objects allocated for
  869. // each address (endpoint). This is not very many.
  870. //
  871. struct BASE_DATAGRAM : BASE_ASYNC_OBJECT
  872. {
  873. //
  874. // The endpoint on which requests will be received. This will
  875. // actually be either a WS_DATAGRAM_ENDPOINT or a MQ_DATAGRAM_ENDPOINT.
  876. //
  877. BASE_ADDRESS *pEndpoint;
  878. };
  879. struct WS_DATAGRAM : BASE_DATAGRAM
  880. {
  881. // If FALSE then the datagram is available to submit a recv on.
  882. BOOL Busy;
  883. // Size of the address received (ignored but needs to be
  884. // writeable during the async IO completion.)
  885. INT cRecvAddr;
  886. // Address object to receive the remote/local address of the datagram.
  887. // The object itself is in the runtime packet object
  888. DatagramTransportPair *AddressPair;
  889. // The IO buffer used to receive the packet.
  890. WSABUF Packet;
  891. // Async IO control information
  892. BASE_OVERLAPPED Read;
  893. // The message used to control the operation
  894. WSAMSG Msg;
  895. // The control information for the message
  896. char MessageAncillaryData[WSA_CMSG_SPACE(sizeof(in_pktinfo))];
  897. };
  898. typedef WS_DATAGRAM *PWS_DATAGRAM;
  899. #ifdef NCADG_MQ_ON
  900. struct MQ_DATAGRAM : BASE_DATAGRAM
  901. {
  902. // If FALSE then the datagram is available to submit a recv on.
  903. BOOL Busy;
  904. // Size of the address received.
  905. INT cRecvAddr;
  906. // Address object to receive the source address of the datagram.
  907. MQ_ADDRESS *pAddress;
  908. // The IO buffer used to receive the packet.
  909. ULONG dwPacketSize;
  910. UCHAR *pPacket;
  911. // Async IO control information
  912. MQ_OVERLAPPED Read;
  913. };
  914. typedef MQ_DATAGRAM *PMQ_DATAGRAM;
  915. #endif
  916. //
  917. // Finds the async object based on the overlapped structure an io
  918. // completed on.
  919. //
  920. inline PBASE_OVERLAPPED FindOverlapped(LPOVERLAPPED pol)
  921. {
  922. return(CONTAINING_RECORD(pol, BASE_OVERLAPPED, ol));
  923. }
  924. inline PREQUEST FindRequest(LPOVERLAPPED pol)
  925. {
  926. return (pol) ? (FindOverlapped(pol)->pAsyncObject) : 0;
  927. }
  928. //
  929. // Connection protocol loaders
  930. //
  931. const RPC_CONNECTION_TRANSPORT *WS_TransportLoad(PROTOCOL_ID);
  932. #ifdef NETBIOS_ON
  933. const RPC_CONNECTION_TRANSPORT *NB_TransportLoad(PROTOCOL_ID);
  934. #endif
  935. const RPC_CONNECTION_TRANSPORT *NMP_TransportLoad();
  936. //
  937. // Datagram protocol loaders
  938. //
  939. const RPC_DATAGRAM_TRANSPORT *DG_TransportLoad(PROTOCOL_ID);
  940. //
  941. // Misc functions
  942. //
  943. extern RPC_STATUS IP_BuildAddressVector(
  944. OUT NETWORK_ADDRESS_VECTOR **,
  945. IN ULONG NICFlags,
  946. IN RPC_CHAR *NetworkAddress OPTIONAL,
  947. IN WS_ADDRESS *Address OPTIONAL);
  948. extern RPC_STATUS CDP_BuildAddressVector(NETWORK_ADDRESS_VECTOR **);
  949. extern RPC_ADDRESS_CHANGE_FN * SpxAddressChangeFn;
  950. //
  951. // IP name resolver
  952. //
  953. const int IP_RETAIL_BUFFER_SIZE = 3*0x38;
  954. const int IP_BUFFER_SIZE = DEBUG_MIN(1, IP_RETAIL_BUFFER_SIZE);
  955. typedef enum tagIPVersionToUse
  956. {
  957. ipvtuIPv4 = 0,
  958. ipvtuIPv6,
  959. ipvtuIPAny
  960. } IPVersionToUse;
  961. typedef enum tagClientOrServer
  962. {
  963. cosClient,
  964. cosServer
  965. } ClientOrServer;
  966. class IP_ADDRESS_RESOLVER
  967. /*++
  968. Class Description:
  969. Converts the string address to an IP address.
  970. --*/
  971. {
  972. public:
  973. IP_ADDRESS_RESOLVER(
  974. IN RPC_CHAR *Name,
  975. IN ClientOrServer cos,
  976. IN IPVersionToUse IPvToUse
  977. )
  978. /*++
  979. Arguments:
  980. Name - The name (dotted ip address or DNS name) to resolve.
  981. fUseIPv6 - if TRUE, an IPv6 address will be resolved. If
  982. FALSE, an IPv4 address will be resolved.
  983. --*/
  984. {
  985. if (Name && (*Name == 0))
  986. Name = 0;
  987. this->Name = Name;
  988. this->IPvToUse = IPvToUse;
  989. this->cos = cos;
  990. AddrInfo = NULL;
  991. LoopbacksReturned = 0;
  992. CurrentAddrInfo = NULL;
  993. RpcpMemorySet(&Hint, 0, sizeof(ADDRINFO));
  994. }
  995. inline RPC_STATUS
  996. NextAddress(
  997. OUT SOCKADDR_IN *pAddress
  998. )
  999. {
  1000. ASSERT(IPvToUse == ipvtuIPv4);
  1001. return NextAddress((SOCKADDR_STORAGE *)pAddress);
  1002. }
  1003. RPC_STATUS
  1004. NextAddress(
  1005. OUT SOCKADDR_STORAGE *pAddress
  1006. );
  1007. ~IP_ADDRESS_RESOLVER();
  1008. private:
  1009. RPC_CHAR *Name;
  1010. IPVersionToUse IPvToUse;
  1011. ADDRINFO *AddrInfo; // the start of the addr info list. NULL if enumeration hasn't
  1012. // started
  1013. ADDRINFO *CurrentAddrInfo; // the current element in the addr info list enumeration. NULL
  1014. // if enumeration hasn't started or has finished.
  1015. ClientOrServer cos;
  1016. ADDRINFO Hint;
  1017. int LoopbacksReturned;
  1018. };
  1019. //
  1020. // Common functions exported by each protocol
  1021. //
  1022. extern RPC_STATUS RPC_ENTRY
  1023. COMMON_ProcessCalls(
  1024. IN INT Timeout,
  1025. OUT RPC_TRANSPORT_EVENT *pEvent,
  1026. OUT RPC_STATUS *pEventStatus,
  1027. OUT PVOID *ppEventContext,
  1028. OUT UINT *pBufferLength,
  1029. OUT BUFFER *pBuffer,
  1030. OUT PVOID *ppSourceContext
  1031. );
  1032. extern RPC_STATUS
  1033. COMMON_PostNonIoEvent(
  1034. RPC_TRANSPORT_EVENT Event,
  1035. DWORD Type,
  1036. PVOID Context
  1037. );
  1038. extern void
  1039. COMMON_RemoveAddress (
  1040. IN BASE_ADDRESS *Address
  1041. );
  1042. extern RPC_STATUS RPC_ENTRY
  1043. COMMON_TowerConstruct(
  1044. IN PCHAR Protseq,
  1045. IN PCHAR NetworkAddress,
  1046. IN PCHAR Endpoint,
  1047. OUT PUSHORT Floors,
  1048. OUT PULONG ByteCount,
  1049. OUT PUCHAR *Tower
  1050. );
  1051. extern RPC_STATUS RPC_ENTRY
  1052. COMMON_TowerExplode(
  1053. IN PUCHAR Tower,
  1054. OUT PCHAR *Protseq,
  1055. OUT PCHAR *NetworkAddress,
  1056. OUT PCHAR *Endpoint
  1057. );
  1058. extern VOID RPC_ENTRY
  1059. COMMON_ServerCompleteListen(
  1060. IN RPC_TRANSPORT_ADDRESS
  1061. );
  1062. #ifndef NO_PLUG_AND_PLAY
  1063. extern VOID RPC_ENTRY
  1064. COMMON_ListenForPNPNotifications (
  1065. );
  1066. extern VOID RPC_ENTRY
  1067. COMMON_StartPnpNotifications (
  1068. );
  1069. #endif
  1070. // Internal to transport interface
  1071. extern RPC_STATUS
  1072. COMMON_PrepareNewHandle(
  1073. IN HANDLE hAdd
  1074. );
  1075. extern VOID
  1076. COMMON_AddressManager(
  1077. IN BASE_ADDRESS *
  1078. );
  1079. extern RPC_STATUS RPC_ENTRY
  1080. WS_Abort(
  1081. IN RPC_TRANSPORT_CONNECTION Connection
  1082. );
  1083. extern RPC_STATUS
  1084. WS_ReactivateAddress (
  1085. IN WS_ADDRESS *pAddress
  1086. );
  1087. extern VOID
  1088. WS_DeactivateAddress (
  1089. IN WS_ADDRESS *pAddress
  1090. );
  1091. extern RPC_STATUS
  1092. DG_ReactivateAddress (
  1093. IN WS_DATAGRAM_ENDPOINT *pAddress
  1094. );
  1095. extern VOID
  1096. DG_DeactivateAddress (
  1097. IN WS_DATAGRAM_ENDPOINT *pAddress
  1098. );
  1099. inline
  1100. void
  1101. TransConnectionFreePacket(
  1102. RPC_TRANSPORT_CONNECTION ThisConnection,
  1103. BUFFER Ptr
  1104. )
  1105. {
  1106. I_RpcTransConnectionFreePacket(ThisConnection, Ptr);
  1107. }
  1108. inline
  1109. BUFFER
  1110. TransConnectionAllocatePacket(
  1111. RPC_TRANSPORT_CONNECTION ThisConnection,
  1112. UINT Size
  1113. )
  1114. {
  1115. return (I_RpcTransConnectionAllocatePacket(ThisConnection, Size));
  1116. }
  1117. inline
  1118. RPC_STATUS
  1119. TransConnectionReallocPacket(
  1120. IN RPC_TRANSPORT_CONNECTION ThisConnection,
  1121. IN BUFFER *ppBuffer,
  1122. IN UINT OldSize,
  1123. IN UINT NewSize
  1124. )
  1125. {
  1126. return(I_RpcTransConnectionReallocPacket(ThisConnection, ppBuffer, OldSize, NewSize));
  1127. }
  1128. #define InitReadEvent(p) \
  1129. hEvent = I_RpcTransGetThreadEvent(); \
  1130. \
  1131. p->Read.ol.hEvent = (HANDLE)((ULONG_PTR)hEvent | 0x1)
  1132. #define ASSERT_READ_EVENT_IS_THERE(p) \
  1133. ASSERT( p->Read.ol.hEvent == (HANDLE) ((ULONG_PTR)I_RpcTransGetThreadEvent() | 0x1))
  1134. extern HMODULE hWinsock2;
  1135. #endif // __TRANS_HXX