XRootD
Loading...
Searching...
No Matches
XrdXrootdConfig.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d X r o o t d C o n f i g . c c */
4/* */
5/* (c) 2010 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 Deprtment 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 <unistd.h>
31#include <cctype>
32#include <fcntl.h>
33#include <string>
34#include <cstring>
35#include <cstdio>
36#include <sys/param.h>
37#include <sys/stat.h>
38#include <sys/types.h>
39#include <vector>
40
41#ifdef __solaris__
42#include <sys/isa_defs.h>
43#endif
44
45#include "XrdVersion.hh"
46
48
49#include "XrdSfs/XrdSfsFlags.hh"
51#include "XrdNet/XrdNetOpts.hh"
54#include "XrdOuc/XrdOuca2x.hh"
55#include "XrdOuc/XrdOucEnv.hh"
56#include "XrdOuc/XrdOucProg.hh"
57#include "XrdOuc/XrdOucReqID.hh"
60#include "XrdOuc/XrdOucUtils.hh"
62#include "XrdSys/XrdSysError.hh"
65
67
82
83#include "Xrd/XrdBuffer.hh"
84#include "Xrd/XrdInet.hh"
85#include "Xrd/XrdLink.hh"
86
87/******************************************************************************/
88/* P r o t o c o l C o m m a n d L i n e O p t i o n s */
89/******************************************************************************/
90
91/* This is the XRootd server. The syntax is:
92
93 xrootd [options]
94
95 options: [<xopt>] [-r] [-t] [-y] [path]
96
97Where:
98 xopt are xrd specified options that are screened out.
99
100 -r This is a redirecting server.
101
102 -t This server is a redirection target.
103
104 -y This server is a proxy server.
105
106 path Export path. Any number of paths may be specified.
107 By default, only '/tmp' is exported.
108
109*/
110/******************************************************************************/
111/* G l o b a l s */
112/******************************************************************************/
113
115
117
119
120 const char *XrdXrootdInstance;
121
123
126 const char *,
127 const char *, XrdOucEnv *);
128
131 const char *, const char *,
132 const char *, XrdOucEnv *);
133
135 (XrdSfsFileSystem *nativeFS,
137 const char *configFn,
138 XrdOucEnv *EnvInfo);
139
140/******************************************************************************/
141/* G l o b a l S t a t i c s */
142/******************************************************************************/
143
144namespace XrdXrootd
145{
146extern XrdBuffManager *BPool;
147extern XrdScheduler *Sched;
148extern XrdXrootdStats *SI;
149}
150
151/******************************************************************************/
152/* L o c a l S t a t i c s */
153/******************************************************************************/
154
155namespace
156{
157char *digParm = 0;
158char *FSLib[2] = {0,0};
159std::vector<std::string> FSLPath; // fslib
160std::vector<std::string> RDLPath; // redirlib
161std::vector<std::string> RDLParm; // redirlib
162char *gpfLib = 0;// Normally zero for default
163char *gpfParm = 0;
164char *SecLib;
166int asyncFlags = 0;
167
168static const int asDebug = 0x01;
169static const int asNoCache = 0x02;
170}
171
172/******************************************************************************/
173/* C o n f i g u r e */
174/******************************************************************************/
175
177{
178/*
179 Function: Establish configuration at load time.
180
181 Input: None.
182
183 Output: 0 upon success or !0 otherwise.
184*/
185
187 (XrdSfsFileSystem *nativeFS,
189 const char *configFn,
190 const char *theParms);
191
192 XrdOucEnv xrootdEnv;
193 XrdXrootdXPath *xp;
194 char *adminp, *rdf, *bP, *tmp, buff[1024];
195 int i, n;
196
197// Copy out the special info we want to use at top level
198//
199 eDest.logger(pi->eDest->logger());
200 XrdXrootdTrace.SetLogger(pi->eDest->logger());
201 SI = new XrdXrootdStats(pi->Stats);
203 Sched = pi->Sched; XrdXrootd::Sched = pi->Sched;
204 BPool = pi->BPool; XrdXrootd::BPool = pi->BPool;
205 hailWait = pi->hailWait;
206 readWait = pi->readWait;
207 Port = pi->Port;
208 myInst = pi->myInst;
209 Window = pi->WSize;
210 tlsPort = pi->tlsPort;
211 tlsCtx = pi->tlsCtx;
212 XrdXrootdCF = pi->totalCF;
213
214// Record globally accessible values
215//
217 XrdXrootdPort = pi->Port;
218
219// Set the callback object static areas now!
220//
222
223// Pick up exported paths from the command line
224//
225 for (i = 1; i < pi->argc; i++) xexpdo(pi->argv[i]);
226
227// Pre-initialize some i/o values. Note that we now set maximum readv element
228// transfer size to the buffer size (before it was a reasonable 256K).
229//
230 n = (pi->theEnv ? pi->theEnv->GetInt("MaxBuffSize") : 0);
231 maxTransz = maxBuffsz = (n ? n : BPool->MaxSize());
233
234// Export the readv_ior_max and readv_iov_max values
235//
236 {char buff[256];
237 snprintf(buff, sizeof(buff), "%d,%d", maxReadv_ior, XrdProto::maxRvecsz);
238 XrdOucEnv::Export("XRD_READV_LIMITS", buff);
239 }
240
241 memset(Route, 0, sizeof(Route));
242
243// Now process and configuration parameters
244//
245 rdf = (parms && *parms ? parms : pi->ConfigFN);
246 if (rdf && Config(rdf)) return 0;
247 if (pi->DebugON) XrdXrootdTrace.What = TRACE_ALL;
248
249// Initialize the packet marking framework if configured. We do that here as
250// nothing else following this code can fail but we can so be consistent.
251//
252 bool bad = false;
254 if (PMark)
255 {if (pi->theEnv) pi->theEnv->PutPtr("XrdNetPMark*", PMark);
256 xrootdEnv.PutPtr("XrdNetPMark*", PMark);
257 }
258 else if (bad) return 0;
259
260// Check if we are exporting a generic object name
261//
262 if (XPList.Opts() & XROOTDXP_NOSLASH)
263 {eDest.Say("Config exporting ", XPList.Path(n)); n += 2;}
264 else n = 0;
265
266// Check if we are exporting anything
267//
268 if (!(xp = XPList.Next()) && !n)
269 {XPList.Insert("/tmp"); n = 8;
270 eDest.Say("Config warning: only '/tmp' will be exported.");
271 } else {
272 while(xp) {eDest.Say("Config exporting ", xp->Path(i));
273 n += i+2; xp = xp->Next();
274 }
275 }
276
277// Export the exports
278//
279 bP = tmp = (char *)malloc(n);
280 if (XPList.Opts() & XROOTDXP_NOSLASH)
281 {strcpy(bP, XPList.Path(i)); bP += i, *bP++ = ' ';}
282 xp = XPList.Next();
283 while(xp) {strcpy(bP, xp->Path(i)); bP += i; *bP++ = ' '; xp = xp->Next();}
284 *(bP-1) = '\0';
285 XrdOucEnv::Export("XRDEXPORTS", tmp); free(tmp);
286
287// Initialize the security system if this is wanted
288//
289 if (!ConfigSecurity(xrootdEnv, pi->ConfigFN)) return 0;
290
291// Set up the network for self-identification and display it
292//
293 pi->NetTCP->netIF.Port(Port);
294 pi->NetTCP->netIF.Display("Config ");
295
296// Establish our specific environment that will be passed along
297//
298 xrootdEnv.PutPtr("XrdInet*", (void *)(pi->NetTCP));
299 xrootdEnv.PutPtr("XrdNetIF*", (void *)(&(pi->NetTCP->netIF)));
300 xrootdEnv.PutPtr("XrdScheduler*", Sched);
301
302// Copy over the xrd environment which contains plugin argv's and re-export
303// the monitoring registration object into out own env for simplicity
304//
305 if (pi->theEnv)
306 {xrootdEnv.PutPtr("xrdEnv*", pi->theEnv);
307 void* theMon = pi->theEnv->GetPtr("XrdMonRoll*");
308 if (theMon) xrootdEnv.PutPtr("XrdMonRoll*", theMon);
309 }
310
311// Initialize monitoring (it won't do anything if it wasn't enabled). This
312// needs to be done before we load any plugins as plugins may need monitoring.
313//
314 if (!ConfigMon(pi, xrootdEnv)) return 0;
315
316// Get the filesystem to be used and its features.
317//
318 if (!ConfigFS(xrootdEnv, pi->ConfigFN)) return 0;
319 fsFeatures = osFS->Features();
321 if (pi->theEnv) pi->theEnv->PutPtr("XrdSfsFileSystem*", osFS);
322
323// Check if the file system includes a custom prepare handler as this will
324// affect how we handle prepare requests.
325//
326 if (fsFeatures & XrdSfs::hasPRP2 || xrootdEnv.Get("XRD_PrepHandler"))
327 PrepareAlt = true;
328
329// Check if the diglib should be loaded. We only support the builtin one. In
330// the future we will have to change this code to be like the above.
331//
332 if (digParm)
333 {TRACE(DEBUG, "Loading dig filesystem builtin");
334 digFS = XrdDigGetFS(osFS, eDest.logger(), pi->ConfigFN, digParm);
335 if (!digFS) eDest.Emsg("Config","Unable to load digFS; "
336 "remote debugging disabled!");
337 }
338
339// Check if we are going to be processing checksums locally
340//
341 if (JobCKT) {
342 XrdOucString csList(1024);
343 XrdOucErrInfo myError("Config");
345 int csNum = 0;
346 do {
347 if(JobLCL) {
348 // Check natively supported checksum
349 if (osFS->chksum(XrdSfsFileSystem::csSize, tP->text, 0, myError)) {
350 eDest.Emsg("Config", tP->text, "checksum is not natively supported.");
351 return 0;
352 }
353 }
354 tP->ival[1] = myError.getErrInfo();
355 if (csNum) csList += ',';
356 csList.append(csNum);
357 csList.append(':');
358 csList.append(tP->text);
359 csNum++;
360 tP = tP->next;
361 } while (tP);
362 if (csNum) XrdOucEnv::Export("XRD_CSLIST", csList.c_str());
363 }
364
365// Configure the redirect plugins. After loading the chain we publish the
366// final pointer in two places: the protocol environment (so external
367// plugins can fetch the raw pointer of the plugin via the
368// "XrdXrootdRedirPI*" key) and XrdXrootdRedirHelper, the in-tree adapter
369// that fsRedirPI() and the HTTP TPC handler both call to apply plugin-
370// driven routing (issue #2767).
371//
372 if (!RDLPath.empty())
373 {for (int i = 0; i < (int)RDLPath.size(); i++)
374 {const char* parm = (RDLParm[i].length() ? RDLParm[i].c_str() : 0);
375 if (!ConfigRedirPI(RDLPath[i].c_str(),xrootdEnv,pi->ConfigFN,parm))
376 return 0;
377 if (pi->theEnv)
378 pi->theEnv->PutPtr("XrdXrootdRedirPI*", RedirPI);
379 }
381 }
382
383// Initialiaze for AIO. If we are not in debug mode and aio is enabled then we
384// turn off async I/O if tghe filesystem requests it or if this is a caching
385// proxy and we were asked not to use aio in such a cacse.
386//
387 if (!(asyncFlags & asDebug) && as_aioOK)
388 {if (fsFeatures & XrdSfs::hasNAIO) as_aioOK = false;
389 else if (asyncFlags & asNoCache && fsFeatures & XrdSfs::hasCACH)
390 as_aioOK = false;
391 if (!as_aioOK) eDest.Say("Config asynchronous I/O has been disabled!");
392 }
393
394// Compute the maximum stutter allowed during async I/O (one per 64k)
395//
396 if (as_segsize > 65536) as_okstutter = as_segsize/65536;
397
398// Establish final sendfile processing mode. This may be turned off by the
399// link or by the SFS plugin usually because it's a proxy.
400//
401 const char *why = 0;
402 if (!as_nosf)
403 {if (fsFeatures & XrdSfs::hasNOSF) why = "file system plugin.";
404 else if (!XrdLink::sfOK) why = "OS kernel.";
405 if (why)
406 {as_nosf = true;
407 eDest.Say("Config sendfile has been disabled by ", why);
408 }
409 }
410
411// Create the file lock manager and initialize file handling
412//
415
416// Schedule protocol object cleanup (also advise the transit protocol)
417//
418 ProtStack.Set(pi->Sched, &XrdXrootdTrace, TRACE_MEM);
419 n = (pi->ConnMax/3 ? pi->ConnMax/3 : 30);
420 ProtStack.Set(n, 60*60);
421 XrdXrootdTransit::Init(pi->Sched, n, 60*60);
422
423// Initialize the request ID generation object
424//
425 PrepID = new XrdOucReqID(pi->urAddr, (int)Port);
426
427// Initialize for prepare processing
428//
430 sprintf(buff, "%%s://%s:%d/&L=%%d&U=%%s", pi->myName, pi->Port);
431 Notify = strdup(buff);
432
433// Set the redirect flag if we are a pure redirector
434//
435 int tlsFlags = myRole & kXR_tlsAny;
437 if ((rdf = getenv("XRDREDIRECT"))
438 && (!strcmp(rdf, "R") || !strcmp(rdf, "M")))
439 {isRedir = *rdf;
441 if (!strcmp(rdf, "M")) myRole |=kXR_attrMeta;
442 }
445 myRole |= tlsFlags;
446
447// Turn off client redirects if we are neither a redirector nor a proxy server
448//
449 if (CL_Redir && !isRedir && !isProxy)
450 {CL_Redir = false;
451 eDest.Say("Config warning: 'redirect client' ignored; "
452 "not a redirector nor a proxy server");
453 }
454
455// Check if we are redirecting anything
456//
457 if ((xp = RPList.Next()))
458 {int k;
459 char buff[2048], puff[1024];
460 do {k = xp->Opts();
461 if (Route[k].Host[0] == Route[k].Host[1]
462 && Route[k].Port[0] == Route[k].Port[1]) *puff = 0;
463 else sprintf(puff, "%%%s:%d", Route[k].Host[1], Route[k].Port[1]);
464 sprintf(buff," to %s:%d%s",Route[k].Host[0],Route[k].Port[0],puff);
465 eDest.Say("Config redirect static ", xp->Path(), buff);
466 xp = xp->Next();
467 } while(xp);
468 }
469
470 if ((xp = RQList.Next()))
471 {int k;
472 const char *cgi1, *cgi2;
473 char buff[2048], puff[1024], xCgi[RD_Num] = {0};
474 if (isRedir) {cgi1 = "+"; cgi2 = getenv("XRDCMSCLUSTERID");}
475 else {cgi1 = ""; cgi2 = pi->myName;}
476 myCNlen = snprintf(buff, sizeof(buff), "%s%s", cgi1, cgi2);
477 myCName = strdup(buff);
478 do {k = xp->Opts();
479 if (Route[k].Host[0] == Route[k].Host[1]
480 && Route[k].Port[0] == Route[k].Port[1]) *puff = 0;
481 else sprintf(puff, "%%%s:%d", Route[k].Host[1], Route[k].Port[1]);
482 sprintf(buff," to %s:%d%s",Route[k].Host[0],Route[k].Port[0],puff);
483 eDest.Say("Config redirect enoent ", xp->Path(), buff);
484 if (!xCgi[k] && cgi2)
485 {bool isdup = Route[k].Host[0] == Route[k].Host[1]
486 && Route[k].Port[0] == Route[k].Port[1];
487 for (i = 0; i < 2; i++)
488 {n = snprintf(buff,sizeof(buff), "%s?tried=%s%s",
489 Route[k].Host[i], cgi1, cgi2);
490 free(Route[k].Host[i]); Route[k].Host[i] = strdup(buff);
491 Route[k].RDSz[i] = n;
492 if (isdup) {Route[k].Host[1] = Route[k].Host[0];
493 Route[k].RDSz[1] = n; break;
494 }
495 }
496 }
497 xCgi[k] = 1;
498 xp = xp->Next();
499 } while(xp);
500 }
501
502// Add all jobs that we can run to the admin object
503//
504 if (JobCKS) XrdXrootdAdmin::addJob("chksum", JobCKS);
505
506// Establish the path to be used for admin functions. We will loose this
507// storage upon an error but we don't care because we'll just exit.
508//
509 adminp = XrdOucUtils::genPath(pi->AdmPath, 0, ".xrootd");
510
511// Setup the admin path (used in all roles).
512//
513 if (!(AdminSock = XrdNetSocket::Create(&eDest, adminp, "admin", pi->AdmMode))
514 || !XrdXrootdAdmin::Init(&eDest, AdminSock)) return 0;
515
516// Indicate whether or not we support extended attributes
517//
518 {XrdOucEnv myEnv;
519 XrdOucErrInfo eInfo("", &myEnv);
520 char buff[128];
521 if (osFS->FAttr(0, eInfo, 0) == SFS_OK)
522 {usxMaxNsz = myEnv.GetInt("usxMaxNsz");
523 if (usxMaxNsz < 0) usxMaxNsz = 0;
524 usxMaxVsz = myEnv.GetInt("usxMaxVsz");
525 if (usxMaxVsz < 0) usxMaxVsz = 0;
526 snprintf(buff, sizeof(buff), "%d %d", usxMaxNsz, usxMaxVsz);
527 usxParms = strdup(buff);
528 } else {
529 usxMaxNsz = 0;
530 usxMaxVsz = 0;
531 usxParms = strdup("0 0");
532 }
533 }
534
535// Finally, check if we really need to be in bypass mode if it is set
536//
537 if (OD_Bypass)
538 {const char *penv = getenv("XRDXROOTD_PROXY");
539 if (!penv || *penv != '=')
540 {OD_Bypass = false;
541 eDest.Say("Config warning: 'fsoverload bypass' ignored; "
542 "not a forwarding proxy.");
543 }
544 }
545
546// Add any additional features
547//
553
554// Finally note whether or not we have TLS enabled
555//
556 if (tlsCtx) myRole |= kXR_haveTLS;
557
558// Return success
559//
560 free(adminp);
561 return 1;
562}
563
564/******************************************************************************/
565/* C o n f i g */
566/******************************************************************************/
567
568#define TS_Xeq(x,m) (!strcmp(x,var)) GoNo = m(Config)
569#define TS_Zeq(x,m) (!strcmp(x,var)) GoNo = m(&eDest, Config)
570
571int XrdXrootdProtocol::Config(const char *ConfigFN)
572{
573 XrdOucEnv myEnv;
574 XrdOucStream Config(&eDest, getenv("XRDINSTANCE"), &myEnv, "=====> ");
575 char *var;
576 int cfgFD, GoNo, NoGo = 0, ismine;
577
578 // Open and attach the config file
579 //
580 if ((cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
581 return eDest.Emsg("Config", errno, "open config file", ConfigFN);
582 Config.Attach(cfgFD);
583
584 // Indicate what we are about to do in the capture stream
585 //
586 static const char *cvec[] = { "*** xroot protocol config:", 0 };
587 Config.Capture(cvec);
588
589 // Process items
590 //
591 while((var = Config.GetMyFirstWord()))
592 { if ((ismine = !strncmp("xrootd.", var, 7)) && var[7]) var += 7;
593 else if ((ismine = !strcmp("all.export", var))) var += 4;
594 else if ((ismine = !strcmp("all.seclib", var))) var += 4;
595
596 if (ismine)
597 { if TS_Xeq("async", xasync);
598 else if TS_Xeq("bindif", xbif);
599 else if TS_Xeq("chksum", xcksum);
600 else if TS_Xeq("diglib", xdig);
601 else if TS_Xeq("export", xexp);
602 else if TS_Xeq("fslib", xfsl);
603 else if TS_Xeq("fsoverload", xfso);
604 else if TS_Xeq("gpflib", xgpf);
605 else if TS_Xeq("log", xlog);
606 else if TS_Xeq("mongstream", xmongs);
607 else if TS_Xeq("monitor", xmon);
608 else if TS_Zeq("pmark", XrdNetPMarkCfg::Parse);
609 else if TS_Xeq("prep", xprep);
610 else if TS_Xeq("redirect", xred);
611 else if TS_Xeq("redirlib", xrdl);
612 else if TS_Xeq("seclib", xsecl);
613 else if TS_Xeq("tls", xtls);
614 else if TS_Xeq("tlsreuse", xtlsr);
615 else if TS_Xeq("trace", xtrace);
616 else if TS_Xeq("limit", xlimit);
617 else {if (!strcmp(var, "pidpath"))
618 {eDest.Say("Config warning: 'xrootd.pidpath' no longer "
619 "supported; use 'all.pidpath'.");
620 } else {
621 eDest.Say("Config warning: ignoring unknown "
622 "directive '", var, "'.");
623 }
624 Config.Echo(false);
625 continue;
626 }
627 if (GoNo) {Config.Echo(); NoGo = 1;}
628 }
629 }
630
631// We now have to generate the correct TLS context if one was specified. Our
632// context must be of the non-verified kind as we don't accept certs.
633//
634 if (!NoGo && tlsCtx)
635 {tlsCtx = tlsCtx->Clone(false,true);
636 if (!tlsCtx)
637 {eDest.Say("Config failure: unable to setup TLS for protocol!");
638 NoGo = 1;
639 } else {
640 static const char *sessID = "xroots";
641 tlsCtx->SessionCache(tlsCache, sessID, 6);
642 }
643 }
644
645// Add our config to our environment and return
646//
647 return NoGo;
648}
649
650/******************************************************************************/
651/* P r i v a t e F u n c t i o n s */
652/******************************************************************************/
653/******************************************************************************/
654/* C h e c k T L S */
655/******************************************************************************/
656
657int XrdXrootdProtocol::CheckTLS(const char *tlsProt)
658{
659
660// If login specified, turn off session as it doesn't make sense together.
661//
662 if (myRole & kXR_tlsLogin) myRole &= ~kXR_tlsSess;
665
666// Turn off TPC TLS requirement if login or session is required to have TLS
667// However, that flag must remain to be set in the protocol response.
668//
671
672// If some authnetication protocols need TLS then we must requie that login
673// uses TLS. For incapable clients, we leave this alone as we will skip
674// TLS authnetication based protocols should the login phase not have TLS.
675//
676 if (tlsProt && !(tlsCap & Req_TLSLogin))
677 {eDest.Say("Config Authentication protocol(s)", tlsProt,
678 " require TLS; login now requires TLS.");
681 }
682
683// If there are any TLS requirements then TLS must have been configured.
684//
685 if (myRole & kXR_tlsAny && !tlsCtx)
686 {eDest.Say("Config failure: unable to honor TLS requirement; "
687 "TLS not configured!");
688 return 0;
689 }
690
691// All done
692//
693 return 1;
694}
695
696/******************************************************************************/
697/* C o n f i g F S */
698/******************************************************************************/
699
700bool XrdXrootdProtocol::ConfigFS(XrdOucEnv &xEnv, const char *cfn)
701{
702 const char *fsLoc;
703 int n;
704
705// The filesystem may need access to the list of valid checksums. We construct
706// here and place it in the local env.
707//
708 if (JobCKT) {
709 XrdOucString csList(1024);
710 XrdOucTList *tP = JobCKTLST;
711 do {
712 if (csList.length()) csList += ' ';
713 csList.append(tP->text);
714 tP = tP->next;
715 } while (tP);
716 if (csList.length()) xEnv.Put("csList", csList.c_str());
717 }
718
719// Get the filesystem to be used
720//
721 if (FSLib[0])
722 {TRACE(DEBUG, "Loading base filesystem library " <<FSLib[0]);
723 osFS = XrdXrootdloadFileSystem(&eDest, 0, FSLib[0], cfn, &xEnv);
724 fsLoc = FSLib[0];
725 } else {
726 osFS = XrdSfsGetDefaultFileSystem(0, eDest.logger(), cfn, &xEnv);
727 fsLoc = "default";
728 }
729
730// Make sure we have loaded something
731//
732 if (!osFS)
733 {eDest.Emsg("Config", "Unable to load base file system using", fsLoc);
734 return false;
735 }
736 if (FSLib[0]) osFS->EnvInfo(&xEnv);
737
738// If there is an old style wrapper, load it now.
739//
740 if (FSLib[1] && !ConfigFS(FSLib[1], xEnv, cfn)) return false;
741
742// Run through any other pushdowns
743//
744 if ((n = FSLPath.size()))
745 for (int i = 0; i < n; i++)
746 {if (!ConfigFS(FSLPath[i].c_str(), xEnv, cfn)) return false;}
747
748// Inform the statistics object which filesystem to use
749//
750 SI->setFS(osFS);
751
752// All done here
753//
754 return true;
755}
756
757/******************************************************************************/
758
759bool XrdXrootdProtocol::ConfigFS(const char *path, XrdOucEnv &xEnv,
760 const char *cfn)
761{
762
763// Try to load this wrapper library
764//
765 TRACE(DEBUG, "Loading wrapper filesystem library " <<path);
766 osFS = XrdXrootdloadFileSystem(&eDest, osFS, path, cfn, &xEnv);
767 if (!osFS)
768 {eDest.Emsg("Config", "Unable to load file system wrapper from", path);
769 return false;
770 }
771 osFS->EnvInfo(&xEnv);
772 return true;
773}
774
775/******************************************************************************/
776/* C o n f i g R e d i r P I */
777/******************************************************************************/
778
779bool XrdXrootdProtocol::ConfigRedirPI(const char *path, XrdOucEnv &xEnv,
780 const char *cfn, const char *parms)
781{
782
783// Try to load this wrapper library
784//
785 TRACE(DEBUG, "Loading redirect plugin library " <<path);
786 RedirPI = XrdXrootdloadRedirLib(&eDest, RedirPI, path, parms, cfn, &xEnv);
787 return RedirPI != 0;
788}
789
790/******************************************************************************/
791/* C o n f i g S e c u r i t y */
792/******************************************************************************/
793
794int XrdXrootdProtocol::ConfigSecurity(XrdOucEnv &xEnv, const char *cfn)
795{
796 XrdSecGetProt_t secGetProt = 0;
797 char idBuff[256];
798 int n;
799
800// Obtain our uid and username
801//
802 myUID = geteuid();
803 if ((n = XrdOucUtils::UidName(myUID, idBuff, sizeof(idBuff))))
804 {myUName = strdup(idBuff);
805 myUNLen = n;
806 }
807
808// Obtain our gid and groupname
809//
810 myGID = getegid();
811 if ((n = XrdOucUtils::GidName(myGID, idBuff, sizeof(idBuff))))
812 {myGName = strdup(idBuff);
813 myGNLen = n;
814 }
815
816// TLS support is independent of security per se. Record context, if any.
817//
818 if (tlsCtx) xEnv.PutPtr("XrdTLSContext*", (void *)tlsCtx);
819
820// Check if we need to load anything
821//
822 if (!SecLib)
823 {eDest.Say("Config warning: 'xrootd.seclib' not specified;"
824 " strong authentication disabled!");
825 xEnv.PutPtr("XrdSecGetProtocol*", (void *)0);
826 xEnv.PutPtr("XrdSecProtector*" , (void *)0);
827 return 1;
828 }
829
830// Blad some debugging info
831//
832 TRACE(DEBUG, "Loading security library " <<SecLib);
833
834// Load the security server
835//
836 if (!(CIA = XrdSecLoadSecService(&eDest, cfn,
837 (strcmp(SecLib,"default") ? SecLib : 0),
838 &secGetProt, &DHS)))
839 {eDest.Emsg("Config", "Unable to load security system.");
840 return 0;
841 }
842
843// Set environmental pointers
844//
845 xEnv.PutPtr("XrdSecGetProtocol*", (void *)secGetProt);
846 xEnv.PutPtr("XrdSecProtector*" , (void *)DHS);
847
848// If any protocol needs TLS then all logins must use TLS, ufortunately.
849//
850 const char *tlsProt = CIA->protTLS();
851 if (tlsProt) return CheckTLS(tlsProt);
852 return 1;
853}
854
855/******************************************************************************/
856/* x a s y n c */
857/******************************************************************************/
858
859/* Function: xasync
860
861 Purpose: To parse directive: async [limit <aiopl>] [maxsegs <msegs>]
862 [maxtot <mtot>] [segsize <segsize>]
863 [minsize <iosz>] [maxstalls <cnt>]
864 [timeout <tos>]
865 [Debug] [force] [syncw] [off]
866 [nocache] [nosf]
867
868 <aiopl> maximum number of async req per link. Default 8.
869 <msegs> maximum number of async ops per request. Default 8.
870 <mtot> maximum number of async ops per server. Default is 4096.
871 of maximum connection times aiopl divided by two.
872 <segsz> The aio segment size. This is the maximum size that data
873 will be read or written. The defaults to 64K but is
874 adjusted for each request to minimize latency.
875 <iosz> the minimum number of bytes that must be read or written
876 to allow async processing to occur (default is maxbsz/2
877 typically 1M).
878 <tos> second timeout for async I/O.
879 <cnt> Maximum number of client stalls before synchronous i/o is
880 used. Async mode is tried after <cnt> requests.
881 Debug Turns on async I/O for everything. This an internal
882 undocumented option used for testing purposes.
883 force Uses async i/o for all requests, even when not explicitly
884 requested (this is compatible with synchronous clients).
885 syncw Use synchronous i/o for write requests.
886 off Disables async i/o
887 nocache Disables async I/O is this is a caching proxy.
888 nosf Disables use of sendfile to send data to the client.
889
890 Output: 0 upon success or 1 upon failure.
891*/
892
893int XrdXrootdProtocol::xasync(XrdOucStream &Config)
894{
895 char *val;
896 int i, ppp;
897 int V_force=-1, V_syncw = -1, V_off = -1, V_mstall = -1, V_nosf = -1;
898 int V_limit=-1, V_msegs=-1, V_mtot=-1, V_minsz=-1, V_segsz=-1;
899 int V_minsf=-1, V_debug=-1, V_noca=-1, V_tmo=-1;
900 long long llp;
901 struct asyncopts {const char *opname; int minv; int *oploc;
902 const char *opmsg;} asopts[] =
903 {
904 {"Debug", -1, &V_debug, ""},
905 {"force", -1, &V_force, ""},
906 {"off", -1, &V_off, ""},
907 {"nocache", -1, &V_noca, ""},
908 {"nosf", -1, &V_nosf, ""},
909 {"syncw", -1, &V_syncw, ""},
910 {"limit", 0, &V_limit, "async limit"},
911 {"segsize", 4096, &V_segsz, "async segsize"},
912 {"timeout", 0, &V_tmo, "async timeout"},
913 {"maxsegs", 0, &V_msegs, "async maxsegs"},
914 {"maxstalls", 0, &V_mstall,"async maxstalls"},
915 {"maxtot", 0, &V_mtot, "async maxtot"},
916 {"minsfsz", 1, &V_minsf, "async minsfsz"},
917 {"minsize", 4096, &V_minsz, "async minsize"}};
918 int numopts = sizeof(asopts)/sizeof(struct asyncopts);
919
920 if (!(val = Config.GetWord()))
921 {eDest.Emsg("Config", "async option not specified"); return 1;}
922
923 while (val)
924 {for (i = 0; i < numopts; i++)
925 if (!strcmp(val, asopts[i].opname))
926 {if (asopts[i].minv >= 0 && !(val = Config.GetWord()))
927 {eDest.Emsg("Config","async",(char *)asopts[i].opname,
928 "value not specified");
929 return 1;
930 }
931 if (asopts[i].minv > 0)
932 if (XrdOuca2x::a2sz(eDest,asopts[i].opmsg, val, &llp,
933 (long long)asopts[i].minv)) return 1;
934 else *asopts[i].oploc = (int)llp;
935 else if (asopts[i].minv == 0)
936 if (XrdOuca2x::a2i(eDest,asopts[i].opmsg,val,&ppp,1))
937 return 1;
938 else *asopts[i].oploc = ppp;
939 else *asopts[i].oploc = 1;
940 break;
941 }
942 if (i >= numopts)
943 eDest.Emsg("Config", "Warning, invalid async option", val);
944 val = Config.GetWord();
945 }
946
947// Make sure max values are consistent
948//
949 if (V_limit > 0 && V_mtot > 0 && V_limit > V_mtot)
950 {eDest.Emsg("Config", "async limit may not be greater than maxtot");
951 return 1;
952 }
953
954// Calculate the actual segment size
955//
956 if (V_segsz > 0)
957 {i = BPool->Recalc(V_segsz);
958 if (!i) {eDest.Emsg("Config", "async segsize is too large"); return 1;}
959 if (i != V_segsz)
960 {char buff[64];
961 sprintf(buff, "%d readjusted to %d", V_segsz, i);
962 eDest.Emsg("Config", "async segsize", buff);
963 V_segsz = i;
964 }
965 }
966
967// Calculate actual timeout
968//
969 if (V_tmo >= 0)
970 {i = V_tmo;
971 if (V_tmo < 1) i = 1;
972 else if (V_tmo > 360) i = 360;
973 if (i != V_tmo)
974 {char buff[64];
975 sprintf(buff, "%d readjusted to %d", V_tmo, i);
976 eDest.Emsg("Config", "async timeout", buff);
977 V_tmo = i;
978 }
979 }
980
981// Establish async options
982//
983 if (V_limit > 0) as_maxperlnk = V_limit;
984 if (V_msegs > 0) as_maxperreq = V_msegs;
985 if (V_mtot > 0) as_maxpersrv = V_mtot;
986 if (V_minsz > 0) as_miniosz = V_minsz;
987 if (V_segsz > 0){as_segsize = V_segsz; as_seghalf = V_segsz/2;}
988 if (V_tmo >= 0) as_timeout = V_tmo;
989 if (V_mstall> 0) as_maxstalls = V_mstall;
990 if (V_debug > 0) asyncFlags |= asDebug;
991 if (V_force > 0) as_force = true;
992 if (V_off > 0) as_aioOK = false;
993 if (V_syncw > 0) as_syncw = true;
994 if (V_noca > 0) asyncFlags |= asNoCache;
995 if (V_nosf > 0) as_nosf = true;
996 if (V_minsf > 0) as_minsfsz = V_minsf;
997
998 return 0;
999}
1000
1001/******************************************************************************/
1002/* x b i f */
1003/******************************************************************************/
1004
1005/* Function: xbif
1006
1007 Purpose: To parse the directive: bindif <trg>
1008
1009 <trg>: <host>:<port>[%<prvhost>:<port>]] [<trg>]
1010*/
1011
1012namespace XrdXrootd
1013{
1014char *bifResp[2] = {0,0};
1015int bifRLen[2] = {0,0};
1016}
1017
1018int XrdXrootdProtocol::xbif(XrdOucStream &Config)
1019{
1020 static const int brSize = sizeof(XrdProto::bifReqs);
1021 using XrdXrootd::bifResp;
1022 using XrdXrootd::bifRLen;
1023
1024 XrdOucString bSpec[2];
1025 char *bHost[2], *val, buff[512];
1026 int bPort[2], thePort;
1027
1028// Cleanup any previous bif specification
1029//
1030 if (bifResp[1])
1031 {if (bifResp[1] != bifResp[0]) free(bifResp[1]);
1032 bifResp[1] = 0; bifRLen[1] = 0;
1033 }
1034 if (bifResp[0])
1035 {free(bifResp[0]);
1036 bifResp[0] = 0; bifRLen[0] = 0;
1037 }
1038
1039// Process all of the options
1040//
1041 while((val = Config.GetWord()) && *val)
1042 {if (!xred_php(val, bHost, bPort, "bindif", true)) return 1;
1043 for (int i = 0; i < 2 && bHost[i] != 0; i++)
1044 {thePort = (bPort[i] ? bPort[i] : XrdXrootdPort);
1045 snprintf(buff, sizeof(buff), "%s%s:%d",
1046 (bSpec[i].length() ? "," : ""), bHost[i], thePort);
1047 bSpec[i] += buff;
1048 }
1049 }
1050
1051// Generate the "b" record for each type of interface
1052//
1053 for (int i = 0; i < 2 && bSpec[i].length(); i++)
1054 {int n = brSize + bSpec[i].length() + 1;
1055 n = (n + 7) & ~7;
1056 XrdProto::bifReqs *bifRec = (XrdProto::bifReqs *)malloc(n);
1057 memset(bifRec, 0, n);
1058 bifRec->theTag = 'B';
1059 bifRec->bifILen = htons(static_cast<kXR_unt16>(n-brSize));
1060 strcpy(((char *)bifRec)+brSize, bSpec[i].c_str());
1061 bifResp[i] = (char *)bifRec;
1062 bifRLen[i] = n;
1063 }
1064
1065// Now complete the definition
1066//
1067 if (bifResp[0] && bifResp[1] == 0)
1068 {bifResp[1] = bifResp[0];
1069 bifRLen[1] = bifRLen[0];
1070 }
1071
1072// All done
1073//
1074 return 0;
1075}
1076
1077/******************************************************************************/
1078/* x c k s u m */
1079/******************************************************************************/
1080
1081/* Function: xcksum
1082
1083 Purpose: To parse the directive: chksum [chkcgi] [max <n>] <type> [<path>]
1084
1085 max maximum number of simultaneous jobs
1086 chkcgi Always check for checksum type in cgo info.
1087 <type> algorithm of checksum (e.g., md5). If more than one
1088 checksum is supported then they should be listed with
1089 each separated by a space.
1090 <path> the path of the program performing the checksum
1091 If no path is given, the checksum is local.
1092
1093 Output: 0 upon success or !0 upon failure.
1094*/
1095
1096int XrdXrootdProtocol::xcksum(XrdOucStream &Config)
1097{
1098 static XrdOucProg *theProg = 0;
1099 int (*Proc)(XrdOucStream *, char **, int) = 0;
1100 XrdOucTList *tP, *algFirst = 0, *algLast = 0;
1101 char *palg, prog[2048];
1102 int jmax = 4, anum[2] = {0,0};
1103
1104// Get the algorithm name and the program implementing it
1105//
1106 JobCKCGI = 0;
1107 while ((palg = Config.GetWord()) && *palg != '/')
1108 {if (!strcmp(palg,"chkcgi")) {JobCKCGI = 1; continue;}
1109 if (strcmp(palg, "max"))
1110 {XrdOucUtils::toLower(palg);
1111 XrdOucTList *xalg = new XrdOucTList(palg, anum); anum[0]++;
1112 if (algLast) algLast->next = xalg;
1113 else algFirst = xalg;
1114 algLast = xalg;
1115 continue;
1116 }
1117 if (!(palg = Config.GetWord()))
1118 {eDest.Emsg("Config", "chksum max not specified"); return 1;}
1119 if (XrdOuca2x::a2i(eDest, "chksum max", palg, &jmax, 0)) return 1;
1120 }
1121
1122// Verify we have an algoritm
1123//
1124 if (!algFirst)
1125 {eDest.Emsg("Config", "chksum algorithm not specified"); return 1;}
1126 if (JobCKT) free(JobCKT);
1127 JobCKT = strdup(algFirst->text);
1128
1129// Handle alternate checksums
1130//
1131 while((tP = JobCKTLST)) {JobCKTLST = tP->next; delete tP;}
1132 JobCKTLST = algFirst;
1133 if (algFirst->next) JobCKCGI = 2;
1134
1135// Handle program if we have one
1136//
1137 if (palg)
1138 {int n = strlen(palg);
1139 if (n+2 >= (int)sizeof(prog))
1140 {eDest.Emsg("Config", "cksum program too long"); return 1;}
1141 strcpy(prog, palg); palg = prog+n; *palg++ = ' '; n = sizeof(prog)-n-1;
1142 if (!Config.GetRest(palg, n))
1143 {eDest.Emsg("Config", "cksum parameters too long"); return 1;}
1144 } else *prog = 0;
1145
1146// Check if we have a program. If not, then this will be a local checksum and
1147// the algorithm will be verified after we load the filesystem.
1148//
1149 if (*prog) JobLCL = 0;
1150 else { JobLCL = 1; Proc = &CheckSum; strcpy(prog, "chksum");}
1151
1152// Set up the program and job
1153//
1154 if (!theProg) theProg = new XrdOucProg(0);
1155 if (theProg->Setup(prog, &eDest, Proc)) return 1;
1156 if (JobCKS) delete JobCKS;
1157 if (jmax) JobCKS = new XrdXrootdJob(Sched, theProg, "chksum", jmax);
1158 else JobCKS = 0;
1159 return 0;
1160}
1161
1162/******************************************************************************/
1163/* x d i g */
1164/******************************************************************************/
1165
1166/* Function: xdig
1167
1168 Purpose: To parse the directive: diglib * <parms>
1169
1170 * use builtin digfs library (only one supported now).
1171 parms parameters for digfs.
1172
1173 Output: 0 upon success or !0 upon failure.
1174*/
1175
1176int XrdXrootdProtocol::xdig(XrdOucStream &Config)
1177{
1178 char parms[4096], *val;
1179
1180// Get the path
1181//
1182 if (!(val = Config.GetWord()))
1183 {eDest.Emsg("Config", "diglib not specified"); return 1;}
1184
1185// Make sure it refers to an internal one
1186//
1187 if (strcmp(val, "*"))
1188 {eDest.Emsg("Config", "builtin diglib not specified"); return 1;}
1189
1190// Grab the parameters
1191//
1192 if (!Config.GetRest(parms, sizeof(parms)))
1193 {eDest.Emsg("Config", "diglib parameters too long"); return 1;}
1194 if (digParm) free(digParm);
1195 digParm = strdup(parms);
1196
1197// All done
1198//
1199 return 0;
1200}
1201
1202/******************************************************************************/
1203/* x e x p */
1204/******************************************************************************/
1205
1206/* Function: xexp
1207
1208 Purpose: To parse the directive: export <path> [lock|nolock] [mwfiles]
1209
1210 <path> the path to be exported.
1211
1212 Output: 0 upon success or !0 upon failure.
1213*/
1214
1215int XrdXrootdProtocol::xexp(XrdOucStream &Config)
1216{
1217 char *val, pbuff[1024];
1218 int popt = 0;
1219
1220// Get the path
1221//
1222 val = Config.GetWord();
1223 if (!val || !val[0])
1224 {eDest.Emsg("Config", "export path not specified"); return 1;}
1225 strlcpy(pbuff, val, sizeof(pbuff));
1226
1227// Get export lock option
1228//
1229 while((val = Config.GetWord()))
1230 { if (!strcmp( "nolock", val)) popt |= XROOTDXP_NOLK;
1231 else if (!strcmp( "lock", val)) popt &= ~XROOTDXP_NOLK;
1232 else if (!strcmp("mwfiles", val)) popt |= XROOTDXP_NOMWCHK;
1233 else {Config.RetToken(); break;}
1234 }
1235
1236// Add path to configuration
1237//
1238 return xexpdo(pbuff, popt);
1239}
1240
1241/******************************************************************************/
1242
1243int XrdXrootdProtocol::xexpdo(char *path, int popt)
1244{
1245 char *opaque;
1246 int xopt;
1247
1248// Check if we are exporting a generic name
1249//
1250 if (*path == '*')
1252 if (*(path+1))
1253 {if (*(path+1) == '?') popt &= ~XROOTDXP_NOCGI;
1254 else {eDest.Emsg("Config","invalid export path -",path);return 1;}
1255 }
1256 XPList.Set(popt, path);
1257 return 0;
1258 }
1259
1260// Make sure path start with a slash
1261//
1262 if (rpCheck(path, &opaque))
1263 {eDest.Emsg("Config", "non-absolute export path -", path); return 1;}
1264
1265// Record the path
1266//
1267 if (!(xopt = Squash(path)) || xopt != (popt|XROOTDXP_OK))
1268 XPList.Insert(path, popt);
1269 return 0;
1270}
1271
1272/******************************************************************************/
1273/* x f s l */
1274/******************************************************************************/
1275
1276/* Function: xfsl
1277
1278 Purpose: To parse the directive: fslib [throttle | [-2] <fspath2>]
1279 {default | [-2] <fspath1>}
1280 | ++ <fspath2>
1281
1282 -2 Uses version2 of the plugin initializer.
1283 This is ignored now because it's always done.
1284 ++ Pushes a wrapper onto the library stack.
1285 throttle load libXrdThrottle.so as the head interface.
1286 <fspath2> load the named library as the head interface.
1287 default load libXrdOfs.so ro libXrdPss.so as the tail
1288 interface. This is the default.
1289 <fspath1> load the named library as the tail interface.
1290
1291 Output: 0 upon success or !0 upon failure.
1292*/
1293
1294int XrdXrootdProtocol::xfsl(XrdOucStream &Config)
1295{
1296 char *val;
1297
1298// Get the path
1299//
1300 if (!(val = Config.GetWord()))
1301 {eDest.Emsg("Config", "fslib not specified"); return 1;}
1302
1303// First check for a psuhdown
1304//
1305 if (!strcmp("++", val))
1306 {if (!(val = Config.GetWord()))
1307 {eDest.Emsg("Config", "fslib wrapper not specified"); return 1;}
1308 if (strcmp("throttle", val)) FSLPath.push_back((std::string)val);
1309 else FSLPath.push_back("libXrdThrottle.so");
1310 return 0;
1311 }
1312
1313// Clear storage pointers
1314//
1315 if (FSLib[0]) {free(FSLib[0]); FSLib[0] = 0;}
1316 if (FSLib[1]) {free(FSLib[1]); FSLib[1] = 0;}
1317
1318// Check if this is "thottle"
1319//
1320 if (!strcmp("throttle", val))
1321 {FSLib[1] = strdup("libXrdThrottle.so");
1322 if (!(val = Config.GetWord()))
1323 {eDest.Emsg("Config","fslib throttle target library not specified");
1324 return 1;
1325 }
1326 return xfsL(Config, val, 0);
1327 }
1328
1329// Check for default or default library, the common case
1330//
1331 if (xfsL(Config, val, 1)) return 1;
1332 if (!FSLib[1]) return 0;
1333
1334// If we dont have another token, then demote the previous library
1335//
1336 if (!(val = Config.GetWord()))
1337 {FSLib[0] = FSLib[1]; FSLib[1] = 0;
1338 return 0;
1339 }
1340
1341// Check for default or default library, the common case
1342//
1343 return xfsL(Config, val, 0);
1344}
1345
1346/******************************************************************************/
1347
1348int XrdXrootdProtocol::xfsL(XrdOucStream &Config, char *val, int lix)
1349{
1350 char *Slash;
1351
1352// Check if this is a version token
1353//
1354 if (!strcmp(val, "-2"))
1355 {if (!(val = Config.GetWord()))
1356 {eDest.Emsg("Config", "fslib not specified"); return 1;}
1357 }
1358
1359// We will play fast and furious with the syntax as "default" should not be
1360// prefixed with a version number but will let that pass.
1361//
1362 if (!strcmp("default", val)) return 0;
1363
1364// If this is the "standard" name tell the user that we are ignoring this lib.
1365// Otherwise, record the path and return.
1366//
1367 if (!(Slash = rindex(val, '/'))) Slash = val;
1368 else Slash++;
1369 if (!strcmp(Slash, "libXrdOfs.so"))
1370 eDest.Say("Config warning: 'fslib libXrdOfs.so' is actually built-in.");
1371 else FSLib[lix] = strdup(val);
1372 return 0;
1373}
1374
1375/******************************************************************************/
1376/* x f s o */
1377/******************************************************************************/
1378
1379/* Function: xfso
1380
1381 Purpose: To parse the directive: fsoverload [options]
1382
1383 options: [[no]bypass] [redirect <host>:<port>[%<prvhost>:<port>]]
1384 [stall <sec>]
1385
1386 bypass If path is a forwarding path, redirect client to the
1387 location specified in the path to bypass this server.
1388 The default is nobypass.
1389 redirect Redirect the request to the specified destination.
1390 stall Stall the client <sec> seconds. The default is 33.
1391*/
1392
1393int XrdXrootdProtocol::xfso(XrdOucStream &Config)
1394{
1395 static const int rHLen = 264;
1396 char rHost[2][rHLen], *hP[2] = {0,0}, *val;
1397 int rPort[2], bypass = -1, stall = -1;
1398
1399// Process all of the options
1400//
1401 while((val = Config.GetWord()) && *val)
1402 { if (!strcmp(val, "bypass")) bypass = 1;
1403 else if (!strcmp(val, "nobypass")) bypass = 0;
1404 else if (!strcmp(val, "redirect"))
1405 {val = Config.GetWord();
1406 if (!xred_php(val, hP, rPort, "redirect")) return 1;
1407 for (int i = 0; i < 2; i++)
1408 {if (!hP[i]) rHost[i][0] = 0;
1409 else {strlcpy(rHost[i], hP[i], rHLen);
1410 hP[i] = rHost[i];
1411 }
1412 }
1413 }
1414 else if (!strcmp(val, "stall"))
1415 {if (!(val = Config.GetWord()) || !(*val))
1416 {eDest.Emsg("Config", "stall value not specified");
1417 return 1;
1418 }
1419 if (XrdOuca2x::a2tm(eDest,"stall",val,&stall,0,32767))
1420 return 1;
1421 }
1422 else {eDest.Emsg("config","invalid fsoverload option",val); return 1;}
1423 }
1424
1425// Set all specified values
1426//
1427 if (bypass >= 0) OD_Bypass = (bypass ? true : false);
1428 if (stall >= 0) OD_Stall = stall;
1429 if (hP[0])
1430 {if (Route[RD_ovld].Host[0]) free(Route[RD_ovld].Host[0]);
1431 if (Route[RD_ovld].Host[1]) free(Route[RD_ovld].Host[1]);
1432 Route[RD_ovld].Host[0] = strdup(hP[0]);
1433 Route[RD_ovld].Port[0] = rPort[0];
1434 Route[RD_ovld].RDSz[0] = strlen(hP[0]);
1435 if (hP[1])
1436 {Route[RD_ovld].Host[1] = strdup(hP[1]);
1437 Route[RD_ovld].Port[1] = rPort[1];
1438 Route[RD_ovld].RDSz[1] = strlen(hP[1]);
1439 } else {
1440 Route[RD_ovld].Host[1] = Route[RD_ovld].Host[0];
1441 Route[RD_ovld].Port[1] = Route[RD_ovld].Port[0];
1442 Route[RD_ovld].RDSz[1] = Route[RD_ovld].RDSz[0];
1443 }
1444 OD_Redir = true;
1445 } else OD_Redir = false;
1446
1447 return 0;
1448}
1449
1450/******************************************************************************/
1451/* x g p f */
1452/******************************************************************************/
1453
1454/* Function: xgpf
1455
1456 Purpose: To parse the directive: gpflib <path> <parms>
1457
1458 <path> library path to use or default to use the builtin one.
1459 parms optional parameters.
1460
1461 Output: 0 upon success or !0 upon failure.
1462*/
1463
1464int XrdXrootdProtocol::xgpf(XrdOucStream &Config)
1465{
1466 char parms[4096], *val;
1467
1468// Remove any previous parameters
1469//
1470 if (gpfLib) {free(gpfLib); gpfLib = 0;}
1471 if (gpfParm) {free(gpfParm); gpfParm = 0;}
1472
1473// Get the path
1474//
1475 if (!(val = Config.GetWord()))
1476 {eDest.Emsg("Config", "gpflib not specified"); return 1;}
1477
1478// If this refers to out default, then keep the library pointer nil
1479//
1480 if (strcmp(val, "default")) gpfLib = strdup(val);
1481
1482// Grab the parameters
1483//
1484 if (!Config.GetRest(parms, sizeof(parms)))
1485 {eDest.Emsg("Config", "gpflib parameters too long"); return 1;}
1486 gpfParm = strdup(parms);
1487
1488// All done
1489//
1490 return 0;
1491}
1492
1493/******************************************************************************/
1494/* x l o g */
1495/******************************************************************************/
1496
1497/* Function: xlog
1498
1499 Purpose: To parse the directive: log <events>
1500
1501 <events> the blank separated list of events to log.
1502
1503 Output: 0 upon success or 1 upon failure.
1504*/
1505
1506int XrdXrootdProtocol::xlog(XrdOucStream &Config)
1507{
1508 char *val;
1509 static struct logopts {const char *opname; int opval;} lgopts[] =
1510 {
1511 {"all", -1},
1512 {"disc", SYS_LOG_02},
1513 {"login", SYS_LOG_01}
1514 };
1515 int i, neg, lgval = -1, numopts = sizeof(lgopts)/sizeof(struct logopts);
1516
1517 if (!(val = Config.GetWord()))
1518 {eDest.Emsg("config", "log option not specified"); return 1;}
1519 while (val)
1520 {if ((neg = (val[0] == '-' && val[1]))) val++;
1521 for (i = 0; i < numopts; i++)
1522 {if (!strcmp(val, lgopts[i].opname))
1523 {if (neg) lgval &= ~lgopts[i].opval;
1524 else lgval |= lgopts[i].opval;
1525 break;
1526 }
1527 }
1528 if (i >= numopts) eDest.Emsg("config","invalid log option",val);
1529 val = Config.GetWord();
1530 }
1531 eDest.setMsgMask(lgval);
1532 return 0;
1533}
1534
1535/******************************************************************************/
1536/* x p r e p */
1537/******************************************************************************/
1538
1539/* Function: xprep
1540
1541 Purpose: To parse the directive: prep [keep <sec>] [scrub <sec>]
1542 [logdir <path>]
1543 keep <sec> time (seconds, M, H) to keep logdir entries.
1544 scrub <sec> time (seconds, M, H) between logdir scrubs.
1545 logdir <path> the absolute path to the prepare log directory.
1546
1547 Output: 0 upon success or !0 upon failure. Ignored by master.
1548*/
1549int XrdXrootdProtocol::xprep(XrdOucStream &Config)
1550{ int rc, keep = 0, scrub=0;
1551 char *ldir=0,*val,buff[1024];
1552
1553 if (!(val = Config.GetWord()))
1554 {eDest.Emsg("Config", "prep options not specified"); return 1;}
1555
1556 do { if (!strcmp("keep", val))
1557 {if (!(val = Config.GetWord()))
1558 {eDest.Emsg("Config", "prep keep value not specified");
1559 return 1;
1560 }
1561 if (XrdOuca2x::a2tm(eDest,"prep keep int",val,&keep,1)) return 1;
1562 }
1563 else if (!strcmp("scrub", val))
1564 {if (!(val = Config.GetWord()))
1565 {eDest.Emsg("Config", "prep scrub value not specified");
1566 return 1;
1567 }
1568 if (XrdOuca2x::a2tm(eDest,"prep scrub",val,&scrub,0)) return 1;
1569 }
1570 else if (!strcmp("logdir", val))
1571 {if (!(ldir = Config.GetWord()))
1572 {eDest.Emsg("Config", "prep logdir value not specified");
1573 return 1;
1574 }
1575 }
1576 else eDest.Emsg("Config", "Warning, invalid prep option", val);
1577 } while((val = Config.GetWord()));
1578
1579// Set the values
1580//
1581 if (scrub || keep) XrdXrootdPrepare::setParms(scrub, keep);
1582 if (ldir)
1583 if ((rc = XrdOucUtils::genPath(buff, sizeof(buff), ldir, myInst)) < 0
1584 || (rc = XrdOucUtils::makePath(buff, XrdOucUtils::pathMode)) < 0
1585 || (rc = XrdXrootdPrepare::setParms(buff)) < 0)
1586 {eDest.Emsg("Config", rc, "process logdir", ldir);
1587 return 1;
1588 }
1589 return 0;
1590}
1591
1592/******************************************************************************/
1593/* x r d l */
1594/******************************************************************************/
1595
1596/* Function: xrdl
1597
1598 Purpose: To parse the directive: redirlib [++] [<opts>] <libpath> [<parm>]
1599
1600 ++ Pushes a wrapper onto the library stack.
1601 <opts> Options:
1602 +iphold <time>
1603 <libpath> load the named library as the head interface.
1604 <parms> optional parameters
1605
1606 Output: 0 upon success or !0 upon failure.
1607*/
1608
1609int XrdXrootdProtocol::xrdl(XrdOucStream &Config)
1610{
1611 char *val;
1612 char pbuff[4096];
1613
1614// Get the path
1615//
1616 if (!(val = Config.GetWord()))
1617 {eDest.Emsg("Config", "redirlib path not specified"); return 1;}
1618
1619// First check for a psuhdown
1620//
1621 if (!strcmp("++", val))
1622 {if (!(val = Config.GetWord()))
1623 {eDest.Emsg("Config", "redrilib wrapper not specified"); return 1;}
1624 if (RDLPath.empty())
1625 {eDest.Emsg("Config", "base redrilib not specified"); return 1;}
1626 if (*val == '+' && !(val = xrdlopt(Config, val))) return 1;
1627 RDLPath.push_back((std::string)val);
1628 if (!Config.GetRest(pbuff, sizeof(pbuff)))
1629 {eDest.Emsg("Config", "redirlib parameters too long"); return 1;}
1630 RDLParm.push_back((std::string)pbuff);
1631 return 0;
1632 } else if (*val == '+' && !(val = xrdlopt(Config, val))) return 1;
1633
1634// This is either a base library specification or a replacement
1635//
1636 if (RDLPath.empty()) RDLPath.push_back((std::string)val);
1637 else RDLPath[0] = val;
1638
1639// Get the optional parameters
1640//
1641 if (!Config.GetRest(pbuff, sizeof(pbuff)))
1642 {eDest.Emsg("Config", "redirlib parameters too long"); return 1;}
1643 if (RDLParm.empty()) RDLParm.push_back((std::string)pbuff);
1644 else RDLParm[0] = pbuff;
1645
1646// All done
1647//
1648 return 0;
1649}
1650
1651/******************************************************************************/
1652/* x r d r o p t */
1653/******************************************************************************/
1654
1655char* XrdXrootdProtocol::xrdlopt(XrdOucStream &Config, char* val)
1656{
1657 int num;
1658
1659// Check for valid options
1660//
1661do{if (!strcmp(val, "+iphold"))
1662 {if (!(val = Config.GetWord()))
1663 {eDest.Emsg("Config", "+iphold value not specified"); return 0;}
1664 if (XrdOuca2x::a2tm(eDest,"redirlib iphold",val,&num,0)) return 0;
1665 redirIPHold = num;
1666 }
1667 } while((val = Config.GetWord()) && *val == '+');
1668
1669// All done
1670//
1671 return val;
1672}
1673
1674/******************************************************************************/
1675/* x r e d */
1676/******************************************************************************/
1677
1678/* Function: xred
1679
1680 Purpose: To parse the directive: redirect <host>:<port>[%<prvhost>:<port>]
1681 {<funcs>|[?]<path>} |
1682 client <domlist>
1683
1684 <funcs> are one or more of the following functions that will
1685 be immediately redirected to <host>:<port>. Each function
1686 may be prefixed by a minus sign to disable redirection.
1687
1688 chmod dirlist locate mkdir mv prepare rm rmdir stat
1689
1690 <paths> redirects the client when an attempt is made to open
1691 one of absolute <paths>. Up to 4 different redirect
1692 combinations may be specified. When prefixed by "?"
1693 then the redirect applies to any operation on the path
1694 that results in an ENOENT error.
1695
1696 <domlist> {private | local | .<domain>} [<domlist>]
1697
1698 Output: 0 upon success or !0 upon failure.
1699*/
1700
1701int XrdXrootdProtocol::xred(XrdOucStream &Config)
1702{
1703 static struct rediropts {const char *opname; RD_func opval;} rdopts[] =
1704 {
1705 {"chmod", RD_chmod},
1706 {"chksum", RD_chksum},
1707 {"dirlist", RD_dirlist},
1708 {"locate", RD_locate},
1709 {"mkdir", RD_mkdir},
1710 {"mv", RD_mv},
1711 {"openw", RD_openw},
1712 {"prepare", RD_prepare},
1713 {"prepstage",RD_prepstg},
1714 {"rm", RD_rm},
1715 {"rmdir", RD_rmdir},
1716 {"stat", RD_stat},
1717 {"trunc", RD_trunc}
1718 };
1719 static const int rHLen = 264;
1720 char rHost[2][rHLen], *hP[2], *val;
1721 int i, k, neg, numopts = sizeof(rdopts)/sizeof(struct rediropts);
1722 int rPort[2], isQ = 0;
1723
1724// Get the host and port
1725//
1726 val = Config.GetWord();
1727 if (!xred_php(val, hP, rPort, "redirect")) return 1;
1728
1729// Copy out he values as the target variable will be lost
1730//
1731 for (i = 0; i < 2; i++)
1732 {if (!hP[i]) rHost[i][0] = 0;
1733 else {strlcpy(rHost[i], hP[i], rHLen);
1734 hP[i] = rHost[i];
1735 }
1736 }
1737
1738// Set all redirect target functions
1739//
1740 if (!(val = Config.GetWord()))
1741 {eDest.Emsg("config", "redirect option not specified"); return 1;}
1742
1743// Handle the client option
1744//
1745 if (!strcmp("client", val)) return xred_clnt(Config, hP, rPort);
1746
1747 if (*val == '/' || (isQ = ((*val == '?') || !strcmp(val,"enoent"))))
1748 {if (isQ)
1749 {RQLxist = 1;
1750 if (!(val = Config.GetWord()))
1751 {eDest.Emsg("Config", "redirect path not specified.");
1752 return 1;
1753 }
1754 if (*val != '/')
1755 {eDest.Emsg("Config", "non-absolute redirect path -", val);
1756 return 1;
1757 }
1758 }
1759 for (k = static_cast<int>(RD_open1); k < RD_Num; k++)
1760 if (xred_xok(k, hP, rPort)) break;
1761 if (k >= RD_Num)
1762 {eDest.Emsg("Config", "too many different path redirects"); return 1;}
1763 xred_set(RD_func(k), hP, rPort);
1764 do {if (isQ) RQList.Insert(val, k, 0);
1765 else RPList.Insert(val, k, 0);
1766 if ((val = Config.GetWord()) && *val != '/')
1767 {eDest.Emsg("Config", "non-absolute redirect path -", val);
1768 return 1;
1769 }
1770 } while(val);
1771 return 0;
1772 }
1773
1774 while (val)
1775 {if (!strcmp(val, "all"))
1776 {for (i = 0; i < numopts; i++)
1777 xred_set(rdopts[i].opval, hP, rPort);
1778 }
1779 else {if ((neg = (val[0] == '-' && val[1]))) val++;
1780 for (i = 0; i < numopts; i++)
1781 {if (!strcmp(val, rdopts[i].opname))
1782 {if (neg) xred_set(rdopts[i].opval, 0, 0);
1783 else xred_set(rdopts[i].opval, hP, rPort);
1784 break;
1785 }
1786 }
1787 if (i >= numopts)
1788 eDest.Emsg("config", "invalid redirect option", val);
1789 }
1790 val = Config.GetWord();
1791 }
1792 return 0;
1793}
1794
1795/******************************************************************************/
1796
1797int XrdXrootdProtocol::xred_clnt(XrdOucStream &Config,char *hP[2],int rPort[2])
1798{
1799 static const int maxDom = sizeof(RouteClient.Domain)/sizeof(char*);
1800 char *val;
1801
1802// Reset values
1803//
1804 if (CL_Redir)
1805 {for (int i = 0; i < RouteClient.DomCnt; i++)
1806 {if (RouteClient.Domain[i]) free(RouteClient.Domain[i]);}
1807 }
1808 for (int i = 0; i < maxDom; i++) RouteClient.Domain[i] = 0;
1809 RouteClient.DomCnt = 0;
1810 RouteClient.pvtIP = false;
1811 RouteClient.lclDom = false;
1812 CL_Redir = true;
1813
1814// Process arguments
1815//
1816 if (!(val = Config.GetWord()))
1817 {eDest.Emsg("Config", "redirect client argument not specified.");
1818 return 1;
1819 }
1820
1821 while(val)
1822 { if (!strcmp("private", val)) RouteClient.pvtIP = true;
1823 else if (!strcmp("local", val)) RouteClient.lclDom = true;
1824 else if (*val == '.')
1825 {if (RouteClient.DomCnt >= maxDom)
1826 {eDest.Emsg("Config",
1827 "Too many redirect client domains specified.");
1828 return 1;
1829 }
1830 RouteClient.Domain[RouteClient.DomCnt++] = strdup(val);
1831 }
1832 else {eDest.Emsg("Config", "Invalid redirect client domain -", val);
1833 return 1;
1834 }
1835 val = Config.GetWord();
1836 }
1837
1838// Set the host parameters
1839//
1840 xred_set(RD_client, hP, rPort);
1841 return 0;
1842}
1843
1844/******************************************************************************/
1845
1846bool XrdXrootdProtocol::xred_php(char *val, char *hP[2], int rPort[2],
1847 const char *what, bool optport)
1848{
1849 XrdNetAddr testAddr;
1850 char *pp;
1851
1852// Make sure we have a value
1853//
1854 if (!val || !(*val))
1855 {eDest.Emsg("config", what, "argument not specified"); return false;}
1856
1857// Check if we have two hosts here
1858//
1859 hP[0] = val;
1860 if (!(pp = index(val, '%'))) hP[1] = 0;
1861 else {hP[1] = pp+1; *pp = 0;}
1862
1863// Verify corectness here
1864//
1865 if (!(*val) || (hP[1] && !*hP[1]))
1866 {eDest.Emsg("Config", "malformed", what, "host specification");
1867 return false;
1868 }
1869
1870// Process the hosts
1871//
1872 for (int i = 0; i < 2; i++)
1873 {if (!(val = hP[i])) break;
1874 if (!val || !val[0] || val[0] == ':')
1875 {eDest.Emsg("Config", what, "host not specified"); return false;}
1876 if ((pp = rindex(val, ':')))
1877 {if ((rPort[i] = XrdOuca2x::a2p(eDest, "tcp", pp+1, false)) <= 0)
1878 return false;
1879 *pp = '\0';
1880 } else {
1881 if (optport) rPort[i] = 0;
1882 else {eDest.Emsg("Config", what, "port not specified");
1883 return false;
1884 }
1885 }
1886 const char *eText = testAddr.Set(val, 0);
1887 if (eText)
1888 {if (XrdNetAddrInfo::isHostName(val) && !strncmp(eText,"Dynamic",7))
1889 eDest.Say("Config warning: ", eText, " as ", val);
1890 else {eDest.Say("Config failure: ", what, " target ", val,
1891 " is invalid; ", eText);
1892 return false;
1893 }
1894 }
1895 }
1896
1897// All done
1898//
1899 return true;
1900}
1901
1902void XrdXrootdProtocol::xred_set(RD_func func, char *rHost[2], int rPort[2])
1903{
1904
1905// Reset static redirection
1906//
1907 if (Route[func].Host[0]) free(Route[func].Host[0]);
1908 if (Route[func].Host[0] != Route[func].Host[1]) free(Route[func].Host[1]);
1909
1910 if (rHost)
1911 {Route[func].Host[0] = strdup(rHost[0]);
1912 Route[func].Port[0] = rPort[0];
1913 } else {
1914 Route[func].Host[0] = Route[func].Host[1] = 0;
1915 Route[func].Port[0] = Route[func].Port[1] = 0;
1916 return;
1917 }
1918
1919 if (!rHost[1])
1920 {Route[func].Host[1] = Route[func].Host[0];
1921 Route[func].Port[1] = Route[func].Port[0];
1922 } else {
1923 Route[func].Host[1] = strdup(rHost[1]);
1924 Route[func].Port[1] = rPort[1];
1925 }
1926}
1927
1928bool XrdXrootdProtocol::xred_xok(int func, char *rHost[2], int rPort[2])
1929{
1930 if (!Route[func].Host[0]) return true;
1931
1932 if (strcmp(Route[func].Host[0], rHost[0])
1933 || Route[func].Port[0] != rPort[0]) return false;
1934
1935 if (!rHost[1]) return Route[func].Host[0] == Route[func].Host[1];
1936
1937 if (strcmp(Route[func].Host[1], rHost[1])
1938 || Route[func].Port[1] != rPort[1]) return false;
1939
1940 return true;
1941}
1942
1943/******************************************************************************/
1944/* x s e c l */
1945/******************************************************************************/
1946
1947/* Function: xsecl
1948
1949 Purpose: To parse the directive: seclib {default | <path>}
1950
1951 <path> the path of the security library to be used.
1952 "default" uses the default security library.
1953
1954 Output: 0 upon success or !0 upon failure.
1955*/
1956
1957int XrdXrootdProtocol::xsecl(XrdOucStream &Config)
1958{
1959 char *val;
1960
1961// Get the path
1962//
1963 val = Config.GetWord();
1964 if (!val || !val[0])
1965 {eDest.Emsg("Config", "seclib argument not specified"); return 1;}
1966
1967// Record the path
1968//
1969 if (SecLib) free(SecLib);
1970 SecLib = strdup(val);
1971 return 0;
1972}
1973
1974/******************************************************************************/
1975/* x t l s */
1976/******************************************************************************/
1977
1978/* Function: xtls
1979
1980topPurpose: To parse the directive: tls [capable] <reqs>
1981
1982 capable Enforce TLS requirements only for TLS capable clients.
1983 Otherwise, TLS is enforced for all clients.
1984 <reqs> are one or more of the following tls requirements. Each
1985 may be prefixed by a minus sign to disable it. Note
1986 this directive is cummalitive.
1987
1988 all Requires all of the below.
1989 data All bound sockets must use TLS. When specified,
1990 session is implied unless login is specified.
1991 gpfile getile and putfile requests must use TLS
1992 login Logins and all subsequent requests must use TLS
1993 none Turns all requirements off (default).
1994 off Synonym for none.
1995 session All requests after login must use TLS
1996 tpc Third party copy requests must use TLS
1997
1998 Output: 0 upon success or !0 upon failure.
1999*/
2000
2001int XrdXrootdProtocol::xtls(XrdOucStream &Config)
2002{
2003 static const int Req_TLSAll = Req_TLSData|Req_TLSLogin|Req_TLSTPC;
2004 static struct enforceopts {const char *opname; int opval; int enval;}
2005 enfopts[] =
2006 {
2007 {"all", kXR_tlsAny, Req_TLSAll},
2008 {"data", kXR_tlsData, Req_TLSData},
2009 {"gpfile", kXR_tlsGPF, Req_TLSGPFile},
2010 {"login", kXR_tlsLogin, Req_TLSLogin},
2011 {"session", kXR_tlsSess, Req_TLSSess},
2012 {"tpc", kXR_tlsTPC, Req_TLSTPC}
2013 };
2014 char *val;
2015 int i, numopts = sizeof(enfopts)/sizeof(struct enforceopts);
2016 bool neg, forall = true;
2017
2018 if (!(val = Config.GetWord()))
2019 {eDest.Emsg("config", "tls parameter not specified"); return 1;}
2020
2021 if (!strcmp("capable", val))
2022 {forall = false;
2023 if (!(val = Config.GetWord()))
2024 {eDest.Emsg("config", "tls requirement not specified"); return 1;}
2025 }
2026
2027 while (val)
2028 {if (!strcmp(val, "off") || !strcmp(val, "none"))
2029 {myRole &= ~kXR_tlsAny;
2030 if (forall) tlsCap = tlsNot = 0;
2031 else tlsCap = 0;
2032 } else {
2033 if ((neg = (val[0] == '-' && val[1]))) val++;
2034 for (i = 0; i < numopts; i++)
2035 {if (!strcmp(val, enfopts[i].opname))
2036 {if (neg) myRole &= ~enfopts[i].opval;
2037 else myRole |= enfopts[i].opval;
2038 if (neg) tlsCap &= ~enfopts[i].enval;
2039 else tlsCap |= enfopts[i].enval;
2040 if (forall)
2041 {if (neg) tlsNot &= ~enfopts[i].enval;
2042 else tlsNot |= enfopts[i].enval;
2043 }
2044 break;
2045 }
2046 }
2047 if (i >= numopts)
2048 {eDest.Emsg("config", "Invalid tls requirement -", val);
2049 return 1;
2050 }
2051 }
2052 val = Config.GetWord();
2053 }
2054
2055// If data needs TLS but the session does not, then force session TLS
2056//
2057 if ((myRole & kXR_tlsData) && !(myRole & (kXR_tlsLogin | kXR_tlsSess)))
2059 if ((tlsCap & kXR_tlsData) && !(tlsCap & (Req_TLSLogin | Req_TLSSess)))
2061 if ((tlsNot & kXR_tlsData) && !(tlsNot & (Req_TLSLogin | Req_TLSSess)))
2063
2064// Do final resolution on the settins
2065//
2066 return (CheckTLS(0) ? 0 : 1);
2067}
2068
2069/******************************************************************************/
2070/* x t l s r */
2071/******************************************************************************/
2072
2073/* Function: xtlsr
2074
2075 Purpose: To parse the directive: tlsreuse off | on [flush <ft>[h|m|s]]
2076
2077 off turns off the TLS session reuse cache.
2078 on turns on the TLS session reuse cache.
2079 <ft> sets the cache flush frequency. the default is set
2080 by the TLS libraries and is typically connection count.
2081
2082 Output: 0 upon success or !0 upon failure.
2083*/
2084
2085int XrdXrootdProtocol::xtlsr(XrdOucStream &Config)
2086{
2087 char *val;
2088 int num;
2089
2090// Get the argument
2091//
2092 val = Config.GetWord();
2093 if (!val || !val[0])
2094 {eDest.Emsg("Config", "tlsreuse argument not specified"); return 1;}
2095
2096// If it's off, we set it off
2097//
2098 if (!strcmp(val, "off"))
2100 return 0;
2101 }
2102
2103// If it's on we may need more to do
2104//
2105 if (!strcmp(val, "on"))
2106 {if (!tlsCtx) {eDest.Emsg("Config warning:", "Ignoring "
2107 "'tlsreuse on'; TLS not configured!");
2108 return 0;
2109 }
2111 if (!(val = Config.GetWord())) return 0;
2112 if (!strcmp(val, "flush" ))
2113 {if (!(val = Config.GetWord()))
2114 {eDest.Emsg("Config", "tlsreuse flush value not specified");
2115 return 1;
2116 }
2117 if (XrdOuca2x::a2tm(eDest,"tlsreuse flush",val,&num,1)) return 1;
2118 if (num < 60) num = 60;
2119 else if (num > XrdTlsContext::scFMax)
2121 tlsCache |= num;
2122 }
2123 }
2124
2125// We have a bad keyword
2126//
2127 eDest.Emsg("config", "Invalid tlsreuse option -", val);
2128 return 1;
2129}
2130
2131/******************************************************************************/
2132/* x t r a c e */
2133/******************************************************************************/
2134
2135/* Function: xtrace
2136
2137 Purpose: To parse the directive: trace <events>
2138
2139 <events> the blank separated list of events to trace. Trace
2140 directives are cummalative.
2141
2142 Output: 0 upon success or 1 upon failure.
2143*/
2144
2145int XrdXrootdProtocol::xtrace(XrdOucStream &Config)
2146{
2147 char *val;
2148 static struct traceopts {const char *opname; int opval;} tropts[] =
2149 {
2150 {"all", TRACE_ALL},
2151 {"auth", TRACE_AUTH},
2152 {"debug", TRACE_DEBUG},
2153 {"emsg", TRACE_EMSG},
2154 {"fs", TRACE_FS},
2155 {"fsaio", TRACE_FSAIO},
2156 {"fsio", TRACE_FSIO},
2157 {"login", TRACE_LOGIN},
2158 {"mem", TRACE_MEM},
2159 {"pgcserr", TRACE_PGCS},
2160 {"redirect", TRACE_REDIR},
2161 {"request", TRACE_REQ},
2162 {"response", TRACE_RSP},
2163 {"stall", TRACE_STALL}
2164 };
2165 int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
2166
2167 if (!(val = Config.GetWord()))
2168 {eDest.Emsg("config", "trace option not specified"); return 1;}
2169 while (val)
2170 {if (!strcmp(val, "off")) trval = 0;
2171 else {if ((neg = (val[0] == '-' && val[1]))) val++;
2172 for (i = 0; i < numopts; i++)
2173 {if (!strcmp(val, tropts[i].opname))
2174 {if (neg) trval &= ~tropts[i].opval;
2175 else trval |= tropts[i].opval;
2176 break;
2177 }
2178 }
2179 if (i >= numopts)
2180 eDest.Emsg("config", "invalid trace option", val);
2181 }
2182 val = Config.GetWord();
2183 }
2184 XrdXrootdTrace.What = trval;
2185 return 0;
2186}
2187
2188/******************************************************************************/
2189/* x l i m i t */
2190/******************************************************************************/
2191
2192/* Function: xlimit
2193
2194 Purpose: To parse the directive: limit [prepare <count>] [noerror]
2195
2196 prepare <count> The maximum number of prepares that are allowed
2197 during the course of a single connection
2198
2199 noerror When possible, do not issue an error when a limit
2200 is hit.
2201
2202 Output: 0 upon success or 1 upon failure.
2203*/
2204int XrdXrootdProtocol::xlimit(XrdOucStream &Config)
2205{
2206 int plimit = -1;
2207 const char *word;
2208
2209// Look for various limits set
2210//
2211 while ( (word = Config.GetWord()) ) {
2212 if (!strcmp(word, "prepare")) {
2213 if (!(word = Config.GetWord()))
2214 {
2215 eDest.Emsg("Config", "'limit prepare' value not specified");
2216 return 1;
2217 }
2218 if (XrdOuca2x::a2i(eDest, "limit prepare", word, &plimit, 0)) { return 1; }
2219 } else if (!strcmp(word, "noerror")) {
2220 LimitError = false;
2221 }
2222 }
2223 if (plimit >= 0) {PrepareLimit = plimit;}
2224 return 0;
2225}
#define kXR_isManager
#define kXR_tlsLogin
#define kXR_suppgrw
#define kXR_attrMeta
#define kXR_haveTLS
#define kXR_anongpf
#define kXR_tlsAny
#define kXR_tlsTPC
#define kXR_isServer
#define kXR_attrCache
#define kXR_attrProxy
#define kXR_LBalServer
#define kXR_tlsGPF
#define kXR_supposc
#define kXR_tlsSess
#define kXR_DataServer
#define kXR_supgpf
#define kXR_tlsData
unsigned short kXR_unt16
Definition XPtypes.hh:67
#define DEBUG(x)
#define TS_Xeq(x, m)
Definition XrdConfig.cc:160
static XrdSysLogger Logger
static XrdSysError eDest(0,"crypto_")
XrdSfsFileSystem * XrdDigGetFS(XrdSfsFileSystem *native_fs, XrdSysLogger *lp, const char *cFN, const char *parms)
Definition XrdDigFS.cc:105
#define TRACE_AUTH
#define TRACE_REQ
#define TRACE_RSP
#define TRACE_REDIR
XrdSfsFileSystem * XrdSfsGetDefaultFileSystem(XrdSfsFileSystem *native_fs, XrdSysLogger *lp, const char *configfn, XrdOucEnv *EnvInfo)
Definition XrdOfsFS.cc:49
#define open
Definition XrdPosix.hh:78
XrdSecProtocol *(* XrdSecGetProt_t)(const char *hostname, XrdNetAddrInfo &endPoint, XrdSecParameters &sectoken, XrdOucErrInfo *einfo)
Typedef to simplify the encoding of methods returning XrdSecProtocol.
XrdSecService * XrdSecLoadSecService(XrdSysError *eDest, const char *cfn, const char *seclib, XrdSecGetProt_t *getP, XrdSecProtector **proP)
#define SFS_OK
const int SYS_LOG_02
const int SYS_LOG_01
size_t strlcpy(char *dst, const char *src, size_t sz)
#define TRACE_DEBUG
Definition XrdTrace.hh:36
#define TRACE_MEM
Definition XrdTrace.hh:38
#define TRACE(act, x)
Definition XrdTrace.hh:63
#define TRACE_ALL
Definition XrdTrace.hh:35
XrdSysTrace XrdXrootdTrace
const char * XrdXrootdInstance
XrdXrootdPrepare * XrdXrootdPrepQ
XrdSfsFileSystem * XrdXrootdloadFileSystem(XrdSysError *, XrdSfsFileSystem *, const char *, const char *, XrdOucEnv *)
XrdSfsFileSystem * XrdSfsGetDefaultFileSystem(XrdSfsFileSystem *nativeFS, XrdSysLogger *Logger, const char *configFn, XrdOucEnv *EnvInfo)
Definition XrdOfsFS.cc:49
XrdXrootdRedirPI * XrdXrootdloadRedirLib(XrdSysError *, XrdXrootdRedirPI *, const char *, const char *, const char *, XrdOucEnv *)
#define TS_Zeq(x, m)
XrdOucString * XrdXrootdCF
int XrdXrootdPort
#define TRACE_FS
#define TRACE_FSAIO
#define TRACE_FSIO
#define TRACE_PGCS
#define TRACE_LOGIN
#define TRACE_EMSG
#define TRACE_STALL
#define XROOTDXP_OK
#define XROOTDXP_NOLK
#define XROOTDXP_NOSLASH
#define XROOTDXP_NOMWCHK
#define XROOTDXP_NOCGI
static XrdNetIF netIF
Definition XrdInet.hh:68
static bool isHostName(const char *name)
const char * Set(const char *hSpec, int pNum=PortInSpec)
void Display(const char *pfx="=====> ")
Definition XrdNetIF.cc:142
int Port()
Definition XrdNetIF.hh:276
static int Parse(XrdSysError *eLog, XrdOucStream &Config)
static XrdNetPMark * Config(XrdSysError *eLog, XrdScheduler *sched, XrdSysTrace *trc, bool &fatal)
static XrdNetSocket * Create(XrdSysError *Say, const char *path, const char *fn, mode_t mode, int isudp=0)
long GetInt(const char *varname)
Definition XrdOucEnv.cc:235
char * Get(const char *varname)
Definition XrdOucEnv.hh:69
static int Export(const char *Var, const char *Val)
Definition XrdOucEnv.cc:170
void * GetPtr(const char *varname)
Definition XrdOucEnv.cc:263
void PutPtr(const char *varname, void *value)
Definition XrdOucEnv.cc:298
void Put(const char *varname, const char *value)
Definition XrdOucEnv.hh:85
int Setup(const char *prog, XrdSysError *errP=0, int(*Proc)(XrdOucStream *, char **, int)=0)
int length() const
void append(const int i)
const char * c_str() const
XrdOucTList * next
static const mode_t pathMode
static char * genPath(const char *path, const char *inst, const char *psfx=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)
static int makePath(char *path, mode_t mode, bool reset=false)
static void toLower(char *str)
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition XrdOuca2x.cc:45
static int a2sz(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
Definition XrdOuca2x.cc:257
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
Definition XrdOuca2x.cc:288
static int a2p(XrdSysError &, const char *ptype, const char *val, bool anyOK=true)
Definition XrdOuca2x.cc:140
const char * myName
XrdBuffManager * BPool
XrdScheduler * Sched
XrdTlsContext * tlsCtx
const char * AdmPath
XrdSysError * eDest
XrdOucString * totalCF
XrdOucEnv * theEnv
const char * myInst
XrdSysLogger * logger(XrdSysLogger *lp=0)
XrdTlsContext * Clone(bool full=true, bool startCRLRefresh=false)
int SessionCache(int opts=scNone, const char *id=0, int idlen=0)
static const int scNone
Do not change any option settings.
static const int scOff
Turn off cache.
static const int scFMax
static const int scSrvr
Turn on cache server mode (default).
static int Init(XrdSysError *erp, XrdNetSocket *asock)
static void addJob(const char *jname, XrdXrootdJob *jp)
static void setVals(XrdSysError *erp, XrdXrootdStats *SIp, XrdScheduler *schp, int port)
static void Init(XrdXrootdFileLock *lp, XrdSysError *erP, bool sfok)
static int setParms(int stime, int skeep)
static XrdXrootdStats * SI
static const char * myInst
static XrdSfsFileSystem * digFS
static XrdNetPMark * PMark
static XrdXrootdXPath RPList
static XrdNetSocket * AdminSock
static const char Req_TLSGPFile
static const char Req_TLSSess
static XrdXrootdJob * JobCKS
static XrdSysError & eDest
static XrdXrootdRedirPI * RedirPI
static const char * myCName
static const char Req_TLSData
static XrdXrootdFileLock * Locker
static const char Req_TLSTPC
static XrdTlsContext * tlsCtx
static XrdXrootdXPath XPList
static XrdScheduler * Sched
static struct XrdXrootdProtocol::RC_Table RouteClient
static const char * myUName
static const char Req_TLSLogin
static int Configure(char *parms, XrdProtocol_Config *pi)
static XrdOucTList * JobCKTLST
static XrdXrootdXPath RQList
static struct XrdXrootdProtocol::RD_Table Route[RD_Num]
static XrdSecProtector * DHS
static XrdBuffManager * BPool
static XrdSecService * CIA
static const char * myGName
static uint64_t fsFeatures
static XrdOucReqID * PrepID
static XrdSfsFileSystem * osFS
static void Init(XrdXrootdRedirPI *pi, XrdSysError *eDest, int ipHold)
static void Init(XrdScheduler *schedP, int qMax, int qTTL)
Perform one-time initialization.
XrdXrootdXPath * Next()
struct ServerResponseBifs_Protocol bifReqs
static const int maxRvecsz
Definition XProtocol.hh:722
static const uint64_t hasPGRW
Feature: pgRead and pgWrite.
static const uint64_t hasPRP2
Feature: Prepare Handler Version 2 (different calling conventions).
static const uint64_t hasGPFA
Feature: gpFile anonymous.
static const uint64_t hasCACH
Feature: Implements a data cache.
static const uint64_t hasNOSF
Feature: Supports no sendfile.
static const uint64_t hasPOSC
Feature: Persist On Successful Close.
static const uint64_t hasGPF
Feature: gpFile.
static const uint64_t hasNAIO
Feature: Supports no async I/O.
static const uint64_t hasPRXY
Feature: Proxy Server.
XrdXrootdStats * SI
XrdScheduler * Sched
char * bifResp[2]
XrdBuffManager * BPool