Skip to content

Commit

Permalink
[Server] Allow prefunctory redirect based on client's net attributes.
Browse files Browse the repository at this point in the history
  • Loading branch information
abh3 authored and gganis committed Nov 23, 2021
1 parent d26b177 commit 14ec193
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 5 deletions.
56 changes: 55 additions & 1 deletion src/XrdXrootd/XrdXrootdConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,8 @@ int XrdXrootdProtocol::xprep(XrdOucStream &Config)
/* Function: xred
Purpose: To parse the directive: redirect <host>:<port>[%<prvhost>:<port>]
{<funcs>|[?]<path>}
{<funcs>|[?]<path>} |
client <domlist>
<funcs> are one or more of the following functions that will
be immediately redirected to <host>:<port>. Each function
Expand Down Expand Up @@ -1547,6 +1548,10 @@ int XrdXrootdProtocol::xred(XrdOucStream &Config)
if (!(val = Config.GetWord()))
{eDest.Emsg("config", "redirect option not specified"); return 1;}

// Handle the client option
//
if (!strcmp("client", val)) return xred_clnt(Config, hP, rPort);

if (*val == '/' || (isQ = ((*val == '?') || !strcmp(val,"enoent"))))
{if (isQ)
{RQLxist = 1;
Expand Down Expand Up @@ -1597,6 +1602,55 @@ int XrdXrootdProtocol::xred(XrdOucStream &Config)

/******************************************************************************/

int XrdXrootdProtocol::xred_clnt(XrdOucStream &Config,char *hP[2],int rPort[2])
{
static const int maxDom = sizeof(RouteClient.Domain)/sizeof(char*);
char *val;

// Reset values
//
if (CL_Redir)
{for (int i = 0; i < RouteClient.DomCnt; i++)
{if (RouteClient.Domain[i]) free(RouteClient.Domain[i]);}
}
for (int i = 0; i < maxDom; i++) RouteClient.Domain[i] = 0;
RouteClient.DomCnt = 0;
RouteClient.pvtIP = false;
RouteClient.lclDom = false;
CL_Redir = true;

// Process arguments
//
if (!(val = Config.GetWord()))
{eDest.Emsg("Config", "redirect client argument not specified.");
return 1;
}

while(val)
{ if (!strcmp("private", val)) RouteClient.pvtIP = true;
else if (!strcmp("local", val)) RouteClient.lclDom = true;
else if (*val == '.')
{if (RouteClient.DomCnt >= maxDom)
{eDest.Emsg("Config",
"Too many redirect client domains specified.");
return 1;
}
RouteClient.Domain[RouteClient.DomCnt++] = strdup(val);
}
else {eDest.Emsg("Config", "Invalid redirect client domain -", val);
return 1;
}
val = Config.GetWord();
}

// Set the host parameters
//
xred_set(RD_client, hP, rPort);
return 0;
}

/******************************************************************************/

bool XrdXrootdProtocol::xred_php(char *val, char *hP[2], int rPort[2],
const char *what, bool optport)
{
Expand Down
37 changes: 34 additions & 3 deletions src/XrdXrootd/XrdXrootdProtocol.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,12 @@

#include "Xrd/XrdBuffer.hh"
#include "Xrd/XrdLink.hh"
#include "XrdOuc/XrdOucStream.hh"
#include "XrdNet/XrdNetIF.hh"
#include "XrdOuc/XrdOucEnv.hh"
#include "XrdOuc/XrdOucUtils.hh"
#include "XrdOuc/XrdOucStream.hh"
#include "XrdOuc/XrdOucString.hh"
#include "XrdOuc/XrdOucUtils.hh"
#include "XrdSec/XrdSecProtect.hh"
#include "XrdSfs/XrdSfsFlags.hh"
#include "XrdSfs/XrdSfsInterface.hh"
Expand Down Expand Up @@ -149,10 +152,13 @@ bool XrdXrootdProtocol::PrepareAlt = false;
bool XrdXrootdProtocol::LimitError = true;

struct XrdXrootdProtocol::RD_Table XrdXrootdProtocol::Route[RD_Num];
struct XrdXrootdProtocol::RC_Table XrdXrootdProtocol::RouteClient;
int XrdXrootdProtocol::OD_Stall = 33;
bool XrdXrootdProtocol::OD_Bypass= false;
bool XrdXrootdProtocol::OD_Redir = false;

bool XrdXrootdProtocol::CL_Redir = false;

bool XrdXrootdProtocol::isProxy = false;

int XrdXrootdProtocol::usxMaxNsz= kXR_faMaxNlen;
Expand Down Expand Up @@ -481,6 +487,8 @@ int XrdXrootdProtocol::Process2()
return do_Sync();
case kXR_close: ReqID.setID(Request.header.streamid);
return do_Close();
case kXR_stat: if (!Request.header.dlen) return do_Stat();
break;
case kXR_truncate: ReqID.setID(Request.header.streamid);
if (!Request.header.dlen) return do_Truncate();
break;
Expand Down Expand Up @@ -518,8 +526,7 @@ int XrdXrootdProtocol::Process2()
// Process items that don't need arguments but may have them
//
switch(Request.header.requestid)
{case kXR_stat: return do_Stat();
case kXR_endsess: return do_Endsess();
{case kXR_endsess: return do_Endsess();
default: break;
}

Expand All @@ -530,6 +537,29 @@ int XrdXrootdProtocol::Process2()
return 0;
}

// All of the subsequent requests can be redirected and are subject to
// prefunctory redirection which we check here.
//
if (CL_Redir && !Link->hasBridge())
{bool doRdr = false;
if (Link->AddrInfo()->isPrivate()) rdType = 1;
if (RouteClient.pvtIP && rdType) doRdr = true;
else if (RouteClient.lclDom && XrdNetIF::InDomain( Link->AddrInfo()))
doRdr = true;
else if (RouteClient.DomCnt)
{XrdOucString hName = Link->Host();
for (int i = 0; i < RouteClient.DomCnt; i++)
{if (hName.endswith(RouteClient.Domain[i]))
{doRdr = true; break;}
}
}
if (doRdr)
{Response.Send(kXR_redirect,Route[RD_client].Port[rdType],
Route[RD_client].Host[rdType]);
return -1;
}
}

// Process items that keep own statistics
//
switch(Request.header.requestid)
Expand All @@ -556,6 +586,7 @@ int XrdXrootdProtocol::Process2()
case kXR_rm: return do_Rm();
case kXR_rmdir: return do_Rmdir();
case kXR_set: return do_Set();
case kXR_stat: return do_Stat();
case kXR_statx: return do_Statx();
case kXR_truncate: return do_Truncate();
default: break;
Expand Down
11 changes: 10 additions & 1 deletion src/XrdXrootd/XrdXrootdProtocol.hh
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ private:
//
enum RD_func {RD_chmod = 0, RD_chksum, RD_dirlist, RD_locate, RD_mkdir,
RD_mv, RD_prepare, RD_prepstg, RD_rm, RD_rmdir,
RD_stat, RD_trunc, RD_ovld,
RD_stat, RD_trunc, RD_ovld, RD_client,
RD_open1, RD_open2, RD_open3, RD_open4, RD_Num};

int do_Auth();
Expand Down Expand Up @@ -349,6 +349,7 @@ static int xmongs(XrdOucStream &Config);
static bool xmongsend(XrdOucStream &Config, char *val, char *&dest,
int &opt, int &fmt, int &hdr);
static int xred(XrdOucStream &Config);
static int xred_clnt(XrdOucStream &Config, char *hP[2], int rPort[2]);
static bool xred_php(char *val, char *hP[2], int rPort[2], const char *what,
bool optport=false);
static void xred_set(RD_func func, char *rHost[2], int rPort[2]);
Expand Down Expand Up @@ -432,10 +433,18 @@ static uint64_t fsFeatures;
static struct RD_Table {char *Host[2];
unsigned short Port[2];
short RDSz[2];} Route[RD_Num];

static struct RC_Table {char *Domain[4];
short DomCnt;
bool pvtIP;
bool lclDom;} RouteClient;

static int OD_Stall;
static bool OD_Bypass;
static bool OD_Redir;

static bool CL_Redir;

static bool isProxy;

// Extended attributes
Expand Down

0 comments on commit 14ec193

Please sign in to comment.