00001 //------------------------------------------------------------------------------ 00002 // Copyright (c) 2011-2012 by European Organization for Nuclear Research (CERN) 00003 // Author: Lukasz Janyst <ljanyst@cern.ch> 00004 //------------------------------------------------------------------------------ 00005 // XRootD is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // XRootD is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with XRootD. If not, see <http://www.gnu.org/licenses/>. 00017 //------------------------------------------------------------------------------ 00018 00019 #ifndef __XRD_CL_ASYNC_SOCKET_HANDLER_HH__ 00020 #define __XRD_CL_ASYNC_SOCKET_HANDLER_HH__ 00021 00022 #include "XrdCl/XrdClSocket.hh" 00023 #include "XrdCl/XrdClDefaultEnv.hh" 00024 #include "XrdCl/XrdClPoller.hh" 00025 #include "XrdCl/XrdClPostMasterInterfaces.hh" 00026 #include "XrdCl/XrdClTaskManager.hh" 00027 #include "XrdCl/XrdClXRootDResponses.hh" 00028 #include "XrdCl/XrdClURL.hh" 00029 00030 namespace XrdCl 00031 { 00032 class Stream; 00033 00034 //---------------------------------------------------------------------------- 00037 //---------------------------------------------------------------------------- 00038 class AsyncSocketHandler: public SocketHandler 00039 { 00040 //------------------------------------------------------------------------ 00041 // We need an extra task for rescheduling of HS request that received 00042 // a wait response. 00043 //------------------------------------------------------------------------ 00044 class WaitTask: public XrdCl::Task 00045 { 00046 public: 00047 WaitTask( XrdCl::AsyncSocketHandler *handler, XrdCl::Message *msg ): 00048 pHandler( handler ), pMsg( msg ) 00049 { 00050 std::ostringstream o; 00051 o << "WaitTask for: 0x" << msg; 00052 SetName( o.str() ); 00053 } 00054 00055 virtual time_t Run( time_t now ) 00056 { 00057 pHandler->RetryHSMsg( pMsg ); 00058 return 0; 00059 } 00060 00061 private: 00062 XrdCl::AsyncSocketHandler *pHandler; 00063 XrdCl::Message *pMsg; 00064 }; 00065 00066 public: 00067 //------------------------------------------------------------------------ 00069 //------------------------------------------------------------------------ 00070 AsyncSocketHandler( const URL &url, 00071 Poller *poller, 00072 TransportHandler *transport, 00073 AnyObject *channelData, 00074 uint16_t subStreamNum ); 00075 00076 //------------------------------------------------------------------------ 00078 //------------------------------------------------------------------------ 00079 ~AsyncSocketHandler(); 00080 00081 //------------------------------------------------------------------------ 00083 //------------------------------------------------------------------------ 00084 void SetAddress( const XrdNetAddr &address ) 00085 { 00086 pSockAddr = address; 00087 } 00088 00089 //------------------------------------------------------------------------ 00091 //------------------------------------------------------------------------ 00092 const XrdNetAddr &GetAddress() const 00093 { 00094 return pSockAddr; 00095 } 00096 00097 //------------------------------------------------------------------------ 00099 //------------------------------------------------------------------------ 00100 XRootDStatus Connect( time_t timeout ); 00101 00102 //------------------------------------------------------------------------ 00104 //------------------------------------------------------------------------ 00105 XRootDStatus Close(); 00106 00107 //------------------------------------------------------------------------ 00109 //------------------------------------------------------------------------ 00110 void SetStream( Stream *stream ); 00111 00112 //------------------------------------------------------------------------ 00114 //------------------------------------------------------------------------ 00115 virtual void Event( uint8_t type, XrdCl::Socket */*socket*/ ); 00116 00117 //------------------------------------------------------------------------ 00119 //------------------------------------------------------------------------ 00120 XRootDStatus EnableUplink() 00121 { 00122 if( !pPoller->EnableWriteNotification( pSocket, true, pTimeoutResolution ) ) 00123 return XRootDStatus( stFatal, errPollerError ); 00124 return XRootDStatus(); 00125 } 00126 00127 //------------------------------------------------------------------------ 00129 //------------------------------------------------------------------------ 00130 XRootDStatus DisableUplink() 00131 { 00132 if( !pPoller->EnableWriteNotification( pSocket, false ) ) 00133 return XRootDStatus( stFatal, errPollerError ); 00134 return XRootDStatus(); 00135 } 00136 00137 //------------------------------------------------------------------------ 00139 //------------------------------------------------------------------------ 00140 const std::string &GetStreamName() 00141 { 00142 return pStreamName; 00143 } 00144 00145 //------------------------------------------------------------------------ 00147 //------------------------------------------------------------------------ 00148 time_t GetLastActivity() 00149 { 00150 return pLastActivity; 00151 } 00152 00153 protected: 00154 00155 //------------------------------------------------------------------------ 00156 // Connect returned 00157 //------------------------------------------------------------------------ 00158 virtual void OnConnectionReturn(); 00159 00160 //------------------------------------------------------------------------ 00161 // Got a write readiness event 00162 //------------------------------------------------------------------------ 00163 void OnWrite(); 00164 00165 //------------------------------------------------------------------------ 00166 // Got a write readiness event while handshaking 00167 //------------------------------------------------------------------------ 00168 void OnWriteWhileHandshaking(); 00169 00170 //------------------------------------------------------------------------ 00171 // Write the message and it's signature in one go with writev 00172 //------------------------------------------------------------------------ 00173 XRootDStatus WriteMessageAndRaw( Message *toWrite, Message *&sign ); 00174 00175 //------------------------------------------------------------------------ 00176 // Write the current message 00177 //------------------------------------------------------------------------ 00178 XRootDStatus WriteCurrentMessage( Message *toWrite ); 00179 00180 //------------------------------------------------------------------------ 00181 // Got a read readiness event 00182 //------------------------------------------------------------------------ 00183 void OnRead(); 00184 00185 //------------------------------------------------------------------------ 00186 // Got a read readiness event while handshaking 00187 //------------------------------------------------------------------------ 00188 void OnReadWhileHandshaking(); 00189 00190 //------------------------------------------------------------------------ 00191 // Handle the handshake message 00192 //------------------------------------------------------------------------ 00193 void HandleHandShake(); 00194 00195 //------------------------------------------------------------------------ 00196 // Prepare the next step of the hand-shake procedure 00197 //------------------------------------------------------------------------ 00198 void HandShakeNextStep( bool done ); 00199 00200 //------------------------------------------------------------------------ 00201 // Read a message 00202 //------------------------------------------------------------------------ 00203 XRootDStatus ReadMessage( Message *&toRead ); 00204 00205 //------------------------------------------------------------------------ 00206 // Handle fault 00207 //------------------------------------------------------------------------ 00208 void OnFault( XRootDStatus st ); 00209 00210 //------------------------------------------------------------------------ 00211 // Handle fault while handshaking 00212 //------------------------------------------------------------------------ 00213 void OnFaultWhileHandshaking( XRootDStatus st ); 00214 00215 //------------------------------------------------------------------------ 00216 // Handle write timeout event 00217 //------------------------------------------------------------------------ 00218 void OnWriteTimeout(); 00219 00220 //------------------------------------------------------------------------ 00221 // Handle read timeout event 00222 //------------------------------------------------------------------------ 00223 void OnReadTimeout(); 00224 00225 //------------------------------------------------------------------------ 00226 // Handle timeout event while handshaking 00227 //------------------------------------------------------------------------ 00228 void OnTimeoutWhileHandshaking(); 00229 00230 //------------------------------------------------------------------------ 00231 // Carry out the TLS hand-shake 00232 // 00233 // The TLS hand-shake is being initiated in HandleHandShake() by calling 00234 // Socket::TlsHandShake(), however it returns suRetry the TLS hand-shake 00235 // needs to be followed up by OnTlsHandShake(). 00236 // 00237 // However, once the TLS connection has been established the server may 00238 // decide to redo the TLS hand-shake at any time, this operation is handled 00239 // under the hood by read and write requests and facilitated by 00240 // Socket::MapEvent() 00241 //------------------------------------------------------------------------ 00242 XRootDStatus DoTlsHandShake(); 00243 00244 //------------------------------------------------------------------------ 00245 // Handle read/write event if we are in the middle of a TLS hand-shake 00246 //------------------------------------------------------------------------ 00247 // Handle read/write event if we are in the middle of a TLS hand-shake 00248 void OnTLSHandShake(); 00249 00250 //------------------------------------------------------------------------ 00251 // Retry hand shake message 00252 //------------------------------------------------------------------------ 00253 void RetryHSMsg( Message *msg ); 00254 00255 //------------------------------------------------------------------------ 00256 // Extract the value of a wait response 00257 // 00258 // @param rsp : the server response 00259 // @return : if rsp is a wait response then its value 00260 // otherwise -1 00261 //------------------------------------------------------------------------ 00262 inline kXR_int32 HandleWaitRsp( Message *rsp ); 00263 00264 //------------------------------------------------------------------------ 00265 // Data members 00266 //------------------------------------------------------------------------ 00267 Poller *pPoller; 00268 TransportHandler *pTransport; 00269 AnyObject *pChannelData; 00270 uint16_t pSubStreamNum; 00271 Stream *pStream; 00272 std::string pStreamName; 00273 Socket *pSocket; 00274 Message *pIncoming; 00275 Message *pHSIncoming; 00276 Message *pOutgoing; 00277 Message *pSignature; 00278 Message *pHSOutgoing; 00279 XrdNetAddr pSockAddr; 00280 HandShakeData *pHandShakeData; 00281 bool pHandShakeDone; 00282 uint16_t pTimeoutResolution; 00283 time_t pConnectionStarted; 00284 time_t pConnectionTimeout; 00285 bool pHeaderDone; 00286 // true means the handler owns the server response 00287 std::pair<IncomingMsgHandler*, bool> pIncHandler; 00288 bool pOutMsgDone; 00289 OutgoingMsgHandler *pOutHandler; 00290 uint32_t pIncMsgSize; 00291 uint32_t pOutMsgSize; 00292 time_t pLastActivity; 00293 URL pUrl; 00294 bool pTlsHandShakeOngoing; 00295 }; 00296 } 00297 00298 #endif // __XRD_CL_ASYNC_SOCKET_HANDLER_HH__