XRootD
Loading...
Searching...
No Matches
XrdLinkXeq Class Reference

#include <XrdLinkXeq.hh>

+ Inheritance diagram for XrdLinkXeq:
+ Collaboration diagram for XrdLinkXeq:

Public Member Functions

 XrdLinkXeq ()
 
 ~XrdLinkXeq ()
 
XrdNetAddrInfoAddrInfo ()
 
int Backlog ()
 
int Client (char *buff, int blen)
 
int Close (bool defer=false)
 
void DoIt ()
 
int getIOStats (long long &inbytes, long long &outbytes, int &numstall, int &numtardy)
 
XrdTlsPeerCertsgetPeerCerts ()
 
XrdProtocolgetProtocol ()
 
const char * Name () const
 
const XrdNetAddrNetAddr () const
 
int Peek (char *buff, int blen, int timeout=-1)
 
int Recv (char *buff, int blen)
 
int Recv (char *buff, int blen, int timeout)
 
int Recv (const struct iovec *iov, int iocnt, int timeout)
 
int RecvAll (char *buff, int blen, int timeout=-1)
 
bool Register (const char *hName)
 
int Send (const char *buff, int blen)
 
int Send (const sfVec *sdP, int sdn)
 
int Send (const struct iovec *iov, int iocnt, int bytes=0)
 
void setID (const char *userid, int procid)
 
void setLocation (XrdNetAddrInfo::LocInfo &loc)
 
bool setNB ()
 
void setProtName (const char *name)
 
XrdProtocolsetProtocol (XrdProtocol *pp, bool push)
 
bool setTLS (bool enable, XrdTlsContext *ctx=0)
 
void Shutdown (bool getLock)
 
void syncStats (int *ctime=0)
 
int TLS_Peek (char *Buff, int Blen, int timeout)
 
int TLS_Recv (char *Buff, int Blen)
 
int TLS_Recv (char *Buff, int Blen, int timeout, bool havelock=false)
 
int TLS_Recv (const struct iovec *iov, int iocnt, int timeout)
 
int TLS_RecvAll (char *Buff, int Blen, int timeout)
 
int TLS_Send (const char *Buff, int Blen)
 
int TLS_Send (const sfVec *sfP, int sfN)
 
int TLS_Send (const struct iovec *iov, int iocnt, int bytes)
 
const char * verTLS ()
 

Static Public Member Functions

static int getName (int &curr, char *bname, int blen, XrdLinkMatch *who=0)
 
static int Stats (char *buff, int blen, bool do_sync=false)
 

Public Attributes

XrdLinkInfo LinkInfo
 
XrdPollInfo PollInfo
 

Protected Member Functions

int RecvIOV (const struct iovec *iov, int iocnt)
 
void Reset ()
 
int sendData (const char *Buff, int Blen)
 
int SendIOV (const struct iovec *iov, int iocnt, int bytes)
 
int SFError (int rc)
 
int TLS_Error (const char *act, XrdTls::RC rc)
 
bool TLS_Write (const char *Buff, int Blen)
 
- Protected Member Functions inherited from XrdJob
 XrdJob (const char *desc="")
 
virtual ~XrdJob ()
 

Protected Attributes

XrdNetAddr Addr
 
long long BytesIn
 
long long BytesInTot
 
long long BytesOut
 
long long BytesOutTot
 
int HNlen
 
char isIdle
 
bool KeepFD
 
char Lname [256]
 
bool LockReads
 
XrdProtocolProtoAlt
 
XrdProtocolProtocol
 
XrdSysMutex rdMutex
 
XrdSendQsendQ
 
int SfIntr
 
int stallCnt
 
int stallCntTot
 
int tardyCnt
 
int tardyCntTot
 
XrdTlsSocket tlsIO
 
char Uname [24]
 
XrdSysMutex wrMutex
 
- Protected Attributes inherited from XrdJob
const char * Comment
 
XrdJobNextJob
 

Static Protected Attributes

static long long LinkBytesIn = 0
 
static long long LinkBytesOut = 0
 
static long long LinkConTime = 0
 
static int LinkCount = 0
 
static int LinkCountMax = 0
 
static long long LinkCountTot = 0
 
static int LinkSfIntr = 0
 
static int LinkStalls = 0
 
static int LinkTimeOuts = 0
 
static XrdSysMutex statsMutex
 
static const char * TraceID = "LinkXeq"
 

Additional Inherited Members

Detailed Description

Definition at line 52 of file XrdLinkXeq.hh.

Constructor & Destructor Documentation

◆ XrdLinkXeq()

XrdLinkXeq::XrdLinkXeq ( )

Definition at line 108 of file XrdLinkXeq.cc.

108 : XrdLink(*this), PollInfo((XrdLink &)*this)
109{
111}
void Reset()
XrdPollInfo PollInfo

References XrdLink::XrdLink(), PollInfo, and Reset().

+ Here is the call graph for this function:

◆ ~XrdLinkXeq()

XrdLinkXeq::~XrdLinkXeq ( )
inline

Definition at line 142 of file XrdLinkXeq.hh.

142{} // Is never deleted!

Member Function Documentation

◆ AddrInfo()

XrdNetAddrInfo * XrdLinkXeq::AddrInfo ( )
inline

Definition at line 57 of file XrdLinkXeq.hh.

57{return (XrdNetAddrInfo *)&Addr;}
XrdNetAddr Addr

References Addr.

◆ Backlog()

int XrdLinkXeq::Backlog ( )

Definition at line 139 of file XrdLinkXeq.cc.

140{
141 XrdSysMutexHelper lck(wrMutex);
142
143// Return backlog information
144//
145 return (sendQ ? sendQ->Backlog() : 0);
146}
XrdSysMutex wrMutex
XrdSendQ * sendQ

References sendQ, and wrMutex.

◆ Client()

int XrdLinkXeq::Client ( char * buff,
int blen )

Definition at line 152 of file XrdLinkXeq.cc.

153{
154 int ulen;
155
156// Generate full client name
157//
158 if (nbsz <= 0) return 0;
159 ulen = (Lname - ID);
160 if ((ulen + HNlen) >= nbsz) ulen = 0;
161 else {strncpy(nbuf, ID, ulen);
162 strcpy(nbuf+ulen, HostName);
163 ulen += HNlen;
164 }
165 return ulen;
166}
char Lname[256]

References HNlen, XrdLink::HostName, XrdLink::ID, and Lname.

Referenced by XrdLinkCtl::getName().

+ Here is the caller graph for this function:

◆ Close()

int XrdLinkXeq::Close ( bool defer = false)

Definition at line 172 of file XrdLinkXeq.cc.

