XRootD
XrdNetPMarkCfg Class Reference

#include <XrdNetPMarkCfg.hh>

+ Inheritance diagram for XrdNetPMarkCfg:
+ Collaboration diagram for XrdNetPMarkCfg:

Public Member Functions

 XrdNetPMarkCfg ()
 
XrdNetPMark::HandleBegin (XrdNetAddrInfo &addr, XrdNetPMark::Handle &handle, const char *tident) override
 
XrdNetPMark::HandleBegin (XrdSecEntity &Client, const char *path=0, const char *cgi=0, const char *app=0) override
 
- Public Member Functions inherited from XrdNetPMark
 XrdNetPMark ()
 
virtual ~XrdNetPMark ()
 

Static Public Member Functions

static XrdNetPMarkConfig (XrdSysError *eLog, XrdScheduler *sched, XrdSysTrace *trc, bool &fatal)
 
static int Parse (XrdSysError *eLog, XrdOucStream &Config)
 
- Static Public Member Functions inherited from XrdNetPMark
static bool getEA (const char *cgi, int &ecode, int &acode)
 

Additional Inherited Members

- Static Public Attributes inherited from XrdNetPMark
static const int maxTotID = 65535
 
static const int minTotID = 65
 
- Static Protected Attributes inherited from XrdNetPMark
static const int btsActID = 6
 
static const int maxActID = maxTotID & mskActID
 
static const int maxExpID = maxTotID >> btsActID
 
static const int minActID = minTotID & mskActID
 
static const int minExpID = minTotID >> btsActID
 
static const int mskActID = 63
 

Detailed Description

Definition at line 43 of file XrdNetPMarkCfg.hh.

Constructor & Destructor Documentation

◆ XrdNetPMarkCfg()

XrdNetPMarkCfg::XrdNetPMarkCfg ( )
inline

Definition at line 61 of file XrdNetPMarkCfg.hh.

61 {}

Member Function Documentation

◆ Begin() [1/2]

XrdNetPMark::Handle * XrdNetPMarkCfg::Begin ( XrdNetAddrInfo addr,
XrdNetPMark::Handle handle,
const char *  tident 
)
overridevirtual

Implements XrdNetPMark.

Definition at line 235 of file XrdNetPMarkCfg.cc.

238 {
239 
240 // If we are allowed to use the flow label set on the incoming connection
241 // then try to do so. This is only valid for IPv6 connections. Currently,
242 // this is not implemented.
243 //
244 // if (useFLbl && addrInfo.isIPType(XrdNetAddrInfo::IPv6)
245 // && !addrInfo.isMapped())
246 // {
247 // TODO???
248 // }
249 
250 // If we are allowed to use firefly, return a firefly handle
251 //
252  if (handle.Valid() && useFFly)
253  {XrdNetPMarkFF *pmFF = new XrdNetPMarkFF(handle, tident);
254  if (pmFF->Start(addrInfo)) return pmFF;
255  delete pmFF;
256  eDest->Emsg("PMark_Begin", "Unable to start pmark for session",tident);
257  } else {
258  if (useFFly)
259  eDest->Emsg("PMark_Begin", "Flow value is invalid; "
260  "pmark disabled for session", tident);
261  }
262 
263 // All done, nothing will be pmarked
264 //
265  return 0;
266 }
#define tident
bool Start(XrdNetAddrInfo &addr)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
XrdSysError * eDest

References XrdNetPMarkConfig::eDest, XrdSysError::Emsg(), XrdNetPMarkFF::Start(), tident, XrdNetPMarkConfig::useFFly, and XrdNetPMark::Handle::Valid().

+ Here is the call graph for this function:

◆ Begin() [2/2]

XrdNetPMark::Handle * XrdNetPMarkCfg::Begin ( XrdSecEntity Client,
const char *  path = 0,
const char *  cgi = 0,
const char *  app = 0 
)
overridevirtual

Implements XrdNetPMark.

Definition at line 175 of file XrdNetPMarkCfg.cc.

