// _RequestThread
int32
AuthenticationServer::_RequestThread()
{
	TaskManager taskManager;
	while (!fTerminating) {
		taskManager.RemoveDoneTasks();
		// read the request
		KMessage request;
		status_t error = request.ReceiveFrom(fRequestPort);
		if (error != B_OK)
			continue;
		// get the parameters
		const char* context = NULL;
		const char* server = NULL;
		const char* share = NULL;
		bool badPassword = true;
		request.FindString("context", &context);
		request.FindString("server", &server);
		request.FindString("share", &share);
		request.FindBool("badPassword", &badPassword);
		if (!context || !server || !share)
			continue;
		String foundUser;
		String foundPassword;
		if (!badPassword && _GetAuthentication(context, server, share,
			&foundUser, &foundPassword)) {
			_SendRequestReply(request.ReplyPort(), request.ReplyToken(),
				error, false, foundUser.GetString(), foundPassword.GetString());
		} else {
			// we need to ask the user: create a task that does it
			UserDialogTask* task = new(nothrow) UserDialogTask(this, context,
				server, share, badPassword, request.ReplyPort(),
				request.ReplyToken());
			if (!task) {
				ERROR(("AuthenticationServer::_RequestThread(): ERROR: "
					"failed to allocate "));
				continue;
			}
			status_t error = taskManager.RunTask(task);
			if (error != B_OK) {
				ERROR(("AuthenticationServer::_RequestThread(): Failed to "
					"start server info task: %s\n", strerror(error)));
				continue;
			}
		}
	}
	return 0;
}
Beispiel #2
0
// _ServerInfoConnectionListener
int32
NetFSServer::_ServerInfoConnectionListener()
{
	if (fServerInfoConnectionListenerSocket < 0)
		return B_BAD_VALUE;

	TaskManager taskManager;

	// accept a incoming connection
	while (!fTerminating) {
		int fd = -1;
		do {
			taskManager.RemoveDoneTasks();

			fd = accept(fServerInfoConnectionListenerSocket, NULL, 0);
			if (fd < 0) {
				status_t error = errno;
				if (error != B_INTERRUPTED)
					return error;
				if (fTerminating)
					return B_OK;
			}
		} while (fd < 0);

		// get a fresh server info
		ServerInfo info;
		status_t error = _GetServerInfo(info);
		if (error != B_OK) {
			closesocket(fd);
			return error;
		}

		// create a server info sender thread
		ServerInfoSender* sender = new(std::nothrow) ServerInfoSender(fd, info);
		if (!sender || sender->Init() != B_OK) {
			closesocket(fd);
			delete sender;
		}
		taskManager.RunTask(sender);
	}

	return B_OK;
}
Beispiel #3
0
// _BroadcastListener
int32
ServerManager::_BroadcastListener()
{
	TaskManager taskManager;
	while (!fTerminating) {
		taskManager.RemoveDoneTasks();

		// receive
		sockaddr_in addr;
		addr.sin_family = AF_INET;
		addr.sin_port = htons(kDefaultBroadcastPort);
		addr.sin_addr.s_addr = INADDR_ANY;
		socklen_t addrSize = sizeof(addr);
		BroadcastMessage message;
//PRINT(("ServerManager::_BroadcastListener(): recvfrom()...\n"));
		ssize_t bytesRead = recvfrom(fBroadcastListenerSocket, &message,
			sizeof(message), 0, (sockaddr*)&addr, &addrSize);
		if (bytesRead < 0) {
			PRINT("ServerManager::_BroadcastListener(): recvfrom() "
				"failed: %s\n", strerror(errno));
			continue;
		}

		// check message size, magic, and protocol version
		if (bytesRead != sizeof(BroadcastMessage)) {
			PRINT("ServerManager::_BroadcastListener(): received "
				"%ld bytes, but it should be %lu\n", bytesRead,
				sizeof(BroadcastMessage));
			continue;
		}
		if (message.magic != B_HOST_TO_BENDIAN_INT32(BROADCAST_MESSAGE_MAGIC)) {
			PRINT("ServerManager::_BroadcastListener(): message has"
				" bad magic.\n");
			continue;
		}
		if (message.protocolVersion
			!= (int32)B_HOST_TO_BENDIAN_INT32(NETFS_PROTOCOL_VERSION)) {
			PRINT("ServerManager::_BroadcastListener(): protocol "
				"version does not match: %" B_PRId32 " vs. %d.\n",
				(int32)B_BENDIAN_TO_HOST_INT32(
					message.protocolVersion),
				NETFS_PROTOCOL_VERSION);
			continue;
		}

		// check, if the server is local
		NetAddress netAddress(addr);
		#ifndef ADD_SERVER_LOCALHOST
			if (netAddress.IsLocal())
				continue;
		#endif	// ADD_SERVER_LOCALHOST

		AutoLocker<Locker> locker(fLock);
		ExtendedServerInfo* oldServerInfo = fServerInfos->Get(netAddress);

		// examine the message
		switch (B_BENDIAN_TO_HOST_INT32(message.message)) {
			case BROADCAST_MESSAGE_SERVER_TICK:
//				PRINT(("ServerManager::_BroadcastListener(): "
//					"BROADCAST_MESSAGE_SERVER_TICK.\n"));
				if (oldServerInfo)
					continue;
				break;
			case BROADCAST_MESSAGE_SERVER_UPDATE:
//				PRINT(("ServerManager::_BroadcastListener(): "
//					"BROADCAST_MESSAGE_SERVER_UPDATE.\n"));
				break;
			case BROADCAST_MESSAGE_CLIENT_HELLO:
//				PRINT(("ServerManager::_BroadcastListener(): "
//					"BROADCAST_MESSAGE_CLIENT_HELLO. Ignoring.\n"));
				continue;
				break;
		}

		if (oldServerInfo && oldServerInfo->GetState() != STATE_READY)
			continue;

		// create a new server info and add it
		ExtendedServerInfo* serverInfo
			= new(std::nothrow) ExtendedServerInfo(netAddress);
		if (!serverInfo)
			return B_NO_MEMORY;
		serverInfo->SetState(STATE_ADDING);
		BReference<ExtendedServerInfo> serverInfoReference(serverInfo, true);
		if (oldServerInfo) {
			oldServerInfo->SetState(STATE_UPDATING);
		} else {
			status_t error = fServerInfos->Put(netAddress, serverInfo);
			if (error != B_OK)
				continue;
			serverInfo->AcquireReference();
		}

		// create a task to add/update the server info
		ServerInfoTask* task = new(std::nothrow) ServerInfoTask(this, oldServerInfo,
			serverInfo);
		if (!task) {
			if (oldServerInfo) {
				oldServerInfo->SetState(STATE_READY);
			} else {
				fServerInfos->Remove(serverInfo->GetAddress());
				serverInfo->ReleaseReference();
			}
			continue;
		}
		// now the task has all info and will call the respective cleanup
		// method when being deleted
		if (task->Init() != B_OK) {
			delete task;
			continue;
		}
		status_t error = taskManager.RunTask(task);
		if (error != B_OK) {
			ERROR("ServerManager::_BroadcastListener(): Failed to start server "
				"info task: %s\n", strerror(error));
			continue;
		}
	}
	return B_OK;
}