// ----------------------------------------------------------------------
// File: ShouldRedirect.cc
// Author: Andreas-Joachim Peters - CERN
// ----------------------------------------------------------------------
/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2011 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
//------------------------------------------------------------------------------
// This file is included source code in XrdMgmOfs.cc to make the code more
// transparent without slowing down the compilation time.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Check if a client based on the called function and his identity should be
// redirected
//------------------------------------------------------------------------------
bool
XrdMgmOfs::ShouldRedirect(const char* function, int __AccessMode__,
eos::common::VirtualIdentity& vid,
std::string& host, int& port, bool& collapse)
{
eos::common::RWMutexReadLock lock(Access::gAccessMutex);
if ((vid.host == "localhost") || (vid.host == "localhost.localdomain") ||
(vid.uid == 0)) {
if (mMaster->IsMaster() || (IS_ACCESSMODE_R)) {
// the slave is redirected to the master for everything which sort of 'writes'
return false;
}
}
if (!Access::gRedirectionRules.empty()) {
bool c1 = Access::gRedirectionRules.count(std::string("*"));
bool c3 = (IS_ACCESSMODE_R &&
Access::gRedirectionRules.count(std::string("r:*")));
bool c2 = (IS_ACCESSMODE_W &&
Access::gRedirectionRules.count(std::string("w:*")));
bool c4 = (IS_ACCESSMODE_R_MASTER &&
Access::gRedirectionRules.count(std::string("w:*")));
if (c1 || c2 || c3 || c4) {
// redirect
std::string delimiter = ":";
std::vector tokens;
if (c1) {
eos::common::StringConversion::Tokenize(
Access::gRedirectionRules[std::string("*")], tokens, delimiter);
gOFS->MgmStats.Add("Redirect", vid.uid, vid.gid, 1);
} else {
if (c2) {
eos::common::StringConversion::Tokenize(
Access::gRedirectionRules[std::string("w:*")], tokens, delimiter);
gOFS->MgmStats.Add("RedirectW", vid.uid, vid.gid, 1);
} else {
if (c3) {
eos::common::StringConversion::Tokenize(
Access::gRedirectionRules[std::string("r:*")], tokens, delimiter);
gOFS->MgmStats.Add("RedirectR", vid.uid, vid.gid, 1);
} else {
if (c4) {
eos::common::StringConversion::Tokenize(
Access::gRedirectionRules[std::string("w:*")], tokens, delimiter);
gOFS->MgmStats.Add("RedirectR-Master", vid.uid, vid.gid, 1);
}
}
}
}
if (!tokens.empty()) { // tokens should never be empty but @note fuzz tests showed it could be. Will have to dig deeper
if (tokens.size() == 1) {
host = tokens[0];
port = 1094;
} else {
if (tokens.size() == 2) {
host = tokens[0];
port = strtol(tokens[1].c_str(), nullptr,10);
} else {
if (tokens.size() == 3) {
host = tokens[0];
port = strtol(tokens[1].c_str(), nullptr,10);
uint64_t delay = ( strtol(tokens[2].c_str(), nullptr,10 ));
if (delay) {
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
}
}
}
}
}
collapse = true;
return true;
}
}
return false;
}