Commit c4ce72d5 authored by Romain Bignon's avatar Romain Bignon

Daemon-fork mode supports ipv6. (refs #163)

parent 5efc4458
......@@ -32,10 +32,16 @@ irc {
# With 'daemon' and 'daemon fork' modes, set some
# parameters to listen on network.
daemon {
# Interface or IP address to listen on. It can be a IPv4 or
# a IPv6 address or netmask.
# To listen on every interfaces, set 'bind' to '::'.
bind = 0.0.0.0
# Port to listen on.
port = 6667
# If this parameter is enabled, it run MinBif as a daemon.
# stdin, stdout and stderr will be also closed.
background = true
}
......
......@@ -34,40 +34,6 @@
#include "im/im.h"
#include "server_poll/poll.h"
/** This is a derived class from ConfigItem whose represent an IP address item */
class ConfigItem_ipaddr : public ConfigItem
{
public:
ConfigItem_ipaddr(std::string _label, std::string _description, std::string def_value = "",
TCallBack cb = 0, MyConfig* _config = 0, ConfigSection* _parent = 0)
: ConfigItem(_label, _description, def_value, cb, _config, _parent)
{}
virtual ConfigItem* Clone() const
{
return new ConfigItem_ipaddr(Label(), Description(), DefValue(), CallBack(), GetConfig(), Parent());
}
/** We return a string form of this integer */
virtual std::string String() const { return value; }
virtual bool SetValue(std::string s)
{
if(!is_ip(s.c_str()))
return false;
value = s;
return true;
}
std::string ValueType() const
{
return "ip address";
}
private:
string value;
};
/** This is a derived class from ConfigItem whose represent an integer range item */
class ConfigItem_intrange : public ConfigItem_int
{
......@@ -142,7 +108,7 @@ Minbif::Minbif()
section->AddItem(new ConfigItem_string("buddy_icons_url", "URL to display in /WHOIS to get a buddy icon", " "));
ConfigSection* sub = section->AddSection("daemon", "Daemon information", true);
sub->AddItem(new ConfigItem_ipaddr("bind", "IP address to listen on"));
sub->AddItem(new ConfigItem_string("bind", "IP address to listen on"));
sub->AddItem(new ConfigItem_int("port", "Port to listen on", 1, 65535), true);
sub->AddItem(new ConfigItem_bool("background", "Start minbif in background", "true"));
......
......@@ -40,6 +40,7 @@
DaemonForkServerPoll::DaemonForkServerPoll(Minbif* application)
: ServerPoll(application),
irc(NULL),
sock(-1),
read_cb(NULL)
{
std::vector<ConfigSection*> sections = conf.GetSection("irc")->GetSectionClones("daemon");
......@@ -50,9 +51,6 @@ DaemonForkServerPoll::DaemonForkServerPoll(Minbif* application)
}
ConfigSection* section = sections[0];
const char* bind_addr = section->GetItem("bind")->String().c_str();
uint16_t port = (uint16_t)section->GetItem("port")->Integer();
if(section->GetItem("background")->Boolean())
{
int r = fork();
......@@ -69,32 +67,50 @@ DaemonForkServerPoll::DaemonForkServerPoll(Minbif* application)
if(isatty(2)) close(2);
}
static struct sockaddr_in fsocket;
fsocket.sin_family = AF_INET;
fsocket.sin_addr.s_addr = inet_addr(bind_addr);
fsocket.sin_port = htons(port);
struct addrinfo *addrinfo_bind, *res, hints;
string bind_addr = section->GetItem("bind")->String();
uint16_t port = (uint16_t)section->GetItem("port")->Integer();
unsigned int reuse_addr = 1;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if(getaddrinfo(bind_addr.c_str(), t2s(port).c_str(), &hints, &addrinfo_bind))
{
b_log[W_ERR] << "Could not parse address " << bind_addr << ":" << port;
throw ServerPollError();
}
for(res = addrinfo_bind; res && sock < 0;)
if((sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
res = res->ai_next;
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock < 0)
{
b_log[W_ERR] << "Unable to create a socket: " << strerror(errno);
throw ServerPollError();
goto out;
}
unsigned int reuse_addr = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof reuse_addr);
if(bind(sock, (struct sockaddr *) &fsocket, sizeof fsocket) < 0 ||
if(bind(sock, res->ai_addr, res->ai_addrlen) < 0 ||
listen(sock, 5) < 0)
{
b_log[W_ERR] << "Unable to listen on " << bind_addr << ":" << port
<< ": " << strerror(errno);
throw ServerPollError();
<< ":" << sock << ": " << strerror(errno);
goto out;
}
read_cb = new CallBack<DaemonForkServerPoll>(this, &DaemonForkServerPoll::new_client_cb);
read_id = glib_input_add(sock, (PurpleInputCondition)PURPLE_INPUT_READ,
g_callback_input, read_cb);
out:
freeaddrinfo(addrinfo_bind);
if(!read_cb)
throw ServerPollError();
}
DaemonForkServerPoll::~DaemonForkServerPoll()
......@@ -240,7 +256,6 @@ bool DaemonForkServerPoll::ipc_read(void* data)
{
if(r < 0 && sockerr_again())
return true;
b_log[W_ERR] << "Error while receiving IPC data: " << strerror(errno);
if(child)
{
for(vector<child_t*>::iterator it = childs.begin(); it != childs.end();)
......
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