using RS::REMOTE_SCRIPT;
+namespace {
+
+template<typename T>
+struct USER_IS
+{
+ USER_IS(USER_PTR u) : user(u) {}
+ bool operator()(const T & notifier) { return notifier.GetUser() == user; }
+
+ USER_PTR user;
+};
+
+} // namespace anonymous
+
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-RS::USER::USER(const std::vector<uint32_t> & r, USER_PTR it, REMOTE_SCRIPT & rs)
- : lastSentTime(0),
- user(it),
- routers(r),
- shortPacketsCount(0),
- ip(user->GetCurrIP()),
- notifier(rs, *this)
-{
- user->AddConnectedAfterNotifier(¬ifier);
-}
-//-----------------------------------------------------------------------------
-RS::USER::USER(const RS::USER & rhs)
- : lastSentTime(rhs.lastSentTime),
- user(rhs.user),
- routers(rhs.routers),
- shortPacketsCount(rhs.shortPacketsCount),
- ip(rhs.ip),
- notifier(rhs.notifier)
-{
- user->DelConnectedAfterNotifier(&rhs.notifier);
- user->AddConnectedAfterNotifier(¬ifier);
-}
-//-----------------------------------------------------------------------------
-RS::USER::~USER()
-{
- user->DelConnectedAfterNotifier(¬ifier);
-}
-//-----------------------------------------------------------------------------
RS::SETTINGS::SETTINGS()
: sendPeriod(0),
port(0),
REMOTE_SCRIPT::REMOTE_SCRIPT()
: ctx(),
ipNotifierList(),
+ connNotifierList(),
authorizedUsers(),
errorStr(),
rsSettings(),
{
if (difftime(stgTime, it->second.lastSentTime) - (rand() % halfPeriod) > sendPeriod)
{
- Send(it->first, it->second);
+ Send(it->second);
}
++it;
}
}
//-----------------------------------------------------------------------------
#ifdef NDEBUG
-bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t, uint32_t ip, RS::USER & rsu, bool forceDisconnect) const
+bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t, RS::USER & rsu, bool forceDisconnect) const
#else
-bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t bufSize, uint32_t ip, RS::USER & rsu, bool forceDisconnect) const
+bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t bufSize, RS::USER & rsu, bool forceDisconnect) const
#endif
{
RS::PACKET_HEADER packetHead;
if (forceDisconnect)
{
packetHead.packetType = RS_DISCONNECT_PACKET;
+ printfd(__FILE__, "RSCRIPT: force disconnect for '%s'\n", rsu.user->GetLogin().c_str());
}
else
{
{
//SendLong
packetHead.packetType = rsu.user->IsInetable() ? RS_CONNECT_PACKET : RS_DISCONNECT_PACKET;
+ if (rsu.user->IsInetable())
+ printfd(__FILE__, "RSCRIPT: connect for '%s'\n", rsu.user->GetLogin().c_str());
+ else
+ printfd(__FILE__, "RSCRIPT: disconnect for '%s'\n", rsu.user->GetLogin().c_str());
}
else
{
//SendShort
packetHead.packetType = rsu.user->IsInetable() ? RS_ALIVE_PACKET : RS_DISCONNECT_PACKET;
+ if (rsu.user->IsInetable())
+ printfd(__FILE__, "RSCRIPT: alive for '%s'\n", rsu.user->GetLogin().c_str());
+ else
+ printfd(__FILE__, "RSCRIPT: disconnect for '%s'\n", rsu.user->GetLogin().c_str());
}
}
rsu.shortPacketsCount++;
rsu.lastSentTime = stgTime;
-packetHead.ip = htonl(ip);
+packetHead.ip = htonl(rsu.ip);
packetHead.id = htonl(rsu.user->GetID());
strncpy((char*)packetHead.login, rsu.user->GetLogin().c_str(), RS_LOGIN_LEN);
packetHead.login[RS_LOGIN_LEN - 1] = 0;
return false;
}
//-----------------------------------------------------------------------------
-bool REMOTE_SCRIPT::Send(uint32_t ip, RS::USER & rsu, bool forceDisconnect) const
+bool REMOTE_SCRIPT::Send(RS::USER & rsu, bool forceDisconnect) const
{
char buffer[RS_MAX_PACKET_LEN];
memset(buffer, 0, sizeof(buffer));
-if (PreparePacket(buffer, sizeof(buffer), ip, rsu, forceDisconnect))
+if (PreparePacket(buffer, sizeof(buffer), rsu, forceDisconnect))
{
printfd(__FILE__, "REMOTE_SCRIPT::Send() - Invalid packet length!\n");
return true;
return false;
}
//-----------------------------------------------------------------------------
-bool REMOTE_SCRIPT::SendDirect(uint32_t ip, RS::USER & rsu, uint32_t routerIP, bool forceDisconnect) const
+bool REMOTE_SCRIPT::SendDirect(RS::USER & rsu, uint32_t routerIP, bool forceDisconnect) const
{
char buffer[RS_MAX_PACKET_LEN];
-if (PreparePacket(buffer, sizeof(buffer), ip, rsu, forceDisconnect))
+if (PreparePacket(buffer, sizeof(buffer), rsu, forceDisconnect))
{
printfd(__FILE__, "REMOTE_SCRIPT::SendDirect() - Invalid packet length!\n");
return true;
while (!users->SearchNext(h, &u))
{
- SetUserNotifier(u);
+ SetUserNotifiers(u);
}
users->CloseSearch(h);
*/
if (newIP)
{
- RS::USER rsu(IP2Routers(newIP), u, *this);
- Send(newIP, rsu);
+ RS::USER rsu(IP2Routers(newIP), u);
+ Send(rsu);
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
authorizedUsers.insert(std::make_pair(newIP, rsu));
);
if (it != authorizedUsers.end())
{
- Send(oldIP, it->second, true);
+ Send(it->second, true);
authorizedUsers.erase(it);
}
}
return value;
}
//-----------------------------------------------------------------------------
-void REMOTE_SCRIPT::SetUserNotifier(USER_PTR u)
+void REMOTE_SCRIPT::SetUserNotifiers(USER_PTR u)
{
ipNotifierList.push_front(RS::IP_NOTIFIER(*this, u));
-
-u->AddCurrIPAfterNotifier(&(*ipNotifierList.begin()));
+connNotifierList.push_front(RS::CONNECTED_NOTIFIER(*this, u));
}
//-----------------------------------------------------------------------------
-void REMOTE_SCRIPT::UnSetUserNotifier(USER_PTR u)
+void REMOTE_SCRIPT::UnSetUserNotifiers(USER_PTR u)
{
-list<RS::IP_NOTIFIER>::iterator ipAIter;
-std::list<list<RS::IP_NOTIFIER>::iterator> toErase;
+ipNotifierList.erase(std::remove_if(ipNotifierList.begin(),
+ ipNotifierList.end(),
+ USER_IS<IP_NOTIFIER>(u)),
+ ipNotifierList.end());
+connNotifierList.erase(std::remove_if(connNotifierList.begin(),
+ connNotifierList.end(),
+ USER_IS<CONNECTED_NOTIFIER>(u)),
+ connNotifierList.end());
-for (ipAIter = ipNotifierList.begin(); ipAIter != ipNotifierList.end(); ++ipAIter)
- {
- if (ipAIter->GetUser() == u)
- {
- u->DelCurrIPAfterNotifier(&(*ipAIter));
- toErase.push_back(ipAIter);
- }
- }
-
-std::list<list<RS::IP_NOTIFIER>::iterator>::iterator eIter;
+}
+//-----------------------------------------------------------------------------
+void REMOTE_SCRIPT::AddRSU(USER_PTR user)
+{
+RS::USER rsu(IP2Routers(user->GetCurrIP()), user);
+Send(rsu);
-for (eIter = toErase.begin(); eIter != toErase.end(); ++eIter)
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+authorizedUsers.insert(std::make_pair(user->GetCurrIP(), rsu));
+}
+//-----------------------------------------------------------------------------
+void REMOTE_SCRIPT::DelRSU(USER_PTR user)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+const map<uint32_t, RS::USER>::iterator it(
+ authorizedUsers.find(user->GetCurrIP())
+ );
+if (it != authorizedUsers.end())
{
- ipNotifierList.erase(*eIter);
+ Send(it->second, true);
+ authorizedUsers.erase(it);
}
}
//-----------------------------------------------------------------------------
-void RS::IP_NOTIFIER::Notify(const uint32_t & oldValue, const uint32_t & newValue)
+void RS::IP_NOTIFIER::Notify(const uint32_t & /*oldValue*/, const uint32_t & newValue)
{
-rs.ChangedIP(user, oldValue, newValue);
+//rs.ChangedIP(user, oldValue, newValue);
+if (newValue)
+ rs.AddRSU(user);
+else
+ rs.DelRSU(user);
}
//-----------------------------------------------------------------------------
void RS::CONNECTED_NOTIFIER::Notify(const bool & /*oldValue*/, const bool & newValue)
{
-if (!newValue)
- rs.Send(user.ip, user, true);
+if (newValue)
+ rs.AddRSU(user);
+else
+ rs.DelRSU(user);
}
//-----------------------------------------------------------------------------
void REMOTE_SCRIPT::InitEncrypt(BLOWFISH_CTX * ctx, const string & password) const
class IP_NOTIFIER: public PROPERTY_NOTIFIER_BASE<uint32_t> {
public:
IP_NOTIFIER(REMOTE_SCRIPT & r, USER_PTR u)
- : PROPERTY_NOTIFIER_BASE<uint32_t>(), user(u), rs(r) {}
+ : PROPERTY_NOTIFIER_BASE<uint32_t>(), user(u), rs(r) { user->AddCurrIPAfterNotifier(this); }
IP_NOTIFIER(const IP_NOTIFIER & rhs)
- : PROPERTY_NOTIFIER_BASE<uint32_t>(), user(rhs.user), rs(rhs.rs) {}
+ : PROPERTY_NOTIFIER_BASE<uint32_t>(), user(rhs.user), rs(rhs.rs) { user->AddCurrIPAfterNotifier(this); }
+ ~IP_NOTIFIER() { user->DelCurrIPAfterNotifier(this); }
+
+ IP_NOTIFIER & operator=(const IP_NOTIFIER & rhs)
+ {
+ user->DelCurrIPAfterNotifier(this);
+ user = rhs.user;
+ user->AddCurrIPAfterNotifier(this);
+ return *this;
+ }
+
void Notify(const uint32_t & oldValue, const uint32_t & newValue);
- USER_PTR GetUser() { return user; }
+ USER_PTR GetUser() const { return user; }
private:
- IP_NOTIFIER & operator=(const IP_NOTIFIER & rhs);
USER_PTR user;
REMOTE_SCRIPT & rs;
};
//-----------------------------------------------------------------------------
-class USER;
-//-----------------------------------------------------------------------------
class CONNECTED_NOTIFIER: public PROPERTY_NOTIFIER_BASE<bool> {
public:
- CONNECTED_NOTIFIER(REMOTE_SCRIPT & r, USER & u)
- : PROPERTY_NOTIFIER_BASE<bool>(), user(u), rs(r) {}
+ CONNECTED_NOTIFIER(REMOTE_SCRIPT & r, USER_PTR u)
+ : PROPERTY_NOTIFIER_BASE<bool>(), user(u), rs(r) { user->AddConnectedAfterNotifier(this); }
CONNECTED_NOTIFIER(const CONNECTED_NOTIFIER & rhs)
- : PROPERTY_NOTIFIER_BASE<bool>(), user(rhs.user), rs(rhs.rs) {}
+ : PROPERTY_NOTIFIER_BASE<bool>(), user(rhs.user), rs(rhs.rs) { user->AddConnectedAfterNotifier(this); }
+ ~CONNECTED_NOTIFIER() { user->DelConnectedAfterNotifier(this); }
+
+ CONNECTED_NOTIFIER & operator=(const CONNECTED_NOTIFIER & rhs)
+ {
+ user->DelConnectedAfterNotifier(this);
+ user = rhs.user;
+ user->AddConnectedAfterNotifier(this);
+ return *this;
+ }
+
void Notify(const bool & oldValue, const bool & newValue);
+ USER_PTR GetUser() const { return user; }
private:
- CONNECTED_NOTIFIER & operator=(const CONNECTED_NOTIFIER & rhs);
- USER & user;
+ USER_PTR user;
REMOTE_SCRIPT & rs;
};
//-----------------------------------------------------------------------------
struct USER {
- USER(const std::vector<uint32_t> & r, USER_PTR it, REMOTE_SCRIPT & rs);
- USER(const USER & rhs);
- ~USER();
+ USER(const std::vector<uint32_t> & r, USER_PTR it)
+ : user(it),
+ routers(r),
+ ip(user->GetCurrIP())
+ {}
time_t lastSentTime;
USER_PTR user;
std::vector<uint32_t> routers;
int shortPacketsCount;
uint32_t ip;
- CONNECTED_NOTIFIER notifier;
};
//-----------------------------------------------------------------------------
class SETTINGS {
uint16_t GetStartPosition() const { return 10; }
uint16_t GetStopPosition() const { return 10; }
- void DelUser(USER_PTR u) { UnSetUserNotifier(u); }
- void AddUser(USER_PTR u) { SetUserNotifier(u); }
+ void DelUser(USER_PTR u) { UnSetUserNotifiers(u); }
+ void AddUser(USER_PTR u) { SetUserNotifiers(u); }
void ChangedIP(USER_PTR u, uint32_t oldIP, uint32_t newIP);
+ void AddRSU(USER_PTR user);
+ void DelRSU(USER_PTR user);
private:
REMOTE_SCRIPT(const REMOTE_SCRIPT & rhs);
bool PrepareNet();
bool FinalizeNet();
- bool Send(uint32_t ip, USER & rsu, bool forceDisconnect = false) const;
- bool SendDirect(uint32_t ip, USER & rsu, uint32_t routerIP, bool forceDisconnect = false) const;
- bool PreparePacket(char * buf, size_t bufSize, uint32_t ip, USER &rsu, bool forceDisconnect = false) const;
+ bool Send(USER & rsu, bool forceDisconnect = false) const;
+ bool SendDirect(USER & rsu, uint32_t routerIP, bool forceDisconnect = false) const;
+ bool PreparePacket(char * buf, size_t bufSize, USER &rsu, bool forceDisconnect = false) const;
void PeriodicSend();
std::vector<uint32_t> IP2Routers(uint32_t ip);
bool GetUsers();
std::string GetUserParam(USER_PTR u, const std::string & paramName) const;
- void SetUserNotifier(USER_PTR u);
- void UnSetUserNotifier(USER_PTR u);
+ void SetUserNotifiers(USER_PTR u);
+ void UnSetUserNotifiers(USER_PTR u);
void InitEncrypt(BLOWFISH_CTX * ctx, const string & password) const;
void Encrypt(BLOWFISH_CTX * ctx, char * dst, const char * src, size_t len8) const;
mutable BLOWFISH_CTX ctx;
std::list<IP_NOTIFIER> ipNotifierList;
+ std::list<CONNECTED_NOTIFIER> connNotifierList;
std::map<uint32_t, USER> authorizedUsers;
mutable std::string errorStr;
DisconnectUser(REMOTE_SCRIPT & rs) : rscript(rs) {}
void operator()(std::pair<const uint32_t, USER> & p)
{
- rscript.Send(p.first, p.second, true);
+ rscript.Send(p.second, true);
}
private:
REMOTE_SCRIPT & rscript;