173{ XrdSysMutexHelper opHelper(LinkInfo.opMutex);
174 int csec, fd, rc = 0;
175
176// If a defer close is requested, we can close the descriptor but we must
177// keep the slot number to prevent a new client getting the same fd number.
178// Linux is peculiar in that any in-progress operations will remain in that
179// state even after the FD is closed unless there is some activity either on
180// the connection or an event occurs that causes an operation restart. We
181// portably solve this problem by issuing a shutdown() on the socket prior
182// closing it. On most platforms, this informs readers that the connection is
183// gone (though not on old (i.e. <= 2.3) versions of Linux, sigh). Also, if
184// nonblocking mode is enabled, we need to do this in a separate thread as
185// a shutdown may block for a pretty long time if lots\ of messages are queued.
186// We will ask the SendQ object to schedule the shutdown for us before it
187// commits suicide.
188// Note that we can hold the opMutex while we also get the wrMutex.
189//
190 if (defer)
191 {if (!sendQ) Shutdown(false);
192 else {TRACEI(DEBUG, "Shutdown FD " <<LinkInfo.FD<<" only via SendQ");
193 LinkInfo.InUse++;
194 LinkInfo.FD = -LinkInfo.FD; // Leave poll version untouched!
195 wrMutex.Lock();
196 sendQ->Terminate(this);
197 sendQ = 0;
198 wrMutex.UnLock();
199 }
200 return 0;
201 }
202
203// If we got here then this is not a deferred close so we just need to check
204// if there is a sendq appendage we need to get rid of.
205//
206 if (sendQ)
207 {wrMutex.Lock();
208 sendQ->Terminate();
209 sendQ = 0;
210 wrMutex.UnLock();
211 }
212
213// Multiple protocols may be bound to this link. If it is in use, defer the
214// actual close until the use count drops to one.
215//
216 while(LinkInfo.InUse > 1)
217 {opHelper.UnLock();
218 TRACEI(DEBUG, "Close FD "<<LinkInfo.FD <<" deferred, use count="
219 <<LinkInfo.InUse);
220 Serialize();
221 opHelper.Lock(&LinkInfo.opMutex);
222 }
223 LinkInfo.InUse--;
224 Instance = 0;
225
226// Add up the statistic for this link
227//
228 syncStats(&csec);
229
230// Cleanup TLS if it is active
231//
232 if (isTLS) tlsIO.Shutdown();
233
234// Clean this link up
235//
236 if (Protocol) {Protocol->Recycle(this, csec, LinkInfo.Etext); Protocol = 0;}
237 if (ProtoAlt) {ProtoAlt->Recycle(this, csec, LinkInfo.Etext); ProtoAlt = 0;}
238 if (LinkInfo.Etext) {free(LinkInfo.Etext); LinkInfo.Etext = 0;}
239 LinkInfo.InUse = 0;
240
241// At this point we can have no lock conflicts, so if someone is waiting for
242// us to terminate let them know about it. Note that we will get the condvar
243// mutex while we hold the opMutex. This is the required order! We will also
244// zero out the pointer to the condvar while holding the opmutex.
245//
246 if (LinkInfo.KillcvP)
247 {LinkInfo.KillcvP->Lock();
248 LinkInfo.KillcvP->Signal();
249 LinkInfo.KillcvP->UnLock();
250 LinkInfo.KillcvP = 0;
251 }
252
253// Remove ourselves from the poll table and then from the Link table. We may
254// not hold on to the opMutex when we acquire the LTMutex. However, the link
255// table needs to be cleaned up prior to actually closing the socket. So, we
256// do some fancy footwork to prevent multiple closes of this link.
257//
258 fd = abs(LinkInfo.FD);
259 if (PollInfo.FD > 0)
260 {if (PollInfo.Poller) {XrdPoll::Detach(PollInfo); PollInfo.Poller = 0;}
261 PollInfo.FD = -1;
262 opHelper.UnLock();
264 } else opHelper.UnLock();
265
266// Invoke the TCP monitor if it was loaded.
267//
268 if (TcpMonPin && fd > 2)
269 {XrdTcpMonPin::LinkInfo lnkInfo;
270 lnkInfo.tident = ID;
271 lnkInfo.fd = fd;
272 lnkInfo.consec = csec;
273 lnkInfo.bytesIn = BytesInTot;
274 lnkInfo.bytesOut = BytesOutTot;
275 TcpMonPin->Monitor(Addr, lnkInfo, sizeof(lnkInfo));
276 }
277
278// Close the file descriptor if it isn't being shared. Do it as the last
279// thing because closes and accepts and not interlocked.
280//
281 if (fd >= 2) {if (KeepFD) rc = 0;
282 else rc = (close(fd) < 0 ? errno : 0);
283 }
284 if (rc) Log.Emsg("Link", rc, "close", ID);
285 return rc;
286}
#define DEBUG(x)
#define close(a)
Definition XrdPosix.hh:48
#define TRACEI(act, x)
Definition XrdTrace.hh:66
static void Unhook(int fd)
Unhook a link from the active table of links.
XrdLinkInfo LinkInfo
XrdProtocol * ProtoAlt
long long BytesInTot
long long BytesOutTot
void Shutdown(bool getLock)
XrdTlsSocket tlsIO
XrdProtocol * Protocol
void syncStats(int *ctime=0)
static void Detach(XrdPollInfo &pInfo)
Definition XrdPoll.cc:177
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
int fd
Socket file descriptor.
long long bytesOut
Bytes written to the socket.
int consec
Seconds connected.
virtual void Monitor(XrdNetAddrInfo &netInfo, LinkInfo &lnkInfo, int liLen)=0
long long bytesIn
Bytes read from the socket.
const char * tident
Pointer to the client's trace identifier.
XrdTcpMonPin * TcpMonPin
Definition XrdLinkXeq.cc:80
XrdSysError Log
Definition XrdConfig.cc:113

References Addr, XrdTcpMonPin::LinkInfo::bytesIn, BytesInTot, XrdTcpMonPin::LinkInfo::bytesOut, BytesOutTot, close, XrdTcpMonPin::LinkInfo::consec, DEBUG, XrdPoll::Detach(), XrdTcpMonPin::LinkInfo::fd, XrdLink::ID, XrdLink::Instance, XrdLink::isTLS, KeepFD, LinkInfo, XrdSysMutexHelper::Lock(), XrdGlobal::Log, PollInfo, ProtoAlt, Protocol, sendQ, XrdLink::Serialize(), Shutdown(), syncStats(), XrdGlobal::TcpMonPin, XrdTcpMonPin::LinkInfo::tident, tlsIO, TRACEI, XrdLinkCtl::Unhook(), XrdSysMutexHelper::UnLock(), and wrMutex.

Referenced by DoIt().

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

◆ DoIt()

void XrdLinkXeq::DoIt ( )
virtual

Reimplemented from XrdLink.

Definition at line 292 of file XrdLinkXeq.cc.

293{
294 int rc;
295
296// The Process() return code tells us what to do:
297// < 0 -> Stop getting requests,
298// -EINPROGRESS leave link disabled but otherwise all is well
299// -n Error, disable and close the link
300// = 0 -> OK, get next request, if allowed, o/w enable the link
301// > 0 -> Slow link, stop getting requests and enable the link
302//
303 if (Protocol)
304 do {rc = Protocol->Process(this);} while (!rc && Sched.canStick());
305 else {Log.Emsg("Link", "Dispatch on closed link", ID);
306 return;
307 }
308
309// Either re-enable the link and cycle back waiting for a new request, leave
310// disabled, or terminate the connection.
311//
312 if (rc >= 0)
313 {if (PollInfo.Poller && !PollInfo.Poller->Enable(PollInfo)) Close();}
314 else if (rc != -EINPROGRESS) Close();
315}
int Close(bool defer=false)
XrdScheduler Sched
Definition XrdLinkCtl.cc:54

References Close(), XrdLink::ID, XrdGlobal::Log, PollInfo, Protocol, and XrdGlobal::Sched.

+ Here is the call graph for this function:

◆ getIOStats()

int XrdLinkXeq::getIOStats ( long long & inbytes,
long long & outbytes,
int & numstall,
int & numtardy )
inline

Definition at line 68 of file XrdLinkXeq.hh.

70 { inbytes = BytesIn + BytesInTot;
71 outbytes = BytesOut+BytesOutTot;
72 numstall = stallCnt + stallCntTot;
73 numtardy = tardyCnt + tardyCntTot;
74 return LinkInfo.InUse;
75 }
long long BytesOut
long long BytesIn

References BytesIn, BytesInTot, BytesOut, BytesOutTot, LinkInfo, stallCnt, stallCntTot, tardyCnt, and tardyCntTot.

◆ getName()

static int XrdLinkXeq::getName ( int & curr,
char * bname,
int blen,
XrdLinkMatch * who = 0 )
static

◆ getPeerCerts()

XrdTlsPeerCerts * XrdLinkXeq::getPeerCerts ( )

Definition at line 321 of file XrdLinkXeq.cc.

322{
323 return (isTLS ? tlsIO.getCerts(true) : 0);
324}

References XrdLink::isTLS, and tlsIO.

◆ getProtocol()

XrdProtocol * XrdLinkXeq::getProtocol ( )
inline

Definition at line 82 of file XrdLinkXeq.hh.

82{return Protocol;}

References Protocol.

◆ Name()

const char * XrdLinkXeq::Name ( ) const
inline

Definition at line 85 of file XrdLinkXeq.hh.

85{return (const char *)Lname;}

References Lname.

◆ NetAddr()

const XrdNetAddr * XrdLinkXeq::NetAddr ( ) const
inline

Definition at line 88 of file XrdLinkXeq.hh.

88{return &Addr;}

References Addr.

◆ Peek()

int XrdLinkXeq::Peek ( char * buff,
int blen,
int timeout = -1 )

Definition at line 330 of file XrdLinkXeq.cc.

331{
332 XrdSysMutexHelper theMutex;
333 struct pollfd polltab = {PollInfo.FD, POLLIN|POLLRDNORM, 0};
334 ssize_t mlen;
335 int retc;
336
337// Lock the read mutex if we need to, the helper will unlock it upon exit
338//
339 if (LockReads) theMutex.Lock(&rdMutex);
340
341// Wait until we can actually read something
342//
343 isIdle = 0;
344 do {retc = poll(&polltab, 1, timeout);} while(retc < 0 && errno == EINTR);
345 if (retc != 1)
346 {if (retc == 0) return 0;
347 return Log.Emsg("Link", -errno, "poll", ID);
348 }
349
350// Verify it is safe to read now
351//
352 if (!(polltab.revents & (POLLIN|POLLRDNORM)))
353 {Log.Emsg("Link", XrdPoll::Poll2Text(polltab.revents), "polling", ID);
354 return -1;
355 }
356
357// Do the peek.
358//
359 do {mlen = recv(LinkInfo.FD, Buff, Blen, MSG_PEEK);}
360 while(mlen < 0 && errno == EINTR);
361
362// Return the result
363//
364 if (mlen >= 0) return int(mlen);
365 Log.Emsg("Link", errno, "peek on", ID);
366 return -1;
367}
XrdSysMutex rdMutex
static char * Poll2Text(short events)
Definition XrdPoll.cc:272
void Lock(XrdSysMutex *Mutex)

