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 {"prepare", RD_prepare},
1689 {"prepstage",RD_prepstg},
1690 {"rm", RD_rm},
1691 {"rmdir", RD_rmdir},
1692 {"stat", RD_stat},
1693 {"trunc", RD_trunc}
1694 };
1695 static const int rHLen = 264;
1696 char rHost[2][rHLen], *hP[2], *val;
1697 int i, k, neg, numopts = sizeof(rdopts)/sizeof(struct rediropts);
1698 int rPort[2], isQ = 0;
1699
1700// Get the host and port
1701//
1702 val = Config.GetWord();
1703 if (!xred_php(val, hP, rPort, "redirect")) return 1;
1704
1705// Copy out he values as the target variable will be lost
1706//
1707 for (i = 0; i < 2; i++)
1708 {if (!hP[i]) rHost[i][0] = 0;
1709 else {strlcpy(rHost[i], hP[i], rHLen);
1710 hP[i] = rHost[i];
1711 }
1712 }
1713
1714// Set all redirect target functions
1715//
1716 if (!(val = Config.GetWord()))
1717 {eDest.Emsg("config", "redirect option not specified"); return 1;}
1718
1719// Handle the client option
1720//
1721 if (!strcmp("client", val)) return xred_clnt(Config, hP, rPort);
1722
1723 if (*val == '/' || (isQ = ((*val == '?') || !strcmp(val,"enoent"))))
1724 {if (isQ)
1725 {RQLxist = 1;
1726 if (!(val = Config.GetWord()))
1727 {eDest.Emsg("Config", "redirect path not specified.");
1728 return 1;
1729 }
1730 if (*val != '/')
1731 {eDest.Emsg("Config", "non-absolute redirect path -", val);
1732 return 1;
1733 }
1734 }
1735 for (k = static_cast<int>(RD_open1); k < RD_Num; k++)
1736 if (xred_xok(k, hP, rPort)) break;
1737 if (k >= RD_Num)
1738 {eDest.Emsg("Config", "too many different path redirects"); return 1;}
1739 xred_set(RD_func(k), hP, rPort);
1740 do {if (isQ) RQList.Insert(val, k, 0);
1741 else RPList.Insert(val, k, 0);
1742 if ((val = Config.GetWord()) && *val != '/')
1743 {eDest.Emsg("Config", "non-absolute redirect path -", val);
1744 return 1;
1745 }
1746 } while(val);
1747 return 0;
1748 }
1749
1750 while (val)
1751 {if (!strcmp(val, "all"))
1752 {for (i = 0; i < numopts; i++)
1753 xred_set(rdopts[i].opval, hP, rPort);
1754 }
1755 else {if ((neg = (val[0] == '-' && val[1]))) val++;
1756 for (i = 0; i < numopts; i++)
1757 {if (!strcmp(val, rdopts[i].opname))
1758 {if (neg) xred_set(rdopts[i].opval, 0, 0);
1759 else xred_set(rdopts[i].opval, hP, rPort);
1760 break;
1761 }
1762 }
1763 if (i >= numopts)
1764 eDest.Emsg("config", "invalid redirect option", val);
1765 }
1766 val = Config.GetWord();
1767 }
1768 return 0;
1769}
1770
1771/******************************************************************************/
1772
1773int XrdXrootdProtocol::xred_clnt(XrdOucStream &Config,char *hP[2],int rPort[2])
1774{
1775 static const int maxDom = sizeof(RouteClient.Domain)/sizeof(char*);
1776 char *val;
1777
1778// Reset values
1779//
1780 if (CL_Redir)
1781 {for (int i = 0; i < RouteClient.DomCnt; i++)
1782 {if (RouteClient.Domain[i]) free(RouteClient.Domain[i]);}
1783 }
1784 for (int i = 0; i < maxDom; i++) RouteClient.Domain[i] = 0;
1785 RouteClient.DomCnt = 0;
1786 RouteClient.pvtIP = false;
1787 RouteClient.lclDom = false;
1788 CL_Redir = true;
1789
1790// Process arguments
1791//
1792 if (!(val = Config.GetWord()))
1793 {eDest.Emsg("Config", "redirect client argument not specified.");
1794 return 1;
1795 }
1796
1797 while(val)
1798 { if (!strcmp("private", val)) RouteClient.pvtIP = true;
1799 else if (!strcmp("local", val)) RouteClient.lclDom = true;
1800 else if (*val == '.')
1801 {if (RouteClient.DomCnt >= maxDom)
1802 {eDest.Emsg("Config",
1803 "Too many redirect client domains specified.");
1804 return 1;
1805 }
1806 RouteClient.Domain[RouteClient.DomCnt++] = strdup(val);
1807 }
1808 else {eDest.Emsg("Config", "Invalid redirect client domain -", val);
1809 return 1;
1810 }
1811 val = Config.GetWord();
1812 }
1813
1814// Set the host parameters
1815//
1816 xred_set(RD_client, hP, rPort);
1817 return 0;
1818}
1819
1820/******************************************************************************/
1821
1822bool XrdXrootdProtocol::xred_php(char *val, char *hP[2], int rPort[2],
1823 const char *what, bool optport)
1824{
1825 XrdNetAddr testAddr;
1826 char *pp;
1827
1828// Make sure we have a value
1829//
1830 if (!val || !(*val))
1831 {eDest.Emsg("config", what, "argument not specified"); return false;}
1832
1833// Check if we have two hosts here
1834//
1835 hP[0] = val;
1836 if (!(pp = index(val, '%'))) hP[1] = 0;
1837 else {hP[1] = pp+1; *pp = 0;}
1838
1839// Verify corectness here
1840//
1841 if (!(*val) || (hP[1] && !*hP[1]))
1842 {eDest.Emsg("Config", "malformed", what, "host specification");
1843 return false;
1844 }
1845
1846// Process the hosts
1847//
1848 for (int i = 0; i < 2; i++)
1849 {if (!(val = hP[i])) break;
1850 if (!val || !val[0] || val[0] == ':')
1851 {eDest.Emsg("Config", what, "host not specified"); return false;}
1852 if ((pp = rindex(val, ':')))
1853 {if ((rPort[i] = XrdOuca2x::a2p(eDest, "tcp", pp+1, false)) <= 0)
1854 return false;
1855 *pp = '\0';
1856 } else {
1857 if (optport) rPort[i] = 0;
1858 else {eDest.Emsg("Config", what, "port not specified");
1859 return false;
1860 }
1861 }
1862 const char *eText = testAddr.Set(val, 0);
1863 if (eText)
1864 {if (XrdNetAddrInfo::isHostName(val) && !strncmp(eText,"Dynamic",7))
1865 eDest.Say("Config warning: ", eText, " as ", val);
1866 else {eDest.Say("Config failure: ", what, " target ", val,
1867 " is invalid; ", eText);
1868 return false;
1869 }
1870 }
1871 }
1872
1873// All done
1874//
1875 return true;
1876}
1877
1878void XrdXrootdProtocol::xred_set(RD_func func, char *rHost[2], int rPort[2])
1879{
1880
1881// Reset static redirection
1882//
1883 if (Route[func].Host[0]) free(Route[func].Host[0]);
1884 if (Route[func].Host[0] != Route[func].Host[1]) free(Route[func].Host[1]);
1885
1886 if (rHost)
1887 {Route[func].Host[0] = strdup(rHost[0]);
1888 Route[func].Port[0] = rPort[0];
1889 } else {
1890 Route[func].Host[0] = Route[func].Host[1] = 0;
1891 Route[func].Port[0] = Route[func].Port[1] = 0;
1892 return;
1893 }
1894
1895 if (!rHost[1])
1896 {Route[func].Host[1] = Route[func].Host[0];
1897 Route[func].Port[1] = Route[func].Port[0];
1898 } else {
1899 Route[func].Host[1] = strdup(rHost[1]);
1900 Route[func].Port[1] = rPort[1];
1901 }
1902}
1903
1904bool XrdXrootdProtocol::xred_xok(int func, char *rHost[2], int rPort[2])
1905{
1906 if (!Route[func].Host[0]) return true;
1907
1908 if (strcmp(Route[func].Host[0], rHost[0])
1909 || Route[func].Port[0] != rPort[0]) return false;
1910
1911 if (!rHost[1]) return Route[func].Host[0] == Route[func].Host[1];
1912
1913 if (strcmp(Route[func].Host[1], rHost[1])
1914 || Route[func].Port[1] != rPort[1]) return false;
1915
1916 return true;
1917}
1918
1919/******************************************************************************/
1920/* x s e c l */
1921/******************************************************************************/
1922
1923/* Function: xsecl
1924
1925 Purpose: To parse the directive: seclib {default | <path>}
1926
1927 <path> the path of the security library to be used.
1928 "default" uses the default security library.
1929
1930 Output: 0 upon success or !0 upon failure.
1931*/
1932
1933int XrdXrootdProtocol::xsecl(XrdOucStream &Config)
1934{
1935 char *val;
1936
1937// Get the path
1938//
1939 val = Config.GetWord();
1940 if (!val || !val[0])
1941 {eDest.Emsg("Config", "seclib argument not specified"); return 1;}
1942
1943// Record the path
1944//
1945 if (SecLib) free(SecLib);
1946 SecLib = strdup(val);
1947 return 0;
1948}
1949
1950/******************************************************************************/
1951/* x t l s */
1952/******************************************************************************/
1953
1954/* Function: xtls
1955
1956topPurpose: To parse the directive: tls [capable] <reqs>
1957
1958 capable Enforce TLS requirements only for TLS capable clients.
1959 Otherwise, TLS is enforced for all clients.
1960 <reqs> are one or more of the following tls requirements. Each
1961 may be prefixed by a minus sign to disable it. Note
1962 this directive is cummalitive.
1963
1964 all Requires all of the below.
1965 data All bound sockets must use TLS. When specified,
1966 session is implied unless login is specified.
1967 gpfile getile and putfile requests must use TLS
1968 login Logins and all subsequent requests must use TLS
1969 none Turns all requirements off (default).
1970 off Synonym for none.
1971 session All requests after login must use TLS
1972 tpc Third party copy requests must use TLS
1973
1974 Output: 0 upon success or !0 upon failure.
1975*/
1976
1977int XrdXrootdProtocol::xtls(XrdOucStream &Config)
1978{
1979 static const int Req_TLSAll = Req_TLSData|Req_TLSLogin|Req_TLSTPC;
1980 static struct enforceopts {const char *opname; int opval; int enval;}
1981 enfopts[] =
1982 {
1983 {"all", kXR_tlsAny, Req_TLSAll},
1984 {"data", kXR_tlsData, Req_TLSData},
1985 {"gpfile", kXR_tlsGPF, Req_TLSGPFile},
1986 {"login", kXR_tlsLogin, Req_TLSLogin},
1987 {"session", kXR_tlsSess, Req_TLSSess},
1988 {"tpc", kXR_tlsTPC, Req_TLSTPC}
1989 };
1990 char *val;
1991 int i, numopts = sizeof(enfopts)/sizeof(struct enforceopts);
1992 bool neg, forall = true;
1993
1994 if (!(val = Config.GetWord()))
1995 {eDest.Emsg("config", "tls parameter not specified"); return 1;}
1996
1997 if (!strcmp("capable", val))
1998 {forall = false;
1999 if (!(val = Config.GetWord()))
2000 {eDest.Emsg("config", "tls requirement not specified"); return 1;}
2001 }
2002
2003 while (val)
2004 {if (!strcmp(val, "off") || !strcmp(val, "none"))
2005 {myRole &= ~kXR_tlsAny;
2006 if (forall) tlsCap = tlsNot = 0;
2007 else tlsCap = 0;
2008 } else {
2009 if ((neg = (val[0] == '-' && val[1]))) val++;
2010 for (i = 0; i < numopts; i++)
2011 {if (!strcmp(val, enfopts[i].opname))
2012 {if (neg) myRole &= ~enfopts[i].opval;
2013 else myRole |= enfopts[i].opval;
2014 if (neg) tlsCap &= ~enfopts[i].enval;
2015 else tlsCap |= enfopts[i].enval;
2016 if (forall)
2017 {if (neg) tlsNot &= ~enfopts[i].enval;
2018 else tlsNot |= enfopts[i].enval;
2019 }
2020 break;
2021 }
2022 }
2023 if (i >= numopts)
2024 {eDest.Emsg("config", "Invalid tls requirement -", val);
2025 return 1;
2026 }
2027 }
2028 val = Config.GetWord();
2029 }
2030
2031// If data needs TLS but the session does not, then force session TLS
2032//
2033 if ((myRole & kXR_tlsData) && !(myRole & (kXR_tlsLogin | kXR_tlsSess)))
2035 if ((tlsCap & kXR_tlsData) && !(tlsCap & (Req_TLSLogin | Req_TLSSess)))
2037 if ((tlsNot & kXR_tlsData) && !(tlsNot & (Req_TLSLogin | Req_TLSSess)))
2039
2040// Do final resolution on the settins
2041//
2042 return (CheckTLS(0) ? 0 : 1);
2043}
2044
2045/******************************************************************************/
2046/* x t l s r */
2047/******************************************************************************/
2048
2049/* Function: xtlsr
2050
2051 Purpose: To parse the directive: tlsreuse off | on [flush <ft>[h|m|s]]
2052
2053 off turns off the TLS session reuse cache.
2054 on turns on the TLS session reuse cache.
2055 <ft> sets the cache flush frequency. the default is set
2056 by the TLS libraries and is typically connection count.
2057
2058 Output: 0 upon success or !0 upon failure.
2059*/
2060
2061int XrdXrootdProtocol::xtlsr(XrdOucStream &Config)
2062{
2063 char *val;
2064 int num;
2065
2066// Get the argument
2067//
2068 val = Config.GetWord();
2069 if (!val || !val[0])
2070 {eDest.Emsg("Config", "tlsreuse argument not specified"); return 1;}
2071
2072// If it's off, we set it off
2073//
2074 if (!strcmp(val, "off"))
2076 return 0;
2077 }
2078
2079// If it's on we may need more to do
2080//
2081 if (!strcmp(val, "on"))
2082 {if (!tlsCtx) {eDest.Emsg("Config warning:", "Ignoring "
2083 "'tlsreuse on'; TLS not configured!");
2084 return 0;
2085 }
2087 if (!(val = Config.GetWord())) return 0;
2088 if (!strcmp(val, "flush" ))
2089 {if (!(val = Config.GetWord()))
2090 {eDest.Emsg("Config", "tlsreuse flush value not specified");
2091 return 1;
2092 }
2093 if (XrdOuca2x::a2tm(eDest,"tlsreuse flush",val,&num,1)) return 1;
2094 if (num < 60) num = 60;
2095 else if (num > XrdTlsContext::scFMax)
2097 tlsCache |= num;
2098 }
2099 }
2100
2101// We have a bad keyword
2102//
2103 eDest.Emsg("config", "Invalid tlsreuse option -", val);
2104 return 1;
2105}
2106
2107/******************************************************************************/
2108/* x t r a c e */
2109/******************************************************************************/
2110
2111/* Function: xtrace
2112
2113 Purpose: To parse the directive: trace <events>
2114
2115 <events> the blank separated list of events to trace. Trace
2116 directives are cummalative.
2117
2118 Output: 0 upon success or 1 upon failure.
2119*/
2120
2121int XrdXrootdProtocol::xtrace(XrdOucStream &Config)
2122{
2123 char *val;
2124 static struct traceopts {const char *opname; int opval;} tropts[] =
2125 {
2126 {"all", TRACE_ALL},
2127 {"auth", TRACE_AUTH},
2128 {"debug", TRACE_DEBUG},
2129 {"emsg", TRACE_EMSG},
2130 {"fs", TRACE_FS},
2131 {"fsaio", TRACE_FSAIO},
2132 {"fsio", TRACE_FSIO},
2133 {"login", TRACE_LOGIN},
2134 {"mem", TRACE_MEM},
2135 {"pgcserr", TRACE_PGCS},
2136 {"redirect", TRACE_REDIR},
2137 {"request", TRACE_REQ},
2138 {"response", TRACE_RSP},
2139 {"stall", TRACE_STALL}
2140 };
2141 int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
2142
2143 if (!(val = Config.GetWord()))
2144 {eDest.Emsg("config", "trace option not specified"); return 1;}
2145 while (val)
2146 {if (!strcmp(val, "off")) trval = 0;
2147 else {if ((neg = (val[0] == '-' && val[1]))) val++;
2148 for (i = 0; i < numopts; i++)
2149 {if (!strcmp(val, tropts[i].opname))
2150 {if (neg) trval &= ~tropts[i].opval;
2151 else trval |= tropts[i].opval;
2152 break;
2153 }
2154 }
2155 if (i >= numopts)
2156 eDest.Emsg("config", "invalid trace option", val);
2157 }
2158 val = Config.GetWord();
2159 }
2160 XrdXrootdTrace.What = trval;
2161 return 0;
2162}
2163
2164/******************************************************************************/
2165/* x l i m i t */
2166/******************************************************************************/
2167
2168/* Function: xlimit
2169
2170 Purpose: To parse the directive: limit [prepare <count>] [noerror]
2171
2172 prepare <count> The maximum number of prepares that are allowed
2173 during the course of a single connection
2174
2175 noerror When possible, do not issue an error when a limit
2176 is hit.
2177
2178 Output: 0 upon success or 1 upon failure.
2179*/
2180int XrdXrootdProtocol::xlimit(XrdOucStream &Config)
2181{
2182 int plimit = -1;
2183 const char *word;
2184
2185// Look for various limits set
2186//
2187 while ( (word = Config.GetWord()) ) {
2188 if (!strcmp(word, "prepare")) {
2189 if (!(word = Config.GetWord()))
2190 {
2191 eDest.Emsg("Config", "'limit prepare' value not specified");
2192 return 1;
2193 }
2194 if (XrdOuca2x::a2i(eDest, "limit prepare", word, &plimit, 0)) { return 1; }
2195 } else if (!strcmp(word, "noerror")) {
2196 LimitError = false;
2197 }
2198 }
2199 if (plimit >= 0) {PrepareLimit = plimit;}
2200 return 0;
2201}
#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
XrdOucTrace * XrdXrootdTrace
#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
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:686
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