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. Similarly, if a thread is
216// dispatched into the protocol (i.e. inside Process()), wait for it to
217// return before we recycle the protocol stack out from under it. Once both
218// counts drain we hold the opMutex until the protocol is removed, so no new
219// dispatch can slip in.
220//
221 while(LinkInfo.InUse > 1 || LinkInfo.dspCnt > 0)
222 {if (LinkInfo.InUse > 1)
223 {opHelper.UnLock();
224 TRACEI(DEBUG, "Close FD "<<LinkInfo.FD <<" deferred, use count="
225 <<LinkInfo.InUse);
226 Serialize();
227 }
228 else
229 {LinkInfo.dspPost++;
230 opHelper.UnLock();
231 TRACEI(DEBUG, "Close FD "<<LinkInfo.FD <<" deferred, dispatch count="
232 <<LinkInfo.dspCnt);
233 LinkInfo.dspSem.Wait();
234 }
235 opHelper.Lock(&LinkInfo.opMutex);
236 }
237 LinkInfo.InUse--;
238 Instance = 0;
239
240// Add up the statistic for this link
241//
242 syncStats(&csec);
243
244// Cleanup TLS if it is active
245//
246 if (isTLS) tlsIO.Shutdown();
247
248// Clean this link up
249//
250 if (Protocol) {Protocol->Recycle(this, csec, LinkInfo.Etext); Protocol = 0;}
251 if (ProtoAlt) {ProtoAlt->Recycle(this, csec, LinkInfo.Etext); ProtoAlt = 0;}
252 if (LinkInfo.Etext) {free(LinkInfo.Etext); LinkInfo.Etext = 0;}
253 LinkInfo.InUse = 0;
254
255// At this point we can have no lock conflicts, so if someone is waiting for
256// us to terminate let them know about it. Note that we will get the condvar
257// mutex while we hold the opMutex. This is the required order! We will also
258// zero out the pointer to the condvar while holding the opmutex.
259//
260 if (LinkInfo.KillcvP)
261 {LinkInfo.KillcvP->Lock();
262 LinkInfo.KillcvP->Signal();
263 LinkInfo.KillcvP->UnLock();
264 LinkInfo.KillcvP = 0;
265 }
266
267// Remove ourselves from the poll table and then from the Link table. We may
268// not hold on to the opMutex when we acquire the LTMutex. However, the link
269// table needs to be cleaned up prior to actually closing the socket. So, we
270// do some fancy footwork to prevent multiple closes of this link.
271//
272 fd = abs(LinkInfo.FD);
273 if (PollInfo.FD > 0)
274 {if (PollInfo.Poller) {XrdPoll::Detach(PollInfo); PollInfo.Poller = 0;}
275 PollInfo.FD = -1;
276 opHelper.UnLock();
278 } else opHelper.UnLock();
279
280// Invoke the TCP monitor if it was loaded.
281//
282 if (TcpMonPin && fd > 2)
283 {XrdTcpMonPin::LinkInfo lnkInfo;
284 lnkInfo.tident = ID;
285 lnkInfo.fd = fd;
286 lnkInfo.consec = csec;
287 lnkInfo.bytesIn = BytesInTot;
288 lnkInfo.bytesOut = BytesOutTot;
289 TcpMonPin->Monitor(Addr, lnkInfo, sizeof(lnkInfo));
290 }
291
292// Close the file descriptor if it isn't being shared. Do it as the last
293// thing because closes and accepts and not interlocked.
294//
295 if (fd >= 2) {if (KeepFD) rc = 0;
296 else rc = (close(fd) < 0 ? errno : 0);
297 }
298 if (rc) Log.Emsg("Link", rc, "close", ID);
299 return rc;
300}
#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 306 of file XrdLinkXeq.cc.

307{
308 int rc;
309
310// Count this thread as dispatched into the protocol so that a concurrent
311// Close() waits for the protocol call to return before recycling the protocol
312// stack (e.g. XrdHttp's SSL session) out from under Process(). We may only do
313// so while the link still has a protocol; Close() removes the protocol while
314// continuously holding the opMutex after draining dispatched threads, making
315// this check-and-count atomic with respect to link teardown. Note that we
316// cannot use setRef() for this because InUse counts threads other than the
317// one running the protocol (e.g. Serialize() called within Process() would
318// count us and deadlock).
319//
320 LinkInfo.opMutex.Lock();
321 bool isOpen = (Protocol != 0);
322 if (isOpen) LinkInfo.dspCnt++;
323 LinkInfo.opMutex.UnLock();
324
325// The Process() return code tells us what to do:
326// < 0 -> Stop getting requests,
327// -EINPROGRESS leave link disabled but otherwise all is well
328// -n Error, disable and close the link
329// = 0 -> OK, get next request, if allowed, o/w enable the link
330// > 0 -> Slow link, stop getting requests and enable the link
331//
332 if (isOpen)
333 do {rc = Protocol->Process(this);} while (!rc && Sched.canStick());
334 else {Log.Emsg("Link", "Dispatch on closed link", ID);
335 return;
336 }
337
338// Either re-enable the link and cycle back waiting for a new request, leave
339// disabled, or terminate the connection.
340//
341 bool doCl = false;
342 if (rc >= 0)
343 {if (PollInfo.Poller && !PollInfo.Poller->Enable(PollInfo)) doCl = true;}
344 else if (rc != -EINPROGRESS) doCl = true;
345
346// Indicate that we are no longer dispatched into the protocol, waking up any
347// thread waiting to close this link. This must be done before we ourselves
348// try to close the link lest we deadlock waiting on ourselves.
349//
350 LinkInfo.opMutex.Lock();
351 LinkInfo.dspCnt--;
352 while(LinkInfo.dspCnt == 0 && LinkInfo.dspPost)
353 {LinkInfo.dspSem.Post(); LinkInfo.dspPost--;}
354 LinkInfo.opMutex.UnLock();
355
356 if (doCl)
357 {if (CloseRequestCb)
358 {const bool res = CloseRequestCb(CloseRequestCbArg);
359 if (!res) return;
360 }
361 Close();
362 }
363}
bool(* CloseRequestCb)(void *)
int Close(bool defer=false)
void * CloseRequestCbArg
XrdScheduler Sched
Definition XrdLinkCtl.cc:54