179 {
180  EPName("PMBegin");
181  XrdOucString altApp;
182  int eCode, aCode;
183 
184 // If we need to screen out domains, do that
185 //
186  if (chkDom)
187  {XrdNetAddrInfo &addrInfo = *client.addrInfo;
188  char domType = (addrInfo.isPrivate() ? domLcl : domRmt);
189  if (domType == domRmt && *myDomain)
190  {const char *urName = addrInfo.Name();
191  if (urName && XrdNetAddrInfo::isHostName(urName))
192  {const char *dot = index(urName, '.');
193  if (dot && !strcmp(dot+1, myDomain)) domType = domLcl;
194  }
195  }
196  if (domType != chkDom)
197  {DBGID(client.tident, "Skipping sending flow info; unwanted domain");
198  return 0;
199  }
200  }
201 
202 // Now get the experiment and activity code. If we can't get at least the
203 // experiment code, then proceed without marking the flow.
204 //
205  if (!getCodes(client, path, cgi, eCode, aCode))
206  {TRACE("Unable to determine experiment; flow not marked.");
207  return 0;
208  }
209 
210 // Obtain the appname overridefrom the cgi
211 //
212  if (cgi) // 01234567890123
213  {const char *apP = strstr(cgi, "pmark.appname=");
214  if (apP)
215  {apP += 14;
216  const char* aP = apP;
217  while(*aP && *aP != '&') aP++;
218  int apLen = aP - apP;
219  if (apLen > 0)
220  {altApp = "";
221  altApp.insert(apP, 0, apLen);
222  app = altApp.c_str();
223  }
224  }
225  }
226 
227 // Continue with successor function to complete the logic
228 //
229  XrdNetPMark::Handle handle(app, eCode, aCode);
230  return Begin(*client.addrInfo, handle, client.tident);
231 }
#define TRACE(txt)
#define EPName(ep)
#define DBGID(tid, txt)
static bool isHostName(const char *name)
const char * Name(const char *eName=0, const char **eText=0)
XrdNetPMark::Handle * Begin(XrdSecEntity &Client, const char *path=0, const char *cgi=0, const char *app=0) override
void insert(const int i, int start=-1)
const char * c_str() const
static const int domLcl
const char * myDomain
static const int domRmt

References XrdSecEntity::addrInfo, XrdOucString::c_str(), XrdNetPMarkConfig::chkDom, DBGID, XrdNetPMarkConfig::domLcl, XrdNetPMarkConfig::domRmt, EPName, XrdOucString::insert(), XrdNetAddrInfo::isHostName(), XrdNetAddrInfo::isPrivate(), XrdNetPMarkConfig::myDomain, XrdNetAddrInfo::Name(), XrdSecEntity::tident, and TRACE.

+ Here is the call graph for this function:

◆ Config()

XrdNetPMark * XrdNetPMarkCfg::Config ( XrdSysError eLog,
XrdScheduler sched,
XrdSysTrace trc,
bool &  fatal 
)
static

Definition at line 272 of file XrdNetPMarkCfg.cc.

