#ifndef __XRD_LINK_H__
#define __XRD_LINK_H__
/******************************************************************************/
/* */
/* X r d L i n k . h h */
/* */
/* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include
#include
#include
#include "XrdNet/XrdNetAddr.hh"
#include "XrdOuc/XrdOucSFVec.hh"
#include "XrdSys/XrdSysPthread.hh"
#include "Xrd/XrdJob.hh"
#include "Xrd/XrdLinkMatch.hh"
#include "Xrd/XrdProtocol.hh"
/******************************************************************************/
/* X r d L i n k O p t i o n s */
/******************************************************************************/
#define XRDLINK_RDLOCK 0x0001
#define XRDLINK_NOCLOSE 0x0002
/******************************************************************************/
/* C l a s s D e f i n i t i o n */
/******************************************************************************/
class XrdInet;
class XrdNetAddr;
class XrdPoll;
class XrdOucTrace;
class XrdScheduler;
class XrdSendQ;
class XrdSysError;
class XrdLink : XrdJob
{
public:
friend class XrdLinkScan;
friend class XrdPoll;
friend class XrdPollPoll;
friend class XrdPollDev;
friend class XrdPollE;
//-----------------------------------------------------------------------------
//! Obtain the address information for this link.
//!
//! @return Pointer to the XrdAddrInfo object. The pointer is valid while the
//! end-point is connected.
//-----------------------------------------------------------------------------
inline
XrdNetAddrInfo *AddrInfo() {return (XrdNetAddrInfo *)&Addr;}
//-----------------------------------------------------------------------------
//! Allocate a new link object.
//!
//! @param peer The connection information for the endpoint.
//! @param opts Processing options:
//! XRDLINK_NOCLOSE - do not close the FD upon recycling.
//! XRDLINK_RDLOCK - obtain a lock prior to reading data.
//!
//! @return !0 The pointer to the new object.
//! =0 A new link object could not be allocated.
//-----------------------------------------------------------------------------
static XrdLink *Alloc(XrdNetAddr &peer, int opts=0);
int Backlog();
void Bind() {} // Obsolete
void Bind(pthread_t tid) { (void)tid; } // Obsolete
int Client(char *buff, int blen);
int Close(int defer=0);
void DoIt();
void Enable();
int FDnum() {int fd = FD; return (fd < 0 ? -fd : fd);}
static XrdLink *fd2link(int fd)
{if (fd < 0) fd = -fd;
return (fd <= LTLast && LinkBat[fd] ? LinkTab[fd] : 0);
}
static XrdLink *fd2link(int fd, unsigned int inst)
{if (fd < 0) fd = -fd;
if (fd <= LTLast && LinkBat[fd] && LinkTab[fd]
&& LinkTab[fd]->Instance == inst) return LinkTab[fd];
return (XrdLink *)0;
}
static XrdLink *Find(int &curr, XrdLinkMatch *who=0);
int getIOStats(long long &inbytes, long long &outbytes,
int &numstall, int &numtardy)
{ inbytes = BytesIn + BytesInTot;
outbytes = BytesOut+BytesOutTot;
numstall = stallCnt + stallCntTot;
numtardy = tardyCnt + tardyCntTot;
return InUse;
}
static int getName(int &curr, char *bname, int blen, XrdLinkMatch *who=0);
XrdProtocol *getProtocol() {return Protocol;} // opmutex must be locked
void Hold(int lk) {(lk ? opMutex.Lock() : opMutex.UnLock());}
//-----------------------------------------------------------------------------
//! Get the fully qualified name of the endpoint.
//!
//! @return Pointer to fully qualified host name. The contents are valid
//! while the endpoint is connected.
//-----------------------------------------------------------------------------
const char *Host() {return (const char *)HostName;}
char *ID; // This is referenced a lot
static void Init(XrdSysError *eP, XrdOucTrace *tP, XrdScheduler *sP)
{XrdLog = eP; XrdTrace = tP; XrdSched = sP;}
static void Init(XrdInet *iP) {XrdNetTCP = iP;}
//-----------------------------------------------------------------------------
//! Obtain the link's instance number.
//!
//! @return The link's instance number.
//-----------------------------------------------------------------------------
inline
unsigned int Inst() {return Instance;}
//-----------------------------------------------------------------------------
//! Indicate whether or not the link has an outstanding error.
//!
//! @return True the link has an outstanding error.
//! the link has no outstanding error.
//-----------------------------------------------------------------------------
inline
bool isFlawed() {return Etext != 0;}
//-----------------------------------------------------------------------------
//! Indicate whether or not this link is of a particular instance.
//! only be used for display and not for security purposes.
//!
//! @param inst the expected instance number.
//!
//! @return True the link matches the instance number.
//! the link differs the instance number.
//-----------------------------------------------------------------------------
inline
bool isInstance(unsigned int inst)
{return FD >= 0 && Instance == inst;}
//-----------------------------------------------------------------------------
//! Obtain the domain trimmed name of the end-point. The returned value should
//! only be used for display and not for security purposes.
//!
//! @return Pointer to the name that remains valid during the link's lifetime.
//-----------------------------------------------------------------------------
inline
const char *Name() {return (const char *)Lname;}
//-----------------------------------------------------------------------------
//! Obtain the network address object for this link. The returned value is
//! valid as long as the end-point is connected. Otherwise, it may change.
//!
//! @return Pointer to the object and remains valid during the link's lifetime.
//-----------------------------------------------------------------------------
inline const
XrdNetAddr *NetAddr() {return &Addr;}
int Peek(char *buff, int blen, int timeout=-1);
int Recv(char *buff, int blen);
int Recv(char *buff, int blen, int timeout);
int RecvAll(char *buff, int blen, int timeout=-1);
int Send(const char *buff, int blen);
int Send(const struct iovec *iov, int iocnt, int bytes=0);
static int sfOK; // True if Send(sfVec) enabled
typedef XrdOucSFVec sfVec;
int Send(const sfVec *sdP, int sdn); // Iff sfOK > 0
void Serialize(); // ASYNC Mode
int setEtext(const char *text);
void setID(const char *userid, int procid);
static void setKWT(int wkSec, int kwSec);
void setLocation(XrdNetAddrInfo::LocInfo &loc) {Addr.SetLocation(loc);}
bool setNB();
XrdProtocol *setProtocol(XrdProtocol *pp);
void setRef(int cnt); // ASYNC Mode
static int Setup(int maxfd, int idlewait);
void Shutdown(bool getLock);
static int Stats(char *buff, int blen, int do_sync=0);
void syncStats(int *ctime=0);
int Terminate(const XrdLink *owner, int fdnum, unsigned int inst);
time_t timeCon() {return conTime;}
int UseCnt() {return InUse;}
void armBridge() {isBridged = 1;}
int hasBridge() {return isBridged;}
XrdLink();
~XrdLink() {} // Is never deleted!
private:
void Reset();
int sendData(const char *Buff, int Blen);
static XrdSysError *XrdLog;
static XrdOucTrace *XrdTrace;
static XrdScheduler *XrdSched;
static XrdInet *XrdNetTCP;
static XrdSysMutex LTMutex; // For the LinkTab only LTMutex->IOMutex allowed
static XrdLink **LinkTab;
static char *LinkBat;
static unsigned int LinkAlloc;
static int LTLast;
static const char *TraceID;
static int devNull;
static short killWait;
static short waitKill;
// Statistical area (global and local)
//
static long long LinkBytesIn;
static long long LinkBytesOut;
static long long LinkConTime;
static long long LinkCountTot;
static int LinkCount;
static int LinkCountMax;
static int LinkTimeOuts;
static int LinkStalls;
static int LinkSfIntr;
static int maxFD;
long long BytesIn;
long long BytesInTot;
long long BytesOut;
long long BytesOutTot;
int stallCnt;
int stallCntTot;
int tardyCnt;
int tardyCntTot;
int SfIntr;
static XrdSysMutex statsMutex;
// Identification section
//
XrdNetAddr Addr;
char Uname[24]; // Uname and Lname must be adjacent!
char Lname[232];
char *HostName;
int HNlen;
#if defined( __linux__ ) || defined( __solaris__ )
pthread_t TID; // Hack to keep abi compatability
#else
XrdLink *Next; // Only used by PollPoll.icc
#endif
XrdSysMutex opMutex;
XrdSysMutex rdMutex;
XrdSysMutex wrMutex;
XrdSysSemaphore IOSemaphore;
XrdSysCondVar *KillcvP; // Protected by opMutex!
XrdSendQ *sendQ; // Protected by wrMutex && opMutex
XrdProtocol *Protocol;
XrdProtocol *ProtoAlt;
XrdPoll *Poller;
struct pollfd *PollEnt;
char *Etext;
int FD;
unsigned int Instance;
time_t conTime;
int InUse;
int doPost;
char LockReads;
char KeepFD;
char isEnabled;
char isIdle;
char inQ; // Only used by PollPoll.icc
char isBridged;
char KillCnt; // Protected by opMutex!
static const char KillMax = 60;
static const char KillMsk = 0x7f;
static const char KillXwt = 0x80;
};
#endif