Browse Source

fix osx upnp support

fix tabulation in UPnP.cpp
pull/806/head
R4SAS 8 years ago
parent
commit
83300044dd
  1. 1
      Makefile.homebrew
  2. 5
      Makefile.osx
  3. 234
      UPnP.cpp

1
Makefile.homebrew

@ -11,6 +11,7 @@ LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem
ifeq ($(USE_UPNP),yes) ifeq ($(USE_UPNP),yes)
LDFLAGS += -ldl LDFLAGS += -ldl
CXXFLAGS += -DUSE_UPNP CXXFLAGS += -DUSE_UPNP
LDLIBS += -lminiupnpc
endif endif
# OSX Notes # OSX Notes

5
Makefile.osx vendored

@ -13,6 +13,11 @@ endif
ifeq ($(USE_UPNP),yes) ifeq ($(USE_UPNP),yes)
LDFLAGS += -ldl LDFLAGS += -ldl
CXXFLAGS += -DUSE_UPNP CXXFLAGS += -DUSE_UPNP
ifeq ($(USE_STATIC),yes)
LDLIBS += /usr/local/lib/libminiupnpc.a
else
LDLIBS += -lminiupnpc
endif
endif endif
ifeq ($(USE_AESNI),1) ifeq ($(USE_AESNI),1)

234
UPnP.cpp