274 {
275  class DelCfgInfo
276  {public: DelCfgInfo(CfgInfo *&cfg) : cfgInfo(cfg) {}
277  ~DelCfgInfo() {if (cfgInfo) {delete cfgInfo; cfgInfo = 0;}}
278  private:
279  CfgInfo *&cfgInfo;
280  } cleanup(Cfg);
281 
282 // If we have not been configured then simply retrn nil
283 //
284  if (!Cfg)
285  {useFFly = false;
286  return 0;
287  }
288 
289 // Save the message handler
290 //
291  eDest = eLog;
292  Sched = sched;
293  Trace = trc;
294  fatal = false;
295 
296 // If firefly is enabled, make sure we have an ffdest
297 //
298  if (useFFly < 0)
299  {if (ffPortD || ffPortO)
300  {useFFly = true;
301  if (!ffPortO) ffPortO = ffPORT;
302  } else {
303  useFFly = false;
304  eLog->Say("Config warning: firefly disabled; "
305  "configuration incomplete!");
306  return 0;
307  }
308  } else if (useFFly && !ffPortO) ffPortO = ffPORT;
309 
310 // Resolve trace and debug settings
311 //
312  if (doDebug) doTrace = true;
313 
314 // Check if we need a defsfile, if so, construct the map.
315 //
316  if (Cfg->x2aSet.size() == 0 && Cfg->x2eSet.size() == 0)
317  {if (Cfg->defsFile.length())
318  eLog->Say("Config warning: ignoring defsfile; "
319  "no mappings have been specified!");
320  useDefs = false;
321  } else {
322  if (!Cfg->defsFile.length())
323  {eLog->Say("Config invalid: pmark mappings cannot be resolved "
324  "without specifying defsfile!");
325  fatal = true;
326  return 0;
327  }
328  useDefs = true;
329  if (!ConfigDefs())
330  {if (useDefs)
331  {fatal = true;
332  return 0;
333  }
334  eLog->Say("Config warning: pmark ignoring defsfile; "
335  "unable to process and nofail is in effect!");
336  }
337  }
338 
339 // At this point either we still enabled or not. We can be disabled for a
340 // number of reasons and appropriate messages will have been issued.
341 //
342  if (!useFFly) return 0;
343 
344 // Create a netmsg object for firefly reporting if a dest was specified
345 //
346  bool aOK = false;
347  if (ffDest)
348  {XrdNetAddr spec;
349  char buff[1024];
350  const char *eTxt = spec.Set(ffDest, -ffPortD);
351  if (eTxt)
352  {snprintf(buff, sizeof(buff), "%s:%d; %s", ffDest, ffPortD, eTxt);
353  eLog->Emsg("Config", "pmark unable to create UDP tunnel to", buff);
354  useFFly = false;
355  fatal = true;
356  return 0;
357  }
358  if (spec.Format(buff, sizeof(buff)))
359  netMsg = new XrdNetMsg(eDest, buff, &aOK);
360  if (!aOK)
361  {eLog->Emsg("Config", "pmark unable to create UDP tunnel to", ffDest);
362  fatal = true;
363  delete netMsg;
364  netMsg = 0;
365  useFFly= false;
366  return 0;
367  }
368  }
369 
370 // Handle the firefly messages to origin
371 //
372  if (ffPortO)
373  {netOrg = new XrdNetMsg(eDest, 0, &aOK);
374  if (!aOK)
375  {eLog->Emsg("Config","pmark unable to create origin UDP tunnel");
376  fatal = true;
377  useFFly= false;
378  return 0;
379  }
380  }
381 
382 // Get our host name.
383 //
384  myHostName = XrdNetUtils::MyHostName("-"); // Never deleted!
385 
386 // Setup for domain checking
387 //
388  if (chkDom)
389  {const char *dot = index(myHostName, '.');
390  if (dot) myDomain = dot+1;
391  else eDest->Say("Config warning: Unable to determine local domain; "
392  " domain check restricted to IP address type!");
393  }
394 
395 // Finally, we are done. Return the packet markling stub.
396 //
397  return new XrdNetPMarkCfg;
398 }
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
const char * Set(const char *hSpec, int pNum=PortInSpec)
Definition: XrdNetAddr.cc:216
static char * MyHostName(const char *eName="*unknown*", const char **eText=0)
Definition: XrdNetUtils.cc:667
int length() const
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)
Definition: XrdSysError.cc:141
XrdSysTrace * Trace
static const int ffPORT
XrdScheduler * Sched
const char * myHostName
XrdSysError * eLog
std::set< std::string > x2eSet
std::set< std::string > x2aSet