References Close(), CloseRequestCb, CloseRequestCbArg, XrdLink::ID, LinkInfo, 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 369 of file XrdLinkXeq.cc.

370{
371 return (isTLS ? tlsIO.getCerts(true) : 0);
372}

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

379{
380 XrdSysMutexHelper theMutex;
381 struct pollfd polltab = {PollInfo.FD, POLLIN|POLLRDNORM, 0};
382 ssize_t mlen;
383 int retc;
384
385// Lock the read mutex if we need to, the helper will unlock it upon exit
386//
387 if (LockReads) theMutex.Lock(&rdMutex);
388
389// Wait until we can actually read something
390//
391 isIdle = 0;
392 do {retc = poll(&polltab, 1, timeout);} while(retc < 0 && errno == EINTR);
393 if (retc != 1)
394 {if (retc == 0) return 0;
395 return Log.Emsg("Link", -errno, "poll", ID);
396 }
397
398// Verify it is safe to read now
399//
400 if (!(polltab.revents & (POLLIN|POLLRDNORM)))
401 {Log.Emsg("Link", XrdPoll::Poll2Text(polltab.revents), "polling", ID);
402 return -1;
403 }
404
405// Do the peek.
406//
407 do {mlen = recv(LinkInfo.FD, Buff, Blen, MSG_PEEK);}
408 while(mlen < 0 && errno == EINTR);
409
410// Return the result
411//
412 if (mlen >= 0) return int(mlen);
413 Log.Emsg("Link", errno, "peek on", ID);
414 return -1;
415}
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 421 of file XrdLinkXeq.cc.

422{
423 ssize_t rlen;
424
425// Note that we will read only as much as is queued. Use Recv() with a
426// timeout to receive as much data as possible.
427//
428 if (LockReads) rdMutex.Lock();
429 isIdle = 0;
430 do {rlen = read(LinkInfo.FD, Buff, Blen);} while(rlen < 0 && errno == EINTR);
431 if (rlen > 0) AtomicAdd(BytesIn, rlen);
432 if (LockReads) rdMutex.UnLock();
433
434 if (rlen >= 0) return int(rlen);
435 if (LinkInfo.FD >= 0) Log.Emsg("Link", errno, "receive from", ID);
436 return -1;
437}
#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 441 of file XrdLinkXeq.cc.

442{
443 XrdSysMutexHelper theMutex;
444 struct pollfd polltab = {PollInfo.FD, POLLIN|POLLRDNORM, 0};
445 ssize_t rlen, totlen = 0;
446 int retc;
447
448// Lock the read mutex if we need to, the helper will unlock it upon exit
449//
450 if (LockReads) theMutex.Lock(&rdMutex);
451
452// Wait up to timeout milliseconds for data to arrive
453//
454 isIdle = 0;
455 while(Blen > 0)
456 {do {retc = poll(&polltab,1,timeout);} while(retc < 0 && errno == EINTR);
457 if (retc != 1)
458 {if (retc == 0)
459 {tardyCnt++;
460 if (totlen)
461 {if ((++stallCnt & 0xff) == 1) TRACEI(DEBUG,"read timed out");
462 AtomicAdd(BytesIn, totlen);
463 }
464 return int(totlen);
465 }
466 return (LinkInfo.FD >= 0 ? Log.Emsg("Link",-errno,"poll",ID) : -1);
467 }
468
469 // Verify it is safe to read now
470 //
471 if (!(polltab.revents & (POLLIN|POLLRDNORM)))
472 {Log.Emsg("Link", XrdPoll::Poll2Text(polltab.revents),
473 "polling", ID);
474 return -1;
475 }
476
477 // Read as much data as you can. Note that we will force an error
478 // if we get a zero-length read after poll said it was OK.
479 //
480 do {rlen = recv(LinkInfo.FD, Buff, Blen, 0);}
481 while(rlen < 0 && errno == EINTR);
482 if (rlen <= 0)
483 {if (!rlen) return -ENOMSG;
484 if (LinkInfo.FD > 0) Log.Emsg("Link", -errno, "receive from", ID);
485 return -1;
486 }
487 totlen += rlen; Blen -= rlen; Buff += rlen;
488 }
489
490 AtomicAdd(BytesIn, totlen);
491 return int(totlen);
492}

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

497{
498 XrdSysMutexHelper theMutex;
499 struct pollfd polltab = {PollInfo.FD, POLLIN|POLLRDNORM, 0};
500 int retc, rlen;
501
502// Lock the read mutex if we need to, the helper will unlock it upon exit
503//
504 if (LockReads) theMutex.Lock(&rdMutex);
505
506// Wait up to timeout milliseconds for data to arrive
507//
508 isIdle = 0;
509 do {retc = poll(&polltab,1,timeout);} while(retc < 0 && errno == EINTR);
510 if (retc != 1)
511 {if (retc == 0)
512 {tardyCnt++;
513 return 0;
514 }
515 return (LinkInfo.FD >= 0 ? Log.Emsg("Link",-errno,"poll",ID) : -1);
516 }
517
518// Verify it is safe to read now
519//
520 if (!(polltab.revents & (POLLIN|POLLRDNORM)))
521 {Log.Emsg("Link", XrdPoll::Poll2Text(polltab.revents), "polling", ID);
522 return -1;
523 }
524
525// If the iocnt is within limits then just go ahead and read once.
526//
527 if (iocnt <= maxIOV)
528 {rlen = RecvIOV(iov, iocnt);
529 if (rlen > 0) {AtomicAdd(BytesIn, rlen);}
530 return rlen;
531 }
532
533// We will have to break this up into allowable segments and we need to add up
534// the bytes in each segment so that we know when to stop reading.
535//
536 int seglen, segcnt = maxIOV, totlen = 0;
537 do {seglen = 0;
538 for (int i = 0; i < segcnt; i++) seglen += iov[i].iov_len;
539 if ((rlen = RecvIOV(iov, segcnt)) < 0) return rlen;
540 totlen += rlen;
541 if (rlen < seglen) break;
542 iov += segcnt;
543 iocnt -= segcnt;
544 if (iocnt <= maxIOV) segcnt = iocnt;
545 } while(iocnt > 0);
546
547// All done
548//
549 AtomicAdd(BytesIn, totlen);
550 return totlen;
551}
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 557 of file XrdLinkXeq.cc.

558{
559 struct pollfd polltab = {PollInfo.FD, POLLIN|POLLRDNORM, 0};
560 ssize_t rlen;
561 int retc;
562
563// Check if timeout specified. Notice that the timeout is the max we will
564// for some data. We will wait forever for all the data. Yeah, it's weird.
565//
566 if (timeout >= 0)
567 {do {retc = poll(&polltab,1,timeout);} while(retc < 0 && errno == EINTR);
568 if (retc != 1)
569 {if (!retc) return -ETIMEDOUT;
570 Log.Emsg("Link",errno,"poll",ID);
571 return -1;
572 }
573 if (!(polltab.revents & (POLLIN|POLLRDNORM)))
574 {Log.Emsg("Link",XrdPoll::Poll2Text(polltab.revents),"polling",ID);
575 return -1;
576 }
577 }
578
579// Note that we will block until we receive all he bytes.
580//
581 if (LockReads) rdMutex.Lock();
582 isIdle = 0;
583 do {rlen = recv(LinkInfo.FD, Buff, Blen, MSG_WAITALL);}
584 while(rlen < 0 && errno == EINTR);
585 if (rlen > 0) AtomicAdd(BytesIn, rlen);
586 if (LockReads) rdMutex.UnLock();
587
588 if (int(rlen) == Blen) return Blen;
589 if (!rlen) {TRACEI(DEBUG, "No RecvAll() data; errno=" <<errno);}
590 else if (rlen > 0) Log.Emsg("RecvAll", "Premature end from", ID);
591 else if (LinkInfo.FD >= 0) Log.Emsg("Link", errno, "receive from", ID);
592 return -1;
593}

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

600{
601 ssize_t retc = 0;
602
603// Read the data in. On some version of Unix (e.g., Linux) a readv() may
604// end at any time without reading all the bytes when directed to a socket.
605// We always return the number bytes read (or an error). The caller needs to
606// restart the read at the appropriate place in the iovec when more data arrives.
607//
608 do {retc = readv(LinkInfo.FD, iov, iocnt);}
609 while(retc < 0 && errno == EINTR);
610
611// Check how we completed
612//
613 if (retc < 0) Log.Emsg("Link", errno, "receive from", ID);
614 return retc;
615}
#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 621 of file XrdLinkXeq.cc.

622{
623
624// Make appropriate changes here
625//
626 if (HostName) free(HostName);
627 HostName = strdup(hName);
628 strlcpy(Lname, hName, sizeof(Lname));
629 return true;
630}
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 1503 of file XrdLinkXeq.cc.

1505{
1506 if (pp != Protocol) return false;
1507
1508 CloseRequestCb = cb;
1509 CloseRequestCbArg = cbarg;
1510 return true;
1511}

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

637{
638 ssize_t retc = 0, bytesleft = Blen;
639
640// Get a lock
641//
642 wrMutex.Lock();
643 isIdle = 0;
644 AtomicAdd(BytesOut, Blen);
645
646// Do non-blocking writes if we are setup to do so.
647//
648 if (sendQ)
649 {retc = sendQ->Send(Buff, Blen);
650 wrMutex.UnLock();
651 return retc;
652 }
653
654// Write the data out
655//
656 while(bytesleft)
657 {if ((retc = write(LinkInfo.FD, Buff, bytesleft)) < 0)
658 {if (errno == EINTR) continue;
659 else break;
660 }
661 bytesleft -= retc; Buff += retc;
662 }
663
664// All done
665//
666 wrMutex.UnLock();
667 if (retc >= 0) return Blen;
668 Log.Emsg("Link", errno, "send to", ID);
669 return -1;
670}
#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 723 of file XrdLinkXeq.cc.

724{
725#if !defined(HAVE_SENDFILE)
726
727 return -1;
728
729#elif defined(__solaris__)
730
731 sendfilevec_t vecSF[XrdOucSFVec::sfMax], *vecSFP = vecSF;
732 size_t xframt, totamt, bytes = 0;
733 ssize_t retc;
734 int i = 0;
735
736// Construct the sendfilev() vector
737//
738 for (i = 0; i < sfN; sfP++, i++)
739 {if (sfP->fdnum < 0)
740 {vecSF[i].sfv_fd = SFV_FD_SELF;
741 vecSF[i].sfv_off = (off_t)sfP->buffer;
742 } else {
743 vecSF[i].sfv_fd = sfP->fdnum;
744 vecSF[i].sfv_off = sfP->offset;
745 }
746 vecSF[i].sfv_flag = 0;
747 vecSF[i].sfv_len = sfP->sendsz;
748 bytes += sfP->sendsz;
749 }
750 totamt = bytes;
751
752// Lock the link, issue sendfilev(), and unlock the link. The documentation
753// is very spotty and inconsistent. We can only retry this operation under
754// very limited conditions.
755//
756 wrMutex.Lock();
757 isIdle = 0;
758do{retc = sendfilev(LinkInfo.FD, vecSFP, sfN, &xframt);
759
760// Check if all went well and return if so (usual case)
761//
762 if (xframt == bytes)
763 {AtomicAdd(BytesOut, bytes);
764 wrMutex.UnLock();
765 return totamt;
766 }
767
768// The only one we will recover from is EINTR. We cannot legally get EAGAIN.
769//
770 if (retc < 0 && errno != EINTR) break;
771
772// Try to resume the transfer
773//
774 if (xframt > 0)
775 {AtomicAdd(BytesOut, xframt); bytes -= xframt; SfIntr++;
776 while(xframt > 0 && sfN)
777 {if ((ssize_t)xframt < (ssize_t)vecSFP->sfv_len)
778 {vecSFP->sfv_off += xframt; vecSFP->sfv_len -= xframt; break;}
779 xframt -= vecSFP->sfv_len; vecSFP++; sfN--;
780 }
781 }
782 } while(sfN > 0);
783
784// See if we can recover without destroying the connection
785//
786 retc = (retc < 0 ? errno : ECANCELED);
787 wrMutex.UnLock();
788 Log.Emsg("Link", retc, "send file to", ID);
789 return -1;
790
791#elif defined(__linux__) || defined(__GNU__)
792
793 static const int setON = 1, setOFF = 0;
794 ssize_t retc = 0, bytesleft;
795 off_t myOffset;
796 int i, xfrbytes = 0, uncork = 1, xIntr = 0;
797
798// lock the link
799//
800 wrMutex.Lock();
801 isIdle = 0;
802
803// In linux we need to cork the socket. On permanent errors we do not uncork
804// the socket because it will be closed in short order.
805//
806 if (setsockopt(PollInfo.FD, SOL_TCP, TCP_CORK, &setON, sizeof(setON)) < 0)
807 {Log.Emsg("Link", errno, "cork socket for", ID);
808 uncork = 0; sfOK = 0;
809 }
810
811// Send the header first
812//
813 for (i = 0; i < sfN; sfP++, i++)
814 {if (sfP->fdnum < 0) retc = sendData(sfP->buffer, sfP->sendsz);
815 else {myOffset = sfP->offset; bytesleft = sfP->sendsz;
816 while(bytesleft
817 && (retc=sendfile(LinkInfo.FD,sfP->fdnum,&myOffset,bytesleft)) > 0)
818 {bytesleft -= retc; xIntr++;}
819 }
820 if (retc < 0 && errno == EINTR) continue;
821 if (retc <= 0) break;
822 xfrbytes += sfP->sendsz;
823 }
824
825// Diagnose any sendfile errors
826//
827 if (retc <= 0)
828 {if (retc == 0) errno = ECANCELED;
829 wrMutex.UnLock();
830 Log.Emsg("Link", errno, "send file to", ID);
831 return -1;
832 }
833
834// Now uncork the socket
835//
836 if (uncork
837 && setsockopt(PollInfo.FD, SOL_TCP, TCP_CORK, &setOFF, sizeof(setOFF)) < 0)
838 Log.Emsg("Link", errno, "uncork socket for", ID);
839
840// All done
841//
842 if (xIntr > sfN) SfIntr += (xIntr - sfN);
843 AtomicAdd(BytesOut, xfrbytes);
844 wrMutex.UnLock();
845 return xfrbytes;
846
847#else
848
849 return -1;
850
851#endif
852}
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 674 of file XrdLinkXeq.cc.

675{
676 int retc;
677
678// Get a lock and assume we will be successful (statistically we are)
679//
680 wrMutex.Lock();
681 isIdle = 0;
682 AtomicAdd(BytesOut, bytes);
683
684// Do non-blocking writes if we are setup to do so.
685//
686 if (sendQ)
687 {retc = sendQ->Send(iov, iocnt, bytes);
688 wrMutex.UnLock();
689 return retc;
690 }
691
692// If the iocnt is within limits then just go ahead and write this out
693//
694 if (iocnt <= maxIOV)
695 {retc = SendIOV(iov, iocnt, bytes);
696 wrMutex.UnLock();
697 return retc;
698 }
699
700// We will have to break this up into allowable segments
701//
702 int seglen, segcnt = maxIOV, iolen = 0;
703 do {seglen = 0;
704 for (int i = 0; i < segcnt; i++) seglen += iov[i].iov_len;
705 if ((retc = SendIOV(iov, segcnt, seglen)) < 0)
706 {wrMutex.UnLock();
707 return retc;
708 }
709 iolen += retc;
710 iov += segcnt;
711 iocnt -= segcnt;
712 if (iocnt <= maxIOV) segcnt = iocnt;
713 } while(iocnt > 0);
714
715// All done
716//
717 wrMutex.UnLock();
718 return iolen;
719}
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 858 of file XrdLinkXeq.cc.

859{
860 ssize_t retc = 0, bytesleft = Blen;
861
862// Write the data out
863//
864 while(bytesleft)
865 {if ((retc = write(LinkInfo.FD, Buff, bytesleft)) < 0)
866 {if (errno == EINTR) continue;
867 else break;
868 }
869 bytesleft -= retc; Buff += retc;
870 }
871
872// All done
873//
874 return retc;
875}

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

882{
883 ssize_t bytesleft, n, retc = 0;
884 const char *Buff;
885
886// Write the data out. On some version of Unix (e.g., Linux) a writev() may
887// end at any time without writing all the bytes when directed to a socket.
888// So, we attempt to resume the writev() using a combination of write() and
889// a writev() continuation. This approach slowly converts a writev() to a
890// series of writes if need be. We must do this inline because we must hold
891// the lock until all the bytes are written or an error occurs.
892//
893 bytesleft = static_cast<ssize_t>(bytes);
894 while(bytesleft)
895 {do {retc = writev(LinkInfo.FD, iov, iocnt);}
896 while(retc < 0 && errno == EINTR);
897 if (retc >= bytesleft || retc < 0) break;
898 bytesleft -= retc;
899 while(retc >= (n = static_cast<ssize_t>(iov->iov_len)))
900 {retc -= n; iov++; iocnt--;}
901 Buff = (const char *)iov->iov_base + retc; n -= retc; iov++; iocnt--;
902 while(n) {if ((retc = write(LinkInfo.FD, Buff, n)) < 0)
903 {if (errno == EINTR) continue;
904 else break;
905 }
906 n -= retc; Buff += retc; bytesleft -= retc;
907 }
908 if (retc < 0 || iocnt < 1) break;
909 }
910
911// All done
912//
913 if (retc >= 0) return bytes;
914 Log.Emsg("Link", errno, "send to", ID);
915 return -1;
916}
#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 922 of file XrdLinkXeq.cc.

923{
924 char buff[sizeof(Uname)], *bp, *sp;
925 int ulen;
926
927 snprintf(buff, sizeof(buff), "%s.%d:%d", userid, procid, PollInfo.FD);
928 ulen = strlen(buff);
929 sp = buff + ulen - 1;
930 bp = &Uname[sizeof(Uname)-1];
931 if (ulen > (int)sizeof(Uname)) ulen = sizeof(Uname);
932 *bp = '@'; bp--;
933 while(ulen--) {*bp = *sp; bp--; sp--;}
934 ID = bp+1;
935 Comment = (const char *)ID;
936
937// Update the ID in the TLS socket if enabled
938//
939 if (isTLS) tlsIO.SetTraceID(ID);
940}

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

947{
948// We don't support non-blocking output except for Linux at the moment
949//
950#if !defined(__linux__)
951 return false;
952#else
953// Trace this request
954//
955 TRACEI(DEBUG,"enabling non-blocking output");
956
957// If we don't already have a sendQ object get one. This is a one-time call
958// so to optimize checking if this object exists we also get the opMutex.'
959//
960 LinkInfo.opMutex.Lock();
961 if (!sendQ)
962 {wrMutex.Lock();
963 sendQ = new XrdSendQ(*this, wrMutex);
964 wrMutex.UnLock();
965 }
966 LinkInfo.opMutex.UnLock();
967 return true;
968#endif
969}

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

