42#include <sys/isa_defs.h>
45#include "XrdVersion.hh"
130 const char *,
const char *,
136 const char *configFn,
157char *FSLib[2] = {0,0};
158std::vector<std::string> FSLPath;
159std::vector<std::string> RDLPath;
160std::vector<std::string> RDLParm;
167static const int asDebug = 0x01;
168static const int asNoCache = 0x02;
188 const char *configFn,
189 const char *theParms);
193 char *adminp, *rdf, *bP, *tmp, buff[1024];
224 for (i = 1; i < pi->
argc; i++) xexpdo(pi->
argv[i]);
244 rdf = (parms && *parms ? parms : pi->
ConfigFN);
245 if (rdf && Config(rdf))
return 0;
257 else if (bad)
return 0;
262 {
eDest.Say(
"Config exporting ",
XPList.Path(n)); n += 2;}
267 if (!(xp =
XPList.Next()) && !n)
268 {
XPList.Insert(
"/tmp"); n = 8;
269 eDest.Say(
"Config warning: only '/tmp' will be exported.");
271 while(xp) {
eDest.Say(
"Config exporting ", xp->
Path(i));
272 n += i+2; xp = xp->
Next();
278 bP = tmp = (
char *)malloc(n);
280 {strcpy(bP,
XPList.Path(i)); bP += i, *bP++ =
' ';}
282 while(xp) {strcpy(bP, xp->
Path(i)); bP += i; *bP++ =
' '; xp = xp->
Next();}
288 if (!ConfigSecurity(xrootdEnv, pi->
ConfigFN))
return 0;
307 if (theMon) xrootdEnv.
PutPtr(
"XrdMonRoll*", theMon);
313 if (!ConfigMon(pi, xrootdEnv))
return 0;
317 if (!ConfigFS(xrootdEnv, pi->
ConfigFN))
return 0;
332 {
TRACE(
DEBUG,
"Loading dig filesystem builtin");
334 if (!
digFS)
eDest.Emsg(
"Config",
"Unable to load digFS; "
335 "remote debugging disabled!");
349 eDest.Emsg(
"Config", tP->
text,
"checksum is not natively supported.");
354 if (csNum) csList +=
',';
366 if (!RDLPath.empty())
367 {
for (
int i = 0; i < (int)RDLPath.size(); i++)
368 {
const char* parm = (RDLParm[i].length() ? RDLParm[i].c_str() : 0);
369 if (!ConfigRedirPI(RDLPath[i].c_str(),xrootdEnv,pi->
ConfigFN,parm))
378 if (!(asyncFlags & asDebug) &&
as_aioOK)
382 if (!
as_aioOK)
eDest.Say(
"Config asynchronous I/O has been disabled!");
398 eDest.Say(
"Config sendfile has been disabled by ", why);
411 ProtStack.Set(n, 60*60);
421 sprintf(buff,
"%%s://%s:%d/&L=%%d&U=%%s", pi->
myName, pi->
Port);
428 if ((rdf = getenv(
"XRDREDIRECT"))
429 && (!strcmp(rdf,
"R") || !strcmp(rdf,
"M")))
442 eDest.Say(
"Config warning: 'redirect client' ignored; "
443 "not a redirector nor a proxy server");
450 char buff[2048], puff[1024];
454 else sprintf(puff,
"%%%s:%d",
Route[k].Host[1],
Route[k].
Port[1]);
455 sprintf(buff,
" to %s:%d%s",
Route[k].Host[0],
Route[k].
Port[0],puff);
456 eDest.Say(
"Config redirect static ", xp->
Path(), buff);
463 const char *cgi1, *cgi2;
464 char buff[2048], puff[1024], xCgi[RD_Num] = {0};
465 if (
isRedir) {cgi1 =
"+"; cgi2 = getenv(
"XRDCMSCLUSTERID");}
466 else {cgi1 =
""; cgi2 = pi->
myName;}
467 myCNlen = snprintf(buff,
sizeof(buff),
"%s%s", cgi1, cgi2);
472 else sprintf(puff,
"%%%s:%d",
Route[k].Host[1],
Route[k].
Port[1]);
473 sprintf(buff,
" to %s:%d%s",
Route[k].Host[0],
Route[k].
Port[0],puff);
474 eDest.Say(
"Config redirect enoent ", xp->
Path(), buff);
475 if (!xCgi[k] && cgi2)
476 {
bool isdup =
Route[k].Host[0] ==
Route[k].Host[1]
478 for (i = 0; i < 2; i++)
479 {n = snprintf(buff,
sizeof(buff),
"%s?tried=%s%s",
480 Route[k].Host[i], cgi1, cgi2);
481 free(
Route[k].Host[i]);
Route[k].Host[i] = strdup(buff);
482 Route[k].RDSz[i] = n;
483 if (isdup) {
Route[k].Host[1] =
Route[k].Host[0];
484 Route[k].RDSz[1] = n;
break;
529 {
const char *penv = getenv(
"XRDXROOTD_PROXY");
530 if (!penv || *penv !=
'=')
532 eDest.Say(
"Config warning: 'fsoverload bypass' ignored; "
533 "not a forwarding proxy.");
559#define TS_Xeq(x,m) (!strcmp(x,var)) GoNo = m(Config)
560#define TS_Zeq(x,m) (!strcmp(x,var)) GoNo = m(&eDest, Config)
562int XrdXrootdProtocol::Config(
const char *ConfigFN)
567 int cfgFD, GoNo, NoGo = 0, ismine;
571 if ((cfgFD =
open(ConfigFN, O_RDONLY, 0)) < 0)
572 return eDest.Emsg(
"Config", errno,
"open config file", ConfigFN);
573 Config.Attach(cfgFD);
577 static const char *cvec[] = {
"*** xroot protocol config:", 0 };
578 Config.Capture(cvec);
582 while((var = Config.GetMyFirstWord()))
583 {
if ((ismine = !strncmp(
"xrootd.", var, 7)) && var[7]) var += 7;
584 else if ((ismine = !strcmp(
"all.export", var))) var += 4;
585 else if ((ismine = !strcmp(
"all.seclib", var))) var += 4;
588 {
if TS_Xeq(
"async", xasync);
589 else if TS_Xeq(
"bindif", xbif);
590 else if TS_Xeq(
"chksum", xcksum);
591 else if TS_Xeq(
"diglib", xdig);
592 else if TS_Xeq(
"export", xexp);
593 else if TS_Xeq(
"fslib", xfsl);
594 else if TS_Xeq(
"fsoverload", xfso);
595 else if TS_Xeq(
"gpflib", xgpf);
596 else if TS_Xeq(
"log", xlog);
597 else if TS_Xeq(
"mongstream", xmongs);
598 else if TS_Xeq(
"monitor", xmon);
600 else if TS_Xeq(
"prep", xprep);
601 else if TS_Xeq(
"redirect", xred);
602 else if TS_Xeq(
"redirlib", xrdl);
603 else if TS_Xeq(
"seclib", xsecl);
604 else if TS_Xeq(
"tls", xtls);
605 else if TS_Xeq(
"tlsreuse", xtlsr);
606 else if TS_Xeq(
"trace", xtrace);
607 else if TS_Xeq(
"limit", xlimit);
608 else {
if (!strcmp(var,
"pidpath"))
609 {
eDest.Say(
"Config warning: 'xrootd.pidpath' no longer "
610 "supported; use 'all.pidpath'.");
612 eDest.Say(
"Config warning: ignoring unknown "
613 "directive '", var,
"'.");
618 if (GoNo) {Config.Echo(); NoGo = 1;}
628 {
eDest.Say(
"Config failure: unable to setup TLS for protocol!");
631 static const char *sessID =
"xroots";
648int XrdXrootdProtocol::CheckTLS(
const char *tlsProt)
668 {
eDest.Say(
"Config Authentication protocol(s)", tlsProt,
669 " require TLS; login now requires TLS.");
677 {
eDest.Say(
"Config failure: unable to honor TLS requirement; "
678 "TLS not configured!");
691bool XrdXrootdProtocol::ConfigFS(
XrdOucEnv &xEnv,
const char *cfn)
699 {
TRACE(
DEBUG,
"Loading base filesystem library " <<FSLib[0]);
710 {
eDest.Emsg(
"Config",
"Unable to load base file system using", fsLoc);
713 if (FSLib[0])
osFS->EnvInfo(&xEnv);
717 if (FSLib[1] && !ConfigFS(FSLib[1], xEnv, cfn))
return false;
721 if ((n = FSLPath.size()))
722 for (
int i = 0; i < n; i++)
723 {
if (!ConfigFS(FSLPath[i].c_str(), xEnv, cfn))
return false;}
736bool XrdXrootdProtocol::ConfigFS(
const char *path,
XrdOucEnv &xEnv,
742 TRACE(
DEBUG,
"Loading wrapper filesystem library " <<path);
745 {
eDest.Emsg(
"Config",
"Unable to load file system wrapper from", path);
748 osFS->EnvInfo(&xEnv);
756bool XrdXrootdProtocol::ConfigRedirPI(
const char *path,
XrdOucEnv &xEnv,
757 const char *cfn,
const char *parms)
762 TRACE(
DEBUG,
"Loading redirect plugin library " <<path);
771int XrdXrootdProtocol::ConfigSecurity(
XrdOucEnv &xEnv,
const char *cfn)
800 {
eDest.Say(
"Config warning: 'xrootd.seclib' not specified;"
801 " strong authentication disabled!");
802 xEnv.
PutPtr(
"XrdSecGetProtocol*", (
void *)0);
803 xEnv.
PutPtr(
"XrdSecProtector*" , (
void *)0);
809 TRACE(
DEBUG,
"Loading security library " <<SecLib);
814 (strcmp(SecLib,
"default") ? SecLib : 0),
816 {
eDest.Emsg(
"Config",
"Unable to load security system.");
822 xEnv.
PutPtr(
"XrdSecGetProtocol*", (
void *)secGetProt);
823 xEnv.
PutPtr(
"XrdSecProtector*" , (
void *)
DHS);
827 const char *tlsProt =
CIA->protTLS();
828 if (tlsProt)
return CheckTLS(tlsProt);
874 int V_force=-1, V_syncw = -1, V_off = -1, V_mstall = -1, V_nosf = -1;
875 int V_limit=-1, V_msegs=-1, V_mtot=-1, V_minsz=-1, V_segsz=-1;
876 int V_minsf=-1, V_debug=-1, V_noca=-1, V_tmo=-1;
878 struct asyncopts {
const char *opname;
int minv;
int *oploc;
879 const char *opmsg;} asopts[] =
881 {
"Debug", -1, &V_debug,
""},
882 {
"force", -1, &V_force,
""},
883 {
"off", -1, &V_off,
""},
884 {
"nocache", -1, &V_noca,
""},
885 {
"nosf", -1, &V_nosf,
""},
886 {
"syncw", -1, &V_syncw,
""},
887 {
"limit", 0, &V_limit,
"async limit"},
888 {
"segsize", 4096, &V_segsz,
"async segsize"},
889 {
"timeout", 0, &V_tmo,
"async timeout"},
890 {
"maxsegs", 0, &V_msegs,
"async maxsegs"},
891 {
"maxstalls", 0, &V_mstall,
"async maxstalls"},
892 {
"maxtot", 0, &V_mtot,
"async maxtot"},
893 {
"minsfsz", 1, &V_minsf,
"async minsfsz"},
894 {
"minsize", 4096, &V_minsz,
"async minsize"}};
895 int numopts =
sizeof(asopts)/
sizeof(
struct asyncopts);
897 if (!(val = Config.GetWord()))
898 {
eDest.Emsg(
"Config",
"async option not specified");
return 1;}
901 {
for (i = 0; i < numopts; i++)
902 if (!strcmp(val, asopts[i].opname))
903 {
if (asopts[i].minv >= 0 && !(val = Config.GetWord()))
904 {
eDest.Emsg(
"Config",
"async",(
char *)asopts[i].opname,
905 "value not specified");
908 if (asopts[i].minv > 0)
910 (
long long)asopts[i].minv))
return 1;
911 else *asopts[i].oploc = (int)llp;
912 else if (asopts[i].minv == 0)
915 else *asopts[i].oploc = ppp;
916 else *asopts[i].oploc = 1;
920 eDest.Emsg(
"Config",
"Warning, invalid async option", val);
921 val = Config.GetWord();
926 if (V_limit > 0 && V_mtot > 0 && V_limit > V_mtot)
927 {
eDest.Emsg(
"Config",
"async limit may not be greater than maxtot");
934 {i =
BPool->Recalc(V_segsz);
935 if (!i) {
eDest.Emsg(
"Config",
"async segsize is too large");
return 1;}
938 sprintf(buff,
"%d readjusted to %d", V_segsz, i);
939 eDest.Emsg(
"Config",
"async segsize", buff);
948 if (V_tmo < 1) i = 1;
949 else if (V_tmo > 360) i = 360;
952 sprintf(buff,
"%d readjusted to %d", V_tmo, i);
953 eDest.Emsg(
"Config",
"async timeout", buff);
967 if (V_debug > 0) asyncFlags |= asDebug;
971 if (V_noca > 0) asyncFlags |= asNoCache;
972 if (V_nosf > 0)
as_nosf =
true;
1001 XrdOucString bSpec[2];
1002 char *bHost[2], *val, buff[512];
1003 int bPort[2], thePort;
1008 {
if (bifResp[1] != bifResp[0]) free(bifResp[1]);
1018 while((val = Config.GetWord()) && *val)
1019 {
if (!xred_php(val, bHost, bPort,
"bindif",
true))
return 1;
1020 for (
int i = 0; i < 2 && bHost[i] != 0; i++)
1022 snprintf(buff,
sizeof(buff),
"%s%s:%d",
1023 (bSpec[i].length() ?
"," :
""), bHost[i], thePort);
1030 for (
int i = 0; i < 2 && bSpec[i].
length(); i++)
1031 {
int n = brSize + bSpec[i].
length() + 1;
1034 memset(bifRec, 0, n);
1037 strcpy(((
char *)bifRec)+brSize, bSpec[i].c_str());
1044 if (bifResp[0] && bifResp[1] == 0)
1075 static XrdOucProg *theProg = 0;
1076 int (*Proc)(XrdOucStream *,
char **, int) = 0;
1077 XrdOucTList *tP, *algFirst = 0, *algLast = 0;
1078 char *palg, prog[2048];
1079 int jmax = 4, anum[2] = {0,0};
1084 while ((palg = Config.GetWord()) && *palg !=
'/')
1085 {
if (!strcmp(palg,
"chkcgi")) {
JobCKCGI = 1;
continue;}
1086 if (strcmp(palg,
"max"))
1088 XrdOucTList *xalg =
new XrdOucTList(palg, anum); anum[0]++;
1089 if (algLast) algLast->next = xalg;
1090 else algFirst = xalg;
1094 if (!(palg = Config.GetWord()))
1095 {
eDest.Emsg(
"Config",
"chksum max not specified");
return 1;}
1102 {
eDest.Emsg(
"Config",
"chksum algorithm not specified");
return 1;}
1115 {
int n = strlen(palg);
1116 if (n+2 >= (
int)
sizeof(prog))
1117 {
eDest.Emsg(
"Config",
"cksum program too long");
return 1;}
1118 strcpy(prog, palg); palg = prog+n; *palg++ =
' '; n =
sizeof(prog)-n-1;
1119 if (!Config.GetRest(palg, n))
1120 {
eDest.Emsg(
"Config",
"cksum parameters too long");
return 1;}
1127 else {
JobLCL = 1; Proc = &CheckSum; strcpy(prog,
"chksum");}
1131 if (!theProg) theProg =
new XrdOucProg(0);
1132 if (theProg->
Setup(prog, &
eDest, Proc))
return 1;
1134 if (jmax)
JobCKS =
new XrdXrootdJob(
Sched, theProg,
"chksum", jmax);
1155 char parms[4096], *val;
1159 if (!(val = Config.GetWord()))
1160 {
eDest.Emsg(
"Config",
"diglib not specified");
return 1;}
1164 if (strcmp(val,
"*"))
1165 {
eDest.Emsg(
"Config",
"builtin diglib not specified");
return 1;}
1169 if (!Config.GetRest(parms,
sizeof(parms)))
1170 {
eDest.Emsg(
"Config",
"diglib parameters too long");
return 1;}
1171 if (digParm) free(digParm);
1172 digParm = strdup(parms);
1194 char *val, pbuff[1024];
1199 val = Config.GetWord();
1200 if (!val || !val[0])
1201 {
eDest.Emsg(
"Config",
"export path not specified");
return 1;}
1202 strlcpy(pbuff, val,
sizeof(pbuff));
1206 while((val = Config.GetWord()))
1208 else if (!strcmp(
"lock", val)) popt &= ~XROOTDXP_NOLK;
1210 else {Config.RetToken();
break;}
1215 return xexpdo(pbuff, popt);
1220int XrdXrootdProtocol::xexpdo(
char *path,
int popt)
1230 {
if (*(path+1) ==
'?') popt &= ~XROOTDXP_NOCGI;
1231 else {
eDest.Emsg(
"Config",
"invalid export path -",path);
return 1;}
1239 if (rpCheck(path, &opaque))
1240 {
eDest.Emsg(
"Config",
"non-absolute export path -", path);
return 1;}
1244 if (!(xopt = Squash(path)) || xopt != (popt|
XROOTDXP_OK))
1245 XPList.Insert(path, popt);
1277 if (!(val = Config.GetWord()))
1278 {
eDest.Emsg(
"Config",
"fslib not specified");
return 1;}
1282 if (!strcmp(
"++", val))
1283 {
if (!(val = Config.GetWord()))
1284 {
eDest.Emsg(
"Config",
"fslib wrapper not specified");
return 1;}
1285 if (strcmp(
"throttle", val)) FSLPath.push_back((std::string)val);
1286 else FSLPath.push_back(
"libXrdThrottle.so");
1292 if (FSLib[0]) {free(FSLib[0]); FSLib[0] = 0;}
1293 if (FSLib[1]) {free(FSLib[1]); FSLib[1] = 0;}
1297 if (!strcmp(
"throttle", val))
1298 {FSLib[1] = strdup(
"libXrdThrottle.so");
1299 if (!(val = Config.GetWord()))
1300 {
eDest.Emsg(
"Config",
"fslib throttle target library not specified");
1303 return xfsL(Config, val, 0);
1308 if (xfsL(Config, val, 1))
return 1;
1309 if (!FSLib[1])
return 0;
1313 if (!(val = Config.GetWord()))
1314 {FSLib[0] = FSLib[1]; FSLib[1] = 0;
1320 return xfsL(Config, val, 0);
1325int XrdXrootdProtocol::xfsL(
XrdOucStream &Config,
char *val,
int lix)
1331 if (!strcmp(val,
"-2"))
1332 {
if (!(val = Config.GetWord()))
1333 {
eDest.Emsg(
"Config",
"fslib not specified");
return 1;}
1339 if (!strcmp(
"default", val))
return 0;
1344 if (!(Slash = rindex(val,
'/'))) Slash = val;
1346 if (!strcmp(Slash,
"libXrdOfs.so"))
1347 eDest.Say(
"Config warning: 'fslib libXrdOfs.so' is actually built-in.");
1348 else FSLib[lix] = strdup(val);
1372 static const int rHLen = 264;
1373 char rHost[2][rHLen], *hP[2] = {0,0}, *val;
1374 int rPort[2], bypass = -1, stall = -1;
1378 while((val = Config.GetWord()) && *val)
1379 {
if (!strcmp(val,
"bypass")) bypass = 1;
1380 else if (!strcmp(val,
"nobypass")) bypass = 0;
1381 else if (!strcmp(val,
"redirect"))
1382 {val = Config.GetWord();
1383 if (!xred_php(val, hP, rPort,
"redirect"))
return 1;
1384 for (
int i = 0; i < 2; i++)
1385 {
if (!hP[i]) rHost[i][0] = 0;
1386 else {
strlcpy(rHost[i], hP[i], rHLen);
1391 else if (!strcmp(val,
"stall"))
1392 {
if (!(val = Config.GetWord()) || !(*val))
1393 {
eDest.Emsg(
"Config",
"stall value not specified");
1399 else {
eDest.Emsg(
"config",
"invalid fsoverload option",val);
return 1;}
1404 if (bypass >= 0)
OD_Bypass = (bypass ? true :
false);
1407 {
if (
Route[RD_ovld].Host[0]) free(
Route[RD_ovld].Host[0]);
1408 if (
Route[RD_ovld].Host[1]) free(
Route[RD_ovld].Host[1]);
1409 Route[RD_ovld].Host[0] = strdup(hP[0]);
1410 Route[RD_ovld].Port[0] = rPort[0];
1411 Route[RD_ovld].RDSz[0] = strlen(hP[0]);
1413 {
Route[RD_ovld].Host[1] = strdup(hP[1]);
1414 Route[RD_ovld].Port[1] = rPort[1];
1415 Route[RD_ovld].RDSz[1] = strlen(hP[1]);
1417 Route[RD_ovld].Host[1] =
Route[RD_ovld].Host[0];
1418 Route[RD_ovld].Port[1] =
Route[RD_ovld].Port[0];
1419 Route[RD_ovld].RDSz[1] =
Route[RD_ovld].RDSz[0];
1443 char parms[4096], *val;
1447 if (gpfLib) {free(gpfLib); gpfLib = 0;}
1448 if (gpfParm) {free(gpfParm); gpfParm = 0;}
1452 if (!(val = Config.GetWord()))
1453 {
eDest.Emsg(
"Config",
"gpflib not specified");
return 1;}
1457 if (strcmp(val,
"default")) gpfLib = strdup(val);
1461 if (!Config.GetRest(parms,
sizeof(parms)))
1462 {
eDest.Emsg(
"Config",
"gpflib parameters too long");
return 1;}
1463 gpfParm = strdup(parms);
1486 static struct logopts {
const char *opname;
int opval;} lgopts[] =
1492 int i, neg, lgval = -1, numopts =
sizeof(lgopts)/
sizeof(
struct logopts);
1494 if (!(val = Config.GetWord()))
1495 {
eDest.Emsg(
"config",
"log option not specified");
return 1;}
1497 {
if ((neg = (val[0] ==
'-' && val[1]))) val++;
1498 for (i = 0; i < numopts; i++)
1499 {
if (!strcmp(val, lgopts[i].opname))
1500 {
if (neg) lgval &= ~lgopts[i].opval;
1501 else lgval |= lgopts[i].opval;
1505 if (i >= numopts)
eDest.Emsg(
"config",
"invalid log option",val);
1506 val = Config.GetWord();
1508 eDest.setMsgMask(lgval);
1527{
int rc, keep = 0, scrub=0;
1528 char *ldir=0,*val,buff[1024];
1530 if (!(val = Config.GetWord()))
1531 {
eDest.Emsg(
"Config",
"prep options not specified");
return 1;}
1533 do {
if (!strcmp(
"keep", val))
1534 {
if (!(val = Config.GetWord()))
1535 {
eDest.Emsg(
"Config",
"prep keep value not specified");
1540 else if (!strcmp(
"scrub", val))
1541 {
if (!(val = Config.GetWord()))
1542 {
eDest.Emsg(
"Config",
"prep scrub value not specified");
1547 else if (!strcmp(
"logdir", val))
1548 {
if (!(ldir = Config.GetWord()))
1549 {
eDest.Emsg(
"Config",
"prep logdir value not specified");
1553 else eDest.Emsg(
"Config",
"Warning, invalid prep option", val);
1554 }
while((val = Config.GetWord()));
1563 {
eDest.Emsg(
"Config", rc,
"process logdir", ldir);
1593 if (!(val = Config.GetWord()))
1594 {
eDest.Emsg(
"Config",
"redirlib path not specified");
return 1;}
1598 if (!strcmp(
"++", val))
1599 {
if (!(val = Config.GetWord()))
1600 {
eDest.Emsg(
"Config",
"redrilib wrapper not specified");
return 1;}
1601 if (RDLPath.empty())
1602 {
eDest.Emsg(
"Config",
"base redrilib not specified");
return 1;}
1603 if (*val ==
'+' && !(val = xrdlopt(Config, val)))
return 1;
1604 RDLPath.push_back((std::string)val);
1605 if (!Config.GetRest(pbuff,
sizeof(pbuff)))
1606 {
eDest.Emsg(
"Config",
"redirlib parameters too long");
return 1;}
1607 RDLParm.push_back((std::string)pbuff);
1609 }
else if (*val ==
'+' && !(val = xrdlopt(Config, val)))
return 1;
1613 if (RDLPath.empty()) RDLPath.push_back((std::string)val);
1614 else RDLPath[0] = val;
1618 if (!Config.GetRest(pbuff,
sizeof(pbuff)))
1619 {
eDest.Emsg(
"Config",
"redirlib parameters too long");
return 1;}
1620 if (RDLParm.empty()) RDLParm.push_back((std::string)pbuff);
1621 else RDLParm[0] = pbuff;
1632char* XrdXrootdProtocol::xrdlopt(
XrdOucStream &Config,
char* val)
1638do{
if (!strcmp(val,
"+iphold"))
1639 {
if (!(val = Config.GetWord()))
1640 {
eDest.Emsg(
"Config",
"+iphold value not specified");
return 0;}
1644 }
while((val = Config.GetWord()) && *val ==
'+');
1680 static struct rediropts {
const char *opname; RD_func opval;} rdopts[] =
1682 {
"chmod", RD_chmod},
1683 {
"chksum", RD_chksum},
1684 {
"dirlist", RD_dirlist},
1685 {
"locate", RD_locate},
1686 {
"mkdir", RD_mkdir},
1688 {
"prepare", RD_prepare},
1689 {
"prepstage",RD_prepstg},
1691 {
"rmdir", RD_rmdir},
1695 static const int rHLen = 264;
1696 char rHost[2][rHLen], *hP[2], *val;
1697 int i, k, neg, numopts =
sizeof(rdopts)/
sizeof(
struct rediropts);
1698 int rPort[2], isQ = 0;
1702 val = Config.GetWord();
1703 if (!xred_php(val, hP, rPort,
"redirect"))
return 1;
1707 for (i = 0; i < 2; i++)
1708 {
if (!hP[i]) rHost[i][0] = 0;
1709 else {
strlcpy(rHost[i], hP[i], rHLen);
1716 if (!(val = Config.GetWord()))
1717 {
eDest.Emsg(
"config",
"redirect option not specified");
return 1;}
1721 if (!strcmp(
"client", val))
return xred_clnt(Config, hP, rPort);
1723 if (*val ==
'/' || (isQ = ((*val ==
'?') || !strcmp(val,
"enoent"))))
1726 if (!(val = Config.GetWord()))
1727 {
eDest.Emsg(
"Config",
"redirect path not specified.");
1731 {
eDest.Emsg(
"Config",
"non-absolute redirect path -", val);
1735 for (k =
static_cast<int>(RD_open1); k < RD_Num; k++)
1736 if (xred_xok(k, hP, rPort))
break;
1738 {
eDest.Emsg(
"Config",
"too many different path redirects");
return 1;}
1739 xred_set(RD_func(k), hP, rPort);
1740 do {
if (isQ)
RQList.Insert(val, k, 0);
1741 else RPList.Insert(val, k, 0);
1742 if ((val = Config.GetWord()) && *val !=
'/')
1743 {
eDest.Emsg(
"Config",
"non-absolute redirect path -", val);
1751 {
if (!strcmp(val,
"all"))
1752 {
for (i = 0; i < numopts; i++)
1753 xred_set(rdopts[i].opval, hP, rPort);
1755 else {
if ((neg = (val[0] ==
'-' && val[1]))) val++;
1756 for (i = 0; i < numopts; i++)
1757 {
if (!strcmp(val, rdopts[i].opname))
1758 {
if (neg) xred_set(rdopts[i].opval, 0, 0);
1759 else xred_set(rdopts[i].opval, hP, rPort);
1764 eDest.Emsg(
"config",
"invalid redirect option", val);
1766 val = Config.GetWord();
1773int XrdXrootdProtocol::xred_clnt(
XrdOucStream &Config,
char *hP[2],
int rPort[2])
1775 static const int maxDom =
sizeof(
RouteClient.Domain)/
sizeof(
char*);
1784 for (
int i = 0; i < maxDom; i++)
RouteClient.Domain[i] = 0;
1792 if (!(val = Config.GetWord()))
1793 {
eDest.Emsg(
"Config",
"redirect client argument not specified.");
1798 {
if (!strcmp(
"private", val))
RouteClient.pvtIP =
true;
1799 else if (!strcmp(
"local", val))
RouteClient.lclDom =
true;
1800 else if (*val ==
'.')
1802 {
eDest.Emsg(
"Config",
1803 "Too many redirect client domains specified.");
1808 else {
eDest.Emsg(
"Config",
"Invalid redirect client domain -", val);
1811 val = Config.GetWord();
1816 xred_set(RD_client, hP, rPort);
1822bool XrdXrootdProtocol::xred_php(
char *val,
char *hP[2],
int rPort[2],
1823 const char *what,
bool optport)
1825 XrdNetAddr testAddr;
1830 if (!val || !(*val))
1831 {
eDest.Emsg(
"config", what,
"argument not specified");
return false;}
1836 if (!(pp = index(val,
'%'))) hP[1] = 0;
1837 else {hP[1] = pp+1; *pp = 0;}
1841 if (!(*val) || (hP[1] && !*hP[1]))
1842 {
eDest.Emsg(
"Config",
"malformed", what,
"host specification");
1848 for (
int i = 0; i < 2; i++)
1849 {
if (!(val = hP[i]))
break;
1850 if (!val || !val[0] || val[0] ==
':')
1851 {
eDest.Emsg(
"Config", what,
"host not specified");
return false;}
1852 if ((pp = rindex(val,
':')))
1857 if (optport) rPort[i] = 0;
1858 else {
eDest.Emsg(
"Config", what,
"port not specified");
1862 const char *eText = testAddr.
Set(val, 0);
1865 eDest.Say(
"Config warning: ", eText,
" as ", val);
1866 else {
eDest.Say(
"Config failure: ", what,
" target ", val,
1867 " is invalid; ", eText);
1878void XrdXrootdProtocol::xred_set(RD_func func,
char *rHost[2],
int rPort[2])
1883 if (
Route[func].Host[0]) free(
Route[func].Host[0]);
1884 if (
Route[func].Host[0] !=
Route[func].Host[1]) free(
Route[func].Host[1]);
1887 {
Route[func].Host[0] = strdup(rHost[0]);
1888 Route[func].Port[0] = rPort[0];
1890 Route[func].Host[0] =
Route[func].Host[1] = 0;
1891 Route[func].Port[0] =
Route[func].Port[1] = 0;
1899 Route[func].Host[1] = strdup(rHost[1]);
1900 Route[func].Port[1] = rPort[1];
1904bool XrdXrootdProtocol::xred_xok(
int func,
char *rHost[2],
int rPort[2])
1906 if (!
Route[func].Host[0])
return true;
1908 if (strcmp(
Route[func].Host[0], rHost[0])
1909 ||
Route[func].
Port[0] != rPort[0])
return false;
1911 if (!rHost[1])
return Route[func].Host[0] ==
Route[func].Host[1];
1913 if (strcmp(
Route[func].Host[1], rHost[1])
1914 ||
Route[func].
Port[1] != rPort[1])
return false;
1939 val = Config.GetWord();
1940 if (!val || !val[0])
1941 {
eDest.Emsg(
"Config",
"seclib argument not specified");
return 1;}
1945 if (SecLib) free(SecLib);
1946 SecLib = strdup(val);
1980 static struct enforceopts {
const char *opname;
int opval;
int enval;}
1991 int i, numopts =
sizeof(enfopts)/
sizeof(
struct enforceopts);
1992 bool neg, forall =
true;
1994 if (!(val = Config.GetWord()))
1995 {
eDest.Emsg(
"config",
"tls parameter not specified");
return 1;}
1997 if (!strcmp(
"capable", val))
1999 if (!(val = Config.GetWord()))
2000 {
eDest.Emsg(
"config",
"tls requirement not specified");
return 1;}
2004 {
if (!strcmp(val,
"off") || !strcmp(val,
"none"))
2009 if ((neg = (val[0] ==
'-' && val[1]))) val++;
2010 for (i = 0; i < numopts; i++)
2011 {
if (!strcmp(val, enfopts[i].opname))
2012 {
if (neg)
myRole &= ~enfopts[i].opval;
2013 else myRole |= enfopts[i].opval;
2014 if (neg)
tlsCap &= ~enfopts[i].enval;
2015 else tlsCap |= enfopts[i].enval;
2017 {
if (neg)
tlsNot &= ~enfopts[i].enval;
2018 else tlsNot |= enfopts[i].enval;
2024 {
eDest.Emsg(
"config",
"Invalid tls requirement -", val);
2028 val = Config.GetWord();
2042 return (CheckTLS(0) ? 0 : 1);
2068 val = Config.GetWord();
2069 if (!val || !val[0])
2070 {
eDest.Emsg(
"Config",
"tlsreuse argument not specified");
return 1;}
2074 if (!strcmp(val,
"off"))
2081 if (!strcmp(val,
"on"))
2082 {
if (!
tlsCtx) {
eDest.Emsg(
"Config warning:",
"Ignoring "
2083 "'tlsreuse on'; TLS not configured!");
2087 if (!(val = Config.GetWord()))
return 0;
2088 if (!strcmp(val,
"flush" ))
2089 {
if (!(val = Config.GetWord()))
2090 {
eDest.Emsg(
"Config",
"tlsreuse flush value not specified");
2094 if (num < 60) num = 60;
2103 eDest.Emsg(
"config",
"Invalid tlsreuse option -", val);
2124 static struct traceopts {
const char *opname;
int opval;} tropts[] =
2141 int i, neg, trval = 0, numopts =
sizeof(tropts)/
sizeof(
struct traceopts);
2143 if (!(val = Config.GetWord()))
2144 {
eDest.Emsg(
"config",
"trace option not specified");
return 1;}
2146 {
if (!strcmp(val,
"off")) trval = 0;
2147 else {
if ((neg = (val[0] ==
'-' && val[1]))) val++;
2148 for (i = 0; i < numopts; i++)
2149 {
if (!strcmp(val, tropts[i].opname))
2150 {
if (neg) trval &= ~tropts[i].opval;
2151 else trval |= tropts[i].opval;
2156 eDest.Emsg(
"config",
"invalid trace option", val);
2158 val = Config.GetWord();
2187 while ( (word = Config.GetWord()) ) {
2188 if (!strcmp(word,
"prepare")) {
2189 if (!(word = Config.GetWord()))
2191 eDest.Emsg(
"Config",
"'limit prepare' value not specified");
2195 }
else if (!strcmp(word,
"noerror")) {
static XrdSysLogger Logger
static XrdSysError eDest(0,"crypto_")
XrdSfsFileSystem * XrdDigGetFS(XrdSfsFileSystem *native_fs, XrdSysLogger *lp, const char *cFN, const char *parms)
XrdOucTrace * XrdXrootdTrace
XrdSfsFileSystem * XrdSfsGetDefaultFileSystem(XrdSfsFileSystem *native_fs, XrdSysLogger *lp, const char *configfn, XrdOucEnv *EnvInfo)
XrdSecProtocol *(* XrdSecGetProt_t)(const char *hostname, XrdNetAddrInfo &endPoint, XrdSecParameters §oken, XrdOucErrInfo *einfo)
Typedef to simplify the encoding of methods returning XrdSecProtocol.
XrdSecService * XrdSecLoadSecService(XrdSysError *eDest, const char *cfn, const char *seclib, XrdSecGetProt_t *getP, XrdSecProtector **proP)
const char * XrdXrootdInstance
XrdXrootdPrepare * XrdXrootdPrepQ
XrdSfsFileSystem * XrdXrootdloadFileSystem(XrdSysError *, XrdSfsFileSystem *, const char *, const char *, XrdOucEnv *)
XrdSfsFileSystem * XrdSfsGetDefaultFileSystem(XrdSfsFileSystem *nativeFS, XrdSysLogger *Logger, const char *configFn, XrdOucEnv *EnvInfo)
XrdXrootdRedirPI * XrdXrootdloadRedirLib(XrdSysError *, XrdXrootdRedirPI *, const char *, const char *, const char *, XrdOucEnv *)
XrdOucString * XrdXrootdCF
static bool isHostName(const char *name)
const char * Set(const char *hSpec, int pNum=PortInSpec)
void Display(const char *pfx="=====> ")
static int Parse(XrdSysError *eLog, XrdOucStream &Config)
static XrdNetPMark * Config(XrdSysError *eLog, XrdScheduler *sched, XrdSysTrace *trc, bool &fatal)
static XrdNetSocket * Create(XrdSysError *Say, const char *path, const char *fn, mode_t mode, int isudp=0)
long GetInt(const char *varname)
char * Get(const char *varname)
static int Export(const char *Var, const char *Val)
void * GetPtr(const char *varname)
void PutPtr(const char *varname, void *value)
int Setup(const char *prog, XrdSysError *errP=0, int(*Proc)(XrdOucStream *, char **, int)=0)
const char * c_str() const
static const mode_t pathMode
static char * genPath(const char *path, const char *inst, const char *psfx=0)
static int GidName(gid_t gID, char *gName, int gNsz, time_t keepT=0)
static int UidName(uid_t uID, char *uName, int uNsz, time_t keepT=0)
static int makePath(char *path, mode_t mode, bool reset=false)
static void toLower(char *str)
static int a2i(XrdSysError &, const char *emsg, const char *item, int *val, int minv=-1, int maxv=-1)
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)
XrdSysLogger * logger(XrdSysLogger *lp=0)
XrdTlsContext * Clone(bool full=true, bool startCRLRefresh=false)
int SessionCache(int opts=scNone, const char *id=0, int idlen=0)
static const int scNone
Do not change any option settings.
static const int scOff
Turn off cache.
static const int scSrvr
Turn on cache server mode (default).
static int Init(XrdSysError *erp, XrdNetSocket *asock)
static void addJob(const char *jname, XrdXrootdJob *jp)
static void setVals(XrdSysError *erp, XrdXrootdStats *SIp, XrdScheduler *schp, int port)
static void Init(XrdXrootdFileLock *lp, XrdSysError *erP, bool sfok)
static int setParms(int stime, int skeep)
static XrdXrootdStats * SI
static const char * myInst
static XrdSfsFileSystem * digFS
static XrdNetPMark * PMark
static short as_okstutter
static XrdXrootdXPath RPList
static XrdNetSocket * AdminSock
static const char Req_TLSGPFile
static const char Req_TLSSess
static XrdXrootdJob * JobCKS
static XrdSysError & eDest
static XrdXrootdRedirPI * RedirPI
static const char * myCName
static const char Req_TLSData
static XrdXrootdFileLock * Locker
static const char Req_TLSTPC
static XrdTlsContext * tlsCtx
static XrdXrootdXPath XPList
static XrdScheduler * Sched
static struct XrdXrootdProtocol::RC_Table RouteClient
static const char * myUName
static const char Req_TLSLogin
static int Configure(char *parms, XrdProtocol_Config *pi)
static XrdOucTList * JobCKTLST
static XrdXrootdXPath RQList
static struct XrdXrootdProtocol::RD_Table Route[RD_Num]
static XrdSecProtector * DHS
static XrdBuffManager * BPool
static XrdSecService * CIA
static const char * myGName
static uint64_t fsFeatures
static XrdOucReqID * PrepID
static XrdSfsFileSystem * osFS
static void Init(XrdScheduler *schedP, int qMax, int qTTL)
Perform one-time initialization.
struct ServerResponseBifs_Protocol bifReqs
static const int maxRvecsz
static const uint64_t hasPGRW
Feature: pgRead and pgWrite.
static const uint64_t hasPRP2
Feature: Prepare Handler Version 2 (different calling conventions).
static const uint64_t hasGPFA
Feature: gpFile anonymous.
static const uint64_t hasCACH
Feature: Implements a data cache.
static const uint64_t hasNOSF
Feature: Supports no sendfile.
static const uint64_t hasPOSC
Feature: Persist On Successful Close.
static const uint64_t hasGPF
Feature: gpFile.
static const uint64_t hasNAIO
Feature: Supports no async I/O.
static const uint64_t hasPRXY
Feature: Proxy Server.