References XrdLink::ID, isIdle, LinkInfo, XrdSysMutexHelper::Lock(), LockReads, XrdGlobal::Log, XrdPoll::Poll2Text(), PollInfo, and rdMutex.

+ Here is the call graph for this function:

◆ Recv() [1/3]

int XrdLinkXeq::Recv ( char * buff,
int blen )

Definition at line 373 of file XrdLinkXeq.cc.

374{
375 ssize_t rlen;
376
377// Note that we will read only as much as is queued. Use Recv() with a
378// timeout to receive as much data as possible.
379//
380 if (LockReads) rdMutex.Lock();
381 isIdle = 0;
382 do {rlen = read(LinkInfo.FD, Buff, Blen);} while(rlen < 0 && errno == EINTR);
383 if (rlen > 0) AtomicAdd(BytesIn, rlen);
384 if (LockReads) rdMutex.UnLock();
385
386 if (rlen >= 0) return int(rlen);
387 if (LinkInfo.FD >= 0) Log.Emsg("Link", errno, "receive from", ID);
388 return -1;
389}
#define read(a, b, c)
Definition XrdPosix.hh:82
#define AtomicAdd(x, y)

References AtomicAdd, BytesIn, XrdLink::ID, isIdle, LinkInfo, LockReads, XrdGlobal::Log, rdMutex, and read.

◆ Recv() [2/3]

int XrdLinkXeq::Recv ( char * buff,
int blen,
int timeout )

Definition at line 393 of file XrdLinkXeq.cc.

394{
395 XrdSysMutexHelper theMutex;
396 struct pollfd polltab = {PollInfo.FD, POLLIN|POLLRDNORM, 0};
397 ssize_t rlen, totlen = 0;
398 int retc;
399
400// Lock the read mutex if we need to, the helper will unlock it upon exit
401//
402 if (LockReads) theMutex.Lock(&rdMutex);
403
404// Wait up to timeout milliseconds for data to arrive
405//
406 isIdle = 0;
407 while(Blen > 0)
408 {do {retc = poll(&polltab,1,timeout);} while(retc < 0 && errno == EINTR);
409 if (retc != 1)
410 {if (retc == 0)
411 {tardyCnt++;
412 if (totlen)
413 {if ((++stallCnt & 0xff) == 1) TRACEI(DEBUG,"read timed out");
414 AtomicAdd(BytesIn, totlen);
415 }
416 return int(totlen);
417 }
418 return (LinkInfo.FD >= 0 ? Log.Emsg("Link",-errno,"poll",ID) : -1);
419 }
420
421 // Verify it is safe to read now
422 //
423 if (!(polltab.revents & (POLLIN|POLLRDNORM)))
424 {Log.Emsg("Link", XrdPoll::Poll2Text(polltab.revents),
425 "polling", ID);
426 return -1;
427 }
428
429 // Read as much data as you can. Note that we will force an error
430 // if we get a zero-length read after poll said it was OK.
431 //
432 do {rlen = recv(LinkInfo.FD, Buff, Blen, 0);}
433 while(rlen < 0 && errno == EINTR);
434 if (rlen <= 0)
435 {if (!rlen) return -ENOMSG;
436 if (LinkInfo.FD > 0) Log.Emsg("Link", -errno, "receive from", ID);
437 return -1;
438 }
439 totlen += rlen; Blen -= rlen; Buff += rlen;
440 }
441
442 AtomicAdd(BytesIn, totlen);
443 return int(totlen);
444}

References AtomicAdd, BytesIn, DEBUG, XrdLink::ID, isIdle, LinkInfo, XrdSysMutexHelper::Lock(), LockReads, XrdGlobal::Log, XrdPoll::Poll2Text(), PollInfo, rdMutex, stallCnt, tardyCnt, and TRACEI.

+ Here is the call graph for this function:

◆ Recv() [3/3]

int XrdLinkXeq::Recv ( const struct iovec * iov,
int iocnt,
int timeout )

Definition at line 448 of file XrdLinkXeq.cc.

449{
450 XrdSysMutexHelper theMutex;
451 struct pollfd polltab = {PollInfo.FD, POLLIN|POLLRDNORM, 0};
452 int retc, rlen;
453
454// Lock the read mutex if we need to, the helper will unlock it upon exit
455//
456 if (LockReads) theMutex.Lock(&rdMutex);
457
458// Wait up to timeout milliseconds for data to arrive
459//
460 isIdle = 0;
461 do {retc = poll(&polltab,1,timeout);} while(retc < 0 && errno == EINTR);
462 if (retc != 1)
463 {if (retc == 0)
464 {tardyCnt++;
465 return 0;
466 }
467 return (LinkInfo.FD >= 0 ? Log.Emsg("Link",-errno,"poll",ID) : -1);
468 }
469
470// Verify it is safe to read now
471//
472 if (!(polltab.revents & (POLLIN|POLLRDNORM)))
473 {Log.Emsg("Link", XrdPoll::Poll2Text(polltab.revents), "polling", ID);
474 return -1;
475 }
476
477// If the iocnt is within limits then just go ahead and read once.
478//
479 if (iocnt <= maxIOV)
480 {rlen = RecvIOV(iov, iocnt);
481 if (rlen > 0) {AtomicAdd(BytesIn, rlen);}
482 return rlen;
483 }
484
485// We will have to break this up into allowable segments and we need to add up
486// the bytes in each segment so that we know when to stop reading.
487//
488 int seglen, segcnt = maxIOV, totlen = 0;
489 do {seglen = 0;
490 for (int i = 0; i < segcnt; i++) seglen += iov[i].iov_len;
491 if ((rlen = RecvIOV(iov, segcnt)) < 0) return rlen;
492 totlen += rlen;
493 if (rlen < seglen) break;
494 iov += segcnt;
495 iocnt -= segcnt;
496 if (iocnt <= maxIOV) segcnt = iocnt;
497 } while(iocnt > 0);
498
499// All done
500//
501 AtomicAdd(BytesIn, totlen);
502 return totlen;
503}
int RecvIOV(const struct iovec *iov, int iocnt)
const int maxIOV
Definition XrdLinkXeq.cc:82

References AtomicAdd, BytesIn, XrdLink::ID, isIdle, LinkInfo, XrdSysMutexHelper::Lock(), LockReads, XrdGlobal::Log, XrdGlobal::maxIOV, XrdPoll::Poll2Text(), PollInfo, rdMutex, RecvIOV(), and tardyCnt.

+ Here is the call graph for this function:

◆ RecvAll()

int XrdLinkXeq::RecvAll ( char * buff,
int blen,
int timeout = -1 )

Definition at line 509 of file XrdLinkXeq.cc.

510{
511 struct pollfd polltab = {PollInfo.FD, POLLIN|POLLRDNORM, 0};
512 ssize_t rlen;
513 int retc;
514
515// Check if timeout specified. Notice that the timeout is the max we will
516// for some data. We will wait forever for all the data. Yeah, it's weird.
517//
518 if (timeout >= 0)
519 {do {retc = poll(&polltab,1,timeout);} while(retc < 0 && errno == EINTR);
520 if (retc != 1)
521 {if (!retc) return -ETIMEDOUT;
522 Log.Emsg("Link",errno,"poll",ID);
523 return -1;
524 }
525 if (!(polltab.revents & (POLLIN|POLLRDNORM)))
526 {Log.Emsg("Link",XrdPoll::Poll2Text(polltab.revents),"polling",ID);
527 return -1;
528 }
529 }
530
531// Note that we will block until we receive all he bytes.
532//
533 if (LockReads) rdMutex.Lock();
534 isIdle = 0;
535 do {rlen = recv(LinkInfo.FD, Buff, Blen, MSG_WAITALL);}
536 while(rlen < 0 && errno == EINTR);
537 if (rlen > 0) AtomicAdd(BytesIn, rlen);
538 if (LockReads) rdMutex.UnLock();
539
540 if (int(rlen) == Blen) return Blen;
541 if (!rlen) {TRACEI(DEBUG, "No RecvAll() data; errno=" <<errno);}
542 else if (rlen > 0) Log.Emsg("RecvAll", "Premature end from", ID);
543 else if (LinkInfo.FD >= 0) Log.Emsg("Link", errno, "receive from", ID);
544 return -1;
545}

References AtomicAdd, BytesIn, DEBUG, XrdLink::ID, isIdle, LinkInfo, LockReads, XrdGlobal::Log, XrdPoll::Poll2Text(), PollInfo, rdMutex, and TRACEI.

+ Here is the call graph for this function:

◆ RecvIOV()

int XrdLinkXeq::RecvIOV ( const struct iovec * iov,
int iocnt )
protected

Definition at line 551 of file XrdLinkXeq.cc.

552{
553 ssize_t retc = 0;
554
555// Read the data in. On some version of Unix (e.g., Linux) a readv() may
556// end at any time without reading all the bytes when directed to a socket.
557// We always return the number bytes read (or an error). The caller needs to
558// restart the read at the appropriate place in the iovec when more data arrives.
559//
560 do {retc = readv(LinkInfo.FD, iov, iocnt);}
561 while(retc < 0 && errno == EINTR);
562
563// Check how we completed
564//
565 if (retc < 0) Log.Emsg("Link", errno, "receive from", ID);
566 return retc;
567}
#define readv(a, b, c)
Definition XrdPosix.hh:84

References XrdLink::ID, LinkInfo, XrdGlobal::Log, and readv.

Referenced by Recv().

+ Here is the caller graph for this function:

◆ Register()

bool XrdLinkXeq::Register ( const char * hName)

Definition at line 573 of file XrdLinkXeq.cc.

574{
575
576// Make appropriate changes here
577//
578 if (HostName) free(HostName);
579 HostName = strdup(hName);
580 strlcpy(Lname, hName, sizeof(Lname));
581 return true;
582}
size_t strlcpy(char *dst, const char *src, size_t sz)

References XrdLink::HostName, Lname, and strlcpy().

+ Here is the call graph for this function:

◆ Reset()

void XrdLinkXeq::Reset ( )
protected

Definition at line 113 of file XrdLinkXeq.cc.

114{
115 memcpy(Uname+sizeof(Uname)-7, "anon.0@", 7);
116 strcpy(Lname, "somewhere");
117 ID = &Uname[sizeof(Uname)-5];
118 Comment = ID;
119 sendQ = 0;
120 stallCnt = stallCntTot = 0;
121 tardyCnt = tardyCntTot = 0;
122 SfIntr = 0;
123 isIdle = 0;
125 LockReads= false;
126 KeepFD = false;
127 Protocol = 0;
128 ProtoAlt = 0;
129
130 LinkInfo.Reset();
131 PollInfo.Zorch();
132 ResetLink();
133}
const char * Comment
Definition XrdJob.hh:47
char Uname[24]

References BytesIn, BytesInTot, BytesOut, BytesOutTot, XrdJob::Comment, XrdLink::ID, isIdle, KeepFD, LinkInfo, Lname, LockReads, PollInfo, ProtoAlt, Protocol, XrdLink::ResetLink(), sendQ, SfIntr, stallCnt, stallCntTot, tardyCnt, tardyCntTot, and Uname.

Referenced by XrdLinkXeq(), and XrdLinkCtl::Alloc().

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

◆ Send() [1/3]

int XrdLinkXeq::Send ( const char * buff,
int blen )

Definition at line 588 of file XrdLinkXeq.cc.

589{
590 ssize_t retc = 0, bytesleft = Blen;
591
592// Get a lock
593//
594 wrMutex.Lock();
595 isIdle = 0;
596 AtomicAdd(BytesOut, Blen);
597
598// Do non-blocking writes if we are setup to do so.
599//
600 if (sendQ)
601 {retc = sendQ->Send(Buff, Blen);
602 wrMutex.UnLock();
603 return retc;
604 }
605
606// Write the data out
607//
608 while(bytesleft)
609 {if ((retc = write(LinkInfo.FD, Buff, bytesleft)) < 0)
610 {if (errno == EINTR) continue;
611 else break;
612 }
613 bytesleft -= retc; Buff += retc;
614 }
615
616// All done
617//
618 wrMutex.UnLock();
619 if (retc >= 0) return Blen;
620 Log.Emsg("Link", errno, "send to", ID);
621 return -1;
622}
#define write(a, b, c)
Definition XrdPosix.hh:115

References AtomicAdd, BytesOut, XrdLink::ID, isIdle, LinkInfo, XrdGlobal::Log, sendQ, write, and wrMutex.

◆ Send() [2/3]

int XrdLinkXeq::Send ( const sfVec * sdP,
int sdn )

Definition at line 675 of file XrdLinkXeq.cc.

676{
677#if !defined(HAVE_SENDFILE)
678
679 return -1;
680
681#elif defined(__solaris__)
682
683 sendfilevec_t vecSF[XrdOucSFVec::sfMax], *vecSFP = vecSF;
684 size_t xframt, totamt, bytes = 0;
685 ssize_t retc;
686 int i = 0;
687
688// Construct the sendfilev() vector
689//
690 for (i = 0; i < sfN; sfP++, i++)
691 {if (sfP->fdnum < 0)
692 {vecSF[i].sfv_fd = SFV_FD_SELF;
693 vecSF[i].sfv_off = (off_t)sfP->buffer;
694 } else {
695 vecSF[i].sfv_fd = sfP->fdnum;
696 vecSF[i].sfv_off = sfP->offset;
697 }
698 vecSF[i].sfv_flag = 0;
699 vecSF[i].sfv_len = sfP->sendsz;
700 bytes += sfP->sendsz;
701 }
702 totamt = bytes;
703
704// Lock the link, issue sendfilev(), and unlock the link. The documentation
705// is very spotty and inconsistent. We can only retry this operation under
706// very limited conditions.
707//
708 wrMutex.Lock();
709 isIdle = 0;
710do{retc = sendfilev(LinkInfo.FD, vecSFP, sfN, &xframt);
711
712// Check if all went well and return if so (usual case)
713//
714 if (xframt == bytes)
715 {AtomicAdd(BytesOut, bytes);
716 wrMutex.UnLock();
717 return totamt;
718 }
719
720// The only one we will recover from is EINTR. We cannot legally get EAGAIN.
721//
722 if (retc < 0 && errno != EINTR) break;
723
724// Try to resume the transfer
725//
726 if (xframt > 0)
727 {AtomicAdd(BytesOut, xframt); bytes -= xframt; SfIntr++;
728 while(xframt > 0 && sfN)
729 {if ((ssize_t)xframt < (ssize_t)vecSFP->sfv_len)
730 {vecSFP->sfv_off += xframt; vecSFP->sfv_len -= xframt; break;}
731 xframt -= vecSFP->sfv_len; vecSFP++; sfN--;
732 }
733 }
734 } while(sfN > 0);
735
736// See if we can recover without destroying the connection
737//
738 retc = (retc < 0 ? errno : ECANCELED);
739 wrMutex.UnLock();
740 Log.Emsg("Link", retc, "send file to", ID);
741 return -1;
742
743#elif defined(__linux__) || defined(__GNU__)
744
745 static const int setON = 1, setOFF = 0;
746 ssize_t retc = 0, bytesleft;
747 off_t myOffset;
748 int i, xfrbytes = 0, uncork = 1, xIntr = 0;
749
750// lock the link
751//
752 wrMutex.Lock();
753 isIdle = 0;
754
755// In linux we need to cork the socket. On permanent errors we do not uncork
756// the socket because it will be closed in short order.
757//
758 if (setsockopt(PollInfo.FD, SOL_TCP, TCP_CORK, &setON, sizeof(setON)) < 0)
759 {Log.Emsg("Link", errno, "cork socket for", ID);
760 uncork = 0; sfOK = 0;
761 }
762
763// Send the header first
764//
765 for (i = 0; i < sfN; sfP++, i++)
766 {if (sfP->fdnum < 0) retc = sendData(sfP->buffer, sfP->sendsz);
767 else {myOffset = sfP->offset; bytesleft = sfP->sendsz;
768 while(bytesleft
769 && (retc=sendfile(LinkInfo.FD,sfP->fdnum,&myOffset,bytesleft)) > 0)
770 {bytesleft -= retc; xIntr++;}
771 }
772 if (retc < 0 && errno == EINTR) continue;
773 if (retc <= 0) break;
774 xfrbytes += sfP->sendsz;
775 }
776
777// Diagnose any sendfile errors
778//
779 if (retc <= 0)
780 {if (retc == 0) errno = ECANCELED;
781 wrMutex.UnLock();
782 Log.Emsg("Link", errno, "send file to", ID);
783 return -1;
784 }
785
786// Now uncork the socket
787//
788 if (uncork
789 && setsockopt(PollInfo.FD, SOL_TCP, TCP_CORK, &setOFF, sizeof(setOFF)) < 0)
790 Log.Emsg("Link", errno, "uncork socket for", ID);
791
792// All done
793//
794 if (xIntr > sfN) SfIntr += (xIntr - sfN);
795 AtomicAdd(BytesOut, xfrbytes);
796 wrMutex.UnLock();
797 return xfrbytes;
798
799#else
800
801 return -1;
802
803#endif
804}
int sendData(const char *Buff, int Blen)

References AtomicAdd, BytesOut, XrdOucSFVec::fdnum, XrdLink::ID, isIdle, LinkInfo, XrdGlobal::Log, PollInfo, sendData(), XrdOucSFVec::sendsz, SfIntr, XrdOucSFVec::sfMax, XrdLink::sfOK, and wrMutex.

+ Here is the call graph for this function:

◆ Send() [3/3]

int XrdLinkXeq::Send ( const struct iovec * iov,
int iocnt,
int bytes = 0 )

Definition at line 626 of file XrdLinkXeq.cc.

627{
628 int retc;
629
630// Get a lock and assume we will be successful (statistically we are)
631//
632 wrMutex.Lock();
633 isIdle = 0;
634 AtomicAdd(BytesOut, bytes);
635
636// Do non-blocking writes if we are setup to do so.
637//
638 if (sendQ)
639 {retc = sendQ->Send(iov, iocnt, bytes);
640 wrMutex.UnLock();
641 return retc;
642 }
643
644// If the iocnt is within limits then just go ahead and write this out
645//
646 if (iocnt <= maxIOV)
647 {retc = SendIOV(iov, iocnt, bytes);
648 wrMutex.UnLock();
649 return retc;
650 }
651
652// We will have to break this up into allowable segments
653//
654 int seglen, segcnt = maxIOV, iolen = 0;
655 do {seglen = 0;
656 for (int i = 0; i < segcnt; i++) seglen += iov[i].iov_len;
657 if ((retc = SendIOV(iov, segcnt, seglen)) < 0)
658 {wrMutex.UnLock();
659 return retc;
660 }
661 iolen += retc;
662 iov += segcnt;
663 iocnt -= segcnt;
664 if (iocnt <= maxIOV) segcnt = iocnt;
665 } while(iocnt > 0);
666
667// All done
668//
669 wrMutex.UnLock();
670 return iolen;
671}
int SendIOV(const struct iovec *iov, int iocnt, int bytes)

References AtomicAdd, BytesOut, isIdle, XrdGlobal::maxIOV, SendIOV(), sendQ, and wrMutex.

+ Here is the call graph for this function:

◆ sendData()

int XrdLinkXeq::sendData ( const char * Buff,
int Blen )
protected

Definition at line 810 of file XrdLinkXeq.cc.

811{
812 ssize_t retc = 0, bytesleft = Blen;
813
814// Write the data out
815//
816 while(bytesleft)
817 {if ((retc = write(LinkInfo.FD, Buff, bytesleft)) < 0)
818 {if (errno == EINTR) continue;
819 else break;
820 }
821 bytesleft -= retc; Buff += retc;
822 }
823
824// All done
825//
826 return retc;
827}

References LinkInfo, and write.

Referenced by Send().

+ Here is the caller graph for this function:

◆ SendIOV()

int XrdLinkXeq::SendIOV ( const struct iovec * iov,
int iocnt,
int bytes )
protected

Definition at line 833 of file XrdLinkXeq.cc.

834{
835 ssize_t bytesleft, n, retc = 0;
836 const char *Buff;
837
838// Write the data out. On some version of Unix (e.g., Linux) a writev() may
839// end at any time without writing all the bytes when directed to a socket.
840// So, we attempt to resume the writev() using a combination of write() and
841// a writev() continuation. This approach slowly converts a writev() to a
842// series of writes if need be. We must do this inline because we must hold
843// the lock until all the bytes are written or an error occurs.
844//
845 bytesleft = static_cast<ssize_t>(bytes);
846 while(bytesleft)
847 {do {retc = writev(LinkInfo.FD, iov, iocnt);}
848 while(retc < 0 && errno == EINTR);
849 if (retc >= bytesleft || retc < 0) break;
850 bytesleft -= retc;
851 while(retc >= (n = static_cast<ssize_t>(iov->iov_len)))
852 {retc -= n; iov++; iocnt--;}
853 Buff = (const char *)iov->iov_base + retc; n -= retc; iov++; iocnt--;
854 while(n) {if ((retc = write(LinkInfo.FD, Buff, n)) < 0)
855 {if (errno == EINTR) continue;
856 else break;
857 }
858 n -= retc; Buff += retc; bytesleft -= retc;
859 }
860 if (retc < 0 || iocnt < 1) break;
861 }
862
863// All done
864//
865 if (retc >= 0) return bytes;
866 Log.Emsg("Link", errno, "send to", ID);
867 return -1;
868}
#define writev(a, b, c)
Definition XrdPosix.hh:117

References XrdLink::ID, LinkInfo, XrdGlobal::Log, write, and writev.

Referenced by Send().

+ Here is the caller graph for this function:

◆ setID()

void XrdLinkXeq::setID ( const char * userid,
int procid )

Definition at line 874 of file XrdLinkXeq.cc.

875{
876 char buff[sizeof(Uname)], *bp, *sp;
877 int ulen;
878
879 snprintf(buff, sizeof(buff), "%s.%d:%d", userid, procid, PollInfo.FD);
880 ulen = strlen(buff);
881 sp = buff + ulen - 1;
882 bp = &Uname[sizeof(Uname)-1];
883 if (ulen > (int)sizeof(Uname)) ulen = sizeof(Uname);
884 *bp = '@'; bp--;
885 while(ulen--) {*bp = *sp; bp--; sp--;}
886 ID = bp+1;
887 Comment = (const char *)ID;
888
889// Update the ID in the TLS socket if enabled
890//
891 if (isTLS) tlsIO.SetTraceID(ID);
892}

References XrdJob::Comment, XrdLink::ID, XrdLink::isTLS, PollInfo, tlsIO, and Uname.

◆ setLocation()

void XrdLinkXeq::setLocation ( XrdNetAddrInfo::LocInfo & loc)
inline

Definition at line 107 of file XrdLinkXeq.hh.

107{Addr.SetLocation(loc);}

References Addr.

◆ setNB()

bool XrdLinkXeq::setNB ( )

Definition at line 898 of file XrdLinkXeq.cc.

899{
900// We don't support non-blocking output except for Linux at the moment
901//
902#if !defined(__linux__)
903 return false;
904#else
905// Trace this request
906//
907 TRACEI(DEBUG,"enabling non-blocking output");
908
909// If we don't already have a sendQ object get one. This is a one-time call
910// so to optimize checking if this object exists we also get the opMutex.'
911//
912 LinkInfo.opMutex.Lock();
913 if (!sendQ)
914 {wrMutex.Lock();
915 sendQ = new XrdSendQ(*this, wrMutex);
916 wrMutex.UnLock();
917 }
918 LinkInfo.opMutex.UnLock();
919 return true;
920#endif
921}

References DEBUG, LinkInfo, sendQ, TRACEI, and wrMutex.

◆ setProtName()

void XrdLinkXeq::setProtName ( const char * name)

Definition at line 944 of file XrdLinkXeq.cc.

945{
946
947// Set the protocol name.
948//
949 LinkInfo.opMutex.Lock();
950 Addr.SetDialect(name);
951 LinkInfo.opMutex.UnLock();
952}

References Addr, and LinkInfo.

◆ setProtocol()

XrdProtocol * XrdLinkXeq::setProtocol ( XrdProtocol * pp,
bool push )

Definition at line 927 of file XrdLinkXeq.cc.

928{
929
930// Set new protocol.
931//
932 LinkInfo.opMutex.Lock();
933 XrdProtocol *op = Protocol;
934 if (push) ProtoAlt = Protocol;
935 Protocol = pp;
936 LinkInfo.opMutex.UnLock();
937 return op;
938}

References LinkInfo, ProtoAlt, and Protocol.

◆ setTLS()

bool XrdLinkXeq::setTLS ( bool enable,
XrdTlsContext * ctx = 0 )

Definition at line 958 of file XrdLinkXeq.cc.

959{ //???
960// static const XrdTlsConnection::RW_Mode rwMode=XrdTlsConnection::TLS_RNB_WBL;
963 const char *eNote;
964 XrdTls::RC rc;
965
966// If we are already in a compatible mode, we are done
967//
968
969 if (isTLS == enable) return true;
970
971// If this is a shutdown, then do it now.
972//
973 if (!enable)
974 {tlsIO.Shutdown();
975 isTLS = enable;
976 Addr.SetTLS(enable);
977 return true;
978 }
979// We want to initialize TLS, do so now.
980//
981 if (!ctx) ctx = tlsCtx;
982 eNote = tlsIO.Init(*ctx, PollInfo.FD, rwMode, hsMode, false, false, ID);
983
984// Check for errors
985//
986 if (eNote)
987 {char buff[1024];
988 snprintf(buff, sizeof(buff), "Unable to enable tls for %s;", ID);
989 Log.Emsg("LinkXeq", buff, eNote);
990 return false;
991 }
992
993// Now we need to accept this TLS connection
994//
995 std::string eMsg;
996 rc = tlsIO.Accept(&eMsg);
997
998// Diagnose return state
999//
1000 if (rc != XrdTls::TLS_AOK) Log.Emsg("LinkXeq", eMsg.c_str());
1001 else {isTLS = enable;
1002 Addr.SetTLS(enable);
1003 Log.Emsg("LinkXeq", ID, "connection upgraded to", verTLS());
1004 }
1005 return rc == XrdTls::TLS_AOK;
1006}
#define eMsg(x)
const char * verTLS()
@ TLS_HS_BLOCK
Always block during handshake.
@ TLS_RBL_WBL
blocking read blocking write
@ TLS_AOK
All went well, will always be zero.
Definition XrdTls.hh:40
XrdTlsContext * tlsCtx
Definition XrdGlobals.cc:52