References XrdNetPMarkConfig::Cfg, XrdNetPMarkConfig::chkDom, XrdNetPMarkConfig::CfgInfo::defsFile, XrdNetPMarkConfig::doDebug, XrdNetPMarkConfig::doTrace, XrdNetPMarkConfig::eDest, XrdOfsPrepGPIReal::eLog, XrdSysError::Emsg(), XrdNetPMarkConfig::ffDest, XrdNetPMarkConfig::ffPORT, XrdNetPMarkConfig::ffPortD, XrdNetPMarkConfig::ffPortO, XrdNetAddrInfo::Format(), XrdOucString::length(), XrdNetPMarkConfig::myDomain, XrdNetPMarkConfig::myHostName, XrdNetUtils::MyHostName(), XrdNetPMarkConfig::netMsg, XrdNetPMarkConfig::netOrg, XrdSysError::Say(), XrdNetPMarkConfig::Sched, XrdNetAddr::Set(), XrdNetPMarkConfig::Trace, XrdNetPMarkConfig::useDefs, XrdNetPMarkConfig::useFFly, XrdNetPMarkConfig::CfgInfo::x2aSet, and XrdNetPMarkConfig::CfgInfo::x2eSet.

Referenced by XrdXrootdProtocol::Configure().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Parse()

int XrdNetPMarkCfg::Parse ( XrdSysError eLog,
XrdOucStream Config 
)
static

Definition at line 972 of file XrdNetPMarkCfg.cc.

