Robustify accesses to server config
This commit is contained in:
parent
6032f236d2
commit
98e3940079
15 changed files with 320 additions and 266 deletions
|
@ -126,6 +126,7 @@ static inline void show_stackframe(){}
|
|||
|
||||
#define SHM_STREAM_INDEX "MstSTRM%s" //%s stream name
|
||||
#define SHM_STREAM_STATE "MstSTATE%s" //%s stream name
|
||||
#define SHM_STREAM_CONF "MstSCnf%s" //%s stream name
|
||||
#define STRMSTAT_OFF 0
|
||||
#define STRMSTAT_INIT 1
|
||||
#define STRMSTAT_BOOT 2
|
||||
|
@ -142,9 +143,10 @@ static inline void show_stackframe(){}
|
|||
#define SHM_TRIGGER "MstTRGR%s" //%s trigger name
|
||||
#define SEM_LIVE "/MstLIVE%s" //%s stream name
|
||||
#define SEM_INPUT "/MstInpt%s" //%s stream name
|
||||
#define SEM_CONF "/MstConfLock"
|
||||
#define SEM_SESSCACHE "/MstSessCacheLock"
|
||||
#define SHM_CONF "MstConf"
|
||||
#define SHM_CAPA "MstCapa"
|
||||
#define SHM_PROTO "MstProt"
|
||||
#define SHM_PROXY "MstProx"
|
||||
#define SHM_STATE_LOGS "MstStateLogs"
|
||||
#define SHM_STATE_ACCS "MstStateAccs"
|
||||
#define SHM_STATE_STREAMS "MstStateStreams"
|
||||
|
|
125
lib/stream.cpp
125
lib/stream.cpp
|
@ -129,20 +129,17 @@ JSON::Value Util::getStreamConfig(const std::string & streamname){
|
|||
FAIL_MSG("Stream opening denied: %s is longer than 100 characters (%lu).", streamname.c_str(), streamname.size());
|
||||
return result;
|
||||
}
|
||||
IPC::sharedPage mistConfOut(SHM_CONF, DEFAULT_CONF_PAGE_SIZE, false, false);
|
||||
IPC::semaphore configLock(SEM_CONF, O_CREAT | O_RDWR, ACCESSPERMS, 1);
|
||||
configLock.wait();
|
||||
DTSC::Scan config = DTSC::Scan(mistConfOut.mapped, mistConfOut.len);
|
||||
std::string smp = streamname.substr(0, streamname.find_first_of("+ "));
|
||||
//check if smp (everything before + or space) exists
|
||||
DTSC::Scan stream_cfg = config.getMember("streams").getMember(smp);
|
||||
|
||||
char tmpBuf[NAME_BUFFER_SIZE];
|
||||
snprintf(tmpBuf, NAME_BUFFER_SIZE, SHM_STREAM_CONF, smp.c_str());
|
||||
Util::DTSCShmReader rStrmConf(tmpBuf);
|
||||
DTSC::Scan stream_cfg = rStrmConf.getScan();
|
||||
if (!stream_cfg){
|
||||
DEBUG_MSG(DLVL_MEDIUM, "Stream %s not configured", streamname.c_str());
|
||||
}else{
|
||||
result = stream_cfg.asJSON();
|
||||
WARN_MSG("Could not get stream '%s' config!", smp.c_str());
|
||||
return result;
|
||||
}
|
||||
configLock.post();//unlock the config semaphore
|
||||
return result;
|
||||
return stream_cfg.asJSON();
|
||||
}
|
||||
|
||||
DTSC::Meta Util::getStreamMeta(const std::string & streamname){
|
||||
|
@ -207,25 +204,20 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
|
|||
return true;
|
||||
}
|
||||
|
||||
/*LTS-START*/
|
||||
/*
|
||||
* OLD CODE FOR HARDLIMITS.
|
||||
* Maybe re-enable?
|
||||
* Still sorta-works, but undocumented...
|
||||
{
|
||||
//Attempt to load up configuration and find this stream
|
||||
IPC::sharedPage mistConfOut(SHM_CONF, DEFAULT_CONF_PAGE_SIZE);
|
||||
IPC::semaphore configLock(SEM_CONF, O_CREAT | O_RDWR, ACCESSPERMS, 1);
|
||||
//Lock the config to prevent race conditions and corruption issues while reading
|
||||
configLock.wait();
|
||||
DTSC::Scan config = DTSC::Scan(mistConfOut.mapped, mistConfOut.len);
|
||||
//Abort if no config available
|
||||
if (config){
|
||||
if (config.getMember("hardlimit_active")) {
|
||||
configLock.post();//unlock the config semaphore
|
||||
return false;
|
||||
}
|
||||
IPC::ConfigWrapper confLock(15);
|
||||
if (confLock){
|
||||
IPC::sharedPage mistConfOut(SHM_CONF, DEFAULT_CONF_PAGE_SIZE);
|
||||
DTSC::Scan config = DTSC::Scan(mistConfOut.mapped, mistConfOut.len);
|
||||
//Abort if we loaded a config and there is a hardlimit active in it.
|
||||
if (config && config.getMember("hardlimit_active")){return false;}
|
||||
}
|
||||
//unlock the config semaphore
|
||||
configLock.post();
|
||||
}
|
||||
/*LTS-END*/
|
||||
*/
|
||||
|
||||
//Find stream base name
|
||||
std::string smp = streamname.substr(0, streamname.find_first_of("+ "));
|
||||
|
@ -368,22 +360,17 @@ JSON::Value Util::getInputBySource(const std::string &filename, bool isProvider)
|
|||
JSON::Value ret;
|
||||
|
||||
//Attempt to load up configuration and find this stream
|
||||
IPC::sharedPage mistConfOut(SHM_CONF, DEFAULT_CONF_PAGE_SIZE);
|
||||
IPC::semaphore configLock(SEM_CONF, O_CREAT | O_RDWR, ACCESSPERMS, 1);
|
||||
//Lock the config to prevent race conditions and corruption issues while reading
|
||||
configLock.wait();
|
||||
DTSC::Scan config = DTSC::Scan(mistConfOut.mapped, mistConfOut.len);
|
||||
//Abort if no config available
|
||||
if (!config){
|
||||
FAIL_MSG("Configuration not available, aborting! Is MistController running?");
|
||||
configLock.post();//unlock the config semaphore
|
||||
Util::DTSCShmReader rCapa(SHM_CAPA);
|
||||
DTSC::Scan inputs = rCapa.getMember("inputs");
|
||||
//Abort if not available
|
||||
if (!inputs){
|
||||
FAIL_MSG("Capabilities not available, aborting! Is MistController running?");
|
||||
return false;
|
||||
}
|
||||
|
||||
//check in curConf for capabilities-inputs-<naam>-priority/source_match
|
||||
//check in curConf for <naam>-priority/source_match
|
||||
bool selected = false;
|
||||
long long int curPrio = -1;
|
||||
DTSC::Scan inputs = config.getMember("capabilities").getMember("inputs");
|
||||
DTSC::Scan input;
|
||||
unsigned int input_size = inputs.getSize();
|
||||
bool noProviderNoPick = false;
|
||||
|
@ -437,7 +424,6 @@ JSON::Value Util::getInputBySource(const std::string &filename, bool isProvider)
|
|||
}else{
|
||||
ret = input.asJSON();
|
||||
}
|
||||
configLock.post();//unlock the config semaphore
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -462,34 +448,34 @@ pid_t Util::startPush(const std::string & streamname, std::string & target) {
|
|||
streamVariables(target, streamname);
|
||||
|
||||
//Attempt to load up configuration and find this stream
|
||||
IPC::sharedPage mistConfOut(SHM_CONF, DEFAULT_CONF_PAGE_SIZE);
|
||||
IPC::semaphore configLock(SEM_CONF, O_CREAT | O_RDWR, ACCESSPERMS, 1);
|
||||
//Lock the config to prevent race conditions and corruption issues while reading
|
||||
configLock.wait();
|
||||
|
||||
DTSC::Scan config = DTSC::Scan(mistConfOut.mapped, mistConfOut.len);
|
||||
DTSC::Scan outputs = config.getMember("capabilities").getMember("connectors");
|
||||
std::string output_bin = "";
|
||||
std::string checkTarget = target.substr(0, target.rfind('?'));
|
||||
unsigned int outputs_size = outputs.getSize();
|
||||
for (unsigned int i = 0; i<outputs_size && !output_bin.size(); ++i){
|
||||
DTSC::Scan output = outputs.getIndice(i);
|
||||
if (output.getMember("push_urls")){
|
||||
unsigned int push_count = output.getMember("push_urls").getSize();
|
||||
for (unsigned int j = 0; j < push_count; ++j){
|
||||
std::string tar_match = output.getMember("push_urls").getIndice(j).asString();
|
||||
std::string front = tar_match.substr(0,tar_match.find('*'));
|
||||
std::string back = tar_match.substr(tar_match.find('*')+1);
|
||||
MEDIUM_MSG("Checking output %s: %s (%s)", outputs.getIndiceName(i).c_str(), output.getMember("name").asString().c_str(), checkTarget.c_str());
|
||||
|
||||
if (checkTarget.substr(0,front.size()) == front && checkTarget.substr(checkTarget.size()-back.size()) == back){
|
||||
output_bin = Util::getMyPath() + "MistOut" + output.getMember("name").asString();
|
||||
break;
|
||||
{
|
||||
Util::DTSCShmReader rCapa(SHM_CAPA);
|
||||
DTSC::Scan outputs = rCapa.getMember("connectors");
|
||||
if (!outputs){
|
||||
FAIL_MSG("Capabilities not available, aborting! Is MistController running?");
|
||||
return 0;
|
||||
}
|
||||
std::string checkTarget = target.substr(0, target.rfind('?'));
|
||||
unsigned int outputs_size = outputs.getSize();
|
||||
for (unsigned int i = 0; i<outputs_size && !output_bin.size(); ++i){
|
||||
DTSC::Scan output = outputs.getIndice(i);
|
||||
if (output.getMember("push_urls")){
|
||||
unsigned int push_count = output.getMember("push_urls").getSize();
|
||||
for (unsigned int j = 0; j < push_count; ++j){
|
||||
std::string tar_match = output.getMember("push_urls").getIndice(j).asString();
|
||||
std::string front = tar_match.substr(0,tar_match.find('*'));
|
||||
std::string back = tar_match.substr(tar_match.find('*')+1);
|
||||
MEDIUM_MSG("Checking output %s: %s (%s)", outputs.getIndiceName(i).c_str(), output.getMember("name").asString().c_str(), checkTarget.c_str());
|
||||
|
||||
if (checkTarget.substr(0,front.size()) == front && checkTarget.substr(checkTarget.size()-back.size()) == back){
|
||||
output_bin = Util::getMyPath() + "MistOut" + output.getMember("name").asString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
configLock.post();
|
||||
|
||||
if (output_bin == ""){
|
||||
FAIL_MSG("No output found for target %s, aborting push.", target.c_str());
|
||||
|
@ -517,3 +503,18 @@ uint8_t Util::getStreamStatus(const std::string & streamname){
|
|||
return streamStatus.mapped[0];
|
||||
}
|
||||
|
||||
Util::DTSCShmReader::DTSCShmReader(const std::string &pageName){
|
||||
rPage.init(pageName, 0);
|
||||
if (rPage){
|
||||
rAcc = Util::RelAccX(rPage.mapped);
|
||||
}
|
||||
}
|
||||
|
||||
DTSC::Scan Util::DTSCShmReader::getMember(const std::string &indice){
|
||||
return DTSC::Scan(rAcc.getPointer("dtsc_data"), rAcc.getSize("dtsc_data")).getMember(indice.c_str());
|
||||
}
|
||||
|
||||
DTSC::Scan Util::DTSCShmReader::getScan(){
|
||||
return DTSC::Scan(rAcc.getPointer("dtsc_data"), rAcc.getSize("dtsc_data"));
|
||||
}
|
||||
|
||||
|
|
13
lib/stream.h
13
lib/stream.h
|
@ -6,6 +6,8 @@
|
|||
#include "socket.h"
|
||||
#include "json.h"
|
||||
#include "dtsc.h"
|
||||
#include "shared_memory.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace Util {
|
||||
void streamVariables(std::string &str, const std::string & streamname, const std::string & source = "");
|
||||
|
@ -18,5 +20,16 @@ namespace Util {
|
|||
JSON::Value getInputBySource(const std::string & filename, bool isProvider = false);
|
||||
DTSC::Meta getStreamMeta(const std::string & streamname);
|
||||
uint8_t getStreamStatus(const std::string & streamname);
|
||||
|
||||
class DTSCShmReader{
|
||||
public:
|
||||
DTSCShmReader(const std::string &pageName);
|
||||
DTSC::Scan getMember(const std::string &indice);
|
||||
DTSC::Scan getScan();
|
||||
private:
|
||||
IPC::sharedPage rPage;
|
||||
Util::RelAccX rAcc;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "defines.h"
|
||||
#include "timing.h"
|
||||
#include "procs.h"
|
||||
#include "dtsc.h"
|
||||
#include <errno.h> // errno, ENOENT, EEXIST
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
@ -564,6 +565,13 @@ namespace Util{
|
|||
r << std::endl;
|
||||
break;
|
||||
}
|
||||
case RAX_DTSC:{
|
||||
char * ptr = getPointer(it->first, i);
|
||||
size_t sz = getSize(it->first, i);
|
||||
r << std::endl;
|
||||
r << DTSC::Scan(ptr, sz).toPrettyString(indent+6) << std::endl;
|
||||
break;
|
||||
}
|
||||
default: r << "[UNIMPLEMENTED]" << std::endl; break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ namespace Util{
|
|||
#define RAX_RAW 0x40
|
||||
#define RAX_256RAW 0x44
|
||||
#define RAX_512RAW 0x45
|
||||
#define RAX_DTSC 0x50
|
||||
|
||||
/// Reliable Access class.
|
||||
/// Provides reliable access to memory data structures, using dynamic static offsets and a status
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue