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)
 
bool RegisterCloseRequestCb (XrdProtocol *pp, bool(*cb)(void *), void *cbarg)
 
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
 
bool(* CloseRequestCb )(void *)
 
void * CloseRequestCbArg
 
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().

Referenced by XrdLinkCtl::RegisterCloseRequestCb().

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

◆ ~XrdLinkXeq()

XrdLinkXeq::~XrdLinkXeq ( )
inline

Definition at line 145 of file XrdLinkXeq.hh.

145{} // 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 140 of file XrdLinkXeq.cc.

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

References sendQ, and wrMutex.

◆ Client()

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

Definition at line 153 of file XrdLinkXeq.cc.

154{
155 int ulen;
156
157// Generate full client name
158//
159 if (nbsz <= 0) return 0;
160 ulen = (Lname - ID);
161 if ((ulen + HNlen) >= nbsz) ulen = 0;
162 else {strncpy(nbuf, ID, ulen);
163 strcpy(nbuf+ulen, HostName);
164 ulen += HNlen;
165 }
166 return ulen;
167}
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 173 of file XrdLinkXeq.cc.

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

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

References Close(), CloseRequestCb, CloseRequestCbArg, 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 331 of file XrdLinkXeq.cc.

332{
333 return (isTLS ? tlsIO.getCerts(true) : 0);
334}

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 340 of file XrdLinkXeq.cc.

341{
342 XrdSysMutexHelper theMutex;
343 struct pollfd polltab = {PollInfo.FD, POLLIN|POLLRDNORM, 0};
344 ssize_t mlen;
345 int retc;
346
347// Lock the read mutex if we need to, the helper will unlock it upon exit
348//
349 if (LockReads) theMutex.Lock(&rdMutex);
350
351// Wait until we can actually read something
352//
353 isIdle = 0;
354 do {retc = poll(&polltab, 1, timeout);} while(retc < 0 && errno == EINTR);
355 if (retc != 1)
356 {if (retc == 0) return 0;
357 return Log.Emsg("Link", -errno, "poll", ID);
358 }
359
360// Verify it is safe to read now
361//
362 if (!(polltab.revents & (POLLIN|POLLRDNORM)))
363 {Log.Emsg("Link", XrdPoll::Poll2Text(polltab.revents), "polling", ID);
364 return -1;
365 }
366
367// Do the peek.
368//
369 do {mlen = recv(LinkInfo.FD, Buff, Blen, MSG_PEEK);}
370 while(mlen < 0 && errno == EINTR);
371
372// Return the result
373//
374 if (mlen >= 0) return int(mlen);
375 Log.Emsg("Link", errno, "peek on", ID);
376 return -1;
377}
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 383 of file XrdLinkXeq.cc.

384{
385 ssize_t rlen;
386
387// Note that we will read only as much as is queued. Use Recv() with a
388// timeout to receive as much data as possible.
389//
390 if (LockReads) rdMutex.Lock();
391 isIdle = 0;
392 do {rlen = read(LinkInfo.FD, Buff, Blen);} while(rlen < 0 && errno == EINTR);
393 if (rlen > 0) AtomicAdd(BytesIn, rlen);
394 if (LockReads) rdMutex.UnLock();
395
396 if (rlen >= 0) return int(rlen);
397 if (LinkInfo.FD >= 0) Log.Emsg("Link", errno, "receive from", ID);
398 return -1;
399}
#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 403 of file XrdLinkXeq.cc.

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

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 458 of file XrdLinkXeq.cc.

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

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

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 561 of file XrdLinkXeq.cc.

562{
563 ssize_t retc = 0;
564
565// Read the data in. On some version of Unix (e.g., Linux) a readv() may
566// end at any time without reading all the bytes when directed to a socket.
567// We always return the number bytes read (or an error). The caller needs to
568// restart the read at the appropriate place in the iovec when more data arrives.
569//
570 do {retc = readv(LinkInfo.FD, iov, iocnt);}
571 while(retc < 0 && errno == EINTR);
572
573// Check how we completed
574//
575 if (retc < 0) Log.Emsg("Link", errno, "receive from", ID);
576 return retc;
577}
#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 583 of file XrdLinkXeq.cc.

584{
585
586// Make appropriate changes here
587//
588 if (HostName) free(HostName);
589 HostName = strdup(hName);
590 strlcpy(Lname, hName, sizeof(Lname));
591 return true;
592}
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:

◆ RegisterCloseRequestCb()

bool XrdLinkXeq::RegisterCloseRequestCb ( XrdProtocol * pp,
bool(* cb )(void *),
void * cbarg )

Definition at line 1465 of file XrdLinkXeq.cc.

1467{
1468 if (pp != Protocol) return false;
1469
1470 CloseRequestCb = cb;
1471 CloseRequestCbArg = cbarg;
1472 return true;
1473}

References CloseRequestCb, CloseRequestCbArg, and Protocol.

Referenced by XrdLinkCtl::RegisterCloseRequestCb().

+ Here is the caller 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 CloseRequestCb = 0;
130
131 LinkInfo.Reset();
132 PollInfo.Zorch();
133 ResetLink();
134}
const char * Comment
Definition XrdJob.hh:47
char Uname[24]

References BytesIn, BytesInTot, BytesOut, BytesOutTot, CloseRequestCb, 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 598 of file XrdLinkXeq.cc.

599{
600 ssize_t retc = 0, bytesleft = Blen;
601
602// Get a lock
603//
604 wrMutex.Lock();
605 isIdle = 0;
606 AtomicAdd(BytesOut, Blen);
607
608// Do non-blocking writes if we are setup to do so.
609//
610 if (sendQ)
611 {retc = sendQ->Send(Buff, Blen);
612 wrMutex.UnLock();
613 return retc;
614 }
615
616// Write the data out
617//
618 while(bytesleft)
619 {if ((retc = write(LinkInfo.FD, Buff, bytesleft)) < 0)
620 {if (errno == EINTR) continue;
621 else break;
622 }
623 bytesleft -= retc; Buff += retc;
624 }
625
626// All done
627//
628 wrMutex.UnLock();
629 if (retc >= 0) return Blen;
630 Log.Emsg("Link", errno, "send to", ID);
631 return -1;
632}
#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 685 of file XrdLinkXeq.cc.

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

637{
638 int retc;
639
640// Get a lock and assume we will be successful (statistically we are)
641//
642 wrMutex.Lock();
643 isIdle = 0;
644 AtomicAdd(BytesOut, bytes);
645
646// Do non-blocking writes if we are setup to do so.
647//
648 if (sendQ)
649 {retc = sendQ->Send(iov, iocnt, bytes);
650 wrMutex.UnLock();
651 return retc;
652 }
653
654// If the iocnt is within limits then just go ahead and write this out
655//
656 if (iocnt <= maxIOV)
657 {retc = SendIOV(iov, iocnt, bytes);
658 wrMutex.UnLock();
659 return retc;
660 }
661
662// We will have to break this up into allowable segments
663//
664 int seglen, segcnt = maxIOV, iolen = 0;
665 do {seglen = 0;
666 for (int i = 0; i < segcnt; i++) seglen += iov[i].iov_len;
667 if ((retc = SendIOV(iov, segcnt, seglen)) < 0)
668 {wrMutex.UnLock();
669 return retc;
670 }
671 iolen += retc;
672 iov += segcnt;
673 iocnt -= segcnt;
674 if (iocnt <= maxIOV) segcnt = iocnt;
675 } while(iocnt > 0);
676
677// All done
678//
679 wrMutex.UnLock();
680 return iolen;
681}
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 820 of file XrdLinkXeq.cc.

821{
822 ssize_t retc = 0, bytesleft = Blen;
823
824// Write the data out
825//
826 while(bytesleft)
827 {if ((retc = write(LinkInfo.FD, Buff, bytesleft)) < 0)
828 {if (errno == EINTR) continue;
829 else break;
830 }
831 bytesleft -= retc; Buff += retc;
832 }
833
834// All done
835//
836 return retc;
837}

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 843 of file XrdLinkXeq.cc.

