46#include <sys/resource.h>
53#include "XrdVersion.hh"
95#if defined(__linux__) || defined(__GNU__)
96#include <netinet/tcp.h>
102#include <AvailabilityMacros.h>
143void TlsError(
const char *tid,
const char *msg,
bool sslmsg)
151 const char *XrdConfig::TraceID =
"Config";
157#define TS_Xeq(x,m) if (!strcmp(x,var)) return m(eDest, Config);
188 {
for (
int i = 0; i <
numP; i++)
189 if (pnum == portVec[i])
190 {tlsVec[i] = isTLS;
return true;}
192 portVec[
numP] = pnum; tlsVec[
numP] = isTLS;
197void Reset(
char *ln,
char *pp,
int np=-1,
bool to=
false)
202 memset(portVec, 0,
sizeof(portVec));
204 memset(tlsVec, 0,
sizeof(tlsVec));
212 {memset(portVec, 0,
sizeof(portVec)); port = np;
213 memset(tlsVec, 0,
sizeof(tlsVec)); dotls = to;
235 {
theEnv.Put(
"configFN", cfn);}
258 AdminPath= strdup(
"/tmp");
260 PidPath = strdup(
"/tmp");
286 Firstcp = Lastcp = 0;
318 Sched.setNproc(
true);
334 const char *xrdInst=
"XRDINSTANCE=";
336 int retc, NoGo = 0, clPort = -1;
338 char c, buff[512], *dfltProt, *libProt = 0;
342 extern int optind, opterr;
344 int pipeFD[2] = {-1, -1};
345 const char *pidFN = 0;
346 static const int myMaxc = 80;
347 char **urArgv, *myArgv[myMaxc], argBuff[myMaxc*3+8];
348 char *argbP = argBuff, *argbE = argbP+
sizeof(argBuff)-4;
350 int myArgc = 1, urArgc = argc, i;
351 bool noV6, ipV4 =
false, ipV6 =
false, rootChk =
true, optbg =
false;
356 for (
int k = 1; k < argc; k++)
357 {CmdLine +=
' '; CmdLine += argv[k];}
361 retc = strlen(argv[0]);
362 while(retc--)
if (argv[0][retc] ==
'/')
break;
363 myProg = &argv[0][retc+1];
370 {
char *p = dfltProt = strdup(myProg);
371 while(*p && (*p ==
'.' || *p ==
'-')) p++;
373 {
char *dot = index(p,
'.'), *dash = index(p,
'-');
374 if (dot && (dot < dash || !dash)) p = dot;
375 else if (dash) p = dash;
378 if (!strcmp(
"xrootd", dfltProt)) dfltProt[5] = 0;
379 else if (!strcmp(
"cmsd", dfltProt)) dfltProt[3] = 0;
389 {
if (*(argv[i]) ==
'-' && *(argv[i]+1) ==
'+')
390 {
int n = strlen(argv[i]+2), j = i+1, k = 1;
391 if (urArgc == argc) urArgc = i;
392 if (n) memcpy(buff, argv[i]+2, (n > 256 ? 256 : n));
393 strcpy(&(buff[n]),
".argv**");
394 while(j < argc && (*(argv[j]) !=
'-' || *(argv[j]+1) !=
'+')) j++;
395 urArgv =
new char*[j-i+1];
398 while(i < j) urArgv[k++] = argv[i++];
400 theEnv.
PutPtr(buff, urArgv);
401 strcpy(&(buff[n]),
".argc");
402 theEnv.
PutInt(buff,
static_cast<long>(k));
405 theEnv.
PutPtr(
"argv[0]", argv[0]);
411 if (argc > 1 &&
'-' == *argv[1])
412 while ((c = getopt(urArgc,argv,
":a:A:bc:dhHI:k:l:L:n:N:p:P:R:s:S:vw:W:z"))
413 && ((
unsigned char)c != 0xff))
416 case 'a':
if (AdminPath) free(AdminPath);
417 AdminPath = strdup(optarg);
418 AdminMode =
ProtInfo.AdmMode = S_IRWXU;
421 case 'A':
if (AdminPath) free(AdminPath);
422 AdminPath = strdup(optarg);
423 AdminMode =
ProtInfo.AdmMode = S_IRWXU | S_IRWXG;
426 case 'b': optbg =
true;
428 case 'c':
if (ConfigFN) free(ConfigFN);
429 ConfigFN = strdup(optarg);
439 case 'I':
if (!strcmp(
"v4", optarg)) {ipV4 =
true; ipV6 =
false;}
440 else if (!strcmp(
"v6", optarg)) {ipV4 =
false; ipV6 =
true;}
441 else {
Log.Emsg(
"Config",
"Invalid -I argument -",optarg);
445 case 'k':
if (!(LogInfo.
keepV =
Log.logger()->ParseKeep(optarg)))
446 {
Log.Emsg(
"Config",
"Invalid -k argument -",optarg);
450 case 'l': LogInfo.
logArg = optarg;
452 case 'L':
if (!*optarg)
453 {
Log.Emsg(
"Config",
"Protocol library path not specified.");
456 if (libProt) free(libProt);
457 libProt = strdup(optarg);
459 case 'n': myInsName = (!strcmp(optarg,
"anon")||!strcmp(optarg,
"default")
466 case 'P':
if (dfltProt) free(dfltProt);
467 dfltProt = strdup(optarg);
469 case 'R':
if (!(getUG(optarg, myUid, myGid)))
Usage(1);
472 case 's': pidFN = optarg;
474 case 'S': mySitName = optarg;
476 case ':': buff[0] =
'-'; buff[1] =
optopt; buff[2] = 0;
477 Log.Emsg(
"Config", buff,
"parameter not specified.");
480 case 'v': std::cerr <<XrdVSTRING <<std::endl;
483 case 'w':
if (HomePath) free(HomePath);
484 HomePath = strdup(optarg);
488 case 'W':
if (HomePath) free(HomePath);
489 HomePath = strdup(optarg);
490 HomeMode = S_IRWXU | S_IRGRP | S_IXGRP;
493 case 'z': LogInfo.
hiRes =
true;
497 {
Log.Emsg(
"Config",
"Long options are not supported.");
500 if (myArgc >= myMaxc || argbP >= argbE)
501 {
Log.Emsg(
"Config",
"Too many command line arguments.");
504 myArgv[myArgc++] = argbP;
505 *argbP++ =
'-'; *argbP++ =
optopt; *argbP++ = 0;
513 {
Log.Emsg(
"Config",
"Command line adminpath is not absolute.");
519 if (HomePath && *HomePath !=
'/')
520 {
Log.Emsg(
"Config",
"Command line home path is not absolute.");
527 if (ConfigFN) setCFG(
true);
533 else if (ipV6){
if (noV6)
Log.Say(
"Config warning: ipV6 appears to be broken;"
534 " forced ipV6 mode not advised!");
537 else if (noV6)
Log.Say(
"Config warning: ipV6 is misconfigured or "
538 "unavailable; reverting to ipV4.");
546 if (myGid && setegid(myGid))
547 {
Log.Emsg(
"Config", errno,
"set effective gid"); exit(17);}
548 if (myUid && seteuid(myUid))
549 {
Log.Emsg(
"Config", errno,
"set effective uid"); exit(17);}
553 if (rootChk && geteuid() == 0)
554 {
Log.Emsg(
"Config",
"Security reasons prohibit running as "
555 "superuser; program is terminating.");
561 if (urArgc-
optind+2 >= myMaxc)
562 {
Log.Emsg(
"Config",
"Too many command line arguments.");
580 if (pipe( pipeFD ) == -1)
581 {
Log.Emsg(
"Config", errno,
"create a pipe"); exit(17);}
590 if (!(myName = myIPAddr->
Name(0, &temp))) myName =
"";
603 sprintf(buff,
"%s%s %s@%s", xrdInst, myProg,
ProtInfo.myInst, myName);
604 myInstance = strdup(buff);
606 myInstance += strlen(xrdInst);
614 {LogInfo.
xrdEnv = &theEnv;
615 LogInfo.
iName = myInsName;
616 LogInfo.
cfgFn = ConfigFN;
618 Log.logger()->AddMsg(CmdLine.
c_str());
627 {
Log.Emsg(
"Config",
"Unable to determine host name; ",
628 (temp ? temp :
"reason unknown"),
629 "; execution terminated.");
639 strcpy(buff,
"Starting on ");
651 {
Log.Emsg(
"Config",myName,
"does not appear to be registered in the DNS.");
652 Log.Emsg(
"Config",
"Verify that the '/etc/hosts' file is correct and "
653 "this machine is registered in DNS.");
654 Log.Emsg(
"Config",
"Execution continues but connection failures may occur.");
656 }
else if (!(myDomain = index(myName,
'.')))
657 Log.Say(
"Config warning: this hostname, ", myName,
658 ", is registered without a domain qualification.");
662 Firstcp = Lastcp =
new XrdConfigProt(strdup(dfltProt), libProt, 0);
666 Log.Say(
"++++++ ", myInstance,
" initialization started.");
670 devNull = XrdSysFD_Open(
"/dev/null", O_RDONLY);
672 {
Log.Emsg(
"Config", errno,
"open '/dev/null' which is required!");
679 {
Log.Say(
"Config using configuration file ", ConfigFN);
683 if (clPort >= 0) PortTCP = clPort;
691 NoGo |= SetupAPath();
697 else {
Log.Say(
"++++++ ", myInstance,
" TLS initialization started.");
699 {
Log.Say(
"------ ",myInstance,
" TLS initialization ended.");
704 Log.Say(
"------ ",myInstance,
" TLS initialization failed.");
714 {
Log.Say(
"Config TLS port specification ignored; TLS not configured!");
718 ProtInfo.tlsPort = (PortTLS > 0 ? PortTLS : 0);
734 {
Log.Emsg(
"Config",
"Unable to determine interface addresses!");
740 if ((myInsName || HomePath)
745 if (!PidFile(pidFN, optbg)) NoGo = 1;
749 if (!NoGo) Manifest(pidFN);
753 if (!NoGo) NoGo = Setup(dfltProt, libProt);
762 if (tmoInfo && !NoGo)
763 {
void *theGS = theEnv.
GetPtr(
"TcpMon.gStream*");
764 if (!theGS)
Log.Say(
"Config warning: TCP monitoring not enabled; "
765 "tcpmonlib plugin not loaded!");
766 else {tmoInfo->theEnv.PutPtr(
"TcpMon.gStream*", theGS);
767 TcpMonPin = tmoInfo->KingPin.Load(
"TcpMonPin");
777 int status = NoGo ? 1 : 0;
778 if(
write( pipeFD[1], &status,
sizeof( status ) )) {};
785 temp = (NoGo ?
" initialization failed." :
" initialization completed.");
786 sprintf(buff,
"%s:%d", myInstance, PortTCP);
787 Log.Say(
"------ ", buff, temp);
789 {strcat(buff,
" running ");
792 Log.logger()->AddMsg(buff);
807 if (
eDest) dynamic = 1;
821 TS_Xeq(
"adminpath", xapath);
823 TS_Xeq(
"homepath", xhpath);
827 TS_Xeq(
"protocol", xprot);
830 TS_Xeq(
"tcpmonlib", xtcpmon);
834 TS_Xeq(
"tlsciphers", xtlsci);
839 eDest->Say(
"Config warning: ignoring unknown xrd directive '",var,
"'.");
851int XrdConfig::ASocket(
const char *path,
const char *fname, mode_t mode)
853 struct sockaddr_un unixvar;
854 int plen = strlen(path), flen = strlen(fname);
858 if ((plen + flen + 3) > (
int)
sizeof(unixvar.sun_path))
859 {
Log.Emsg(
"Config",
"admin path", path,
"too long");
894int XrdConfig::ConfigProc()
897 int cfgFD, retc, NoGo = 0;
899 XrdOucStream
Config(&
Log, myInstance, &myEnv,
"=====> ");
903 if ( (cfgFD =
open(ConfigFN, O_RDONLY, 0)) < 0)
904 {
Log.
Emsg(
"Config", errno,
"open config file", ConfigFN);
911 while((var =
Config.GetMyFirstWord()))
912 if (!strncmp(var,
"xrd.", 4)
913 || !strcmp (var,
"all.adminpath")
914 || !strcmp (var,
"all.pidpath")
915 || !strcmp (var,
"all.sitename" ))
920 if ((retc =
Config.LastError()))
921 NoGo =
Log.
Emsg(
"Config", retc,
"read config file", ConfigFN);
933XrdInet *XrdConfig::getNet(
int port,
bool isTLS)
935 int the_Opts, the_Blen;
939 for (
int i = 0; i < (int)
NetTCP.size(); i++)
944 XrdInet *newNet =
new XrdInet(&
Log, Police);
950 {the_Opts = TLS_Opts; the_Blen = TLS_Blen;
952 the_Opts = Net_Opts; the_Blen = Net_Blen;
954 if (the_Opts || the_Blen) newNet->
setDefaults(the_Opts, the_Blen);
958 if (myDomain) newNet->
setDomain(myDomain);
962 if (newNet->
BindSD(port,
"tcp") == 0)
return newNet;
971int XrdConfig::getUG(
char *parm, uid_t &newUid, gid_t &newGid)
978 {
Log.
Emsg(
"Config",
"-R user not specified.");
return 0;}
981 {
if (!(newUid = atol(parm)))
982 {
Log.
Emsg(
"Config",
"-R", parm,
"is invalid");
return 0;}
983 pp = getpwuid(newUid);
985 else pp = getpwnam(parm);
990 {
Log.
Emsg(
"Config", errno,
"retrieve -R user password entry");
993 if (!(newUid = pp->pw_uid))
994 {
Log.
Emsg(
"Config",
"-R", parm,
"is still unacceptably a superuser!");
1005void XrdConfig::Manifest(
const char *pidfn)
1008 char envBuff[8192], pwdBuff[2048], manBuff[1024], *pidP, *sP, *xP;
1013 if (!getcwd(pwdBuff,
sizeof(pwdBuff)))
1014 {
Log.
Emsg(
"Config",
"Unable to get current working directory!");
1020 if (HomePath) free(HomePath);
1021 HomePath = strdup(pwdBuff);
1026 envLen = strlen(envBuff);
1027 if (envBuff[envLen-1] !=
'/') {envBuff[envLen] =
'/'; envLen++;}
1028 strcpy(envBuff+envLen,
".xrd/");
1029 xP = envBuff+envLen+5;
1033 if ((sP = getenv(
"XRDCONFIGFN")))
1034 {sprintf(xP,
"=/conf/%s.cf", myProg);
1040 sprintf(xP,
"=/core/%s", myProg);
1045 if ((sP = getenv(
"XRDLOGDIR")))
1046 {sprintf(xP,
"=/logs/%s", myProg);
1053 sprintf(xP,
"=/proc/%s", myProg);
1054 sprintf(manBuff,
"/proc/%d", getpid());
1060 envLen = snprintf(envBuff,
sizeof(envBuff),
"pid=%d&host=%s&inst=%s&ver=%s"
1061 "&home=%s&cfgfn=%s&cwd=%s&apath=%s&logfn=%s",
1062 static_cast<int>(getpid()),
ProtInfo.myName,
1063 ProtInfo.myInst, XrdVSTRING, HomePath,
1064 (getenv(
"XRDCONFIGFN") ? getenv(
"XRDCONFIGFN") :
""),
1069 if (pidfn && (Slash = rindex(pidfn,
'/')))
1070 {strncpy(manBuff, pidfn, Slash-pidfn); pidP = manBuff+(Slash-pidfn);}
1071 else {strcpy(manBuff,
ProtInfo.AdmPath); pidP = manBuff+strlen(
ProtInfo.AdmPath);}
1075 snprintf(pidP,
sizeof(manBuff)-(pidP-manBuff),
"/%s.%s.env",
1081 if ((envFD =
open(manBuff, O_WRONLY|O_CREAT|O_TRUNC, 0664)) < 0)
1082 {
Log.
Emsg(
"Config", errno,
"create envfile", manBuff);
1088 if (
write(envFD, envBuff, envLen) < 0)
1089 Log.
Emsg(
"Config", errno,
"write to envfile", manBuff);
1097bool XrdConfig::PidFile(
const char *clpFN,
bool optbg)
1100 char *ppath, buff[32], pidFN[1200];
1101 const char *xop = 0;
1115 {xop =
"create"; snprintf(pidFN,
sizeof(pidFN),
"%s", ppath); errno = rc;}
1116 else {snprintf(pidFN,
sizeof(pidFN),
"%s/%s.pid", ppath, myProg);
1118 if ((xfd =
open(pidFN, O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0)
1120 else {
if (
write(xfd,buff,snprintf(buff,
sizeof(buff),
"%d",
1121 static_cast<int>(getpid()))) < 0) xop =
"write";
1129 if (xop)
Log.
Emsg(
"Config", errno, xop, pidFN);
1137void XrdConfig::setCFG(
bool start)
1142 if (!ConfigFN || !(*ConfigFN))
1166 if (*ConfigFN !=
'/')
1167 {
char cwdBuff[1024];
1168 if (getcwd(cwdBuff,
sizeof(cwdBuff)-strlen(ConfigFN)-2))
1169 {
int n = strlen(cwdBuff);
1170 if (cwdBuff[n-1] !=
'/') cwdBuff[n++] =
'/';
1171 strcpy(cwdBuff+n, ConfigFN);
1173 ConfigFN = strdup(cwdBuff);
1186 const char *cvec[] = {
"*** ", myProg,
" config from '", ConfigFN,
"':", 0 };
1194int XrdConfig::setFDL()
1201 if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
1202 return Log.
Emsg(
"Config", errno,
"get FD limit");
1206 if (rlim.rlim_max == RLIM_INFINITY || (isStrict && rlim.rlim_max > maxFD))
1207 rlim.rlim_cur = maxFD;
1208 else rlim.rlim_cur = rlim.rlim_max;
1209#if (defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_5))
1210 if (rlim.rlim_cur > OPEN_MAX) rlim.rlim_max = rlim.rlim_cur = OPEN_MAX;
1212#if defined(__linux__)
1214 unsigned int epoll_max_fd = (INT_MAX /
sizeof(
struct epoll_event));
1215 if (rlim.rlim_cur > (rlim_t)epoll_max_fd) rlim.rlim_max = rlim.rlim_cur = epoll_max_fd;
1217 if (setrlimit(RLIMIT_NOFILE, &rlim) < 0)
1218 return Log.
Emsg(
"Config", errno,
"set FD limit");
1222 if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
1223 return Log.
Emsg(
"Config", errno,
"get FD limit");
1228 sprintf(buff,
"%d",
ProtInfo.ConnMax);
1229 Log.
Say(
"Config maximum number of connections restricted to ", buff);
1233#
if !defined( __solaris__ ) && defined(RLIMIT_CORE)
1235 {
if (getrlimit(RLIMIT_CORE, &rlim) < 0)
1236 Log.
Emsg(
"Config", errno,
"get core limit");
1237 else {rlim.rlim_cur = (coreV ? rlim.rlim_max : 0);
1238 if (setrlimit(RLIMIT_CORE, &rlim) < 0)
1239 Log.
Emsg(
"Config", errno,
"set core limit");
1246#if ( defined(__linux__) || defined(__GNU__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__)) ) && defined(RLIMIT_NPROC)
1250 if (getrlimit(RLIMIT_NPROC, &rlim) < 0)
1251 return Log.
Emsg(
"Config", errno,
"get thread limit");
1255 int nthr =
static_cast<int>(rlim.rlim_cur);
1257 {sprintf(buff,
"%d", static_cast<int>(rlim.rlim_cur));
1258 Log.Say(
"Config maximum number of threads restricted to ", buff);
1269int XrdConfig::Setup(
char *dfltp,
char *libProt)
1272 int xport, protNum = 0;
1276 if (setFDL())
return 1;
1280#if ( defined(__linux__) || defined(__GNU__) ) && defined(TCP_CORK)
1281{
int sokFD, setON = 1;
1282 if ((sokFD = socket(PF_INET, SOCK_STREAM, 0)) >= 0)
1284 &setON,
sizeof(setON));
1285 if (setsockopt(sokFD, SOL_TCP, TCP_CORK, &setON,
sizeof(setON)) < 0)
1321 for (
int i = 0; i < cp->
numP; i++)
1324 "configured with a TLS-only port "
1325 "but TLS is not configured!");
1329 xport = (cp->dotls ? PortTLS : PortTCP);
1330 ProtInfo.Port = (cp->port < 0 ? xport : cp->port);
1333 if (cp->port < 0)
return 1;
1334 for (
int i = 1; i < cp->
numP; i++)
1335 if (cp->port == cp->portVec[i]) cp->portVec[i] = -1;
1350 xport = (strcmp(
"xroot", Firstcp->proname) ? 0 : Firstcp->port);
1358 XrdInet *arbNet = 0, *theNet;
1359 while((cp = Firstcp))
1360 {
for (
int i = 0; i < cp->
numP; i++)
1361 {
if (cp->portVec[i] < 0)
continue;
1362 if (!(cp->portVec[i]) && arbNet) theNet = arbNet;
1363 else {theNet = getNet(cp->portVec[i], cp->tlsVec[i]);
1364 if (!theNet)
return 1;
1365 if (!(cp->portVec[i])) arbNet = theNet;
1379 if (!protNum)
return 1;
1382 if (!strcmp(
"http", cp->
proname) && xport)
1383 {
for (
int i = 0; i < cp->
numP; i++)
1384 {
if (cp->portVec[i] == xport) {xport = 0;
break;}}
1387 Firstcp = cp->
Next;
delete cp;
1399 if (repDest[0] != 0 && repOpts)
1400 {
ProtInfo.Stats->Report(repDest, repInt, repOpts);
1401 theMon =
new XrdMonitor;
1402 XrdMonRoll* monRoll =
new XrdMonRoll(*theMon);
1415int XrdConfig::SetupAPath()
1433 {
Log.
Emsg(
"Config", rc,
"create admin path", AdminPath);
1440 if (chmod(AdminPath, AdminMode & ~S_IWGRP))
1441 {
Log.
Emsg(
"Config", errno,
"set permission for admin path", AdminPath);
1449 return ASocket(AdminPath,
"admin", (mode_t)AdminMode);
1456bool XrdConfig::SetupTLS()
1461 if (!caDir && !caFile && !tlsNoVer)
1463 Log.
Say(
"Config failure: the tlsca directive was not specified!");
1464 else Log.
Say(
"Config failure: the tlsca directive did not specify "
1465 "a certdir or certfile!");
1487 static XrdTlsContext xrdTLS(tlsCert, tlsKey, caDir, caFile, tlsOpts);
1491 if (!xrdTLS.isOK())
return false;
1503void XrdConfig::Usage(
int rc)
1509 std::cerr <<
"\nUsage: " <<myProg <<
" [-b] [-c <cfn>] [-d] [-h] [-H] [-I {v4|v6}]\n"
1510 "[-k {n|sz|sig}] [-l [=]<fn>] [-n <name>] [-N <hname>] [-p <port>]\n"
1511 "[-P <prot>] [-L <libprot>] [-R] [-s pidfile] [-S site] [-v] [-z]\n"
1512 "[<protocol_options>]" <<std::endl;
1513 _exit(rc > 0 ? rc : 0);
1536 mode_t mode = S_IRWXU;
1541 if (!pval || !pval[0])
1542 {
eDest->
Emsg(
"Config",
"adminpath not specified");
return 1;}
1547 {
eDest->
Emsg(
"Config",
"adminpath not absolute");
return 1;}
1551 if (AdminPath) free(AdminPath);
1552 AdminPath = strdup(pval);
1556 if ((val =
Config.GetWord()) && val[0])
1557 {
if (!strcmp(
"group", val)) mode |= S_IRWXG;
1558 else {
eDest->
Emsg(
"Config",
"invalid admin path modifier -", val);
1562 AdminMode =
ProtInfo.AdmMode = mode;
1586 if (!(val =
Config.GetWord()))
1587 {
eDest->
Emsg(
"Config",
"allow type not specified");
return 1;}
1589 if (!strcmp(val,
"host")) ishost = 1;
1590 else if (!strcmp(val,
"netgroup")) ishost = 0;
1591 else {
eDest->
Emsg(
"Config",
"invalid allow type -", val);
1595 if (!(val =
Config.GetWord()))
1596 {
eDest->
Emsg(
"Config",
"allow target name not specified");
return 1;}
1598 if (!Police) {Police =
new XrdNetSecurity();
1601 if (ishost) Police->AddHost(val);
1602 else Police->AddNetGroup(val);
1627 {
eDest->
Say(
"Config warning: command line homepath cannot be overridden.");
1634 if (HomePath) {free(HomePath); HomePath = 0;}
1639 return (HomePath ? 0 : 1);
1660 static const long long minBSZ = 1024*1024*2+1;
1661 static const long long maxBSZ = 1024*1024*1024;
1666 if (!(val =
Config.GetWord()))
1667 {
eDest->
Emsg(
"Config",
"buffer memory limit not specified");
return 1;}
1669 if (!strcmp(
"maxbsz", val))
1670 {
if (!(val =
Config.GetWord()))
1671 {
eDest->
Emsg(
"Config",
"max buffer size not specified");
return 1;}
1675 if (!(val =
Config.GetWord()))
return 0;
1679 (
long long)1024*1024))
return 1;
1681 if ((val =
Config.GetWord()))
1707 long long minV = 1024, maxV = 1024LL*1024LL;
1711 if ((val =
Config.GetWord()))
1712 {
if (!strcmp(val,
"strict"))
1715 }
else isStrict =
false;
1719 {
eDest->
Emsg(
"Config",
"file descriptor limit not specified");
return 1;}
1724 maxFD =
static_cast<unsigned int>(fdVal);
1758 int i, n, V_keep = -1, V_nodnr = 0, V_istls = 0, V_blen = -1, V_ct = -1;
1759 int V_assumev4 = -1, v_rpip = -1, V_dyndns = -1;
1761 struct netopts {
const char *opname;
int hasarg;
int opval;
1762 int *oploc;
const char *etxt;}
1765 {
"assumev4", 0, 1, &V_assumev4,
"option"},
1766 {
"keepalive", 0, 1, &V_keep,
"option"},
1767 {
"nokeepalive",0, 0, &V_keep,
"option"},
1768 {
"kaparms", 4, 0, &V_keep,
"option"},
1769 {
"buffsz", 1, 0, &V_blen,
"network buffsz"},
1770 {
"cache", 2, 0, &V_ct,
"cache time"},
1771 {
"dnr", 0, 0, &V_nodnr,
"option"},
1772 {
"nodnr", 0, 1, &V_nodnr,
"option"},
1773 {
"dyndns", 0, 1, &V_dyndns,
"option"},
1774 {
"nodyndns", 0, 0, &V_dyndns,
"option"},
1775 {
"routes", 3, 1, 0,
"routes"},
1776 {
"rpipa", 0, 1, &v_rpip,
"rpipa"},
1777 {
"norpipa", 0, 0, &v_rpip,
"norpipa"},
1778 {
"tls", 0, 1, &V_istls,
"option"}
1780 int numopts =
sizeof(ntopts)/
sizeof(
struct netopts);
1782 if (!(val =
Config.GetWord()))
1783 {
eDest->
Emsg(
"Config",
"net option not specified");
return 1;}
1786 {
for (i = 0; i < numopts; i++)
1787 if (!strcmp(val, ntopts[i].opname))
1788 {
if (!ntopts[i].hasarg) *ntopts[i].oploc = ntopts[i].opval;
1789 else {
if (!(val =
Config.GetWord()))
1791 ntopts[i].opname,
"argument missing");
1794 if (ntopts[i].hasarg == 4)
1795 {
if (xnkap(
eDest, val))
return 1;
1798 if (ntopts[i].hasarg == 3)
1799 {
if (!strcmp(val,
"split"))
1801 else if (!strcmp(val,
"common"))
1803 else if (!strcmp(val,
"local"))
1805 else {
eDest->
Emsg(
"Config",
"Invalid routes argument -",val);
1808 if (!(val =
Config.GetWord())|| !(*val))
break;
1809 if (strcmp(val,
"use"))
continue;
1810 if (!(val =
Config.GetWord())|| !(*val))
1811 {
eDest->
Emsg(
"Config",
"network routes i/f names "
1819 if (ntopts[i].hasarg == 2)
1822 *ntopts[i].oploc = n;
1826 *ntopts[i].oploc = (int)llp;
1832 eDest->
Say(
"Config warning: ignoring invalid net option '",val,
"'.");
1833 else if (!val)
break;
1838 {
if (V_blen >= 0) TLS_Blen = V_blen;
1842 if (V_blen >= 0) Net_Blen = V_blen;
1849 {
if (V_dyndns && V_ct < 0) V_ct = 0;
1882 if ((comma = index(val,
','))) {val = comma+1; *comma = 0;}
1889 if (!(karg = val))
return 0;
1890 if ((comma = index(val,
','))) {val = comma+1; *comma = 0;}
1926 if (!val || !val[0])
1927 {
eDest->
Emsg(
"Config",
"pidpath not specified");
return 1;}
1931 if (PidPath) free(PidPath);
1932 PidPath = strdup(val);
1953{
int rc, istls = 0, pnum = 0;
1954 char *val, cport[32];
1956 do {
if (!(val =
Config.GetWord()))
1957 {
eDest->
Emsg(
"Config",
"tcp port not specified");
return 1;}
1958 if (strcmp(
"tls", val) || istls)
break;
1962 strncpy(cport, val,
sizeof(cport)-1); cport[
sizeof(cport)-1] =
'\0';
1964 if ((val =
Config.GetWord()) && !strcmp(
"if", val))
1967 {
if (!rc)
Config.noEcho();
return (rc < 0);}
1970 if (istls) PortTLS = pnum;
1971 else PortTCP = PortUDP = pnum;
1998 char *val, *parms, *lib, proname[64], buff[2048];
2002 do {
if (!(val =
Config.GetWord()))
2003 {
eDest->
Emsg(
"Config",
"protocol name not specified");
return 1;}
2004 if (dotls || strcmp(
"tls", val))
break;
2008 if (strlen(val) >
sizeof(proname)-1)
2009 {
eDest->
Emsg(
"Config",
"protocol name is too long");
return 1;}
2010 strcpy(proname, val);
2012 if ((val = index(proname,
':')))
2017 if (!(val =
Config.GetWord()))
2018 {
eDest->
Emsg(
"Config",
"protocol library not specified");
return 1;}
2019 if (!strcmp(
"*", val)) lib = 0;
2020 else if (*val ==
'+')
2021 {
if (strcmp(val,
"+port"))
2022 {
eDest->
Emsg(
"Config",
"invalid library specification -",val);
2025 if ((cpp = Firstcp))
2026 do {
if (!strcmp(proname, cpp->
proname))
2027 {
if (cpp->
AddPort(portnum, dotls))
return 0;
2028 eDest->
Emsg(
"Config",
"port add limit exceeded!");
2031 }
while((cpp = cpp->
Next));
2032 eDest->
Emsg(
"Config",
"protocol",proname,
"not previously defined!");
2035 else lib = strdup(val);
2040 if (!lib && Firstcp && strcmp(proname, Firstcp->proname))
2042 snprintf(eBuff,
sizeof(eBuff),
"the %s protocol is '%s' not '%s'; "
2043 "assuming you meant '%s'",
2044 (Firstcp->libpath ?
"assigned" :
"builtin"),
2045 Firstcp->proname, proname, Firstcp->proname);
2046 eDest->
Say(
"Config warning: ", eBuff,
" but please correct "
2047 "the following directive!");
2048 snprintf(proname,
sizeof(proname),
"%s", Firstcp->proname);
2052 if (!
Config.GetRest(buff,
sizeof(buff)))
2053 {
eDest->
Emsg(
"Config",
"Too many parms for protocol", proname);
2056 parms = (*buff ? strdup(buff) : 0);
2058 if ((cpp = Firstcp))
2059 do {
if (!strcmp(proname, cpp->
proname))
2060 {cpp->
Reset(lib, parms, portnum, dotls);
2063 }
while((cpp = cpp->
Next));
2065 cpp =
new XrdConfigProt(strdup(proname), lib, parms, portnum, dotls);
2066 if (!lib) {cpp->
Next = Firstcp; Firstcp = cpp;
2067 if (!Lastcp) Lastcp = cpp;
2069 else {
if (Lastcp) Lastcp->Next = cpp;
2099 static struct repopts {
const char *opname;
int opval;} rpopts[] =
2114 int i, neg, numopts =
sizeof(rpopts)/
sizeof(
struct repopts);
2117 if (!(val =
Config.GetWord()))
2118 {
eDest->
Emsg(
"Config",
"report parameters not specified");
return 1;}
2122 if (repDest[0]) {free(repDest[0]); repDest[0] = 0;}
2123 if (repDest[1]) {free(repDest[1]); repDest[1] = 0;}
2129 if ((cp = (
char *)index(val,
',')))
2131 {
eDest->
Emsg(
"Config",
"malformed report destination -",val);
return 1;}
2132 else { repDest[1] = cp+1; *cp =
'\0';}
2135 for (i = 0; i < 2; i++)
2136 {
if (!(val = repDest[i]))
break;
2137 if (*val !=
'/' && (!(cp = index(val, (
int)
':')) || !atoi(cp+1)))
2138 {
eDest->
Emsg(
"Config",
"report dest port missing or invalid in",val);
2141 repDest[i] = strdup(val);
2146 if (repDest[0] && repDest[1] && !strcmp(repDest[0], repDest[1]))
2147 {
eDest->
Emsg(
"Config",
"Warning, report dests are identical.");
2148 free(repDest[1]); repDest[1] = 0;
2154 if (!strcmp(
"every", val))
2155 {
if (!(val =
Config.GetWord()))
2156 {
eDest->
Emsg(
"Config",
"report every value not specified");
return 1;}
2164 {
if (!strcmp(val,
"off")) repOpts = 0;
2165 else {
if ((neg = (val[0] ==
'-' && val[1]))) val++;
2166 for (i = 0; i < numopts; i++)
2167 {
if (!strcmp(val, rpopts[i].opname))
2168 {
if (neg) repOpts &= ~rpopts[i].opval;
2169 else repOpts |= rpopts[i].opval;
2174 eDest->
Say(
"Config warning: ignoring invalid report option '",val,
"'.");
2219 int V_mint = -1, V_maxt = -1, V_idle = -1, V_avlt = -1;
2220 struct schedopts {
const char *opname;
int minv;
int *oploc;
2221 const char *opmsg;} scopts[] =
2223 {
"stksz", 0, 0,
"sched stksz"},
2224 {
"mint", 1, &V_mint,
"sched mint"},
2225 {
"maxt", 1, &V_maxt,
"sched maxt"},
2226 {
"avlt", 1, &V_avlt,
"sched avlt"},
2227 {
"core", 1, 0,
"sched core"},
2228 {
"idle", 0, &V_idle,
"sched idle"}
2230 int numopts =
sizeof(scopts)/
sizeof(
struct schedopts);
2232 if (!(val =
Config.GetWord()))
2233 {
eDest->
Emsg(
"Config",
"sched option not specified");
return 1;}
2236 {
for (i = 0; i < numopts; i++)
2237 if (!strcmp(val, scopts[i].opname))
2238 {
if (!(val =
Config.GetWord()))
2239 {
eDest->
Emsg(
"Config",
"sched", scopts[i].opname,
2240 "value not specified");
2243 if (*scopts[i].opname ==
'i')
2245 &ppp, scopts[i].minv))
return 1;
2247 else if (*scopts[i].opname ==
'c')
2248 {
if (!strcmp(
"asis", val)) coreV = -1;
2249 else if (!strcmp(
"max", val)) coreV = 1;
2250 else if (!strcmp(
"off", val)) coreV = 0;
2251 else {
eDest->
Emsg(
"Config",
"invalid sched core value -",val);
2255 else if (*scopts[i].opname ==
's')
2257 &lpp, scopts[i].minv))
return 1;
2262 &ppp,scopts[i].minv))
return 1;
2263 *scopts[i].oploc = ppp;
2267 eDest->
Say(
"Config warning: ignoring invalid sched option '",val,
"'.");
2274 {
if (V_mint > 0 && V_mint > V_maxt)
2275 {
eDest->
Emsg(
"Config",
"sched mint must be less than maxt");
2278 if (V_avlt > 0 && V_avlt > V_maxt)
2279 {
eDest->
Emsg(
"Config",
"sched avlt must be less than maxt");
2309 if (!(val =
Config.GetWord()))
2310 {
eDest->
Emsg(
"Config",
"sitename value not specified");
return 1;}
2312 if (mySitName)
eDest->
Emsg(
"Config",
"sitename already specified, using '",
2335 char *val, parms[2048];
2340 if ((val =
Config.GetWord()))
2341 {
if (!strcmp(val,
"++"))
2350 {
eDest->
Emsg(
"Config",
"tcpmonlib not specified");
return 1;}
2355 {
eDest->
Emsg(
"Config",
"tcpmonlib path is not absolute");
return 1;}
2363 if (!
Config.GetRest(parms,
sizeof(parms)))
2364 {
eDest->
Emsg(
"Config",
"tcpmonlib parameters too long");
return 1;}
2368 if (!tmoInfo) tmoInfo =
new XrdTcpMonInfo(
"xrd.tcpmonlib",ConfigFN,*
eDest);
2372 tmoInfo->KingPin.Add(path.c_str(), (*parms ? parms : 0), push);
2401 if (!(val =
Config.GetWord()))
2402 {
eDest->
Emsg(
"Config",
"tls cert path not specified");
return 1;}
2405 {
eDest->
Emsg(
"Config",
"tls cert path not absolute");
return 1;}
2407 if (tlsCert) free(tlsCert);
2408 tlsCert = strdup(val);
2409 if (tlsKey) free(tlsKey);
2412 if (!(val =
Config.GetWord()))
return 0;
2415 {tlsKey = strdup(val);
2416 if (!(val =
Config.GetWord()))
return 0;
2419do {
if (!strcmp(val,
"detail")) SSLmsgs =
true;
2420 else if (!strcmp(val,
"nodetail")) SSLmsgs =
false;
2421 else if (!strcmp(val,
"hsto" ))
2422 {
if (!(val =
Config.GetWord()))
2423 {
eDest->
Emsg(
"Config",
"tls hsto value not specified");
2430 else {
eDest->
Emsg(
"Config",
"invalid tls option -",val);
return 1;}
2431 }
while ((val =
Config.GetWord()));
2468 char *val, **cadest, kword[16];
2472 if (!(val =
Config.GetWord()))
2473 {
eDest->
Emsg(
"Config",
"tlsca parameter not specified");
return 1;}
2476 if (!strcmp(val,
"noverify"))
2478 if (caDir) {free(caDir); caDir = 0;}
2479 if (caFile) {free(caFile); caFile = 0;}
2485 do {
if (!strcmp(val,
"proxies") || !strcmp(
"noproxies", val))
2487 else tlsOpts &= ~XrdTlsContext::nopxy;
2491 if (strlen(val) >= (
int)
sizeof(kword))
2492 {
eDest->
Emsg(
"Config",
"Invalid tlsca parameter -", val);
2497 if (!(val =
Config.GetWord()))
2498 {
eDest->
Emsg(
"Config",
"tlsca", kword,
"value not specified");
2501 if ((isdir = !strcmp(kword,
"certdir"))
2502 || !strcmp(kword,
"certfile"))
2504 {
eDest->
Emsg(
"Config",
"tlsca",kword,
"path is not absolute.");
2507 cadest = (isdir ? &caDir : &caFile);
2508 if (*cadest) free(*cadest);
2509 *cadest = strdup(val);
2511 else if (!strcmp(kword,
"crlcheck"))
2515 else if ( strcmp(val,
"external"))
2516 {
eDest->
Emsg(
"Config",
"Invalid tlsca crlcheck "
2521 else if (!strcmp(kword,
"log"))
2522 {
if (!strcmp(val,
"off"))
2523 tlsOpts &= ~XrdTlsContext::logVF;
2524 else if (!strcmp(val,
"failure"))
2526 else {
eDest->
Emsg(
"Config",
"Invalid tlsca log argument -",val);
2530 else if (!strcmp(kword,
"refresh"))
2533 if (rt < 60) rt = 60;
2534 else if (rt % 60) rt += 60;
2538 else if (!strcmp(kword,
"verdepth"))
2543 else {
eDest->
Emsg(
"Config",
"invalid tlsca option -",kword);
return 1;}
2545 }
while((val =
Config.GetWord()));
2565 char *val, *ciphers;
2567 if (!(val =
Config.GetWord()))
2568 {
eDest->
Emsg(
"Config",
"tlsciphers parameter not specified");
return 1;}
2570 ciphers = strdup(val);
2572 if ((val =
Config.GetWord()))
2573 {
eDest->
Emsg(
"Config",
"Invalid tlsciphers argument -",val);
2607 int V_read = -1, V_idle = -1, V_hail = -1, V_kill = -1;
2608 struct tmoopts {
const char *opname;
int istime;
int minv;
2609 int *oploc;
const char *etxt;}
2612 {
"read", 1, 1, &V_read,
"timeout read"},
2613 {
"hail", 1, 1, &V_hail,
"timeout hail"},
2614 {
"idle", 1, 0, &V_idle,
"timeout idle"},
2615 {
"kill", 1, 0, &V_kill,
"timeout kill"}
2617 int numopts =
sizeof(tmopts)/
sizeof(
struct tmoopts);
2619 if (!(val =
Config.GetWord()))
2620 {
eDest->
Emsg(
"Config",
"timeout option not specified");
return 1;}
2623 {
for (i = 0; i < numopts; i++)
2624 if (!strcmp(val, tmopts[i].opname))
2625 {
if (!(val =
Config.GetWord()))
2626 {
eDest->
Emsg(
"Config",
"timeout", tmopts[i].opname,
2627 "value not specified");
2630 rc = (tmopts[i].istime ?
2633 XrdOuca2x::a2i (*
eDest,tmopts[i].etxt,val,&ppp,
2636 *tmopts[i].oploc = ppp;
2640 eDest->
Say(
"Config warning: ignoring invalid timeout option '",val,
"'.");
2646 if (V_read > 0)
ProtInfo.readWait = V_read*1000;
2647 if (V_hail >= 0)
ProtInfo.hailWait = V_hail*1000;
2648 if (V_idle >= 0)
ProtInfo.idleWait = V_idle;
2670 static struct traceopts {
const char *opname;
int opval;} tropts[] =
2687 int i, neg, trval = 0, numopts =
sizeof(tropts)/
sizeof(
struct traceopts);
2689 if (!(val =
Config.GetWord()))
2690 {
eDest->
Emsg(
"Config",
"trace option not specified");
return 1;}
2692 {
if (!strcmp(val,
"off")) trval = 0;
2693 else {
if ((neg = (val[0] ==
'-' && val[1]))) val++;
2694 for (i = 0; i < numopts; i++)
2695 {
if (!strcmp(val, tropts[i].opname))
2697 if (tropts[i].opval) trval &= ~tropts[i].opval;
2699 else if (tropts[i].opval) trval |= tropts[i].opval;
2705 eDest->
Say(
"Config warning: ignoring invalid trace option '",val,
"'.");
void Usage(const char *msg)
int portVec[XrdProtLoad::PortoMax]
bool tlsVec[XrdProtLoad::PortoMax]
static XrdSysError eDest(0,"crypto_")
static XrdVERSIONINFODEF(compiledVer, XrdHttpProtocolTest, XrdVNUMBER, XrdVERSION)
#define TLS_SET_VDEPTH(cOpts, vdv)
#define TLS_SET_HSTO(cOpts, hstv)
#define TLS_SET_REFINT(cOpts, refi)
void Set(int maxmem=-1, int minw=-1)
void Reset(char *ln, char *pp, int np=-1, bool to=false)
XrdConfigProt(char *pn, char *ln, char *pp, int np=-1, bool to=false)
bool AddPort(int pnum, bool isTLS)
XrdProtocol_Config ProtInfo
std::vector< XrdInet * > NetTCP
int ConfigXeq(char *var, XrdOucStream &Config, XrdSysError *eDest=0)
int Configure(int argc, char **argv)
int BindSD(int port, const char *contype="tcp")
static void SetAssumeV4(bool newVal)
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 SetCache(int keeptime)
static void SetDynDNS(bool onoff)
static void SetRPIPA(bool rval)
static int GetIF(XrdOucTList **ifList, const char **eText=0)
static void Routing(netType nettype)
static void SetMsgs(XrdSysError *erp)
static bool SetIFNames(char *ifnames)
static void SetFQN(const char *fqn)
static int ProtoID(const char *pName)
static int ServPort(const char *sName, bool isUDP=false, const char **eText=0)
void setDomain(const char *dname)
void setDefaults(int options, int buffsz=0)
void PutInt(const char *varname, long value)
static int Export(const char *Var, const char *Val)
void * GetPtr(const char *varname)
void PutPtr(const char *varname, void *value)
void Put(const char *varname, const char *value)
static bool configLog(XrdSysError &eDest, configLogInfo &logInfo)
static const char * Set(const char *name, int maxlen=15)
static XrdOucString * Capture()
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)
static int a2sz(XrdSysError &, const char *emsg, const char *item, long long *val, long long minv=-1, long long maxv=-1)
static int a2tm(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
static int a2p(XrdSysError &, const char *ptype, const char *val, bool anyOK=true)
static int Setup(int numfd)
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)
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)
static void setDebug(XrdSysError *erp)
static void setStackSize(size_t stsz, bool force=false)
static int FmtUname(char *buff, int blen)
XrdOucPinKing< XrdTcpMonPin > KingPin
XrdTcpMonInfo(const char *drctv, const char *cfn, XrdSysError &errR)
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)
static const int dbgSIO
Turn debugging in for socket I/O.
static const int dbgSOK
Turn debugging in for socket operations.
static const int dbgALL
Turn debugging for everything.
static const int dbgCTX
Turn debugging in for context operations.
static void SetDebug(int opts, XrdSysLogger *logP=0)