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