XRootD
Loading...
Searching...
No Matches
XrdClSocket.cc
Go to the documentation of this file.
1//------------------------------------------------------------------------------
2// Copyright (c) 2011-2012 by European Organization for Nuclear Research (CERN)
3// Author: Lukasz Janyst <ljanyst@cern.ch>
4//------------------------------------------------------------------------------
5// XRootD is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// XRootD is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
17//------------------------------------------------------------------------------
18
19#include "XrdCl/XrdClSocket.hh"
20#include "XrdCl/XrdClUtils.hh"
22#include "XrdCl/XrdClMessage.hh"
24#include "XrdCl/XrdClTls.hh"
26#include "XrdSys/XrdSysFD.hh"
27
28#include <arpa/inet.h>
29#include <unistd.h>
30#include <fcntl.h>
31#include <poll.h>
32#include <ctime>
33#include <sys/types.h>
34#include <sys/socket.h>
35#include <signal.h>
36#include <cstdlib>
37#include <cstring>
38#include <sys/uio.h>
39#include <netinet/tcp.h>
40#include <stdexcept>
41
42namespace XrdCl
43{
44 Socket::Socket( int socket, SocketStatus status ):
45 pSocket(socket), pStatus( status ),
46 pProtocolFamily( AF_INET ),
47 pChannelID( 0 ),
48 pCorked( false )
49 {
50 };
51
52 //------------------------------------------------------------------------
53 // Desctuctor
54 //------------------------------------------------------------------------
56 {
57 Close();
58 };
59
60 //----------------------------------------------------------------------------
61 // Initialize
62 //----------------------------------------------------------------------------
64 {
65 if( pSocket != -1 )
67
68 pSocket = XrdSysFD_Socket( family, SOCK_STREAM, 0 );
69 if( pSocket < 0 )
70 {
71 pSocket = -1;
73 }
74
75 pProtocolFamily = family;
76
77 //--------------------------------------------------------------------------
78 // Make the socket non blocking and disable the Nagle algorithm since
79 // we will be using this for transmitting messages not handling streams
80 //--------------------------------------------------------------------------
81 int flags;
82 if( (flags = ::fcntl( pSocket, F_GETFL, 0 )) == -1 )
83 flags = 0;
84 if( ::fcntl( pSocket, F_SETFL, flags | O_NONBLOCK | O_NDELAY ) == -1 )
85 {
86 Close();
87 return XRootDStatus( stError, errFcntl, errno );
88 }
89
91 flags = DefaultNoDelay;
92 env->GetInt( "NoDelay", flags );
93 if( setsockopt( pSocket, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof( int ) ) < 0 )
94 {
95 Close();
96 return XRootDStatus( stError, errFcntl, errno );
97 }
98
99 //--------------------------------------------------------------------------
100 // We use send with MSG_NOSIGNAL to avoid SIGPIPEs on Linux, on MacOSX
101 // we set SO_NOSIGPIPE option, on Solaris we ignore the SIGPIPE
102 //--------------------------------------------------------------------------
103#ifdef __APPLE__
104 int set = 1;
105 XRootDStatus st = SetSockOpt( SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(int) );
106 if( !st.IsOK() )
107 {
108 Close();
109 return st;
110 }
111#elif __solaris__
112 struct sigaction act;
113 act.sa_handler = SIG_IGN;
114 sigaction( SIGPIPE, &act, NULL );
115#endif
116
117 return XRootDStatus();
118 }
119
120 //----------------------------------------------------------------------------
121 // Set the socket flags
122 //----------------------------------------------------------------------------
124 {
125 if( pSocket == -1 )
127
128 int st = ::fcntl( pSocket, F_SETFL, flags );
129 if( st == -1 )
130 return XRootDStatus( stError, errSocketError, errno );
131 return XRootDStatus();
132 }
133
134 //----------------------------------------------------------------------------
135 // Get the socket flags
136 //----------------------------------------------------------------------------
138 {
139 if( pSocket == -1 )
141
142 int st = ::fcntl( pSocket, F_GETFL, 0 );
143 if( st == -1 )
144 return XRootDStatus( stError, errSocketError, errno );
145 flags = st;
146 return XRootDStatus();
147 }
148
149 //----------------------------------------------------------------------------
150 // Get socket options
151 //----------------------------------------------------------------------------
152 XRootDStatus Socket::GetSockOpt( int level, int optname, void *optval,
153 socklen_t *optlen )
154 {
155 if( pSocket == -1 )
157
158 if( ::getsockopt( pSocket, level, optname, optval, optlen ) != 0 )
159 return XRootDStatus( stError, errSocketOptError, errno );
160
161 return XRootDStatus();
162 }
163
164 //------------------------------------------------------------------------
165 // Set socket options
166 //------------------------------------------------------------------------
167 XRootDStatus Socket::SetSockOpt( int level, int optname, const void *optval,
168 socklen_t optlen )
169 {
170 if( pSocket == -1 )
172
173 if( ::setsockopt( pSocket, level, optname, optval, optlen ) != 0 )
174 return XRootDStatus( stError, errSocketOptError, errno );
175
176 return XRootDStatus();
177 }
178
179
180 //----------------------------------------------------------------------------
181 // Connect to the given host name
182 //----------------------------------------------------------------------------
183 XRootDStatus Socket::Connect( const std::string &host,
184 uint16_t port,
185 uint16_t timeout )
186 {
187 if( pSocket == -1 || pStatus == Connected || pStatus == Connecting )
189
190 std::vector<XrdNetAddr> addrs;
191 std::ostringstream o; o << host << ":" << port;
192 XRootDStatus st;
193
194 if( pProtocolFamily == AF_INET6 )
195 st = Utils::GetHostAddresses( addrs, URL( o.str() ), Utils::IPAll );
196 else
197 st = Utils::GetHostAddresses( addrs, URL( o.str() ), Utils::IPv4 );
198
199 if( !st.IsOK() )
200 return st;
201
203 addrs );
204
205
206 return ConnectToAddress( addrs[0], timeout );
207 }
208
209 //----------------------------------------------------------------------------
210 // Connect to the given host
211 //----------------------------------------------------------------------------
213 uint16_t timeout )
214 {
215 if( pSocket == -1 || pStatus == Connected || pStatus == Connecting )
217
218 pServerAddr.reset( new XrdNetAddr( addr ) );;
219
220 //--------------------------------------------------------------------------
221 // Make sure TLS is off when the physical connection is newly established
222 //--------------------------------------------------------------------------
223 pTls.reset();
224
225 //--------------------------------------------------------------------------
226 // Connect
227 //--------------------------------------------------------------------------
229 pServerAddr->SockSize(), timeout );
230 if( status != 0 )
231 {
232 XRootDStatus st( stError );
233
234 //------------------------------------------------------------------------
235 // If we connect asynchronously this is not really an error
236 //------------------------------------------------------------------------
237 if( !timeout && status == EINPROGRESS )
238 {
240 return XRootDStatus();
241 }
242
243 //------------------------------------------------------------------------
244 // Errors
245 //------------------------------------------------------------------------
246 else if( status == ETIMEDOUT )
248 else
249 st.code = errSocketError;
250 st.errNo = status;
251
252 Close();
253 return st;
254 }
256 return XRootDStatus();
257 }
258
259 //----------------------------------------------------------------------------
260 // Disconnect
261 //----------------------------------------------------------------------------
263 {
264 if( pTls ) pTls->Shutdown();
265
266 if( pSocket != -1 )
267 {
268 close( pSocket );
270 pSocket = -1;
271 pSockName = "";
272 pPeerName = "";
273 pName = "";
274 }
275 }
276
277 //----------------------------------------------------------------------------
279 //----------------------------------------------------------------------------
280 XRootDStatus Socket::ReadRaw( void *buffer, uint32_t size, int32_t timeout,
281 uint32_t &bytesRead )
282 {
283 //--------------------------------------------------------------------------
284 // Check if we're connected
285 //--------------------------------------------------------------------------
286 if( pStatus != Connected )
288
289 //--------------------------------------------------------------------------
290 // Some useful variables
291 //--------------------------------------------------------------------------
292 bytesRead = 0;
293
294 char *current = (char *)buffer;
295 bool useTimeout = (timeout!=-1);
296 time_t now = 0;
297 time_t newNow = 0;
298 XRootDStatus sc;
299
300 if( useTimeout )
301 now = ::time(0);
302
303 //--------------------------------------------------------------------------
304 // Repeat the following until we have read all the requested data
305 //--------------------------------------------------------------------------
306 while ( bytesRead < size )
307 {
308 //------------------------------------------------------------------------
309 // Check if we can read something
310 //------------------------------------------------------------------------
311 sc = Poll( true, false, useTimeout ? timeout : -1 );
312
313 //------------------------------------------------------------------------
314 // It looks like we've got an event. Let's check if we can read something.
315 //------------------------------------------------------------------------
316 if( sc.status == stOK )
317 {
318 ssize_t n = ::read( pSocket, current, (size-bytesRead) );
319
320 if( n > 0 )
321 {
322 bytesRead += n;
323 current += n;
324 }
325
326 //----------------------------------------------------------------------
327 // We got a close here - this means that there is no more data in
328 // the buffer so we disconnect
329 //----------------------------------------------------------------------
330 if( n == 0 )
331 {
332 Close();
334 }
335
336 //----------------------------------------------------------------------
337 // Error
338 //----------------------------------------------------------------------
339 if( (n < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) )
340 {
341 Close();
342 return XRootDStatus( stError, errSocketError, errno );
343 }
344 }
345 else
346 {
347 Close();
348 return sc;
349 }
350
351 //------------------------------------------------------------------------
352 // Do we still have time to wait for data?
353 //------------------------------------------------------------------------
354 if( useTimeout )
355 {
356 newNow = ::time(0);
357 timeout -= (newNow-now);
358 now = newNow;
359 if( timeout < 0 )
360 break;
361 }
362 }
363
364 //--------------------------------------------------------------------------
365 // Have we managed to read everything?
366 //--------------------------------------------------------------------------
367 if( bytesRead < size )
369 return XRootDStatus( stOK );
370 }
371
372 //----------------------------------------------------------------------------
373 // Write raw bytes to the socket
374 //----------------------------------------------------------------------------
375 XRootDStatus Socket::WriteRaw( void *buffer, uint32_t size, int32_t timeout,
376 uint32_t &bytesWritten )
377 {
378 //--------------------------------------------------------------------------
379 // Check if we're connected
380 //--------------------------------------------------------------------------
381 if( pStatus != Connected )
383
384 //--------------------------------------------------------------------------
385 // Some useful variables
386 //--------------------------------------------------------------------------
387 bytesWritten = 0;
388
389 char *current = (char *)buffer;
390 bool useTimeout = (timeout!=-1);
391 time_t now = 0;
392 time_t newNow = 0;
393 XRootDStatus sc;
394
395 if( useTimeout )
396 now = ::time(0);
397
398 //--------------------------------------------------------------------------
399 // Repeat the following until we have written everything
400 //--------------------------------------------------------------------------
401 while ( bytesWritten < size )
402 {
403 //------------------------------------------------------------------------
404 // Check if we can read something
405 //------------------------------------------------------------------------
406 sc = Poll( false, true, useTimeout ? timeout : -1 );
407
408 //------------------------------------------------------------------------
409 // Let's write
410 //------------------------------------------------------------------------
411 if( sc.status == stOK )
412 {
413 ssize_t n = ::write( pSocket, current, (size-bytesWritten) );
414
415 if( n > 0 )
416 {
417 bytesWritten += n;
418 current += n;
419 }
420
421 //----------------------------------------------------------------------
422 // Error
423 //----------------------------------------------------------------------
424 if( (n <= 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) )
425 {
426 Close();
427 return XRootDStatus( stError, errSocketError, errno );
428 }
429 }
430 else
431 {
432 Close();
433 return sc;
434 }
435
436 //------------------------------------------------------------------------
437 // Do we still have time to wait for data?
438 //------------------------------------------------------------------------
439 if( useTimeout )
440 {
441 newNow = ::time(0);
442 timeout -= (newNow-now);
443 now = newNow;
444 if( timeout < 0 )
445 break;
446 }
447 }
448
449 //--------------------------------------------------------------------------
450 // Have we managed to read everything?
451 //--------------------------------------------------------------------------
452 if( bytesWritten < size )
454
455 return XRootDStatus( stOK );
456 }
457
458 //------------------------------------------------------------------------
459 // Portable wrapper around SIGPIPE free send
460 //----------------------------------------------------------------------------
461 XRootDStatus Socket::Send( const char *buffer, size_t size, int &bytesWritten )
462 {
463 if( pTls ) return pTls->Send( buffer, size, bytesWritten );
464
465 //--------------------------------------------------------------------------
466 // We use send with MSG_NOSIGNAL to avoid SIGPIPEs on Linux
467 //--------------------------------------------------------------------------
468#if defined(__linux__) || defined(__GNU__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
469 int status = ::send( pSocket, buffer, size, MSG_NOSIGNAL );
470#else
471 int status = ::write( pSocket, buffer, size );
472#endif
473
474 if( status <= 0 )
475 return ClassifyErrno( errno );
476
477 bytesWritten = status;
478 return XRootDStatus();
479 }
480
481 //------------------------------------------------------------------------
486 //------------------------------------------------------------------------
487 XRootDStatus Socket::Send( XrdSys::KernelBuffer &kbuff, int &bytesWritten )
488 {
489 if( pTls ) return XRootDStatus( stError, errNotSupported, 0,
490 "Cannot send a kernel-buffer over TLS." );
491
492 ssize_t status = XrdSys::Send( pSocket, kbuff );
493
494 if( status <= 0 )
495 return ClassifyErrno( errno );
496 bytesWritten += status;
497 return XRootDStatus();
498 }
499
500 //------------------------------------------------------------------------
501 // Write message to the socket
502 //------------------------------------------------------------------------
503 XRootDStatus Socket::Send( Message &msg, const std::string &strmname )
504 {
505 //----------------------------------------------------------------------
506 // Try to write down the current message
507 //----------------------------------------------------------------------
508 size_t btsleft = msg.GetSize() - msg.GetCursor();
509 if( !btsleft ) return XRootDStatus();
510
511 while( btsleft )
512 {
513 int wrtcnt = 0;
514 XRootDStatus st = Send( msg.GetBufferAtCursor(), btsleft, wrtcnt );
515
516 if( !st.IsOK() )
517 {
518 msg.SetCursor( 0 );
519 return st;
520 }
521
522 if( st.code == suRetry ) return st;
523
524 msg.AdvanceCursor( wrtcnt );
525 btsleft -= wrtcnt;
526 }
527
528 //----------------------------------------------------------------------
529 // We have written the message successfully
530 //----------------------------------------------------------------------
531 Log *log = DefaultEnv::GetLog();
532 log->Dump( AsyncSockMsg, "[%s] Wrote a message: %s (%p), %d bytes",
533 strmname.c_str(), msg.GetObfuscatedDescription().c_str(),
534 &msg, msg.GetSize() );
535 return XRootDStatus();
536 }
537
538 //----------------------------------------------------------------------------
539 // Poll the descriptor
540 //----------------------------------------------------------------------------
541 XRootDStatus Socket::Poll( bool readyForReading, bool readyForWriting,
542 int32_t timeout )
543 {
544 //--------------------------------------------------------------------------
545 // Check if we're connected
546 //--------------------------------------------------------------------------
547 if( pStatus != Connected )
549
550 //--------------------------------------------------------------------------
551 // Prepare the stuff
552 //--------------------------------------------------------------------------
553 pollfd pollDesc;
554 int pollRet;
555 bool useTimeout = (timeout!=-1);
556 time_t now = 0;
557 time_t newNow = 0;
558 short hupEvents = POLLHUP;
559
560#ifdef __linux__
561 hupEvents |= POLLRDHUP;
562#endif
563
564 if( useTimeout )
565 now = ::time(0);
566
567 pollDesc.fd = pSocket;
568 pollDesc.events = POLLERR | POLLNVAL | hupEvents;
569
570 if( readyForReading )
571 pollDesc.events |= (POLLIN | POLLPRI);
572
573 if( readyForWriting )
574 pollDesc.events |= POLLOUT;
575
576 //--------------------------------------------------------------------------
577 // We loop on poll because it may return -1 even thought no fatal error
578 // has occurred, these may be:
579 // * a signal interrupting the execution (errno == EINTR)
580 // * a failure to initialize some internal structures (Solaris only)
581 // (errno == EAGAIN)
582 //--------------------------------------------------------------------------
583 do
584 {
585 pollRet = poll( &pollDesc, 1, (useTimeout ? timeout*1000 : -1) );
586 if( (pollRet < 0) && (errno != EINTR) && (errno != EAGAIN) )
587 return XRootDStatus( stError, errPoll, errno );
588
589 //------------------------------------------------------------------------
590 // Check if we did not time out in the case where we are not supposed
591 // to wait indefinitely
592 //------------------------------------------------------------------------
593 if( useTimeout )
594 {
595 newNow = time(0);
596 timeout -= (newNow-now);
597 now = newNow;
598 if( timeout < 0 )
600 }
601 }
602 while( pollRet == -1 );
603
604 //--------------------------------------------------------------------------
605 // Check if we have timed out
606 //--------------------------------------------------------------------------
607 if( pollRet == 0 )
609
610 //--------------------------------------------------------------------------
611 // We have some events
612 //--------------------------------------------------------------------------
613 if( pollDesc.revents & (POLLIN | POLLPRI | POLLOUT) )
614 return XRootDStatus( stOK );
615
616 //--------------------------------------------------------------------------
617 // We've been hang up on
618 //--------------------------------------------------------------------------
619 if( pollDesc.revents & hupEvents )
621
622 //--------------------------------------------------------------------------
623 // We're messed up, either because we messed up ourselves (POLLNVAL) or
624 // got messed up by the network (POLLERR)
625 //--------------------------------------------------------------------------
627 }
628
629 //----------------------------------------------------------------------------
630 // Get the name of the socket
631 //----------------------------------------------------------------------------
632 std::string Socket::GetSockName() const
633 {
634 if( pStatus != Connected )
635 return "";
636
637 if( pSockName.length() )
638 return pSockName;
639
640 char nameBuff[256];
641 int len = XrdNetUtils::IPFormat( -pSocket, nameBuff, sizeof(nameBuff) );
642 if( len == 0 )
643 return "";
644
645 pSockName = nameBuff;
646 return pSockName;
647 }
648
649 //----------------------------------------------------------------------------
650 // Get the name of the remote peer
651 //----------------------------------------------------------------------------
652 std::string Socket::GetPeerName() const
653 {
654 if( pStatus != Connected )
655 return "";
656
657 if( pPeerName.length() )
658 return pPeerName;
659
660 char nameBuff[256];
661 int len = XrdNetUtils::IPFormat( pSocket, nameBuff, sizeof(nameBuff) );
662 if( len == 0 )
663 return "";
664
665 pPeerName = nameBuff;
666 return pPeerName;
667 }
668
669 //----------------------------------------------------------------------------
670 // Get the string representation of the socket
671 //----------------------------------------------------------------------------
672 std::string Socket::GetName() const
673 {
674 if( pStatus != Connected )
675 return "<x><--><x>";
676
677 if( pName.length() )
678 return pName;
679
680 pName = "<";
681 pName += GetSockName();
682 pName += "><--><";
683 pName += GetPeerName();
684 pName += ">";
685 return pName;
686 }
687
688
689 //------------------------------------------------------------------------
690 // Classify errno while reading/writing
691 //------------------------------------------------------------------------
693 {
694 switch( errno )
695 {
696
697 case EAGAIN:
698#if EAGAIN != EWOULDBLOCK
699 case EWOULDBLOCK:
700#endif
701 {
702 //------------------------------------------------------------------
703 // Reading/writing operation would block! So we are done for now,
704 // but we will be back ;-)
705 //------------------------------------------------------------------
706 return XRootDStatus( stOK, suRetry );
707 }
708 case ECONNRESET:
709 case EDESTADDRREQ:
710 case EMSGSIZE:
711 case ENOTCONN:
712 case ENOTSOCK:
713 {
714 //------------------------------------------------------------------
715 // Actual socket error error!
716 //------------------------------------------------------------------
717 return XRootDStatus( stError, errSocketError, errno );
718 }
719 case EFAULT:
720 {
721 //------------------------------------------------------------------
722 // The buffer provided by the user for reading/writing is invalid
723 //------------------------------------------------------------------
725 }
726 default:
727 {
728 //------------------------------------------------------------------
729 // Not a socket error
730 //------------------------------------------------------------------
731 return XRootDStatus( stError, errInternal, errno );
732 }
733 }
734 }
735
736
737 //----------------------------------------------------------------------------
738 // Read helper from raw socket helper
739 //----------------------------------------------------------------------------
740 XRootDStatus Socket::Read( char *buffer, size_t size, int &bytesRead )
741 {
742 if( pTls ) return pTls->Read( buffer, size, bytesRead );
743
744 int status = ::read( pSocket, buffer, size );
745
746 // if the server shut down the socket declare a socket error (it
747 // will trigger a re-connect)
748 if( status == 0 )
749 return XRootDStatus( stError, errSocketError, errno );
750
751 if( status < 0 )
752 return ClassifyErrno( errno );
753
754 bytesRead = status;
755 return XRootDStatus();
756 }
757
758 //----------------------------------------------------------------------------
759 // ReadV helper for raw socket
760 //----------------------------------------------------------------------------
761 XRootDStatus Socket::ReadV( iovec *iov, int iovcnt, int &bytesRead )
762 {
763 if( pTls ) return pTls->ReadV( iov, iovcnt, bytesRead );
764
765 int status = ::readv( pSocket, iov, iovcnt );
766
767 // if the server shut down the socket declare a socket error (it
768 // will trigger a re-connect)
769 if( status == 0 )
770 return XRootDStatus( stError, errSocketError, errno );
771
772 if( status < 0 )
773 return ClassifyErrno( errno );
774
775 bytesRead = status;
776 return XRootDStatus();
777 }
778
779 //------------------------------------------------------------------------
780 // Cork the underlying socket
781 //------------------------------------------------------------------------
783 {
784#if defined(TCP_CORK) && !defined(__GNU__)
785 // it's not defined on mac, we might want explore the possibility of using TCP_NOPUSH
786 if( pCorked ) return XRootDStatus();
787
788 int state = 1;
789 int rc = setsockopt( pSocket, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) );
790 if( rc != 0 )
791 return XRootDStatus( stFatal, errSocketOptError, errno );
792#endif
793 pCorked = true;
794 return XRootDStatus();
795 }
796
797 //------------------------------------------------------------------------
798 // Uncork the underlying socket
799 //------------------------------------------------------------------------
801 {
802#if defined(TCP_CORK) && !defined(__GNU__)
803 // it's not defined on mac, we might want explore the possibility of using TCP_NOPUSH
804 if( !pCorked ) return XRootDStatus();
805
806 int state = 0;
807 int rc = setsockopt( pSocket, IPPROTO_TCP, TCP_CORK, &state, sizeof( state ) );
808 if( rc != 0 )
809 return XRootDStatus( stFatal, errSocketOptError, errno );
810#endif
811 pCorked = false;
812 return XRootDStatus();
813 }
814
815 //------------------------------------------------------------------------
816 // Flash the underlying socket
817 //------------------------------------------------------------------------
819 {
820 //----------------------------------------------------------------------
821 // Uncork the socket in order to flash the socket
822 //----------------------------------------------------------------------
823 XRootDStatus st = Uncork();
824 if( !st.IsOK() ) return st;
825
826 //----------------------------------------------------------------------
827 // Once the data has been flashed we can cork the socket back
828 //----------------------------------------------------------------------
829 return Cork();
830 }
831
832 //------------------------------------------------------------------------
833 // Do special event mapping if applicable
834 //------------------------------------------------------------------------
835 uint8_t Socket::MapEvent( uint8_t event )
836 {
837 if( pTls ) return pTls->MapEvent( event );
838 return event;
839 }
840
841 //------------------------------------------------------------------------
842 // Enable encryption
843 //------------------------------------------------------------------------
845 const std::string &thehost )
846 {
847 try
848 {
850 if( !pTls ) pTls.reset( new Tls( this, socketHandler ) );
851 return pTls->Connect( thehost, pServerAddr.get() );
852 }
853 catch( std::exception& ex )
854 {
855 // the exception has been thrown when we tried to create
856 // the TLS context
857 return XRootDStatus( stFatal, errTlsError, 0, ex.what() );
858 }
859
860 return XRootDStatus();
861 }
862
863 //------------------------------------------------------------------------
864 // @return : true if socket is using TLS layer for encryption,
865 // false otherwise
866 //------------------------------------------------------------------------
868 {
869 return bool( pTls.get() );
870 }
871
872}
873
874
#define IPPROTO_TCP
int fcntl(int fd, int cmd,...)
#define close(a)
Definition XrdPosix.hh:48
#define write(a, b, c)
Definition XrdPosix.hh:115
#define readv(a, b, c)
Definition XrdPosix.hh:84
#define read(a, b, c)
Definition XrdPosix.hh:82
void AdvanceCursor(uint32_t delta)
Advance the cursor.
char * GetBufferAtCursor()
Get the buffer pointer at the append cursor.
void SetCursor(uint32_t cursor)
Set the cursor.
uint32_t GetCursor() const
Get append cursor.
uint32_t GetSize() const
Get the size of the message.
static Log * GetLog()
Get default log.
static Env * GetEnv()
Get default client environment.
bool GetInt(const std::string &key, int &value)
Definition XrdClEnv.cc:89
Handle diagnostics.
Definition XrdClLog.hh:101
void Dump(uint64_t topic, const char *format,...)
Print a dump message.
Definition XrdClLog.cc:299
The message representation used throughout the system.
const std::string & GetObfuscatedDescription() const
Get the description of the message with authz parameter obfuscated.
std::string GetSockName() const
Get the name of the socket.
std::string pSockName
std::string GetName() const
Get the string representation of the socket.
virtual XRootDStatus Send(const char *buffer, size_t size, int &bytesWritten)
XRootDStatus Initialize(int family=AF_INET)
Initialize the socket.
static XRootDStatus ClassifyErrno(int error)
Socket(int socket=-1, SocketStatus status=Disconnected)
SocketStatus
Status of the socket.
@ Disconnected
The socket is disconnected.
@ Connected
The socket is connected.
@ Connecting
The connection process is in progress.
XRootDStatus Flash()
SocketStatus pStatus
XRootDStatus Uncork()
virtual XRootDStatus Read(char *buffer, size_t size, int &bytesRead)
std::unique_ptr< Tls > pTls
XRootDStatus ConnectToAddress(const XrdNetAddr &addr, uint16_t timout=10)
void Close()
Disconnect.
XRootDStatus SetSockOpt(int level, int optname, const void *optval, socklen_t optlen)
Set socket options.
XRootDStatus ReadV(iovec *iov, int iocnt, int &bytesRead)
XRootDStatus TlsHandShake(AsyncSocketHandler *socketHandler, const std::string &thehost=std::string())
XRootDStatus GetFlags(int &flags)
Get the socket flags (man fcntl)
uint8_t MapEvent(uint8_t event)
std::string pName
XRootDStatus Connect(const std::string &host, uint16_t port, uint16_t timout=10)
XRootDStatus Cork()
XRootDStatus GetSockOpt(int level, int optname, void *optval, socklen_t *optlen)
Get socket options.
XRootDStatus WriteRaw(void *buffer, uint32_t size, int32_t timeout, uint32_t &bytesWritten)
std::string pPeerName
XRootDStatus ReadRaw(void *buffer, uint32_t size, int32_t timeout, uint32_t &bytesRead)
Read raw bytes from the socket.
XRootDStatus Poll(bool readyForReading, bool readyForWriting, int32_t timeout)
virtual ~Socket()
Desctuctor.
std::unique_ptr< XrdNetAddr > pServerAddr
XRootDStatus SetFlags(int flags)
Set the socket flags (man fcntl)
std::string GetPeerName() const
Get the name of the remote peer.
TLS layer for socket connection.
Definition XrdClTls.hh:40
URL representation.
Definition XrdClURL.hh:31
static void LogHostAddresses(Log *log, uint64_t type, const std::string &hostId, std::vector< XrdNetAddr > &addresses)
Log all the addresses on the list.
static Status GetHostAddresses(std::vector< XrdNetAddr > &addresses, const URL &url, AddressType type)
Resolve IP addresses.
const sockaddr * SockAddr()
SOCKLEN_t SockSize()
static int Connect(int fd, const struct sockaddr *name, int namelen, int tsec=-1)
static int IPFormat(const struct sockaddr *sAddr, char *bP, int bL, int opts=0)
const uint16_t errPoll
error while polling descriptors
const uint16_t suRetry
const uint16_t errSocketOptError
const uint16_t errTlsError
const uint16_t stFatal
Fatal error, it's still an error.
const uint16_t stError
An error occurred that could potentially be retried.
const uint64_t PostMasterMsg
const uint16_t errSocketTimeout
const uint16_t errInternal
Internal error.
const uint16_t stOK
Everything went OK.
const uint16_t errInvalidOp
const uint64_t AsyncSockMsg
const uint16_t errInvalidArgs
const uint16_t errNotSupported
const uint16_t errSocketError
const uint16_t errFcntl
failed manipulate file descriptor
const int DefaultNoDelay
const uint16_t errSocketDisconnected
ssize_t Send(int fd, KernelBuffer &buffer)
uint16_t code
Error type, or additional hints on what to do.
uint16_t status
Status of the execution.
bool IsOK() const
We're fine.
uint32_t errNo
Errno, if any.