973 {
974 // Parse pmark directive parameters:
975 //
976 // [[no]debug] [defsfile [[no]fail] {<path> | {curl | wget} [tmo] <url>}]
977 // [domain {any | local | remote}] [[no]fail] [ffdest <udpdest>]
978 // [ffecho <intvl>]
979 // [map2act <ename> {default | {role | user} <name>} <aname>]
980 // [map2exp {default | {path <path> | vo <vo>} <ename>}] [[no]trace]
981 // [use {[no]flowlabel | flowlabel+ff | [no]firefly | [no]scitag}
982 //
983 // <udpdest>: {origin[:<port>] | <host>[:port]} [,<udpdest>]
984 //
985  std::string name;
986  char *val;
987 
988 // If this is the first time here, allocate config info object
989 //
990  if (!Cfg) Cfg = new CfgInfo;
991 
992 // Make sure we have something to parse
993 //
994  if (!(val = Config.GetWord()))
995  {eLog->Say("Config invalid: pmark argument not specified"); return 1;}
996 
997 // Parse the directive options
998 //
999 do{if (!strcmp("debug", val) || !strcmp("nodebug", val))
1000  {doDebug = (*val != 'n');
1001  continue;
1002  }
1003 
1004  if (!strcmp("defsfile", val))
1005  {if (!(val = Config.GetWord()))
1006  {eLog->Say("Config invalid: pmark defsfile value not specified");
1007  return 1;
1008  }
1009 
1010  if (!strcmp("fail", val) || !strcmp("nofail", val))
1011  {noFail = (*val == 'n');
1012  if (!(val = Config.GetWord()))
1013  {eLog->Say("Config invalid: pmark defsfile location not specified");
1014  return 1;
1015  }
1016  }
1017 
1018  if (*val == '/')
1019  {Cfg->defsFile = val;
1020  continue;
1021  }
1022 
1023  if (strcmp("curl", val) && strcmp("wget", val))
1024  {eLog->Say("Config invalid: unknown defsfile transfer agent '",val,"'");
1025  return 1;
1026  }
1027  if (!XrdOucUtils::findPgm(val, Cfg->pgmPath))
1028  {eLog->Say("Config invalid: defsfile transfer agent '",val,"' not found.");
1029  return 1;
1030  }
1031 
1032  if (*val == 'c')
1033  {Cfg->pgmOpts[0]="-m"; Cfg->pgmOpts[2]="-s"; Cfg->pgmOpts[3]="-o";
1034  } else {
1035  Cfg->pgmOpts[0]="-T"; Cfg->pgmOpts[2]="-q"; Cfg->pgmOpts[3]="-O";
1036  }
1037 
1038  val = Config.GetWord();
1039  if (val && isdigit(*val))
1040  {if (XrdOuca2x::a2tm(*eLog,"defsfile timeout",val,&Cfg->defsTO,10))
1041  return 1;
1042  val = Config.GetWord();
1043  }
1044 
1045  if (!val) {eLog->Say("Config invalid: pmark defsfile url not specified");
1046  return 1;
1047  }
1048  Cfg->defsFile = val;
1049  continue;
1050  }
1051 
1052  if (!strcmp("domain", val))
1053  {if (!(val = Config.GetWord()))
1054  {eLog->Say("Config invalid: pmark domain value not specified");
1055  return 1;
1056  }
1057  if (!strcmp(val, "any" )
1058  || !strcmp(val, "all" )) chkDom = domAny;
1059  else if (!strcmp(val, "local" )) chkDom = domLcl;
1060  else if (!strcmp(val, "remote")) chkDom = domRmt;
1061  else {eLog->Say("Config invalid: pmark invalid domain determinant '",
1062  val, "'");
1063  return 1;
1064  }
1065  continue;
1066  }
1067 
1068  if (!strcmp("fail", val) || !strcmp("nofail", val))
1069  {noFail = (*val == 'n');
1070  continue;
1071  }
1072 
1073  // We accept 'origin' as a dest for backward compatibility. That is the
1074  // enforced default should 'use firefly' be specified.
1075  //
1076  if (!strcmp("ffdest", val))
1077  {const char *addtxt = "";
1078  char *colon, *comma;
1079  int xPort;
1080  val = Config.GetWord();
1081  do {if (!val || *val == 0 || *val == ',' || *val == ':')
1082  {eLog->Say("Config invalid: pmark ffdest value not specified",
1083  addtxt); return 1;
1084  }
1085  if ((comma = index(val, ','))) *comma++ = 0;
1086  if ((colon = index(val, ':')))
1087  {*colon++ = 0;
1088  if ((xPort = XrdOuca2x::a2p(*eLog, "udp", colon, false)) <= 0)
1089  return 1;
1090  } else xPort = ffPORT;
1091  if (!strcmp(val, "origin")) ffPortO = xPort;
1092  else {if (ffDest) free(ffDest);
1093  ffDest = strdup(val);
1094  ffPortD = xPort;
1095  }
1096  addtxt = " after comma";
1097  } while((val = comma));
1098  if (useFFly < 0) useFFly = 1;
1099  continue;
1100  }
1101 
1102  if (!strcmp("ffecho", val))
1103  {if (!(val = Config.GetWord()))
1104  {eLog->Say("Config invalid: pmark ffecho value not specified");
1105  return 1;
1106  }
1107  if (XrdOuca2x::a2tm(*eLog,"ffecho interval", val, &ffEcho, 0)) return 1;
1108  if (ffEcho < 30) ffEcho = 0;
1109  continue;
1110  }
1111 
1112  if (!strcmp("map2act", val))
1113  {if (!(val = Config.GetWord()))
1114  {eLog->Say("Config invalid: pmark activity experiment not specified");
1115  return 1;
1116  }
1117  name = val;
1118 
1119  if (!(val = Config.GetWord()))
1120  {eLog->Say("Config invalid: pmark activity determinant not specified");
1121  return 1;
1122  }
1123 
1124  const char *adet;
1125  if (!strcmp(val, "default")) adet = "dflt";
1126  else if (!strcmp(val, "role")) adet = "role";
1127  else if (!strcmp(val, "user")) adet = "user";
1128  else {eLog->Say("Config invalid: pmark invalid activity determinant '",
1129  val, "'");
1130  return 1;
1131  }
1132  name += ' '; name += val;
1133 
1134  if (*adet != 'd' && !(val = Config.GetWord()))
1135  {eLog->Say("Config invalid: pmark activity", adet, "not specified");
1136  return 1;
1137  }
1138  name += ' '; name += val;
1139 
1140  if (!(val = Config.GetWord()))
1141  {eLog->Say("Config invalid: pmark", adet, "activity not specified");
1142  return 1;
1143  }
1144  name += ' '; name += val;
1145 
1146  Cfg->x2aSet.insert(name);
1147  continue;
1148  }
1149 
1150  if (!strcmp("map2exp", val))
1151  {if (!(val = Config.GetWord()))
1152  {eLog->Say("Config invalid: pmark map2exp type not specified");
1153  return 1;
1154  }
1155  if (strcmp("default", val) && strcmp("path", val)
1156  && strcmp("vo", val) && strcmp("vorg", val))
1157  {eLog->Say("Config invalid: invalid pmark map2exp type, '",val,"'.");
1158  return 1;
1159  }
1160  name = val;
1161 
1162  if (*val != 'd' && !(val = Config.GetWord()))
1163  {eLog->Say("Config invalid: pmark map2exp ", name.c_str(),
1164  "not specified");
1165  return 1;
1166  }
1167  name += ' '; name += val;
1168 
1169  if (!(val = Config.GetWord()))
1170  {eLog->Say("Config invalid: pmark map2exp expirement not specified");
1171  return 1;
1172  }
1173  name += ' '; name += val;
1174 
1175  Cfg->x2eSet.insert(name);
1176  continue;
1177  }
1178 
1179  if (!strcmp("trace", val) || !strcmp("notrace", val))
1180  {doTrace = (*val != 'n');
1181  continue;
1182  }
1183 
1184  if (!strcmp("use", val))
1185  {if (!(val = Config.GetWord()))
1186  {eLog->Say("Config invalid: pmark use argument not specified");
1187  return 1;
1188  }
1189  bool argOK = false;
1190  char *arg;
1191  do {bool theval = strncmp(val, "no", 2) != 0;
1192  arg = (!theval ? val += 2 : val);
1193  if (!strcmp("flowlabel", arg))
1194  {useFLbl = theval; addFLFF = false; argOK = true;}
1195  else if (!strcmp("flowlabel+ff", arg))
1196  {addFLFF = useFLbl = theval; argOK = true;}
1197  else if (!strcmp("firefly", arg))
1198  {useFFly = (theval ? 1 : 0); argOK = true;}
1199  else if (!strcmp("scitag", arg)) {useSTag = theval; argOK = true;}
1200  else if (argOK) {Config.RetToken(); break;}
1201  else {eLog->Say("Config invalid: 'use ",val,"' is invalid");
1202  return 1;
1203  }
1204  } while((val = Config.GetWord()));
1205  if (!val) break;
1206  continue;
1207  }
1208 
1209  eLog->Say("Config warning: ignoring unknown pmark argument'",val,"'.");
1210 
1211  } while ((val = Config.GetWord()));
1212 
1213  return 0;
1214 }
static XrdNetPMark * Config(XrdSysError *eLog, XrdScheduler *sched, XrdSysTrace *trc, bool &fatal)
static bool findPgm(const char *pgm, XrdOucString &path)
Definition: XrdOucUtils.cc:355
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 const int domAny
const char * pgmOpts[pgmOptN]

