XRootD
XrdLinkCtl Class Reference

#include <XrdLinkCtl.hh>

+ Inheritance diagram for XrdLinkCtl:
+ Collaboration diagram for XrdLinkCtl:

Public Member Functions

 XrdLinkCtl ()
 Constructor. More...
 

Static Public Member Functions

static XrdLinkAlloc (XrdNetAddr &peer, int opts=0)
 
static XrdLinkfd2link (int fd)
 
static XrdLinkfd2link (int fd, unsigned int inst)
 
static XrdPollInfofd2PollInfo (int fd)
 
static XrdLinkFind (int &curr, XrdLinkMatch *who=0)
 
static int getName (int &curr, char *bname, int blen, XrdLinkMatch *who=0)
 
static void idleScan ()
 Look for idle links and close hem down. More...
 
static void setKWT (int wkSec, int kwSec)
 
static int Setup (int maxfds, int idlewt)
 
static void SyncAll ()
 Synchronize statustics for ll links. More...
 
static void Unhook (int fd)
 Unhook a link from the active table of links. More...
 

Static Public Attributes

static short killWait = 3
 Link destruction control constants. More...
 
static short waitKill = 4
 

Additional Inherited Members

- Protected Member Functions inherited from XrdLinkXeq
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)
 
 XrdLinkXeq ()
 
 ~XrdLinkXeq ()
 
XrdNetAddrInfoAddrInfo ()
 
int Backlog ()
 
int Client (char *buff, int blen)
 
int Close (bool defer=false)
 
void DoIt ()
 
int getIOStats (long long &inbytes, long long &outbytes, int &numstall, int &numtardy)
 
XrdTlsPeerCertsgetPeerCerts ()
 
XrdProtocolgetProtocol ()
 
const char * Name () const
 
const XrdNetAddrNetAddr () const
 
int Peek (char *buff, int blen, int timeout=-1)
 
int Recv (char *buff, int blen)
 
int Recv (char *buff, int blen, int timeout)
 
int Recv (const struct iovec *iov, int iocnt, int timeout)
 
int RecvAll (char *buff, int blen, int timeout=-1)
 
bool Register (const char *hName)
 
int Send (const char *buff, int blen)
 
int Send (const sfVec *sdP, int sdn)
 
int Send (const struct iovec *iov, int iocnt, int bytes=0)
 
void setID (const char *userid, int procid)
 
void setLocation (XrdNetAddrInfo::LocInfo &loc)
 
bool setNB ()
 
void setProtName (const char *name)
 
XrdProtocolsetProtocol (XrdProtocol *pp, bool push)
 
bool setTLS (bool enable, XrdTlsContext *ctx=0)
 
void Shutdown (bool getLock)
 
void syncStats (int *ctime=0)
 
int TLS_Peek (char *Buff, int Blen, int timeout)
 
int TLS_Recv (char *Buff, int Blen)
 
int TLS_Recv (char *Buff, int Blen, int timeout, bool havelock=false)
 
int TLS_Recv (const struct iovec *iov, int iocnt, int timeout)
 
int TLS_RecvAll (char *Buff, int Blen, int timeout)
 
int TLS_Send (const char *Buff, int Blen)
 
int TLS_Send (const sfVec *sfP, int sfN)
 
int TLS_Send (const struct iovec *iov, int iocnt, int bytes)
 
const char * verTLS ()
 
- Protected Member Functions inherited from XrdJob
 XrdJob (const char *desc="")
 
virtual ~XrdJob ()
 
- Static Protected Member Functions inherited from XrdLinkXeq
static int getName (int &curr, char *bname, int blen, XrdLinkMatch *who=0)
 
static int Stats (char *buff, int blen, bool do_sync=false)
 
- Protected Attributes inherited from XrdLinkXeq
XrdNetAddr Addr
 
long long BytesIn
 
long long BytesInTot
 
long long BytesOut
 
long long BytesOutTot
 
int HNlen
 
char isIdle
 
bool KeepFD
 
char Lname [256]
 
bool LockReads
 
XrdProtocolProtoAlt
 
XrdProtocolProtocol
 
