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