if (!m_running)
break;
if (res > 0)
- {
- printfd(__FILE__, "Something happend - received %d events.\n", res);
HandleEvents(fds);
- }
CleanupConns();
}
void CONFIGPROTO::BuildFDSet(fd_set & fds) const
{
- printfd(__FILE__, "Building fd set for %d connections.\n", m_conns.size());
FD_ZERO(&fds);
FD_SET(m_listenSocket, &fds);
std::deque<STG::Conn *>::const_iterator it;
void CONFIGPROTO::CleanupConns()
{
- size_t old = m_conns.size();
-
std::deque<STG::Conn *>::iterator pos;
for (pos = m_conns.begin(); pos != m_conns.end(); ++pos)
if (((*pos)->IsDone() && !(*pos)->IsKeepAlive()) || !(*pos)->IsOk())
pos = std::remove(m_conns.begin(), m_conns.end(), static_cast<STG::Conn *>(NULL));
m_conns.erase(pos, m_conns.end());
-
- if (m_conns.size() < old)
- printfd(__FILE__, "Cleaned up %d connections.\n", old - m_conns.size());
}
void CONFIGPROTO::HandleEvents(const fd_set & fds)
std::deque<STG::Conn *>::iterator it;
for (it = m_conns.begin(); it != m_conns.end(); ++it)
if (FD_ISSET((*it)->Sock(), &fds))
- {
- printfd(__FILE__, "Reading data from %s:%d.\n", inet_ntostring((*it)->IP()).c_str(), (*it)->Port());
(*it)->Read();
- }
}
}
void CONFIGPROTO::AcceptConnection()
{
- printfd(__FILE__, "Accepting new connection.\n");
-
struct sockaddr_in outerAddr;
socklen_t outerAddrLen(sizeof(outerAddr));
int sock = accept(m_listenSocket, reinterpret_cast<sockaddr *>(&outerAddr), &outerAddrLen);
try
{
- m_conns.push_back(new STG::Conn(m_registry, *m_admins, sock, outerAddr));
+ m_conns.push_back(new STG::Conn(m_registry, *m_admins, sock, outerAddr, m_logger));
printfd(__FILE__, "New connection from %s:%d. Total connections: %d\n", inet_ntostring(m_conns.back()->IP()).c_str(), m_conns.back()->Port(), m_conns.size());
}
catch (const STG::Conn::Error & error)
m_logger(std::string("Failed to create new client connection: '") + error.what() + "'.");
}
}
-/*
-void CONFIGPROTO::WriteLogAccessFailed(uint32_t ip)
-{
- m_logger("Admin's connection failed. IP %s", inet_ntostring(ip).c_str());
-}
-*/
#include "stg/admins.h"
#include "stg/admin.h"
+#include "stg/logger.h"
#include "stg/blowfish.h"
#include "stg/bfstream.h"
#include "stg/common.h"
const char Conn::ERR_LOGINS[] = "ERLS";
Conn::Conn(const BASE_PARSER::REGISTRY & registry,
- ADMINS & admins, int sock, const sockaddr_in& addr)
+ ADMINS & admins, int sock, const sockaddr_in& addr,
+ PLUGIN_LOGGER & logger)
: m_registry(registry),
m_admins(admins),
m_admin(NULL),
m_buffer(m_header),
m_bufferSize(sizeof(m_header)),
m_stream(NULL),
+ m_logger(logger),
m_dataState(false, *this)
{
if (m_xmlParser == NULL)
ssize_t res = read(m_sock, m_buffer, m_bufferSize);
if (res < 0)
{
- printfd(__FILE__, "Failed to read data from %s:%d: '%s'.\n", inet_ntostring(IP()).c_str(), Port(), strerror(errno));
m_state = ERROR;
- // TODO: log it
+ Log(__FILE__, "Failed to read data from " + inet_ntostring(IP()) + ":" + x2str(Port()) + ". Reason: '" + strerror(errno) + "'");
return false;
}
if (res == 0 && m_state != DATA) // EOF is ok for data.
{
- printfd(__FILE__, "Failed to read data from %s:%d: 'EOF'.\n", inet_ntostring(IP()).c_str(), Port());
m_state = ERROR;
- // TODO: log it
+ Log(__FILE__, "Failed to read data from " + inet_ntostring(IP()) + ":" + x2str(Port()) + ". Unexpected EOF.");
return false;
}
m_bufferSize -= res;
ssize_t res = write(m_sock, buffer, size);
if (res < 0)
{
- // TODO: log it
+ m_state = ERROR;
+ Log(__FILE__, "Failed to write data to " + inet_ntostring(IP()) + ":" + x2str(Port()) + ". Reason: '" + strerror(errno) + "'.");
return false;
}
return true;
BASE_PARSER * Conn::GetParser(const std::string & tag) const
{
- BASE_PARSER::REGISTRY::const_iterator it = m_registry.find(tag);
+ BASE_PARSER::REGISTRY::const_iterator it = m_registry.find(ToLower(tag));
if (it == m_registry.end())
return NULL;
return it->second->create(*m_admin);
bool Conn::HandleBuffer(size_t size)
{
- printfd(__FILE__, "Got %d bytes. State: %s.\n", size, (m_state == DATA ? "DATA" : (m_state == HEADER ? "HEADER" : (m_state == LOGIN ? "LOGIN" : (m_state == CRYPTO_LOGIN ? "CRYPTO_LOGIN" : (m_state == DONE ? "DONE" : "ERROR"))))));
if (m_state == DATA)
return HandleData(size);
{
if (strncmp(m_header, STG_HEADER, sizeof(m_header)) != 0)
{
- printfd(__FILE__, "Wrong header from %s:%d.\n", inet_ntostring(IP()).c_str(), Port());
+ Log(__FILE__, "Received invalid header from " + inet_ntostring(IP()) + ":" + x2str(Port()) + ".");
WriteAnswer(ERR_HEADER, sizeof(ERR_HEADER) - 1); // Without \0
- // TODO: log it
m_state = ERROR;
return false;
}
{
if (m_admins.Find(m_login, &m_admin)) // ADMINS::Find returns true on error.
{
- printfd(__FILE__, "Wrong login ('%s') from %s:%d.\n", m_login, inet_ntostring(IP()).c_str(), Port());
+ std::string login(m_login, strnlen(m_login, sizeof(m_login)));
+ Log(__FILE__, "Received invalid login '" + ToPrintable(login) + "' from " + inet_ntostring(IP()) + ":" + x2str(Port()) + ".");
WriteAnswer(ERR_LOGIN, sizeof(ERR_LOGIN) - 1); // Without \0
- // TODO: log it
m_state = ERROR;
return false;
}
if (strncmp(m_login, login, sizeof(login)) != 0)
{
- printfd(__FILE__, "Wrong password from %s:%d: '%s' != '%s'.\n", inet_ntostring(IP()).c_str(), Port(), login, m_login);
+ Log(__FILE__, "Attempt to connect with wrong password from " + m_admin->GetLogin() + "@" + inet_ntostring(IP()) + ":" + x2str(Port()) + ".");
WriteAnswer(ERR_LOGINS, sizeof(ERR_LOGINS) - 1); // Without \0
- // TODO: log it
m_state = ERROR;
return false;
}
if (XML_Parse(state.conn.m_xmlParser, xml, length, state.final) == XML_STATUS_ERROR)
{
- // TODO: log it
+ state.conn.Log(__FILE__, "Received invalid XML from " + state.conn.m_admin->GetLogin() + "@" + inet_ntostring(state.conn.IP()) + ":" + x2str(state.conn.Port()) + ".");
printfd(__FILE__, "XML parse error at line %d, %d: %s. Is final: %d\n",
static_cast<int>(XML_GetCurrentLineNumber(state.conn.m_xmlParser)),
static_cast<int>(XML_GetCurrentColumnNumber(state.conn.m_xmlParser)),
{
if (!state.conn.WriteResponse())
{
- // TODO: log it
+ state.conn.Log(__FILE__, "Failed to write response to " + state.conn.m_admin->GetLogin() + "@" + inet_ntostring(state.conn.IP()) + ":" + x2str(state.conn.Port()) + ".");
state.conn.m_state = ERROR;
return false;
}
if (conn.m_parser == NULL)
{
- printfd(__FILE__, "Failed to find a suitable parser for '%s'.\n", el);
- // TODO: log it
+ conn.Log(__FILE__, "Received unknown command '" + std::string(el) + "' from " + conn.m_admin->GetLogin() + "@" + inet_ntostring(conn.IP()) + ":" + x2str(conn.Port()) + ".");
conn.m_state = ERROR;
return;
}
- else
- printfd(__FILE__, "Using parser '%s'.\n", conn.m_parser->GetTag().c_str());
conn.m_parser->Start(data, el, attr);
}
if (conn.m_parser == NULL)
{
- // TODO: log it
+ // No need to log it.
conn.m_state = ERROR;
return;
}
answer = m_parser->GetAnswer();
else
answer = "<Error result=\"Unknown command.\"/>";
- printfd(__FILE__, "Writing %d bytes of answer: '%s'\n", answer.length(), answer.c_str());
+ printfd(__FILE__, "Writing %d bytes of answer.\n", answer.length());
stream.Put(answer.c_str(), answer.length() + 1 /* including \0 */, true /* final */);
return stream.IsOk();
}
Conn & conn = *static_cast<Conn *>(data);
return WriteAll(conn.m_sock, block, size);;
}
+
+void Conn::Log(const char * file, const std::string & message)
+{
+ printfd(file, "%s\n", message.c_str());
+ m_logger(message);
+}
class TARIFFS;
class ADMIN;
class BASE_PARSER;
+class PLUGIN_LOGGER;
namespace STG
{
};
Conn(const BASE_PARSER::REGISTRY & registry,
- ADMINS & admins, int sock, const sockaddr_in& addr);
+ ADMINS & admins, int sock, const sockaddr_in& addr,
+ PLUGIN_LOGGER & logger);
~Conn();
int Sock() const { return m_sock; }
char m_cryptoLogin[ADM_LOGIN_LEN]; // Without \0
char m_data[1024];
STG::DECRYPT_STREAM * m_stream;
+ PLUGIN_LOGGER & m_logger;
BASE_PARSER * GetParser(const std::string & tag) const;
bool WriteAnswer(const void* buffer, size_t size);
bool WriteResponse();
+ void Log(const char * file, const std::string & message);
+
struct DataState
{
DataState(bool f, Conn & c) : final(f), conn(c) {}
#include "parser_admins.h"
#include "stg/admins.h"
-#include "stg/common.h"
#include <strings.h> // strcasecmp
#include "parser.h"
+#include "stg/common.h"
#include "stg/resetable.h"
#include <string>
FACTORY(const ADMINS & admins) : m_admins(admins) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new GET_ADMINS(admin, m_admins); }
static void Register(REGISTRY & registry, const ADMINS & admins)
- { registry[tag] = new FACTORY(admins); }
+ { registry[ToLower(tag)] = new FACTORY(admins); }
private:
const ADMINS & m_admins;
};
FACTORY(ADMINS & admins) : m_admins(admins) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new ADD_ADMIN(admin, m_admins); }
static void Register(REGISTRY & registry, ADMINS & admins)
- { registry[tag] = new FACTORY(admins); }
+ { registry[ToLower(tag)] = new FACTORY(admins); }
private:
ADMINS & m_admins;
};
FACTORY(ADMINS & admins) : m_admins(admins) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new DEL_ADMIN(admin, m_admins); }
static void Register(REGISTRY & registry, ADMINS & admins)
- { registry[tag] = new FACTORY(admins); }
+ { registry[ToLower(tag)] = new FACTORY(admins); }
private:
ADMINS & m_admins;
};
FACTORY(ADMINS & admins) : m_admins(admins) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new CHG_ADMIN(admin, m_admins); }
static void Register(REGISTRY & registry, ADMINS & admins)
- { registry[tag] = new FACTORY(admins); }
+ { registry[ToLower(tag)] = new FACTORY(admins); }
private:
ADMINS & m_admins;
};
#include "parser.h"
+#include "stg/common.h"
+
#include <string>
class ADMIN;
FACTORY(const USERS & users) : m_users(users) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new AUTH_BY(admin, m_users); }
static void Register(REGISTRY & registry, const USERS & users)
- { registry[tag] = new FACTORY(users); }
+ { registry[ToLower(tag)] = new FACTORY(users); }
private:
const USERS & m_users;
};
#include "parser_message.h"
#include "stg/users.h"
-#include "stg/common.h"
extern volatile time_t stgTime; // So sad...
#include "parser.h"
#include "stg/message.h"
+#include "stg/common.h"
#include <vector>
#include <string>
FACTORY(USERS & users) : m_users(users) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new SEND_MESSAGE(admin, m_users); }
static void Register(REGISTRY & registry, USERS & users)
- { registry[tag] = new FACTORY(users); }
+ { registry[ToLower(tag)] = new FACTORY(users); }
private:
USERS & m_users;
};
#include "stg/settings.h"
#include "stg/users.h"
#include "stg/tariffs.h"
-#include "stg/common.h"
#include "stg/version.h"
#include "stg/const.h"
#include "parser.h"
+#include "stg/common.h"
+
class ADMIN;
class SETTINGS;
class USERS;
: m_settings(settings), m_users(users), m_tariffs(tariffs) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new GET_SERVER_INFO(admin, m_settings, m_users, m_tariffs); }
static void Register(REGISTRY & registry, const SETTINGS & settings, const USERS & users, const TARIFFS & tariffs)
- { registry[tag] = new FACTORY(settings, users, tariffs); }
+ { registry[ToLower(tag)] = new FACTORY(settings, users, tariffs); }
private:
const SETTINGS & m_settings;
const USERS & m_users;
#include "stg/tariffs.h"
#include "stg/users.h"
-#include "stg/common.h"
#include "stg/resetable.h"
#include <cstdio> // snprintf
#include "parser.h"
#include "stg/tariff_conf.h"
+#include "stg/common.h"
#include <string>
FACTORY(const TARIFFS & tariffs) : m_tariffs(tariffs) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new GET_TARIFFS(admin, m_tariffs); }
static void Register(REGISTRY & registry, const TARIFFS & tariffs)
- { registry[tag] = new FACTORY(tariffs); }
+ { registry[ToLower(tag)] = new FACTORY(tariffs); }
private:
const TARIFFS & m_tariffs;
};
FACTORY(TARIFFS & tariffs) : m_tariffs(tariffs) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new ADD_TARIFF(admin, m_tariffs); }
static void Register(REGISTRY & registry, TARIFFS & tariffs)
- { registry[tag] = new FACTORY(tariffs); }
+ { registry[ToLower(tag)] = new FACTORY(tariffs); }
private:
TARIFFS & m_tariffs;
};
FACTORY(TARIFFS & tariffs, const USERS & users) : m_tariffs(tariffs), m_users(users) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new DEL_TARIFF(admin, m_users, m_tariffs); }
static void Register(REGISTRY & registry, TARIFFS & tariffs, const USERS & users)
- { registry[tag] = new FACTORY(tariffs, users); }
+ { registry[ToLower(tag)] = new FACTORY(tariffs, users); }
private:
TARIFFS & m_tariffs;
const USERS & m_users;
FACTORY(TARIFFS & tariffs) : m_tariffs(tariffs) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new CHG_TARIFF(admin, m_tariffs); }
static void Register(REGISTRY & registry, TARIFFS & tariffs)
- { registry[tag] = new FACTORY(tariffs); }
+ { registry[ToLower(tag)] = new FACTORY(tariffs); }
private:
TARIFFS & m_tariffs;
};
#include "stg/user_property.h"
#include "stg/user_conf.h"
#include "stg/user_stat.h"
-#include "stg/common.h"
#include <cstdio>
#include <cassert>
#include "stg/user_conf.h"
#include "stg/user_stat.h"
+#include "stg/common.h"
#include "stg/resetable.h"
#include <string>
FACTORY(USERS & users) : m_users(users) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new GET_USERS(admin, m_users); }
static void Register(REGISTRY & registry, USERS & users)
- { registry[tag] = new FACTORY(users); }
+ { registry[ToLower(tag)] = new FACTORY(users); }
private:
USERS & m_users;
};
FACTORY(const USERS & users) : m_users(users) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new GET_USER(admin, m_users); }
static void Register(REGISTRY & registry, const USERS & users)
- { registry[tag] = new FACTORY(users); }
+ { registry[ToLower(tag)] = new FACTORY(users); }
private:
const USERS & m_users;
};
FACTORY(USERS & users) : m_users(users) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new ADD_USER(admin, m_users); }
static void Register(REGISTRY & registry, USERS & users)
- { registry[tag] = new FACTORY(users); }
+ { registry[ToLower(tag)] = new FACTORY(users); }
private:
USERS & m_users;
};
{}
virtual BASE_PARSER * create(const ADMIN & admin) { return new CHG_USER(admin, m_users, m_store, m_tariffs); }
static void Register(REGISTRY & registry, USERS & users, STORE & store, const TARIFFS & tariffs)
- { registry[tag] = new FACTORY(users, store, tariffs); }
+ { registry[ToLower(tag)] = new FACTORY(users, store, tariffs); }
private:
USERS & m_users;
STORE & m_store;
FACTORY(USERS & users) : m_users(users) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new DEL_USER(admin, m_users); }
static void Register(REGISTRY & registry, USERS & users)
- { registry[tag] = new FACTORY(users); }
+ { registry[ToLower(tag)] = new FACTORY(users); }
private:
USERS & m_users;
};
FACTORY(const USERS & users) : m_users(users) {}
virtual BASE_PARSER * create(const ADMIN & admin) { return new CHECK_USER(admin, m_users); }
static void Register(REGISTRY & registry, const USERS & users)
- { registry[tag] = new FACTORY(users); }
+ { registry[ToLower(tag)] = new FACTORY(users); }
private:
const USERS & m_users;
};
}
return true;
}
+
+std::string ToPrintable(const std::string & src)
+{
+ std::string dest;
+
+ for (size_t i = 0; i < src.size(); ++i)
+ if (std::isprint(src[i]))
+ dest += src[i];
+ else
+ dest += "\\" + x2str(src[i]);
+
+ return dest;
+}
bool ReadAll(int sd, void * dest, size_t size);
bool WriteAll(int sd, const void * source, size_t size);
+std::string ToPrintable(const std::string & src);
+
//-----------------------------------------------------------------------------
int str2x(const std::string & str, int32_t & x);
int str2x(const std::string & str, uint32_t & x);