Add the outgoing_bind option
Lets the admin choose a local address to bind each outgoing (IRC) socket.
This commit is contained in:
@@ -120,6 +120,15 @@ The configuration file uses a simple format of the form
|
|||||||
negociating a TLS session. By default this value is unset and biboumi
|
negociating a TLS session. By default this value is unset and biboumi
|
||||||
tries a list of well-known paths.
|
tries a list of well-known paths.
|
||||||
|
|
||||||
|
`outgoing_bind`
|
||||||
|
|
||||||
|
An address (IPv4 or IPv6) to bind the outgoing sockets to. If no value is
|
||||||
|
specified, it will use the one assigned by the operating system. You can
|
||||||
|
for example use outgoing_bind=192.168.1.11 to force biboumi to use the
|
||||||
|
interface with this address. Note that this is only used for connections
|
||||||
|
to IRC servers, the connection to the XMPP server is always done locally
|
||||||
|
on 127.0.0.1.
|
||||||
|
|
||||||
The configuration can be re-read at runtime (you can for example change the
|
The configuration can be re-read at runtime (you can for example change the
|
||||||
log level without having to restart biboumi) by sending SIGUSR1 or SIGUSR2
|
log level without having to restart biboumi) by sending SIGUSR1 or SIGUSR2
|
||||||
(see kill(1)) to the process.
|
(see kill(1)) to the process.
|
||||||
|
|||||||
@@ -56,6 +56,34 @@ void TCPSocketHandler::init_socket(const struct addrinfo* rp)
|
|||||||
::close(this->socket);
|
::close(this->socket);
|
||||||
if ((this->socket = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1)
|
if ((this->socket = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1)
|
||||||
throw std::runtime_error("Could not create socket: "s + strerror(errno));
|
throw std::runtime_error("Could not create socket: "s + strerror(errno));
|
||||||
|
// Bind the socket to a specific address, if specified
|
||||||
|
if (!this->bind_addr.empty())
|
||||||
|
{
|
||||||
|
// Convert the address from string format to a sockaddr that can be
|
||||||
|
// used in bind()
|
||||||
|
struct addrinfo* result;
|
||||||
|
int err = ::getaddrinfo(this->bind_addr.data(), nullptr, nullptr, &result);
|
||||||
|
if (err != 0)
|
||||||
|
log_error("Failed to bind socket to " << this->bind_addr << ": "
|
||||||
|
<< gai_strerror(err));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct addrinfo* rp;
|
||||||
|
int bind_error;
|
||||||
|
for (rp = result; rp; rp = rp->ai_next)
|
||||||
|
{
|
||||||
|
if ((bind_error = ::bind(this->socket,
|
||||||
|
reinterpret_cast<const struct sockaddr*>(rp->ai_addr),
|
||||||
|
rp->ai_addrlen)) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!rp)
|
||||||
|
log_error("Failed to bind socket to " << this->bind_addr << ": "
|
||||||
|
<< strerror(bind_error));
|
||||||
|
else
|
||||||
|
log_info("Socket successfully bound to " << this->bind_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
int optval = 1;
|
int optval = 1;
|
||||||
if (::setsockopt(this->socket, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) == -1)
|
if (::setsockopt(this->socket, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) == -1)
|
||||||
log_warning("Failed to enable TCP keepalive on socket: " << strerror(errno));
|
log_warning("Failed to enable TCP keepalive on socket: " << strerror(errno));
|
||||||
|
|||||||
@@ -224,6 +224,12 @@ protected:
|
|||||||
|
|
||||||
bool hostname_resolution_failed;
|
bool hostname_resolution_failed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address to bind the socket to, before calling connect().
|
||||||
|
* If empty, it’s equivalent to binding to INADDR_ANY.
|
||||||
|
*/
|
||||||
|
std::string bind_addr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TCPSocketHandler(const TCPSocketHandler&) = delete;
|
TCPSocketHandler(const TCPSocketHandler&) = delete;
|
||||||
TCPSocketHandler(TCPSocketHandler&&) = delete;
|
TCPSocketHandler(TCPSocketHandler&&) = delete;
|
||||||
|
|||||||
@@ -86,6 +86,9 @@ void IrcClient::start()
|
|||||||
this->bridge->send_xmpp_message(this->hostname, "", "Connecting to "s +
|
this->bridge->send_xmpp_message(this->hostname, "", "Connecting to "s +
|
||||||
this->hostname + ":" + port + " (" +
|
this->hostname + ":" + port + " (" +
|
||||||
(tls ? "encrypted" : "not encrypted") + ")");
|
(tls ? "encrypted" : "not encrypted") + ")");
|
||||||
|
|
||||||
|
this->bind_addr = Config::get("outgoing_bind", "");
|
||||||
|
|
||||||
this->connect(this->hostname, port, tls);
|
this->connect(this->hostname, port, tls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user