844{
845 ssize_t bytesleft, n, retc = 0;
846 const char *Buff;
847
848// Write the data out. On some version of Unix (e.g., Linux) a writev() may
849// end at any time without writing all the bytes when directed to a socket.
850// So, we attempt to resume the writev() using a combination of write() and
851// a writev() continuation. This approach slowly converts a writev() to a
852// series of writes if need be. We must do this inline because we must hold
853// the lock until all the bytes are written or an error occurs.
854//
855 bytesleft = static_cast<ssize_t>(bytes);
856 while(bytesleft)
857 {do {retc = writev(LinkInfo.FD, iov, iocnt);}
858 while(retc < 0 && errno == EINTR);
859 if (retc >= bytesleft || retc < 0) break;
860 bytesleft -= retc;
861 while(retc >= (n = static_cast<ssize_t>(iov->iov_len)))
862 {retc -= n; iov++; iocnt--;}
863 Buff = (const char *)iov->iov_base + retc; n -= retc; iov++; iocnt--;
864 while(n) {if ((retc = write(LinkInfo.FD, Buff, n)) < 0)
865 {if (errno == EINTR) continue;
866 else break;
867 }
868 n -= retc; Buff += retc; bytesleft -= retc;
869 }
870 if (retc < 0 || iocnt < 1) break;
871 }
872
873// All done
874//
875 if (retc >= 0) return bytes;
876 Log.Emsg("Link", errno, "send to", ID);
877 return -1;
878}
#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 884 of file XrdLinkXeq.cc.

885{
886 char buff[sizeof(Uname)], *bp, *sp;
887 int ulen;
888
889 snprintf(buff, sizeof(buff), "%s.%d:%d", userid, procid, PollInfo.FD);
890 ulen = strlen(buff);
891 sp = buff + ulen - 1;
892 bp = &Uname[sizeof(Uname)-1];
893 if (ulen > (int)sizeof(Uname)) ulen = sizeof(Uname);
894 *bp = '@'; bp--;
895 while(ulen--) {*bp = *sp; bp--; sp--;}
896 ID = bp+1;
897 Comment = (const char *)ID;
898
899// Update the ID in the TLS socket if enabled
900//
901 if (isTLS) tlsIO.SetTraceID(ID);
902}

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 908 of file XrdLinkXeq.cc.

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

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

◆ setProtName()

void XrdLinkXeq::setProtName ( const char * name)

Definition at line 954 of file XrdLinkXeq.cc.

955{
956
957// Set the protocol name.
958//
959 LinkInfo.opMutex.Lock();
960 Addr.SetDialect(name);
961 LinkInfo.opMutex.UnLock();
962}

References Addr, and LinkInfo.

◆ setProtocol()

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

Definition at line 937 of file XrdLinkXeq.cc.

938{
939
940// Set new protocol.
941//
942 LinkInfo.opMutex.Lock();
943 XrdProtocol *op = Protocol;
944 if (push) ProtoAlt = Protocol;
945 Protocol = pp;
946 LinkInfo.opMutex.UnLock();
947 return op;
948}

References LinkInfo, ProtoAlt, and Protocol.

◆ setTLS()

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

Definition at line 968 of file XrdLinkXeq.cc.

969{ //???
970// static const XrdTlsConnection::RW_Mode rwMode=XrdTlsConnection::TLS_RNB_WBL;
973 const char *eNote;
974 XrdTls::RC rc;
975
976// If we are already in a compatible mode, we are done
977//
978
979 if (isTLS == enable) return true;
980
981// If this is a shutdown, then do it now.
982//
983 if (!enable)
984 {tlsIO.Shutdown();
985 isTLS = enable;
986 Addr.SetTLS(enable);
987 return true;
988 }
989// We want to initialize TLS, do so now.
990//
991 if (!ctx) ctx = tlsCtx;
992 eNote = tlsIO.Init(*ctx, PollInfo.FD, rwMode, hsMode, false, false, ID);
993
994// Check for errors
995//
996 if (eNote)
997 {char buff[1024];
998 snprintf(buff, sizeof(buff), "Unable to enable tls for %s;", ID);
999 Log.Emsg("LinkXeq", buff, eNote);
1000 return false;
1001 }
1002
1003// Now we need to accept this TLS connection
1004//
1005 std::string eMsg;
1006 rc = tlsIO.Accept(&eMsg);
1007
1008// Diagnose return state
1009//
1010 if (rc != XrdTls::TLS_AOK) Log.Emsg("LinkXeq", eMsg.c_str());
1011 else {isTLS = enable;
1012 Addr.SetTLS(enable);
1013 Log.Emsg("LinkXeq", ID, "connection upgraded to", verTLS());
1014 }
1015 return rc == XrdTls::TLS_AOK;
1016}
#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 1022 of file XrdLinkXeq.cc.

