diff --git a/src/client/Client.hxx b/src/client/Client.hxx index 06b5a68b5..2f030b486 100644 --- a/src/client/Client.hxx +++ b/src/client/Client.hxx @@ -39,6 +39,8 @@ class Client final friend struct ClientPerPartitionListHook; friend class ClientList; + const std::string name; + IntrusiveListHook<> list_siblings, partition_siblings; CoarseTimerEvent timeout_event; @@ -52,8 +54,6 @@ class Client final CommandListBuilder cmd_list; - const unsigned int num; /* client number */ - /** is this client waiting for an "idle" response? */ bool idle_waiting = false; @@ -122,7 +122,7 @@ public: Client(EventLoop &loop, Partition &partition, UniqueSocketDescriptor fd, int uid, unsigned _permission, - int num) noexcept; + std::string &&_name) noexcept; ~Client() noexcept; diff --git a/src/client/Event.cxx b/src/client/Event.cxx index 52afc9404..870d4eb79 100644 --- a/src/client/Event.cxx +++ b/src/client/Event.cxx @@ -9,7 +9,7 @@ void Client::OnSocketError(std::exception_ptr ep) noexcept { - FmtError(client_domain, "error on client {}: {}", num, ep); + FmtError(client_domain, "[{}] error: {}", name, ep); SetExpired(); } diff --git a/src/client/Expire.cxx b/src/client/Expire.cxx index b26b1d01b..a775d3947 100644 --- a/src/client/Expire.cxx +++ b/src/client/Expire.cxx @@ -28,7 +28,7 @@ Client::OnTimeout() noexcept assert(!idle_waiting); assert(!background_command); - FmtDebug(client_domain, "[{}] timeout", num); + FmtDebug(client_domain, "[{}] timeout", name); } Close(); diff --git a/src/client/New.cxx b/src/client/New.cxx index 36d9f616d..84788b5fd 100644 --- a/src/client/New.cxx +++ b/src/client/New.cxx @@ -12,10 +12,13 @@ #include "net/PeerCredentials.hxx" #include "net/UniqueSocketDescriptor.hxx" #include "net/SocketAddress.hxx" +#include "net/ToString.hxx" #include "util/SpanCast.hxx" #include "Log.hxx" #include "Version.h" +#include <fmt/core.h> + #include <cassert> using std::string_view_literals::operator""sv; @@ -25,27 +28,41 @@ static constexpr auto GREETING = "OK MPD " PROTOCOL_VERSION "\n"sv; Client::Client(EventLoop &_loop, Partition &_partition, UniqueSocketDescriptor _fd, int _uid, unsigned _permission, - int _num) noexcept + std::string &&_name) noexcept :FullyBufferedSocket(_fd.Release(), _loop, 16384, client_max_output_buffer_size), + name(std::move(_name)), timeout_event(_loop, BIND_THIS_METHOD(OnTimeout)), partition(&_partition), permission(_permission), uid(_uid), - num(_num), last_album_art(_loop) { + FmtInfo(client_domain, "[{}] client connected", name); + timeout_event.Schedule(client_timeout); } +[[gnu::pure]] +static std::string +MakeClientName(SocketAddress address, const SocketPeerCredentials &cred) noexcept +{ + if (cred.IsDefined()) { + if (cred.GetPid() > 0) + return fmt::format("pid={} uid={}", cred.GetPid(), cred.GetUid()); + + return fmt::format("uid={}", cred.GetUid()); + } + + return ToString(address); +} + void client_new(EventLoop &loop, Partition &partition, UniqueSocketDescriptor fd, SocketAddress remote_address, SocketPeerCredentials cred, unsigned permission) noexcept { - static unsigned int next_client_num; - assert(fd.IsDefined()); ClientList &client_list = *partition.instance.client_list; @@ -58,16 +75,12 @@ client_new(EventLoop &loop, Partition &partition, const int uid = cred.IsDefined() ? static_cast<int>(cred.GetUid()) : -1; - const unsigned num = next_client_num++; auto *client = new Client(loop, partition, std::move(fd), uid, - permission, - num); + permission, + MakeClientName(remote_address, cred)); client_list.Add(*client); partition.clients.push_back(*client); - - FmtInfo(client_domain, "[{}] opened from {}", - num, remote_address); } void @@ -79,6 +92,6 @@ Client::Close() noexcept if (FullyBufferedSocket::IsDefined()) FullyBufferedSocket::Close(); - FmtInfo(client_domain, "[{}] closed", num); + FmtInfo(client_domain, "[{}] disconnected", name); delete this; } diff --git a/src/client/Process.cxx b/src/client/Process.cxx index 6aa5225d1..3956b3d07 100644 --- a/src/client/Process.cxx +++ b/src/client/Process.cxx @@ -54,14 +54,14 @@ Client::ProcessLine(char *line) noexcept request */ FmtWarning(client_domain, "[{}] malformed command {:?}", - num, line); + name, line); return CommandResult::CLOSE; } if (cmd_list.IsActive() && IsAsyncCommmand(line)) { FmtWarning(client_domain, "[{}] not possible in comand list: {:?}", - num, line); + name, line); return CommandResult::CLOSE; } @@ -82,17 +82,15 @@ Client::ProcessLine(char *line) noexcept except "noidle" */ FmtWarning(client_domain, "[{}] command {:?} during idle", - num, line); + name, line); return CommandResult::CLOSE; } if (cmd_list.IsActive()) { if (StringIsEqual(line, CLIENT_LIST_MODE_END)) { - const unsigned id = num; - FmtDebug(client_domain, "[{}] process command list", - id); + name); const bool ok_mode = cmd_list.IsOKMode(); auto list = cmd_list.Commit(); @@ -102,7 +100,7 @@ Client::ProcessLine(char *line) noexcept std::move(list)); FmtDebug(client_domain, "[{}] process command " - "list returned {}", id, unsigned(ret)); + "list returned {}", name, unsigned(ret)); if (ret == CommandResult::OK) WriteOK(); @@ -113,7 +111,7 @@ Client::ProcessLine(char *line) noexcept FmtWarning(client_domain, "[{}] command list size " "is larger than the max ({})", - num, client_max_command_list_size); + name, client_max_command_list_size); return CommandResult::CLOSE; } @@ -127,15 +125,13 @@ Client::ProcessLine(char *line) noexcept cmd_list.Begin(true); return CommandResult::OK; } else { - const unsigned id = num; - FmtDebug(client_domain, "[{}] process command {:?}", - id, line); + name, line); auto ret = command_process(*this, 0, line); FmtDebug(client_domain, "[{}] command returned {}", - id, unsigned(ret)); + name, unsigned(ret)); if (IsExpired()) return CommandResult::CLOSE;