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