◆ setProtName()

void XrdLinkXeq::setProtName ( const char * name)

Definition at line 992 of file XrdLinkXeq.cc.

993{
994
995// Set the protocol name.
996//
997 LinkInfo.opMutex.Lock();
998 Addr.SetDialect(name);
999 LinkInfo.opMutex.UnLock();
1000}

References Addr, and LinkInfo.

◆ setProtocol()

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

Definition at line 975 of file XrdLinkXeq.cc.

976{
977
978// Set new protocol.
979//
980 LinkInfo.opMutex.Lock();
981 XrdProtocol *op = Protocol;
982 if (push) ProtoAlt = Protocol;
983 Protocol = pp;
984 LinkInfo.opMutex.UnLock();
985 return op;
986}

References LinkInfo, ProtoAlt, and Protocol.

◆ setTLS()

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

Definition at line 1006 of file XrdLinkXeq.cc.

1007{ //???
1008// static const XrdTlsConnection::RW_Mode rwMode=XrdTlsConnection::TLS_RNB_WBL;
1011 const char *eNote;
1012 XrdTls::RC rc;
1013
1014// If we are already in a compatible mode, we are done
1015//
1016
1017 if (isTLS == enable) return true;
1018
1019// If this is a shutdown, then do it now.
1020//
1021 if (!enable)
1022 {tlsIO.Shutdown();
1023 isTLS = enable;
1024 Addr.SetTLS(enable);
1025 return true;
1026 }
1027// We want to initialize TLS, do so now.
1028//
1029 if (!ctx) ctx = tlsCtx;
1030 eNote = tlsIO.Init(*ctx, PollInfo.FD, rwMode, hsMode, false, false, ID);
1031
1032// Check for errors
1033//
1034 if (eNote)
1035 {char buff[1024];
1036 snprintf(buff, sizeof(buff), "Unable to enable tls for %s;", ID);
1037 Log.Emsg("LinkXeq", buff, eNote);
1038 return false;
1039 }
1040
1041// Now we need to accept this TLS connection
1042//
1043 std::string eMsg;
1044 rc = tlsIO.Accept(&eMsg);
1045
1046// Diagnose return state
1047//
1048 if (rc != XrdTls::TLS_AOK) Log.Emsg("LinkXeq", eMsg.c_str());
1049 else {isTLS = enable;
1050 Addr.SetTLS(enable);
1051 Log.Emsg("LinkXeq", ID, "connection upgraded to", verTLS());
1052 }
1053 return rc == XrdTls::TLS_AOK;
1054}
#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 1060 of file XrdLinkXeq.cc.

1061{
1062 Log.Emsg("TLS", rc, "send file to", ID);
1063 return -1;
1064}

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

1071{
1072 int temp;
1073
1074// Trace the entry
1075//
1076 TRACEI(DEBUG, (getLock ? "Async" : "Sync") <<" link shutdown in progress");
1077
1078// Get the lock if we need too (external entry via another thread)
1079//
1080 if (getLock) LinkInfo.opMutex.Lock();
1081
1082// If there is something to do, do it now
1083//
1084 temp = Instance; Instance = 0;
1085 if (!KeepFD)
1086 {shutdown(PollInfo.FD, SHUT_RDWR);
1087 if (dup2(devNull, PollInfo.FD) < 0)
1088 {Instance = temp;
1089 Log.Emsg("Link", errno, "shutdown FD for", ID);
1090 }
1091 }
1092
1093// All done
1094//
1095 if (getLock) LinkInfo.opMutex.UnLock();
1096}

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