References XrdOuca2x::a2p(), XrdOuca2x::a2tm(), XrdNetPMarkConfig::addFLFF, XrdNetPMarkConfig::Cfg, XrdNetPMarkConfig::chkDom, XrdCms::Config, XrdNetPMarkConfig::CfgInfo::defsFile, XrdNetPMarkConfig::CfgInfo::defsTO, XrdNetPMarkConfig::doDebug, XrdNetPMarkConfig::domAny, XrdNetPMarkConfig::domLcl, XrdNetPMarkConfig::domRmt, XrdNetPMarkConfig::doTrace, XrdOfsPrepGPIReal::eLog, XrdNetPMarkConfig::ffDest, XrdNetPMarkConfig::ffEcho, XrdNetPMarkConfig::ffPORT, XrdNetPMarkConfig::ffPortD, XrdNetPMarkConfig::ffPortO, XrdOucUtils::findPgm(), XrdNetPMarkConfig::noFail, XrdNetPMarkConfig::CfgInfo::pgmOpts, XrdNetPMarkConfig::CfgInfo::pgmPath, XrdSysError::Say(), XrdNetPMarkConfig::useFFly, XrdNetPMarkConfig::useFLbl, XrdNetPMarkConfig::useSTag, XrdNetPMarkConfig::CfgInfo::x2aSet, and XrdNetPMarkConfig::CfgInfo::x2eSet.

+ Here is the call graph for this function:

The documentation for this class was generated from the following files: