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;
}
Beispiel #7
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();
    }
}
Beispiel #10
0
bool ClientManager::isActive() const {
	return CONNSETTING(INCOMING_CONNECTIONS) != SettingsManager::INCOMING_PASSIVE;
}