1103{
1104 static const char statfmt[] = "<stats id=\"link\"><num>%d</num>"
1105 "<maxn>%d</maxn><tot>%lld</tot><in>%lld</in><out>%lld</out>"
1106 "<ctime>%lld</ctime><tmo>%d</tmo><stall>%d</stall>"
1107 "<sfps>%d</sfps></stats>";
1108 int i;
1109
1110// Check if actual length wanted
1111//
1112 if (!buff) return sizeof(statfmt)+17*6;
1113
1114// We must synchronize the statistical counters
1115//
1116 if (do_sync) XrdLinkCtl::SyncAll();
1117
1118// Obtain lock on the stats area and format it
1119//
1121 i = snprintf(buff, blen, statfmt, AtomicGet(LinkCount),
1131 return i;
1132}
#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 1138 of file XrdLinkXeq.cc.

1139{
1140 long long tmpLL;
1141 int tmpI4;
1142
1143// If this is dynamic, get the opMutex lock
1144//
1145 if (!ctime) LinkInfo.opMutex.Lock();
1146
1147// Either the caller has the opMutex or this is called out of close. In either
1148// case, we need to get the read and write mutexes; each followed by the stats
1149// mutex. This order is important because we should not hold the stats mutex
1150// for very long and the r/w mutexes may take a long time to acquire. If we
1151// must maintain the link count we need to actually acquire the stats mutex as
1152// we will be doing compound operations. Atomics are still used to keep other
1153// threads from seeing partial results.
1154//
1156
1157 if (ctime)
1158 {*ctime = time(0) - LinkInfo.conTime;
1159 AtomicAdd(LinkConTime, *ctime);
1160 statsMutex.Lock();
1161 if (LinkCount > 0) AtomicDec(LinkCount);
1162 statsMutex.UnLock();
1163 }
1164
1166
1167 tmpLL = AtomicFAZ(BytesIn);
1168 AtomicAdd(LinkBytesIn, tmpLL); AtomicAdd(BytesInTot, tmpLL);
1169 tmpI4 = AtomicFAZ(tardyCnt);
1171 tmpI4 = AtomicFAZ(stallCnt);
1172 AtomicAdd(LinkStalls, tmpI4); AtomicAdd(stallCntTot, tmpI4);
1174
1176 tmpLL = AtomicFAZ(BytesOut);
1178 tmpI4 = AtomicFAZ(SfIntr);
1179 AtomicAdd(LinkSfIntr, tmpI4);
1181
1182// Make sure the protocol updates it's statistics as well
1183//
1184 if (Protocol) Protocol->Stats(0, 0, 1);
1185
1186// All done
1187//
1188 if (!ctime) LinkInfo.opMutex.UnLock();
1189}
#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 1195 of file XrdLinkXeq.cc.

1196{
1197 std::string reason = XrdTls::RC2Text(rc);
1198 char msg[512];
1199
1200 snprintf(msg, sizeof(msg), "Unable to %s %s;", act, ID);
1201 Log.Emsg("TLS", msg, reason.c_str());
1202 return -1;
1203}
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 1209 of file XrdLinkXeq.cc.

1210{
1211 XrdSysMutexHelper theMutex;
1212 XrdTls::RC retc;
1213 int rc, rlen;
1214
1215// Lock the read mutex if we need to, the helper will unlock it upon exit
1216//
1217 if (LockReads) theMutex.Lock(&rdMutex);
1218
1219// Wait until we can actually read something
1220//
1221 isIdle = 0;
1222 if (timeout)
1223 {rc = Wait4Data(timeout);
1224 if (rc < 1) return rc;
1225 }
1226
1227// Do the peek and if sucessful, the number of bytes available.
1228//
1229 retc = tlsIO.Peek(Buff, Blen, rlen);
1230 if (retc == XrdTls::TLS_AOK) return rlen;
1231
1232// Dianose the TLS error and return failure
1233//
1234 return TLS_Error("peek on", retc);
1235}
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 1241 of file XrdLinkXeq.cc.

1242{
1243 XrdSysMutexHelper theMutex;
1244 XrdTls::RC retc;
1245 int rlen;
1246
1247// Lock the read mutex if we need to, the helper will unlock it upon exit
1248//
1249 if (LockReads) theMutex.Lock(&rdMutex);
1250
1251// Note that we will read only as much as is queued. Use Recv() with a
1252// timeout to receive as much data as possible.
1253//
1254 isIdle = 0;
1255 retc = tlsIO.Read(Buff, Blen, rlen);
1256 if (retc != XrdTls::TLS_AOK) return TLS_Error("receive from", retc);
1257 if (rlen > 0) AtomicAdd(BytesIn, rlen);
1258 return rlen;
1259}

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

1264{
1265 XrdSysMutexHelper theMutex;
1266 XrdTls::RC retc;
1267 int pend, rlen, totlen = 0;
1268
1269// Lock the read mutex if we need to, the helper will unlock it upon exit
1270//
1271 if (LockReads && !havelock) theMutex.Lock(&rdMutex);
1272
1273// Wait up to timeout milliseconds for data to arrive
1274//
1275 isIdle = 0;
1276 while(Blen > 0)
1277 {pend = tlsIO.Pending(true);
1278 if (!pend) pend = Wait4Data(timeout);
1279 if (pend < 1)
1280 {if (pend < 0) return -1;
1281 tardyCnt++;
1282 if (totlen)
1283 {if ((++stallCnt & 0xff) == 1) TRACEI(DEBUG,"read timed out");
1284 AtomicAdd(BytesIn, totlen);
1285 }
1286 return totlen;
1287 }
1288
1289 // Read as much data as you can. Note that we will force an error
1290 // if we get a zero-length read after poll said it was OK. However,
1291 // if we never read anything, then we simply return -ENOMSG to avoid
1292 // generating a "read link error" as clearly there was a hangup.
1293 //
1294 retc = tlsIO.Read(Buff, Blen, rlen);
1295 if (retc != XrdTls::TLS_AOK)
1296 {if (!totlen) return -ENOMSG;
1297 AtomicAdd(BytesIn, totlen);
1298 return TLS_Error("receive from", retc);
1299 }
1300 if (rlen <= 0) break;
1301 totlen += rlen; Blen -= rlen; Buff += rlen;
1302 }
1303
1304 AtomicAdd(BytesIn, totlen);
1305 return totlen;
1306}

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

1311{
1312 XrdSysMutexHelper theMutex;
1313 char *Buff;
1314 int Blen, rlen, totlen = 0;
1315
1316// Lock the read mutex if we need to, the helper will unlock it upon exit
1317//
1318 if (LockReads) theMutex.Lock(&rdMutex);
1319
1320// Individually process each element until we can't read any more
1321//
1322 isIdle = 0;
1323 for (int i = 0; i < iocnt; i++)
1324 {Buff = (char *)iov[i].iov_base;
1325 Blen = iov[i].iov_len;
1326 rlen = TLS_Recv(Buff, Blen, timeout, true);
1327 if (rlen <= 0) break;
1328 totlen += rlen;
1329 if (rlen < Blen) break;
1330 }
1331
1332 if (totlen) {AtomicAdd(BytesIn, totlen);}
1333 return totlen;
1334}
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 1340 of file XrdLinkXeq.cc.

1341{
1342 int retc;
1343
1344// Check if timeout specified. Notice that the timeout is the max we will
1345// wait for some data. We will wait forever for all the data. Yeah, it's weird.
1346//
1347 if (timeout >= 0)
1348 {retc = tlsIO.Pending(true);
1349 if (!retc) retc = Wait4Data(timeout);
1350 if (retc < 1) return (retc ? -1 : -ETIMEDOUT);
1351 }
1352
1353// Note that we will block until we receive all the bytes.
1354//
1355 return TLS_Recv(Buff, Blen, -1);
1356}

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

1363{
1364 XrdSysMutexHelper lck(wrMutex);
1365 ssize_t bytesleft = Blen;
1366 XrdTls::RC retc;
1367 int byteswritten;
1368
1369// Prepare to send
1370//
1371 isIdle = 0;
1372 AtomicAdd(BytesOut, Blen);
1373
1374// Do non-blocking writes if we are setup to do so.
1375//
1376 if (sendQ) return sendQ->Send(Buff, Blen);
1377
1378// Write the data out
1379//
1380 while(bytesleft)
1381 {retc = tlsIO.Write(Buff, bytesleft, byteswritten);
1382 if (retc != XrdTls::TLS_AOK) return TLS_Error("send to", retc);
1383 bytesleft -= byteswritten; Buff += byteswritten;
1384 }
1385
1386// All done
1387//
1388 return Blen;
1389}

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

1429{
1430 XrdSysMutexHelper lck(wrMutex);
1431 int bytes, buffsz, fileFD, retc;
1432 off_t offset;
1433 ssize_t totamt = 0;
1434 char myBuff[65536];
1435
1436// Convert the sendfile to a regular send. The conversion is not particularly
1437// fast and caller are advised to avoid using sendfile on TLS connections.
1438//
1439 isIdle = 0;
1440 for (int i = 0; i < sfN; sfP++, i++)
1441 {if (!(bytes = sfP->sendsz)) continue;
1442 totamt += bytes;
1443 if (sfP->fdnum < 0)
1444 {if (!TLS_Write(sfP->buffer, bytes)) return -1;
1445 continue;
1446 }
1447 offset = sfP->offset;
1448 fileFD = sfP->fdnum;
1449 buffsz = (bytes < (int)sizeof(myBuff) ? bytes : sizeof(myBuff));
1450 do {do {retc = pread(fileFD, myBuff, buffsz, offset);}
1451 while(retc < 0 && errno == EINTR);
1452 if (retc < 0) return SFError(errno);
1453 if (!retc) break;
1454 if (!TLS_Write(myBuff, buffsz)) return -1;
1455 offset += buffsz; bytes -= buffsz; totamt += retc;
1456 } while(bytes > 0);
1457 }
1458
1459// We are done
1460//
1461 AtomicAdd(BytesOut, totamt);
1462 return totamt;
1463}
#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 1393 of file XrdLinkXeq.cc.

1394{
1395 XrdSysMutexHelper lck(wrMutex);
1396 XrdTls::RC retc;
1397 int byteswritten;
1398
1399// Get a lock and assume we will be successful (statistically we are). Note
1400// that the calling interface gauranteed bytes are not zero.
1401//
1402 isIdle = 0;
1403 AtomicAdd(BytesOut, bytes);
1404
1405// Do non-blocking writes if we are setup to do so.
1406//
1407 if (sendQ) return sendQ->Send(iov, iocnt, bytes);
1408
1409// Write the data out.
1410//
1411 for (int i = 0; i < iocnt; i++)
1412 {ssize_t bytesleft = iov[i].iov_len;
1413 char *Buff = (char *)iov[i].iov_base;
1414 while(bytesleft)
1415 {retc = tlsIO.Write(Buff, bytesleft, byteswritten);
1416 if (retc != XrdTls::TLS_AOK) return TLS_Error("send to", retc);
1417 bytesleft -= byteswritten; Buff += byteswritten;
1418 }
1419 }
1420
1421// All done
1422//
1423 return bytes;
1424}

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

1470{
1471 XrdTls::RC retc;
1472 int byteswritten;
1473
1474// Write the data out
1475//
1476 while(Blen)
1477 {retc = tlsIO.Write(Buff, Blen, byteswritten);
1478 if (retc != XrdTls::TLS_AOK)
1479 {TLS_Error("write to", retc);
1480 return false;
1481 }
1482 Blen -= byteswritten; Buff += byteswritten;
1483 }
1484
1485// All done
1486//
1487 return true;
1488}

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

1495{
1496 return tlsIO.Version();
1497}

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: