mirror of
https://github.com/badaix/snapcast.git
synced 2025-08-01 15:49:56 +02:00
Authentication for streaming clients
This commit is contained in:
parent
67fd20619d
commit
02b8033728
20 changed files with 302 additions and 132 deletions
|
@ -1,6 +1,6 @@
|
|||
/***
|
||||
This file is part of snapcast
|
||||
Copyright (C) 2014-2024 Johannes Pohl
|
||||
Copyright (C) 2014-2025 Johannes Pohl
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,6 +20,7 @@
|
|||
|
||||
|
||||
// local headers
|
||||
#include "authinfo.hpp"
|
||||
#include "common/message/message.hpp"
|
||||
#include "streamreader/stream_manager.hpp"
|
||||
|
||||
|
@ -40,29 +41,35 @@
|
|||
|
||||
class StreamSession;
|
||||
|
||||
/// Write result callback function type
|
||||
using WriteHandler = std::function<void(boost::system::error_code ec, std::size_t length)>;
|
||||
|
||||
/// Interface: callback for a received message.
|
||||
class StreamMessageReceiver
|
||||
{
|
||||
public:
|
||||
virtual void onMessageReceived(StreamSession* connection, const msg::BaseMessage& baseMessage, char* buffer) = 0;
|
||||
/// message received callback
|
||||
virtual void onMessageReceived(const std::shared_ptr<StreamSession>& connection, const msg::BaseMessage& baseMessage, char* buffer) = 0;
|
||||
/// disonnect callback
|
||||
virtual void onDisconnect(StreamSession* connection) = 0;
|
||||
};
|
||||
|
||||
|
||||
// A reference-counted non-modifiable buffer class.
|
||||
/// A reference-counted non-modifiable buffer class.
|
||||
class shared_const_buffer
|
||||
{
|
||||
/// the message
|
||||
struct Message
|
||||
{
|
||||
std::vector<char> data;
|
||||
bool is_pcm_chunk;
|
||||
message_type type;
|
||||
chronos::time_point_clk rec_time;
|
||||
std::vector<char> data; ///< data
|
||||
bool is_pcm_chunk; ///< is it a PCM chunk
|
||||
message_type type; ///< message type
|
||||
chronos::time_point_clk rec_time; ///< recording time
|
||||
};
|
||||
|
||||
public:
|
||||
shared_const_buffer(msg::BaseMessage& message) : on_air(false)
|
||||
/// c'tor
|
||||
explicit shared_const_buffer(msg::BaseMessage& message)
|
||||
{
|
||||
tv t;
|
||||
message.sent = t;
|
||||
|
@ -83,32 +90,47 @@ public:
|
|||
// Implement the ConstBufferSequence requirements.
|
||||
using value_type = boost::asio::const_buffer;
|
||||
using const_iterator = const boost::asio::const_buffer*;
|
||||
|
||||
/// begin iterator
|
||||
const boost::asio::const_buffer* begin() const
|
||||
{
|
||||
return &buffer_;
|
||||
}
|
||||
|
||||
/// end iterator
|
||||
const boost::asio::const_buffer* end() const
|
||||
{
|
||||
return &buffer_ + 1;
|
||||
}
|
||||
|
||||
/// the payload
|
||||
const Message& message() const
|
||||
{
|
||||
return *message_;
|
||||
}
|
||||
|
||||
bool on_air;
|
||||
/// set write callback
|
||||
void setWriteHandler(WriteHandler&& handler)
|
||||
{
|
||||
handler_ = std::move(handler);
|
||||
}
|
||||
|
||||
/// get write callback
|
||||
const WriteHandler& getWriteHandler() const
|
||||
{
|
||||
return handler_;
|
||||
}
|
||||
|
||||
/// is the buffer sent?
|
||||
bool on_air{false};
|
||||
|
||||
private:
|
||||
std::shared_ptr<Message> message_;
|
||||
boost::asio::const_buffer buffer_;
|
||||
WriteHandler handler_;
|
||||
};
|
||||
|
||||
|
||||
/// Write result callback function type
|
||||
using WriteHandler = std::function<void(boost::system::error_code ec, std::size_t length)>;
|
||||
|
||||
/// Endpoint for a connected client.
|
||||
/**
|
||||
* Endpoint for a connected client.
|
||||
|
@ -119,7 +141,7 @@ class StreamSession : public std::enable_shared_from_this<StreamSession>
|
|||
{
|
||||
public:
|
||||
/// c'tor. Received message from the client are passed to StreamMessageReceiver
|
||||
StreamSession(const boost::asio::any_io_executor& executor, StreamMessageReceiver* receiver);
|
||||
StreamSession(const boost::asio::any_io_executor& executor, const ServerSettings& server_settings, StreamMessageReceiver* receiver);
|
||||
/// d'tor
|
||||
virtual ~StreamSession() = default;
|
||||
|
||||
|
@ -139,33 +161,40 @@ public:
|
|||
|
||||
protected:
|
||||
/// Send data @p buffer to the streaming client, result is returned in the callback @p handler
|
||||
virtual void sendAsync(const shared_const_buffer& buffer, const WriteHandler& handler) = 0;
|
||||
virtual void sendAsync(const shared_const_buffer& buffer, WriteHandler&& handler) = 0;
|
||||
|
||||
public:
|
||||
/// Sends a message to the client (asynchronous)
|
||||
void send(msg::message_ptr message);
|
||||
void send(const msg::message_ptr& message, WriteHandler&& handler = nullptr);
|
||||
|
||||
/// Sends a message to the client (asynchronous)
|
||||
void send(shared_const_buffer const_buf);
|
||||
void send(shared_const_buffer const_buf, WriteHandler&& handler = nullptr);
|
||||
|
||||
/// Max playout latency. No need to send PCM data that is older than bufferMs
|
||||
void setBufferMs(size_t bufferMs);
|
||||
|
||||
/// Client id of the session
|
||||
std::string clientId;
|
||||
|
||||
/// Set the sessions PCM stream
|
||||
void setPcmStream(streamreader::PcmStreamPtr pcmStream);
|
||||
/// Get the sessions PCM stream
|
||||
const streamreader::PcmStreamPtr pcmStream() const;
|
||||
|
||||
protected:
|
||||
void send_next();
|
||||
/// Authentication info attached to this session
|
||||
AuthInfo authinfo;
|
||||
|
||||
msg::BaseMessage baseMessage_;
|
||||
std::vector<char> buffer_;
|
||||
size_t base_msg_size_;
|
||||
StreamMessageReceiver* messageReceiver_;
|
||||
size_t bufferMs_;
|
||||
streamreader::PcmStreamPtr pcmStream_;
|
||||
boost::asio::strand<boost::asio::any_io_executor> strand_;
|
||||
std::deque<shared_const_buffer> messages_;
|
||||
mutable std::mutex mutex_;
|
||||
protected:
|
||||
/// Send next message from "messages_"
|
||||
void sendNext();
|
||||
|
||||
msg::BaseMessage baseMessage_; ///< base message buffer
|
||||
std::vector<char> buffer_; ///< buffer
|
||||
size_t base_msg_size_; ///< size of a base message
|
||||
StreamMessageReceiver* messageReceiver_; ///< message receiver
|
||||
size_t bufferMs_; ///< buffer size in [ms]
|
||||
streamreader::PcmStreamPtr pcm_stream_; ///< the sessions PCM stream
|
||||
boost::asio::strand<boost::asio::any_io_executor> strand_; ///< strand to sync IO on
|
||||
std::deque<shared_const_buffer> messages_; ///< messages to be sent
|
||||
mutable std::mutex mutex_; ///< protect pcm_stream_
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue