Skip to content

Commit

Permalink
Fix packet sending
Browse files Browse the repository at this point in the history
  • Loading branch information
janhenke committed Apr 1, 2024
1 parent 93ec897 commit 02b0dfa
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 131 deletions.
17 changes: 11 additions & 6 deletions client/lib/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,19 @@ struct MumbleClient::Impl final {
asio::steady_timer ping_timer;

std::array<std::byte, common::kMaxPacketLength> receive_buffer;
std::array<std::byte, common::kMaxPacketLength> send_buffer;

Impl(std::string_view serverName, uint16_t port, std::string_view userName, bool validateServerCertificate)
: tls_context(asio::ssl::context_base::tlsv13_client), tls_socket(io_context, tls_context),
ping_timer(io_context), receive_buffer() {
ping_timer(io_context), receive_buffer(), send_buffer() {

tls_context.set_default_verify_paths();
tls_socket.set_verify_mode(validateServerCertificate ? asio::ssl::verify_peer : asio::ssl::verify_none);
tls_socket.set_verify_callback(asio::ssl::host_name_verification(std::string{serverName}));

asio::ip::tcp::resolver resolver{io_context};
const auto &endpoints = resolver.resolve(serverName, std::to_string(port));
const std::string service = std::to_string(port);
const auto &endpoints = resolver.resolve(serverName, service);

const auto connectedEndpoint = asio::connect(tls_socket.next_layer(), endpoints);
spdlog::debug("Connected to endpoint: {}, port: {}", connectedEndpoint.address().to_string(),
Expand Down Expand Up @@ -127,7 +129,10 @@ struct MumbleClient::Impl final {
}

void queuePacket(const common::MumbleControlPacket &packet) {
asio::async_write(tls_socket, asio::buffer(packet.Serialize()),

const std::size_t size = packet.Serialize(send_buffer);

asio::async_write(tls_socket, asio::buffer(send_buffer, size),
[](const std::error_code &ec, std::size_t bytes_transferred) {
if (ec) {
spdlog::critical("Error writing to socket: {}", ec.message());
Expand Down Expand Up @@ -155,21 +160,21 @@ struct MumbleClient::Impl final {
static void handleVersionPacket(const std::span<const std::byte> payload) {
common::MumbleVersionPacket versionPacket(payload);

spdlog::debug("Received version packet: \n{}", versionPacket.debugString());
spdlog::debug("Received version packet: \n{}", versionPacket.DebugString());
spdlog::info("Server version {}.{}.{}", versionPacket.majorVersion(), versionPacket.minorVersion(),
versionPacket.patchVersion());
}

static void handlePingPacket(const std::span<const std::byte> payload) {
common::MumblePingPacket pingPacket(payload);

spdlog::debug("Received server ping: \n{}", pingPacket.debugString());
spdlog::debug("Received server ping: \n{}", pingPacket.DebugString());
}

static void handleCryptSetupPacket(const std::span<const std::byte> payload) {
common::MumbleCryptographySetupPacket cryptographySetupPacket(payload);

spdlog::debug("Received crypt setup: \n{}", cryptographySetupPacket.debugString());
spdlog::debug("Received crypt setup: \n{}", cryptographySetupPacket.DebugString());
}
};

Expand Down
98 changes: 49 additions & 49 deletions common/src/packet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,33 @@ namespace libmumble_protocol::common {
std::tuple<PacketType, std::span<const std::byte>>
ParseNetworkBuffer(std::span<const std::byte, kMaxPacketLength> buffer) {

std::uint16_t rawPacketType;
std::uint32_t payloadLength;
std::uint16_t raw_packet_type;
std::uint32_t payload_length;

std::memcpy(&rawPacketType, buffer.data(), sizeof(rawPacketType));
std::memcpy(&payloadLength, buffer.data() + sizeof(rawPacketType), sizeof(payloadLength));
std::memcpy(&raw_packet_type, buffer.data(), sizeof(raw_packet_type));
std::memcpy(&payload_length, buffer.data() + sizeof(raw_packet_type), sizeof(payload_length));

return {static_cast<PacketType>(SwapNetworkBytes(rawPacketType)),
buffer.subspan(kHeaderLength, SwapNetworkBytes(payloadLength))};
return {static_cast<PacketType>(SwapNetworkBytes(raw_packet_type)),
buffer.subspan(kHeaderLength, SwapNetworkBytes(payload_length))};
}

std::vector<std::byte> MumbleControlPacket::Serialize() const {
std::size_t MumbleControlPacket::Serialize(std::span<std::byte, kMaxPacketLength> buffer) const {

const auto &message = this->Message();
const std::size_t payload_bytes = message.ByteSizeLong();
const size_t total_length = kHeaderLength + payload_bytes;
const auto packet_type = SwapNetworkBytes(std::to_underlying(this->PacketType()));
const auto payload_length = SwapNetworkBytes(static_cast<uint32_t>(payload_bytes));

const auto &message = this->message();
const std::size_t payloadBytes = message.ByteSizeLong();
const auto packetType = SwapNetworkBytes(std::to_underlying(this->packetType()));
const auto payloadLength = static_cast<uint32_t>(SwapNetworkBytes(payloadBytes));

std::vector<std::byte> buffer(kHeaderLength + payloadBytes);
std::byte *data = buffer.data();
std::memcpy(data, &packetType, sizeof(packetType));
std::memcpy(data + sizeof(packetType), &payloadLength, sizeof(payloadLength));
message.SerializeToArray(data + kHeaderLength, static_cast<int>(payloadBytes));

return buffer;
std::memcpy(data, &packet_type, sizeof(packet_type));
std::memcpy(data + sizeof(packet_type), &payload_length, sizeof(payload_length));
message.SerializeToArray(data + kHeaderLength, static_cast<int>(payload_bytes));
return total_length;
}

std::string MumbleControlPacket::debugString() const { return message().DebugString(); }
std::string MumbleControlPacket::DebugString() const { return Message().DebugString(); }

/*
* Mumble version_ packet (ID 0)
Expand All @@ -56,19 +56,19 @@ MumbleVersionPacket::MumbleVersionPacket(const std::span<const std::byte> buffer
}

MumbleVersionPacket::MumbleVersionPacket(const MumbleVersion mumble_version, const std::string_view release,
const std::string_view operatingSystem,
const std::string_view operatingSystemVersion)
const std::string_view operating_system,
const std::string_view operating_system_version)
: version_(), mumbleVersion_(mumble_version) {

version_.set_version_v1(static_cast<std::uint32_t>(mumbleVersion_));
version_.set_version_v2(static_cast<std::uint64_t>(mumbleVersion_));
version_.set_release(std::string(release));
version_.set_os(std::string(operatingSystem));
version_.set_os_version(std::string(operatingSystemVersion));
version_.set_os(std::string(operating_system));
version_.set_os_version(std::string(operating_system_version));
}

PacketType MumbleVersionPacket::packetType() const { return PacketType::Version; }
google::protobuf::Message const &MumbleVersionPacket::message() const { return version_; }
PacketType MumbleVersionPacket::PacketType() const { return PacketType::Version; }
google::protobuf::Message const &MumbleVersionPacket::Message() const { return version_; }

/*
* Mumble authenticate packet (ID 2)
Expand All @@ -90,8 +90,8 @@ MumbleAuthenticatePacket::MumbleAuthenticatePacket(std::span<const std::byte> bu
authenticate_.ParseFromArray(buffer.data(), static_cast<int>(bufferSize));
}

PacketType MumbleAuthenticatePacket::packetType() const { return PacketType::Authenticate; }
google::protobuf::Message const &MumbleAuthenticatePacket::message() const { return authenticate_; }
PacketType MumbleAuthenticatePacket::PacketType() const { return PacketType::Authenticate; }
google::protobuf::Message const &MumbleAuthenticatePacket::Message() const { return authenticate_; }

/*
* Mumble ping packet (ID 3)
Expand All @@ -100,55 +100,55 @@ google::protobuf::Message const &MumbleAuthenticatePacket::message() const { ret
MumblePingPacket::MumblePingPacket(std::uint64_t timestamp) { ping_.set_timestamp(timestamp); }

MumblePingPacket::MumblePingPacket(std::uint64_t timestamp, std::uint32_t good, std::uint32_t late, std::uint32_t lost,
std::uint32_t reSync, std::uint32_t udpPackets, std::uint32_t tcpPackets,
float udpPingAverage, float udpPingVariation, float tcpPingAverage,
float tcpPingVariation) {
std::uint32_t re_sync, std::uint32_t udp_packets, std::uint32_t tcp_packets,
float udp_ping_average, float udp_ping_variation, float tcp_ping_average,
float tcp_ping_variation) {
ping_.set_timestamp(timestamp);
ping_.set_good(good);
ping_.set_late(late);
ping_.set_lost(lost);
ping_.set_resync(reSync);
ping_.set_udp_packets(udpPackets);
ping_.set_tcp_packets(tcpPackets);
ping_.set_udp_ping_avg(udpPingAverage);
ping_.set_udp_ping_var(udpPingVariation);
ping_.set_tcp_ping_avg(tcpPingAverage);
ping_.set_tcp_ping_var(tcpPingVariation);
ping_.set_resync(re_sync);
ping_.set_udp_packets(udp_packets);
ping_.set_tcp_packets(tcp_packets);
ping_.set_udp_ping_avg(udp_ping_average);
ping_.set_udp_ping_var(udp_ping_variation);
ping_.set_tcp_ping_avg(tcp_ping_average);
ping_.set_tcp_ping_var(tcp_ping_variation);
}

MumblePingPacket::MumblePingPacket(std::span<const std::byte> buffer) {
const auto bufferSize = std::size(buffer);
ping_.ParseFromArray(buffer.data(), static_cast<int>(bufferSize));
}
PacketType MumblePingPacket::packetType() const { return PacketType::Ping; }
const google::protobuf::Message &MumblePingPacket::message() const { return ping_; }
PacketType MumblePingPacket::PacketType() const { return PacketType::Ping; }
const google::protobuf::Message &MumblePingPacket::Message() const { return ping_; }

/*
* Mumble crypt setup packet (ID 15)
*/

MumbleCryptographySetupPacket::MumbleCryptographySetupPacket(std::span<const std::byte> &key,
std::span<const std::byte> &clientNonce,
std::span<const std::byte> &serverNonce) {
std::span<const std::byte> &client_nonce,
std::span<const std::byte> &server_nonce) {
if (!key.empty()) {
std::string container;
const auto count = std::size(key);
container.reserve(count);
std::memcpy(container.data(), key.data(), count);
cryptSetup_.set_key(container);
}
if (!clientNonce.empty()) {
if (!client_nonce.empty()) {
std::string container;
const auto count = std::size(clientNonce);
const auto count = std::size(client_nonce);
container.reserve(count);
std::memcpy(container.data(), clientNonce.data(), count);
std::memcpy(container.data(), client_nonce.data(), count);
cryptSetup_.set_key(container);
}
if (!serverNonce.empty()) {
if (!server_nonce.empty()) {
std::string container;
const auto count = std::size(serverNonce);
const auto count = std::size(server_nonce);
container.reserve(count);
std::memcpy(container.data(), serverNonce.data(), count);
std::memcpy(container.data(), server_nonce.data(), count);
cryptSetup_.set_key(container);
}
}
Expand All @@ -158,7 +158,7 @@ MumbleCryptographySetupPacket::MumbleCryptographySetupPacket(std::span<const std
cryptSetup_.ParseFromArray(buffer.data(), static_cast<int>(bufferSize));
}

PacketType MumbleCryptographySetupPacket::packetType() const { return PacketType::CryptSetup; }
const google::protobuf::Message &MumbleCryptographySetupPacket::message() const { return cryptSetup_; }
PacketType MumbleCryptographySetupPacket::PacketType() const { return PacketType::CryptSetup; }
const google::protobuf::Message &MumbleCryptographySetupPacket::Message() const { return cryptSetup_; }

}// namespace libmumble_protocol::common
43 changes: 25 additions & 18 deletions common/src/packet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ class MUMBLE_PROTOCOL_COMMON_EXPORT MumbleControlPacket {
public:
virtual ~MumbleControlPacket() = default;

[[nodiscard]] std::vector<std::byte> Serialize() const;
[[nodiscard]] std::size_t Serialize(std::span<std::byte, kMaxPacketLength>) const;

[[nodiscard]] std::string debugString() const;
[[nodiscard]] std::string DebugString() const;

protected:
[[nodiscard]] virtual PacketType packetType() const = 0;
[[nodiscard]] virtual PacketType PacketType() const = 0;

[[nodiscard]] virtual google::protobuf::Message const &message() const = 0;
[[nodiscard]] virtual google::protobuf::Message const &Message() const = 0;
};

//
Expand Down Expand Up @@ -136,8 +136,8 @@ class MumbleVersion {

class MUMBLE_PROTOCOL_COMMON_EXPORT MumbleVersionPacket : public MumbleControlPacket {
public:
MumbleVersionPacket(MumbleVersion mumble_version, std::string_view release, std::string_view operatingSystem,
std::string_view operatingSystemVersion);
MumbleVersionPacket(MumbleVersion mumble_version, std::string_view release, std::string_view operating_system,
std::string_view operating_system_version);

explicit MumbleVersionPacket(std::span<const std::byte>);

Expand All @@ -156,9 +156,9 @@ class MUMBLE_PROTOCOL_COMMON_EXPORT MumbleVersionPacket : public MumbleControlPa
std::string_view operatingSystemVersion() const { return version_.os_version(); }

protected:
PacketType packetType() const override;
enum PacketType PacketType() const override;

google::protobuf::Message const &message() const override;
google::protobuf::Message const &Message() const override;

private:
MumbleProto::Version version_;
Expand Down Expand Up @@ -195,9 +195,9 @@ class MUMBLE_PROTOCOL_COMMON_EXPORT MumbleAuthenticatePacket : public MumbleCont
bool opusSupported() const { return authenticate_.opus(); }

protected:
PacketType packetType() const override;
enum PacketType PacketType() const override;

google::protobuf::Message const &message() const override;
google::protobuf::Message const &Message() const override;

private:
MumbleProto::Authenticate authenticate_;
Expand All @@ -208,24 +208,24 @@ class MUMBLE_PROTOCOL_COMMON_EXPORT MumblePingPacket : public MumbleControlPacke
explicit MumblePingPacket(std::uint64_t);

MumblePingPacket(std::uint64_t timestamp, std::uint32_t good, std::uint32_t late, std::uint32_t lost,
std::uint32_t reSync, std::uint32_t udpPackets, std::uint32_t tcpPackets, float udpPingAverage,
float udpPingVariation, float tcpPingAverage, float tcpPingVariation);
std::uint32_t re_sync, std::uint32_t udp_packets, std::uint32_t tcp_packets, float udp_ping_average,
float udp_ping_variation, float tcp_ping_average, float tcp_ping_variation);

explicit MumblePingPacket(std::span<const std::byte>);

protected:
PacketType packetType() const override;
enum PacketType PacketType() const override;

const google::protobuf::Message &message() const override;
const google::protobuf::Message &Message() const override;

private:
MumbleProto::Ping ping_;
};

class MumbleCryptographySetupPacket : public MumbleControlPacket {
public:
MumbleCryptographySetupPacket(std::span<const std::byte> &key, std::span<const std::byte> &clientNonce,
std::span<const std::byte> &serverNonce);
MumbleCryptographySetupPacket(std::span<const std::byte> &key, std::span<const std::byte> &client_nonce,
std::span<const std::byte> &server_nonce);

explicit MumbleCryptographySetupPacket(std::span<const std::byte>);

Expand All @@ -236,12 +236,19 @@ class MumbleCryptographySetupPacket : public MumbleControlPacket {
std::span<const std::byte> serverNonce() const { return as_bytes(std::span(cryptSetup_.server_nonce())); }

protected:
PacketType packetType() const override;
enum PacketType PacketType() const override;

const google::protobuf::Message &message() const override;
const google::protobuf::Message &Message() const override;

private:
MumbleProto::CryptSetup cryptSetup_;
};

}// namespace libmumble_protocol::common

template<>
struct std::formatter<libmumble_protocol::common::PacketType> : public std::formatter<std::uint16_t> {
auto format(const libmumble_protocol::common::PacketType &packet_type, std::format_context &ctx) const {
return std::formatter<std::uint16_t>::format(static_cast<uint16_t>(packet_type), ctx);
}
};
24 changes: 0 additions & 24 deletions example/CMakeLists.txt

This file was deleted.

Loading

0 comments on commit 02b0dfa

Please sign in to comment.