XRootD
Loading...
Searching...
No Matches
XrdXrootdProtocol.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d X r o o t d P r o t o c o l . c c */
4/* */
5/* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* Produced by Andrew Hanushevsky for Stanford University under contract */
7/* DE-AC02-76-SFO0515 with the Department of Energy */
8/* */
9/* This file is part of the XRootD software suite. */
10/* */
11/* XRootD is free software: you can redistribute it and/or modify it under */
12/* the terms of the GNU Lesser General Public License as published by the */
13/* Free Software Foundation, either version 3 of the License, or (at your */
14/* option) any later version. */
15/* */
16/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19/* License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24/* */
25/* The copyright holder's institutional names and contributor's names may not */
26/* be used to endorse or promote products derived from this software without */
27/* specific prior written permission of the institution or contributor. */
28/******************************************************************************/
29
30#include <poll.h>
31
32#include "XrdVersion.hh"
33
35
36#include "Xrd/XrdBuffer.hh"
37#include "Xrd/XrdLink.hh"
38#include "XrdNet/XrdNetIF.hh"
39#include "XrdOuc/XrdOucEnv.hh"
40#include "XrdOuc/XrdOucUtils.hh"
43#include "XrdOuc/XrdOucUtils.hh"
45#include "XrdSfs/XrdSfsFlags.hh"
48#include "XrdSys/XrdSysTimer.hh"
49#include "XrdTls/XrdTls.hh"
61
62/******************************************************************************/
63/* G l o b a l s */
64/******************************************************************************/
65
66namespace XrdXrootd
67{
68XrdSysError eLog(0, "Xrootd");
72}
73
75
76/******************************************************************************/
77/* S t a t i c M e m b e r s */
78/******************************************************************************/
79
99
101const char *XrdXrootdProtocol::myCName= 0;
112
113int XrdXrootdProtocol::hcMax = 28657; // const for now
115int XrdXrootdProtocol::maxTransz = 262144; // 256KB
118int XrdXrootdProtocol::as_maxperlnk = 8; // Max ops per link
119int XrdXrootdProtocol::as_maxperreq = 8; // Max ops per request
120int XrdXrootdProtocol::as_maxpersrv = 4096;// Max ops per server
124#ifdef __solaris__
126#else
128#endif
130short XrdXrootdProtocol::as_okstutter = 1; // For 64K unit
132bool XrdXrootdProtocol::as_force = false;
134bool XrdXrootdProtocol::as_nosf = false;
135bool XrdXrootdProtocol::as_syncw = false;
136
137const char *XrdXrootdProtocol::myInst = 0;
138const char *XrdXrootdProtocol::TraceID = "Protocol";
140int XrdXrootdProtocol::myPID = static_cast<int>(getpid());
141
144
149const char *XrdXrootdProtocol::myGName= "?";
150const char *XrdXrootdProtocol::myUName= "?";
151time_t XrdXrootdProtocol::keepT = 86400; // 24 hours
152
156
161bool XrdXrootdProtocol::OD_Redir = false;
162
163bool XrdXrootdProtocol::CL_Redir = false;
164
165bool XrdXrootdProtocol::isProxy = false;
166
170
173
175
176/******************************************************************************/
177/* P r o t o c o l M a n a g e m e n t S t a c k s */
178/******************************************************************************/
179
181 XrdXrootdProtocol::ProtStack("ProtStack",
182 "xroot protocol anchor");
183
184/******************************************************************************/
185/* P r o t o c o l L o a d e r */
186/* X r d g e t P r o t o c o l */
187/******************************************************************************/
188
189// This protocol can live in a shared library. The interface below is used by
190// the protocol driver to obtain a copy of the protocol object that can be used
191// to decide whether or not a link is talking a particular protocol.
192//
194
195extern "C"
196{
197XrdProtocol *XrdgetProtocol(const char *pname, char *parms,
199{
200 XrdProtocol *pp = 0;
201 const char *txt = "completed.";
202
203// Put up the banner
204//
205 pi->eDest->Say("Copr. 2012 Stanford University, xroot protocol "
206 kXR_PROTOCOLVSTRING, " version ", XrdVERSION);
207 pi->eDest->Say("++++++ xroot protocol initialization started.");
208
209// Return the protocol object to be used if static init succeeds
210//
211 if (XrdXrootdProtocol::Configure(parms, pi))
212 pp = (XrdProtocol *)new XrdXrootdProtocol();
213 else txt = "failed.";
214 pi->eDest->Say("------ xroot protocol initialization ", txt);
215 return pp;
216}
217}
218
219/******************************************************************************/
220/* P r o t o c o l P o r t D e t e r m i n a t i o n */
221/* X r d g e t P r o t o c o l P o r t */
222/******************************************************************************/
223
224// This function is called early on to determine the port we need to use. The
225// default is ostensibly 1094 but can be overridden; which we allow.
226//
228
229extern "C"
230{
231int XrdgetProtocolPort(const char *pname, char *parms, XrdProtocol_Config *pi)
232{
233
234// Figure out what port number we should return. In practice only one port
235// number is allowed. However, we could potentially have a clustered port
236// and several unclustered ports. So, we let this practicality slide.
237//
238 if (pi->Port < 0) return 1094;
239 return pi->Port;
240}
241}
242
243/******************************************************************************/
244/* X r d P r o t o c o l X r o o t d C l a s s */
245/******************************************************************************/
246
247namespace
248{
251}
252
253/******************************************************************************/
254/* C o n s t r u c t o r */
255/******************************************************************************/
256
258 : XrdProtocol("xroot protocol handler"),
259 XrdSfsXio(SfsXioImpl),
260 ProtLink(this), Entity(0), AppName(0)
261{
262 Reset();
263}
264
265/******************************************************************************/
266/* protected: g e t S I D */
267/******************************************************************************/
268
270{
271 static XrdSysMutex SidMutex;
272 static unsigned int Sid = 1;
273 unsigned int theSid;
274
275// Generate unqiue number for this server instance
276//
277 AtomicBeg(SidMutex);
278 theSid = AtomicInc(Sid);
279 AtomicEnd(SidMutex);
280 return theSid;
281}
282
283/******************************************************************************/
284/* M a t c h */
285/******************************************************************************/
286
287#define TRACELINK lp
288
290{
291static const int hsSZ = sizeof(ClientInitHandShake);
292 char hsbuff[hsSZ];
293 struct ClientInitHandShake *hsData = (ClientInitHandShake *)hsbuff;
294
295static struct hs_response
296 {kXR_unt16 streamid;
297 kXR_unt16 status;
298 kXR_unt32 rlen; // Specified as kXR_int32 in doc!
299 kXR_unt32 pval; // Specified as kXR_int32 in doc!
300 kXR_unt32 styp; // Specified as kXR_int32 in doc!
301 } hsresp={0, 0, htonl(8), htonl(kXR_PROTOCOLVERSION),
302 (isRedir ? htonl((unsigned int)kXR_LBalServer)
303 : htonl((unsigned int)kXR_DataServer))};
305int dlen, rc;
306
307// Peek at the first 20 bytes of data
308//
309 if ((dlen = lp->Peek(hsbuff, hsSZ, hailWait)) < hsSZ)
310 {if (dlen <= 0) lp->setEtext("handshake not received");
311 return (XrdProtocol *)0;
312 }
313
314// Trace the data
315//
316// TRACEI(REQ, "received: " <<Trace->bin2hex(hsbuff,dlen));
317
318// Verify that this is our protocol
319//
320 hsData->fourth = ntohl(hsData->fourth);
321 hsData->fifth = ntohl(hsData->fifth);
322 if (hsData->first || hsData->second || hsData->third
323 || hsData->fourth != 4 || hsData->fifth != ROOTD_PQ) return 0;
324
325// Send the handshake response. We used optimize the subsequent protocol
326// request sent with handshake but the protocol request is now overloaded.
327//
328 rc = lp->Send((char *)&hsresp, sizeof(hsresp));
329
330// Verify that our handshake response was actually sent
331//
332 if (!rc)
333 {lp->setEtext("handshake failed");
334 return (XrdProtocol *)0;
335 }
336
337// We can now read all 20 bytes and discard them (no need to wait for it)
338//
339 if (lp->Recv(hsbuff, hsSZ) != hsSZ)
340 {lp->setEtext("reread failed");
341 return (XrdProtocol *)0;
342 }
343
344// Get a protocol object off the stack (if none, allocate a new one)
345//
346 if (!(xp = ProtStack.Pop())) xp = new XrdXrootdProtocol();
347
348// Bind the protocol to the link and return the protocol
349//
350 SI->Bump(SI->Count);
351 xp->Link = lp;
352 xp->Response.Set(lp);
353 strcpy(xp->Entity.prot, "host");
354 xp->Entity.host = (char *)lp->Host();
355 xp->Entity.addrInfo = lp->AddrInfo();
356 return (XrdProtocol *)xp;
357}
358
359/******************************************************************************/
360/* P r o c e s s */
361/******************************************************************************/
362
363#undef TRACELINK
364#define TRACELINK Link
365
366int XrdXrootdProtocol::Process(XrdLink *lp) // We ignore the argument here
367{
368 int rc;
369 kXR_unt16 reqID;
370
371// Check if we are servicing a slow link
372//
373 if (Resume)
374 {if (myBlen && (rc = getData("data", myBuff, myBlen)) != 0) return rc;
375 else if ((rc = (*this.*Resume)()) != 0) return rc;
376 else {Resume = 0; return 0;}
377 }
378
379// Read the next request header
380//
381 if ((rc=getData("request",(char *)&Request,sizeof(Request))) != 0) return rc;
382
383// Check if we need to copy the request prior to unmarshalling it
384//
385 reqID = ntohs(Request.header.requestid);
386 if (reqID != kXR_sigver && NEED2SECURE(Protect)(Request))
387 {memcpy(&sigReq2Ver, &Request, sizeof(ClientRequest));
388 sigNeed = true;
389 }
390
391// Deserialize the data
392//
393 Request.header.requestid = reqID;
396 TRACEP(REQ, "req=" <<XProtocol::reqName(reqID)
397 <<" dlen=" <<Request.header.dlen);
398
399// Every request has an associated data length. It better be >= 0 or we won't
400// be able to know how much data to read.
401//
402 if (Request.header.dlen < 0)
403 {Response.Send(kXR_ArgInvalid, "Invalid request data length");
404 return Link->setEtext("protocol data length error");
405 }
406
407// Process sigver requests now as they appear ahead of a request
408//
409 if (reqID == kXR_sigver) return ProcSig();
410
411// Read any argument data at this point, except when the request is a write.
412// The argument may have to be segmented and we're not prepared to do that here.
413//
414 if (reqID != kXR_write && reqID != kXR_pgwrite && Request.header.dlen)
415 {if (!argp || Request.header.dlen+1 > argp->bsize)
416 {if (argp) BPool->Release(argp);
417 if (!(argp = BPool->Obtain(Request.header.dlen+1)))
418 {Response.Send(kXR_ArgTooLong, "Request argument is too long");
419 return 0;
420 }
421 hcNow = hcPrev; halfBSize = argp->bsize >> 1;
422 }
423 argp->buff[Request.header.dlen] = '\0';
424 if ((rc = getData("arg", argp->buff, Request.header.dlen)))
425 {Resume = &XrdXrootdProtocol::Process2; return rc;}
426 }
427
428// Continue with request processing at the resume point
429//
430 return Process2();
431}
432
433/******************************************************************************/
434/* p r i v a t e P r o c e s s 2 */
435/******************************************************************************/
436
438{
439// If we are verifying requests, see if this request needs to be verified
440//
441 if (sigNeed)
442 {const char *eText = "Request not signed";
443 if (!sigHere || (eText = Protect->Verify(sigReq,sigReq2Ver,argp->buff)))
444 {Response.Send(kXR_SigVerErr, eText);
446 <<" verification failed; " <<eText);
447 SI->Bump(SI->badSCnt);
448 return Link->setEtext(eText);
449 } else {
450 SI->Bump(SI->aokSCnt);
451 sigNeed = sigHere = false;
452 }
453 } else {
454 if (sigHere)
456 <<" unneeded signature discarded.");
457 if (sigWarn)
458 {eDest.Emsg("Protocol","Client is needlessly signing requests.");
459 sigWarn = false;
460 }
461 SI->Bump(SI->ignSCnt);
462 sigHere = false;
463 }
464 }
465
466// If the user is not yet logged in, restrict what the user can do
467//
468 if (!Status)
469 switch(Request.header.requestid)
470 {case kXR_login: return do_Login();
471 case kXR_protocol: return do_Protocol();
472 case kXR_bind: return do_Bind();
474 "Invalid request; user not logged in");
475 return Link->setEtext("request without login");
476 }
477
478// Help the compiler, select the the high activity requests (the ones with
479// file handles) in a separate switch statement. A special case exists for
480// sync() which return with a callback, so handle it here. Note that stat(fh)
481// normally never does a callback but historically we allowed it to do so.
482// We maintain that capability even when it's likely never used.
483//
484 switch(Request.header.requestid) // First, the ones with file handles
485 {case kXR_read: return do_Read();
486 case kXR_readv: return do_ReadV();
487 case kXR_write: return do_Write();
488 case kXR_writev: return do_WriteV();
489 case kXR_pgread: return do_PgRead();
490 case kXR_pgwrite: return do_PgWrite();
492 return do_Sync();
494 return do_Close();
495 case kXR_stat: if (!Request.header.dlen)
497 return do_Stat();
498 }
499 break;
501 if (!Request.header.dlen) return do_Truncate();
502 break;
503 case kXR_query: if (!Request.header.dlen) return do_Qfh();
504 break;
505 case kXR_chkpoint: return do_ChkPnt();
506 default: break;
507 }
508
509// Now select the requests that do not need authentication
510//
511 switch(Request.header.requestid)
512 {case kXR_protocol: return do_Protocol(); // dlen ignored
513 case kXR_ping: return do_Ping(); // dlen ignored
514 default: break;
515 }
516
517// Force authentication at this point, if need be
518//
519 if (Status & XRD_NEED_AUTH)
520 {int rc;
521 if (Request.header.requestid == kXR_auth) rc = do_Auth();
523 "Invalid request; user not authenticated");
524 rc = -1;
525 }
527 return rc;
528 }
529
530// Construct request ID as the following functions are async eligible
531//
533
534// Process items that don't need arguments but may have them
535//
536 switch(Request.header.requestid)
537 {case kXR_endsess: return do_Endsess();
538 default: break;
539 }
540
541// All remaining requests require an argument. Make sure we have one
542//
543 if (!argp || !Request.header.dlen)
544 {Response.Send(kXR_ArgMissing, "Required argument not present");
545 return 0;
546 }
547
548// All of the subsequent requests can be redirected and are subject to
549// prefunctory redirection which we check here.
550//
551 if (CL_Redir && !Link->hasBridge())
552 {bool doRdr = false;
553 if (Link->AddrInfo()->isPrivate()) rdType = 1;
554 if (RouteClient.pvtIP && rdType) doRdr = true;
556 doRdr = true;
557 else if (RouteClient.DomCnt)
558 {XrdOucString hName = Link->Host();
559 for (int i = 0; i < RouteClient.DomCnt; i++)
560 {if (hName.endswith(RouteClient.Domain[i]))
561 {doRdr = true; break;}
562 }
563 }
564 if (doRdr)
566 Route[RD_client].Host[rdType]);
567 return -1;
568 }
569 }
570
571// Process items that keep own statistics
572//
573 switch(Request.header.requestid)
574 {case kXR_open: return do_Open();
575 case kXR_gpfile: return do_gpFile();
576 default: break;
577 }
578
579// Update misc stats count
580//
581 SI->Bump(SI->miscCnt);
582
583// Now process whatever we have
584//
585 switch(Request.header.requestid)
586 {case kXR_chmod: return do_Chmod();
587 case kXR_dirlist: return do_Dirlist();
588 case kXR_fattr: return do_FAttr();
589 case kXR_locate: return do_Locate();
590 case kXR_mkdir: return do_Mkdir();
591 case kXR_mv: return do_Mv();
592 case kXR_query: return do_Query();
593 case kXR_prepare: return do_Prepare();
594 case kXR_rm: return do_Rm();
595 case kXR_rmdir: return do_Rmdir();
596 case kXR_set: return do_Set();
597 case kXR_stat: return do_Stat();
598 case kXR_statx: return do_Statx();
599 case kXR_truncate: return do_Truncate();
600 default: break;
601 }
602
603// Whatever we have, it's not valid
604//
605 Response.Send(kXR_InvalidRequest, "Invalid request code");
606 return 0;
607}
608
609/******************************************************************************/
610/* P r o c S i g */
611/******************************************************************************/
612
614{
615 int rc;
616
617// Check if we completed reading the signature and if so, we are done
618//
619 if (sigRead)
620 {sigRead = false;
621 sigHere = true;
622 return 0;
623 }
624
625// Verify that the hash is not longer that what we support and is present
626//
627 if (Request.header.dlen <= 0
628 || Request.header.dlen > (int)sizeof(sigBuff))
629 {Response.Send(kXR_ArgInvalid, "Invalid signature data length");
630 return Link->setEtext("signature data length error");
631 }
632
633// Save relevant information for the next round
634//
635 memcpy(&sigReq, &Request, sizeof(ClientSigverRequest));
637
638// Now read in the signature
639//
640 sigRead = true;
641 if ((rc = getData("arg", sigBuff, Request.header.dlen)))
642 {Resume = &XrdXrootdProtocol::ProcSig; return rc;}
643 sigRead = false;
644
645// All done
646//
647 sigHere = true;
648 return 0;
649}
650
651/******************************************************************************/
652/* R e c y c l e */
653/******************************************************************************/
654
655#undef TRACELINK
656#define TRACELINK Link
657
658void XrdXrootdProtocol::Recycle(XrdLink *lp, int csec, const char *reason)
659{
660 char *sfxp, ctbuff[24], buff[128], Flags = (reason ? XROOTD_MON_FORCED : 0);
661 const char *What;
662 XrdSysMutexHelper recycleHelper(unbindMutex);
663
664// Check for disconnect or unbind
665//
666 if (Status == XRD_BOUNDPATH) {What = "unbind"; Flags |= XROOTD_MON_BOUNDP;}
667 else What = "disc";
668
669// Document the disconnect or undind
670//
671 if (lp)
672 {XrdSysTimer::s2hms(csec, ctbuff, sizeof(ctbuff));
673 if (reason && strcmp(reason, "hangup"))
674 {snprintf(buff, sizeof(buff), "%s (%s)", ctbuff, reason);
675 sfxp = buff;
676 } else sfxp = ctbuff;
677
678 eDest.Log(SYS_LOG_02, "Xeq", lp->ID, (char *)What, sfxp);
679 }
680
681// Handle any waiting read on this link. This is a tricky proposition because
682// we don't know if the thread is waiting to run or not. However, we will
683// indicate that gdFail was already called and should the thread run, it will
684// promptly exit should it ever run again. That way, we handle the cleanup.
685//
689
690// If this is a bound stream then we cannot release the resources until
691// all activity ceases on this stream (i.e., lp == 0). This is only relevant for
692// writes that read from the link. if we are still tagged as active and not
693// waiting for link activity then ask to be signalled once activity stops.
694// Otherwise, redrive the parallel I/O so that it cleans up.
695//
696 if (lp && Status == XRD_BOUNDPATH)
697 {streamMutex.Lock();
698 isDead = isNOP = true;
699 if (isActive)
700 {if (isLinkWT)
702 do_OffloadIO();
703 } else {
704 while(isActive)
705 {XrdSysCondVar2 aioDone(streamMutex);
706 endNote = &aioDone;
707 aioDone.Wait();
708 endNote = 0;
709 }
711 }
712 } else streamMutex.UnLock();
713 if (lp) return; // Async close
714 }
715
716// Release all appendages
717//
718 Cleanup();
719
720// If we are monitoring logins then we are also monitoring disconnects. We do
721// this after cleanup so that close records can be generated before we cut a
722// disconnect record. This then requires we clear the monitor object here.
723// We and the destrcutor are the only ones who call cleanup and a deletion
724// will call the monitor clear method. So, we won't leak memeory.
725//
726 if (Monitor.Logins()) Monitor.Agent->Disc(Monitor.Did, csec, Flags);
728 Monitor.Clear();
729
730// Set fields to starting point (debugging mostly)
731//
732 Reset();
733
734// Push ourselves on the stack
735//
736 if (Response.isOurs()) ProtStack.Push(&ProtLink);
737}
738
739/******************************************************************************/
740/* S t a t G e n */
741/******************************************************************************/
742
743int XrdXrootdProtocol::StatGen(struct stat &buf, char *xxBuff, int xxLen,
744 bool xtnd)
745{
746 const mode_t isReadable = (S_IRUSR | S_IRGRP | S_IROTH);
747 const mode_t isWritable = (S_IWUSR | S_IWGRP | S_IWOTH);
748 const mode_t isExecable = (S_IXUSR | S_IXGRP | S_IXOTH);
749 uid_t theuid;
750 gid_t thegid;
751 union {long long uuid; struct {int hi; int lo;} id;} Dev;
752 long long fsz;
753 int m, n, flags = 0;
754
755// Get the right uid/gid
756//
757 theuid = (Client && Client->uid ? Client->uid : myUID);
758 thegid = (Client && Client->gid ? Client->gid : myGID);
759
760// Compute the unique id
761//
762 Dev.id.lo = buf.st_ino;
763 Dev.id.hi = buf.st_dev;
764
765// Compute correct setting of the readable flag
766//
767 if (buf.st_mode & isReadable
768 &&((buf.st_mode & S_IRUSR && theuid == buf.st_uid)
769 || (buf.st_mode & S_IRGRP && thegid == buf.st_gid)
770 || buf.st_mode & S_IROTH)) flags |= kXR_readable;
771
772// Compute correct setting of the writable flag
773//
774 if (buf.st_mode & isWritable
775 &&((buf.st_mode & S_IWUSR && theuid == buf.st_uid)
776 || (buf.st_mode & S_IWGRP && thegid == buf.st_gid)
777 || buf.st_mode & S_IWOTH)) flags |= kXR_writable;
778
779// Compute correct setting of the execable flag
780//
781 if (buf.st_mode & isExecable
782 &&((buf.st_mode & S_IXUSR && theuid == buf.st_uid)
783 || (buf.st_mode & S_IXGRP && thegid == buf.st_gid)
784 || buf.st_mode & S_IXOTH)) flags |= kXR_xset;
785
786// Compute the other flag settings
787//
788 if (!Dev.uuid) flags |= kXR_offline;
789 if (S_ISDIR(buf.st_mode)) flags |= kXR_isDir;
790 else if (!S_ISREG(buf.st_mode)) flags |= kXR_other;
791 else{if (buf.st_mode & XRDSFS_POSCPEND) flags |= kXR_poscpend;
792 if ((buf.st_rdev & XRDSFS_RDVMASK) == 0)
793 {if (buf.st_rdev & XRDSFS_OFFLINE) flags |= kXR_offline;
794 if (buf.st_rdev & XRDSFS_HASBKUP) flags |= kXR_bkpexist;
795 }
796 }
797 if ((fsFeatures & XrdSfs::hasCACH) != 0 && buf.st_atime != 0)
798 flags |= kXR_cachersp;
799 fsz = static_cast<long long>(buf.st_size);
800
801// Format the default response: <devid> <size> <flags> <mtime>
802//
803 m = snprintf(xxBuff, xxLen, "%lld %lld %d %lld",
804 Dev.uuid, fsz, flags, (long long) buf.st_mtime);
805// if (!xtnd || m >= xxLen) return xxLen;
806//
807
808// Format extended response: <ctime> <atime> <mode>
809//
810 char *origP = xxBuff;
811 char *nullP = xxBuff + m++;
812 xxBuff += m; xxLen -= m;
813 n = snprintf(xxBuff, xxLen, "%lld %lld %04o ",
814 (long long) buf.st_ctime, (long long) buf.st_atime,
815 buf.st_mode&07777);
816 if (n >= xxLen) return m;
817 xxBuff += n; xxLen -= n;
818
819// Tack on owner
820//
821 if (buf.st_uid == myUID)
822 {if (myUNLen >= xxLen) return m;
823 strcpy(xxBuff, myUName);
824 n = myUNLen;
825 } else {
826 if (!(n = XrdOucUtils::UidName(buf.st_uid,xxBuff,xxLen,keepT))) return m;
827 }
828 xxBuff += n;
829 *xxBuff++ = ' ';
830 xxLen -= (n+1);
831
832// Tack on group
833//
834 if (buf.st_gid == myGID)
835 {if (myGNLen >= xxLen) return m;
836 strcpy(xxBuff, myGName);
837 n = myGNLen;
838 } else {
839 if (!(n = XrdOucUtils::GidName(buf.st_gid,xxBuff,xxLen,keepT))) return m;
840 }
841 xxBuff += n+1;
842
843// All done, return full response
844//
845 *nullP = ' ';
846 return xxBuff - origP;
847}
848
849/******************************************************************************/
850/* S t a t s */
851/******************************************************************************/
852
853int XrdXrootdProtocol::Stats(char *buff, int blen, int do_sync)
854{
855// Synchronize statistics if need be
856//
857 if (do_sync)
858 {SI->statsMutex.Lock();
859 SI->readCnt += numReads;
860 cumReads += numReads; numReads = 0;
861 SI->prerCnt += numReadP;
862 cumReadP += numReadP; numReadP = 0;
863
864 SI->rvecCnt += numReadV;
865 cumReadV += numReadV; numReadV = 0;
866 SI->rsegCnt += numSegsV;
867 cumSegsV += numSegsV; numSegsV = 0;
868
869 SI->wvecCnt += numWritV;
870 cumWritV += numWritV; numWritV = 0;
871 SI->wsegCnt += numSegsW;
872 cumSegsW += numSegsW, numSegsW = 0;
873
877 }
878
879// Now return the statistics
880//
881 return SI->Stats(buff, blen, do_sync);
882}
883
884/******************************************************************************/
885/* X r d S f s X i o M e t h o d s */
886/******************************************************************************/
887/******************************************************************************/
888/* Static: B u f f e r */
889/******************************************************************************/
890
892{
893 XrdBuffer *xbP = (XrdBuffer *)h;
894
895 if (h)
896 {if (bsz) *bsz = xbP->bsize;
897 return xbP->buff;
898 }
899 if (bsz) *bsz = 0;
900 return 0;
901}
902
903/******************************************************************************/
904/* C l a i m */
905/******************************************************************************/
906
907XrdSfsXioHandle XrdXrootdProtocol::Claim(const char *buff, int datasz,
908 int minasz)
909{
910
911// Qualify swap choice
912//
913 if (minasz >= argp->bsize || datasz >= argp->bsize/2) return Swap(buff);
914 errno = 0;
915 return 0;
916}
917
918/******************************************************************************/
919/* Static: R e c l a i m */
920/******************************************************************************/
921
923{
924
925 if (h) BPool->Release((XrdBuffer *)h);
926}
927
928/******************************************************************************/
929/* S t r e a m N O P */
930/******************************************************************************/
931
933{
934
935// Mark this stream as not operation if it is not the control strea,
936//
937 if (PathID)
938 {streamMutex.Lock();
939 isNOP = true;
941 }
942}
943
944/******************************************************************************/
945/* S w a p */
946/******************************************************************************/
947
949{
950 XrdBuffer *oldBP = argp;
951
952// Verify the context and linkage and if OK, swap buffers
953//
954 if (Request.header.requestid != kXR_write) errno = ENOTSUP;
955 else if (buff != argp->buff) errno = EINVAL;
956 else {if (h)
957 {argp = (XrdBuffer *)h;
958 return oldBP;
959 } else {
961 if (argp) return oldBP;
962 argp = oldBP;
963 errno = ENOBUFS;
964 }
965 }
966 return 0;
967}
968
969/******************************************************************************/
970/* V e r i f y S t r e a m */
971/******************************************************************************/
972
974{
976
977// Verify that the path actually exists
978//
979 if (pID >= maxStreams || !(pp = Stream[pID]))
980 {rc = Response.Send(kXR_ArgInvalid, "invalid path ID");
981 return 0;
982 }
983
984// Verify that this path is still functional
985//
986 pp->streamMutex.Lock();
987 if (pp->isNOP)
988 {pp->streamMutex.UnLock();
989 rc = Response.Send(kXR_ArgInvalid, "path ID is not operational");
990 return 0;
991 }
992
993// All done!
994//
995 if (!lok) pp->streamMutex.UnLock();
996 return pp;
997}
998
999/******************************************************************************/
1000/* P r i v a t e M e t h o d s */
1001/******************************************************************************/
1002/******************************************************************************/
1003/* C h e c k S u m */
1004/******************************************************************************/
1005
1006int XrdXrootdProtocol::CheckSum(XrdOucStream *Stream, char **argv, int argc)
1007{
1008 int rc, ecode;
1009
1010// The arguments must have <name> <cstype> <path> <tident> [name] (argc >= 4)
1011//
1012 if (argc < 4)
1013 {Stream->PutLine("Internal error; not enough checksum args!");
1014 return 8;
1015 }
1016
1017// Construct the error information
1018//
1019 XrdOucEnv myEnv;
1020 XrdOucErrInfo myInfo(argv[3], &myEnv);
1021
1022// Add username, if present
1023//
1024 if (argc > 4 && *argv[4]) myEnv.Put("request.name", argv[4]);
1025
1026// Issue the checksum calculation (that's all we do here).
1027//
1028 rc = osFS->chksum(XrdSfsFileSystem::csCalc, argv[1], argv[2], myInfo);
1029
1030// Return result regardless of what it is
1031//
1032 Stream->PutLine(myInfo.getErrText(ecode));
1033 if (rc) {SI->errorCnt++;
1034 if (ecode) rc = ecode;
1035 }
1036 return rc;
1037}
1038
1039/******************************************************************************/
1040/* C l e a n u p */
1041/******************************************************************************/
1042
1043void XrdXrootdProtocol::Cleanup()
1044{
1045 XrdXrootdPio *pioP;
1046 int i;
1047
1048// Handle parallel stream cleanup. The session stream cannot be closed if
1049// there is any queued activity on subordinate streams. A subordinate
1050// can either be closed from the session stream or asynchronously only if
1051// it is active. Which means they could be running while we are running.
1052// So, we first call close() which should trigger a recycle quiesce. Upon
1053// return we can actually recycle the object.
1054//
1055 if (Status != XRD_BOUNDPATH)
1056 {streamMutex.Lock();
1057 for (i = 1; i < maxStreams; i++)
1058 if (Stream[i])
1059 {Stream[i]->Stream[0] = 0;
1060 if (!Stream[i]->isDead) Stream[i]->Link->Close();
1061 Stream[i]->Recycle(0, 0, 0);
1062 Stream[i] = 0;
1063 }
1065 }
1066
1067// Handle packet parking (needs to be done before deleting other stuff)
1068//
1069 if (pmHandle) delete pmHandle;
1070
1071// Release any internal monitoring information
1072//
1073 if (Entity.moninfo) {free(Entity.moninfo); Entity.moninfo = 0;}
1074
1075// If we have a buffer, release it
1076//
1077 if (argp) {BPool->Release(argp); argp = 0;}
1078
1079// Notify the filesystem of a disconnect prior to deleting file tables
1080//
1082
1083// Handle parallel I/O appendages. We need to do this first as these have
1084// referenced open files and we need to deref them before we cleanup the ftab.
1085//
1086 while((pioP = pioFirst))
1087 {pioP->IO.File->Ref(-1); pioFirst = pioP->Next; pioP->Recycle();}
1088 while((pioP = pioFree )) {pioFree = pioP->Next; pioP->Recycle();}
1089
1090// Delete the FTab if we have it
1091//
1092 if (FTab)
1094 FTab = 0;
1095 }
1096
1097// Handle statistics
1098//
1099 SI->statsMutex.Lock();
1101 SI->statsMutex.UnLock();
1102
1103// Handle authentication protocol
1104//
1105 if (AuthProt) {AuthProt->Delete(); AuthProt = 0;}
1106 if (Protect) {Protect->Delete(); Protect = 0;}
1107
1108// Handle writev appendage
1109//
1110 if (wvInfo) {free(wvInfo); wvInfo = 0;}
1111
1112// Release aplication name
1113//
1114 if (AppName) {free(AppName); AppName = 0;}
1115
1116// Release the pagewrite control object
1117//
1118 if (pgwCtl) delete pgwCtl;
1119}
1120
1121/******************************************************************************/
1122/* g e t D a t a */
1123/******************************************************************************/
1124
1125int XrdXrootdProtocol::getData(const char *dtype, char *buff, int blen)
1126{
1127 int rlen;
1128
1129// Read the data but reschedule he link if we have not received all of the
1130// data within the timeout interval.
1131//
1132 rlen = Link->Recv(buff, blen, readWait);
1133 if (rlen < 0)
1134 {if (rlen != -ENOMSG) return Link->setEtext("link read error");
1135 else return -1;
1136 }
1137 if (rlen < blen)
1138 {myBuff = buff+rlen; myBlen = blen-rlen;
1139 TRACEP(REQ, dtype <<" timeout; read " <<rlen <<" of " <<blen <<" bytes");
1140 return 1;
1141 }
1142 return 0;
1143}
1144
1145/******************************************************************************/
1146
1148 const char *dtype, char *buff, int blen)
1149{
1150 bool inCB = (gdCtl.Status == GetDataCtl::inCallBk);
1151
1152// Setup the control information to direct the vector read
1153//
1154 memset((char *)&gdCtl, 0, sizeof(gdCtl));
1155 gdCtl.BuffLen = blen; // Buffer length (bytes to read)
1156 gdCtl.Buffer = buff; // The actual buffer
1157 gdCtl.CallBack= cbP; // Method to callback upon success
1158 gdCtl.ioDType = dtype; // Name of the data being read for tracing
1160
1161// Effect the read. We prevent recursive calls if this was called while
1162// we were in a callback, which is possible due to I/O continuations.
1163//
1164 if (inCB)
1165 {gdCtl.useCB = true;
1166 return 1;
1167 }
1168 return getDataCont();
1169}
1170
1171/******************************************************************************/
1172namespace {int consumed = 0;}
1173
1175 const char *dtype, struct iovec *iov, int iovn)
1176{
1177 bool inCB = (gdCtl.Status == GetDataCtl::inCallBk);
1178
1179// Setup the control information to direct the vector read
1180//
1181 memset((char *)&gdCtl, 0, sizeof(gdCtl));
1182 gdCtl.iovNum = iovn; // Number of original elements
1183 gdCtl.iovVec = iov; // The actual vector
1184 gdCtl.CallBack= cbP; // Method to callback upon success
1185 gdCtl.ioDType = dtype; // Name of the data being read for tracing
1187
1188// Effect the read. We prevent recursive calls if this was called while
1189// we were in a callback, which is possible due to I/O continuations.
1190//
1191 if (inCB)
1192 {gdCtl.useCB = true;
1193 return 1;
1194 }
1195consumed = 0;
1196 return getDataIovCont();
1197}
1198
1199/******************************************************************************/
1200/* g e t D a t a C o n t */
1201/******************************************************************************/
1202
1203int XrdXrootdProtocol::getDataCont()
1204{
1205 int rlen;
1206
1207// Check if we need to terminate because the link died or we can proceed.
1208//
1210 return -EINPROGRESS;
1211
1212// I/O continuations may occur either via entry or an attempt to continue a new
1213// operation via the callback. This takes care of it here.
1214//
1215do{if ((rlen = Link->Recv(gdCtl.Buffer, gdCtl.BuffLen, readWait)) < 0) break;
1216 gdCtl.Buffer += rlen;
1217 gdCtl.BuffLen -= rlen;
1218
1219// If we completed the read then either return or use the callback. Note that
1220// we convert recursive call for more data into an iterative continuation.
1221//
1222 if (!gdCtl.BuffLen)
1223 {if (gdCtl.useCB)
1225 if (int(gdCtl.stalls) > as_okstutter)
1227 rlen = gdCtl.CallBack->gdDone();
1228 if (rlen < 0) break;
1229 if (gdCtl.Status == GetDataCtl::inData) continue;
1230 if (gdCtl.Status == GetDataCtl::inDataIov) return getDataIovCont();
1231 if (gdCtl.Status == GetDataCtl::inDump) return getDumpCont();
1233 return rlen;
1234 }
1236 return 0;
1237 }
1238
1239// Make sure we don't have an over-run
1240//
1241 if (gdCtl.BuffLen < 0)
1242 {rlen = Link->setEtext("link excessive read length error");
1243 break;
1244 }
1245
1246// Record where we stopped and setup to resume here when more data arrives. We
1247// must set myBlen to zero to avoid calling the other GetData() method. We want
1248// to resume and perform the GetData() function here.
1249//
1250 Resume = &XrdXrootdProtocol::getDataCont;
1251 myBlen = 0;
1252 gdCtl.useCB = true;
1254 if (gdCtl.stalls < 255) gdCtl.stalls++;
1255
1256// Return indicating we need more data
1257//
1258 TRACEP(REQ, gdCtl.ioDType <<" timeout; read " <<rlen <<" bytes "
1259 <<gdCtl.BuffLen <<" remaining");
1260 return 1;
1261
1262 } while(true);
1263
1264// If got here then we had a link failure or some other fatal issue
1265//
1266 if (rlen != -ENOMSG) return Link->setEtext("link read error");
1267
1268// Use callback, if need be.
1269//
1270 if (gdCtl.useCB)
1273 }
1275 return -1;
1276}
1277
1278/******************************************************************************/
1279/* g e t D a t I o v C o n t */
1280/******************************************************************************/
1281
1282int XrdXrootdProtocol::getDataIovCont()
1283{
1284 int rc;
1285
1286// Check if we need to terminate because the link died or we can proceed.
1287//
1289 return -EINPROGRESS;
1290
1291// I/O continuations may occur either via entry or an attempt to continue a new
1292// operation via the callback. This takes care of it here.
1293//
1294do{struct iovec *ioV = gdCtl.iovVec;
1295 int i, rlen, iovN = gdCtl.iovNum, iNow = gdCtl.iovNow;
1296
1297// Read as much data as we can. Handle any link error. Note that when a link
1298// error occurs we return failure whether or not the callback wants to do more.
1299//
1300 rlen = Link->Recv(&ioV[iNow], iovN - iNow, readWait);
1301 if (rlen < 0)
1302 {if (rlen != -ENOMSG) Link->setEtext("link read error");
1303 if (gdCtl.iovAdj)
1304 {ioV[iNow].iov_base = ((char *)ioV[iNow].iov_base) - gdCtl.iovAdj;
1305 ioV[iNow].iov_len += gdCtl.iovAdj;
1306 gdCtl.iovAdj = 0;
1307 }
1308 rc = -1;
1309 break;
1310 }
1311
1312// Compute where we finished in the iovec.
1313//
1314 for (i = iNow; i < iovN && (int)ioV[i].iov_len <= rlen; i++)
1315 rlen -= ioV[i].iov_len;
1316
1317// Before proceeding, restore any changes we made to a completed iovec element
1318//
1319 if (i != iNow && gdCtl.iovAdj)
1320 {ioV[iNow].iov_base = ((char *)ioV[iNow].iov_base) - gdCtl.iovAdj;
1321 ioV[iNow].iov_len += gdCtl.iovAdj;
1322 gdCtl.iovAdj = 0;
1323 }
1324
1325// If the vector is complete then effect the callback unless this was the
1326// initial call, we simply return to prevent recursive continuations by
1327// converting a recursive call to an iterative continuation!
1328//
1329 if (i >= iovN)
1330 {if (!rlen)
1331 {if (gdCtl.useCB)
1333 if (int(gdCtl.stalls) > as_okstutter)
1335 rc = gdCtl.CallBack->gdDone();
1336 if (rc < 0) break;
1337 if (gdCtl.Status == GetDataCtl::inDataIov) continue;
1338 if (gdCtl.Status == GetDataCtl::inDump) return getDumpCont();
1340 return rc;
1341 }
1343 return 0;
1344 }
1345 rc = Link->setEtext("link iov read length error");
1346 break;
1347 }
1348
1349// Record where we stopped and adjust the iovec element address and length if
1350// needed. Record the change made so that it can be undone as we progress.
1351//
1352 gdCtl.iovNow = i;
1353 if (rlen)
1354 {if (gdCtl.iovAdj == 0) gdCtl.iovNow = i;
1355 gdCtl.iovAdj += rlen;
1356 ioV[i].iov_base = ((char *)ioV[i].iov_base) + rlen;
1357 ioV[i].iov_len -= rlen;
1358 }
1359
1360// Setup to resume here when more data arrives. We must set myBlen to zero to
1361// avoid calling the other GetData() method as we want to resume here.
1362//
1363 Resume = &XrdXrootdProtocol::getDataIovCont;
1364 myBlen = 0;
1365 gdCtl.useCB = true;
1367 if (gdCtl.stalls < 255) gdCtl.stalls++;
1368
1369// Return indicating we need more data
1370//
1371 TRACEP(REQ, gdCtl.ioDType<<" read timeout; "<<iovN-i<<" of "
1372 <<gdCtl.iovNum <<" iov elements left");
1373 return 1;
1374
1375 } while(true);
1376
1377// If got here then we had a link failure or some other fatal issue
1378//
1379 if (gdCtl.useCB)
1382 }
1384 return rc;
1385}
1386
1387/******************************************************************************/
1388/* g e t D u m p */
1389/******************************************************************************/
1390
1391int XrdXrootdProtocol::getDump(const char *dtype, int dlen)
1392{
1393 bool inCB = (gdCtl.Status == GetDataCtl::inCallBk);
1394
1395// Setup the control information to direct the vector read
1396//
1397 memset((char *)&gdCtl, 0, sizeof(gdCtl));
1398 gdCtl.DumpLen = dlen; // Bytes left to drain
1399 gdCtl.ioDType = dtype; // Name of the data being read for tracing
1401
1402// Effect the read. We prevent recursive calls if this was called while
1403// we were in a callback, which is possible due to I/O continuations.
1404//
1405 return (inCB ? 1 : getDumpCont());
1406}
1407
1408/******************************************************************************/
1409/* Private: g e t D u m p C o n t */
1410/******************************************************************************/
1411
1412int XrdXrootdProtocol::getDumpCont()
1413{
1414 int rlen = 0, rwant;
1415 char buff[65536];
1416
1417 TRACEP(REQ, gdCtl.ioDType<<" discarding "<<gdCtl.DumpLen<<" bytes.");
1418
1419// Read data and discard it
1420//
1421 while(gdCtl.DumpLen > 0)
1422 {if (gdCtl.DumpLen <= (int)sizeof(buff)) rwant = gdCtl.DumpLen;
1423 else rwant = sizeof(buff);
1424 if ((rlen = Link->Recv(buff, rwant, readWait)) <= 0) break;
1425 gdCtl.DumpLen -= rlen;
1426 }
1427
1428// Check if we failed
1429//
1430 if (rlen < 0 || gdCtl.DumpLen < 0)
1431 {if (gdCtl.DumpLen < 0) Link->setEtext("link read overrun error");
1432 else if (rlen != -ENOMSG) Link->setEtext("link read error");
1434 return -1;
1435 }
1436
1437// Check if we completed
1438//
1439 if (gdCtl.DumpLen == 0)
1441 return 0;
1442 }
1443
1444// Wait until more data arrives. We will now need to use the callback.
1445//
1446 Resume = &XrdXrootdProtocol::getDumpCont;
1447 myBlen = 0;
1448
1449 TRACEP(REQ, gdCtl.ioDType<<" read timeout; "<<gdCtl.DumpLen
1450 <<" bytes left to discard");
1451 return 1;
1452}
1453
1454/******************************************************************************/
1455/* R e s e t */
1456/******************************************************************************/
1457
1458void XrdXrootdProtocol::Reset()
1459{
1460 Status = 0;
1461 argp = 0;
1462 Link = 0;
1463 FTab = 0;
1464 pmHandle = 0;
1465 ResumePio = 0;
1466 Resume = 0;
1467 myBuff = (char *)&Request;
1468 myBlen = sizeof(Request);
1469 myBlast = 0;
1470 myStalls = 0;
1471 pgwCtl = 0;
1472 memset(&IO, 0, sizeof(IO));
1473 wvInfo = 0;
1474 numReads = 0;
1475 numReadP = 0;
1476 numReadV = 0;
1477 numSegsV = 0;
1478 numWritV = 0;
1479 numSegsW = 0;
1480 numWrites = 0;
1481 numFiles = 0;
1482 cumReads = 0;
1483 cumReadV = 0;
1484 cumSegsV = 0;
1485 cumWritV = 0;
1486 cumSegsW = 0;
1487 cumWrites = 0;
1488 totReadP = 0;
1489 hcPrev =13;
1490 hcNext =21;
1491 hcNow =13;
1492 Client = 0;
1493 AuthProt = 0;
1494 Protect = 0;
1495 mySID = 0;
1496 CapVer = 0;
1497 clientPV = 0;
1498 clientRN = 0;
1499 pmDone = false;
1500 reTry = 0;
1501 endNote = 0;
1502 PathID = 0;
1503 newPio = false;
1504 rvSeq = 0;
1505 wvSeq = 0;
1506 doTLS = tlsNot; // Assume client is not capable. This will be
1507 ableTLS = false; // resolved during the kXR_protocol interchange.
1508 isTLS = false; // Made true when link converted to TLS
1509 linkAioReq = 0;
1510 pioFree = pioFirst = pioLast = 0;
1511 isActive = isLinkWT= isNOP = isDead = false;
1512 sigNeed = sigHere = sigRead = false;
1513 sigWarn = true;
1514 rdType = 0;
1515 Entity.Reset(0);
1516 memset(Stream, 0, sizeof(Stream));
1517 memset((char *)&gdCtl, 0, sizeof(gdCtl));
1518 PrepareCount = 0;
1519 if (AppName) {free(AppName); AppName = 0;}
1520}
@ kXR_ArgInvalid
Definition XProtocol.hh:990
@ kXR_InvalidRequest
Definition XProtocol.hh:996
@ kXR_ArgMissing
Definition XProtocol.hh:991
@ kXR_SigVerErr
@ kXR_ArgTooLong
Definition XProtocol.hh:992
struct ClientRequestHdr header
Definition XProtocol.hh:881
kXR_char streamid[2]
Definition XProtocol.hh:156
@ kXR_redirect
Definition XProtocol.hh:904
struct ClientRequestHdr header
Definition XProtocol.hh:846
#define kXR_PROTOCOLVSTRING
Definition XProtocol.hh:75
kXR_unt16 requestid
Definition XProtocol.hh:157
@ kXR_read
Definition XProtocol.hh:125
@ kXR_open
Definition XProtocol.hh:122
@ kXR_writev
Definition XProtocol.hh:143
@ kXR_readv
Definition XProtocol.hh:137
@ kXR_mkdir
Definition XProtocol.hh:120
@ kXR_sync
Definition XProtocol.hh:128
@ kXR_chmod
Definition XProtocol.hh:114
@ kXR_bind
Definition XProtocol.hh:136
@ kXR_dirlist
Definition XProtocol.hh:116
@ kXR_sigver
Definition XProtocol.hh:141
@ kXR_fattr
Definition XProtocol.hh:132
@ kXR_rm
Definition XProtocol.hh:126
@ kXR_query
Definition XProtocol.hh:113
@ kXR_write
Definition XProtocol.hh:131
@ kXR_gpfile
Definition XProtocol.hh:117
@ kXR_login
Definition XProtocol.hh:119
@ kXR_auth
Definition XProtocol.hh:112
@ kXR_endsess
Definition XProtocol.hh:135
@ kXR_set
Definition XProtocol.hh:130
@ kXR_rmdir
Definition XProtocol.hh:127
@ kXR_statx
Definition XProtocol.hh:134
@ kXR_truncate
Definition XProtocol.hh:140
@ kXR_protocol
Definition XProtocol.hh:118
@ kXR_mv
Definition XProtocol.hh:121
@ kXR_ping
Definition XProtocol.hh:123
@ kXR_stat
Definition XProtocol.hh:129
@ kXR_pgread
Definition XProtocol.hh:142
@ kXR_chkpoint
Definition XProtocol.hh:124
@ kXR_locate
Definition XProtocol.hh:139
@ kXR_close
Definition XProtocol.hh:115
@ kXR_pgwrite
Definition XProtocol.hh:138
@ kXR_prepare
Definition XProtocol.hh:133
@ kXR_faMaxVlen
Definition XProtocol.hh:282
@ kXR_faMaxNlen
Definition XProtocol.hh:281
#define kXR_LBalServer
#define kXR_PROTOCOLVERSION
Definition XProtocol.hh:70
#define kXR_DataServer
@ kXR_readable
@ kXR_isDir
@ kXR_offline
@ kXR_bkpexist
@ kXR_other
@ kXR_poscpend
@ kXR_writable
@ kXR_cachersp
@ kXR_xset
unsigned int kXR_unt32
Definition XPtypes.hh:90
unsigned short kXR_unt16
Definition XPtypes.hh:67
#define stat(a, b)
Definition XrdPosix.hh:101
#define NEED2SECURE(protP)
This class implements the XRootD protocol security protection.
static const dev_t XRDSFS_HASBKUP
static const dev_t XRDSFS_RDVMASK
#define XRDSFS_POSCPEND
static const dev_t XRDSFS_OFFLINE
class XrdBuffer * XrdSfsXioHandle
Definition XrdSfsXio.hh:46
#define AtomicInc(x)
#define AtomicBeg(Mtx)
#define AtomicEnd(Mtx)
const int SYS_LOG_02
const kXR_char XROOTD_MON_BOUNDP
const kXR_char XROOTD_MON_FORCED
XrdVERSIONINFO(XrdgetProtocol, xrootd)
XrdProtocol * XrdgetProtocol(const char *pname, char *parms, XrdProtocol_Config *pi)
XrdSysTrace XrdXrootdTrace("Xrootd")
int XrdgetProtocolPort(const char *pname, char *parms, XrdProtocol_Config *pi)
#define ROOTD_PQ
#define XRD_BOUNDPATH
#define XRD_NEED_AUTH
#define TRACEP(act, x)
static const char * reqName(kXR_unt16 reqCode)
Definition XProtocol.cc:151
void Release(XrdBuffer *bp)
Definition XrdBuffer.cc:221
XrdBuffer * Obtain(int bsz)
Definition XrdBuffer.cc:140
char * buff
Definition XrdBuffer.hh:45
static bool InDomain(XrdNetAddrInfo *epaddr)
Definition XrdNetIF.cc:606
void Push(XrdObject< T > *Node)
Definition XrdObject.hh:101
T * Pop()
Definition XrdObject.hh:93
void Put(const char *varname, const char *value)
Definition XrdOucEnv.hh:85
XrdSysMutex statsMutex
void Bump(int &val)
bool endswith(char c)
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)
XrdSysError * eDest
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)
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)
T fetch_or(T v) noexcept
T fetch_and(T v) noexcept
static void ClearErrorQueue()
Clear the SSL error queue for the calling thread.
Definition XrdTls.cc:265
void Recycle(XrdXrootdMonitor *monP)
void Ref(int num)
static void Disc(unsigned int usrID)
XrdXrootdMonitor * Agent
void Disc(kXR_unt32 dictid, int csec, char Flags=0)
XrdXrootdPio * Next
XrdXrootd::IOParms IO
static XrdXrootdStats * SI
static const char * myInst
XrdXrootdProtocol * VerifyStream(int &rc, int pID, bool lok=true)
static XrdSfsFileSystem * digFS
XrdSecProtect * Protect
XrdNetPMark::Handle * pmHandle
static XrdNetPMark * PMark
XrdXrootdProtocol * Stream[maxStreams]
XrdXrootd::IOParms IO
static XrdXrootdXPath RPList
static XrdNetSocket * AdminSock
XrdProtocol * Match(XrdLink *lp) override
struct XrdXrootdProtocol::GetDataCtl gdCtl
XrdXrootdWVInfo * wvInfo
XrdXrootdPgwCtl * pgwCtl
static void Reclaim(XrdSfsXioHandle h)
XrdSysSemaphore * reTry
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 const char * myCName
XrdSfsXioHandle Swap(const char *buff, XrdSfsXioHandle h=0) override
static XrdXrootdFileLock * Locker
SecurityRequest sigReq
int(XrdXrootdProtocol::* Resume)()
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
int(XrdXrootdProtocol::* ResumePio)()
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 XrdSecProtector * DHS
static XrdBuffManager * BPool
static XrdSecService * CIA
static RAtomic_int srvrAioOps
static const char * myGName
static uint64_t fsFeatures
static XrdOucReqID * PrepID
XrdXrootdPio * pioFirst
XrdSysCondVar2 * endNote
static struct XrdXrootdProtocol::RD_Table Route[RD_Num]
static XrdSfsFileSystem * osFS
void setID(unsigned long long id)
void Set(XrdLink *lp)
int Stats(char *buff, int blen, int do_sync=0)
virtual int gdDone()=0
static const uint64_t hasCACH
Feature: Implements a data cache.
XrdXrootdStats * SI
XrdScheduler * Sched
XrdBuffManager * BPool
XrdSysError eLog
XrdXrootd::gdCallBack * CallBack