XRootD
Loading...
Searching...
No Matches
XrdConfig.cc
Go to the documentation of this file.
1/*******************************************************************************/
2/* */
3/* X r d C o n f i g . c c */
4/* */
5/* (c) 2011 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/*
31 The default port number comes from:
32 1) The command line option,
33 2) The config file,
34 3) The /etc/services file for service corresponding to the program name.
35*/
36
37#include <unistd.h>
38#include <cctype>
39#include <fcntl.h>
40#include <pwd.h>
41#include <cstdint>
42#include <string>
43#include <cstring>
44#include <cstdio>
45#include <sys/param.h>
46#include <sys/resource.h>
47#include <sys/types.h>
48#include <sys/stat.h>
49#include <sys/un.h>
50#include <algorithm>
51#include <limits>
52
53#include "XrdVersion.hh"
54
55#include "Xrd/XrdBuffer.hh"
56#include "Xrd/XrdBuffXL.hh"
57#include "Xrd/XrdConfig.hh"
58#include "Xrd/XrdInet.hh"
59#include "Xrd/XrdInfo.hh"
60#include "Xrd/XrdLink.hh"
61#include "Xrd/XrdLinkCtl.hh"
62#include "Xrd/XrdPoll.hh"
63#include "Xrd/XrdScheduler.hh"
64#include "Xrd/XrdStats.hh"
65#include "Xrd/XrdTrace.hh"
66
67#include "XrdNet/XrdNetAddr.hh"
69#include "XrdNet/XrdNetIF.hh"
72#include "XrdNet/XrdNetUtils.hh"
73
74#include "XrdOuc/XrdOuca2x.hh"
75#include "XrdOuc/XrdOucEnv.hh"
81#include "XrdOuc/XrdOucUtils.hh"
82
83#include "XrdSys/XrdSysError.hh"
84#include "XrdSys/XrdSysFD.hh"
87#include "XrdSys/XrdSysTimer.hh"
88#include "XrdSys/XrdSysUtils.hh"
89
90#include "XrdTcpMonPin.hh"
91
92#include "XrdTls/XrdTls.hh"
94
95#if defined(__linux__) || defined(__GNU__)
96#include <netinet/tcp.h>
97#endif
98#if defined(__linux__)
99#include <sys/epoll.h>
100#endif
101#ifdef __APPLE__
102#include <AvailabilityMacros.h>
103#endif
104
105/******************************************************************************/
106/* G l o b a l O b j e c t s */
107/******************************************************************************/
108
109namespace XrdGlobal
110{
112extern XrdSysLogger Logger;
114extern XrdSysTrace XrdTrace;
115extern XrdScheduler Sched;
117extern XrdTlsContext *tlsCtx;
118extern XrdInet *XrdNetTCP;
119extern XrdBuffXL xlBuff;
120extern XrdTcpMonPin *TcpMonPin;
121extern int devNull;
122};
123
124using namespace XrdGlobal;
125
127{
128extern int ka_Idle;
129extern int ka_Itvl;
130extern int ka_Icnt;
131extern int udpRefr;
132
134};
135
136/******************************************************************************/
137/* F i l e L o c a l O b j e c t s */
138/******************************************************************************/
139
140namespace
141{
142XrdOucEnv theEnv;
143XrdVERSIONINFODEF(myVer, Xrd, XrdVNUMBER, XrdVERSION);
144bool SSLmsgs = true;
145
146void TlsError(const char *tid, const char *msg, bool sslmsg)
147 {if (!sslmsg || SSLmsgs) XrdGlobal::Log.Emsg("TLS", tid, msg);}
148};
149
150/******************************************************************************/
151/* S t a t i c M e m b e r s */
152/******************************************************************************/
153
154 const char *XrdConfig::TraceID = "Config";
155
156/******************************************************************************/
157/* d e f i n e s */
158/******************************************************************************/
159
160#define TS_Xeq(x,m) if (!strcmp(x,var)) return m(eDest, Config);
161
162#ifndef S_IAMB
163#define S_IAMB 0x1FF
164#endif
165
166/******************************************************************************/
167/* L o c a l C l a s s e s */
168/******************************************************************************/
169/******************************************************************************/
170/* X r d C o n f i g P r o t */
171/******************************************************************************/
172
174{
175public:
176
180char *parms;
181
183union {int port;
185 };
186union {bool dotls;
188 };
189
190bool AddPort(int pnum, bool isTLS)
191 {for (int i = 0; i < numP; i++)
192 if (pnum == portVec[i])
193 {tlsVec[i] = isTLS; return true;}
194 if (numP >= (XrdProtLoad::PortoMax)) return false;
195 portVec[numP] = pnum; tlsVec[numP] = isTLS;
196 numP++;
197 return true;
198 }
199
200void Reset(char *ln, char *pp, int np=-1, bool to=false)
201 {if (libpath) free(libpath);
202 libpath = ln;
203 if (parms) free(parms);
204 parms = pp;
205 memset(portVec, 0, sizeof(portVec));
206 port = np;
207 memset(tlsVec, 0, sizeof(tlsVec));
208 dotls = to;
209 numP = 1;
210 }
211
212 XrdConfigProt(char *pn, char *ln, char *pp, int np=-1,
213 bool to=false)
214 : Next(0), proname(pn), libpath(ln), parms(pp), numP(1)
215 {memset(portVec, 0, sizeof(portVec)); port = np;
216 memset(tlsVec, 0, sizeof(tlsVec)); dotls = to;
217 }
218
220 {free(proname);
221 if (libpath) free(libpath);
222 if (parms) free(parms);
223 }
224};
225
226/******************************************************************************/
227/* X r d T c p M o n I n f o */
228/******************************************************************************/
229
231{
232public:
233
235
236 XrdTcpMonInfo(const char *drctv, const char *cfn, XrdSysError &errR)
237 : KingPin(drctv, theEnv, errR, &myVer)
238 {theEnv.Put("configFN", cfn);}
239
241
243};
244
245/******************************************************************************/
246/* C o n s t r u c t o r */
247/******************************************************************************/
248
250{
251
252// Preset all variables with common defaults
253//
254 PortTCP = -1;
255 PortUDP = -1;
256 PortTLS = -1;
257 ConfigFN = 0;
258 tmoInfo = 0;
259 myInsName= 0;
260 mySitName= 0;
261 AdminPath= strdup("/tmp");
262 HomePath = 0;
263 PidPath = strdup("/tmp");
264 tlsCert = 0;
265 tlsKey = 0;
266 caDir = 0;
267 caFile = 0;
268 AdminMode= S_IRWXU;
269 HomeMode = S_IRWXU;
270 Police = 0;
271 Net_Opts = XRDNET_KEEPALIVE;
272 TLS_Blen = 0; // Accept OS default (leave Linux autotune in effect)
273 TLS_Opts = XRDNET_KEEPALIVE | XRDNET_USETLS;
274 repDest[0] = 0;
275 repDest[1] = 0;
276 repInt = 600;
277 ppNet = 0;
279 tlsNoVer = false;
280 tlsNoCAD = true;
281 NetADM = 0;
282 coreV = 1;
283 Specs = 0;
284 isStrict = false;
285 maxFD = 256*1024; // 256K default
286
287 Firstcp = Lastcp = 0;
288
289 ProtInfo.eDest = &Log; // Stable -> Error Message/Logging Handler
290 ProtInfo.NetTCP = 0; // Stable -> Network Object
291 ProtInfo.BPool = &BuffPool; // Stable -> Buffer Pool Manager
292 ProtInfo.Sched = &Sched; // Stable -> System Scheduler
293 ProtInfo.ConfigFN= 0; // We will fill this in later
294 ProtInfo.Stats = 0; // We will fill this in later
295 ProtInfo.AdmPath = AdminPath; // Stable -> The admin path
296 ProtInfo.AdmMode = AdminMode; // Stable -> The admin path mode
297 ProtInfo.theEnv = &theEnv; // Additional information
298 ProtInfo.xrdFlags= 0; // Additional information
299
301 memset(ProtInfo.rsvd3, 0, sizeof(ProtInfo.rsvd3));
302 ProtInfo.WSize = 0;
303 ProtInfo.ConnMax = -1; // Max connections (fd limit)
304 ProtInfo.readWait = 3*1000; // Wait time for data before we reschedule
305 ProtInfo.idleWait = 0; // Seconds connection may remain idle (0=off)
306 ProtInfo.hailWait =30*1000; // Wait time for data before we drop connection
307 ProtInfo.DebugON = 0; // 1 if started with -d
308 ProtInfo.argc = 0;
309 ProtInfo.argv = 0;
310 ProtInfo.tlsPort = 0;
311 ProtInfo.tlsCtx = 0;
313
314 XrdNetAddr::SetCache(3*60*60); // Cache address resolutions for 3 hours
315
316 // This may reset the NPROC resource limit, which is done here as we
317 // expect to be operating as a daemon. We set the argument limlower=true
318 // to potentially set a more restrictive limit than the current one.
319 Sched.setNproc(true);
320}
321
322/******************************************************************************/
323/* C o n f i g u r e */
324/******************************************************************************/
325
326int XrdConfig::Configure(int argc, char **argv)
327{
328/*
329 Function: Establish configuration at start up time.
330
331 Input: None.
332
333 Output: 0 upon success or !0 otherwise.
334*/
335 const char *xrdInst="XRDINSTANCE=";
336
337 int retc, NoGo = 0, clPort = -1;
338 const char *temp;
339 char c, buff[512], *dfltProt, *libProt = 0;
340 uid_t myUid = 0;
341 gid_t myGid = 0;
342 extern char *optarg;
343 extern int optind, opterr;
344 struct XrdOucLogging::configLogInfo LogInfo;
345 int pipeFD[2] = {-1, -1};
346 const char *pidFN = 0;
347 static const int myMaxc = 80;
348 char **urArgv, *myArgv[myMaxc], argBuff[myMaxc*3+8];
349 char *argbP = argBuff, *argbE = argbP+sizeof(argBuff)-4;
350 char *ifList = 0;
351 int myArgc = 1, urArgc = argc, i;
352 bool noV6, ipV4 = false, ipV6 = false, rootChk = true, optbg = false;
353
354// Reconstruct the command line so we can put it in the log
355//
356 XrdOucString CmdLine(argv[0]);
357 for (int k = 1; k < argc; k++)
358 {CmdLine += ' '; CmdLine += argv[k];}
359
360// Obtain the program name we will be using
361//
362 retc = strlen(argv[0]);
363 while(retc--) if (argv[0][retc] == '/') break;
364 myProg = &argv[0][retc+1];
365
366// Setup the initial required protocol. The program name matches the protocol
367// name but may be arbitrarily suffixed. We need to ignore this suffix. So we
368// look for it here and it it exists we duplicate argv[0] (yes, loosing some
369// bytes - sorry valgrind) without the suffix.
370//
371 {char *p = dfltProt = strdup(myProg);
372 while(*p && (*p == '.' || *p == '-')) p++;
373 if (*p)
374 {char *dot = index(p, '.'), *dash = index(p, '-');
375 if (dot && (dot < dash || !dash)) p = dot;
376 else if (dash) p = dash;
377 else p = 0;
378 if (p) *p = '\0';
379 if (!strcmp("xrootd", dfltProt)) dfltProt[5] = 0;
380 else if (!strcmp("cmsd", dfltProt)) dfltProt[3] = 0;
381 }
382 }
383 myArgv[0] = argv[0];
384
385// Prescan the argument list to see if there is a passthrough option. In any
386// case, we will set the ephemeral argv/arg in the environment.
387//
388 i = 1;
389 while(i < argc)
390 {if (*(argv[i]) == '-' && *(argv[i]+1) == '+')
391 {int n = strlen(argv[i]+2), j = i+1, k = 1;
392 if (urArgc == argc) urArgc = i;
393 if (n) memcpy(buff, argv[i]+2, (n > 256 ? 256 : n));
394 strcpy(&(buff[n]), ".argv**");
395 while(j < argc && (*(argv[j]) != '-' || *(argv[j]+1) != '+')) j++;
396 urArgv = new char*[j-i+1];
397 urArgv[0] = argv[0];
398 i++;
399 while(i < j) urArgv[k++] = argv[i++];
400 urArgv[k] = 0;
401 theEnv.PutPtr(buff, urArgv);
402 strcpy(&(buff[n]), ".argc");
403 theEnv.PutInt(buff, static_cast<long>(k));
404 } else i++;
405 }
406 theEnv.PutPtr("argv[0]", argv[0]);
407
408// Process the options. Note that we cannot passthrough long options or
409// options that take arguments because getopt permutes the arguments.
410//
411 opterr = 0;
412 if (argc > 1 && '-' == *argv[1])
413 while ((c = getopt(urArgc,argv,":a:A:bc:dhHI:k:l:L:n:N:p:P:R:s:S:vw:W:z"))
414 && ((unsigned char)c != 0xff))
415 { switch(c)
416 {
417 case 'a': if (AdminPath) free(AdminPath);
418 AdminPath = strdup(optarg);
419 AdminMode = ProtInfo.AdmMode = S_IRWXU;
421 break;
422 case 'A': if (AdminPath) free(AdminPath);
423 AdminPath = strdup(optarg);
424 AdminMode = ProtInfo.AdmMode = S_IRWXU | S_IRWXG;
426 break;
427 case 'b': optbg = true;
428 break;
429 case 'c': if (ConfigFN) free(ConfigFN);
430 ConfigFN = strdup(optarg);
431 break;
432 case 'd': XrdTrace.What |= TRACE_ALL;
433 ProtInfo.DebugON = 1;
434 XrdOucEnv::Export("XRDDEBUG", "1");
435 break;
436 case 'h': Usage(0);
437 break;
438 case 'H': Usage(-1);
439 break;
440 case 'I': if (!strcmp("v4", optarg)) {ipV4 = true; ipV6 = false;}
441 else if (!strcmp("v6", optarg)) {ipV4 = false; ipV6 = true;}
442 else {Log.Emsg("Config", "Invalid -I argument -",optarg);
443 Usage(1);
444 }
445 break;
446 case 'k': if (!(LogInfo.keepV = Log.logger()->ParseKeep(optarg)))
447 {Log.Emsg("Config","Invalid -k argument -",optarg);
448 Usage(1);
449 }
450 break;
451 case 'l': LogInfo.logArg = optarg;
452 break;
453 case 'L': if (!*optarg)
454 {Log.Emsg("Config", "Protocol library path not specified.");
455 Usage(1);
456 }
457 if (libProt) free(libProt);
458 libProt = strdup(optarg);
459 break;
460 case 'n': myInsName = (!strcmp(optarg,"anon")||!strcmp(optarg,"default")
461 ? 0 : optarg);
462 break;
463 case 'N': XrdNetIdentity::SetFQN(optarg);
464 break;
465 case 'p': if ((clPort = XrdOuca2x::a2p(Log,"tcp",optarg)) < 0) Usage(1);
466 break;
467 case 'P': if (dfltProt) free(dfltProt);
468 dfltProt = strdup(optarg);
469 break;
470 case 'R': if (!(getUG(optarg, myUid, myGid))) Usage(1);
471 rootChk = false;
472 break;
473 case 's': pidFN = optarg;
474 break;
475 case 'S': mySitName = optarg;
476 break;
477 case ':': buff[0] = '-'; buff[1] = optopt; buff[2] = 0;
478 Log.Emsg("Config", buff, "parameter not specified.");
479 Usage(1);
480 break;
481 case 'v': std::cerr <<XrdVSTRING <<std::endl;
482 _exit(0);
483 break;
484 case 'w': if (HomePath) free(HomePath);
485 HomePath = strdup(optarg);
486 HomeMode = S_IRWXU;
487 Specs |= hpSpec;
488 break;
489 case 'W': if (HomePath) free(HomePath);
490 HomePath = strdup(optarg);
491 HomeMode = S_IRWXU | S_IRGRP | S_IXGRP;
492 Specs |= hpSpec;
493 break;
494 case 'z': LogInfo.hiRes = true;
495 break;
496
497 default: if (optopt == '-' && *(argv[optind]+1) == '-')
498 {Log.Emsg("Config", "Long options are not supported.");
499 Usage(1);
500 }
501 if (myArgc >= myMaxc || argbP >= argbE)
502 {Log.Emsg("Config", "Too many command line arguments.");
503 Usage(1);
504 }
505 myArgv[myArgc++] = argbP;
506 *argbP++ = '-'; *argbP++ = optopt; *argbP++ = 0;
507 break;
508 }
509 }
510
511// If an adminpath specified, make sure it's absolute
512//
513 if ((ProtInfo.xrdFlags & XrdProtocol_Config::admPSet) && *AdminPath != '/')
514 {Log.Emsg("Config", "Command line adminpath is not absolute.");
515 exit(17);
516 }
517
518// If an homepath specified, make sure it's absolute
519//
520 if (HomePath && *HomePath != '/')
521 {Log.Emsg("Config", "Command line home path is not absolute.");
522 exit(17);
523 }
524
525// If the configuration file is relative to where we are, get the absolute
526// path as we may be changing the home path. This also starts capturing.
527//
528 if (ConfigFN) setCFG(true);
529
530// The first thing we must do is to set the correct networking mode
531//
532 noV6 = XrdNetAddr::IPV4Set();
533 if (ipV4) XrdNetAddr::SetIPV4();
534 else if (ipV6){if (noV6) Log.Say("Config warning: ipV6 appears to be broken;"
535 " forced ipV6 mode not advised!");
537 }
538 else if (noV6) Log.Say("Config warning: ipV6 is misconfigured or "
539 "unavailable; reverting to ipV4.");
540
541// Set the site name if we have one
542//
543 if (mySitName) mySitName = XrdOucSiteName::Set(mySitName, 63);
544
545// Drop into non-privileged state if so requested
546//
547 if (myGid && setegid(myGid))
548 {Log.Emsg("Config", errno, "set effective gid"); exit(17);}
549 if (myUid && seteuid(myUid))
550 {Log.Emsg("Config", errno, "set effective uid"); exit(17);}
551
552// Prohibit this program from executing as superuser unless -R was specified.
553//
554 if (rootChk && geteuid() == 0)
555 {Log.Emsg("Config", "Security reasons prohibit running as "
556 "superuser; program is terminating.");
557 _exit(8);
558 }
559
560// Pass over any parameters
561//
562 if (urArgc-optind+2 >= myMaxc)
563 {Log.Emsg("Config", "Too many command line arguments.");
564 Usage(1);
565 }
566 for ( ; optind < urArgc; optind++) myArgv[myArgc++] = argv[optind];
567
568// Record the actual arguments that we will pass on
569//
570 myArgv[myArgc] = 0;
571 ProtInfo.argc = myArgc;
572 ProtInfo.argv = myArgv;
573
574// Resolve background/foreground issues
575//
576 if (optbg)
577 {
578#ifdef WIN32
580#else
581 if (pipe( pipeFD ) == -1)
582 {Log.Emsg("Config", errno, "create a pipe"); exit(17);}
583 XrdOucUtils::Undercover(Log, !LogInfo.logArg, pipeFD);
584#endif
585 }
586
587// Get the full host name. We must define myIPAddr here because we may need to
588// run in v4 mode and that doesn't get set until after the options are scanned.
589//
590 static XrdNetAddr *myIPAddr = new XrdNetAddr((int)0);
591 if (!(myName = myIPAddr->Name(0, &temp))) myName = "";
592
593// Get our IP address and FQN
594//
595 ProtInfo.myName = myName;
596 ProtInfo.myAddr = myIPAddr->SockAddr();
598 ProtInfo.myProg = myProg;
599
600// Set the Environmental variable to hold the instance name
601// XRDINSTANCE=<pgm> <instance name>@<host name>
602// XrdOucEnv::Export("XRDINSTANCE")
603//
604 sprintf(buff,"%s%s %s@%s", xrdInst, myProg, ProtInfo.myInst, myName);
605 myInstance = strdup(buff);
606 putenv(myInstance); // XrdOucEnv::Export("XRDINSTANCE",...)
607 myInstance += strlen(xrdInst);
608 XrdOucEnv::Export("XRDHOST", myName);
610 XrdOucEnv::Export("XRDPROG", myProg);
611
612// Bind the log file if we have one
613//
614 if (LogInfo.logArg)
615 {LogInfo.xrdEnv = &theEnv;
616 LogInfo.iName = myInsName;
617 LogInfo.cfgFn = ConfigFN;
618 if (!XrdOucLogging::configLog(Log, LogInfo)) _exit(16);
619 Log.logger()->AddMsg(CmdLine.c_str());
621 }
622
623// We now test for host name. In theory, we should always get some kind of name.
624// We can't really continue without some kind of name at this point. Note that
625// vriable temp should still be valid from the previous NetAddr call.
626//
627 if (!(*myName))
628 {Log.Emsg("Config", "Unable to determine host name; ",
629 (temp ? temp : "reason unknown"),
630 "; execution terminated.");
631 _exit(16);
632 }
633
634// Tell NetIF what logger to use as it's been properly setup by now.
635//
637
638// Put out the herald
639//
640 strcpy(buff, "Starting on ");
641 retc = strlen(buff);
642 XrdSysUtils::FmtUname(buff+retc, sizeof(buff)-retc);
643 Log.Say(0, buff);
644 Log.Say(0, CmdLine.c_str());
646
647// Verify that we have a real name. We've had problems with people setting up
648// bad /etc/hosts files that can cause connection failures if "allow" is used.
649// Otherwise, determine our domain name.
650//
651 if (!myIPAddr->isRegistered())
652 {Log.Emsg("Config",myName,"does not appear to be registered in the DNS.");
653 Log.Emsg("Config","Verify that the '/etc/hosts' file is correct and "
654 "this machine is registered in DNS.");
655 Log.Emsg("Config", "Execution continues but connection failures may occur.");
656 myDomain = 0;
657 } else if (!(myDomain = index(myName, '.')))
658 Log.Say("Config warning: this hostname, ", myName,
659 ", is registered without a domain qualification.");
660
661// Setup the initial required protocol.
662//
663 Firstcp = Lastcp = new XrdConfigProt(strdup(dfltProt), libProt, 0);
664
665// Let start it up!
666//
667 Log.Say("++++++ ", myInstance, " initialization started.");
668
669// Allocate /dev/null as we need it and can't live without it
670//
671 devNull = XrdSysFD_Open("/dev/null", O_RDONLY);
672 if (devNull < 0)
673 {Log.Emsg("Config", errno, "open '/dev/null' which is required!");
674 NoGo = 1;
675 }
676
677// Process the configuration file, if one is present
678//
679 if (ConfigFN)
680 {Log.Say("Config using configuration file ", ConfigFN);
681 ProtInfo.ConfigFN = ConfigFN;
682 NoGo = ConfigProc();
683 }
684 if (clPort >= 0) PortTCP = clPort;
685 if (ProtInfo.DebugON)
688 }
689
690// Setup the admin path now
691//
692 NoGo |= SetupAPath();
693
694// If tls enabled, set it up. We skip this if we failed to avoid confusing msgs
695//
696 if (!NoGo)
697 {if (!tlsCert) ProtInfo.tlsCtx= 0;
698 else {Log.Say("++++++ ", myInstance, " TLS initialization started.");
699 if (SetupTLS())
700 {Log.Say("------ ",myInstance," TLS initialization ended.");
702 theEnv.PutPtr("XrdTlsContext*", XrdGlobal::tlsCtx);
703 } else {
704 NoGo = 1;
705 Log.Say("------ ",myInstance," TLS initialization failed.");
706 }
707 }
708 }
709
710// If there is TLS port verify that it can be used. We ignore this if we
711// will fail anyway so as to not issue confusing messages.
712//
713 if (!NoGo)
714 {if (PortTLS > 0 && !XrdGlobal::tlsCtx)
715 {Log.Say("Config TLS port specification ignored; TLS not configured!");
716 PortTLS = -1;
717 } else {
719 ProtInfo.tlsPort = (PortTLS > 0 ? PortTLS : 0);
720 }
721 }
722
723// Put largest buffer size in the env
724//
725 theEnv.PutInt("MaxBuffSize", XrdGlobal::xlBuff.MaxSize());
726
727// Export the network interface list at this point
728//
729 if (ppNet && XrdNetIF::GetIF(ifList, 0, true))
730 XrdOucEnv::Export("XRDIFADDRS",ifList);
731
732// Configure network routing
733//
734 if (!XrdInet::netIF.SetIF(myIPAddr, ifList))
735 {Log.Emsg("Config", "Unable to determine interface addresses!");
736 NoGo = 1;
737 }
738
739// If we have an instance name change the working directory
740//
741 if ((myInsName || HomePath)
742 && !XrdOucUtils::makeHome(Log, myInsName, HomePath, HomeMode)) NoGo = 1;
743
744// Start the UDP network address refresher.
745//
747
748// Create the pid file
749//
750 if (!PidFile(pidFN, optbg)) NoGo = 1;
751
752// Establish a manifest file for auto-collection
753//
754 if (!NoGo) Manifest(pidFN);
755
756// Now initialize the protocols and other stuff
757//
758 if (!NoGo) NoGo = Setup(dfltProt, libProt);
759
760// End config capture
761//
762 setCFG(false);
763
764// If we have a tcpmon plug-in try loading it now. We won't do that unless
765// tcp monitoring was enabled by the monitoring framework.
766//
767 if (tmoInfo && !NoGo)
768 {void *theGS = theEnv.GetPtr("TcpMon.gStream*");
769 if (!theGS) Log.Say("Config warning: TCP monitoring not enabled; "
770 "tcpmonlib plugin not loaded!");
771 else {tmoInfo->theEnv.PutPtr("TcpMon.gStream*", theGS);
772 TcpMonPin = tmoInfo->KingPin.Load("TcpMonPin");
773 if (!TcpMonPin) NoGo = 1;
774 }
775 }
776
777 // if we call this it means that the daemon has forked and we are
778 // in the child process
779#ifndef WIN32
780 if (optbg)
781 {
782 int status = NoGo ? 1 : 0;
783 if(write( pipeFD[1], &status, sizeof( status ) )) {};
784 close( pipeFD[1]);
785 }
786#endif
787
788// All done, close the stream and return the return code.
789//
790 temp = (NoGo ? " initialization failed." : " initialization completed.");
791 sprintf(buff, "%s:%d", myInstance, PortTCP);
792 Log.Say("------ ", buff, temp);
793 if (LogInfo.logArg)
794 {strcat(buff, " running ");
795 retc = strlen(buff);
796 XrdSysUtils::FmtUname(buff+retc, sizeof(buff)-retc);
797 Log.logger()->AddMsg(buff);
798 }
799 return NoGo;
800}
801
802/******************************************************************************/
803/* C o n f i g X e q */
804/******************************************************************************/
805
807{
808 int dynamic;
809
810 // Determine whether is is dynamic or not
811 //
812 if (eDest) dynamic = 1;
813 else {dynamic = 0; eDest = &Log;}
814
815 // Process common items
816 //
817 TS_Xeq("buffers", xbuf);
818 TS_Xeq("network", xnet);
819 TS_Xeq("sched", xsched);
820 TS_Xeq("trace", xtrace);
821
822 // Process items that can only be processed once
823 //
824 if (!dynamic)
825 {
826 TS_Xeq("adminpath", xapath);
827 TS_Xeq("allow", xallow);
828 TS_Xeq("homepath", xhpath);
829 TS_Xeq("maxfd", xmaxfd);
830 TS_Xeq("pidpath", xpidf);
831 TS_Xeq("port", xport);
832 TS_Xeq("protocol", xprot);
833 TS_Xeq("report", xrep);
834 TS_Xeq("sitename", xsit);
835 TS_Xeq("tcpmonlib", xtcpmon);
836 TS_Xeq("timeout", xtmo);
837 TS_Xeq("tls", xtls);
838 TS_Xeq("tlsca", xtlsca);
839 TS_Xeq("tlsciphers", xtlsci);
840 }
841
842 // No match found, complain.
843 //
844 eDest->Say("Config warning: ignoring unknown xrd directive '",var,"'.");
845 Config.Echo();
846 return 0;
847}
848
849/******************************************************************************/
850/* P r i v a t e F u n c t i o n s */
851/******************************************************************************/
852/******************************************************************************/
853/* A S o c k e t */
854/******************************************************************************/
855
856int XrdConfig::ASocket(const char *path, const char *fname, mode_t mode)
857{
858 struct sockaddr_un unixvar;
859 int plen = strlen(path), flen = strlen(fname);
860
861// Make sure we can fit everything in our buffer
862//
863 if ((plen + flen + 3) > (int)sizeof(unixvar.sun_path))
864 {Log.Emsg("Config", "admin path", path, "too long");
865 return 1;
866 }
867
868// *!*!* At this point we do not yet support the admin path for xrd.
869// sp we comment out all of the following code.
870
871/*
872// Construct the actual socket name
873//
874 char sokpath[sizeof(Unix.sun_path)];
875
876 if (sokpath[plen-1] != '/') sokpath[plen++] = '/';
877 strcpy(&sokpath[plen], fname);
878
879// Create an admin network
880//
881 NetADM = new XrdInet(&Log);
882 if (myDomain) NetADM->setDomain(myDomain);
883
884// Bind the netwok to the named socket
885//
886 if (!NetADM->Bind(sokpath)) return 1;
887
888// Set the mode and return
889//
890 chmod(sokpath, mode); // This may fail on some platforms
891*/
892 return 0;
893}
894
895/******************************************************************************/
896/* C o n f i g P r o c */
897/******************************************************************************/
898
899int XrdConfig::ConfigProc()
900{
901 char *var;
902 int cfgFD, retc, NoGo = 0;
903 XrdOucEnv myEnv;
904 XrdOucStream Config(&Log, myInstance, &myEnv, "=====> ");
905
906// Try to open the configuration file.
907//
908 if ( (cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
909 {Log.Emsg("Config", errno, "open config file", ConfigFN);
910 return 1;
911 }
912 Config.Attach(cfgFD);
913
914// Now start reading records until eof.
915//
916 while((var = Config.GetMyFirstWord()))
917 if (!strncmp(var, "xrd.", 4)
918 || !strcmp (var, "all.adminpath")
919 || !strcmp (var, "all.pidpath")
920 || !strcmp (var, "all.sitename" ))
921 if (ConfigXeq(var+4, Config)) {Config.Echo(); NoGo = 1;}
922
923// Now check if any errors occurred during file i/o
924//
925 if ((retc = Config.LastError()))
926 NoGo = Log.Emsg("Config", retc, "read config file", ConfigFN);
927 Config.Close();
928
929// Return final return code
930//
931 return NoGo;
932}
933
934/******************************************************************************/
935/* g e t N e t */
936/******************************************************************************/
937
938XrdInet *XrdConfig::getNet(int port, bool isTLS)
939{
940 int the_Opts, the_Blen;
941
942// Try to find an existing network for this port
943//
944 for (int i = 0; i < (int)NetTCP.size(); i++)
945 if (port == NetTCP[i]->Port()) return NetTCP[i];
946
947// Create a new network for this port
948//
949 XrdInet *newNet = new XrdInet(&Log, Police);
950 NetTCP.push_back(newNet);
951
952// Set options
953//
954 if (isTLS)
955 {the_Opts = TLS_Opts; the_Blen = TLS_Blen;
956 } else {
957 the_Opts = Net_Opts; the_Blen = Net_Blen;
958 }
959 if (the_Opts || the_Blen) newNet->setDefaults(the_Opts, the_Blen);
960
961// Set the domain if we have one
962//
963 if (myDomain) newNet->setDomain(myDomain);
964
965// Attempt to bind to this socket.
966//
967 if (newNet->BindSD(port, "tcp") == 0) return newNet;
968 delete newNet;
969 return 0;
970}
971
972/******************************************************************************/
973/* g e t U G */
974/******************************************************************************/
975
976int XrdConfig::getUG(char *parm, uid_t &newUid, gid_t &newGid)
977{
978 struct passwd *pp;
979
980// Get the userid entry
981//
982 if (!(*parm))
983 {Log.Emsg("Config", "-R user not specified."); return 0;}
984
985 if (isdigit(*parm))
986 {if (!(newUid = atol(parm)))
987 {Log.Emsg("Config", "-R", parm, "is invalid"); return 0;}
988 pp = getpwuid(newUid);
989 }
990 else pp = getpwnam(parm);
991
992// Make sure it is valid and acceptable
993//
994 if (!pp)
995 {Log.Emsg("Config", errno, "retrieve -R user password entry");
996 return 0;
997 }
998 if (!(newUid = pp->pw_uid))
999 {Log.Emsg("Config", "-R", parm, "is still unacceptably a superuser!");
1000 return 0;
1001 }
1002 newGid = pp->pw_gid;
1003 return 1;
1004}
1005
1006/******************************************************************************/
1007/* M a n i f e s t */
1008/******************************************************************************/
1009
1010void XrdConfig::Manifest(const char *pidfn)
1011{
1012 const char *Slash;
1013 char envBuff[8192], pwdBuff[2048], manBuff[1024], *pidP, *sP, *xP;
1014 int envFD, envLen;
1015
1016// Get the current working directory
1017//
1018 if (!getcwd(pwdBuff, sizeof(pwdBuff)))
1019 {Log.Emsg("Config", "Unable to get current working directory!");
1020 return;
1021 }
1022
1023// The above is the authoratative home directory, so recorded here.
1024//
1025 if (HomePath) free(HomePath);
1026 HomePath = strdup(pwdBuff);
1027
1028// Prepare for symlinks
1029//
1030 strcpy(envBuff, ProtInfo.AdmPath);
1031 envLen = strlen(envBuff);
1032 if (envBuff[envLen-1] != '/') {envBuff[envLen] = '/'; envLen++;}
1033 strcpy(envBuff+envLen, ".xrd/");
1034 xP = envBuff+envLen+5;
1035
1036// Create a symlink to the configuration file
1037//
1038 if ((sP = getenv("XRDCONFIGFN")))
1039 {sprintf(xP, "=/conf/%s.cf", myProg);
1040 XrdOucUtils::ReLink(envBuff, sP);
1041 }
1042
1043// Create a symlink to where core files will be found
1044//
1045 sprintf(xP, "=/core/%s", myProg);
1046 XrdOucUtils::ReLink(envBuff, pwdBuff);
1047
1048// Create a symlink to where log files will be found
1049//
1050 if ((sP = getenv("XRDLOGDIR")))
1051 {sprintf(xP, "=/logs/%s", myProg);
1052 XrdOucUtils::ReLink(envBuff, sP);
1053 }
1054
1055// Create a symlink to out proc information (Linux only)
1056//
1057#ifdef __linux__
1058 sprintf(xP, "=/proc/%s", myProg);
1059 sprintf(manBuff, "/proc/%d", getpid());
1060 XrdOucUtils::ReLink(envBuff, manBuff);
1061#endif
1062
1063// Create environment string
1064//
1065 envLen = snprintf(envBuff, sizeof(envBuff), "pid=%d&host=%s&inst=%s&ver=%s"
1066 "&home=%s&cfgfn=%s&cwd=%s&apath=%s&logfn=%s",
1067 static_cast<int>(getpid()), ProtInfo.myName,
1068 ProtInfo.myInst, XrdVSTRING, HomePath,
1069 (getenv("XRDCONFIGFN") ? getenv("XRDCONFIGFN") : ""),
1070 pwdBuff, ProtInfo.AdmPath, Log.logger()->xlogFN());
1071
1072// Find out where we should write this
1073//
1074 if (pidfn && (Slash = rindex(pidfn, '/')))
1075 {strncpy(manBuff, pidfn, Slash-pidfn); pidP = manBuff+(Slash-pidfn);}
1076 else {strcpy(manBuff, ProtInfo.AdmPath); pidP = manBuff+strlen(ProtInfo.AdmPath);}
1077
1078// Construct the pid file name for ourselves
1079//
1080 snprintf(pidP, sizeof(manBuff)-(pidP-manBuff), "/%s.%s.env",
1082 theEnv.Put("envFile", manBuff);
1083
1084// Open the file
1085//
1086 if ((envFD = open(manBuff, O_WRONLY|O_CREAT|O_TRUNC, 0664)) < 0)
1087 {Log.Emsg("Config", errno, "create envfile", manBuff);
1088 return;
1089 }
1090
1091// Write out environmental information
1092//
1093 if (write(envFD, envBuff, envLen) < 0)
1094 Log.Emsg("Config", errno, "write to envfile", manBuff);
1095 close(envFD);
1096}
1097
1098/******************************************************************************/
1099/* P i d F i l e */
1100/******************************************************************************/
1101
1102bool XrdConfig::PidFile(const char *clpFN, bool optbg)
1103{
1104 int rc, xfd;
1105 char *ppath, buff[32], pidFN[1200];
1106 const char *xop = 0;
1107
1108// If a command line pidfn was specified, we must successfully write it
1109// if we are in background mode. Otherwise, we simply continue.
1110//
1111 if (clpFN && !XrdOucUtils::PidFile(Log, clpFN) && optbg) return false;
1112
1113// Generate the old-style pidpath we will use
1114//
1116
1117// Create the path if it does not exist and write out the pid
1118//
1120 {xop = "create"; snprintf(pidFN, sizeof(pidFN), "%s", ppath); errno = rc;}
1121 else {snprintf(pidFN, sizeof(pidFN), "%s/%s.pid", ppath, myProg);
1122
1123 if ((xfd = open(pidFN, O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0)
1124 xop = "open";
1125 else {if (write(xfd,buff,snprintf(buff,sizeof(buff),"%d",
1126 static_cast<int>(getpid()))) < 0) xop = "write";
1127 close(xfd);
1128 }
1129 }
1130
1131// All done
1132//
1133 free(ppath);
1134 if (xop) Log.Emsg("Config", errno, xop, pidFN);
1135 return true;
1136}
1137
1138/******************************************************************************/
1139/* s e t C F G */
1140/******************************************************************************/
1141
1142void XrdConfig::setCFG(bool start)
1143{
1144
1145// If there is no config file there is nothing to do
1146//
1147 if (!ConfigFN || !(*ConfigFN))
1148 {if (ConfigFN)
1149 {free(ConfigFN);
1150 ConfigFN = 0;
1151 }
1152 return;
1153 }
1154
1155// If ending, post process the config capture
1156//
1157 if (!start)
1158 {XrdOucStream::Capture((XrdOucString *)0);
1159 if (totalCF.length())
1160 {char *temp = (char *)malloc(totalCF.length()+1);
1161 strcpy(temp, totalCF.c_str());
1162 totalCF.resize();
1163 totalCF = temp;
1164 free(temp);
1165 }
1166 return;
1167 }
1168
1169// Prefix current working directory to the config file if not absolute
1170//
1171 if (*ConfigFN != '/')
1172 {char cwdBuff[1024];
1173 if (getcwd(cwdBuff,sizeof(cwdBuff)-strlen(ConfigFN)-2))
1174 {int n = strlen(cwdBuff);
1175 if (cwdBuff[n-1] != '/') cwdBuff[n++] = '/';
1176 strcpy(cwdBuff+n, ConfigFN);
1177 free(ConfigFN);
1178 ConfigFN = strdup(cwdBuff);
1179 }
1180 }
1181
1182// Export result
1183//
1184 XrdOucEnv::Export("XRDCONFIGFN", ConfigFN);
1185
1186// Setup capturing for the XrdOucStream that will be used by all others to
1187// process config files.
1188//
1190 totalCF.resize(1024*1024);
1191 const char *cvec[] = { "*** ", myProg, " config from '", ConfigFN, "':", 0 };
1193}
1194
1195/******************************************************************************/
1196/* s e t F D L */
1197/******************************************************************************/
1198
1199int XrdConfig::setFDL()
1200{
1201 struct rlimit rlim;
1202 char buff[100];
1203
1204// Get the resource limit
1205//
1206 if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
1207 return Log.Emsg("Config", errno, "get FD limit");
1208
1209// Set the limit to the maximum allowed
1210//
1211 if (rlim.rlim_max == RLIM_INFINITY || (isStrict && rlim.rlim_max > maxFD))
1212 rlim.rlim_cur = maxFD;
1213 else rlim.rlim_cur = rlim.rlim_max;
1214#if (defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_5))
1215 if (rlim.rlim_cur > OPEN_MAX) rlim.rlim_max = rlim.rlim_cur = OPEN_MAX;
1216#endif
1217#if defined(__linux__)
1218// Setting a limit beyond this value on Linux is guaranteed to fail during epoll_wait()
1219 unsigned int epoll_max_fd = (INT_MAX / sizeof(struct epoll_event));
1220 if (rlim.rlim_cur > (rlim_t)epoll_max_fd) rlim.rlim_max = rlim.rlim_cur = epoll_max_fd;
1221#endif
1222 if (setrlimit(RLIMIT_NOFILE, &rlim) < 0)
1223 return Log.Emsg("Config", errno,"set FD limit");
1224
1225// Obtain the actual limit now
1226//
1227 if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
1228 return Log.Emsg("Config", errno, "get FD limit");
1229
1230// Establish operating limit
1231//
1232 ProtInfo.ConnMax = rlim.rlim_cur;
1233 sprintf(buff, "%d", ProtInfo.ConnMax);
1234 Log.Say("Config maximum number of connections restricted to ", buff);
1235
1236// Set core limit and but Solaris
1237//
1238#if !defined( __solaris__ ) && defined(RLIMIT_CORE)
1239 if (coreV >= 0)
1240 {if (getrlimit(RLIMIT_CORE, &rlim) < 0)
1241 Log.Emsg("Config", errno, "get core limit");
1242 else {rlim.rlim_cur = (coreV ? rlim.rlim_max : 0);
1243 if (setrlimit(RLIMIT_CORE, &rlim) < 0)
1244 Log.Emsg("Config", errno,"set core limit");
1245 }
1246 }
1247#endif
1248
1249// The scheduler will have already set the thread limit. We just report it
1250//
1251#if ( defined(__linux__) || defined(__GNU__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__)) ) && defined(RLIMIT_NPROC)
1252
1253// Obtain the actual limit now (Scheduler::setNproc may change this)
1254//
1255 if (getrlimit(RLIMIT_NPROC, &rlim) < 0)
1256 return Log.Emsg("Config", errno, "get thread limit");
1257
1258// Establish operating limit
1259//
1260 int nthr = static_cast<int>(rlim.rlim_cur);
1261 if (nthr < 8192 || ProtInfo.DebugON)
1262 {sprintf(buff, "%d", static_cast<int>(rlim.rlim_cur));
1263 Log.Say("Config maximum number of threads restricted to ", buff);
1264 }
1265#endif
1266
1267 return 0;
1268}
1269
1270/******************************************************************************/
1271/* S e t u p */
1272/******************************************************************************/
1273
1274int XrdConfig::Setup(char *dfltp, char *libProt)
1275{
1276 XrdConfigProt *cp;
1277 int xport, protNum = 0;
1278
1279// Establish the FD limit
1280//
1281 if (setFDL()) return 1;
1282
1283// Special handling for Linux sendfile()
1284//
1285#if ( defined(__linux__) || defined(__GNU__) ) && defined(TCP_CORK)
1286{ int sokFD, setON = 1;
1287 if ((sokFD = socket(PF_INET, SOCK_STREAM, 0)) >= 0)
1288 {setsockopt(sokFD, XrdNetUtils::ProtoID("tcp"), TCP_NODELAY,
1289 &setON, sizeof(setON));
1290 if (setsockopt(sokFD, SOL_TCP, TCP_CORK, &setON, sizeof(setON)) < 0)
1291 XrdLink::sfOK = 0;
1292 close(sokFD);
1293 }
1294}
1295#endif
1296
1297// Indicate how sendfile is being handled
1298//
1299 TRACE(NET,"sendfile " <<(XrdLink::sfOK ? "enabled." : "disabled!"));
1300
1301// Initialize the buffer manager
1302//
1303 BuffPool.Init();
1304
1305// Start the scheduler
1306//
1307 Sched.Start();
1308
1309// Setup the link and socket polling infrastructure
1310//
1312 || !XrdPoll::Setup(ProtInfo.ConnMax)) return 1;
1313
1314// Determine the default port number (only for xrootd) if not specified.
1315//
1316 if (PortTCP < 0)
1317 {if ((PortTCP = XrdNetUtils::ServPort(dfltp))) PortUDP = PortTCP;
1318 else PortTCP = -1;
1319 }
1320
1321// We now go through all of the protocols and get each respective port number.
1322//
1323 cp = Firstcp;
1324 while(cp)
1325 {if (!tlsCtx)
1326 for (int i = 0; i < cp->numP; i++)
1327 {if (cp->tlsVec[i])
1328 {Log.Emsg("Config", "protocol", cp->proname,
1329 "configured with a TLS-only port "
1330 "but TLS is not configured!");
1331 return 1;
1332 }
1333 }
1334 xport = (cp->dotls ? PortTLS : PortTCP);
1335 ProtInfo.Port = (cp->port < 0 ? xport : cp->port);
1336 XrdOucEnv::Export("XRDPORT", ProtInfo.Port);
1337 cp->port = XrdProtLoad::Port(cp->libpath,cp->proname,cp->parms,&ProtInfo);
1338 if (cp->port < 0) return 1;
1339 for (int i = 1; i < cp->numP; i++)
1340 if (cp->port == cp->portVec[i]) cp->portVec[i] = -1;
1341 cp = cp->Next;
1342 }
1343
1344// Allocate the statistics object. This is akward since we only know part
1345// of the current configuration. The object will figure this out later.
1346//
1348 ProtInfo.myName, Firstcp->port,
1349 ProtInfo.myInst, ProtInfo.myProg, mySitName);
1350 ProtInfo.Stats->Export(theEnv);
1351
1352// If the base protocol is xroot, then save the base port number so we can
1353// extend the port to the http protocol should it have been loaded. That way
1354// redirects via xroot will also work for http.
1355//
1356 xport = (strcmp("xroot", Firstcp->proname) ? 0 : Firstcp->port);
1357
1358// Load the protocols. For each new protocol port number, create a new
1359// network object to handle the port dependent communications part. All
1360// port issues will have been resolved at this point. Note that we need
1361// to set default network object from the first protocol before loading
1362// any protocol in case one of them starts using the default network.
1363//
1364 XrdInet *arbNet = 0, *theNet;
1365 while((cp = Firstcp))
1366 {for (int i = 0; i < cp->numP; i++)
1367 {if (cp->portVec[i] < 0) continue;
1368 if (!(cp->portVec[i]) && arbNet) theNet = arbNet;
1369 else {theNet = getNet(cp->portVec[i], cp->tlsVec[i]);
1370 if (!theNet) return 1;
1371 if (!(cp->portVec[i])) arbNet = theNet;
1372 }
1373 // The default network is the one of the first protocol; set it
1374 // before any protocol loads, which may use it
1375 if (i == 0 && !XrdNetTCP) XrdNetTCP = theNet;
1376 ProtInfo.Port = theNet->Port();
1377 ProtInfo.NetTCP = theNet;
1378 ProtInfo.WSize = theNet->WSize();
1379 TRACE(NET, cp->proname <<':' <<ProtInfo.Port <<" wsz="
1380 <<ProtInfo.WSize);
1381
1382 if (i) XrdProtLoad::Port(protNum, ProtInfo.Port, cp->tlsVec[i]);
1383 else {XrdOucEnv::Export("XRDPORT", ProtInfo.Port);
1384 protNum = XrdProtLoad::Load(cp->libpath, cp->proname,
1385 cp->parms, &ProtInfo,
1386 cp->dotls);
1387 if (!protNum) return 1;
1388 }
1389 }
1390 if (!strcmp("http", cp->proname) && xport)
1391 {for (int i = 0; i < cp->numP; i++)
1392 {if (cp->portVec[i] == xport) {xport = 0; break;}}
1393 if (xport) XrdProtLoad::Port(protNum, xport, false);
1394 }
1395 Firstcp = cp->Next; delete cp;
1396 }
1397
1398// Leave the env port number to be the first used port number. This may
1399// or may not be the same as the default port number. This corresponds to
1400// the default network object.
1401//
1402 PortTCP = ProtInfo.Port = XrdNetTCP->Port();
1403 XrdOucEnv::Export("XRDPORT", PortTCP);
1404 ProtInfo.Stats->SetPort(PortTCP);
1405
1406// Now check if we have to setup automatic reporting
1407//
1408 if (repDest[0] != 0 && (repOpts[0] || repOpts[1]))
1409 ProtInfo.Stats->Init(repDest, repInt, repOpts[0], repOpts[1]);
1410
1411// All done
1412//
1413 return 0;
1414}
1415
1416/******************************************************************************/
1417/* S e t u p A P a t h */
1418/******************************************************************************/
1419
1420int XrdConfig::SetupAPath()
1421{
1422 int rc;
1423
1424// Modify the AdminPath to account for any instance name. Note that there is
1425// a negligible memory leak under certain path combinations. Not enough to
1426// warrant a lot of logic to get around.
1427//
1428 if (myInsName) ProtInfo.AdmPath = XrdOucUtils::genPath(AdminPath,myInsName);
1429 else ProtInfo.AdmPath = AdminPath;
1430 XrdOucEnv::Export("XRDADMINPATH", ProtInfo.AdmPath);
1431 AdminPath = XrdOucUtils::genPath(AdminPath, myInsName, ".xrd");
1432
1433// Create the path. Only sockets are group writable but allow read access to
1434// the path for group members.
1435//
1436//
1437 if ((rc = XrdOucUtils::makePath(AdminPath, AdminMode & ~S_IWGRP)))
1438 {Log.Emsg("Config", rc, "create admin path", AdminPath);
1439 return 1;
1440 }
1441
1442// Make sure the last component has the permission that we want
1443//
1444#ifndef WIN32
1445 if (chmod(AdminPath, AdminMode & ~S_IWGRP))
1446 {Log.Emsg("Config", errno, "set permission for admin path", AdminPath);
1447 return 1;
1448 }
1449#endif
1450
1451
1452// Setup admin connection now
1453//
1454 return ASocket(AdminPath, "admin", (mode_t)AdminMode);
1455}
1456
1457/******************************************************************************/
1458/* S e t u p T L S */
1459/******************************************************************************/
1460
1461bool XrdConfig::SetupTLS()
1462{
1463
1464// Check if we should issue a verification error
1465//
1466 if (!caDir && !caFile && !tlsNoVer)
1467 {if (tlsNoCAD)
1468 Log.Say("Config failure: the tlsca directive was not specified!");
1469 else Log.Say("Config failure: the tlsca directive did not specify "
1470 "a certdir or certfile!");
1471 return false;
1472 }
1473
1474// Export the CAdir and CAfile values if they have not been exported
1475//
1476 if (caDir && !getenv("X509_CERT_DIR"))
1477 XrdOucEnv::Export("X509_CERT_DIR", caDir);
1478 if (caFile && !getenv("X509_CERT_FILE"))
1479 XrdOucEnv::Export("X509_CERT_FILE", caFile);
1480
1481// Set the message callback before doing anything else
1482//
1483 XrdTls::SetMsgCB(TlsError);
1484
1485// Set tracing options as needed
1486//
1488 {int tlsdbg = 0;
1489 if (TRACING(TRACE_DEBUG)) tlsdbg = XrdTls::dbgALL;
1490 else {if (TRACING(TRACE_TLSCTX)) tlsdbg |= XrdTls::dbgCTX;
1491 if (TRACING(TRACE_TLSSIO)) tlsdbg |= XrdTls::dbgSIO;
1492 if (TRACING(TRACE_TLSSOK)) tlsdbg |= XrdTls::dbgSOK;
1493 }
1494 XrdTls::SetDebug(tlsdbg, &Logger);
1495 }
1496
1497// Create a context
1498//
1499 static XrdTlsContext xrdTLS(tlsCert, tlsKey, caDir, caFile, tlsOpts);
1500
1501// Check if all went well
1502//
1503 if (!xrdTLS.isOK()) return false;
1504
1505// Set address of out TLS object in the global area
1506//
1507 XrdGlobal::tlsCtx = &xrdTLS;
1508 return true;
1509}
1510
1511/******************************************************************************/
1512/* U s a g e */
1513/******************************************************************************/
1514
1515void XrdConfig::Usage(int rc)
1516{
1517 extern const char *XrdLicense;
1518
1519 if (rc < 0) std::cerr <<XrdLicense;
1520 else
1521 std::cerr <<"\nUsage: " <<myProg <<" [-b] [-c <cfn>] [-d] [-h] [-H] [-I {v4|v6}]\n"
1522 "[-k {n|sz|sig}] [-l [=]<fn>] [-n <name>] [-N <hname>] [-p <port>]\n"
1523 "[-P <prot>] [-L <libprot>] [-R] [-s pidfile] [-S site] [-v] [-z]\n"
1524 "[<protocol_options>]" <<std::endl;
1525 _exit(rc > 0 ? rc : 0);
1526}
1527
1528/******************************************************************************/
1529/* x a p a t h */
1530/******************************************************************************/
1531
1532/* Function: xapath
1533
1534 Purpose: To parse the directive: adminpath <path> [group]
1535
1536 <path> the path of the FIFO to use for admin requests.
1537
1538 group allows group access to the admin path
1539
1540 Note: A named socket is created <path>/<name>/.xrd/admin
1541
1542 Output: 0 upon success or !0 upon failure.
1543*/
1544
1545int XrdConfig::xapath(XrdSysError *eDest, XrdOucStream &Config)
1546{
1547 char *pval, *val;
1548 mode_t mode = S_IRWXU;
1549
1550// Get the path
1551//
1552 pval = Config.GetWord();
1553 if (!pval || !pval[0])
1554 {eDest->Emsg("Config", "adminpath not specified"); return 1;}
1555
1556// Make sure it's an absolute path
1557//
1558 if (*pval != '/')
1559 {eDest->Emsg("Config", "adminpath not absolute"); return 1;}
1560
1561// Record the path
1562//
1563 if (AdminPath) free(AdminPath);
1564 AdminPath = strdup(pval);
1565
1566// Get the optional access rights
1567//
1568 if ((val = Config.GetWord()) && val[0])
1569 {if (!strcmp("group", val)) mode |= S_IRWXG;
1570 else {eDest->Emsg("Config", "invalid admin path modifier -", val);
1571 return 1;
1572 }
1573 }
1574 AdminMode = ProtInfo.AdmMode = mode;
1575 return 0;
1576}
1577
1578/******************************************************************************/
1579/* x a l l o w */
1580/******************************************************************************/
1581
1582/* Function: xallow
1583
1584 Purpose: To parse the directive: allow {host | netgroup} <name>
1585
1586 <name> The dns name of the host that is allowed to connect or the
1587 netgroup name the host must be a member of. For DNS names,
1588 a single asterisk may be specified anywhere in the name.
1589
1590 Output: 0 upon success or !0 upon failure.
1591*/
1592
1593int XrdConfig::xallow(XrdSysError *eDest, XrdOucStream &Config)
1594{
1595 char *val;
1596 int ishost;
1597
1598 if (!(val = Config.GetWord()))
1599 {eDest->Emsg("Config", "allow type not specified"); return 1;}
1600
1601 if (!strcmp(val, "host")) ishost = 1;
1602 else if (!strcmp(val, "netgroup")) ishost = 0;
1603 else {eDest->Emsg("Config", "invalid allow type -", val);
1604 return 1;
1605 }
1606
1607 if (!(val = Config.GetWord()))
1608 {eDest->Emsg("Config", "allow target name not specified"); return 1;}
1609
1610 if (!Police) {Police = new XrdNetSecurity();
1611 if (XrdTrace.What == TRACE_ALL) Police->Trace(&XrdTrace);
1612 }
1613 if (ishost) Police->AddHost(val);
1614 else Police->AddNetGroup(val);
1615
1616 return 0;
1617}
1618
1619/******************************************************************************/
1620/* x h p a t h */
1621/******************************************************************************/
1622
1623/* Function: xhpath
1624
1625 Purpose: To parse the directive: homepath <path> [group]
1626
1627 <path> the path of the home director to be made as the cwd.
1628
1629 group allows group access to the home path
1630
1631 Output: 0 upon success or !0 upon failure.
1632*/
1633
1634int XrdConfig::xhpath(XrdSysError *eDest, XrdOucStream &Config)
1635{
1636// If the command line specified he home, it cannot be undone
1637//
1638 if (Specs & hpSpec)
1639 {eDest->Say("Config warning: command line homepath cannot be overridden.");
1640 Config.GetWord();
1641 return 0;
1642 }
1643
1644// Free existing home path, if any
1645//
1646 if (HomePath) {free(HomePath); HomePath = 0;}
1647
1648// Parse the home path and return success or failure
1649//
1650 HomePath = XrdOucUtils::parseHome(*eDest, Config, HomeMode);
1651 return (HomePath ? 0 : 1);
1652}
1653
1654/******************************************************************************/
1655/* x b u f */
1656/******************************************************************************/
1657
1658/* Function: xbuf
1659
1660 Purpose: To parse the directive: buffers [maxbsz <bsz>] <memsz> [<rint>]
1661
1662 <bsz> maximum size of an individualbuffer. The default is 2m.
1663 Specify any value 2m < bsz <= 1g; if specified, it must
1664 appear before the <memsz> and <memsz> becomes optional.
1665 <memsz> maximum amount of memory devoted to buffers
1666 <rint> minimum buffer reshape interval in seconds
1667
1668 Output: 0 upon success or !0 upon failure.
1669*/
1670int XrdConfig::xbuf(XrdSysError *eDest, XrdOucStream &Config)
1671{
1672 static const long long minBSZ = 1024*1024*2+1; // 2mb
1673 static const long long maxBSZ = 1024*1024*1024; // 1gb
1674 int bint = -1;
1675 long long blim;
1676 char *val;
1677
1678 if (!(val = Config.GetWord()))
1679 {eDest->Emsg("Config", "buffer memory limit not specified"); return 1;}
1680
1681 if (!strcmp("maxbsz", val))
1682 {if (!(val = Config.GetWord()))
1683 {eDest->Emsg("Config", "max buffer size not specified"); return 1;}
1684 if (XrdOuca2x::a2sz(*eDest,"maxbz value",val,&blim,minBSZ,maxBSZ))
1685 return 1;
1686 XrdGlobal::xlBuff.Init(blim);
1687 if (!(val = Config.GetWord())) return 0;
1688 }
1689
1690 if (XrdOuca2x::a2sz(*eDest,"buffer limit value",val,&blim,
1691 (long long)1024*1024)) return 1;
1692
1693 if ((val = Config.GetWord()))
1694 if (XrdOuca2x::a2tm(*eDest,"reshape interval", val, &bint, 300))
1695 return 1;
1696
1697 BuffPool.Set((int)blim, bint);
1698 return 0;
1699}
1700
1701
1702/******************************************************************************/
1703/* x m a x f d */
1704/******************************************************************************/
1705
1706/* Function: xmaxfd
1707
1708 Purpose: To parse the directive: maxfd [strict] <numfd>
1709
1710 strict when specified, the limits is always applied. Otherwise,
1711 it is only applied when rlimit is infinite.
1712 <numfd> maximum number of fs that can be established.
1713 Specify a value optionally suffixed with 'k'.
1714
1715 Output: 0 upon success or !0 upon failure.
1716*/
1717int XrdConfig::xmaxfd(XrdSysError *eDest, XrdOucStream &Config)
1718{
1719 long long minV = 1024, maxV = 1024LL*1024LL; // between 1k and 1m
1720 long long fdVal;
1721 char *val;
1722
1723 if ((val = Config.GetWord()))
1724 {if (!strcmp(val, "strict"))
1725 {isStrict = true;
1726 val = Config.GetWord();
1727 } else isStrict = false;
1728 }
1729
1730 if (!val)
1731 {eDest->Emsg("Config", "file descriptor limit not specified"); return 1;}
1732
1733
1734 if (XrdOuca2x::a2sz(*eDest,"maxfd value",val,&fdVal,minV,maxV)) return 1;
1735
1736 maxFD = static_cast<unsigned int>(fdVal);
1737
1738 return 0;
1739}
1740
1741/******************************************************************************/
1742/* x n e t */
1743/******************************************************************************/
1744
1745/* Function: xnet
1746
1747 Purpose: To parse directive: network [tls] [[no]keepalive] [buffsz <blen>]
1748 [kaparms parms] [cache <ct>] [[no]dnr]
1749 [routes <rtype> [use <ifn1>,<ifn2>]]
1750 [[no]rpipa] [[no]dyndns]
1751 [udprefresh <sec>]
1752
1753 <rtype>: split | common | local
1754
1755 tls parameters apply only to the tls port
1756 keepalive do [not] set the socket keepalive option.
1757 kaparms keepalive paramters as specified by parms.
1758 <blen> is the socket's send/rcv buffer size.
1759 <ct> Seconds to cache address to name resolutions.
1760 [no]dnr do [not] perform a reverse DNS lookup if not needed.
1761 routes specifies the network configuration (see reference)
1762 [no]rpipa do [not] resolve private IP addresses.
1763 [no]dyndns This network does [not] use a dynamic DNS.
1764 udprefresh Refreshes udp sendto addresses should they change
1765 This only works for connected udp sockets.
1766
1767 Output: 0 upon success or !0 upon failure.
1768*/
1769
1770int XrdConfig::xnet(XrdSysError *eDest, XrdOucStream &Config)
1771{
1772 char *val;
1773 int i, n, V_keep = -1, V_nodnr = 0, V_istls = 0, V_blen = -1, V_ct = -1;
1774 int V_assumev4 = -1, v_rpip = -1, V_dyndns = -1, V_udpref = -1;
1775 long long llp;
1776 struct netopts {const char *opname; int hasarg; int opval;
1777 int *oploc; const char *etxt;}
1778 ntopts[] =
1779 {
1780 {"assumev4", 0, 1, &V_assumev4, "option"},
1781 {"keepalive", 0, 1, &V_keep, "option"},
1782 {"nokeepalive",0, 0, &V_keep, "option"},
1783 {"kaparms", 4, 0, &V_keep, "option"},
1784 {"buffsz", 1, 0, &V_blen, "network buffsz"},
1785 {"cache", 2, 0, &V_ct, "cache time"},
1786 {"dnr", 0, 0, &V_nodnr, "option"},
1787 {"nodnr", 0, 1, &V_nodnr, "option"},
1788 {"dyndns", 0, 1, &V_dyndns, "option"},
1789 {"nodyndns", 0, 0, &V_dyndns, "option"},
1790 {"routes", 3, 1, 0, "routes"},
1791 {"rpipa", 0, 1, &v_rpip, "rpipa"},
1792 {"norpipa", 0, 0, &v_rpip, "norpipa"},
1793 {"tls", 0, 1, &V_istls, "option"},
1794 {"udprefresh", 2, 1, &V_udpref, "udprefresh"}
1795 };
1796 int numopts = sizeof(ntopts)/sizeof(struct netopts);
1797
1798 if (!(val = Config.GetWord()))
1799 {eDest->Emsg("Config", "net option not specified"); return 1;}
1800
1801 while (val)
1802 {for (i = 0; i < numopts; i++)
1803 if (!strcmp(val, ntopts[i].opname))
1804 {if (!ntopts[i].hasarg) *ntopts[i].oploc = ntopts[i].opval;
1805 else {if (!(val = Config.GetWord()))
1806 {eDest->Emsg("Config", "network",
1807 ntopts[i].opname, "argument missing");
1808 return 1;
1809 }
1810 if (ntopts[i].hasarg == 4)
1811 {if (xnkap(eDest, val)) return 1;
1812 break;
1813 }
1814 if (ntopts[i].hasarg == 3)
1815 { if (!strcmp(val, "split"))
1817 else if (!strcmp(val, "common"))
1819 else if (!strcmp(val, "local"))
1821 else {eDest->Emsg("Config","Invalid routes argument -",val);
1822 return 1;
1823 }
1824 if (!(val = Config.GetWord())|| !(*val)) break;
1825 if (strcmp(val, "use")) continue;
1826 if (!(val = Config.GetWord())|| !(*val))
1827 {eDest->Emsg("Config", "network routes i/f names "
1828 "not specified.");
1829 return 1;
1830 }
1831 if (!XrdNetIF::SetIFNames(val)) return 1;
1832 ppNet = 1;
1833 break;
1834 }
1835 if (ntopts[i].hasarg == 2)
1836 {if (XrdOuca2x::a2tm(*eDest,ntopts[i].etxt,val,&n,0))
1837 return 1;
1838 *ntopts[i].oploc = n;
1839 } else {
1840 if (XrdOuca2x::a2sz(*eDest,ntopts[i].etxt,val,&llp,0))
1841 return 1;
1842 *ntopts[i].oploc = (int)llp;
1843 }
1844 }
1845 break;
1846 }
1847 if (i >= numopts)
1848 eDest->Say("Config warning: ignoring invalid net option '",val,"'.");
1849 else if (!val) break;
1850 val = Config.GetWord();
1851 }
1852
1853 if (V_istls)
1854 {if (V_blen >= 0) TLS_Blen = V_blen;
1855 if (V_keep >= 0) TLS_Opts = (V_keep ? XRDNET_KEEPALIVE : 0);
1856 TLS_Opts |= (V_nodnr ? XRDNET_NORLKUP : 0) | XRDNET_USETLS;
1857 } else {
1858 if (V_blen >= 0) Net_Blen = V_blen;
1859 if (V_keep >= 0) Net_Opts = (V_keep ? XRDNET_KEEPALIVE : 0);
1860 Net_Opts |= (V_nodnr ? XRDNET_NORLKUP : 0);
1861 }
1862
1863 // Turn off name chaing if not specified and dynamic dns was specified
1864 //
1865 if (V_dyndns >= 0)
1866 {if (V_dyndns && V_ct < 0) V_ct = 0;
1867 XrdNetAddr::SetDynDNS(V_dyndns != 0);
1868 }
1869 if (V_ct >= 0) XrdNetAddr::SetCache(V_ct);
1870
1871 if (v_rpip >= 0) XrdInet::netIF.SetRPIPA(v_rpip != 0);
1872 if (V_assumev4 >= 0) XrdInet::SetAssumeV4(true);
1873
1874 if (V_udpref >= 0)
1875 XrdNetSocketCFG::udpRefr = (V_udpref < 1800 ? 1800 : V_udpref);
1876 return 0;
1877}
1878
1879/******************************************************************************/
1880/* x n k a p */
1881/******************************************************************************/
1882
1883/* Function: xnkap
1884
1885 Purpose: To parse the directive: kaparms idle[,itvl[,cnt]]
1886
1887 idle Seconds the connection needs to remain idle before TCP
1888 should start sending keepalive probes.
1889 itvl Seconds between individual keepalive probes.
1890 icnt Maximum number of keepalive probes TCP should send
1891 before dropping the connection,
1892*/
1893
1894int XrdConfig::xnkap(XrdSysError *eDest, char *val)
1895{
1896 char *karg, *comma;
1897 int knum;
1898
1899// Get the first parameter, idle seconds
1900//
1901 karg = val;
1902 if ((comma = index(val, ','))) {val = comma+1; *comma = 0;}
1903 else val = 0;
1904 if (XrdOuca2x::a2tm(*eDest,"kaparms idle", karg, &knum, 0)) return 1;
1906
1907// Get the second parameter, interval seconds
1908//
1909 if (!(karg = val)) return 0;
1910 if ((comma = index(val, ','))) {val = comma+1; *comma = 0;}
1911 else val = 0;
1912 if (XrdOuca2x::a2tm(*eDest,"kaparms interval", karg, &knum, 0)) return 1;
1914
1915// Get the third parameter, count
1916//
1917 if (!val) return 0;
1918 if (XrdOuca2x::a2i(*eDest,"kaparms count", val, &knum, 0)) return 1;
1920
1921// All done
1922//
1923 return 0;
1924}
1925
1926/******************************************************************************/
1927/* x p i d f */
1928/******************************************************************************/
1929
1930/* Function: xpidf
1931
1932 Purpose: To parse the directive: pidpath <path>
1933
1934 <path> the path where the pid file is to be created.
1935
1936 Output: 0 upon success or !0 upon failure.
1937*/
1938
1939int XrdConfig::xpidf(XrdSysError *eDest, XrdOucStream &Config)
1940{
1941 char *val;
1942
1943// Get the path
1944//
1945 val = Config.GetWord();
1946 if (!val || !val[0])
1947 {eDest->Emsg("Config", "pidpath not specified"); return 1;}
1948
1949// Record the path
1950//
1951 if (PidPath) free(PidPath);
1952 PidPath = strdup(val);
1953 return 0;
1954}
1955
1956/******************************************************************************/
1957/* x p o r t */
1958/******************************************************************************/
1959
1960/* Function: xport
1961
1962 Purpose: To parse the directive: port [tls] <tcpnum>
1963 [if [<hlst>] [named <nlst>]]
1964
1965 tls apply this to the tls port
1966 <tcpnum> number of the tcp port for incoming requests
1967 <hlst> list of applicable host patterns
1968 <nlst> list of applicable instance names.
1969
1970 Output: 0 upon success or !0 upon failure.
1971*/
1972int XrdConfig::xport(XrdSysError *eDest, XrdOucStream &Config)
1973{ int rc, istls = 0, pnum = 0;
1974 char *val, cport[32];
1975
1976 do {if (!(val = Config.GetWord()))
1977 {eDest->Emsg("Config", "tcp port not specified"); return 1;}
1978 if (strcmp("tls", val) || istls) break;
1979 istls = 1;
1980 } while(1);
1981
1982 strncpy(cport, val, sizeof(cport)-1); cport[sizeof(cport)-1] = '\0';
1983
1984 if ((val = Config.GetWord()) && !strcmp("if", val))
1985 if ((rc = XrdOucUtils::doIf(eDest,Config, "port directive", myName,
1986 ProtInfo.myInst, myProg)) <= 0)
1987 {if (!rc) Config.noEcho(); return (rc < 0);}
1988
1989 if ((pnum = XrdOuca2x::a2p(*eDest, "tcp", cport)) < 0) return 1;
1990 if (istls) PortTLS = pnum;
1991 else PortTCP = PortUDP = pnum;
1992
1993 return 0;
1994}
1995
1996
1997/******************************************************************************/
1998/* x p r o t */
1999/******************************************************************************/
2000
2001/* Function: xprot
2002
2003 Purpose: To parse the directive: protocol [tls] <name>[:<port>] <args>
2004
2005 <args> {+port | <loc> [<parm>]}
2006 tls The protocol requires tls.
2007 <name> The name of the protocol (e.g., rootd)
2008 <port> Port binding for the protocol, if not the default.
2009 <loc> The shared library in which it is located.
2010 <parm> A one line parameter to be passed to the protocol.
2011
2012 Output: 0 upon success or !0 upon failure.
2013*/
2014
2015int XrdConfig::xprot(XrdSysError *eDest, XrdOucStream &Config)
2016{
2017 XrdConfigProt *cpp;
2018 char *val, *parms, *lib, proname[64], buff[2048];
2019 int portnum = -1;
2020 bool dotls = false;
2021
2022 do {if (!(val = Config.GetWord()))
2023 {eDest->Emsg("Config", "protocol name not specified"); return 1;}
2024 if (dotls || strcmp("tls", val)) break;
2025 dotls = true;
2026 } while(1);
2027
2028 if (strlen(val) > sizeof(proname)-1)
2029 {eDest->Emsg("Config", "protocol name is too long"); return 1;}
2030 strcpy(proname, val);
2031
2032 if ((val = index(proname, ':')))
2033 {if ((portnum = XrdOuca2x::a2p(*eDest, "tcp", val+1)) < 0) return 1;
2034 else *val = '\0';
2035 }
2036
2037 if (!(val = Config.GetWord()))
2038 {eDest->Emsg("Config", "protocol library not specified"); return 1;}
2039 if (!strcmp("*", val)) lib = 0;
2040 else if (*val == '+')
2041 {if (strcmp(val, "+port"))
2042 {eDest->Emsg("Config","invalid library specification -",val);
2043 return 1;
2044 }
2045 if ((cpp = Firstcp))
2046 do {if (!strcmp(proname, cpp->proname))
2047 {if (cpp->AddPort(portnum, dotls)) return 0;
2048 eDest->Emsg("Config", "port add limit exceeded!");
2049 return 1;
2050 }
2051 } while((cpp = cpp->Next));
2052 eDest->Emsg("Config","protocol",proname,"not previously defined!");
2053 return 1;
2054 }
2055 else lib = strdup(val);
2056
2057// If no library was specified then this is a default protocol. We must make sure
2058// sure it is consistent with whatever default we have.
2059//
2060 if (!lib && Firstcp && strcmp(proname, Firstcp->proname))
2061 {char eBuff[512];
2062 snprintf(eBuff, sizeof(eBuff), "the %s protocol is '%s' not '%s'; "
2063 "assuming you meant '%s'",
2064 (Firstcp->libpath ? "assigned" : "builtin"),
2065 Firstcp->proname, proname, Firstcp->proname);
2066 eDest->Say("Config warning: ", eBuff, " but please correct "
2067 "the following directive!");
2068 snprintf(proname, sizeof(proname), "%s", Firstcp->proname);
2069 }
2070
2071 *buff = 0;
2072 if (!Config.GetRest(buff, sizeof(buff)))
2073 {eDest->Emsg("Config", "Too many parms for protocol", proname);
2074 return 1;
2075 }
2076 parms = (*buff ? strdup(buff) : 0);
2077
2078 if ((cpp = Firstcp))
2079 do {if (!strcmp(proname, cpp->proname))
2080 {cpp->Reset(lib, parms, portnum, dotls);
2081 return 0;
2082 }
2083 } while((cpp = cpp->Next));
2084
2085 cpp = new XrdConfigProt(strdup(proname), lib, parms, portnum, dotls);
2086 if (!lib) {cpp->Next = Firstcp; Firstcp = cpp;
2087 if (!Lastcp) Lastcp = cpp;
2088 }
2089 else {if (Lastcp) Lastcp->Next = cpp;
2090 else Firstcp = cpp;
2091 Lastcp = cpp;
2092 }
2093 return 0;
2094}
2095
2096/******************************************************************************/
2097/* x r e p */
2098/******************************************************************************/
2099
2100/* Function: xrep
2101
2102 Purpose: To parse the directive: report <dest1>[,<dest2>]
2103 [every <sec>] <opts>
2104
2105 <dest1> where a UDP based report is to be sent. It may be a
2106 <host:port> or a local named UDP pipe (i.e., "/...").
2107
2108 <dest2> A secondary destination.
2109
2110 <sec> the reporting interval. The default is 10 minutes.
2111
2112 <opts> What to report. "all" is the default.
2113
2114 Output: 0 upon success or !0 upon failure.
2115*/
2116
2117int XrdConfig::xrep(XrdSysError *eDest, XrdOucStream &Config)
2118{
2119 static struct repopts {const char *opname; int opval; bool jOK;} rpopts[] =
2120 {
2121 {"addons", XRD_STATS_ADON, true},
2122 {"all", XRD_STATS_ALLX, true},
2123 {"buff", XRD_STATS_BUFF, false},
2124 {"info", XRD_STATS_INFO, false},
2125 {"link", XRD_STATS_LINK, false},
2126 {"plugins", XRD_STATS_PLUG, true},
2127 {"poll", XRD_STATS_POLL, false},
2128 {"process", XRD_STATS_PROC, false},
2129 {"protocols",XRD_STATS_PROT, false},
2130 {"prot", XRD_STATS_PROT, false},
2131 {"sched", XRD_STATS_SCHD, false},
2132 {"sgen", XRD_STATS_SGEN, false},
2133 {"sync", XRD_STATS_SYNC, true},
2134 {"syncwp", XRD_STATS_SYNCA,true}
2135 };
2136 int i, neg, numopts = sizeof(rpopts)/sizeof(struct repopts);
2137 char *val, *cp;
2138 int isJSON = 0;
2139
2140 if (!(val = Config.GetWord()))
2141 {eDest->Emsg("Config", "report parameters not specified"); return 1;}
2142
2143// Cleanup to start anew
2144//
2145 if (repDest[0]) {free(repDest[0]); repDest[0] = 0;}
2146 if (repDest[1]) {free(repDest[1]); repDest[1] = 0;}
2147 repOpts[0] = 0; repOpts[1] = 0;
2148 repInt = 600;
2149
2150// Decode the destination
2151//
2152 if ((cp = (char *)index(val, ',')))
2153 {if (!*(cp+1))
2154 {eDest->Emsg("Config","malformed report destination -",val); return 1;}
2155 else { repDest[1] = cp+1; *cp = '\0';}
2156 }
2157 repDest[0] = val;
2158 for (i = 0; i < 2; i++)
2159 {if (!(val = repDest[i])) break;
2160 if (*val != '/' && (!(cp = index(val, (int)':')) || !atoi(cp+1)))
2161 {eDest->Emsg("Config","report dest port missing or invalid in",val);
2162 return 1;
2163 }
2164 repDest[i] = strdup(val);
2165 }
2166
2167// Make sure dests differ
2168//
2169 if (repDest[0] && repDest[1] && !strcmp(repDest[0], repDest[1]))
2170 {eDest->Emsg("Config", "Warning, report dests are identical.");
2171 free(repDest[1]); repDest[1] = 0;
2172 }
2173
2174// Get optional "every"
2175//
2176 if (!(val = Config.GetWord()))
2177 {repOpts[0] = XRD_STATS_ALLX; // Default is XML
2178 return 0;
2179 }
2180
2181 if (!strcmp("every", val))
2182 {if (!(val = Config.GetWord()))
2183 {eDest->Emsg("Config", "report every value not specified"); return 1;}
2184 if (XrdOuca2x::a2tm(*eDest,"report every",val,&repInt,1)) return 1;
2185 val = Config.GetWord();
2186 }
2187
2188// Get reporting options
2189//
2190 while(val)
2191 {if (!strcmp(val, "json"))
2192 {isJSON = 1;
2193 val = Config.GetWord(); continue;
2194 }
2195 if (!strcmp(val, "off"))
2196 {repOpts[isJSON] = 0;
2197 val = Config.GetWord(); continue;
2198 }
2199 if ((neg = (val[0] == '-' && val[1]))) val++;
2200 for (i = 0; i < numopts; i++)
2201 {if (!strcmp(val, rpopts[i].opname))
2202 {if (neg) repOpts[isJSON] &= ~rpopts[i].opval;
2203 else {if (isJSON && !rpopts[i].jOK)
2204 {eDest->Emsg("Config",val,"does not support JSON");
2205 return 1;
2206 }
2207 repOpts[isJSON] |= rpopts[i].opval;
2208 }
2209 break;
2210 }
2211 }
2212 if (i >= numopts)
2213 eDest->Say("Config warning: ignoring invalid report option '",val,"'.");
2214 val = Config.GetWord();
2215 }
2216
2217// Apply the sync option to all formats
2218//
2219 if ((repOpts[0] | repOpts[1]) & XRD_STATS_SYNC)
2220 {repOpts[0] |= XRD_STATS_SYNC; repOpts[0] &= ~XRD_STATS_SYNCA;
2221 repOpts[1] |= XRD_STATS_SYNC; repOpts[1] &= ~XRD_STATS_SYNCA;
2222 } else {
2223 if ((repOpts[0] | repOpts[1]) & XRD_STATS_SYNCA)
2224 {repOpts[0] |= XRD_STATS_SYNCA;
2225 repOpts[1] |= XRD_STATS_SYNCA;
2226 }
2227 }
2228
2229// If at the end nothing was selected, then provide the default
2230//
2231 if (!((repOpts[0] | repOpts[1]) & XRD_STATS_ALLX))
2232 repOpts[0] |= (XRD_STATS_ALLX & ~XRD_STATS_INFO);
2234
2235// All done
2236//
2237 return 0;
2238}
2239
2240/******************************************************************************/
2241/* x s c h e d */
2242/******************************************************************************/
2243
2244/* Function: xsched
2245
2246 Purpose: To parse directive: sched [mint <mint>] [maxt <maxt>] [avlt <at>]
2247 [idle <idle>] [stksz <qnt>] [core <cv>]
2248
2249 <mint> is the minimum number of threads that we need. Once
2250 this number of threads is created, it does not decrease.
2251 <maxt> maximum number of threads that may be created. The
2252 actual number of threads will vary between <mint> and
2253 <maxt>.
2254 <avlt> Are the number of threads that must be available for
2255 immediate dispatch. These threads are never bound to a
2256 connection (i.e., made stickied). Any available threads
2257 above <ft> will be allowed to stick to a connection.
2258 <cv> asis - leave current value alone.
2259 max - set value to maximum allowed (hard limit).
2260 off - turn off core files.
2261 <idle> The time (in time spec) between checks for underused
2262 threads. Those found will be terminated. Default is 780.
2263 <qnt> The thread stack size in bytes or K, M, or G.
2264
2265 Output: 0 upon success or 1 upon failure.
2266*/
2267
2268int XrdConfig::xsched(XrdSysError *eDest, XrdOucStream &Config)
2269{
2270 char *val;
2271 long long lpp;
2272 int i, ppp = 0;
2273 int V_mint = -1, V_maxt = -1, V_idle = -1, V_avlt = -1;
2274 struct schedopts {const char *opname; int minv; int *oploc;
2275 const char *opmsg;} scopts[] =
2276 {
2277 {"stksz", 0, 0, "sched stksz"},
2278 {"mint", 1, &V_mint, "sched mint"},
2279 {"maxt", 1, &V_maxt, "sched maxt"},
2280 {"avlt", 1, &V_avlt, "sched avlt"},
2281 {"core", 1, 0, "sched core"},
2282 {"idle", 0, &V_idle, "sched idle"}
2283 };
2284 int numopts = sizeof(scopts)/sizeof(struct schedopts);
2285
2286 if (!(val = Config.GetWord()))
2287 {eDest->Emsg("Config", "sched option not specified"); return 1;}
2288
2289 while (val)
2290 {for (i = 0; i < numopts; i++)
2291 if (!strcmp(val, scopts[i].opname))
2292 {if (!(val = Config.GetWord()))
2293 {eDest->Emsg("Config", "sched", scopts[i].opname,
2294 "value not specified");
2295 return 1;
2296 }
2297 if (*scopts[i].opname == 'i')
2298 {if (XrdOuca2x::a2tm(*eDest, scopts[i].opmsg, val,
2299 &ppp, scopts[i].minv)) return 1;
2300 }
2301 else if (*scopts[i].opname == 'c')
2302 { if (!strcmp("asis", val)) coreV = -1;
2303 else if (!strcmp("max", val)) coreV = 1;
2304 else if (!strcmp("off", val)) coreV = 0;
2305 else {eDest->Emsg("Config","invalid sched core value -",val);
2306 return 1;
2307 }
2308 }
2309 else if (*scopts[i].opname == 's')
2310 {if (XrdOuca2x::a2sz(*eDest, scopts[i].opmsg, val,
2311 &lpp, scopts[i].minv)) return 1;
2312 XrdSysThread::setStackSize((size_t)lpp);
2313 break;
2314 }
2315 else if (XrdOuca2x::a2i(*eDest, scopts[i].opmsg, val,
2316 &ppp,scopts[i].minv)) return 1;
2317 *scopts[i].oploc = ppp;
2318 break;
2319 }
2320 if (i >= numopts)
2321 eDest->Say("Config warning: ignoring invalid sched option '",val,"'.");
2322 val = Config.GetWord();
2323 }
2324
2325// Make sure specified quantities are consistent
2326//
2327 if (V_maxt > 0)
2328 {if (V_mint > 0 && V_mint > V_maxt)
2329 {eDest->Emsg("Config", "sched mint must be less than maxt");
2330 return 1;
2331 }
2332 if (V_avlt > 0 && V_avlt > V_maxt)
2333 {eDest->Emsg("Config", "sched avlt must be less than maxt");
2334 return 1;
2335 }
2336 }
2337
2338// Establish scheduler options
2339//
2340 Sched.setParms(V_mint, V_maxt, V_avlt, V_idle);
2341 return 0;
2342}
2343
2344/******************************************************************************/
2345/* x s i t */
2346/******************************************************************************/
2347
2348/* Function: xsit
2349
2350 Purpose: To parse directive: sitename <name>
2351
2352 <name> is the 1- to 15-character site name to be included in
2353 monitoring information. This can also come from the
2354 command line -N option. The first such name is used.
2355
2356 Output: 0 upon success or 1 upon failure.
2357*/
2358
2359int XrdConfig::xsit(XrdSysError *eDest, XrdOucStream &Config)
2360{
2361 char *val;
2362
2363 if (!(val = Config.GetWord()))
2364 {eDest->Emsg("Config", "sitename value not specified"); return 1;}
2365
2366 if (mySitName) eDest->Emsg("Config", "sitename already specified, using '",
2367 mySitName, "'.");
2368 else mySitName = XrdOucSiteName::Set(val, 63);
2369 return 0;
2370}
2371
2372/******************************************************************************/
2373/* x t c p m o n */
2374/******************************************************************************/
2375
2376/* Function: xtcpmon
2377
2378 Purpose: To parse the directive: tcpmonlib [++] <path> [<parms>]
2379
2380 <path> absolute path to the tcp monitor plugin.
2381 <parms> optional parameters passed to the plugin.
2382
2383 Output: 0 upon success or !0 upon failure.
2384*/
2385
2386int XrdConfig::xtcpmon(XrdSysError *eDest, XrdOucStream &Config)
2387{
2388 std::string path;
2389 char *val, parms[2048];
2390 bool push = false;
2391
2392// Get the path or the push token
2393//
2394 if ((val = Config.GetWord()))
2395 {if (!strcmp(val, "++"))
2396 {push = true;
2397 val = Config.GetWord();
2398 }
2399 }
2400
2401// Make sure a path was specified
2402//
2403 if (!val || !*val)
2404 {eDest->Emsg("Config", "tcpmonlib not specified"); return 1;}
2405
2406// Make sure the path is absolute
2407//
2408 if (*val != '/')
2409 {eDest->Emsg("Config", "tcpmonlib path is not absolute"); return 1;}
2410
2411// Sequester the path as we will get additional tokens
2412//
2413 path = val;
2414
2415// Record any parms
2416//
2417 if (!Config.GetRest(parms, sizeof(parms)))
2418 {eDest->Emsg("Config", "tcpmonlib parameters too long"); return 1;}
2419
2420// Check if we have a plugin info object (we will need one for this)
2421//
2422 if (!tmoInfo) tmoInfo = new XrdTcpMonInfo("xrd.tcpmonlib",ConfigFN,*eDest);
2423
2424// Add the plugin
2425//
2426 tmoInfo->KingPin.Add(path.c_str(), (*parms ? parms : 0), push);
2427
2428// All done
2429//
2430 return 0;
2431}
2432
2433/******************************************************************************/
2434/* x t l s */
2435/******************************************************************************/
2436
2437/* Function: xtls
2438
2439 Purpose: To parse directive: tls <cpath> [<kpath>] [<opts>]
2440
2441 <cpath> is the the certificate file to be used.
2442 <kpath> is the the private key file to be used.
2443 <opts> options:
2444 [no]detail do [not] print TLS library msgs
2445 hsto <sec> handshake timeout (default 10).
2446
2447 Output: 0 upon success or 1 upon failure.
2448*/
2449
2450int XrdConfig::xtls(XrdSysError *eDest, XrdOucStream &Config)
2451{
2452 char *val;
2453 int num;
2454
2455 if (!(val = Config.GetWord()))
2456 {eDest->Emsg("Config", "tls cert path not specified"); return 1;}
2457
2458 if (*val != '/')
2459 {eDest->Emsg("Config", "tls cert path not absolute"); return 1;}
2460
2461 if (tlsCert) free(tlsCert);
2462 tlsCert = strdup(val);
2463 if (tlsKey) free(tlsKey);
2464 tlsKey = 0;
2465
2466 if (!(val = Config.GetWord())) return 0;
2467
2468 if (*val == '/')
2469 {tlsKey = strdup(val);
2470 if (!(val = Config.GetWord())) return 0;
2471 }
2472
2473do { if (!strcmp(val, "detail")) SSLmsgs = true;
2474 else if (!strcmp(val, "nodetail")) SSLmsgs = false;
2475 else if (!strcmp(val, "hsto" ))
2476 {if (!(val = Config.GetWord()))
2477 {eDest->Emsg("Config", "tls hsto value not specified");
2478 return 1;
2479 }
2480 if (XrdOuca2x::a2tm(*eDest,"tls hsto",val,&num,1,255))
2481 return 1;
2482 tlsOpts = TLS_SET_HSTO(tlsOpts,num);
2483 }
2484 else {eDest->Emsg("Config", "invalid tls option -",val); return 1;}
2485 } while ((val = Config.GetWord()));
2486
2487 return 0;
2488}
2489
2490/******************************************************************************/
2491/* x t l s c a */
2492/******************************************************************************/
2493
2494/* Function: xtlsca
2495
2496 Purpose: To parse directive: tlsca noverify | <parms> [<opts>]
2497
2498 parms: {certdir | certfile} <path>
2499
2500 opts: allow-missing-crl
2501
2502 [crlcheck {all | external | last}] [log {failure | off}]
2503
2504 [[no]proxies] [refresh t[m|h|s]] [verdepth <n>]
2505
2506 noverify client's cert need not be verified.
2507 <path> is the the certificate path or file to be used.
2508 Both a file and a directory path can be specified.
2509 allow-missing-crl
2510 Ignores possible missing certificates crls which are
2511 presumed to be empty.
2512 crlcheck Controls internal crl checks:
2513 all applies crls to the full chain
2514 external leaves crl checking to an external plug-in
2515 last applies crl check to the last cert only
2516 log logs verification attempts: "failure" (the default) logs
2517 verification failures, while "off" logs nothing.
2518 proxies allows proxy certs while noproxies does not.
2519 <t> the crl/ca refresh interval.
2520 <n> the maximum certificate depth to be check.
2521
2522 Output: 0 upon success or 1 upon failure.
2523*/
2524
2525int XrdConfig::xtlsca(XrdSysError *eDest, XrdOucStream &Config)
2526{
2527 char *val, **cadest, kword[16];
2528 int vd, rt;
2529 bool isdir;
2530
2531 if (!(val = Config.GetWord()))
2532 {eDest->Emsg("Config", "tlsca parameter not specified"); return 1;}
2533 tlsNoCAD = false;
2534
2535 if (!strcmp(val, "noverify"))
2536 {tlsNoVer = true;
2537 if (caDir) {free(caDir); caDir = 0;}
2538 if (caFile) {free(caFile); caFile = 0;}
2539 return 0;
2540 }
2541 tlsNoVer = false;
2542
2543 do {if (!strcmp(val, "proxies") || !strcmp("noproxies", val))
2544 {if (*val == 'n') tlsOpts |= XrdTlsContext::nopxy;
2545 else tlsOpts &= ~XrdTlsContext::nopxy;
2546 continue;
2547 }
2548
2549 if (!strcmp(val,"allow-missing-crl")) {
2550 tlsOpts |= XrdTlsContext::crlAM;
2551 continue;
2552 }
2553
2554 if (strlen(val) >= (int)sizeof(kword))
2555 {eDest->Emsg("Config", "Invalid tlsca parameter -", val);
2556 return 1;
2557 }
2558 strcpy(kword, val);
2559
2560 if (!(val = Config.GetWord()))
2561 {eDest->Emsg("Config", "tlsca", kword, "value not specified");
2562 return 1;
2563 }
2564 if ((isdir = !strcmp(kword, "certdir"))
2565 || !strcmp(kword, "certfile"))
2566 {if (*val != '/')
2567 {eDest->Emsg("Config","tlsca",kword,"path is not absolute.");
2568 return 1;
2569 }
2570 cadest = (isdir ? &caDir : &caFile);
2571 if (*cadest) free(*cadest);
2572 *cadest = strdup(val);
2573 }
2574 else if (!strcmp(kword, "crlcheck"))
2576 if (!strcmp(val, "all")) tlsOpts |= XrdTlsContext::crlFC;
2577 else if (!strcmp(val, "last")) tlsOpts |= XrdTlsContext::crlON;
2578 else if ( strcmp(val, "external"))
2579 {eDest->Emsg("Config","Invalid tlsca crlcheck "
2580 " argument -",val);
2581 return 1;
2582 }
2583 }
2584 else if (!strcmp(kword, "log"))
2585 { if (!strcmp(val, "off"))
2586 tlsOpts &= ~XrdTlsContext::logVF;
2587 else if (!strcmp(val, "failure"))
2588 tlsOpts |= XrdTlsContext::logVF;
2589 else {eDest->Emsg("Config","Invalid tlsca log argument -",val);
2590 return 1;
2591 }
2592 }
2593 else if (!strcmp(kword, "refresh"))
2594 {if (XrdOuca2x::a2tm(*eDest, "tlsca refresh interval",
2595 val, &rt,1,std::min(int((XrdTlsContext::crlRF >> XrdTlsContext::crlRS) * 60),std::numeric_limits<int>::max()))) return 1;
2596 if (rt < 60) rt = 60;
2597 else if (rt % 60) rt += 60;
2598 rt = rt/60;
2599 tlsOpts = TLS_SET_REFINT(tlsOpts,rt);
2600 }
2601 else if (!strcmp(kword, "verdepth"))
2602 {if (XrdOuca2x::a2i(*eDest,"tlsca verdepth",val,&vd,1,255))
2603 return 1;
2604 tlsOpts = TLS_SET_VDEPTH(tlsOpts,vd);
2605 } else {eDest->Emsg("Config", "invalid tlsca option -",kword); return 1;}
2606
2607 } while((val = Config.GetWord()));
2608
2609 return 0;
2610}
2611
2612/******************************************************************************/
2613/* x t l s c i */
2614/******************************************************************************/
2615
2616/* Function: xtlsci
2617
2618 Purpose: To parse directive: tlsciphers <ciphers>
2619
2620 <ciphers> list of colon sperated ciphers to use.
2621
2622 Output: 0 upon success or 1 upon failure.
2623*/
2624
2625int XrdConfig::xtlsci(XrdSysError *eDest, XrdOucStream &Config)
2626{
2627 char *val, *ciphers;
2628
2629 if (!(val = Config.GetWord()))
2630 {eDest->Emsg("Config", "tlsciphers parameter not specified"); return 1;}
2631
2632 ciphers = strdup(val);
2633
2634 if ((val = Config.GetWord()))
2635 {eDest->Emsg("Config","Invalid tlsciphers argument -",val);
2636 return 1;
2637 }
2638
2640 return 0;
2641}
2642
2643/******************************************************************************/
2644/* x t m o */
2645/******************************************************************************/
2646
2647/* Function: xtmo
2648
2649 Purpose: To parse directive: timeout [read <msd>] [hail <msh>]
2650 [idle <msi>] [kill <msk>]
2651
2652 <msd> is the maximum number of seconds to wait for pending
2653 data to arrive before we reschedule the link
2654 (default is 5 seconds).
2655 <msh> is the maximum number of seconds to wait for the initial
2656 data after a connection (default is 30 seconds)
2657 <msi> is the minimum number of seconds a connection may remain
2658 idle before it is closed (default is 5400 = 90 minutes)
2659 <msk> is the minimum number of seconds to wait after killing a
2660 connection for it to end (default is 3 seconds)
2661
2662 Output: 0 upon success or 1 upon failure.
2663*/
2664
2665int XrdConfig::xtmo(XrdSysError *eDest, XrdOucStream &Config)
2666{
2667 char *val;
2668 int i, ppp, rc;
2669 int V_read = -1, V_idle = -1, V_hail = -1, V_kill = -1;
2670 struct tmoopts { const char *opname; int istime; int minv;
2671 int *oploc; const char *etxt;}
2672 tmopts[] =
2673 {
2674 {"read", 1, 1, &V_read, "timeout read"},
2675 {"hail", 1, 1, &V_hail, "timeout hail"},
2676 {"idle", 1, 0, &V_idle, "timeout idle"},
2677 {"kill", 1, 0, &V_kill, "timeout kill"}
2678 };
2679 int numopts = sizeof(tmopts)/sizeof(struct tmoopts);
2680
2681 if (!(val = Config.GetWord()))
2682 {eDest->Emsg("Config", "timeout option not specified"); return 1;}
2683
2684 while (val)
2685 {for (i = 0; i < numopts; i++)
2686 if (!strcmp(val, tmopts[i].opname))
2687 {if (!(val = Config.GetWord()))
2688 {eDest->Emsg("Config","timeout", tmopts[i].opname,
2689 "value not specified");
2690 return 1;
2691 }
2692 rc = (tmopts[i].istime ?
2693 XrdOuca2x::a2tm(*eDest,tmopts[i].etxt,val,&ppp,
2694 tmopts[i].minv) :
2695 XrdOuca2x::a2i (*eDest,tmopts[i].etxt,val,&ppp,
2696 tmopts[i].minv));
2697 if (rc) return 1;
2698 *tmopts[i].oploc = ppp;
2699 break;
2700 }
2701 if (i >= numopts)
2702 eDest->Say("Config warning: ignoring invalid timeout option '",val,"'.");
2703 val = Config.GetWord();
2704 }
2705
2706// Set values and return
2707//
2708 if (V_read > 0) ProtInfo.readWait = V_read*1000;
2709 if (V_hail >= 0) ProtInfo.hailWait = V_hail*1000;
2710 if (V_idle >= 0) ProtInfo.idleWait = V_idle;
2711 XrdLinkCtl::setKWT(V_read, V_kill);
2712 return 0;
2713}
2714
2715/******************************************************************************/
2716/* x t r a c e */
2717/******************************************************************************/
2718
2719/* Function: xtrace
2720
2721 Purpose: To parse the directive: trace <events>
2722
2723 <events> the blank separated list of events to trace. Trace
2724 directives are cummalative.
2725
2726 Output: 0 upon success or 1 upon failure.
2727*/
2728
2729int XrdConfig::xtrace(XrdSysError *eDest, XrdOucStream &Config)
2730{
2731 char *val;
2732 static struct traceopts {const char *opname; int opval;} tropts[] =
2733 {
2734 {"all", TRACE_ALL},
2735 {"off", TRACE_NONE},
2736 {"none", TRACE_NONE},
2737 {"conn", TRACE_CONN},
2738 {"debug", TRACE_DEBUG},
2739 {"mem", TRACE_MEM},
2740 {"net", TRACE_NET},
2741 {"poll", TRACE_POLL},
2742 {"protocol", TRACE_PROT},
2743 {"sched", TRACE_SCHED},
2744 {"tls", TRACE_TLS},
2745 {"tlsctx", TRACE_TLSCTX},
2746 {"tlssio", TRACE_TLSSIO},
2747 {"tlssok", TRACE_TLSSOK}
2748 };
2749 int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
2750
2751 if (!(val = Config.GetWord()))
2752 {eDest->Emsg("Config", "trace option not specified"); return 1;}
2753 while (val)
2754 {if (!strcmp(val, "off")) trval = 0;
2755 else {if ((neg = (val[0] == '-' && val[1]))) val++;
2756 for (i = 0; i < numopts; i++)
2757 {if (!strcmp(val, tropts[i].opname))
2758 {if (neg)
2759 if (tropts[i].opval) trval &= ~tropts[i].opval;
2760 else trval = TRACE_ALL;
2761 else if (tropts[i].opval) trval |= tropts[i].opval;
2762 else trval = TRACE_NONE;
2763 break;
2764 }
2765 }
2766 if (i >= numopts)
2767 eDest->Say("Config warning: ignoring invalid trace option '",val,"'.");
2768 }
2769 val = Config.GetWord();
2770 }
2771 XrdTrace.What = trval;
2772 return 0;
2773}
#define TS_Xeq(x, m)
Definition XrdConfig.cc:160
XrdSysError eDest(0, "HttpMon")
const char * XrdLicense
Definition XrdInfo.cc:39
#define XrdBANNER
Definition XrdInfo.hh:38
#define XrdFORMATB
Definition XrdInfo.hh:36
int optopt
int optind
#define XRDNET_NORLKUP
Definition XrdNetOpts.hh:87
#define XRDNET_KEEPALIVE
Definition XrdNetOpts.hh:63
#define XRDNET_USETLS
Definition XrdNetOpts.hh:91
#define close(a)
Definition XrdPosix.hh:48
#define write(a, b, c)
Definition XrdPosix.hh:121
#define open
Definition XrdPosix.hh:78
#define XRD_STATS_POLL
Definition XrdStats.hh:44
#define XRD_STATS_ADON
Definition XrdStats.hh:37
#define XRD_STATS_SYNC
Definition XrdStats.hh:49
#define XRD_STATS_INFO
Definition XrdStats.hh:40
#define XRD_STATS_LINK
Definition XrdStats.hh:42
#define XRD_STATS_BUFF
Definition XrdStats.hh:41
#define XRD_STATS_SYNCA
Definition XrdStats.hh:50
#define XRD_STATS_PLUG
Definition XrdStats.hh:43
#define XRD_STATS_SCHD
Definition XrdStats.hh:47
#define XRD_STATS_ALLX
Definition XrdStats.hh:39
#define XRD_STATS_PROT
Definition XrdStats.hh:46
#define XRD_STATS_PROC
Definition XrdStats.hh:45
#define XRD_STATS_SGEN
Definition XrdStats.hh:48
#define XRD_STATS_ALLJ
Definition XrdStats.hh:38
if(ec< 0) ec
#define TLS_SET_VDEPTH(cOpts, vdv)
#define TLS_SET_HSTO(cOpts, hstv)
#define TLS_SET_REFINT(cOpts, refi)
#define TRACE_NONE
Definition XrdTrace.hh:34
#define TRACE_DEBUG
Definition XrdTrace.hh:36
#define TRACE_NET
Definition XrdTrace.hh:39
#define TRACE_TLS
Definition XrdTrace.hh:44
#define TRACE_TLSCTX
Definition XrdTrace.hh:45
#define TRACE_TLSSOK
Definition XrdTrace.hh:47
#define TRACE_CONN
Definition XrdTrace.hh:37
#define TRACE_TLSSIO
Definition XrdTrace.hh:46
#define TRACE_MEM
Definition XrdTrace.hh:38
#define TRACE_POLL
Definition XrdTrace.hh:40
#define TRACE_PROT
Definition XrdTrace.hh:41
#define TRACE_SCHED
Definition XrdTrace.hh:42
#define TRACE(act, x)
Definition XrdTrace.hh:63
#define TRACE_ALL
Definition XrdTrace.hh:35
#define TRACING(x)
Definition XrdTrace.hh:70
void Set(int maxmem=-1, int minw=-1)
Definition XrdBuffer.cc:308
void Init(int maxMSZ)
Definition XrdBuffXL.cc:64
XrdConfigProt * Next
Definition XrdConfig.cc:177
void Reset(char *ln, char *pp, int np=-1, bool to=false)
Definition XrdConfig.cc:200
bool tlsVec[XrdProtLoad::PortoMax]
int portVec[XrdProtLoad::PortoMax]
XrdConfigProt(char *pn, char *ln, char *pp, int np=-1, bool to=false)
Definition XrdConfig.cc:212
bool AddPort(int pnum, bool isTLS)
Definition XrdConfig.cc:190
XrdProtocol_Config ProtInfo
Definition XrdConfig.hh:58
XrdInet * NetADM
Definition XrdConfig.hh:59
std::vector< XrdInet * > NetTCP
Definition XrdConfig.hh:60
int ConfigXeq(char *var, XrdOucStream &Config, XrdSysError *eDest=0)
Definition XrdConfig.cc:806
int Configure(int argc, char **argv)
Definition XrdConfig.cc:326
int BindSD(int port, const char *contype="tcp")
Definition XrdInet.cc:130
XrdInet(XrdSysError *erp, XrdNetSecurity *secp=0)
Definition XrdInet.hh:59
static void SetAssumeV4(bool newVal)
Definition XrdInet.hh:63
static XrdNetIF netIF
Definition XrdInet.hh:68
static int Setup(int maxfds, int idlewt)
static void setKWT(int wkSec, int kwSec)
const sockaddr * SockAddr()
const char * Name(const char *eName=0, const char **eText=0)
XrdNetAddr()
Assignment operator and copy constructor are inherited, no need to define.
static void SetIPV4()
static void SetCache(int keeptime)
static void SetIPV6()
static void SetDynDNS(bool onoff)
static bool IPV4Set()
Definition XrdNetAddr.hh:61
static void SetRPIPA(bool rval)
Definition XrdNetIF.cc:878
static int GetIF(XrdOucTList **ifList, const char **eText=0)
Definition XrdNetIF.cc:413
static void Routing(netType nettype)
Definition XrdNetIF.cc:672
static void SetMsgs(XrdSysError *erp)
Definition XrdNetIF.cc:872
static bool SetIFNames(char *ifnames)
Definition XrdNetIF.cc:765
static void SetFQN(const char *fqn)
static void Start(XrdSysLogger *logP, XrdScheduler *sP)
static int ProtoID(const char *pName)
static int ServPort(const char *sName, bool isUDP=false, const char **eText=0)
int Port()
Definition XrdNet.hh:191
void setDomain(const char *dname)
Definition XrdNet.hh:236
void setDefaults(int options, int buffsz=0)
Definition XrdNet.hh:226
void PutInt(const char *varname, long value)
Definition XrdOucEnv.cc:250
static int Export(const char *Var, const char *Val)
Definition XrdOucEnv.cc:170
void * GetPtr(const char *varname)
Definition XrdOucEnv.cc:263
void PutPtr(const char *varname, void *value)
Definition XrdOucEnv.cc:298
void Put(const char *varname, const char *value)
Definition XrdOucEnv.hh:85
static bool configLog(XrdSysError &eDest, configLogInfo &logInfo)
static const char * Set(const char *name, int maxlen=15)
static XrdOucString * Capture()
int length() const
void resize(int lmx=0)
const char * c_str() const
static char * parseHome(XrdSysError &eDest, XrdOucStream &Config, int &mode)
static const mode_t pathMode
static char * genPath(const char *path, const char *inst, const char *psfx=0)
static int ReLink(const char *path, const char *target, mode_t mode=0)
static const char * InstName(int TranOpt=0)
static int doIf(XrdSysError *eDest, XrdOucStream &Config, const char *what, const char *hname, const char *nname, const char *pname)
static int makePath(char *path, mode_t mode, bool reset=false)
static bool PidFile(XrdSysError &eDest, const char *path)
static void makeHome(XrdSysError &eDest, const char *inst)
static void Undercover(XrdSysError &eDest, int noLog, int *pipeFD=0)
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
static int Setup(int numfd)
Definition XrdPoll.cc:291
static const int PortoMax
static int Port(const char *lname, const char *pname, char *parms, XrdProtocol_Config *pi)
static int Load(const char *lname, const char *pname, char *parms, XrdProtocol_Config *pi, bool istls)
static const int admPSet
const char * myName
XrdBuffManager * BPool
XrdScheduler * Sched
XrdTlsContext * tlsCtx
const char * AdmPath
XrdSysError * eDest
XrdOucString * totalCF
XrdOucEnv * theEnv
const char * myProg
const char * myInst
void setParms(int minw, int maxw, int avlt, int maxi, int once=0)
void setNproc(const bool limlower)
void Init(char **Dest, int iVal=600, int xOpts=0, int jOpts=0)
Definition XrdStats.cc:155
XrdStats(XrdSysError *eP, XrdScheduler *sP, XrdBuffManager *bP, const char *hn, int port, const char *in, const char *pn, const char *sn)
Definition XrdStats.cc:83
void SetPort(int port)
Definition XrdStats.cc:110
void Export(XrdOucEnv &env)
Definition XrdStats.cc:145
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
XrdSysLogger * logger(XrdSysLogger *lp=0)
void AddMsg(const char *msg)
const char * xlogFN()
int ParseKeep(const char *arg)
static void setDebug(XrdSysError *erp)
static void setStackSize(size_t stsz, bool force=false)
static int FmtUname(char *buff, int blen)
XrdOucPinKing< XrdTcpMonPin > KingPin
Definition XrdConfig.cc:234
XrdOucEnv theEnv
Definition XrdConfig.cc:242
XrdTcpMonInfo(const char *drctv, const char *cfn, XrdSysError &errR)
Definition XrdConfig.cc:236
static const int crlRS
Bits to shift vdept.
static void SetDefaultCiphers(const char *ciphers)
static const uint64_t servr
This is a server context.
static const uint64_t nopxy
Do not allow proxy certs.
static const uint64_t logVF
Log verify failures.
static const uint64_t crlFC
Full crl chain checking.
static const uint64_t crlON
Enables crl checking.
static const uint64_t crlAM
Allow CA validation when CRL is missing (CRL soft-fail).
static const uint64_t crlRF
Mask to isolate crl refresh in min.
static void SetMsgCB(msgCB_t cbP)
Definition XrdTls.cc:196
static const int dbgSIO
Turn debugging in for socket I/O.
Definition XrdTls.hh:102
static const int dbgSOK
Turn debugging in for socket operations.
Definition XrdTls.hh:101
static const int dbgALL
Turn debugging for everything.
Definition XrdTls.hh:103
static const int dbgCTX
Turn debugging in for context operations.
Definition XrdTls.hh:100
static void SetDebug(int opts, XrdSysLogger *logP=0)
Definition XrdTls.cc:177
XrdCmsConfig Config
XrdOucEnv theEnv
XrdTlsContext * tlsCtx
Definition XrdGlobals.cc:52
XrdTcpMonPin * TcpMonPin
Definition XrdLinkXeq.cc:80
XrdInet * XrdNetTCP
Definition XrdGlobals.cc:53
XrdSysError Log
Definition XrdConfig.cc:113
XrdBuffXL xlBuff
Definition XrdBuffer.cc:68
XrdScheduler Sched
Definition XrdLinkCtl.cc:54
XrdSysLogger Logger
Definition XrdGlobals.cc:47
XrdSysTrace XrdTrace
Definition XrdTrace.hh:56
XrdOucString totalCF
Definition XrdConfig.cc:111
XrdBuffManager BuffPool
Definition XrdGlobals.cc:51
XrdNetRefresh * NetRefresh