30 #include <sys/types.h>
40 #define TRACELINK this
65 char *XrdLinkCtl::LinkBat = 0;
69 const unsigned int XrdLinkCtl::LinkAlloc = [] {
70 unsigned i = 8192 /
sizeof(
XrdLink);
72 while (i >>= 1) j <<= 1;
75 int XrdLinkCtl::LTLast = -1;
76 int XrdLinkCtl::maxFD = 0;
81 const char *XrdLinkCtl::TraceID =
"LinkCtl";
86 unsigned int myInstance = 1;
90 static const int XRDLINK_USED = 0x01;
91 static const int XRDLINK_FREE = 0x00;
93 class LinkScan :
public XrdJob
100 LinkScan() :
XrdJob(
"Idle link scan") {}
112 char hName[1024], *unp, buff[32];
113 int bl, peerFD = peer.
SockFD();
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);
128 snprintf(hName,
sizeof(hName),
"%d", peerFD);
129 Log.
Emsg(
"Link",
"attempt to reuse active link FD -",hName);
136 if (!(lp = LinkTab[peerFD]))
141 Log.
Emsg(
"Link", ENOMEM,
"create link");
144 blp = &LinkTab[peerFD/LinkAlloc*LinkAlloc];
145 for (i = 0; i < LinkAlloc; i++, blp++) *blp = &nlp[i];
146 lp = LinkTab[peerFD];
149 LinkBat[peerFD] = XRDLINK_USED;
150 if (peerFD > LTLast) LTLast = peerFD;
166 lp->
HNlen = strlen(hName);
170 bl = sprintf(buff,
"anon.0:%d", peerFD);
171 unp = lp->
Uname +
sizeof(Uname) - bl - 1;
172 memcpy(unp, buff, bl);
175 lp->
Comment = (
const char *)unp;
188 if (LinkCountMax <=
AtomicInc(LinkCount)) LinkCountMax = LinkCount;
205 const int MaxSeek = 16;
207 int i, seeklim = MaxSeek;
212 if (curr >= 0 && LinkTab[curr]) LinkTab[curr]->
setRef(-1);
219 for (i = curr+1; i <= LTLast; i++)
220 {
if ((lp = LinkTab[i]) && LinkBat[i] && lp->
HostName)
227 if (myINS == lp->
Instance)
return lp;
230 if (!seeklim--) {LTMutex.UnLock(); seeklim = MaxSeek; LTMutex.Lock();}
251 const int MaxSeek = 16;
252 int i, ulen = 0, seeklim = MaxSeek;
259 for (i = curr+1; i <= LTLast; i++)
260 {
if ((lp = LinkTab[i]) && LinkBat[i] && lp->
HostName)
263 {ulen = lp->
Client(nbuf, nbsz);
268 if (!seeklim--) {LTMutex.UnLock(); seeklim = MaxSeek; LTMutex.Lock();}
288 int i, ltlast, lnum = 0, tmo = 0, tmod = 0;
299 for (i = 0; i <= ltlast; i++)
300 {
if (LinkBat[i] != XRDLINK_USED
301 || !(lp = LinkTab[i]))
continue;
306 if ((
int(lp->
isIdle)) < idleTicks)
310 Log.
Emsg(
"LinkScan",
"Link",lp->
ID,
"is disabled and idle.");
320 TRACE(CONN, lnum <<
" links; " <<tmo <<
" idle; " <<tmod <<
" force closed");
329 if (wkSec > 0) waitKill =
static_cast<short>(wkSec);
330 if (kwSec > 0) killWait =
static_cast<short>(kwSec);
340 TRACE(
DEBUG,
"Allocating " <<LinkAlloc <<
" link objects at a time");
345 {
Log.
Emsg(
"Link", ENOMEM,
"create LinkTab");
return 0;}
346 memset((
void *)LinkTab, 0, maxfds*
sizeof(
XrdLinkCtl *));
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));
357 {
if ((idleCheck = idlewait/3)) idleTicks = 3;
359 idleCheck = idlewait;
361 LinkScan *ls =
new LinkScan;
380 LTMutex.Lock(); myLTLast = LTLast; LTMutex.UnLock();
384 for (
int i = 0; i <= myLTLast; i++)
385 {
if (LinkBat[i] == XRDLINK_USED && LinkTab[i]) LinkTab[i]->syncStats();}
398 LinkBat[fd] = XRDLINK_FREE;
399 if (fd == LTLast)
while(LTLast && !(LinkBat[LTLast])) LTLast--;
int DoIt(int argpnt, int argc, char **argv, bool singleshot)
static XrdLink * Alloc(XrdNetAddr &peer, int opts=0)
static void SyncAll()
Synchronize statustics for ll links.
static int Setup(int maxfds, int idlewt)
static XrdLink * Find(int &curr, XrdLinkMatch *who=0)
static void setKWT(int wkSec, int kwSec)
static void idleScan()
Look for idle links and close hem down.
static short killWait
Link destruction control constants.
static int getName(int &curr, char *bname, int blen, XrdLinkMatch *who=0)
static void Unhook(int fd)
Unhook a link from the active table of links.
int Match(const char *uname, int unlen, const char *hname, int hnlen)
int Client(char *buff, int blen)
char * ID
Pointer to the client's link identity.
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.
virtual void Disable(XrdPollInfo &pInfo, const char *etxt=0)=0
void Schedule(XrdJob *jp)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)