Commit 08025096 authored by Romain Bignon's avatar Romain Bignon

implemented the PING/PONG mechanism

parent a94e7c2d
......@@ -14,6 +14,8 @@ irc {
# 1: daemon
# 2: daemon fork
type = 0
ping = 60
}
# Log function
......
......@@ -53,6 +53,7 @@ Bitlbee::Bitlbee()
section->AddItem(new ConfigItem_string("hostname", "Server hostname", " "));
section->AddItem(new ConfigItem_string("command_chan", "Command channel name", "&bitlbee"));
section->AddItem(new ConfigItem_int("type", "Type of daemon", 0, 2, "0"));
section->AddItem(new ConfigItem_int("ping", "Ping frequence (s)", 1, 65535, "60"));
section = conf.AddSection("logging", "Log informations", false);
section->AddItem(new ConfigItem_string("level", "Logging level"));
......
......@@ -41,6 +41,5 @@ gboolean g_callback(void* data)
return FALSE;
}
cb->run();
return FALSE;
return cb->run();
}
......@@ -24,7 +24,7 @@ class _CallBack
{
public:
virtual ~_CallBack() {}
virtual void run() = 0;
virtual bool run() = 0;
};
template<typename T>
......@@ -32,13 +32,13 @@ class CallBack : public _CallBack
{
public:
typedef void (T::*TFunc) (void*);
typedef bool (T::*TFunc) (void*);
CallBack(T* _obj, TFunc _func, void* _data = 0) : obj(_obj), func(_func), data(_data) {}
virtual void run()
virtual bool run()
{
(obj->*func) (data);
return (obj->*func) (data);
}
private:
......
......@@ -37,17 +37,20 @@ static struct
void (IRC::*func)(Message);
size_t minargs;
} commands[] = {
{ "NICK", &IRC::m_nick, 0 },
{ "USER", &IRC::m_user, 4 },
{ "QUIT", &IRC::m_quit, 0 },
{ "PRIVMSG", &IRC::m_privmsg, 2 },
{ MSG_NICK, &IRC::m_nick, 0 },
{ MSG_USER, &IRC::m_user, 4 },
{ MSG_QUIT, &IRC::m_quit, 0 },
{ MSG_PRIVMSG, &IRC::m_privmsg, 2 },
{ MSG_PING, &IRC::m_ping, 0 },
{ MSG_PONG, &IRC::m_pong, 1 },
};
IRC::IRC(ServerPoll* _poll, int _fd, string _hostname, string cmd_chan_name)
IRC::IRC(ServerPoll* _poll, int _fd, string _hostname, string cmd_chan_name, unsigned ping_freq)
: poll(_poll),
fd(_fd),
read_id(0),
read_cb(NULL),
ping_cb(NULL),
hostname("localhost.localdomain"),
user(NULL),
rootNick(NULL),
......@@ -108,6 +111,10 @@ IRC::IRC(ServerPoll* _poll, int _fd, string _hostname, string cmd_chan_name)
addChannel(cmdChan);
rootNick->join(cmdChan, ChanUser::OP);
/* Ping callback */
ping_cb = new CallBack<IRC>(this, &IRC::ping);
g_timeout_add_seconds(ping_freq, g_callback, ping_cb);
user->send(Message(MSG_NOTICE).setSender(this).setReceiver("AUTH").addArg("BitlBee-IRCd initialized, please go on"));
}
......@@ -125,6 +132,7 @@ void IRC::addChannel(Channel* chan)
{
channels[chan->getName()] = chan;
}
Channel* IRC::getChannel(string channame) const
{
map<string, Channel*>::const_iterator it = channels.find(channame);
......@@ -133,6 +141,7 @@ Channel* IRC::getChannel(string channame) const
return it->second;
}
void IRC::removeChannel(string channame)
{
map<string, Channel*>::iterator it = channels.find(channame);
......@@ -156,6 +165,7 @@ Nick* IRC::getNick(string nickname) const
return it->second;
}
void IRC::removeNick(string nickname)
{
map<string, Nick*>::iterator it = users.find(nickname);
......@@ -188,7 +198,22 @@ void IRC::sendWelcome()
rootNick->privmsg(cmdChan, "Welcome to Bitlbee, dear!");
}
void IRC::readIO(void*)
bool IRC::ping(void*)
{
if(!user->hasFlag(Nick::REGISTERED) || user->hasFlag(Nick::PING))
{
quit("Ping timeout");
return false;
}
else
{
user->setFlag(Nick::PING);
user->send(Message(MSG_PING).addArg(hostname));
return true;
}
}
bool IRC::readIO(void*)
{
static char buf[1024];
string sbuf, line;
......@@ -200,7 +225,7 @@ void IRC::readIO(void*)
this->quit("Connection reset by peer...");
else if(!sockerr_again())
this->quit(string("Read error: ") + strerror(errno));
return;
return false;
}
buf[r] = 0;
sbuf = buf;
......@@ -228,6 +253,21 @@ void IRC::readIO(void*)
else
(this->*commands[i].func)(m);
}
return true;
}
/* PING [args ...] */
void IRC::m_ping(Message message)
{
message.setCommand(MSG_PONG);
user->send(message);
}
/* PONG cookie */
void IRC::m_pong(Message message)
{
user->delFlag(Nick::PING);
}
/* NICK nickname */
......
......@@ -41,6 +41,7 @@ class IRC
int fd;
int read_id;
_CallBack *read_cb;
_CallBack *ping_cb;
string hostname;
User* user;
RootNick* rootNick;
......@@ -51,7 +52,7 @@ class IRC
public:
IRC(ServerPoll* poll, int fd, string hostname, string command_chan);
IRC(ServerPoll* poll, int fd, string hostname, string command_chan, unsigned ping_freq);
~IRC();
string getServerName() const { return hostname; }
......@@ -69,11 +70,14 @@ public:
Nick* getNick(string nick) const;
void removeNick(string nick);
bool ping(void*);
void readIO(void*);
bool readIO(void*);
void m_nick(Message m);
void m_user(Message m);
void m_quit(Message m);
void m_ping(Message m);
void m_pong(Message m);
void m_privmsg(Message m);
};
......
......@@ -48,6 +48,9 @@
#define MSG_QUIT "QUIT"
#define MSG_ERROR "ERROR"
#define MSG_NICK "NICK"
#define MSG_PING "PING"
#define MSG_PONG "PONG"
#define MSG_USER "USER"
class Nick;
class Channel;
......
......@@ -32,7 +32,8 @@ class Nick
public:
enum {
REGISTERED = 1 << 0
REGISTERED = 1 << 0,
PING = 1 << 1
};
Nick(string nickname, string identname, string hostname, string realname="");
......
......@@ -34,7 +34,8 @@ InetdServerPoll::InetdServerPoll(Bitlbee* application)
{
irc = new IRC(this, 0,
conf.GetSection("irc")->GetItem("hostname")->String(),
conf.GetSection("irc")->GetItem("command_chan")->String());
conf.GetSection("irc")->GetItem("command_chan")->String(),
conf.GetSection("irc")->GetItem("ping")->Integer());
b_log.setIRC(irc);
}
catch(IRCAuthError &e)
......@@ -57,7 +58,7 @@ void InetdServerPoll::kill(IRC* irc)
g_timeout_add(0, g_callback, stop_cb);
}
void InetdServerPoll::stopServer_cb(void*)
bool InetdServerPoll::stopServer_cb(void*)
{
delete stop_cb;
stop_cb = NULL;
......@@ -66,4 +67,5 @@ void InetdServerPoll::stopServer_cb(void*)
irc = NULL;
getApplication()->quit();
return false;
}
......@@ -34,7 +34,7 @@ public:
~InetdServerPoll();
void kill(IRC* irc);
void stopServer_cb(void*);
bool stopServer_cb(void*);
};
#endif /* INETD_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment