XRootD
Loading...
Searching...
No Matches
XrdCl::Tls Class Reference

TLS layer for socket connection. More...

#include <XrdClTls.hh>

+ Collaboration diagram for XrdCl::Tls:

Public Member Functions

 Tls (Socket *socket, AsyncSocketHandler *socketHandler)
 Constructor - creates async TLS layer for given socker file descriptor.
 
 ~Tls ()
 Destructor.
 
XRootDStatus Connect (const std::string &thehost, XrdNetAddrInfo *netInfo)
 Establish a TLS/SSL session and perform host verification.
 
uint8_t MapEvent (uint8_t event)
 
XRootDStatus Read (char *buffer, size_t size, int &bytesRead)
 
XRootDStatus ReadV (iovec *iov, int iocnt, int &bytesRead)
 
XRootDStatus Send (const char *buffer, size_t size, int &bytesWritten)
 
void Shutdown ()
 Shutdown the TLS/SSL connection.
 

Static Public Member Functions

static void ClearErrorQueue ()
 Clear the error queue for the calling thread.
 

Detailed Description

TLS layer for socket connection.

Definition at line 39 of file XrdClTls.hh.

Constructor & Destructor Documentation

◆ Tls()

XrdCl::Tls::Tls ( Socket * socket,
AsyncSocketHandler * socketHandler )

Constructor - creates async TLS layer for given socker file descriptor.

Definition at line 144 of file XrdClTls.cc.

144 : pSocket( socket ), pTlsHSRevert( None ), pSocketHandler( socketHandler )
145 {
146 //----------------------------------------------------------------------
147 // Set the message callback for TLS layer
148 //----------------------------------------------------------------------
149 SetTlsMsgCB::Once();
150
151 if( !InitTLS() )
152 throw std::runtime_error( "Failed to initialize TLS" );
153
154 pTls.reset(
157 }
static std::unique_ptr< XrdTlsContext > tlsContext
Definition XrdClTls.cc:34
int GetFD()
Get the file descriptor.
Socket wrapper for TLS I/O.
@ TLS_HS_NOBLK
Do not block during handshake.
@ TLS_RNB_WNB
Non-blocking read non-blocking write.
bool InitTLS()
Definition XrdClTls.cc:96

References XrdCl::Socket::GetFD(), XrdCl::InitTLS(), XrdTlsSocket::TLS_HS_NOBLK, XrdTlsSocket::TLS_RNB_WNB, and tlsContext.

+ Here is the call graph for this function:

◆ ~Tls()

XrdCl::Tls::~Tls ( )
inline

Destructor.

Definition at line 51 of file XrdClTls.hh.

52 {
53 }

Member Function Documentation

◆ ClearErrorQueue()

void XrdCl::Tls::ClearErrorQueue ( )
static

Clear the error queue for the calling thread.

Definition at line 422 of file XrdClTls.cc.

423 {
425 }
static void ClearErrorQueue()
Clear the SSL error queue for the calling thread.
Definition XrdTls.cc:265

References XrdTls::ClearErrorQueue().

+ Here is the call graph for this function:

◆ Connect()

XRootDStatus XrdCl::Tls::Connect ( const std::string & thehost,
XrdNetAddrInfo * netInfo )

Establish a TLS/SSL session and perform host verification.

Definition at line 162 of file XrdClTls.cc.

163 {
164 std::string errmsg;
165 const char *verhost = 0;
166 if( thehost != "localhost" && thehost != "127.0.0.1" && thehost != "[::1]" )
167 verhost = thehost.c_str();
168 XrdTls::RC error = pTls->Connect( verhost, &errmsg );
169 XRootDStatus status = ToStatus( error );
170 if( !status.IsOK() )
171 status.SetErrorMessage( errmsg );
172
173 //--------------------------------------------------------------------------
174 // There's no follow up if the read simply failed
175 //--------------------------------------------------------------------------
176 if( !status.IsOK() )
177 {
179 log->Error( XrdCl::TlsMsg, "Failed to do TLS connect: %s", errmsg.c_str() );
180 return status;
181 }
182
183
184 if( pTls->NeedHandShake() )
185 {
186 //------------------------------------------------------------------------
187 // Make sure the socket is uncorked so the TLS hand-shake can go through
188 //------------------------------------------------------------------------
189 if( pSocket->IsCorked() )
190 {
191 XRootDStatus st = pSocket->Uncork();
192 if( !st.IsOK() ) return st;
193 }
194
195 //----------------------------------------------------------------------
196 // Check if TLS hand-shake wants to write something
197 //----------------------------------------------------------------------
198 if( error == XrdTls::TLS_WantWrite )
199 {
200 XRootDStatus st = pSocketHandler->EnableUplink();
201 if( !st.IsOK() ) return st;
202 }
203 //----------------------------------------------------------------------
204 // Otherwise disable uplink
205 //----------------------------------------------------------------------
206 else if( error == XrdTls::TLS_WantRead )
207 {
208 XRootDStatus st = pSocketHandler->DisableUplink();
209 if( !st.IsOK() ) return st;
210 }
211 }
212
213 return status;
214 }
XRootDStatus EnableUplink()
Enable uplink.
XRootDStatus DisableUplink()
Disable uplink.
static Log * GetLog()
Get default log.
Handle diagnostics.
Definition XrdClLog.hh:101
void Error(uint64_t topic, const char *format,...)
Report an error.
Definition XrdClLog.cc:231
XRootDStatus Uncork()
bool IsCorked() const
bool NeedHandShake()
XrdTls::RC Connect(const char *thehost=0, std::string *eWhy=0)
@ TLS_WantWrite
Reissue call when writes do not block.
Definition XrdTls.hh:52
@ TLS_WantRead
Reissue call when reads do not block.
Definition XrdTls.hh:51
const uint64_t TlsMsg

References XrdTlsSocket::Connect(), XrdCl::AsyncSocketHandler::DisableUplink(), XrdCl::AsyncSocketHandler::EnableUplink(), XrdCl::Log::Error(), XrdCl::DefaultEnv::GetLog(), XrdCl::Socket::IsCorked(), XrdCl::Status::IsOK(), XrdTlsSocket::NeedHandShake(), XrdCl::XRootDStatus::SetErrorMessage(), XrdTls::TLS_WantRead, XrdTls::TLS_WantWrite, XrdCl::TlsMsg, and XrdCl::Socket::Uncork().

+ Here is the call graph for this function:

◆ MapEvent()

uint8_t XrdCl::Tls::MapEvent ( uint8_t event)

Map:

  • in case the TLS layer requested reads on writes map ReadyToWrite to ReadyToRead
  • in case the TLS layer requested writes on reads map ReadyToRead to ReadyToWrite

Definition at line 402 of file XrdClTls.cc.

403 {
404 if( pTlsHSRevert == ReadOnWrite )
405 {
406 //------------------------------------------------------------------------
407 // In this case we would like to call the OnRead routine on the Write event
408 //------------------------------------------------------------------------
410 }
411 else if( pTlsHSRevert == WriteOnRead )
412 {
413 //------------------------------------------------------------------------
414 // In this case we would like to call the OnWrite routine on the Read event
415 //------------------------------------------------------------------------
417 }
418
419 return event;
420 }
@ ReadyToWrite
Writing won't block.
@ ReadyToRead
New data has arrived.

References XrdCl::SocketHandler::ReadyToRead, and XrdCl::SocketHandler::ReadyToWrite.

◆ Read()

XRootDStatus XrdCl::Tls::Read ( char * buffer,
size_t size,
int & bytesRead )

Read through the TLS layer from the socket If necessary, will establish a TLS/SSL session.

Definition at line 216 of file XrdClTls.cc.

217 {
218 //--------------------------------------------------------------------------
219 // If necessary, TLS_read() will negotiate a TLS/SSL session, so we don't
220 // have to explicitly call connect or do_handshake.
221 //--------------------------------------------------------------------------
222 XrdTls::RC error = pTls->Read( buffer, size, bytesRead );
223 XRootDStatus status = ToStatus( error );
224
225 //--------------------------------------------------------------------------
226 // There's no follow up if the read simply failed
227 //--------------------------------------------------------------------------
228 if( !status.IsOK() ) return status;
229
230 if( pTls->NeedHandShake() )
231 {
232 //------------------------------------------------------------------------
233 // Make sure the socket is uncorked so the TLS hand-shake can go through
234 //------------------------------------------------------------------------
235 if( pSocket->IsCorked() )
236 {
237 XRootDStatus st = pSocket->Uncork();
238 if( !st.IsOK() ) return st;
239 }
240
241 //----------------------------------------------------------------------
242 // Check if we need to switch on a revert state
243 //----------------------------------------------------------------------
244 if( error == XrdTls::TLS_WantWrite )
245 {
246 pTlsHSRevert = ReadOnWrite;
247 XRootDStatus st = pSocketHandler->EnableUplink();
248 if( !st.IsOK() ) status = st;
249 //--------------------------------------------------------------------
250 // Return early so the revert state won't get cleared
251 //--------------------------------------------------------------------
252 return status;
253 }
254 }
255
256 //------------------------------------------------------------------------
257 // If we got up until here we need to clear the revert state
258 //------------------------------------------------------------------------
259 if( pTlsHSRevert == ReadOnWrite )
260 {
261 XRootDStatus st = pSocketHandler->DisableUplink();
262 if( !st.IsOK() ) status = st;
263 }
264 pTlsHSRevert = None;
265
266 //------------------------------------------------------------------------
267 // If we didn't manage to read any data wait for another read event
268 //------------------------------------------------------------------------
269 if( bytesRead == 0 )
270 return XRootDStatus( stOK, suRetry );
271
272 return status;
273 }
XrdTls::RC Read(char *buffer, size_t size, int &bytesRead)
Read from the TLS connection. If necessary, a handshake will be done.
const uint16_t suRetry
const uint16_t stOK
Everything went OK.

References XrdCl::AsyncSocketHandler::DisableUplink(), XrdCl::AsyncSocketHandler::EnableUplink(), XrdCl::Socket::IsCorked(), XrdCl::Status::IsOK(), XrdTlsSocket::NeedHandShake(), XrdTlsSocket::Read(), XrdCl::stOK, XrdCl::suRetry, XrdTls::TLS_WantWrite, and XrdCl::Socket::Uncork().

Referenced by ReadV().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ReadV()

XRootDStatus XrdCl::Tls::ReadV ( iovec * iov,
int iocnt,
int & bytesRead )

(Fake) ReadV through the TLS layer from the socket If necessary, will establish a TLS/SSL session.

Definition at line 279 of file XrdClTls.cc.

280 {
281 bytesRead = 0;
282 for( int i = 0; i < iocnt; ++i )
283 {
284 int btsread = 0;
285 auto st = Read( static_cast<char*>( iov[i].iov_base ),
286 iov[i].iov_len, btsread );
287 if( !st.IsOK() ) return st;
288 bytesRead += btsread;
289 if( st.code == suRetry ) return st;
290 }
291 return XRootDStatus();
292 }
XRootDStatus Read(char *buffer, size_t size, int &bytesRead)
Definition XrdClTls.cc:216

References Read(), and XrdCl::suRetry.

+ Here is the call graph for this function:

◆ Send()

XRootDStatus XrdCl::Tls::Send ( const char * buffer,
size_t size,
int & bytesWritten )

Write through the TLS layer to the socket If necessary, will establish a TLS/SSL session.

Definition at line 294 of file XrdClTls.cc.

295 {
296 //--------------------------------------------------------------------------
297 // If necessary, TLS_write() will negotiate a TLS/SSL session, so we don't
298 // have to explicitly call connect or do_handshake.
299 //--------------------------------------------------------------------------
300 XrdTls::RC error = pTls->Write( buffer, size, bytesWritten );
301 XRootDStatus status = ToStatus( error );
302
303 //--------------------------------------------------------------------------
304 // There's no follow up if the write simply failed
305 //--------------------------------------------------------------------------
306 if( !status.IsOK() ) return status;
307
308 //--------------------------------------------------------------------------
309 // We are in the middle of a TLS hand-shake
310 //--------------------------------------------------------------------------
311 if( pTls->NeedHandShake() )
312 {
313 //------------------------------------------------------------------------
314 // Make sure the socket is uncorked so the TLS hand-shake can go through
315 //------------------------------------------------------------------------
316 if( pSocket->IsCorked() )
317 {
318 XRootDStatus st = pSocket->Uncork();
319 if( !st.IsOK() ) return st;
320 }
321
322 //------------------------------------------------------------------------
323 // Check if we need to switch on a revert state
324 //------------------------------------------------------------------------
325 if( error == XrdTls::TLS_WantRead )
326 {
327 pTlsHSRevert = WriteOnRead;
328 XRootDStatus st = pSocketHandler->DisableUplink();
329 if( !st.IsOK() ) status = st;
330 //----------------------------------------------------------------------
331 // Return early so the revert state won't get cleared
332 //----------------------------------------------------------------------
333 return status;
334 }
335 }
336
337 //--------------------------------------------------------------------------
338 // If we got up until here we need to clear the revert state
339 //--------------------------------------------------------------------------
340 if( pTlsHSRevert == WriteOnRead )
341 {
342 XRootDStatus st = pSocketHandler->EnableUplink();
343 if( !st.IsOK() ) status = st;
344 }
345 pTlsHSRevert = None;
346
347 //------------------------------------------------------------------------
348 // If we didn't manage to read any data wait for another write event
349 //
350 // Adding this by symmetry, never actually experienced this (for reads
351 // it has been experienced)
352 //------------------------------------------------------------------------
353 if( bytesWritten == 0 )
354 return XRootDStatus( stOK, suRetry );
355
356 return status;
357 }
XrdTls::RC Write(const char *buffer, size_t size, int &bytesOut)

References XrdCl::AsyncSocketHandler::DisableUplink(), XrdCl::AsyncSocketHandler::EnableUplink(), XrdCl::Socket::IsCorked(), XrdCl::Status::IsOK(), XrdTlsSocket::NeedHandShake(), XrdCl::stOK, XrdCl::suRetry, XrdTls::TLS_WantRead, XrdCl::Socket::Uncork(), and XrdTlsSocket::Write().

+ Here is the call graph for this function:

◆ Shutdown()

void XrdCl::Tls::Shutdown ( )

Shutdown the TLS/SSL connection.

Definition at line 362 of file XrdClTls.cc.

363 {
364 pTls->Shutdown();
365 }
void Shutdown(SDType=sdImmed)

References XrdTlsSocket::Shutdown().

+ Here is the call graph for this function:

The documentation for this class was generated from the following files: