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