mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 08:14:15 +00:00
Add bind to network interface option
This commit is contained in:
parent
14f2b24b16
commit
f88f68f248
@ -27,6 +27,10 @@ namespace config {
|
||||
variables_map m_Options;
|
||||
|
||||
void Init() {
|
||||
bool nat = true;
|
||||
#ifdef MESHNET
|
||||
nat = false;
|
||||
#endif
|
||||
options_description general("General options");
|
||||
general.add_options()
|
||||
("help", "Show this message")
|
||||
@ -39,6 +43,8 @@ namespace config {
|
||||
("family", value<std::string>()->default_value(""), "Specify a family, router belongs to")
|
||||
("datadir", value<std::string>()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)")
|
||||
("host", value<std::string>()->default_value("0.0.0.0"), "External IP")
|
||||
("ifname", value<std::string>()->default_value(""), "network interface to bind to")
|
||||
("nat", value<bool>()->zero_tokens()->default_value(nat), "should we assume we are behind NAT?")
|
||||
("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)")
|
||||
("ipv4", value<bool>()->zero_tokens()->default_value(true), "Enable communication through ipv4")
|
||||
("ipv6", value<bool>()->zero_tokens()->default_value(false), "Enable communication through ipv6")
|
||||
|
44
Daemon.cpp
44
Daemon.cpp
@ -22,6 +22,7 @@
|
||||
#include "I2PControl.h"
|
||||
#include "ClientContext.h"
|
||||
#include "Crypto.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifdef USE_UPNP
|
||||
#include "UPnP.h"
|
||||
@ -114,7 +115,7 @@ namespace i2p
|
||||
}
|
||||
i2p::log::Logger().Ready();
|
||||
|
||||
LogPrint(eLogInfo, "i2pd v", VERSION, " starting");
|
||||
LogPrint(eLogInfo, "i2pd v", VERSION, " starting");
|
||||
LogPrint(eLogDebug, "FS: main config file: ", config);
|
||||
LogPrint(eLogDebug, "FS: data directory: ", datadir);
|
||||
|
||||
@ -122,6 +123,14 @@ namespace i2p
|
||||
i2p::crypto::InitCrypto (precomputation);
|
||||
i2p::context.Init ();
|
||||
|
||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||
#ifdef MESHNET
|
||||
// manual override for meshnet
|
||||
ipv4 = false;
|
||||
ipv6 = true;
|
||||
#endif
|
||||
|
||||
uint16_t port; i2p::config::GetOption("port", port);
|
||||
if (!i2p::config::IsDefault("port"))
|
||||
{
|
||||
@ -129,20 +138,31 @@ namespace i2p
|
||||
i2p::context.UpdatePort (port);
|
||||
}
|
||||
|
||||
std::string host; i2p::config::GetOption("host", host);
|
||||
if (!i2p::config::IsDefault("host"))
|
||||
bool nat; i2p::config::GetOption("nat", nat);
|
||||
if (nat)
|
||||
{
|
||||
LogPrint(eLogInfo, "Daemon: setting address for incoming connections to ", host);
|
||||
i2p::context.UpdateAddress (boost::asio::ip::address::from_string (host));
|
||||
LogPrint(eLogInfo, "Daemon: assuming be are behind NAT");
|
||||
// we are behind nat, try setting via host
|
||||
std::string host; i2p::config::GetOption("host", host);
|
||||
if (!i2p::config::IsDefault("host"))
|
||||
{
|
||||
LogPrint(eLogInfo, "Daemon: setting address for incoming connections to ", host);
|
||||
i2p::context.UpdateAddress (boost::asio::ip::address::from_string (host));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are not behind nat
|
||||
std::string ifname; i2p::config::GetOption("ifname", ifname);
|
||||
if (ifname.size())
|
||||
{
|
||||
// bind to interface, we have no NAT so set external address too
|
||||
auto addr = i2p::util::net::GetInterfaceAddress(ifname, ipv6);
|
||||
LogPrint(eLogInfo, "Daemon: bind to network interface ", ifname, " with public address ", addr);
|
||||
i2p::context.UpdateAddress(addr);
|
||||
}
|
||||
}
|
||||
|
||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||
#ifdef MESHNET
|
||||
// manual override for meshnet
|
||||
ipv4 = false;
|
||||
ipv6 = true;
|
||||
#endif
|
||||
bool transit; i2p::config::GetOption("notransit", transit);
|
||||
i2p::context.SetSupportsV6 (ipv6);
|
||||
i2p::context.SetSupportsV4 (ipv4);
|
||||
|
48
util.cpp
48
util.cpp
@ -413,7 +413,53 @@ namespace net
|
||||
return GetMTUUnix(localAddress, fallback);
|
||||
#endif
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
const boost::asio::ip::address GetInterfaceAddress(const std::string & ifname, bool ipv6)
|
||||
{
|
||||
#ifdef WIN32
|
||||
LogPrint(eLogError, "NetIface: cannot get address by interface name, not implemented on WIN32");
|
||||
return boost::asio::ip::from_string("127.0.0.1");
|
||||
#else
|
||||
int af = (ipv6 ? AF_INET6 : AF_INET);
|
||||
ifaddrs * addrs = nullptr;
|
||||
if(getifaddrs(&addrs) == 0)
|
||||
{
|
||||
// got ifaddrs
|
||||
ifaddrs * cur = addrs;
|
||||
while(cur)
|
||||
{
|
||||
std::string cur_ifname(cur->ifa_name);
|
||||
if (cur_ifname == ifname && cur->ifa_addr->sa_family == af)
|
||||
{
|
||||
// match
|
||||
size_t sz = (ipv6 ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN);
|
||||
char * addr = new char[sz];
|
||||
addr[sz-1] = 0;
|
||||
socklen_t sl = (ipv6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in));
|
||||
// this probably won't screw up (right?)
|
||||
inet_ntop(af, cur->ifa_addr, addr, sl);
|
||||
std::string cur_ifaddr(addr);
|
||||
delete [] addr;
|
||||
freeifaddrs(addrs);
|
||||
return boost::asio::ip::address::from_string(cur_ifaddr);
|
||||
}
|
||||
cur = cur->ifa_next;
|
||||
}
|
||||
}
|
||||
if(addrs) freeifaddrs(addrs);
|
||||
std::string fallback;
|
||||
if(ipv6) {
|
||||
fallback = "::";
|
||||
LogPrint(eLogWarning, "NetIface: cannot find ipv6 address for interface ", ifname);
|
||||
} else {
|
||||
fallback = "127.0.0.1";
|
||||
LogPrint(eLogWarning, "NetIface: cannot find ipv4 address for interface ", ifname);
|
||||
}
|
||||
return boost::asio::ip::address::from_string(fallback);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
} // util
|
||||
|
Loading…
x
Reference in New Issue
Block a user