28 #include <arpa/inet.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
39 #include <netinet/tcp.h>
45 pSocket(socket), pStatus( status ),
46 pProtocolFamily( AF_INET ),
68 pSocket = XrdSysFD_Socket( family, SOCK_STREAM, 0 );
84 if( ::
fcntl(
pSocket, F_SETFL, flags | O_NONBLOCK | O_NDELAY ) == -1 )
92 env->
GetInt(
"NoDelay", flags );
112 struct sigaction act;
113 act.sa_handler = SIG_IGN;
114 sigaction( SIGPIPE, &act, NULL );
158 if( ::getsockopt(
pSocket, level, optname, optval, optlen ) != 0 )
173 if( ::setsockopt(
pSocket, level, optname, optval, optlen ) != 0 )
190 std::vector<XrdNetAddr> addrs;
191 std::ostringstream o; o << host <<
":" << port;
237 if( !timeout && status == EINPROGRESS )
246 else if( status == ETIMEDOUT )
281 uint32_t &bytesRead )
294 char *current = (
char *)buffer;
295 bool useTimeout = (timeout!=-1);
306 while ( bytesRead < size )
311 sc =
Poll(
true,
false, useTimeout ? timeout : -1 );
339 if( (n < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) )
357 timeout -= (newNow-now);
367 if( bytesRead < size )
376 uint32_t &bytesWritten )
389 char *current = (
char *)buffer;
390 bool useTimeout = (timeout!=-1);
401 while ( bytesWritten < size )
406 sc =
Poll(
false,
true, useTimeout ? timeout : -1 );
424 if( (n <= 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) )
442 timeout -= (newNow-now);
452 if( bytesWritten < size )
463 if(
pTls )
return pTls->Send( buffer, size, bytesWritten );
468 #if defined(__linux__) || defined(__GNU__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
469 int status = ::send(
pSocket, buffer, size, MSG_NOSIGNAL );
477 bytesWritten = status;
490 "Cannot send a kernel-buffer over TLS." );
496 bytesWritten += status;
555 bool useTimeout = (timeout!=-1);
558 short hupEvents = POLLHUP;
561 hupEvents |= POLLRDHUP;
568 pollDesc.events = POLLERR | POLLNVAL | hupEvents;
570 if( readyForReading )
571 pollDesc.events |= (POLLIN | POLLPRI);
573 if( readyForWriting )
574 pollDesc.events |= POLLOUT;
585 pollRet = poll( &pollDesc, 1, (useTimeout ? timeout*1000 : -1) );
586 if( (pollRet < 0) && (errno != EINTR) && (errno != EAGAIN) )
596 timeout -= (newNow-now);
602 while( pollRet == -1 );
613 if( pollDesc.revents & (POLLIN | POLLPRI | POLLOUT) )
619 if( pollDesc.revents & hupEvents )
698 #if EAGAIN != EWOULDBLOCK
742 if(
pTls )
return pTls->Read( buffer, size, bytesRead );
763 if(
pTls )
return pTls->ReadV(
iov, iovcnt, bytesRead );
784 #if defined(TCP_CORK) && !defined(__GNU__)
802 #if defined(TCP_CORK) && !defined(__GNU__)
824 if( !st.
IsOK() )
return st;
837 if(
pTls )
return pTls->MapEvent( event );
845 const std::string &thehost )
850 if( !
pTls )
pTls.reset(
new Tls(
this, socketHandler ) );
853 catch( std::exception& ex )
869 return bool(
pTls.get() );
int fcntl(int fd, int cmd,...)
ssize_t readv(int fildes, const struct iovec *iov, int iovcnt)
ssize_t write(int fildes, const void *buf, size_t nbyte)
ssize_t read(int fildes, void *buf, size_t nbyte)
void AdvanceCursor(uint32_t delta)
Advance the 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.
char * GetBufferAtCursor()
Get the buffer pointer at the append cursor.
static Log * GetLog()
Get default log.
static Env * GetEnv()
Get default client environment.
bool GetInt(const std::string &key, int &value)
void Dump(uint64_t topic, const char *format,...)
Print a dump message.
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 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.
virtual XRootDStatus Read(char *buffer, size_t size, int &bytesRead)
std::unique_ptr< Tls > pTls
XRootDStatus ConnectToAddress(const XrdNetAddr &addr, uint16_t timout=10)
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)
XRootDStatus Connect(const std::string &host, uint16_t port, uint16_t timout=10)
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)
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.
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.
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 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 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.