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.

427 lines
12 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. // parameter block used to initialize connections
  54. //
  55. typedef struct _CLIENT_CONN_PARAMS
  56. {
  57. SOCKET sClient;
  58. PSOCKADDR pAddrLocal;
  59. PSOCKADDR pAddrRemote;
  60. PATQ_CONTEXT pAtqContext;
  61. PVOID pEndpointObject;
  62. PIIS_ENDPOINT pEndpoint;
  63. PVOID pvInitialBuff;
  64. DWORD cbInitialBuff;
  65. } CLIENT_CONN_PARAMS, *PCLIENT_CONN_PARAMS;
  66. /*++
  67. class CLIENT_CONNECTION
  68. This class is used for keeping track of individual client
  69. connections established with the server.
  70. It maintains the state of the connection being processed.
  71. In addition it also encapsulates data related to Asynchronous
  72. thread context used for processing the request.
  73. --*/
  74. class CLIENT_CONNECTION
  75. {
  76. public:
  77. //-------------------------------------------------------------------------
  78. // Virtual methods that will be defined by derived classes (more below).
  79. //
  80. virtual BOOL StartSession( void);
  81. virtual char * IsLineComplete(IN OUT const char * pchRecvd, IN DWORD cbRecvd);
  82. //-------------------------------------------------------------------------
  83. private:
  84. ULONG m_signature; // signature on object for sanity check
  85. DWORD m_ClientId; //unique identifier for client
  86. //
  87. // This request came in through the secure port
  88. //
  89. BOOL m_fSecurePort;
  90. //
  91. // Connection Related data
  92. //
  93. SOCKET m_sClient; // socket for this connection
  94. //
  95. // Socket Family this connection came in on
  96. //
  97. USHORT m_sSocketFamily;
  98. //
  99. // time when this object was created in milliseconds.
  100. //
  101. DWORD m_msStartingTime;
  102. //
  103. // Addresses of machines' network addresses through which this
  104. // connection got established.
  105. //
  106. CHAR m_pchLocalHostName[MAX_HOST_NAME_LEN];
  107. CHAR m_pchLocalPortName[sizeof("65536")];
  108. CHAR m_pchRemoteHostName[MAX_HOST_NAME_LEN];
  109. protected:
  110. //
  111. // The overlapped structure for reads (one outstanding read at a time)
  112. // -- writes will dynamically allocate them
  113. //
  114. OVERLAPPED m_Overlapped;
  115. //
  116. // Data required for IO operations
  117. //
  118. PATQ_CONTEXT m_pAtqContext;
  119. //
  120. // server instance. Both are referenced.
  121. //
  122. //PSMTP_SERVER_INSTANCE m_pInstance;
  123. PIIS_ENDPOINT m_pSmtpEndpoint;
  124. //
  125. // server instance - statistics object.
  126. //
  127. //LPSMTP_SERVER_STATISTICS m_pSmtpStats;
  128. //
  129. // context returned on a non-acceptex completion
  130. //
  131. SOCKADDR_IN m_saClient; // socket address for the client
  132. PVOID m_atqEndpointObject;
  133. char m_recvBuffer[MAX_READ_BUFF_SIZE];
  134. DWORD m_cbReceived;
  135. PVOID m_pvInitial; // initial request read
  136. DWORD m_cbInitial; // count of bytes of initial request
  137. DWORD m_dwCmdBytesRecv;
  138. DWORD m_dwCmdBytesSent;
  139. BOOL m_DoCleanup;
  140. SOCKET QuerySocket( VOID) const
  141. { return ( m_sClient); }
  142. //
  143. // Functions for processing client connection at various states
  144. //
  145. BOOL ReceiveRequest( IN DWORD cbWritten,
  146. OUT LPBOOL pfFullRequestRecvd);
  147. const CHAR * QueryLocalHostName( VOID) const
  148. { return m_pchLocalHostName; }
  149. const CHAR * QueryLocalPortName( VOID) const
  150. { return m_pchLocalPortName; }
  151. const CHAR * PassWord( VOID) const
  152. { return NULL; }
  153. DWORD QueryIoTimeout( VOID) const
  154. { return ( DEFAULT_CONNECTION_IO_TIMEOUT); }
  155. PATQ_CONTEXT QueryAtqContext( VOID) const
  156. { return ( m_pAtqContext); }
  157. LPOVERLAPPED QueryAtqOverlapped( void ) const
  158. { return ( m_pAtqContext == NULL ? NULL : &m_pAtqContext->Overlapped ); }
  159. public:
  160. CLIENT_CONNECTION(
  161. IN SOCKET sClient,
  162. IN const SOCKADDR_IN * psockAddrRemote,
  163. IN const SOCKADDR_IN * psockAddrLocal = NULL,
  164. IN PATQ_CONTEXT pAtqContext = NULL,
  165. IN PVOID pvInitialRequest = NULL,
  166. IN DWORD cbInitialData = 0)
  167. : m_signature(CLIENT_CONNECTION_SIGNATURE_VALID),
  168. m_DoCleanup(TRUE)
  169. {
  170. Initialize( sClient, psockAddrRemote, psockAddrLocal,
  171. pAtqContext, pvInitialRequest, cbInitialData);
  172. }
  173. virtual ~CLIENT_CONNECTION(VOID)
  174. {
  175. Cleanup();
  176. // Invalidate the signature. since this connection is trashed.
  177. m_signature = CLIENT_CONNECTION_SIGNATURE_FREE;
  178. }
  179. BOOL
  180. Initialize(
  181. IN SOCKET sClient,
  182. IN const SOCKADDR_IN * psockAddrRemote,
  183. IN const SOCKADDR_IN * psockAddrLocal = NULL,
  184. IN PATQ_CONTEXT pAtqContext = NULL,
  185. IN PVOID pvInitialRequest = NULL,
  186. IN DWORD cbInitialData = 0);
  187. VOID Cleanup(VOID);
  188. BOOL m_Destroy;
  189. //
  190. // IsValid()
  191. // o Checks the signature of the object to determine
  192. // if this is a valid ICLIENT_CONNECTION object.
  193. //
  194. // Returns: TRUE on success and FALSE if invalid.
  195. //
  196. BOOL IsValid( VOID) const
  197. { return ( m_signature == CLIENT_CONNECTION_SIGNATURE_VALID); }
  198. void SetAtqContext (PATQ_CONTEXT pNewContext)
  199. {
  200. m_pAtqContext = pNewContext;
  201. }
  202. VOID StartProcessingTimer(void)
  203. {m_msStartingTime = GetTickCount();}
  204. DWORD QueryProcessingTime( VOID) const
  205. { return ( GetTickCount() - m_msStartingTime); }
  206. virtual LPCSTR QueryRcvBuffer( VOID) const
  207. { return ((LPCSTR) m_recvBuffer); }
  208. virtual LPSTR QueryMRcvBuffer(VOID) // modifiable string
  209. { return (LPSTR) m_recvBuffer; }
  210. const char * QueryClientHostName( VOID) const
  211. { return m_pchRemoteHostName; }
  212. const DWORD QueryClientId(void) const
  213. {return m_ClientId;}
  214. DWORD QueryRequestLen( VOID) const
  215. { return ( m_cbReceived); }
  216. void SetClientId(DWORD Id) {m_ClientId = Id;}
  217. //-------------------------------------------------------------------------
  218. // Virtual method that MUST be defined by derived classes.
  219. //
  220. // Processes a completed IO on the connection for the client.
  221. //
  222. // -- Calls and maybe called from the Atq functions.
  223. //
  224. virtual BOOL ProcessClient(
  225. IN DWORD cbWritten,
  226. IN DWORD dwCompletionStatus,
  227. IN OUT OVERLAPPED * lpo
  228. ) = 0;
  229. //-------------------------------------------------------------------------
  230. //
  231. // Disconnect this client
  232. //
  233. // dwErrorCode is used only when there is server level error
  234. //
  235. VOID virtual DisconnectClient( IN DWORD dwErrorCode = NO_ERROR);
  236. //
  237. // Wrapper functions for common File operations
  238. // ( Used to hide the ATQ and reference counting)
  239. //
  240. BOOL virtual ReadFile( LPVOID pvBuffer, DWORD cbSize = MAX_READ_BUFF_SIZE );
  241. //
  242. // The first (pair) WriteFile does a synchronous write.
  243. // The second does an async write..
  244. //
  245. BOOL virtual WriteFile( IN LPVOID pvBuffer, IN DWORD cbSize );
  246. BOOL virtual WriteFile( IN LPVOID lpvBuffer, IN DWORD cbSize, IN OVERLAPPED *lpo);
  247. LPCTSTR virtual QueryClientUserName( VOID );
  248. BOOL TransmitFile(
  249. IN HANDLE hFile,
  250. IN LARGE_INTEGER & liSize,
  251. IN LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers = NULL);
  252. //
  253. // jstamerj 1998/11/03 20:14:04:
  254. // A wrapper around atq's PostCompletionStatus
  255. //
  256. BOOL virtual PostCompletionStatus( IN DWORD dwBytes );
  257. //
  258. // should be called before processing new command
  259. //
  260. void ResetCommandCounters( void )
  261. {
  262. m_dwCmdBytesRecv = m_dwCmdBytesSent = 0;
  263. }
  264. //
  265. // should be called after IsLineComplete
  266. //
  267. void SetCommandBytesRecv( DWORD dw )
  268. {
  269. m_dwCmdBytesRecv = dw;
  270. }
  271. //
  272. // should be called after each successful WriteFile/send
  273. //
  274. void AddCommandBytesSent( DWORD dw )
  275. {
  276. InterlockedExchangeAdd((LONG *) &m_dwCmdBytesSent, (LONG)dw);
  277. }
  278. //
  279. // should be called after each successful WriteFile/send
  280. //
  281. void AddCommandBytesRecv( DWORD dw )
  282. {
  283. InterlockedExchangeAdd((LONG *) &m_dwCmdBytesRecv, (LONG)dw);
  284. }
  285. BOOL AddToAtqHandles(HANDLE hClient, PVOID EndPointObj, DWORD TimeOut, ATQ_COMPLETION pfnCompletion)
  286. {
  287. return ( AtqAddAsyncHandle( &m_pAtqContext, EndPointObj,
  288. this, pfnCompletion, TimeOut,
  289. hClient));
  290. }
  291. USHORT QuerySocketFamily( VOID ) const
  292. { return m_sSocketFamily; }
  293. PIIS_ENDPOINT QuerySmtpEndpoint( VOID ) const
  294. { _ASSERT(m_pSmtpEndpoint != NULL); return m_pSmtpEndpoint; }
  295. DWORD QueryLocalIPAddress( VOID ) const
  296. { return 0; }
  297. static BOOL WriteSocket( IN SOCKET sock, IN LPVOID pBuffer, IN DWORD cbSize );
  298. public:
  299. //
  300. // LIST_ENTRY object for storing client connections in a list.
  301. //
  302. LIST_ENTRY m_listEntry;
  303. LIST_ENTRY & QueryListEntry( VOID)
  304. { return ( m_listEntry); }
  305. # if DBG
  306. virtual VOID Print( VOID) const;
  307. # endif // DBG
  308. }; // class ICLIENT_CONNECTION
  309. typedef CLIENT_CONNECTION * PCLIENT_CONNECTION;
  310. //
  311. // Auxiliary functions
  312. //
  313. INT ShutAndCloseSocket( IN SOCKET sock);
  314. # endif
  315. /************************ End of File ***********************/