XrdSysMutex rdMutex
 
XrdSendQsendQ
 
int SfIntr
 
int stallCnt
 
int stallCntTot
 
int tardyCnt
 
int tardyCntTot
 
XrdTlsSocket tlsIO
 
char Uname [24]
 
XrdSysMutex wrMutex
 
XrdLinkInfo LinkInfo
 
XrdPollInfo PollInfo
 
- Protected Attributes inherited from XrdJob
const char * Comment
 
XrdJobNextJob
 
- Static Protected Attributes inherited from XrdLinkXeq
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"
 

Detailed Description

Definition at line 42 of file XrdLinkCtl.hh.

Constructor & Destructor Documentation

◆ XrdLinkCtl()

XrdLinkCtl::XrdLinkCtl ( )
inline

Constructor.

Definition at line 197 of file XrdLinkCtl.hh.

197 {}

Member Function Documentation

◆ Alloc()

XrdLink * XrdLinkCtl::Alloc ( XrdNetAddr peer,
int  opts = 0 
)
static

Definition at line 109 of file XrdLinkCtl.cc.

110 {
111  XrdLinkCtl *lp;
112  char hName[1024], *unp, buff[32];
113  int bl, peerFD = peer.SockFD();
114 
115 // Make sure that the incoming file descriptor can be handled
116 //
117  if (peerFD < 0 || peerFD >= maxFD)
118  {snprintf(hName, sizeof(hName), "%d", peerFD);
119  Log.Emsg("Link", "attempt to alloc out of range FD -",hName);
120  return (XrdLink *)0;
121  }
122 
123 // Make sure that the link slot is available
124 //
125  LTMutex.Lock();
126  if (LinkBat[peerFD])
127  {LTMutex.UnLock();
128  snprintf(hName, sizeof(hName), "%d", peerFD);
129  Log.Emsg("Link", "attempt to reuse active link FD -",hName);
130  return (XrdLink *)0;
131  }
132 
133 // Check if we already have a link object in this slot. If not, allocate
134 // a quantum of link objects and put them in the table.
135 //
136  if (!(lp = LinkTab[peerFD]))
137  {unsigned int i;
138  XrdLinkCtl **blp, *nlp = new XrdLinkCtl[LinkAlloc]();
139  if (!nlp)
140  {LTMutex.UnLock();
141  Log.Emsg("Link", ENOMEM, "create link");
142  return (XrdLink *)0;
143  }
144  blp = &LinkTab[peerFD/LinkAlloc*LinkAlloc];
145  for (i = 0; i < LinkAlloc; i++, blp++) *blp = &nlp[i];
146  lp = LinkTab[peerFD];
147  }
148  else lp->Reset();
149  LinkBat[peerFD] = XRDLINK_USED;
150  if (peerFD > LTLast) LTLast = peerFD;
151  LTMutex.UnLock();
152 
153 // Establish the instance number of this link. This is will prevent us from
154 // sending asynchronous responses to the wrong client when the file descriptor
155 // gets reused for connections to the same host.
156 //
157  instMutex.Lock();
158  lp->Instance = myInstance++;
159  instMutex.UnLock();
160 
161 // Establish the address and connection name of this link
162 //
163  peer.Format(hName, sizeof(hName), XrdNetAddr::fmtAuto,
165  lp->HostName = strdup(hName);
166  lp->HNlen = strlen(hName);
167  XrdNetTCP->Trim(hName);
168  lp->Addr = peer;
169  strlcpy(lp->Lname, hName, sizeof(lp->Lname));
170  bl = sprintf(buff, "anon.0:%d", peerFD);
171  unp = lp->Uname + sizeof(Uname) - bl - 1; // Solaris compatibility
172  memcpy(unp, buff, bl);
173  lp->ID = unp;
174  lp->PollInfo.FD = lp->LinkInfo.FD = peerFD;
175  lp->Comment = (const char *)unp;
176 
177 // Set options as needed
178 //
179  lp->LockReads = (0 != (opts & XRDLINK_RDLOCK));
180  lp->KeepFD = (0 != (opts & XRDLINK_NOCLOSE));
181 
182 // Update statistics and return the link. We need to actually get the stats
183 // mutex even when using atomics because we need to use compound operations.
184 // The atomics will keep reporters from seeing partial results.
185 //
186  statsMutex.Lock();
187  AtomicInc(LinkCountTot); // LinkCountTot++
189  statsMutex.UnLock();
190  return lp;
191 }
#define XRDLINK_NOCLOSE
Definition: XrdLinkCtl.hh:59
#define XRDLINK_RDLOCK
Definition: XrdLinkCtl.hh:58
struct myOpts opts
#define AtomicInc(x)
size_t strlcpy(char *dst, const char *src, size_t sz)
const char * Comment
Definition: XrdJob.hh:47
char Uname[24]
Definition: XrdLinkXeq.hh:200
static int LinkCountMax
Definition: XrdLinkXeq.hh:166
XrdLinkInfo LinkInfo
Definition: XrdLinkXeq.hh:144
XrdNetAddr Addr
Definition: XrdLinkXeq.hh:192
static long long LinkCountTot
Definition: XrdLinkXeq.hh:164
static int LinkCount
Definition: XrdLinkXeq.hh:165
void Reset()
Definition: XrdLinkXeq.cc:113
XrdPollInfo PollInfo
Definition: XrdLinkXeq.hh:145
bool LockReads
Definition: XrdLinkXeq.hh:197
char Lname[256]
Definition: XrdLinkXeq.hh:201
static XrdSysMutex statsMutex
Definition: XrdLinkXeq.hh:179
static const int noPort
Do not add port number.
static const int old6Map4
Use deprecated IPV6 mapped format.
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
@ fmtAuto
Hostname if already resolved o/w use fmtAddr.
void Trim(char *hname)
Definition: XrdNet.cc:343
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
XrdInet * XrdNetTCP
Definition: XrdGlobals.cc:53
XrdSysError Log
Definition: XrdConfig.cc:112

References XrdLinkXeq::Addr, AtomicInc, XrdJob::Comment, XrdSysError::Emsg(), XrdLinkInfo::FD, XrdPollInfo::FD, XrdNetAddrInfo::fmtAuto, XrdNetAddrInfo::Format(), XrdLinkXeq::HNlen, XrdLink::HostName, XrdLink::ID, XrdLink::Instance, XrdLinkXeq::KeepFD, XrdLinkXeq::LinkInfo, XrdLinkXeq::Lname, XrdSysMutex::Lock(), XrdLinkXeq::LockReads, XrdGlobal::Log, XrdNetAddrInfo::noPort, XrdNetAddrInfo::old6Map4, opts, XrdLinkXeq::PollInfo, XrdLinkXeq::Reset(), XrdNetAddrInfo::SockFD(), strlcpy(), XrdNet::Trim(), XrdLinkXeq::Uname, XrdSysMutex::UnLock(), XRDLINK_NOCLOSE, XRDLINK_RDLOCK, and XrdGlobal::XrdNetTCP.

Referenced by XrdInet::Accept(), and XrdInet::Connect().

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

◆ fd2link() [1/2]

static XrdLink* XrdLinkCtl::fd2link ( int  fd)
inlinestatic

Translate a file descriptor number to the corresponding link object.

Parameters
fdThe file descriptor number.
Returns
!0 Pointer to the link object. =0 The file descriptor is not associated with a link.

Definition at line 72 of file XrdLinkCtl.hh.

73  {if (fd < 0) fd = -fd;
74  return (fd <= LTLast && LinkBat[fd] ? LinkTab[fd] : 0);
75  }

Referenced by XrdXrootdResponse::Send(), and XrdLink::Terminate().

+ Here is the caller graph for this function:

◆ fd2link() [2/2]

static XrdLink* XrdLinkCtl::fd2link ( int  fd,
unsigned int  inst 
)
inlinestatic

Translate a file descriptor number and an instance to a link object.

Parameters
fdThe file descriptor number.
instThe file descriptor number instance number.
Returns
!0 Pointer to the link object. =0 The file descriptor instance is not associated with a link.

Definition at line 87 of file XrdLinkCtl.hh.

88  {if (fd < 0) fd = -fd;
89  if (fd <= LTLast && LinkBat[fd] && LinkTab[fd]
90  && LinkTab[fd]->Instance == inst) return LinkTab[fd];
91  return (XrdLink *)0;
92  }

References XrdLink::Instance.

◆ fd2PollInfo()

static XrdPollInfo* XrdLinkCtl::fd2PollInfo ( int  fd)
inlinestatic

Translate a file descriptor number to the corresponding PollInfo object.

Parameters
fdThe file descriptor number.
Returns
!0 Pointer to the PollInfo object. =0 The file descriptor is not associated with a link.

Definition at line 103 of file XrdLinkCtl.hh.

104  {if (fd < 0) fd = -fd;
105  if (fd <= LTLast && LinkBat[fd])
106  return &(LinkTab[fd]->PollInfo);
107  return 0;
108  }

References XrdLinkXeq::PollInfo.

◆ Find()

XrdLink * XrdLinkCtl::Find ( int &  curr,
XrdLinkMatch who = 0 
)
static

Find the next link matching certain attributes.

Parameters
currIs an internal tracking value that allows repeated calls. It must be set to a value of 0 or less on the initial call and not touched therafter unless a null pointer is returned.
whoIf the object use to check if the link matches the wanted criterea (typically, client name and host name). If the ppointer is nil, the next link is always returned.
Returns
!0 Pointer to the link object that matches the criterea. The link's reference counter is increased to prevent it from being reused. A subsequent call will reduce the number. =0 No more links exist with the specified criterea.

Definition at line 202 of file XrdLinkCtl.cc.

203 {
204  XrdLinkCtl *lp;
205  const int MaxSeek = 16;
206  unsigned int myINS;
207  int i, seeklim = MaxSeek;
208 
209 // Do initialization
210 //
211  LTMutex.Lock();
212  if (curr >= 0 && LinkTab[curr]) LinkTab[curr]->setRef(-1);
213  else curr = -1;
214 
215 // Find next matching link. Since this may take some time, we periodically
216 // release the LTMutex lock which drives up overhead but will still allow
217 // other critical operations to occur.
218 //
219  for (i = curr+1; i <= LTLast; i++)
220  {if ((lp = LinkTab[i]) && LinkBat[i] && lp->HostName)
221  if (!who
222  || who->Match(lp->ID,lp->Lname-lp->ID-1,lp->HostName,lp->HNlen))
223  {myINS = lp->Instance;
224  LTMutex.UnLock();
225  lp->setRef(1);
226  curr = i;
227  if (myINS == lp->Instance) return lp;
228  LTMutex.Lock();
229  }
230  if (!seeklim--) {LTMutex.UnLock(); seeklim = MaxSeek; LTMutex.Lock();}
231  }
232 
233 // Done scanning the table
234 //
235  LTMutex.UnLock();
236  curr = -1;
237  return 0;
238 }
int Match(const char *uname, int unlen, const char *hname, int hnlen)
Definition: XrdLinkMatch.cc:39

References XrdLinkXeq::HNlen, XrdLink::HostName, XrdLink::ID, XrdLink::Instance, XrdLinkXeq::Lname, XrdLinkMatch::Match(), and XrdLink::setRef().

Referenced by XrdLink::Find().

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

◆ getName()

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

Find the next client name matching certain attributes.

Parameters
currIs an internal tracking value that allows repeated calls. It must be set to a value of 0 or less on the initial call and not touched therafter unless zero is returned.
bnamePointer to a buffer where the name is to be returned.
blenThe length of the buffer.
whoIf the object use to check if the link matches the wanted criterea (typically, client name and host name). If the pointer is nil, a match always occurs.
Returns
!0 The length of the name placed in the buffer. =0 No more links exist with the specified criterea.

Definition at line 248 of file XrdLinkCtl.cc.

249 {
250  XrdLinkCtl *lp;
251  const int MaxSeek = 16;
252  int i, ulen = 0, seeklim = MaxSeek;
253 
254 // Find next matching link. Since this may take some time, we periodically
255 // release the LTMutex lock which drives up overhead but will still allow
256 // other critical operations to occur.
257 //
258  LTMutex.Lock();
259  for (i = curr+1; i <= LTLast; i++)
260  {if ((lp = LinkTab[i]) && LinkBat[i] && lp->HostName)
261  if (!who
262  || who->Match(lp->ID,lp->Lname-lp->ID-1,lp->HostName,lp->HNlen))
263  {ulen = lp->Client(nbuf, nbsz);
264  LTMutex.UnLock();
265  curr = i;
266  return ulen;
267  }
268  if (!seeklim--) {LTMutex.UnLock(); seeklim = MaxSeek; LTMutex.Lock();}
269  }
270  LTMutex.UnLock();
271 
272 // Done scanning the table
273 //
274  curr = -1;
275  return 0;
276 }
int Client(char *buff, int blen)
Definition: XrdLinkXeq.cc:152

References XrdLinkXeq::Client(), XrdLinkXeq::HNlen, XrdLink::HostName, XrdLink::ID, XrdLinkXeq::Lname, and XrdLinkMatch::Match().

Referenced by XrdLink::getName().

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

◆ idleScan()

void XrdLinkCtl::idleScan ( )
static

Look for idle links and close hem down.

Definition at line 285 of file XrdLinkCtl.cc.

286 {
287  XrdLinkCtl *lp;
288  int i, ltlast, lnum = 0, tmo = 0, tmod = 0;
289 
290 // Get the current link high watermark
291 //
292  LTMutex.Lock();
293  ltlast = LTLast;
294  LTMutex.UnLock();
295 
296 // Scan across all links looking for idle links. Links are never deallocated
297 // so we don't need any special kind of lock for these
298 //
299  for (i = 0; i <= ltlast; i++)
300  {if (LinkBat[i] != XRDLINK_USED
301  || !(lp = LinkTab[i])) continue;
302  lnum++;
303  lp->LinkInfo.opMutex.Lock();
304  if (lp->isIdle) tmo++;
305  lp->isIdle++;
306  if ((int(lp->isIdle)) < idleTicks)
307  {lp->LinkInfo.opMutex.UnLock(); continue;}
308  lp->isIdle = 0;
309  if (!(lp->PollInfo.Poller) || !(lp->PollInfo.isEnabled))
310  Log.Emsg("LinkScan","Link",lp->ID,"is disabled and idle.");
311  else if (lp->LinkInfo.InUse == 1)
312  {lp->PollInfo.Poller->Disable(lp->PollInfo, "idle timeout");
313  tmod++;
314  }
315  lp->LinkInfo.opMutex.UnLock();
316  }
317 
318 // Trace what we did
319 //
320  TRACE(CONN, lnum <<" links; " <<tmo <<" idle; " <<tmod <<" force closed");
321 }
#define TRACE(act, x)
Definition: XrdTrace.hh:63
XrdSysRecMutex opMutex
Definition: XrdLinkInfo.hh:46
bool isEnabled
Definition: XrdPollInfo.hh:46
XrdPoll * Poller
Definition: XrdPollInfo.hh:43
virtual void Disable(XrdPollInfo &pInfo, const char *etxt=0)=0

References XrdPoll::Disable(), XrdSysError::Emsg(), XrdLink::ID, XrdLinkInfo::InUse, XrdPollInfo::isEnabled, XrdLinkXeq::isIdle, XrdLinkXeq::LinkInfo, XrdSysMutex::Lock(), XrdGlobal::Log, XrdLinkInfo::opMutex, XrdPollInfo::Poller, XrdLinkXeq::PollInfo, TRACE, and XrdSysMutex::UnLock().

+ Here is the call graph for this function:

◆ setKWT()

void XrdLinkCtl::setKWT ( int  wkSec,
int  kwSec 
)
static

Set kill constants.

Parameters
wkSecSeconds to wait for kill to happed,
kwSecThe minimum number of seconds to wait after killing a connection for it to end.

Definition at line 327 of file XrdLinkCtl.cc.

328 {
329  if (wkSec > 0) waitKill = static_cast<short>(wkSec);
330  if (kwSec > 0) killWait = static_cast<short>(kwSec);
331 }
static short waitKill
Definition: XrdLinkCtl.hh:191
static short killWait
Link destruction control constants.
Definition: XrdLinkCtl.hh:190

◆ Setup()

int XrdLinkCtl::Setup ( int  maxfds,
int  idlewt 
)
static

Setup link processing.

Parameters
maxfdsThe maximum number of connections to handle.
idlewtThe time interval to check for idle connections.
Returns
!0 Successful. =0 Setup failed.

Definition at line 337 of file XrdLinkCtl.cc.

338 {
339  maxFD = maxfds;
340  TRACE(DEBUG, "Allocating " <<LinkAlloc <<" link objects at a time");
341 
342 // Create the link table
343 //
344  if (!(LinkTab = (XrdLinkCtl **)malloc(maxfds*sizeof(XrdLinkCtl*)+LinkAlloc)))
345  {Log.Emsg("Link", ENOMEM, "create LinkTab"); return 0;}
346  memset((void *)LinkTab, 0, maxfds*sizeof(XrdLinkCtl *));
347 
348 // Create the slot status table
349 //
350  if (!(LinkBat = (char *)malloc(maxfds*sizeof(char)+LinkAlloc)))
351  {Log.Emsg("Link", ENOMEM, "create LinkBat"); return 0;}
352  memset((void *)LinkBat, XRDLINK_FREE, maxfds*sizeof(char));
353 
354 // Create an idle connection scan job
355 //
356  if (idlewait)
357  {if ((idleCheck = idlewait/3)) idleTicks = 3;
358  else {idleTicks = 1;
359  idleCheck = idlewait;
360  }
361  LinkScan *ls = new LinkScan;
362  Sched.Schedule((XrdJob *)ls, idleCheck+time(0));
363  }
364 
365 // All done
366 //
367  return 1;
368 }
#define DEBUG(x)
Definition: XrdBwmTrace.hh:54
Definition: XrdJob.hh:43
void Schedule(XrdJob *jp)
XrdScheduler Sched
Definition: XrdLinkCtl.cc:54

References DEBUG, XrdSysError::Emsg(), XrdGlobal::Log, XrdGlobal::Sched, XrdScheduler::Schedule(), and TRACE.

+ Here is the call graph for this function:

◆ SyncAll()

void XrdLinkCtl::SyncAll ( )
static

Synchronize statustics for ll links.

Definition at line 374 of file XrdLinkCtl.cc.

375 {
376  int myLTLast;
377 
378 // Get the current last entry
379 //
380  LTMutex.Lock(); myLTLast = LTLast; LTMutex.UnLock();
381 
382 // Run through all the links and sync the statistics
383 //
384  for (int i = 0; i <= myLTLast; i++)
385  {if (LinkBat[i] == XRDLINK_USED && LinkTab[i]) LinkTab[i]->syncStats();}
386 }
void syncStats(int *ctime=0)
Definition: XrdLinkXeq.cc:1090

Referenced by XrdLinkXeq::Stats().

+ Here is the caller graph for this function:

◆ Unhook()

void XrdLinkCtl::Unhook ( int  fd)
static

Unhook a link from the active table of links.

Definition at line 392 of file XrdLinkCtl.cc.

393 {
394 
395 // Indicate link no longer actvely neing used
396 //
397  LTMutex.Lock();
398  LinkBat[fd] = XRDLINK_FREE;
399  if (fd == LTLast) while(LTLast && !(LinkBat[LTLast])) LTLast--;
400  LTMutex.UnLock();
401 }

Referenced by XrdLinkXeq::Close().

+ Here is the caller graph for this function:

Member Data Documentation

◆ killWait

short XrdLinkCtl::killWait = 3
static

Link destruction control constants.

Definition at line 190 of file XrdLinkCtl.hh.

Referenced by XrdLink::Terminate().

◆ waitKill

short XrdLinkCtl::waitKill = 4
static

Definition at line 191 of file XrdLinkCtl.hh.

Referenced by XrdLink::Terminate().


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