1023{
1024 Log.Emsg("TLS", rc, "send file to", ID);
1025 return -1;
1026}

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 1032 of file XrdLinkXeq.cc.

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

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 1064 of file XrdLinkXeq.cc.

1065{
1066 static const char statfmt[] = "<stats id=\"link\"><num>%d</num>"
1067 "<maxn>%d</maxn><tot>%lld</tot><in>%lld</in><out>%lld</out>"
1068 "<ctime>%lld</ctime><tmo>%d</tmo><stall>%d</stall>"
1069 "<sfps>%d</sfps></stats>";
1070 int i;
1071
1072// Check if actual length wanted
1073//
1074 if (!buff) return sizeof(statfmt)+17*6;
1075
1076// We must synchronize the statistical counters
1077//
1078 if (do_sync) XrdLinkCtl::SyncAll();
1079
1080// Obtain lock on the stats area and format it
1081//
1083 i = snprintf(buff, blen, statfmt, AtomicGet(LinkCount),
1093 return i;
1094}
#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 1100 of file XrdLinkXeq.cc.

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

1158{
1159 std::string reason = XrdTls::RC2Text(rc);
1160 char msg[512];
1161
1162 snprintf(msg, sizeof(msg), "Unable to %s %s;", act, ID);
1163 Log.Emsg("TLS", msg, reason.c_str());
1164 return -1;
1165}
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 1171 of file XrdLinkXeq.cc.

1172{
1173 XrdSysMutexHelper theMutex;
1174 XrdTls::RC retc;
1175 int rc, rlen;
1176
1177// Lock the read mutex if we need to, the helper will unlock it upon exit
1178//
1179 if (LockReads) theMutex.Lock(&rdMutex);
1180
1181// Wait until we can actually read something
1182//
1183 isIdle = 0;
1184 if (timeout)
1185 {rc = Wait4Data(timeout);
1186 if (rc < 1) return rc;
1187 }
1188
1189// Do the peek and if sucessful, the number of bytes available.
1190//
1191 retc = tlsIO.Peek(Buff, Blen, rlen);
1192 if (retc == XrdTls::TLS_AOK) return rlen;
1193
1194// Dianose the TLS error and return failure
1195//
1196 return TLS_Error("peek on", retc);
1197}
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 1203 of file XrdLinkXeq.cc.

1204{
1205 XrdSysMutexHelper theMutex;
1206 XrdTls::RC retc;
1207 int rlen;
1208
1209// Lock the read mutex if we need to, the helper will unlock it upon exit
1210//
1211 if (LockReads) theMutex.Lock(&rdMutex);
1212
1213// Note that we will read only as much as is queued. Use Recv() with a
1214// timeout to receive as much data as possible.
1215//
1216 isIdle = 0;
1217 retc = tlsIO.Read(Buff, Blen, rlen);
1218 if (retc != XrdTls::TLS_AOK) return TLS_Error("receive from", retc);
1219 if (rlen > 0) AtomicAdd(BytesIn, rlen);
1220 return rlen;
1221}

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 1225 of file XrdLinkXeq.cc.

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

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 1272 of file XrdLinkXeq.cc.

1273{
1274 XrdSysMutexHelper theMutex;
1275 char *Buff;
1276 int Blen, rlen, totlen = 0;
1277
1278// Lock the read mutex if we need to, the helper will unlock it upon exit
1279//
1280 if (LockReads) theMutex.Lock(&rdMutex);
1281
1282// Individually process each element until we can't read any more
1283//
1284 isIdle = 0;
1285 for (int i = 0; i < iocnt; i++)
1286 {Buff = (char *)iov[i].iov_base;
1287 Blen = iov[i].iov_len;
1288 rlen = TLS_Recv(Buff, Blen, timeout, true);
1289 if (rlen <= 0) break;
1290 totlen += rlen;
1291 if (rlen < Blen) break;
1292 }
1293
1294 if (totlen) {AtomicAdd(BytesIn, totlen);}
1295 return totlen;
1296}
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 1302 of file XrdLinkXeq.cc.

1303{
1304 int retc;
1305
1306// Check if timeout specified. Notice that the timeout is the max we will
1307// wait for some data. We will wait forever for all the data. Yeah, it's weird.
1308//
1309 if (timeout >= 0)
1310 {retc = tlsIO.Pending(true);
1311 if (!retc) retc = Wait4Data(timeout);
1312 if (retc < 1) return (retc ? -1 : -ETIMEDOUT);
1313 }
1314
1315// Note that we will block until we receive all the bytes.
1316//
1317 return TLS_Recv(Buff, Blen, -1);
1318}

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 1324 of file XrdLinkXeq.cc.

1325{
1326 XrdSysMutexHelper lck(wrMutex);
1327 ssize_t bytesleft = Blen;
1328 XrdTls::RC retc;
1329 int byteswritten;
1330
1331// Prepare to send
1332//
1333 isIdle = 0;
1334 AtomicAdd(BytesOut, Blen);
1335
1336// Do non-blocking writes if we are setup to do so.
1337//
1338 if (sendQ) return sendQ->Send(Buff, Blen);
1339
1340// Write the data out
1341//
1342 while(bytesleft)
1343 {retc = tlsIO.Write(Buff, bytesleft, byteswritten);
1344 if (retc != XrdTls::TLS_AOK) return TLS_Error("send to", retc);
1345 bytesleft -= byteswritten; Buff += byteswritten;
1346 }
1347
1348// All done
1349//
1350 return Blen;
1351}

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 1390 of file XrdLinkXeq.cc.

1391{
1392 XrdSysMutexHelper lck(wrMutex);
1393 int bytes, buffsz, fileFD, retc;
1394 off_t offset;
1395 ssize_t totamt = 0;
1396 char myBuff[65536];
1397
1398// Convert the sendfile to a regular send. The conversion is not particularly
1399// fast and caller are advised to avoid using sendfile on TLS connections.
1400//
1401 isIdle = 0;
1402 for (int i = 0; i < sfN; sfP++, i++)
1403 {if (!(bytes = sfP->sendsz)) continue;
1404 totamt += bytes;
1405 if (sfP->fdnum < 0)
1406 {if (!TLS_Write(sfP->buffer, bytes)) return -1;
1407 continue;
1408 }
1409 offset = sfP->offset;
1410 fileFD = sfP->fdnum;
1411 buffsz = (bytes < (int)sizeof(myBuff) ? bytes : sizeof(myBuff));
1412 do {do {retc = pread(fileFD, myBuff, buffsz, offset);}
1413 while(retc < 0 && errno == EINTR);
1414 if (retc < 0) return SFError(errno);
1415 if (!retc) break;
1416 if (!TLS_Write(myBuff, buffsz)) return -1;
1417 offset += buffsz; bytes -= buffsz; totamt += retc;
1418 } while(bytes > 0);
1419 }
1420
1421// We are done
1422//
1423 AtomicAdd(BytesOut, totamt);
1424 return totamt;
1425}
#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 1355 of file XrdLinkXeq.cc.

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

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 1431 of file XrdLinkXeq.cc.

1432{
1433 XrdTls::RC retc;
1434 int byteswritten;
1435
1436// Write the data out
1437//
1438 while(Blen)
1439 {retc = tlsIO.Write(Buff, Blen, byteswritten);
1440 if (retc != XrdTls::TLS_AOK)
1441 {TLS_Error("write to", retc);
1442 return false;
1443 }
1444 Blen -= byteswritten; Buff += byteswritten;
1445 }
1446
1447// All done
1448//
1449 return true;
1450}

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 1456 of file XrdLinkXeq.cc.

1457{
1458 return tlsIO.Version();
1459}

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 173 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 174 of file XrdLinkXeq.hh.

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

◆ BytesOut

long long XrdLinkXeq::BytesOut
protected

Definition at line 175 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 176 of file XrdLinkXeq.hh.

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

◆ CloseRequestCb

bool(* XrdLinkXeq::CloseRequestCb) (void *)
protected

Definition at line 188 of file XrdLinkXeq.hh.

Referenced by DoIt(), RegisterCloseRequestCb(), and Reset().

◆ CloseRequestCbArg

void* XrdLinkXeq::CloseRequestCbArg
protected

Definition at line 189 of file XrdLinkXeq.hh.

Referenced by DoIt(), and RegisterCloseRequestCb().

◆ HNlen

int XrdLinkXeq::HNlen
protected

Definition at line 201 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 203 of file XrdLinkXeq.hh.

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

◆ LinkBytesIn

long long XrdLinkXeq::LinkBytesIn = 0
staticprotected

Definition at line 164 of file XrdLinkXeq.hh.

Referenced by Stats(), and syncStats().

◆ LinkBytesOut

long long XrdLinkXeq::LinkBytesOut = 0
staticprotected

Definition at line 165 of file XrdLinkXeq.hh.

Referenced by Stats(), and syncStats().

◆ LinkConTime

long long XrdLinkXeq::LinkConTime = 0
staticprotected

Definition at line 166 of file XrdLinkXeq.hh.

Referenced by Stats(), and syncStats().

◆ LinkCount

int XrdLinkXeq::LinkCount = 0
staticprotected

Definition at line 168 of file XrdLinkXeq.hh.

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

◆ LinkCountMax

int XrdLinkXeq::LinkCountMax = 0
staticprotected

Definition at line 169 of file XrdLinkXeq.hh.

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

◆ LinkCountTot

long long XrdLinkXeq::LinkCountTot = 0
staticprotected

Definition at line 167 of file XrdLinkXeq.hh.

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

◆ LinkInfo

◆ LinkSfIntr

int XrdLinkXeq::LinkSfIntr = 0
staticprotected

Definition at line 172 of file XrdLinkXeq.hh.

Referenced by Stats(), and syncStats().

◆ LinkStalls

int XrdLinkXeq::LinkStalls = 0
staticprotected

Definition at line 171 of file XrdLinkXeq.hh.

Referenced by Stats(), and syncStats().

◆ LinkTimeOuts

int XrdLinkXeq::LinkTimeOuts = 0
staticprotected

Definition at line 170 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 187 of file XrdLinkXeq.hh.

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

◆ Protocol

XrdProtocol* XrdLinkXeq::Protocol
protected

◆ rdMutex

XrdSysMutex XrdLinkXeq::rdMutex
protected

Definition at line 198 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 200 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 181 of file XrdLinkXeq.hh.

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

◆ stallCnt

int XrdLinkXeq::stallCnt
protected

Definition at line 177 of file XrdLinkXeq.hh.

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

◆ stallCntTot

int XrdLinkXeq::stallCntTot
protected

Definition at line 178 of file XrdLinkXeq.hh.

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

◆ statsMutex

XrdSysMutex XrdLinkXeq::statsMutex
staticprotected

Definition at line 182 of file XrdLinkXeq.hh.

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

◆ tardyCnt

int XrdLinkXeq::tardyCnt
protected

Definition at line 179 of file XrdLinkXeq.hh.

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

◆ tardyCntTot

int XrdLinkXeq::tardyCntTot
protected

Definition at line 180 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 160 of file XrdLinkXeq.hh.

◆ Uname

char XrdLinkXeq::Uname[24]
protected

Definition at line 205 of file XrdLinkXeq.hh.

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

◆ wrMutex

XrdSysMutex XrdLinkXeq::wrMutex
protected

Definition at line 199 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: