string ConnectivityManager::getInformation() const { if(running) { return "Connectivity settings are being configured; try again later"; } string autoStatus = ok() ? str(boost::format("enabled - %1%") % getStatus()) : "disabled"; string mode; switch(CONNSETTING(INCOMING_CONNECTIONS)) { case SettingsManager::INCOMING_DIRECT: { mode = "Direct connection to the Internet (no router)"; break; } case SettingsManager::INCOMING_FIREWALL_UPNP: { mode = str(boost::format("Active mode behind a router that %1% can configure; port mapping status: %2%") % APPNAME % MappingManager::getInstance()->getStatus()); break; } case SettingsManager::INCOMING_FIREWALL_NAT: { mode = "Active mode behind a router"; break; } case SettingsManager::INCOMING_FIREWALL_PASSIVE: { mode = "Passive mode"; break; } } auto field = [](const string& s) { return s.empty() ? "undefined" : s; }; return str(boost::format( "Connectivity information:\n\n" "Automatic connectivity setup is: %1%\n\n" "\t%2%\n" "\tExternal IP (v4): %3%\n" "\tExternal IP (v6): %4%\n" "\tBound interface (v4): %5%\n" "\tBound interface (v6): %6%\n" "\tTransfer port: %7%\n" "\tEncrypted transfer port: %8%\n" "\tSearch port: %9%") % autoStatus % mode % field(CONNSETTING(EXTERNAL_IP)) % field(CONNSETTING(EXTERNAL_IP6)) % field(CONNSETTING(BIND_ADDRESS)) % field(CONNSETTING(BIND_ADDRESS6)) % field(ConnectionManager::getInstance()->getPort()) % field(ConnectionManager::getInstance()->getSecurePort()) % field(SearchManager::getInstance()->getPort())); }
void SearchManager::listen() { disconnect(); try { socket.reset(new Socket(Socket::TYPE_UDP)); socket->setLocalIp4(CONNSETTING(BIND_ADDRESS)); socket->setLocalIp6(CONNSETTING(BIND_ADDRESS6)); port = socket->listen(Util::toString(CONNSETTING(UDP_PORT))); start(); } catch(...) { socket.reset(); throw; } }
int SearchManager::run() { boost::scoped_array<uint8_t> buf(new uint8_t[BUFSIZE]); int len; string remoteAddr; while(!stop) { try { if(!socket->wait(400, true, false).first) { continue; } if((len = socket->read(&buf[0], BUFSIZE, remoteAddr)) > 0) { string data(reinterpret_cast<char*>(&buf[0]), len); if(PluginManager::getInstance()->onUDP(false, remoteAddr, port, data)) continue; onData(data, remoteAddr); continue; } } catch(const SocketException& e) { dcdebug("SearchManager::run Error: %s\n", e.getError().c_str()); } bool failed = false; while(!stop) { try { socket->disconnect(); port = socket->listen(Util::toString(CONNSETTING(UDP_PORT))); if(failed) { LogManager::getInstance()->message(_("Search enabled again")); failed = false; } break; } catch(const SocketException& e) { dcdebug("SearchManager::run Stopped listening: %s\n", e.getError().c_str()); if(!failed) { LogManager::getInstance()->message(str(F_("Search disabled: %1%") % e.getError())); failed = true; } // Spin for 60 seconds for(auto i = 0; i < 60 && !stop; ++i) { Thread::sleep(1000); } } } } return 0; }
int UDPServer::run() { uint8_t* buf = nullptr; int len; string remoteAddr; while(!stop) { try { if(!socket->wait(400, true, false).first) { continue; } buf = new uint8_t[BUFSIZE]; if((len = socket->read(buf, BUFSIZE, remoteAddr)) > 0) { pp.queue.push(new PacketProcessor::PacketTask(buf, len, remoteAddr)); pp.s.signal(); continue; } delete buf; } catch(const SocketException& e) { dcdebug("SearchManager::run Error: %s\n", e.getError().c_str()); } bool failed = false; while(!stop) { try { socket->disconnect(); port = socket->listen(Util::toString(CONNSETTING(UDP_PORT))); if(failed) { LogManager::getInstance()->message("Search enabled again", LogManager::LOG_INFO); failed = false; } break; } catch(const SocketException& e) { dcdebug("SearchManager::run Stopped listening: %s\n", e.getError().c_str()); if(!failed) { LogManager::getInstance()->message(STRING_F(SEARCH_DISABLED_X, e.getError()), LogManager::LOG_ERROR); failed = true; } // Spin for 60 seconds for(auto i = 0; i < 60 && !stop; ++i) { Thread::sleep(1000); } } } } return 0; }
string ConnectivityManager::getInformation() const { if(isRunning()) { return "Connectivity settings are being configured; try again later"; } string autoStatusV4 = ok(false) ? str(boost::format("enabled - %1%") % getStatus(false)) : "disabled"; string autoStatusV6 = ok(true) ? str(boost::format("enabled - %1%") % getStatus(true)) : "disabled"; auto getMode = [&](bool v6) -> string { switch(v6 ? CONNSETTING(INCOMING_CONNECTIONS6) : CONNSETTING(INCOMING_CONNECTIONS)) { case SettingsManager::INCOMING_ACTIVE: { return "Direct connection to the Internet (no router or manual router configuration)"; break; } case SettingsManager::INCOMING_ACTIVE_UPNP: { return str(boost::format("Active mode behind a router that %1% can configure; port mapping status: %2%") % APPNAME % (v6 ? mapperV6.getStatus() : mapperV4.getStatus())); break; } case SettingsManager::INCOMING_PASSIVE: { return "Passive mode"; break; } default: return "Disabled"; } }; auto field = [](const string& s) { return s.empty() ? "undefined" : s; }; return str(boost::format( "Connectivity information:\n\n" "Automatic connectivity setup (v4) is: %1%\n\n" "Automatic connectivity setup (v6) is: %2%\n\n" "\tMode (v4): %3%\n" "\tMode (v6): %4%\n" "\tExternal IP (v4): %5%\n" "\tExternal IP (v6): %6%\n" "\tBound interface (v4): %7%\n" "\tBound interface (v6): %8%\n" "\tTransfer port: %9%\n" "\tEncrypted transfer port: %10%\n" "\tSearch port: %11%") % autoStatusV4 % autoStatusV6 % getMode(false) % getMode(true) % field(CONNSETTING(EXTERNAL_IP)) % field(CONNSETTING(EXTERNAL_IP6)) % field(CONNSETTING(BIND_ADDRESS)) % field(CONNSETTING(BIND_ADDRESS6)) % field(ConnectionManager::getInstance()->getPort()) % field(ConnectionManager::getInstance()->getSecurePort()) % field(SearchManager::getInstance()->getPort())); }
int MappingManager::run() { ScopedFunctor([this] { busy.clear(); }); // cache ports auto conn_port = ConnectionManager::getInstance()->getPort(), secure_port = ConnectionManager::getInstance()->getSecurePort(), search_port = SearchManager::getInstance()->getPort(); if(renewal) { Mapper& mapper = *working; ScopedFunctor([&mapper] { mapper.uninit(); }); if(!mapper.init()) { // can't renew; try again later. renewLater(mapper); return 0; } auto addRule = [this, &mapper](const string& port, Mapper::Protocol protocol, const string& description) { // just launch renewal requests - don't bother with possible failures. if(!port.empty()) { mapper.open(port, protocol, STRING_F(MAPPER_X_PORT_X, description % port % Mapper::protocols[protocol])); } }; addRule(conn_port, Mapper::PROTOCOL_TCP, "Transfer"); addRule(secure_port, Mapper::PROTOCOL_TCP, "Encrypted transfer"); addRule(search_port, Mapper::PROTOCOL_UDP, "Search"); renewLater(mapper); return 0; } // move the preferred mapper to the top of the stack. const auto& mapperName = SETTING(MAPPER); for(auto i = mappers.begin(); i != mappers.end(); ++i) { if(i->first == mapperName) { if(i != mappers.begin()) { auto mapper = *i; mappers.erase(i); mappers.insert(mappers.begin(), mapper); } break; } } for(auto& i: mappers) { auto setting = v6 ? SettingsManager::BIND_ADDRESS6 : SettingsManager::BIND_ADDRESS; unique_ptr<Mapper> pMapper(i.second((SettingsManager::getInstance()->isDefault(setting) ? Util::emptyString : SettingsManager::getInstance()->get(setting)), v6)); Mapper& mapper = *pMapper; ScopedFunctor([&mapper] { mapper.uninit(); }); if(!mapper.init()) { log(STRING_F(MAPPER_INIT_FAILED, mapper.getName()), LogMessage::SEV_WARNING); continue; } auto addRule = [this, &mapper](const string& port, Mapper::Protocol protocol, const string& description) -> bool { if (!port.empty() && !mapper.open(port, protocol, STRING_F(MAPPER_X_PORT_X, APPNAME % description % port % Mapper::protocols[protocol]))) { this->log(STRING_F(MAPPER_INTERFACE_FAILED, description % port % Mapper::protocols[protocol] % mapper.getName()), LogMessage::SEV_WARNING); mapper.close(); return false; } return true; }; if(!(addRule(conn_port, Mapper::PROTOCOL_TCP, STRING(TRANSFER)) && addRule(secure_port, Mapper::PROTOCOL_TCP, STRING(ENCRYPTED_TRANSFER)) && addRule(search_port, Mapper::PROTOCOL_UDP, STRING(SEARCH)))) continue; log(STRING_F(MAPPER_CREATING_SUCCESS_LONG, conn_port % secure_port % search_port % deviceString(mapper) % mapper.getName()), LogMessage::SEV_INFO); working = move(pMapper); if ((!v6 && !CONNSETTING(NO_IP_OVERRIDE)) || (v6 && !CONNSETTING(NO_IP_OVERRIDE6))) { setting = v6 ? SettingsManager::EXTERNAL_IP6 : SettingsManager::EXTERNAL_IP; string externalIP = mapper.getExternalIP(); if(!externalIP.empty()) { ConnectivityManager::getInstance()->set(setting, externalIP); } else { // no cleanup because the mappings work and hubs will likely provide the correct IP. log(STRING(MAPPER_IP_FAILED), LogMessage::SEV_WARNING); } } ConnectivityManager::getInstance()->mappingFinished(mapper.getName(), v6); renewLater(mapper); break; } if(!getOpened()) { log(STRING(MAPPER_CREATING_FAILED), LogMessage::SEV_ERROR); ConnectivityManager::getInstance()->mappingFinished(Util::emptyString, v6); } return 0; }
const string& Client::getUserIp6() const { if (!get(UserIp6).empty()) { return get(UserIp6); } return CONNSETTING(EXTERNAL_IP6); }
int MappingManager::run() { ScopedFunctor([this] { busy.clear(); }); // cache ports auto conn_port = ConnectionManager::getInstance()->getPort(), secure_port = ConnectionManager::getInstance()->getSecurePort(), search_port = SearchManager::getInstance()->getPort(); if(renewal) { Mapper& mapper = *working; ScopedFunctor([&mapper] { mapper.uninit(); }); if(!mapper.init()) { // can't renew; try again later. renewLater(mapper); return 0; } auto addRule = [this, &mapper](const string& port, Mapper::Protocol protocol, const string& description) { // just launch renewal requests - don't bother with possible failures. if(!port.empty()) { mapper.open(port, protocol, str(boost::format("%1% %2% port (%3% %4%)") % description % port % Mapper::protocols[protocol])); } }; addRule(conn_port, Mapper::PROTOCOL_TCP, "Transfer"); addRule(secure_port, Mapper::PROTOCOL_TCP, "Encrypted transfer"); addRule(search_port, Mapper::PROTOCOL_UDP, "Search"); renewLater(mapper); return 0; } // move the preferred mapper to the top of the stack. const auto& setting = SETTING(MAPPER); for(auto i = mappers.begin(); i != mappers.end(); ++i) { if(i->first == setting) { if(i != mappers.begin()) { auto mapper = *i; mappers.erase(i); mappers.insert(mappers.begin(), mapper); } break; } } for(auto i = mappers.begin(); i != mappers.end(); ++i) { unique_ptr<Mapper> pMapper(i->second(AirUtil::getLocalIp())); Mapper& mapper = *pMapper; ScopedFunctor([&mapper] { mapper.uninit(); }); if(!mapper.init()) { log(str(boost::format("Failed to initalize the %1% interface") % mapper.getName()), LogManager::LOG_WARNING); continue; } auto addRule = [this, &mapper](const string& port, Mapper::Protocol protocol, const string& description) -> bool { if(!port.empty() && !mapper.open(port, protocol, str(boost::format("%1% %2% port (%3% %4%)") % APPNAME % description % port % Mapper::protocols[protocol]))) { this->log(str(boost::format("Failed to map the %1% port (%2% %3%) with the %4% interface") % description % port % Mapper::protocols[protocol] % mapper.getName()), LogManager::LOG_WARNING); mapper.close(); return false; } return true; }; if(!(addRule(conn_port, Mapper::PROTOCOL_TCP, "Transfer") && addRule(secure_port, Mapper::PROTOCOL_TCP, "Encrypted transfer") && addRule(search_port, Mapper::PROTOCOL_UDP, "Search"))) continue; log(str(boost::format("Successfully created port mappings (Transfers: %1%, Encrypted transfers: %2%, Search: %3%) on the %4% device with the %5% interface") % conn_port % secure_port % search_port % deviceString(mapper) % mapper.getName()), LogManager::LOG_INFO); working = move(pMapper); if(!CONNSETTING(NO_IP_OVERRIDE)) { string externalIP = mapper.getExternalIP(); if(!externalIP.empty()) { ConnectivityManager::getInstance()->set(SettingsManager::EXTERNAL_IP, externalIP); } else { // no cleanup because the mappings work and hubs will likely provide the correct IP. log("Failed to get external IP", LogManager::LOG_WARNING); } } ConnectivityManager::getInstance()->mappingFinished(mapper.getName()); renewLater(mapper); break; } if(!getOpened()) { log(str(boost::format("Failed to create port mappings")), LogManager::LOG_ERROR); ConnectivityManager::getInstance()->mappingFinished(Util::emptyString); } return 0; }
SettingHolder::~SettingHolder() { if (SETTING(DISCONNECT_SPEED) < 1) { SettingsManager::getInstance()->set(SettingsManager::DISCONNECT_SPEED, 1); } bool v4Changed = SETTING(INCOMING_CONNECTIONS) != prevConn4 || SETTING(TCP_PORT) != prevTCP || SETTING(UDP_PORT) != prevUDP || SETTING(TLS_PORT) != prevTLS || SETTING(MAPPER) != prevMapper || SETTING(BIND_ADDRESS) != prevBind || SETTING(BIND_ADDRESS6) != prevBind6; bool v6Changed = SETTING(INCOMING_CONNECTIONS6) != prevConn6 || SETTING(TCP_PORT) != prevTCP || SETTING(UDP_PORT) != prevUDP || SETTING(TLS_PORT) != prevTLS || /*SETTING(MAPPER) != prevMapper ||*/ SETTING(BIND_ADDRESS6) != prevBind6; try { ConnectivityManager::getInstance()->setup(v4Changed, v6Changed); } catch (const Exception& e) { showError(e.getError()); } auto outConns = CONNSETTING(OUTGOING_CONNECTIONS); if (outConns != prevProxy || outConns == SettingsManager::OUTGOING_SOCKS5) { Socket::socksUpdated(); } ClientManager::getInstance()->infoUpdated(); if (prevHighPrio != SETTING(HIGH_PRIO_FILES) || prevHighPrioRegex != SETTING(HIGHEST_PRIORITY_USE_REGEXP) || prevDownloadSkiplist != SETTING(SKIPLIST_DOWNLOAD) || prevDownloadSkiplistRegex != SETTING(DOWNLOAD_SKIPLIST_USE_REGEXP)) { QueueManager::getInstance()->setMatchers(); } if (prevShareSkiplist != SETTING(SKIPLIST_SHARE) || prevShareSkiplistRegex != SETTING(SHARE_SKIPLIST_USE_REGEXP)) { ShareManager::getInstance()->setSkipList(); } if (prevFreeSlotMatcher != SETTING(FREE_SLOTS_EXTENSIONS)) { UploadManager::getInstance()->setFreeSlotMatcher(); } bool rebuildGeo = prevGeo && SETTING(COUNTRY_FORMAT) != prevGeoFormat; if (SETTING(GET_USER_COUNTRY) != prevGeo) { if (SETTING(GET_USER_COUNTRY)) { GeoManager::getInstance()->init(); UpdateManager::getInstance()->checkGeoUpdate(); } else { GeoManager::getInstance()->close(); rebuildGeo = false; } } if (rebuildGeo) { GeoManager::getInstance()->rebuild(); } if (prevUpdateChannel != SETTING(UPDATE_CHANNEL)) { UpdateManager::getInstance()->checkVersion(false); } else if (prevTranslation != SETTING(LANGUAGE_FILE)) { UpdateManager::getInstance()->checkLanguage(); } }
bool ClientManager::isActive() const { return CONNSETTING(INCOMING_CONNECTIONS) != SettingsManager::INCOMING_PASSIVE; }