Added maxconnsperip setting to controller. Only enforced if USER_NEW trigger is in use.

This commit is contained in:
Thulinma 2016-05-16 16:47:18 +02:00
parent 219e326048
commit f641989991
4 changed files with 29 additions and 3 deletions

View file

@ -322,7 +322,7 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
/// Attempt to start a push for streamname to target.
/// Both streamname and target may be changed by this function:
/// - streamname is sanitized to a permissible streamname
/// - target gets variables replaced and may be altered by the RECORDING_START trigger response.
/// - target gets variables replaced and may be altered by the PUSH_OUT_START trigger response.
/// Attempts to match the altered target to an output that can push to it.
pid_t Util::startPush(std::string & streamname, std::string & target) {

View file

@ -167,6 +167,7 @@ int main(int argc, char ** argv){
Controller::conf.addOption("port", stored_port);
Controller::conf.addOption("interface", stored_interface);
Controller::conf.addOption("username", stored_user);
Controller::conf.addOption("maxconnsperip", JSON::fromString("{\"long\":\"maxconnsperip\", \"short\":\"M\", \"arg\":\"integer\" \"default\":0, \"help\":\"Max simultaneous sessions per unique IP address. Only enforced if the USER_NEW trigger is in use.\"}"));
Controller::conf.addOption("account", JSON::fromString("{\"long\":\"account\", \"short\":\"a\", \"arg\":\"string\" \"default\":\"\", \"help\":\"A username:password string to create a new account with.\"}"));
Controller::conf.addOption("logfile", JSON::fromString("{\"long\":\"logfile\", \"short\":\"L\", \"arg\":\"string\" \"default\":\"\",\"help\":\"Redirect all standard output to a log file, provided with an argument\"}"));
Controller::conf.addOption("configFile", JSON::fromString("{\"long\":\"config\", \"short\":\"c\", \"arg\":\"string\" \"default\":\"config.json\", \"help\":\"Specify a config file other than default.\"}"));
@ -230,6 +231,7 @@ int main(int argc, char ** argv){
if (Controller::Storage["config"]["controller"]["prometheus"]){
Controller::conf.getOption("prometheus", true)[0u] = Controller::Storage["config"]["controller"]["prometheus"];
}
Controller::maxConnsPerIP = Controller::conf.getInteger("maxconnsperip");
Controller::Storage["config"]["controller"]["prometheus"] = Controller::conf.getString("prometheus");
{
IPC::semaphore configLock(SEM_CONF, O_CREAT | O_RDWR, ACCESSPERMS, 1);

View file

@ -39,6 +39,7 @@ std::map<unsigned long, Controller::sessIndex> Controller::connToSession; ///< M
bool Controller::killOnExit = KILL_ON_EXIT;
tthread::mutex Controller::statsMutex;
std::map<std::string, unsigned int> Controller::activeStreams;
unsigned int Controller::maxConnsPerIP = 0;
//For server-wide totals. Local to this file only.
struct streamTotals {
@ -190,9 +191,31 @@ void Controller::SharedMemStats(void * config){
/// Updates the given active connection with new stats data.
void Controller::statSession::update(unsigned long index, IPC::statExchange & data){
//update the sync byte: 0 = requesting fill, 1 = needs checking, > 1 = state known
//update the sync byte: 0 = requesting fill, 1 = needs checking, > 1 = state known (100=denied, 10=accepted)
if (!data.getSync()){
data.setSync(sync);
//if we have a maximum connection count per IP, enforce it
if (maxConnsPerIP){
unsigned int currConns = 1;
long long shortly = Util::epoch();
std::string myHost;
{
sessIndex tmpidx(data);
myHost = tmpidx.host;
}
for (std::map<sessIndex, statSession>::iterator it = sessions.begin(); it != sessions.end(); it++){
if (&it->second != this && it->first.host == myHost && (it->second.hasDataFor(shortly-STATS_DELAY) || it->second.hasDataFor(shortly) || it->second.hasDataFor(shortly-1) || it->second.hasDataFor(shortly-2) || it->second.hasDataFor(shortly-3) || it->second.hasDataFor(shortly-4) || it->second.hasDataFor(shortly-5)) && ++currConns > maxConnsPerIP){break;}
}
if (currConns > maxConnsPerIP){
WARN_MSG("Disconnecting session from %s: exceeds max connection count of %u", myHost.c_str(), maxConnsPerIP);
data.setSync(100);
}else{
data.setSync(sync);
}
}else{
//no maximum, just set the sync byte to its current value
data.setSync(sync);
}
}else{
if (sync < 2){
sync = data.getSync();

View file

@ -16,6 +16,7 @@
namespace Controller {
extern bool killOnExit;
extern unsigned int maxConnsPerIP;
//These functions keep track of which streams are currently active.
extern std::map<std::string, unsigned int> activeStreams;