[DEV] add support of redirect the client on direct connection of the gateway (if authorised in routeur config file)
This commit is contained in:
parent
27a7c404fb
commit
e7771b706d
@ -32,28 +32,39 @@ appl::ClientInterface::~ClientInterface() {
|
||||
APPL_INFO("-------------------");
|
||||
}
|
||||
|
||||
bool appl::ClientInterface::requestURI(const etk::String& _uri) {
|
||||
APPL_WARNING("request connect on CLIENT: '" << _uri << "'");
|
||||
etk::String appl::ClientInterface::requestURI(const etk::String& _uri, const etk::Map<etk::String,etk::String>& _options) {
|
||||
APPL_INFO("request connect on CLIENT: '" << _uri << "' from " << m_interfaceClient.getRemoteAddress());
|
||||
if(m_routerInterface == nullptr) {
|
||||
APPL_ERROR("Can not access to the main GateWay interface (nullptr)");
|
||||
return false;
|
||||
return "CLOSE";
|
||||
}
|
||||
etk::String tmpURI = _uri;
|
||||
if (tmpURI.size() == 0) {
|
||||
APPL_ERROR("Empty URI ... not supported ...");
|
||||
return false;
|
||||
return "CLOSE";
|
||||
}
|
||||
if (tmpURI[0] == '/') {
|
||||
tmpURI = etk::String(tmpURI.begin() + 1, tmpURI.end());
|
||||
}
|
||||
// TODO : Remove subParameters xxx?YYY
|
||||
m_userGateWay = m_routerInterface->get(tmpURI);
|
||||
APPL_INFO("Connect on client done : '" << tmpURI << "'");
|
||||
if (m_userGateWay == nullptr) {
|
||||
APPL_ERROR("Can not connect on Client ==> it does not exist ...");
|
||||
return false;
|
||||
return "CLOSE";
|
||||
}
|
||||
return true;
|
||||
uint16_t externalPort = m_userGateWay->getOpenExternalPort();
|
||||
if (externalPort != 0) {
|
||||
if (m_interfaceClient.getRemoteAddress().startWith("127.0.0.1:") == true) {
|
||||
// find a local port ==> can redirect stream.
|
||||
APPL_WARNING("Request redirect of the connection, because it is possible");
|
||||
// remove reference on the client befor it was inform of our connection
|
||||
m_userGateWay->rmClient(sharedFromThis());
|
||||
m_userGateWay = nullptr;
|
||||
m_interfaceRedirect = true;
|
||||
return etk::String("REDIRECT:") + m_routerInterface->propertyClientIp.get() + ":" + etk::toString(externalPort);
|
||||
}
|
||||
}
|
||||
return "OK";
|
||||
}
|
||||
|
||||
void appl::ClientInterface::start() {
|
||||
@ -73,6 +84,12 @@ void appl::ClientInterface::stop() {
|
||||
}
|
||||
|
||||
bool appl::ClientInterface::isAlive() {
|
||||
APPL_ERROR("check if alive");
|
||||
// kill interface in case of redirection
|
||||
if (m_interfaceRedirect == true) {
|
||||
APPL_ERROR(" ===> plop");
|
||||
return false;
|
||||
}
|
||||
//APPL_INFO("is alive : " << m_interfaceClient.isActive());
|
||||
bool ret = m_interfaceClient.isActive();
|
||||
if (ret == true) {
|
||||
@ -106,15 +123,15 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Message> _valu
|
||||
}
|
||||
// check correct SourceID
|
||||
if (_value->getSourceId() != m_uid) {
|
||||
answerProtocolError(transactionId, "message with the wrong source ID : " + etk::toString(_value->getSourceId()) + " != " + etk::toString(m_uid));
|
||||
answerProtocolError(transactionId, "message with the wrong source ID: " + etk::toString(_value->getSourceId()) + " != " + etk::toString(m_uid));
|
||||
return;
|
||||
}
|
||||
// Check gateway corectly connected
|
||||
if (m_userGateWay == nullptr) {
|
||||
answerProtocolError(transactionId, "GateWay error");
|
||||
answerProtocolError(transactionId, "GateWay error (not connected)");
|
||||
return;
|
||||
}
|
||||
// TODO: Special hook for the first call that we need to get the curretn ID of the connection, think to set this at an other position ...
|
||||
// TODO: Special hook for the first call that we need to get the current ID of the connection, think to set this at an other position ...
|
||||
if (m_uid == 0) {
|
||||
APPL_INFO("special case, we need to get the ID Of the client:");
|
||||
if (_value->getType() != zeus::message::type::call) {
|
||||
|
@ -17,7 +17,8 @@ namespace appl {
|
||||
private:
|
||||
appl::Router* m_routerInterface;
|
||||
zeus::WebServer m_interfaceClient;
|
||||
bool requestURI(const etk::String& _uri);
|
||||
bool m_interfaceRedirect = false;
|
||||
etk::String requestURI(const etk::String& _uri, const etk::Map<etk::String,etk::String>& _options);
|
||||
public:
|
||||
ememory::SharedPtr<appl::GateWayInterface> m_userGateWay;
|
||||
uint16_t m_uid; //!< gateway unique ID ==> to have an internal routage ...
|
||||
|
@ -17,6 +17,7 @@ static const etk::String protocolError = "PROTOCOL-ERROR";
|
||||
appl::GateWayInterface::GateWayInterface(enet::Tcp _connection, appl::Router* _routerInterface) :
|
||||
m_routerInterface(_routerInterface),
|
||||
m_interfaceClient(etk::move(_connection), true),
|
||||
m_openExternPort(0),
|
||||
m_lastSourceID(0x8000) {
|
||||
ZEUS_INFO("-----------------");
|
||||
ZEUS_INFO("-- NEW GateWay --");
|
||||
@ -34,31 +35,37 @@ appl::GateWayInterface::~GateWayInterface() {
|
||||
bool appl::GateWayInterface::isAlive() {
|
||||
return m_interfaceClient.isActive();
|
||||
}
|
||||
|
||||
bool appl::GateWayInterface::requestURI(const etk::String& _uri) {
|
||||
ZEUS_INFO("request connect on User - GateWay: '" << _uri << "'");
|
||||
etk::String appl::GateWayInterface::requestURI(const etk::String& _uri, const etk::Map<etk::String,etk::String>& _options) {
|
||||
ZEUS_INFO("request connect on User - GateWay: '" << _uri << "' from " << m_interfaceClient.getRemoteAddress());
|
||||
for (auto &it: _options) {
|
||||
ZEUS_INFO(" '" << it.first << "' = '" << it.second << "'");
|
||||
}
|
||||
if(m_routerInterface == nullptr) {
|
||||
ZEUS_ERROR("Can not access to the main GateWay interface (nullptr)");
|
||||
return false;
|
||||
return "CLOSE";
|
||||
}
|
||||
etk::String tmpURI = _uri;
|
||||
if (tmpURI.size() == 0) {
|
||||
ZEUS_ERROR("Empty URI ... not supported ...");
|
||||
return false;
|
||||
return "CLOSE";
|
||||
}
|
||||
if (tmpURI[0] == '/') {
|
||||
tmpURI = etk::String(tmpURI.begin() + 1, tmpURI.end());
|
||||
}
|
||||
// TODO : Remove subParameters xxx?YYY
|
||||
// check if the USER is already connected:
|
||||
bool tmp = m_routerInterface->userIsConnected(tmpURI);
|
||||
if (tmp == true) {
|
||||
ZEUS_ERROR("User is already connected ==> this is a big error ...");
|
||||
return false;
|
||||
return "CLOSE";
|
||||
}
|
||||
m_name = tmpURI;
|
||||
for (auto &it: _options) {
|
||||
if (it.first == "directAccessPort") {
|
||||
m_openExternPort = etk::string_to_uint16_t(it.second);
|
||||
}
|
||||
}
|
||||
ZEUS_WARNING("Connection of user : '" << tmpURI << "'");
|
||||
return true;
|
||||
return "OK";
|
||||
}
|
||||
|
||||
void appl::GateWayInterface::start() {
|
||||
@ -78,6 +85,10 @@ void appl::GateWayInterface::send(ememory::SharedPtr<zeus::Message> _data) {
|
||||
}
|
||||
|
||||
uint16_t appl::GateWayInterface::addClient(ememory::SharedPtr<appl::ClientInterface> _value) {
|
||||
if (_value == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
APPL_WARNING("Add client on GateWay " << _value->getId());
|
||||
m_clientConnected.pushBack(_value);
|
||||
return m_lastSourceID++;
|
||||
}
|
||||
@ -87,14 +98,22 @@ void appl::GateWayInterface::rmClient(ememory::SharedPtr<appl::ClientInterface>
|
||||
return;
|
||||
}
|
||||
uint16_t id = _value->getId();
|
||||
APPL_WARNING("RM client on GateWay : " << id);
|
||||
bool find = false;
|
||||
auto it = m_clientConnected.begin();
|
||||
while (it != m_clientConnected.end()) {
|
||||
if (*it == _value) {
|
||||
if (*it == nullptr) {
|
||||
it = m_clientConnected.erase(it);
|
||||
} else if (*it == _value) {
|
||||
it = m_clientConnected.erase(it);
|
||||
find = true;
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
if (find == false) {
|
||||
return;
|
||||
}
|
||||
m_interfaceClient.call(uint32_t(id)<<16, ZEUS_ID_GATEWAY, "removeRouterClient", id);
|
||||
}
|
||||
|
||||
@ -114,6 +133,7 @@ void appl::GateWayInterface::onServiceData(ememory::SharedPtr<zeus::Message> _va
|
||||
return;
|
||||
}
|
||||
m_name = callObj->getParameter<etk::String>(0);
|
||||
m_openExternPort = callObj->getParameter<uint16_t>(1);
|
||||
m_interfaceClient.setInterfaceName("srv-" + m_name);
|
||||
m_interfaceClient.answerValue(transactionId, _value->getDestination(), _value->getSource(), true);
|
||||
return;
|
||||
|
@ -15,10 +15,11 @@ namespace appl {
|
||||
private:
|
||||
appl::Router* m_routerInterface;
|
||||
zeus::WebServer m_interfaceClient;
|
||||
uint16_t m_openExternPort;
|
||||
uint16_t m_lastSourceID; //!< The source dynbamic generated ID is manage in 2 part the value <= 0x7FFF is used by the gateway and the value >= 0x8000 is manage by the router
|
||||
etk::Vector<ememory::SharedPtr<appl::ClientInterface>> m_clientConnected;
|
||||
etk::String m_name;
|
||||
bool requestURI(const etk::String& _uri);
|
||||
etk::String requestURI(const etk::String& _uri, const etk::Map<etk::String,etk::String>& _options);
|
||||
public:
|
||||
GateWayInterface(enet::Tcp _connection, appl::Router* _routerInterface);
|
||||
virtual ~GateWayInterface();
|
||||
@ -34,6 +35,13 @@ namespace appl {
|
||||
return m_name;
|
||||
}
|
||||
bool isAlive();
|
||||
/**
|
||||
* @brief Get the open port for external direct connection on the gateway
|
||||
* @return Port id or 0 if not open.
|
||||
*/
|
||||
uint16_t getOpenExternalPort() const {
|
||||
return m_openExternPort;
|
||||
}
|
||||
protected:
|
||||
void answerProtocolError(uint32_t _transactionId, const etk::String& _errorHelp);
|
||||
};
|
||||
|
@ -16,6 +16,7 @@ class UserAvaillable {
|
||||
etk::String m_name;
|
||||
etk::String m_basePath;
|
||||
bool m_accessMediaCenter;
|
||||
bool m_enableDirectAccess;
|
||||
FILE* m_subProcess;
|
||||
};
|
||||
etk::Vector<UserAvaillable> g_listUserAvaillable;
|
||||
@ -35,6 +36,7 @@ static void store_db() {
|
||||
propObject.add("name", ejson::String(it.m_name));
|
||||
propObject.add("path", ejson::String(it.m_basePath));
|
||||
propObject.add("access-media-center", ejson::Boolean(it.m_accessMediaCenter));
|
||||
propObject.add("access-direct", ejson::Boolean(it.m_enableDirectAccess));
|
||||
}
|
||||
bool retGenerate = database.storeSafe(g_pathDBName);
|
||||
APPL_ERROR("Store database [STOP] : " << g_pathDBName << " ret = " << retGenerate);
|
||||
@ -55,6 +57,7 @@ static void load_db() {
|
||||
userProperty.m_name = userElement["name"].toString().get();
|
||||
userProperty.m_basePath = userElement["path"].toString().get();
|
||||
userProperty.m_accessMediaCenter = userElement["access-media-center"].toBoolean().get();
|
||||
userProperty.m_enableDirectAccess = userElement["access-direct"].toBoolean().get();
|
||||
APPL_INFO("find USER: '" << userProperty.m_name << "'");
|
||||
g_listUserAvaillable.pushBack(userProperty);
|
||||
}
|
||||
@ -141,7 +144,9 @@ appl::Router::Router() :
|
||||
propertyGateWayIp(this, "gw-ip", "127.0.0.1", "Ip to listen Gateway", &appl::Router::onPropertyChangeGateWayIp),
|
||||
propertyGateWayPort(this, "gw-port", 1984, "Port to listen Gateway", &appl::Router::onPropertyChangeGateWayPort),
|
||||
propertyGateWayMax(this, "gw-max", 8000, "Maximum of Gateway at the same time", &appl::Router::onPropertyChangeGateWayMax),
|
||||
propertyDelayToStop(this, "delay-to-stop", 0, "Delay before the client stop the connection in second (default: 0=automatic set by the gateway; -1=never disconnect; other the time )") {
|
||||
propertyDelayToStop(this, "delay-to-stop", 0, "Delay before the client stop the connection in second (default: 0=automatic set by the gateway; -1=never disconnect; other the time )"),
|
||||
propertyGateWayDirectPortMin(this, "gw-direct-port-min", 12000, "Minimum of Gateway at the same time"),
|
||||
propertyGateWayDirectPortMax(this, "gw-direct-port-max", 13000, "Maximum of Gateway at the same time") {
|
||||
m_interfaceClientServer = ememory::makeShared<appl::TcpServerInput>(this, false);
|
||||
m_interfaceGateWayServer = ememory::makeShared<appl::TcpServerInput>(this, true);
|
||||
load_db();
|
||||
@ -234,9 +239,14 @@ ememory::SharedPtr<appl::GateWayInterface> appl::Router::get(const etk::String&
|
||||
//etk::String logFile = " ";
|
||||
APPL_INFO("New Child log in = " << logFile);
|
||||
}
|
||||
etk::String directAccess;
|
||||
if (it.m_enableDirectAccess == true) {
|
||||
directAccess = "--direct-ip=" + *propertyClientIp;
|
||||
directAccess += " --direct-port=" + etk::toString(*propertyGateWayDirectPortMin);
|
||||
}
|
||||
etk::String delay = "--router-delay=" + etk::toString(*propertyDelayToStop);
|
||||
//etk::String delay = "--router-delay=-1";
|
||||
APPL_INFO("execute: " << binary << " " << userConf << " --srv=all " << delay << " " << basePath << " " << logFile);
|
||||
APPL_INFO("execute: " << binary << " " << userConf << " --srv=all " << delay << " " << basePath << " " << logFile << " " << directAccess);
|
||||
int ret = execlp( binary.c_str(),
|
||||
binary.c_str(), // must repeate the binary name to have the name as first argument ...
|
||||
userConf.c_str(),
|
||||
@ -245,6 +255,7 @@ ememory::SharedPtr<appl::GateWayInterface> appl::Router::get(const etk::String&
|
||||
delay.c_str(),
|
||||
basePath.c_str(),
|
||||
logFile.c_str(),
|
||||
directAccess.c_str(),
|
||||
NULL);
|
||||
APPL_ERROR("Child Execution ret = " << ret);
|
||||
exit (-1);
|
||||
@ -307,7 +318,9 @@ void appl::Router::cleanIO() {
|
||||
if (*it2 != nullptr) {
|
||||
if ((*it2)->isAlive() == false) {
|
||||
(*it2)->stop();
|
||||
APPL_ERROR("count = " << (*it2).useCount() << " list.size()=" << m_clientList.size());
|
||||
it2 = m_clientList.erase(it2);
|
||||
APPL_ERROR(" list.size()=" << m_clientList.size());
|
||||
APPL_INFO("remove DONE ... ");
|
||||
continue;
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ namespace appl {
|
||||
etk::Vector<ememory::SharedPtr<appl::ClientInterface>> m_clientList; //!< List of all Client interface with their own connection
|
||||
ememory::SharedPtr<appl::TcpServerInput> m_interfaceClientServer;
|
||||
ememory::SharedPtr<appl::TcpServerInput> m_interfaceGateWayServer;
|
||||
ejson::Document m_listUser;
|
||||
public:
|
||||
eproperty::Value<bool> propertyStdOut; //!< not set the log in the stdout or in the local file
|
||||
eproperty::Value<etk::String> propertyClientIp;
|
||||
@ -29,6 +28,8 @@ namespace appl {
|
||||
eproperty::Value<uint16_t> propertyGateWayPort;
|
||||
eproperty::Value<uint16_t> propertyGateWayMax;
|
||||
eproperty::Value<int32_t> propertyDelayToStop;
|
||||
eproperty::Value<uint16_t> propertyGateWayDirectPortMin;
|
||||
eproperty::Value<uint16_t> propertyGateWayDirectPortMax;
|
||||
public:
|
||||
Router();
|
||||
virtual ~Router();
|
||||
|
@ -43,13 +43,13 @@ int main(int _argc, const char *_argv[]) {
|
||||
APPL_PRINT(etk::getApplicationName() << " - help : ");
|
||||
APPL_PRINT(" " << _argv[0] << " [options]");
|
||||
APPL_PRINT(" --stdout stdout log");
|
||||
APPL_PRINT(" --client-ip=XXX Client connection IP (default: 127.0.0.1)");
|
||||
APPL_PRINT(" --client-port=XXX Client connection PORT (default: 1983)");
|
||||
APPL_PRINT(" --client-max=XXX Client Maximum parallele connection (default: 80)");
|
||||
APPL_PRINT(" --gw-ip=XXX Gateway connection IP (default: 127.0.0.1)");
|
||||
APPL_PRINT(" --gw-port=XXX Gateway connection PORT (default: 1984)");
|
||||
APPL_PRINT(" --gw-max=XXX Gateway Maximum IO (default: 15)");
|
||||
APPL_PRINT(" --delay-stop-user=XXX Delay before the client stop the connection in second (default: 0=automatic set by the gateway; -1=never disconnect; other the time )");
|
||||
APPL_PRINT(" --client-ip=XXX Client connection IP (default: " << basicRouter.propertyClientIp.get() << ")");
|
||||
APPL_PRINT(" --client-port=XXX Client connection PORT (default: " << basicRouter.propertyClientPort.get() << ")");
|
||||
APPL_PRINT(" --client-max=XXX Client Maximum parallele connection (default: " << basicRouter.propertyClientMax.get() << ")");
|
||||
APPL_PRINT(" --gw-ip=XXX Gateway connection IP (default: " << basicRouter.propertyGateWayIp.get() << ")");
|
||||
APPL_PRINT(" --gw-port=XXX Gateway connection PORT (default: " << basicRouter.propertyGateWayPort.get() << ")");
|
||||
APPL_PRINT(" --gw-max=XXX Gateway Maximum IO (default: " << basicRouter.propertyGateWayMax.get() << ")");
|
||||
APPL_PRINT(" --delay-stop-user=XXX Delay before the client stop the connection in second (default: " << basicRouter.propertyDelayToStop.get() << "0=automatic set by the gateway; -1=never disconnect; other the time )");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user