References Addr, eMsg, XrdLink::ID, XrdLink::isTLS, XrdGlobal::Log, PollInfo, XrdTls::TLS_AOK, XrdTlsSocket::TLS_HS_BLOCK, XrdTlsSocket::TLS_RBL_WBL, XrdGlobal::tlsCtx, tlsIO, and verTLS().

+ Here is the call graph for this function:

◆ SFError()

int XrdLinkXeq::SFError ( int rc)
protected

Definition at line 1012 of file XrdLinkXeq.cc.

1013{
1014 Log.Emsg("TLS", rc, "send file to", ID);
1015 return -1;
1016}

References XrdLink::ID, and XrdGlobal::Log.

Referenced by TLS_Send().

+ Here is the caller graph for this function:

◆ Shutdown()

void XrdLinkXeq::Shutdown ( bool getLock)

Definition at line 1022 of file XrdLinkXeq.cc.

1023{
1024 int temp;
1025
1026// Trace the entry
1027//
1028 TRACEI(DEBUG, (getLock ? "Async" : "Sync") <<" link shutdown in progress");
1029
1030// Get the lock if we need too (external entry via another thread)
1031//
1032 if (getLock) LinkInfo.opMutex.Lock();
1033
1034// If there is something to do, do it now
1035//
1036 temp = Instance; Instance = 0;
1037 if (!KeepFD)
1038 {shutdown(PollInfo.FD, SHUT_RDWR);
1039 if (dup2(devNull, PollInfo.FD) < 0)
1040 {Instance = temp;
1041 Log.Emsg("Link", errno, "shutdown FD for", ID);
1042 }
1043 }
1044
1045// All done
1046//
1047 if (getLock) LinkInfo.opMutex.UnLock();
1048}

References DEBUG, XrdGlobal::devNull, XrdLink::ID, XrdLink::Instance, KeepFD, LinkInfo, XrdGlobal::Log, PollInfo, and TRACEI.

Referenced by Close().

+ Here is the caller graph for this function:

◆ Stats()

int XrdLinkXeq::Stats ( char * buff,
int blen,
bool do_sync = false )
static

Definition at line 1054 of file XrdLinkXeq.cc.

1055{
1056 static const char statfmt[] = "<stats id=\"link\"><num>%d</num>"
1057 "<maxn>%d</maxn><tot>%lld</tot><in>%lld</in><out>%lld</out>"
1058 "<ctime>%lld</ctime><tmo>%d</tmo><stall>%d</stall>"
1059 "<sfps>%d</sfps></stats>";
1060 int i;
1061
1062// Check if actual length wanted
1063//
1064 if (!buff) return sizeof(statfmt)+17*6;
1065
1066// We must synchronize the statistical counters
1067//
1068 if (do_sync) XrdLinkCtl::SyncAll();
1069
1070// Obtain lock on the stats area and format it
1071//
1073 i = snprintf(buff, blen, statfmt, AtomicGet(LinkCount),
1083 return i;
1084}
#define AtomicBeg(Mtx)
#define AtomicGet(x)
#define AtomicEnd(Mtx)
static void SyncAll()
Synchronize statustics for ll links.
static int LinkCountMax
static long long LinkCountTot
static int LinkCount
static long long LinkBytesIn
static long long LinkConTime
static int LinkSfIntr
static XrdSysMutex statsMutex
static int LinkStalls
static long long LinkBytesOut
static int LinkTimeOuts

References AtomicBeg, AtomicEnd, AtomicGet, LinkBytesIn, LinkBytesOut, LinkConTime, LinkCount, LinkCountMax, LinkCountTot, LinkSfIntr, LinkStalls, LinkTimeOuts, statsMutex, and XrdLinkCtl::SyncAll().

Referenced by XrdLink::Stats().

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

◆ syncStats()

void XrdLinkXeq::syncStats ( int * ctime = 0)

Definition at line 1090 of file XrdLinkXeq.cc.

1091{
1092 long long tmpLL;
1093 int tmpI4;
1094
1095// If this is dynamic, get the opMutex lock
1096//
1097 if (!ctime) LinkInfo.opMutex.Lock();
1098
1099// Either the caller has the opMutex or this is called out of close. In either
1100// case, we need to get the read and write mutexes; each followed by the stats
1101// mutex. This order is important because we should not hold the stats mutex
1102// for very long and the r/w mutexes may take a long time to acquire. If we
1103// must maintain the link count we need to actually acquire the stats mutex as
1104// we will be doing compound operations. Atomics are still used to keep other
1105// threads from seeing partial results.
1106//
1108
1109 if (ctime)
1110 {*ctime = time(0) - LinkInfo.conTime;
1111 AtomicAdd(LinkConTime, *ctime);
1112 statsMutex.Lock();
1113 if (LinkCount > 0) AtomicDec(LinkCount);
1114 statsMutex.UnLock();
1115 }
1116
1118
1119 tmpLL = AtomicFAZ(BytesIn);
1120 AtomicAdd(LinkBytesIn, tmpLL); AtomicAdd(BytesInTot, tmpLL);
1121 tmpI4 = AtomicFAZ(tardyCnt);
1123 tmpI4 = AtomicFAZ(stallCnt);
1124 AtomicAdd(LinkStalls, tmpI4); AtomicAdd(stallCntTot, tmpI4);
1126
1128 tmpLL = AtomicFAZ(BytesOut);
1130 tmpI4 = AtomicFAZ(SfIntr);
1131 AtomicAdd(LinkSfIntr, tmpI4);
1133
1134// Make sure the protocol updates it's statistics as well
1135//
1136 if (Protocol) Protocol->Stats(0, 0, 1);
1137
1138// All done
1139//
1140 if (!ctime) LinkInfo.opMutex.UnLock();
1141}
#define AtomicFAZ(x)
#define AtomicDec(x)

References AtomicAdd, AtomicBeg, AtomicDec, AtomicEnd, AtomicFAZ, BytesIn, BytesInTot, BytesOut, BytesOutTot, LinkBytesIn, LinkBytesOut, LinkConTime, LinkCount, LinkInfo, LinkSfIntr, LinkStalls, LinkTimeOuts, Protocol, rdMutex, SfIntr, stallCnt, stallCntTot, statsMutex, tardyCnt, tardyCntTot, and wrMutex.

Referenced by Close().

+ Here is the caller graph for this function:

◆ TLS_Error()

int XrdLinkXeq::TLS_Error ( const char * act,
XrdTls::RC rc )
protected

Definition at line 1147 of file XrdLinkXeq.cc.

1148{
1149 std::string reason = XrdTls::RC2Text(rc);
1150 char msg[512];
1151
1152 snprintf(msg, sizeof(msg), "Unable to %s %s;", act, ID);
1153 Log.Emsg("TLS", msg, reason.c_str());
1154 return -1;
1155}
static std::string RC2Text(XrdTls::RC rc, bool dbg=false)
Definition XrdTls.cc:127

References XrdLink::ID, XrdGlobal::Log, and XrdTls::RC2Text().

Referenced by TLS_Peek(), TLS_Recv(), TLS_Recv(), TLS_Send(), TLS_Send(), and TLS_Write().

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

◆ TLS_Peek()

int XrdLinkXeq::TLS_Peek ( char * Buff,
int Blen,
int timeout )

Definition at line 1161 of file XrdLinkXeq.cc.

1162{
1163 XrdSysMutexHelper theMutex;
1164 XrdTls::RC retc;
1165 int rc, rlen;
1166
1167// Lock the read mutex if we need to, the helper will unlock it upon exit
1168//
1169 if (LockReads) theMutex.Lock(&rdMutex);
1170
1171// Wait until we can actually read something
1172//
1173 isIdle = 0;
1174 if (timeout)
1175 {rc = Wait4Data(timeout);
1176 if (rc < 1) return rc;
1177 }
1178
1179// Do the peek and if sucessful, the number of bytes available.
1180//
1181 retc = tlsIO.Peek(Buff, Blen, rlen);
1182 if (retc == XrdTls::TLS_AOK) return rlen;
1183
1184// Dianose the TLS error and return failure
1185//
1186 return TLS_Error("peek on", retc);
1187}
int TLS_Error(const char *act, XrdTls::RC rc)

References isIdle, XrdSysMutexHelper::Lock(), LockReads, rdMutex, XrdTls::TLS_AOK, TLS_Error(), tlsIO, and XrdLink::Wait4Data().

+ Here is the call graph for this function:

◆ TLS_Recv() [1/3]

int XrdLinkXeq::TLS_Recv ( char * Buff,
int Blen )

Definition at line 1193 of file XrdLinkXeq.cc.

1194{
1195 XrdSysMutexHelper theMutex;
1196 XrdTls::RC retc;
1197 int rlen;
1198
1199// Lock the read mutex if we need to, the helper will unlock it upon exit
1200//
1201 if (LockReads) theMutex.Lock(&rdMutex);
1202
1203// Note that we will read only as much as is queued. Use Recv() with a
1204// timeout to receive as much data as possible.
1205//
1206 isIdle = 0;
1207 retc = tlsIO.Read(Buff, Blen, rlen);
1208 if (retc != XrdTls::TLS_AOK) return TLS_Error("receive from", retc);
1209 if (rlen > 0) AtomicAdd(BytesIn, rlen);
1210 return rlen;
1211}

References AtomicAdd, BytesIn, isIdle, XrdSysMutexHelper::Lock(), LockReads, rdMutex, XrdTls::TLS_AOK, TLS_Error(), and tlsIO.

Referenced by TLS_Recv(), and TLS_RecvAll().

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

◆ TLS_Recv() [2/3]

int XrdLinkXeq::TLS_Recv ( char * Buff,
int Blen,
int timeout,
bool havelock = false )

Definition at line 1215 of file XrdLinkXeq.cc.

1216{
1217 XrdSysMutexHelper theMutex;
1218 XrdTls::RC retc;
1219 int pend, rlen, totlen = 0;
1220
1221// Lock the read mutex if we need to, the helper will unlock it upon exit
1222//
1223 if (LockReads && !havelock) theMutex.Lock(&rdMutex);
1224
1225// Wait up to timeout milliseconds for data to arrive
1226//
1227 isIdle = 0;
1228 while(Blen > 0)
1229 {pend = tlsIO.Pending(true);
1230 if (!pend) pend = Wait4Data(timeout);
1231 if (pend < 1)
1232 {if (pend < 0) return -1;
1233 tardyCnt++;
1234 if (totlen)
1235 {if ((++stallCnt & 0xff) == 1) TRACEI(DEBUG,"read timed out");
1236 AtomicAdd(BytesIn, totlen);
1237 }
1238 return totlen;
1239 }
1240
1241 // Read as much data as you can. Note that we will force an error
1242 // if we get a zero-length read after poll said it was OK. However,
1243 // if we never read anything, then we simply return -ENOMSG to avoid
1244 // generating a "read link error" as clearly there was a hangup.
1245 //
1246 retc = tlsIO.Read(Buff, Blen, rlen);
1247 if (retc != XrdTls::TLS_AOK)
1248 {if (!totlen) return -ENOMSG;
1249 AtomicAdd(BytesIn, totlen);
1250 return TLS_Error("receive from", retc);
1251 }
1252 if (rlen <= 0) break;
1253 totlen += rlen; Blen -= rlen; Buff += rlen;
1254 }
1255
1256 AtomicAdd(BytesIn, totlen);
1257 return totlen;
1258}

References AtomicAdd, BytesIn, DEBUG, isIdle, XrdSysMutexHelper::Lock(), LockReads, rdMutex, stallCnt, tardyCnt, XrdTls::TLS_AOK, TLS_Error(), tlsIO, TRACEI, and XrdLink::Wait4Data().

+ Here is the call graph for this function:

◆ TLS_Recv() [3/3]

int XrdLinkXeq::TLS_Recv ( const struct iovec * iov,
int iocnt,
int timeout )

Definition at line 1262 of file XrdLinkXeq.cc.

1263{
1264 XrdSysMutexHelper theMutex;
1265 char *Buff;
1266 int Blen, rlen, totlen = 0;
1267
1268// Lock the read mutex if we need to, the helper will unlock it upon exit
1269//
1270 if (LockReads) theMutex.Lock(&rdMutex);
1271
1272// Individually process each element until we can't read any more
1273//
1274 isIdle = 0;
1275 for (int i = 0; i < iocnt; i++)
1276 {Buff = (char *)iov[i].iov_base;
1277 Blen = iov[i].iov_len;
1278 rlen = TLS_Recv(Buff, Blen, timeout, true);
1279 if (rlen <= 0) break;
1280 totlen += rlen;
1281 if (rlen < Blen) break;
1282 }
1283
1284 if (totlen) {AtomicAdd(BytesIn, totlen);}
1285 return totlen;
1286}
int TLS_Recv(char *Buff, int Blen)

References AtomicAdd, BytesIn, isIdle, XrdSysMutexHelper::Lock(), LockReads, rdMutex, and TLS_Recv().

+ Here is the call graph for this function:

◆ TLS_RecvAll()

int XrdLinkXeq::TLS_RecvAll ( char * Buff,
int Blen,
int timeout )

Definition at line 1292 of file XrdLinkXeq.cc.

1293{
1294 int retc;
1295
1296// Check if timeout specified. Notice that the timeout is the max we will
1297// wait for some data. We will wait forever for all the data. Yeah, it's weird.
1298//
1299 if (timeout >= 0)
1300 {retc = tlsIO.Pending(true);
1301 if (!retc) retc = Wait4Data(timeout);
1302 if (retc < 1) return (retc ? -1 : -ETIMEDOUT);
1303 }
1304
1305// Note that we will block until we receive all the bytes.
1306//
1307 return TLS_Recv(Buff, Blen, -1);
1308}

References TLS_Recv(), tlsIO, and XrdLink::Wait4Data().

+ Here is the call graph for this function:

◆ TLS_Send() [1/3]

int XrdLinkXeq::TLS_Send ( const char * Buff,
int Blen )

Definition at line 1314 of file XrdLinkXeq.cc.

1315{
1316 XrdSysMutexHelper lck(wrMutex);
1317 ssize_t bytesleft = Blen;
1318 XrdTls::RC retc;
1319 int byteswritten;
1320
1321// Prepare to send
1322//
1323 isIdle = 0;
1324 AtomicAdd(BytesOut, Blen);
1325
1326// Do non-blocking writes if we are setup to do so.
1327//
1328 if (sendQ) return sendQ->Send(Buff, Blen);
1329
1330// Write the data out
1331//
1332 while(bytesleft)
1333 {retc = tlsIO.Write(Buff, bytesleft, byteswritten);
1334 if (retc != XrdTls::TLS_AOK) return TLS_Error("send to", retc);
1335 bytesleft -= byteswritten; Buff += byteswritten;
1336 }
1337
1338// All done
1339//
1340 return Blen;
1341}

References AtomicAdd, BytesOut, isIdle, sendQ, XrdTls::TLS_AOK, TLS_Error(), tlsIO, and wrMutex.

+ Here is the call graph for this function:

◆ TLS_Send() [2/3]

int XrdLinkXeq::TLS_Send ( const sfVec * sfP,
int sfN )

Definition at line 1380 of file XrdLinkXeq.cc.

1381{
1382 XrdSysMutexHelper lck(wrMutex);
1383 int bytes, buffsz, fileFD, retc;
1384 off_t offset;
1385 ssize_t totamt = 0;
1386 char myBuff[65536];
1387
1388// Convert the sendfile to a regular send. The conversion is not particularly
1389// fast and caller are advised to avoid using sendfile on TLS connections.
1390//
1391 isIdle = 0;
1392 for (int i = 0; i < sfN; sfP++, i++)
1393 {if (!(bytes = sfP->sendsz)) continue;
1394 totamt += bytes;
1395 if (sfP->fdnum < 0)
1396 {if (!TLS_Write(sfP->buffer, bytes)) return -1;
1397 continue;
1398 }
1399 offset = sfP->offset;
1400 fileFD = sfP->fdnum;
1401 buffsz = (bytes < (int)sizeof(myBuff) ? bytes : sizeof(myBuff));
1402 do {do {retc = pread(fileFD, myBuff, buffsz, offset);}
1403 while(retc < 0 && errno == EINTR);
1404 if (retc < 0) return SFError(errno);
1405 if (!retc) break;
1406 if (!TLS_Write(myBuff, buffsz)) return -1;
1407 offset += buffsz; bytes -= buffsz; totamt += retc;
1408 } while(bytes > 0);
1409 }
1410
1411// We are done
1412//
1413 AtomicAdd(BytesOut, totamt);
1414 return totamt;
1415}
#define pread(a, b, c, d)
Definition XrdPosix.hh:80
bool TLS_Write(const char *Buff, int Blen)
int SFError(int rc)

References AtomicAdd, BytesOut, XrdOucSFVec::fdnum, isIdle, pread, XrdOucSFVec::sendsz, SFError(), TLS_Write(), and wrMutex.

+ Here is the call graph for this function:

◆ TLS_Send() [3/3]

int XrdLinkXeq::TLS_Send ( const struct iovec * iov,
int iocnt,
int bytes )

Definition at line 1345 of file XrdLinkXeq.cc.

1346{
1347 XrdSysMutexHelper lck(wrMutex);
1348 XrdTls::RC retc;
1349 int byteswritten;
1350
1351// Get a lock and assume we will be successful (statistically we are). Note
1352// that the calling interface gauranteed bytes are not zero.
1353//
1354 isIdle = 0;
1355 AtomicAdd(BytesOut, bytes);
1356
1357// Do non-blocking writes if we are setup to do so.
1358//
1359 if (sendQ) return sendQ->Send(iov, iocnt, bytes);
1360
1361// Write the data out.
1362//
1363 for (int i = 0; i < iocnt; i++)
1364 {ssize_t bytesleft = iov[i].iov_len;
1365 char *Buff = (char *)iov[i].iov_base;
1366 while(bytesleft)
1367 {retc = tlsIO.Write(Buff, bytesleft, byteswritten);
1368 if (retc != XrdTls::TLS_AOK) return TLS_Error("send to", retc);
1369 bytesleft -= byteswritten; Buff += byteswritten;
1370 }
1371 }
1372
1373// All done
1374//
1375 return bytes;
1376}

References AtomicAdd, BytesOut, isIdle, sendQ, XrdTls::TLS_AOK, TLS_Error(), tlsIO, and wrMutex.

+ Here is the call graph for this function:

◆ TLS_Write()

bool XrdLinkXeq::TLS_Write ( const char * Buff,
int Blen )
protected

Definition at line 1421 of file XrdLinkXeq.cc.

1422{
1423 XrdTls::RC retc;
1424 int byteswritten;
1425
1426// Write the data out
1427//
1428 while(Blen)
1429 {retc = tlsIO.Write(Buff, Blen, byteswritten);
1430 if (retc != XrdTls::TLS_AOK)
1431 {TLS_Error("write to", retc);
1432 return false;
1433 }
1434 Blen -= byteswritten; Buff += byteswritten;
1435 }
1436
1437// All done
1438//
1439 return true;
1440}

References XrdTls::TLS_AOK, TLS_Error(), and tlsIO.

Referenced by TLS_Send().

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

◆ verTLS()

const char * XrdLinkXeq::verTLS ( )

Definition at line 1446 of file XrdLinkXeq.cc.

1447{
1448 return tlsIO.Version();
1449}

References tlsIO.

Referenced by setTLS().

+ Here is the caller graph for this function:

Member Data Documentation

◆ Addr

XrdNetAddr XrdLinkXeq::Addr
protected

◆ BytesIn

long long XrdLinkXeq::BytesIn
protected

Definition at line 170 of file XrdLinkXeq.hh.

Referenced by getIOStats(), Recv(), Recv(), Recv(), RecvAll(), Reset(), syncStats(), TLS_Recv(), TLS_Recv(), and TLS_Recv().

◆ BytesInTot

long long XrdLinkXeq::BytesInTot
protected

Definition at line 171 of file XrdLinkXeq.hh.

Referenced by Close(), getIOStats(), Reset(), and syncStats().

◆ BytesOut

long long XrdLinkXeq::BytesOut
protected

Definition at line 172 of file XrdLinkXeq.hh.

Referenced by getIOStats(), Reset(), Send(), Send(), Send(), syncStats(), TLS_Send(), TLS_Send(), and TLS_Send().

◆ BytesOutTot

long long XrdLinkXeq::BytesOutTot
protected

Definition at line 173 of file XrdLinkXeq.hh.

Referenced by Close(), getIOStats(), Reset(), and syncStats().

◆ HNlen

int XrdLinkXeq::HNlen
protected

Definition at line 196 of file XrdLinkXeq.hh.

Referenced by XrdLinkCtl::Alloc(), Client(), XrdLinkCtl::Find(), and XrdLinkCtl::getName().

◆ isIdle

char XrdLinkXeq::isIdle
protected

◆ KeepFD

bool XrdLinkXeq::KeepFD
protected

Definition at line 198 of file XrdLinkXeq.hh.

Referenced by XrdLinkCtl::Alloc(), Close(), Reset(), and Shutdown().

◆ LinkBytesIn

long long XrdLinkXeq::LinkBytesIn = 0
staticprotected

Definition at line 161 of file XrdLinkXeq.hh.

Referenced by Stats(), and syncStats().

◆ LinkBytesOut

long long XrdLinkXeq::LinkBytesOut = 0
staticprotected

Definition at line 162 of file XrdLinkXeq.hh.

Referenced by Stats(), and syncStats().

◆ LinkConTime

long long XrdLinkXeq::LinkConTime = 0
staticprotected

Definition at line 163 of file XrdLinkXeq.hh.

Referenced by Stats(), and syncStats().

◆ LinkCount

int XrdLinkXeq::LinkCount = 0
staticprotected

Definition at line 165 of file XrdLinkXeq.hh.

Referenced by XrdLinkCtl::Alloc(), Stats(), and syncStats().

◆ LinkCountMax

int XrdLinkXeq::LinkCountMax = 0
staticprotected

Definition at line 166 of file XrdLinkXeq.hh.

Referenced by XrdLinkCtl::Alloc(), and Stats().

◆ LinkCountTot

long long XrdLinkXeq::LinkCountTot = 0
staticprotected

Definition at line 164 of file XrdLinkXeq.hh.

Referenced by XrdLinkCtl::Alloc(), and Stats().

◆ LinkInfo

◆ LinkSfIntr

int XrdLinkXeq::LinkSfIntr = 0
staticprotected

Definition at line 169 of file XrdLinkXeq.hh.

Referenced by Stats(), and syncStats().

◆ LinkStalls

int XrdLinkXeq::LinkStalls = 0
staticprotected

Definition at line 168 of file XrdLinkXeq.hh.

Referenced by Stats(), and syncStats().

◆ LinkTimeOuts

int XrdLinkXeq::LinkTimeOuts = 0
staticprotected

Definition at line 167 of file XrdLinkXeq.hh.

Referenced by Stats(), and syncStats().

◆ Lname

char XrdLinkXeq::Lname[256]
protected

◆ LockReads

bool XrdLinkXeq::LockReads
protected

◆ PollInfo

◆ ProtoAlt

XrdProtocol* XrdLinkXeq::ProtoAlt
protected

Definition at line 184 of file XrdLinkXeq.hh.

Referenced by Close(), Reset(), and setProtocol().

◆ Protocol

XrdProtocol* XrdLinkXeq::Protocol
protected

Definition at line 183 of file XrdLinkXeq.hh.

Referenced by Close(), DoIt(), getProtocol(), Reset(), setProtocol(), and syncStats().

◆ rdMutex

XrdSysMutex XrdLinkXeq::rdMutex
protected

Definition at line 193 of file XrdLinkXeq.hh.

Referenced by Peek(), Recv(), Recv(), Recv(), RecvAll(), syncStats(), TLS_Peek(), TLS_Recv(), TLS_Recv(), and TLS_Recv().

◆ sendQ

XrdSendQ* XrdLinkXeq::sendQ
protected

Definition at line 195 of file XrdLinkXeq.hh.

Referenced by Backlog(), Close(), Reset(), Send(), Send(), setNB(), TLS_Send(), and TLS_Send().

◆ SfIntr

int XrdLinkXeq::SfIntr
protected

Definition at line 178 of file XrdLinkXeq.hh.

Referenced by Reset(), Send(), and syncStats().

◆ stallCnt

int XrdLinkXeq::stallCnt
protected

Definition at line 174 of file XrdLinkXeq.hh.

Referenced by getIOStats(), Recv(), Reset(), syncStats(), and TLS_Recv().

◆ stallCntTot

int XrdLinkXeq::stallCntTot
protected

Definition at line 175 of file XrdLinkXeq.hh.

Referenced by getIOStats(), Reset(), and syncStats().

◆ statsMutex

XrdSysMutex XrdLinkXeq::statsMutex
staticprotected

Definition at line 179 of file XrdLinkXeq.hh.

Referenced by XrdLinkCtl::Alloc(), Stats(), and syncStats().

◆ tardyCnt

int XrdLinkXeq::tardyCnt
protected

Definition at line 176 of file XrdLinkXeq.hh.

Referenced by getIOStats(), Recv(), Recv(), Reset(), syncStats(), and TLS_Recv().

◆ tardyCntTot

int XrdLinkXeq::tardyCntTot
protected

Definition at line 177 of file XrdLinkXeq.hh.

Referenced by getIOStats(), Reset(), and syncStats().

◆ tlsIO

XrdTlsSocket XrdLinkXeq::tlsIO
protected

◆ TraceID

const char * XrdLinkXeq::TraceID = "LinkXeq"
staticprotected

Definition at line 157 of file XrdLinkXeq.hh.

◆ Uname

char XrdLinkXeq::Uname[24]
protected

Definition at line 200 of file XrdLinkXeq.hh.

Referenced by XrdLinkCtl::Alloc(), Reset(), and setID().

◆ wrMutex

XrdSysMutex XrdLinkXeq::wrMutex
protected

Definition at line 194 of file XrdLinkXeq.hh.

Referenced by Backlog(), Close(), Send(), Send(), Send(), setNB(), syncStats(), TLS_Send(), TLS_Send(), and TLS_Send().


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