bool MappingManager::open() { if(getOpened()) return false; if(mappers.empty()) { log(STRING(MAPPER_NO_INTERFACE), LogMessage::SEV_ERROR); return false; } if(busy.test_and_set()) { log(STRING(MAPPER_IN_PROGRESS), LogMessage::SEV_INFO); return false; } start(); return true; }
bool MappingManager::open() { if(getOpened()) return false; if(mappers.empty()) { log("No port mapping interface available", LogManager::LOG_ERROR); return false; } if(busy.test_and_set()) { log("Another port mapping attempt is in progress...", LogManager::LOG_INFO); return false; } start(); return true; }
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; }
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; }