Skip to content
Snippets Groups Projects
Commit b75ab9d3 authored by Adrien Béraud's avatar Adrien Béraud
Browse files

tools: add upnpctrl

Change-Id: I4eba598ae849d982d077fce000d0d83f5a4f7762
parent 17765bd1
No related branches found
No related tags found
No related merge requests found
......@@ -145,6 +145,12 @@ if (BUILD_TOOLS)
target_link_libraries(dnc PRIVATE dhtnet fmt::fmt)
target_include_directories(dnc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
install(TARGETS dnc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
add_executable(upnpctrl
tools/upnp/upnpctrl.cpp)
target_link_libraries(upnpctrl PRIVATE dhtnet fmt::fmt readline)
target_include_directories(upnpctrl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
install(TARGETS upnpctrl RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if (BUILD_TESTING AND NOT MSVC)
......
#include "upnp/upnp_control.h"
#include "upnp/upnp_context.h"
#include "string_utils.h"
#include <asio/executor_work_guard.hpp>
#include <opendht/log.h>
#include <readline/readline.h>
#include <readline/history.h>
void
print_help()
{
fmt::print("Commands:\n"
" help, h, ?\n"
" quit, exit, q, x\n"
" ip\n"
" open <port> <protocol>\n");
}
std::string to_lower(std::string_view str_v) {
std::string str(str_v);
std::transform(str.begin(), str.end(), str.begin(),
[](unsigned char c){ return std::tolower(c); }
);
return str;
}
int
main(int argc, char** argv)
{
auto ioContext = std::make_shared<asio::io_context>();
std::shared_ptr<dht::log::Logger> logger = dht::log::getStdLogger();
auto upnpContext = std::make_shared<dhtnet::upnp::UPnPContext>(ioContext, logger);
auto ioContextRunner = std::make_shared<std::thread>([context = ioContext]() {
try {
auto work = asio::make_work_guard(*context);
context->run();
} catch (const std::exception& ex) {
// print the error;
}
});
auto controller = std::make_shared<dhtnet::upnp::Controller>(upnpContext);
std::set<std::shared_ptr<dhtnet::upnp::Mapping>> mappings;
while (true) {
char* l = readline("> ");
if (not l)
break;
std::string_view line{l};
if (line.empty())
continue;
add_history(l);
auto args = dhtnet::split_string(line, ' ');
auto command = args[0];
if (command == "quit" || command == "exit" || command == "q" || command == "x")
break;
else if (command == "help" || command == "h" || command == "?") {
print_help();
}
else if (command == "ip") {
fmt::print("{}\n", controller->getExternalIP().toString());
} else if (command == "open") {
if (args.size() < 3) {
fmt::print("Usage: open <port> <protocol>\n");
continue;
}
auto protocol = to_lower(args[2]) == "udp" ? dhtnet::upnp::PortType::UDP : dhtnet::upnp::PortType::TCP;
mappings.emplace(controller->reserveMapping(dhtnet::to_int<in_port_t>(args[1]), protocol));
} else if (command == "close") {
if (args.size() < 2) {
fmt::print("Usage: close <port>\n");
continue;
}
auto port = dhtnet::to_int<in_port_t>(args[1]);
for (auto it = mappings.begin(); it != mappings.end(); ) {
if ((*it)->getExternalPort() == port) {
controller->releaseMapping(**it);
it = mappings.erase(it);
} else {
++it;
}
}
} else {
fmt::print("Unknown command: {}\n", command);
}
}
fmt::print("Stopping...");
for (auto c: mappings)
controller->releaseMapping(*c);
mappings.clear();
ioContext->stop();
ioContextRunner->join();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment