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.

371 lines
9.5 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name :
  4. gibcli.hxx
  5. Abstract:
  6. This module defines the CLIENT_CONNECTION class.
  7. This object maintains information about a new client connection
  8. Author:
  9. Rohan Phillips ( Rohanp ) 11-Dec-1995
  10. Project:
  11. Gibraltar Services Common Code
  12. Revision History:
  13. Richard Kamicar ( rkamicar ) 31-Dec-1995
  14. Moved to common directory, filled in more
  15. --*/
  16. # ifndef _GEN_CLIENT_HXX_
  17. # define _GEN_CLIENT_HXX_
  18. /************************************************************
  19. * Include Headers
  20. ************************************************************/
  21. //
  22. // Redefine the type to indicate that this is a call-back function
  23. //
  24. typedef ATQ_COMPLETION PFN_ATQ_COMPLETION;
  25. /************************************************************
  26. * Symbolic Constants
  27. ************************************************************/
  28. //
  29. // Valid & Invalid Signatures for Client Connection object
  30. // (Ims Connection USed/FRee)
  31. //
  32. # define CLIENT_CONNECTION_SIGNATURE_VALID 'CONN'
  33. # define CLIENT_CONNECTION_SIGNATURE_FREE 'CONF'
  34. //
  35. // POP3 requires a minimum of 10 minutes before a timeout
  36. // (SMTP doesn't specify, but might as well follow POP3)
  37. //
  38. # define MINIMUM_CONNECTION_IO_TIMEOUT (10 * 60) // 10 minutes
  39. //
  40. //
  41. # define DEFAULT_CONNECTION_IO_TIMEOUT MINIMUM_CONNECTION_IO_TIMEOUT
  42. # define DEFAULT_REQUEST_BUFFER_SIZE (512) // 512 bytes
  43. # define MAX_HOST_NAME_LEN (40)
  44. const MAX_READ_BUFF_SIZE = 1024;
  45. const MAX_MESSAGE_BUFF_SIZE = 1024; // outgoing message
  46. const char CR = '\015';
  47. const char LF = '\012';
  48. static const char *CRLF = "\015\012";
  49. /************************************************************
  50. * Type Definitions
  51. ************************************************************/
  52. /*++
  53. class CLIENT_CONNECTION
  54. This class is used for keeping track of individual client
  55. connections established with the server.
  56. It maintains the state of the connection being processed.
  57. In addition it also encapsulates data related to Asynchronous
  58. thread context used for processing the request.
  59. --*/
  60. class CLIENT_CONNECTION
  61. {
  62. public:
  63. //-------------------------------------------------------------------------
  64. // Virtual methods that will be defined by derived classes (more below).
  65. //
  66. virtual BOOL StartSession( void);
  67. virtual char * IsLineComplete(IN OUT const char * pchRecvd, IN DWORD cbRecvd);
  68. /*++
  69. Resets the line state.
  70. Arguments: none.
  71. Returns: nothing.
  72. --*/
  73. VOID ResetLineState(VOID) { m_PotentialMatch = NULL; }
  74. //-------------------------------------------------------------------------
  75. protected:
  76. //
  77. // Data required for IO operations
  78. //
  79. PATQ_CONTEXT m_pAtqContext;
  80. private:
  81. ULONG m_signature; // signature on object for sanity check
  82. DWORD m_ClientId; //unique identifier for client
  83. //
  84. // Connection Related data
  85. //
  86. SOCKET m_sClient; // socket for this connection
  87. SOCKADDR_IN m_saClient; // socket address for the client
  88. //
  89. // time when this object was created in milliseconds.
  90. //
  91. DWORD m_msStartingTime;
  92. //
  93. // Addresses of machines' network addresses through which this
  94. // connection got established.
  95. //
  96. CHAR m_pchLocalHostName[MAX_HOST_NAME_LEN];
  97. CHAR m_pchRemoteHostName[MAX_HOST_NAME_LEN];
  98. protected:
  99. //
  100. // The overlapped structure for reads (one outstanding read at a time)
  101. // -- writes will dynamically allocate them
  102. //
  103. OVERLAPPED m_Overlapped;
  104. char m_recvBuffer[MAX_READ_BUFF_SIZE];
  105. char * m_PotentialMatch; // Partial Pipelined read marker.
  106. DWORD m_cbReceived;
  107. PVOID m_pvInitial; // initial request read
  108. DWORD m_cbInitial; // count of bytes of initial request
  109. DWORD m_dwCmdBytesRecv;
  110. DWORD m_dwCmdBytesSent;
  111. SOCKET QuerySocket( VOID) const
  112. { return ( m_sClient); }
  113. //
  114. // Functions for processing client connection at various states
  115. //
  116. BOOL ReceiveRequest( IN DWORD cbWritten,
  117. OUT LPBOOL pfFullRequestRecvd);
  118. const CHAR * QueryLocalHostName( VOID) const
  119. { return m_pchLocalHostName; }
  120. const CHAR * PassWord( VOID) const
  121. { return NULL; }
  122. DWORD QueryIoTimeout( VOID) const
  123. { return ( DEFAULT_CONNECTION_IO_TIMEOUT); }
  124. PATQ_CONTEXT QueryAtqContext( VOID) const
  125. { return ( m_pAtqContext); }
  126. LPOVERLAPPED QueryAtqOverlapped( void ) const
  127. { return ( m_pAtqContext == NULL ? NULL : &m_pAtqContext->Overlapped ); }
  128. public:
  129. CLIENT_CONNECTION(
  130. IN SOCKET sClient,
  131. IN const SOCKADDR_IN * psockAddrRemote,
  132. IN const SOCKADDR_IN * psockAddrLocal = NULL,
  133. IN PATQ_CONTEXT pAtqContext = NULL,
  134. IN PVOID pvInitialRequest = NULL,
  135. IN DWORD cbInitialData = 0)
  136. : m_signature(CLIENT_CONNECTION_SIGNATURE_VALID)
  137. {
  138. Initialize( sClient, psockAddrRemote, psockAddrLocal,
  139. pAtqContext, pvInitialRequest, cbInitialData);
  140. }
  141. virtual ~CLIENT_CONNECTION(VOID)
  142. {
  143. Cleanup();
  144. }
  145. BOOL
  146. Initialize(
  147. IN SOCKET sClient,
  148. IN const SOCKADDR_IN * psockAddrRemote,
  149. IN const SOCKADDR_IN * psockAddrLocal = NULL,
  150. IN PATQ_CONTEXT pAtqContext = NULL,
  151. IN PVOID pvInitialRequest = NULL,
  152. IN DWORD cbInitialData = 0);
  153. VOID Cleanup(VOID);
  154. BOOL m_Destroy;
  155. //
  156. // IsValid()
  157. // o Checks the signature of the object to determine
  158. // if this is a valid ICLIENT_CONNECTION object.
  159. //
  160. // Returns: TRUE on success and FALSE if invalid.
  161. //
  162. BOOL IsValid( VOID) const
  163. { return ( m_signature == CLIENT_CONNECTION_SIGNATURE_VALID); }
  164. VOID StartProcessingTimer(void)
  165. {m_msStartingTime = GetTickCount();}
  166. DWORD QueryProcessingTime( VOID) const
  167. { return ( GetTickCount() - m_msStartingTime); }
  168. LPCSTR QueryRcvBuffer( VOID) const
  169. { return ((LPCSTR) m_recvBuffer); }
  170. LPSTR QueryMRcvBuffer(VOID) // modifiable string
  171. { return (LPSTR) m_recvBuffer; }
  172. LPBYTE GetRecvBuffer(void) { return (LPBYTE)m_recvBuffer; }
  173. const char * QueryClientHostName( VOID) const
  174. { return m_pchRemoteHostName; }
  175. const DWORD QueryClientId(void) const
  176. {return m_ClientId;}
  177. DWORD QueryRequestLen( VOID) const
  178. { return ( m_cbReceived); }
  179. void SetClientId(DWORD Id) {m_ClientId = Id;}
  180. //-------------------------------------------------------------------------
  181. // Virtual method that MUST be defined by derived classes.
  182. //
  183. // Processes a completed IO on the connection for the client.
  184. //
  185. // -- Calls and maybe called from the Atq functions.
  186. //
  187. virtual BOOL ProcessClient(
  188. IN DWORD cbWritten,
  189. IN DWORD dwCompletionStatus,
  190. IN OUT OVERLAPPED * lpo
  191. ) = 0;
  192. //-------------------------------------------------------------------------
  193. //
  194. // Disconnect this client
  195. //
  196. // dwErrorCode is used only when there is server level error
  197. //
  198. VOID virtual DisconnectClient( IN DWORD dwErrorCode = NO_ERROR);
  199. //
  200. // Wrapper functions for common File operations
  201. // ( Used to hide the ATQ and reference counting)
  202. //
  203. BOOL virtual ReadFile( LPVOID pvBuffer, DWORD cbSize = MAX_READ_BUFF_SIZE );
  204. //
  205. // The first (pair) WriteFile does a synchronous write.
  206. // The second does an async write..
  207. //
  208. BOOL virtual WriteFile( IN LPVOID pvBuffer, IN DWORD cbSize );
  209. BOOL virtual WriteFile( IN LPVOID lpvBuffer, IN DWORD cbSize, IN OVERLAPPED *lpo);
  210. LPCTSTR virtual QueryClientUserName( VOID );
  211. BOOL TransmitFile(
  212. IN HANDLE hFile,
  213. IN LARGE_INTEGER & liSize,
  214. IN LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers = NULL);
  215. void TransactionLog(
  216. IN const char *pszOperation,
  217. IN const char *pszTarget,
  218. IN const char *pszParameters = NULL,
  219. IN DWORD dwWin32Error = NO_ERROR,
  220. IN DWORD dwServiceSpecificStatus = NO_ERROR
  221. );
  222. //
  223. // should be called before processing new command
  224. //
  225. void ResetCommandCounters( void )
  226. {
  227. m_dwCmdBytesRecv = m_dwCmdBytesSent = 0;
  228. }
  229. //
  230. // should be called after IsLineComplete
  231. //
  232. void SetCommandBytesRecv( DWORD dw )
  233. {
  234. m_dwCmdBytesRecv = dw;
  235. }
  236. //
  237. // should be called after each successful WriteFile/send
  238. //
  239. void AddCommandBytesSent( DWORD dw )
  240. {
  241. InterlockedExchangeAdd((LONG *) &m_dwCmdBytesSent, (LONG)dw);
  242. }
  243. //
  244. // should be called after each successful WriteFile/send
  245. //
  246. void AddCommandBytesRecv( DWORD dw )
  247. {
  248. InterlockedExchangeAdd((LONG *) &m_dwCmdBytesRecv, (LONG)dw);
  249. }
  250. void TransactionLog(const char *pszOperation, DWORD dwError = NO_ERROR);
  251. BOOL AddToAtqHandles(HANDLE hClient, DWORD TimeOut, ATQ_COMPLETION pfnCompletion)
  252. {
  253. return ( AtqAddAsyncHandle( &m_pAtqContext, this,
  254. pfnCompletion,
  255. TimeOut, hClient));
  256. }
  257. public:
  258. //
  259. // LIST_ENTRY object for storing client connections in a list.
  260. //
  261. LIST_ENTRY m_listEntry;
  262. LIST_ENTRY & QueryListEntry( VOID)
  263. { return ( m_listEntry); }
  264. # if DBG
  265. virtual VOID Print( VOID) const;
  266. # endif // DBG
  267. }; // class ICLIENT_CONNECTION
  268. typedef CLIENT_CONNECTION * PCLIENT_CONNECTION;
  269. //
  270. // Auxiliary functions
  271. //
  272. INT ShutAndCloseSocket( IN SOCKET sock);
  273. # endif
  274. /************************ End of File ***********************/