32#include "XrdVersion.hh"
183 XrdXrootdProtocol::ProtStack(
"ProtStack",
184 "xroot protocol anchor");
203 const char *txt =
"completed.";
207 pi->
eDest->
Say(
"Copr. 2012 Stanford University, xroot protocol "
209 pi->
eDest->
Say(
"++++++ xroot protocol initialization started.");
215 else txt =
"failed.";
216 pi->
eDest->
Say(
"------ xroot protocol initialization ", txt);
240 if (pi->
Port < 0)
return 1094;
274 static unsigned int Sid = 1;
297static struct hs_response
312 {
if (dlen <= 0) lp->
setEtext(
"handshake not received");
330 rc = lp->
Send((
char *)&hsresp,
sizeof(hsresp));
341 if (lp->
Recv(hsbuff, hsSZ) != hsSZ)
366#define TRACELINK Link
377 else if ((rc = (*this.*
Resume)()) != 0)
return rc;
378 else {
Resume = 0;
return 0;}
387 reqID = ntohs(
Request.header.requestid);
395 Request.header.requestid = reqID;
399 <<
" dlen=" <<
Request.header.dlen);
444 {
const char *eText =
"Request not signed";
448 <<
" verification failed; " <<eText);
458 <<
" unneeded signature discarded.");
460 {
eDest.
Emsg(
"Protocol",
"Client is needlessly signing requests.");
476 "Invalid request; user not logged in");
526 "Invalid request; user not authenticated");
564 {doRdr =
true;
break;}
594 case kXR_mv:
return do_Mv();
597 case kXR_rm:
return do_Rm();
659#define TRACELINK Link
676 if (reason && strcmp(reason,
"hangup"))
677 {snprintf(buff,
sizeof(buff),
"%s (%s)", ctbuff, reason);
679 }
else sfxp = ctbuff;
747int XrdXrootdProtocol::StatGen(
struct stat &buf,
char *xxBuff,
int xxLen,
750 const mode_t isReadable = (S_IRUSR | S_IRGRP | S_IROTH);
751 const mode_t isWritable = (S_IWUSR | S_IWGRP | S_IWOTH);
752 const mode_t isExecable = (S_IXUSR | S_IXGRP | S_IXOTH);
755 union {
long long uuid;
struct {
int hi;
int lo;} id;} Dev;
766 Dev.id.lo = buf.st_ino;
767 Dev.id.hi = buf.st_dev;
771 if (buf.st_mode & isReadable
772 &&((buf.st_mode & S_IRUSR && theuid == buf.st_uid)
773 || (buf.st_mode & S_IRGRP && thegid == buf.st_gid)
778 if (buf.st_mode & isWritable
779 &&((buf.st_mode & S_IWUSR && theuid == buf.st_uid)
780 || (buf.st_mode & S_IWGRP && thegid == buf.st_gid)
785 if (buf.st_mode & isExecable
786 &&((buf.st_mode & S_IXUSR && theuid == buf.st_uid)
787 || (buf.st_mode & S_IXGRP && thegid == buf.st_gid)
788 || buf.st_mode & S_IXOTH)) flags |=
kXR_xset;
793 if (S_ISDIR(buf.st_mode)) flags |=
kXR_isDir;
794 else if (!S_ISREG(buf.st_mode)) flags |=
kXR_other;
796 if ((buf.st_rdev & XRDSFS_RDVMASK) == 0)
797 {
if (buf.st_rdev & XRDSFS_OFFLINE) flags |=
kXR_offline;
798 if (buf.st_rdev & XRDSFS_HASBKUP) flags |=
kXR_bkpexist;
801 if ((
fsFeatures & XrdSfs::hasCACH) != 0 && buf.st_atime != 0)
803 fsz =
static_cast<long long>(buf.st_size);
807 m = snprintf(xxBuff, xxLen,
"%lld %lld %d %lld",
808 Dev.uuid, fsz, flags, (
long long) buf.st_mtime);
814 char *origP = xxBuff;
815 char *nullP = xxBuff + m++;
816 xxBuff += m; xxLen -= m;
817 n = snprintf(xxBuff, xxLen,
"%lld %lld %04o ",
818 (
long long) buf.st_ctime, (
long long) buf.st_atime,
820 if (n >= xxLen)
return m;
821 xxBuff += n; xxLen -= n;
825 if (buf.st_uid ==
myUID)
826 {
if (
myUNLen >= xxLen)
return m;
838 if (buf.st_gid ==
myGID)
839 {
if (
myGNLen >= xxLen)
return m;
850 return xxBuff - origP;
885 return SI->
Stats(buff, blen, do_sync);
900 {
if (bsz) *bsz = xbP->
bsize;
959 else if (buff !=
argp->
buff) errno = EINVAL;
965 if (
argp)
return oldBP;
1010int XrdXrootdProtocol::CheckSum(
XrdOucStream *Stream,
char **argv,
int argc)
1017 {
Stream->PutLine(
"Internal error; not enough checksum args!");
1024 XrdOucErrInfo myInfo(argv[3], &myEnv);
1028 if (argc > 4 && *argv[4]) myEnv.
Put(
"request.name", argv[4]);
1038 if (ecode) rc = ecode;
1047void XrdXrootdProtocol::Cleanup()
1066 {
Stream[i]->Stream[0] = 0;
1067 const bool doCl =
Stream[i]->RequestClose();
1069 Stream[i]->boundRecycle->Wait();
1070 Stream[i]->Recycle(0, 0, 0);
1147 {
if (rlen != -ENOMSG)
return Link->
setEtext(
"link read error");
1152 TRACEP(REQ, dtype <<
" timeout; read " <<rlen <<
" of " <<blen <<
" bytes");
1161 const char *dtype,
char *buff,
int blen)
1168 gdCtl.BuffLen = blen;
1169 gdCtl.Buffer = buff;
1170 gdCtl.CallBack= cbP;
1171 gdCtl.ioDType = dtype;
1178 {
gdCtl.useCB =
true;
1181 return getDataCont();
1185namespace {
int consumed = 0;}
1188 const char *dtype,
struct iovec *
iov,
int iovn)
1195 gdCtl.iovNum = iovn;
1197 gdCtl.CallBack= cbP;
1198 gdCtl.ioDType = dtype;
1205 {
gdCtl.useCB =
true;
1209 return getDataIovCont();
1216int XrdXrootdProtocol::getDataCont()
1223 return -EINPROGRESS;
1229 gdCtl.Buffer += rlen;
1230 gdCtl.BuffLen -= rlen;
1240 rlen =
gdCtl.CallBack->gdDone();
1241 if (rlen < 0)
break;
1254 if (
gdCtl.BuffLen < 0)
1255 {rlen =
Link->
setEtext(
"link excessive read length error");
1263 Resume = &XrdXrootdProtocol::getDataCont;
1271 TRACEP(REQ,
gdCtl.ioDType <<
" timeout; read " <<rlen <<
" bytes "
1272 <<
gdCtl.BuffLen <<
" remaining");
1279 if (rlen != -ENOMSG)
return Link->
setEtext(
"link read error");
1285 gdCtl.CallBack->gdFail();
1295int XrdXrootdProtocol::getDataIovCont()
1302 return -EINPROGRESS;
1307do{
struct iovec *ioV =
gdCtl.iovVec;
1308 int i, rlen, iovN =
gdCtl.iovNum, iNow =
gdCtl.iovNow;
1315 {
if (rlen != -ENOMSG)
Link->
setEtext(
"link read error");
1317 {ioV[iNow].iov_base = ((
char *)ioV[iNow].iov_base) -
gdCtl.iovAdj;
1318 ioV[iNow].iov_len +=
gdCtl.iovAdj;
1327 for (i = iNow; i < iovN && (int)ioV[i].iov_len <= rlen; i++)
1328 rlen -= ioV[i].iov_len;
1332 if (i != iNow &&
gdCtl.iovAdj)
1333 {ioV[iNow].iov_base = ((
char *)ioV[iNow].iov_base) -
gdCtl.iovAdj;
1334 ioV[iNow].iov_len +=
gdCtl.iovAdj;
1348 rc =
gdCtl.CallBack->gdDone();
1368 gdCtl.iovAdj += rlen;
1369 ioV[i].iov_base = ((
char *)ioV[i].iov_base) + rlen;
1370 ioV[i].iov_len -= rlen;
1376 Resume = &XrdXrootdProtocol::getDataIovCont;
1384 TRACEP(REQ,
gdCtl.ioDType<<
" read timeout; "<<iovN-i<<
" of "
1385 <<
gdCtl.iovNum <<
" iov elements left");
1394 gdCtl.CallBack->gdFail();
1411 gdCtl.DumpLen = dlen;
1412 gdCtl.ioDType = dtype;
1418 return (inCB ? 1 : getDumpCont());
1425int XrdXrootdProtocol::getDumpCont()
1427 int rlen = 0, rwant;
1434 while(
gdCtl.DumpLen > 0)
1435 {
if (
gdCtl.DumpLen <= (
int)
sizeof(buff)) rwant =
gdCtl.DumpLen;
1436 else rwant =
sizeof(buff);
1438 gdCtl.DumpLen -= rlen;
1443 if (rlen < 0 ||
gdCtl.DumpLen < 0)
1445 else if (rlen != -ENOMSG)
Link->
setEtext(
"link read error");
1452 if (
gdCtl.DumpLen == 0)
1459 Resume = &XrdXrootdProtocol::getDumpCont;
1463 <<
" bytes left to discard");
1471void XrdXrootdProtocol::Reset()
1485 memset(&
IO, 0,
sizeof(
IO));
XrdVERSIONINFO(XrdClGetPlugIn, XrdClGetPlugIn) extern "C"
struct ClientRequestHdr header
struct ClientRequestHdr header
#define kXR_PROTOCOLVSTRING
#define kXR_PROTOCOLVERSION
XrdProtocol * XrdgetProtocol(const char *pname, char *parms, XrdProtocol_Config *pi)
int XrdgetProtocolPort(const char *pname, char *parms, XrdProtocol_Config *pi)
#define NEED2SECURE(protP)
This class implements the XRootD protocol security protection.
class XrdBuffer * XrdSfsXioHandle
XrdSys::RAtomic< int > RAtomic_int
XrdSysTrace XrdXrootdTrace
const kXR_char XROOTD_MON_BOUNDP
const kXR_char XROOTD_MON_FORCED
static const char * reqName(kXR_unt16 reqCode)
void Release(XrdBuffer *bp)
XrdBuffer * Obtain(int bsz)
int setEtext(const char *text)
int Peek(char *buff, int blen, int timeout=-1)
int Recv(char *buff, int blen)
XrdNetAddrInfo * AddrInfo()
char * ID
Pointer to the client's link identity.
int Send(const char *buff, int blen)
const char * Host() const
static bool InDomain(XrdNetAddrInfo *epaddr)
void Put(const char *varname, const char *value)
int PutLine(const char *data, int dlen=0)
static int GidName(gid_t gID, char *gName, int gNsz, time_t keepT=0)
static int UidName(uid_t uID, char *uName, int uNsz, time_t keepT=0)
XrdProtocol(const char *jname)
XrdNetAddrInfo * addrInfo
Entity's connection details.
char prot[XrdSecPROTOIDSIZE]
Auth protocol used (e.g. krb5).
gid_t gid
Unix gid or 0 if none.
void Reset(const char *spV=0)
uid_t uid
Unix uid or 0 if none.
char * moninfo
Information for monitoring.
char * host
Entity's host name dnr dependent.
virtual const char * Verify(SecurityRequest &secreq, ClientRequest &thereq, const char *thedata)
virtual void Delete()
Delete this object. Use this method as opposed to operator delete.
virtual void Delete()=0
Delete the protocol object. DO NOT use C++ delete() on this object.
virtual void Disc(const XrdSecEntity *client=0)
virtual int chksum(csFunc Func, const char *csName, const char *path, XrdOucErrInfo &eInfo, const XrdSecEntity *client=0, const char *opaque=0)
XrdSfsXio(XrdSfsXioImpl &xioimpl)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
void Log(int mask, const char *esfx, const char *text1, const char *text2=0, const char *text3=0)
static char * s2hms(int sec, char *buff, int blen)
static void ClearErrorQueue()
Clear the SSL error queue for the calling thread.
void Recycle(XrdXrootdMonitor *monP)
static void Disc(unsigned int usrID)
void Disc(kXR_unt32 dictid, int csec, char Flags=0)
static XrdXrootdStats * SI
static const char * myInst
XrdXrootdProtocol * VerifyStream(int &rc, int pID, bool lok=true)
static XrdSfsFileSystem * digFS
int(XrdXrootdProtocol::*) Resume()
XrdNetPMark::Handle * pmHandle
static XrdNetPMark * PMark
XrdXrootdProtocol * Stream[maxStreams]
static short as_okstutter
static XrdXrootdXPath RPList
static XrdNetSocket * AdminSock
XrdProtocol * Match(XrdLink *lp) override
int(XrdXrootdProtocol::*) ResumePio()
struct XrdXrootdProtocol::GetDataCtl gdCtl
static bool CloseRequestCb(void *cbarg)
static void Reclaim(XrdSfsXioHandle h)
XrdXrootdFileTable * FTab
static XrdXrootdJob * JobCKS
static XrdSysError & eDest
static unsigned int getSID()
XrdSecProtocol * AuthProt
int getData(gdCallBack *gdcbP, const char *dtype, char *buff, int blen)
XrdSfsXioHandle Claim(const char *buff, int datasz, int minasz=0) override
XrdXrootdMonitor::User Monitor
static XrdXrootdRedirPI * RedirPI
static const char * myCName
XrdSfsXioHandle Swap(const char *buff, XrdSfsXioHandle h=0) override
static XrdXrootdFileLock * Locker
static XrdTlsContext * tlsCtx
static XrdXrootdXPath XPList
static XrdScheduler * Sched
static struct XrdXrootdProtocol::RC_Table RouteClient
int Process(XrdLink *lp) override
void Recycle(XrdLink *lp, int consec, const char *reason) override
static char * Buffer(XrdSfsXioHandle h, int *bsz)
static const char * myUName
XrdXrootdResponse Response
static const char * TraceID
static int Configure(char *parms, XrdProtocol_Config *pi)
int Stats(char *buff, int blen, int do_sync=0) override
static const int maxStreams
int getDump(const char *dtype, int dlen)
static XrdOucTList * JobCKTLST
static XrdXrootdXPath RQList
static struct XrdXrootdProtocol::RD_Table Route[RD_Num]
static XrdSecProtector * DHS
static XrdBuffManager * BPool
XrdSysSemaphore * boundRecycle
static XrdSecService * CIA
static RAtomic_int srvrAioOps
static const char * myGName
static uint64_t fsFeatures
static XrdOucReqID * PrepID
static XrdSfsFileSystem * osFS
void setID(unsigned long long id)
int Stats(char *buff, int blen, int do_sync=0)
XrdXrootd::gdCallBack * CallBack
static const int Terminate
static const int inCallBk
static const int inDataIov