@ -22,49 +22,49 @@ namespace i2p
{ {
namespace transport namespace transport
{ {
UPnP::UPnP () : m_IsRunning(false), m_Thread (nullptr), m_Timer (m_Service) UPnP::UPnP () : m_IsRunning(false), m_Thread (nullptr), m_Timer (m_Service)
{ {
} }
void UPnP::Stop () void UPnP::Stop ()
{ {
if (m_IsRunning) if (m_IsRunning)
{ {
LogPrint(eLogInfo, "UPnP: stopping"); LogPrint(eLogInfo, "UPnP: stopping");
m_IsRunning = false; m_IsRunning = false;
m_Timer.cancel (); m_Timer.cancel ();
m_Service.stop (); m_Service.stop ();
if (m_Thread) if (m_Thread)
{ {
m_Thread->join (); m_Thread->join ();
m_Thread.reset (nullptr); m_Thread.reset (nullptr);
} }
CloseMapping (); CloseMapping ();
Close (); Close ();
} }
} }
void UPnP::Start() void UPnP::Start()
{ {
m_IsRunning = true; m_IsRunning = true;
LogPrint(eLogInfo, "UPnP: starting"); LogPrint(eLogInfo, "UPnP: starting");
m_Service.post (std::bind (&UPnP::Discover, this)); m_Service.post (std::bind (&UPnP::Discover, this));
std::unique_lock<std::mutex> l(m_StartedMutex); std::unique_lock<std::mutex> l(m_StartedMutex);
m_Thread.reset (new std::thread (std::bind (&UPnP::Run, this))); m_Thread.reset (new std::thread (std::bind (&UPnP::Run, this)));
m_Started.wait_for (l, std::chrono::seconds (5)); // 5 seconds maximum m_Started.wait_for (l, std::chrono::seconds (5)); // 5 seconds maximum
} }
UPnP::~UPnP () UPnP::~UPnP ()
{ {
Stop (); Stop ();
} }
void UPnP::Run () void UPnP::Run ()
{ {
while (m_IsRunning) while (m_IsRunning)
{ {
try try
{ {
m_Service.run (); m_Service.run ();
// Discover failed // Discover failed
break; // terminate the thread break; // terminate the thread
@ -73,127 +73,127 @@ namespace transport
{ {
LogPrint (eLogError, "UPnP: runtime exception: ", ex.what ()); LogPrint (eLogError, "UPnP: runtime exception: ", ex.what ());
PortMapping (); PortMapping ();
} }
} }
} }
void UPnP::Discover () void UPnP::Discover ()
{ {
int nerror = 0; int nerror = 0;
#if MINIUPNPC_API_VERSION >= 14 #if MINIUPNPC_API_VERSION >= 14
m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, 2, &nerror); m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, 2, &nerror);
#else #else
m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror); m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror);
#endif #endif
{ {
// notify satrting thread // notify satrting thread
std::unique_lock<std::mutex> l(m_StartedMutex); std::unique_lock<std::mutex> l(m_StartedMutex);
m_Started.notify_all (); m_Started.notify_all ();
} }
int r; int r;
r = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); r = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
if (r == 1) if (r == 1)
{ {
r = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); r = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
if(r != UPNPCOMMAND_SUCCESS) if(r != UPNPCOMMAND_SUCCESS)
{ {
LogPrint (eLogError, "UPnP: UPNP_GetExternalIPAddress() returned ", r); LogPrint (eLogError, "UPnP: UPNP_GetExternalIPAddress() returned ", r);
return; return;
} }
else else
{ {
if (!m_externalIPAddress[0]) if (!m_externalIPAddress[0])
{ {
LogPrint (eLogError, "UPnP: GetExternalIPAddress() failed."); LogPrint (eLogError, "UPnP: GetExternalIPAddress() failed.");
return; return;
} }
} }
} }
else else
{ {
LogPrint (eLogError, "UPnP: GetValidIGD() failed."); LogPrint (eLogError, "UPnP: GetValidIGD() failed.");
return; return;
} }
// UPnP discovered // UPnP discovered
LogPrint (eLogDebug, "UPnP: ExternalIPAddress is ", m_externalIPAddress); LogPrint (eLogDebug, "UPnP: ExternalIPAddress is ", m_externalIPAddress);
i2p::context.UpdateAddress (boost::asio::ip::address::from_string (m_externalIPAddress)); i2p::context.UpdateAddress (boost::asio::ip::address::from_string (m_externalIPAddress));
// port mapping // port mapping
PortMapping (); PortMapping ();
} }
void UPnP::PortMapping () void UPnP::PortMapping ()
{ {
const auto& a = context.GetRouterInfo().GetAddresses(); const auto& a = context.GetRouterInfo().GetAddresses();
for (const auto& address : a) for (const auto& address : a)
{ {
if (!address->host.is_v6 ()) if (!address->host.is_v6 ())
TryPortMapping (address); TryPortMapping (address);
} }
m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes
m_Timer.async_wait ([this](const boost::system::error_code& ecode) m_Timer.async_wait ([this](const boost::system::error_code& ecode)
{ {
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)
PortMapping (); PortMapping ();
}); });
} }
void UPnP::CloseMapping () void UPnP::CloseMapping ()
{ {
const auto& a = context.GetRouterInfo().GetAddresses(); const auto& a = context.GetRouterInfo().GetAddresses();
for (const auto& address : a) for (const auto& address : a)
{ {
if (!address->host.is_v6 ()) if (!address->host.is_v6 ())
CloseMapping (address); CloseMapping (address);
} }
} }
void UPnP::TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address) void UPnP::TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address)
{ {
std::string strType (GetProto (address)), strPort (std::to_string (address->port)); std::string strType (GetProto (address)), strPort (std::to_string (address->port));
int r; int r;
std::string strDesc; i2p::config::GetOption("upnp.name", strDesc); std::string strDesc; i2p::config::GetOption("upnp.name", strDesc);
r = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0"); r = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0");
if (r!=UPNPCOMMAND_SUCCESS) if (r!=UPNPCOMMAND_SUCCESS)
{ {
LogPrint (eLogError, "UPnP: AddPortMapping (", m_NetworkAddr, ":", strPort, ") failed with code ", r); LogPrint (eLogError, "UPnP: AddPortMapping (", m_NetworkAddr, ":", strPort, ") failed with code ", r);
return; return;
} }
else else
{ {
LogPrint (eLogDebug, "UPnP: Port Mapping successful. (", m_NetworkAddr ,":", strPort, " type ", strType, " -> ", m_externalIPAddress ,":", strPort ,")"); LogPrint (eLogDebug, "UPnP: Port Mapping successful. (", m_NetworkAddr ,":", strPort, " type ", strType, " -> ", m_externalIPAddress ,":", strPort ,")");
return; return;
} }
} }
void UPnP::CloseMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address) void UPnP::CloseMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address)
{ {
std::string strType (GetProto (address)), strPort (std::to_string (address->port)); std::string strType (GetProto (address)), strPort (std::to_string (address->port));
int r = 0; int r = 0;
r = UPNP_DeletePortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), 0); r = UPNP_DeletePortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), 0);
LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", r); LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", r);
} }
void UPnP::Close () void UPnP::Close ()
{ {
freeUPNPDevlist (m_Devlist); freeUPNPDevlist (m_Devlist);
m_Devlist = 0; m_Devlist = 0;
FreeUPNPUrls (&m_upnpUrls); FreeUPNPUrls (&m_upnpUrls);
} }
std::string UPnP::GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address) std::string UPnP::GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address)
{ {
switch (address->transportStyle) switch (address->transportStyle)
{ {
case i2p::data::RouterInfo::eTransportNTCP: case i2p::data::RouterInfo::eTransportNTCP:
return "TCP"; return "TCP";
break; break;
case i2p::data::RouterInfo::eTransportSSU: case i2p::data::RouterInfo::eTransportSSU:
default: default:
return "UDP"; return "UDP";
} }
} }
} }
} }

Loading…
Cancel
Save