mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-29 18:27:31 +02:00
CI: fixing the files to be complient with pre-commit hooks
This commit is contained in:
@ -1,10 +1,11 @@
|
||||
from esp_docs.conf_docs import * # noqa: F403,F401
|
||||
|
||||
extensions += ['sphinx_copybutton',
|
||||
# Needed as a trigger for running doxygen
|
||||
'esp_docs.esp_extensions.dummy_build_system',
|
||||
'esp_docs.esp_extensions.run_doxygen',
|
||||
]
|
||||
extensions += [
|
||||
'sphinx_copybutton',
|
||||
# Needed as a trigger for running doxygen
|
||||
'esp_docs.esp_extensions.dummy_build_system',
|
||||
'esp_docs.esp_extensions.run_doxygen',
|
||||
]
|
||||
|
||||
# link roles config
|
||||
github_repo = 'espressif/esp-protocols'
|
||||
@ -14,7 +15,7 @@ html_context['github_user'] = 'espressif'
|
||||
html_context['github_repo'] = 'esp-protocols'
|
||||
|
||||
# Extra options required by sphinx_idf_theme
|
||||
project_slug = 'esp-idf' # >=5.0
|
||||
project_slug = 'esp-idf' # >=5.0
|
||||
versions_url = 'https://github.com/espressif/esp-protocols/docs/docs_versions.js'
|
||||
|
||||
idf_targets = ['esp32']
|
||||
|
@ -13,7 +13,7 @@ window.onload =(function() {
|
||||
mySpan.value = 'latest';
|
||||
mySpan.setAttribute('disabled', true);
|
||||
myAnchor.parentNode.replaceChild(mySpan, myAnchor);
|
||||
|
||||
|
||||
var myAnchor = document.getElementById('target-select');
|
||||
var mySpan = document.createElement('input');
|
||||
mySpan.setAttribute('type', 'text');
|
||||
@ -24,4 +24,3 @@ window.onload =(function() {
|
||||
|
||||
})();
|
||||
</script>" >> html/index.html
|
||||
|
||||
|
@ -1 +1 @@
|
||||
.. include:: ../../../en/api-reference/protocols/asio.rst
|
||||
.. include:: ../../../en/api-reference/protocols/asio.rst
|
||||
|
@ -53,14 +53,15 @@ void start_client(void)
|
||||
#ifdef CONFIG_EXAMPLE_CHAT_SERVER
|
||||
std::lock_guard<std::mutex> guard(server_ready);
|
||||
#endif
|
||||
std::thread t([&io_context]() { try {
|
||||
io_context.run();
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGE(TAG, "Exception occured during client thread execution %s", e.what());
|
||||
}
|
||||
catch (...) {
|
||||
ESP_LOGE(TAG, "Unknown exception");
|
||||
}});
|
||||
std::thread t([&io_context]() {
|
||||
try {
|
||||
io_context.run();
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGE(TAG, "Exception occured during client thread execution %s", e.what());
|
||||
} catch (...) {
|
||||
ESP_LOGE(TAG, "Unknown exception");
|
||||
}
|
||||
});
|
||||
do {
|
||||
ESP_LOGI(TAG, "CLIENT: Waiting for input");
|
||||
get_string(line, sizeof(line));
|
||||
@ -95,14 +96,14 @@ extern "C" void app_main(void)
|
||||
asio::io_context io_context;
|
||||
chat_server server(io_context, tcp::endpoint(tcp::v4(), std::atoi(CONFIG_EXAMPLE_CHAT_SERVER_BIND_PORT)));
|
||||
std::thread t = std::thread([&io_context]() { // Chat server starting here
|
||||
try {
|
||||
io_context.run();
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGE(TAG, "Exception occured during server thread execution %s", e.what());
|
||||
}
|
||||
catch (...) {
|
||||
ESP_LOGE(TAG, "Unknown exception");
|
||||
}});;
|
||||
try {
|
||||
io_context.run();
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGE(TAG, "Exception occured during server thread execution %s", e.what());
|
||||
} catch (...) {
|
||||
ESP_LOGE(TAG, "Unknown exception");
|
||||
}
|
||||
});;
|
||||
#endif
|
||||
#ifdef CONFIG_EXAMPLE_CHAT_CLIENT
|
||||
start_client();
|
||||
|
@ -15,77 +15,76 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
class chat_message
|
||||
{
|
||||
class chat_message {
|
||||
public:
|
||||
static constexpr std::size_t header_length = 4;
|
||||
static constexpr std::size_t max_body_length = 512;
|
||||
static constexpr std::size_t header_length = 4;
|
||||
static constexpr std::size_t max_body_length = 512;
|
||||
|
||||
chat_message()
|
||||
: body_length_(0)
|
||||
{
|
||||
}
|
||||
|
||||
const char* data() const
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
char* data()
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
std::size_t length() const
|
||||
{
|
||||
return header_length + body_length_;
|
||||
}
|
||||
|
||||
const char* body() const
|
||||
{
|
||||
return data_ + header_length;
|
||||
}
|
||||
|
||||
char* body()
|
||||
{
|
||||
return data_ + header_length;
|
||||
}
|
||||
|
||||
std::size_t body_length() const
|
||||
{
|
||||
return body_length_;
|
||||
}
|
||||
|
||||
void body_length(std::size_t new_length)
|
||||
{
|
||||
body_length_ = new_length;
|
||||
if (body_length_ > max_body_length)
|
||||
body_length_ = max_body_length;
|
||||
}
|
||||
|
||||
bool decode_header()
|
||||
{
|
||||
char header[header_length + 1] = "";
|
||||
std::strncat(header, data_, header_length);
|
||||
body_length_ = std::atoi(header);
|
||||
if (body_length_ > max_body_length)
|
||||
chat_message()
|
||||
: body_length_(0)
|
||||
{
|
||||
body_length_ = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void encode_header()
|
||||
{
|
||||
char header[header_length + 1] = "";
|
||||
std::sprintf(header, "%4d", static_cast<int>(body_length_));
|
||||
std::memcpy(data_, header, header_length);
|
||||
}
|
||||
const char *data() const
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
char *data()
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
std::size_t length() const
|
||||
{
|
||||
return header_length + body_length_;
|
||||
}
|
||||
|
||||
const char *body() const
|
||||
{
|
||||
return data_ + header_length;
|
||||
}
|
||||
|
||||
char *body()
|
||||
{
|
||||
return data_ + header_length;
|
||||
}
|
||||
|
||||
std::size_t body_length() const
|
||||
{
|
||||
return body_length_;
|
||||
}
|
||||
|
||||
void body_length(std::size_t new_length)
|
||||
{
|
||||
body_length_ = new_length;
|
||||
if (body_length_ > max_body_length) {
|
||||
body_length_ = max_body_length;
|
||||
}
|
||||
}
|
||||
|
||||
bool decode_header()
|
||||
{
|
||||
char header[header_length + 1] = "";
|
||||
std::strncat(header, data_, header_length);
|
||||
body_length_ = std::atoi(header);
|
||||
if (body_length_ > max_body_length) {
|
||||
body_length_ = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void encode_header()
|
||||
{
|
||||
char header[header_length + 1] = "";
|
||||
std::sprintf(header, "%4d", static_cast<int>(body_length_));
|
||||
std::memcpy(data_, header, header_length);
|
||||
}
|
||||
|
||||
private:
|
||||
char data_[header_length + max_body_length];
|
||||
std::size_t body_length_;
|
||||
char data_[header_length + max_body_length];
|
||||
std::size_t body_length_;
|
||||
};
|
||||
|
||||
#endif // CHAT_MESSAGE_HPP
|
||||
|
@ -17,107 +17,91 @@
|
||||
|
||||
typedef std::deque<chat_message> chat_message_queue;
|
||||
|
||||
class chat_client
|
||||
{
|
||||
class chat_client {
|
||||
public:
|
||||
chat_client(asio::io_context& io_context,
|
||||
const asio::ip::tcp::resolver::results_type& endpoints)
|
||||
: io_context_(io_context),
|
||||
socket_(io_context)
|
||||
{
|
||||
do_connect(endpoints);
|
||||
}
|
||||
chat_client(asio::io_context &io_context,
|
||||
const asio::ip::tcp::resolver::results_type &endpoints)
|
||||
: io_context_(io_context),
|
||||
socket_(io_context)
|
||||
{
|
||||
do_connect(endpoints);
|
||||
}
|
||||
|
||||
void write(const chat_message& msg)
|
||||
{
|
||||
asio::post(io_context_,
|
||||
[this, msg]()
|
||||
{
|
||||
bool write_in_progress = !write_msgs_.empty();
|
||||
write_msgs_.push_back(msg);
|
||||
if (!write_in_progress)
|
||||
{
|
||||
do_write();
|
||||
}
|
||||
void write(const chat_message &msg)
|
||||
{
|
||||
asio::post(io_context_,
|
||||
[this, msg]() {
|
||||
bool write_in_progress = !write_msgs_.empty();
|
||||
write_msgs_.push_back(msg);
|
||||
if (!write_in_progress) {
|
||||
do_write();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
asio::post(io_context_, [this]() { socket_.close(); });
|
||||
}
|
||||
void close()
|
||||
{
|
||||
asio::post(io_context_, [this]() {
|
||||
socket_.close();
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
void do_connect(const asio::ip::tcp::resolver::results_type& endpoints)
|
||||
void do_connect(const asio::ip::tcp::resolver::results_type &endpoints)
|
||||
{
|
||||
asio::async_connect(socket_, endpoints,
|
||||
[this](std::error_code ec, asio::ip::tcp::endpoint)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
do_read_header();
|
||||
asio::async_connect(socket_, endpoints,
|
||||
[this](std::error_code ec, asio::ip::tcp::endpoint) {
|
||||
if (!ec) {
|
||||
do_read_header();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void do_read_header()
|
||||
{
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.data(), chat_message::header_length),
|
||||
[this](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec && read_msg_.decode_header())
|
||||
{
|
||||
do_read_body();
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.data(), chat_message::header_length),
|
||||
[this](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec && read_msg_.decode_header()) {
|
||||
do_read_body();
|
||||
} else {
|
||||
socket_.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
socket_.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void do_read_body()
|
||||
{
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.body(), read_msg_.body_length()),
|
||||
[this](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
do_read_header();
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.body(), read_msg_.body_length()),
|
||||
[this](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
do_read_header();
|
||||
} else {
|
||||
socket_.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
socket_.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void do_write()
|
||||
{
|
||||
asio::async_write(socket_,
|
||||
asio::buffer(write_msgs_.front().data(),
|
||||
write_msgs_.front().length()),
|
||||
[this](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
write_msgs_.pop_front();
|
||||
if (!write_msgs_.empty())
|
||||
{
|
||||
do_write();
|
||||
}
|
||||
void do_write()
|
||||
{
|
||||
asio::async_write(socket_,
|
||||
asio::buffer(write_msgs_.front().data(),
|
||||
write_msgs_.front().length()),
|
||||
[this](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
write_msgs_.pop_front();
|
||||
if (!write_msgs_.empty()) {
|
||||
do_write();
|
||||
}
|
||||
} else {
|
||||
socket_.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
socket_.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
asio::io_context& io_context_;
|
||||
asio::io_context &io_context_;
|
||||
asio::ip::tcp::socket socket_;
|
||||
chat_message read_msg_;
|
||||
chat_message_queue write_msgs_;
|
||||
|
@ -27,176 +27,159 @@ extern std::mutex server_ready;
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
||||
class chat_participant
|
||||
{
|
||||
class chat_participant {
|
||||
public:
|
||||
virtual ~chat_participant() {}
|
||||
virtual void deliver(const chat_message& msg) = 0;
|
||||
virtual ~chat_participant() {}
|
||||
virtual void deliver(const chat_message &msg) = 0;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<chat_participant> chat_participant_ptr;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class chat_room
|
||||
{
|
||||
class chat_room {
|
||||
public:
|
||||
void join(chat_participant_ptr participant)
|
||||
{
|
||||
participants_.insert(participant);
|
||||
for (auto msg: recent_msgs_)
|
||||
participant->deliver(msg);
|
||||
}
|
||||
void join(chat_participant_ptr participant)
|
||||
{
|
||||
participants_.insert(participant);
|
||||
for (auto msg : recent_msgs_) {
|
||||
participant->deliver(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void leave(chat_participant_ptr participant)
|
||||
{
|
||||
participants_.erase(participant);
|
||||
}
|
||||
void leave(chat_participant_ptr participant)
|
||||
{
|
||||
participants_.erase(participant);
|
||||
}
|
||||
|
||||
void deliver(const chat_message& msg)
|
||||
{
|
||||
recent_msgs_.push_back(msg);
|
||||
while (recent_msgs_.size() > max_recent_msgs)
|
||||
recent_msgs_.pop_front();
|
||||
void deliver(const chat_message &msg)
|
||||
{
|
||||
recent_msgs_.push_back(msg);
|
||||
while (recent_msgs_.size() > max_recent_msgs) {
|
||||
recent_msgs_.pop_front();
|
||||
}
|
||||
|
||||
for (auto participant: participants_)
|
||||
participant->deliver(msg);
|
||||
}
|
||||
for (auto participant : participants_) {
|
||||
participant->deliver(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<chat_participant_ptr> participants_;
|
||||
enum { max_recent_msgs = 100 };
|
||||
chat_message_queue recent_msgs_;
|
||||
std::set<chat_participant_ptr> participants_;
|
||||
enum { max_recent_msgs = 100 };
|
||||
chat_message_queue recent_msgs_;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
||||
class chat_session
|
||||
: public chat_participant,
|
||||
public std::enable_shared_from_this<chat_session>
|
||||
{
|
||||
: public chat_participant,
|
||||
public std::enable_shared_from_this<chat_session> {
|
||||
public:
|
||||
chat_session(asio::ip::tcp::socket socket, chat_room& room)
|
||||
: socket_(std::move(socket)),
|
||||
room_(room)
|
||||
{
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
room_.join(shared_from_this());
|
||||
do_read_header();
|
||||
}
|
||||
|
||||
void deliver(const chat_message& msg)
|
||||
{
|
||||
bool write_in_progress = !write_msgs_.empty();
|
||||
write_msgs_.push_back(msg);
|
||||
if (!write_in_progress)
|
||||
chat_session(asio::ip::tcp::socket socket, chat_room &room)
|
||||
: socket_(std::move(socket)),
|
||||
room_(room)
|
||||
{
|
||||
do_write();
|
||||
}
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
room_.join(shared_from_this());
|
||||
do_read_header();
|
||||
}
|
||||
|
||||
void deliver(const chat_message &msg)
|
||||
{
|
||||
bool write_in_progress = !write_msgs_.empty();
|
||||
write_msgs_.push_back(msg);
|
||||
if (!write_in_progress) {
|
||||
do_write();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void do_read_header()
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.data(), chat_message::header_length),
|
||||
[this, self](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec && read_msg_.decode_header())
|
||||
{
|
||||
do_read_body();
|
||||
}
|
||||
else
|
||||
{
|
||||
room_.leave(shared_from_this());
|
||||
}
|
||||
});
|
||||
}
|
||||
void do_read_header()
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.data(), chat_message::header_length),
|
||||
[this, self](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec && read_msg_.decode_header()) {
|
||||
do_read_body();
|
||||
} else {
|
||||
room_.leave(shared_from_this());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void do_read_body()
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.body(), read_msg_.body_length()),
|
||||
[this, self](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
ESP_LOGD("asio-chat:", "%s", read_msg_.body());
|
||||
room_.deliver(read_msg_);
|
||||
do_read_header();
|
||||
}
|
||||
else
|
||||
{
|
||||
room_.leave(shared_from_this());
|
||||
}
|
||||
});
|
||||
}
|
||||
void do_read_body()
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
asio::async_read(socket_,
|
||||
asio::buffer(read_msg_.body(), read_msg_.body_length()),
|
||||
[this, self](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
ESP_LOGD("asio-chat:", "%s", read_msg_.body());
|
||||
room_.deliver(read_msg_);
|
||||
do_read_header();
|
||||
} else {
|
||||
room_.leave(shared_from_this());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void do_write()
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
asio::async_write(socket_,
|
||||
asio::buffer(write_msgs_.front().data(),
|
||||
write_msgs_.front().length()),
|
||||
[this, self](std::error_code ec, std::size_t /*length*/)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
write_msgs_.pop_front();
|
||||
if (!write_msgs_.empty())
|
||||
{
|
||||
do_write();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
room_.leave(shared_from_this());
|
||||
}
|
||||
});
|
||||
}
|
||||
void do_write()
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
asio::async_write(socket_,
|
||||
asio::buffer(write_msgs_.front().data(),
|
||||
write_msgs_.front().length()),
|
||||
[this, self](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
write_msgs_.pop_front();
|
||||
if (!write_msgs_.empty()) {
|
||||
do_write();
|
||||
}
|
||||
} else {
|
||||
room_.leave(shared_from_this());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
asio::ip::tcp::socket socket_;
|
||||
chat_room& room_;
|
||||
chat_message read_msg_;
|
||||
chat_message_queue write_msgs_;
|
||||
};
|
||||
asio::ip::tcp::socket socket_;
|
||||
chat_room &room_;
|
||||
chat_message read_msg_;
|
||||
chat_message_queue write_msgs_;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class chat_server
|
||||
{
|
||||
class chat_server {
|
||||
public:
|
||||
chat_server(asio::io_context& io_context,
|
||||
const asio::ip::tcp::endpoint& endpoint)
|
||||
: acceptor_(io_context, endpoint)
|
||||
{
|
||||
do_accept();
|
||||
}
|
||||
chat_server(asio::io_context &io_context,
|
||||
const asio::ip::tcp::endpoint &endpoint)
|
||||
: acceptor_(io_context, endpoint)
|
||||
{
|
||||
do_accept();
|
||||
}
|
||||
|
||||
private:
|
||||
void do_accept()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(server_ready);
|
||||
acceptor_.async_accept(
|
||||
[this](std::error_code ec, asio::ip::tcp::socket socket)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
std::make_shared<chat_session>(std::move(socket), room_)->start();
|
||||
}
|
||||
void do_accept()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(server_ready);
|
||||
acceptor_.async_accept(
|
||||
[this](std::error_code ec, asio::ip::tcp::socket socket) {
|
||||
if (!ec) {
|
||||
std::make_shared<chat_session>(std::move(socket), room_)->start();
|
||||
}
|
||||
|
||||
do_accept();
|
||||
});
|
||||
}
|
||||
do_accept();
|
||||
});
|
||||
}
|
||||
|
||||
asio::ip::tcp::acceptor acceptor_;
|
||||
chat_room room_;
|
||||
asio::ip::tcp::acceptor acceptor_;
|
||||
chat_room room_;
|
||||
};
|
||||
|
||||
#endif // CHAT_SERVER_HPP
|
||||
|
@ -1,14 +1,9 @@
|
||||
# This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
# Unless required by applicable law or agreed to in writing, this
|
||||
# software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, either express or implied.
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import re
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
def test_examples_asio_chat(dut):
|
@ -9,7 +9,7 @@ The application aims to show how to compose async operations using ASIO to build
|
||||
|
||||
# Configure and Building example
|
||||
|
||||
This example doesn't require any configuration, just build it with
|
||||
This example doesn't require any configuration, just build it with
|
||||
|
||||
```
|
||||
idf.py build
|
||||
@ -17,12 +17,12 @@ idf.py build
|
||||
|
||||
# Async operations composition and automatic lifetime control
|
||||
|
||||
On this example we compose the operation by starting the next step in the chain inside the completion handler of the
|
||||
previous operation. Also we pass the `Connection` class itself as the parameter of its final handler to be owned by
|
||||
On this example we compose the operation by starting the next step in the chain inside the completion handler of the
|
||||
previous operation. Also we pass the `Connection` class itself as the parameter of its final handler to be owned by
|
||||
the following operation. This is possible due to the control of lifetime by the usage of `std::shared_ptr`.
|
||||
|
||||
The control of lifetime of the class, done by `std::shared_ptr` usage, guarantee that the data will be available for
|
||||
async operations until it's not needed any more. This makes necessary that all of the async operation class must start
|
||||
The control of lifetime of the class, done by `std::shared_ptr` usage, guarantee that the data will be available for
|
||||
async operations until it's not needed any more. This makes necessary that all of the async operation class must start
|
||||
its lifetime as a `std::shared_ptr` due to the usage of `std::enable_shared_from_this`.
|
||||
|
||||
|
||||
@ -48,5 +48,5 @@ its lifetime as a `std::shared_ptr` due to the usage of `std::enable_shared_from
|
||||
└────►Completion Handler()
|
||||
|
||||
|
||||
The previous diagram shows the process and the life span of each of the tasks in this examples. At each stage the
|
||||
The previous diagram shows the process and the life span of each of the tasks in this examples. At each stage the
|
||||
object responsible for the last action inject itself to the completion handler of the next stage for reuse.
|
||||
|
@ -5,64 +5,64 @@
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
The application aims to show how to connect to a Socks4 proxy using async operations with ASIO. The SOCKS protocol is
|
||||
briefly described by the diagram below.
|
||||
The application aims to show how to connect to a Socks4 proxy using async operations with ASIO. The SOCKS protocol is
|
||||
briefly described by the diagram below.
|
||||
|
||||
┌──────┐ ┌─────┐ ┌──────┐
|
||||
│Client│ │Proxy│ │Target│
|
||||
└──┬───┘ └──┬──┘ └──┬───┘
|
||||
│ │ │
|
||||
│ ╔═╧══════════════╗ │
|
||||
┌──────┐ ┌─────┐ ┌──────┐
|
||||
│Client│ │Proxy│ │Target│
|
||||
└──┬───┘ └──┬──┘ └──┬───┘
|
||||
│ │ │
|
||||
│ ╔═╧══════════════╗ │
|
||||
══════════════════════╪════════════════════════╣ Initialization ╠═══╪════════════════════════════════════════════
|
||||
│ ╚═╤══════════════╝ │
|
||||
│ │ │
|
||||
╔══════════════════╗│ │ │
|
||||
║We establish a ░║│ Socket Connection │ │
|
||||
║TCP connection ║│ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ > │
|
||||
║and get a socket ║│ │ │
|
||||
╚══════════════════╝│ │ │
|
||||
│ │ │
|
||||
│ ╔═╧══════════════╗ │
|
||||
│ ╚═╤══════════════╝ │
|
||||
│ │ │
|
||||
╔══════════════════╗│ │ │
|
||||
║We establish a ░║│ Socket Connection │ │
|
||||
║TCP connection ║│ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ > │
|
||||
║and get a socket ║│ │ │
|
||||
╚══════════════════╝│ │ │
|
||||
│ │ │
|
||||
│ ╔═╧══════════════╗ │
|
||||
══════════════════════╪════════════════════════╣ Socks Protocol ╠═══╪════════════════════════════════════════════
|
||||
│ ╚═╤══════════════╝ │
|
||||
│ │ │
|
||||
│ Client Connection Request│ │
|
||||
│ ─────────────────────────> │
|
||||
│ │ │
|
||||
│ │ │
|
||||
│ ╔════════════╪═══════╤══════════╪════════════════════════════════╗
|
||||
│ ║ TARGET CONNECTION │ │ ║
|
||||
│ ╟────────────────────┘ │ ╔═══════════════════╗ ║
|
||||
│ ║ │ Socket Connection│ ║Proxy establishes ░║ ║
|
||||
│ ║ │ <─ ─ ─ ─ ─ ─ ─ ─ > ║ TCPconnection ║ ║
|
||||
│ ║ │ │ ║ with target host ║ ║
|
||||
│ ╚════════════╪══════════════════╪══╚═══════════════════╝═════════╝
|
||||
│ │ │
|
||||
│ Response packet │ │
|
||||
│ <───────────────────────── │
|
||||
│ │ │
|
||||
│ │ │
|
||||
│ │ ╔═══════╗ │
|
||||
│ ╚═╤══════════════╝ │
|
||||
│ │ │
|
||||
│ Client Connection Request│ │
|
||||
│ ─────────────────────────> │
|
||||
│ │ │
|
||||
│ │ │
|
||||
│ ╔════════════╪═══════╤══════════╪════════════════════════════════╗
|
||||
│ ║ TARGET CONNECTION │ │ ║
|
||||
│ ╟────────────────────┘ │ ╔═══════════════════╗ ║
|
||||
│ ║ │ Socket Connection│ ║Proxy establishes ░║ ║
|
||||
│ ║ │ <─ ─ ─ ─ ─ ─ ─ ─ > ║ TCPconnection ║ ║
|
||||
│ ║ │ │ ║ with target host ║ ║
|
||||
│ ╚════════════╪══════════════════╪══╚═══════════════════╝═════════╝
|
||||
│ │ │
|
||||
│ Response packet │ │
|
||||
│ <───────────────────────── │
|
||||
│ │ │
|
||||
│ │ │
|
||||
│ │ ╔═══════╗ │
|
||||
══════════════════════╪══════════════════════════╪══╣ Usage ╠═══════╪════════════════════════════════════════════
|
||||
│ │ ╚═══════╝ │
|
||||
│ │ │
|
||||
╔═════════════════╗│ │ │
|
||||
║Client uses the ░║│ │ │
|
||||
║ socket opened ║│ │ │
|
||||
║ with proxy ║│ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─>
|
||||
║to communicate ║│ │ │
|
||||
║ ║│ │ │
|
||||
╚═════════════════╝┴───┐ ┌──┴──┐ ┌──┴───┐
|
||||
│Client│ │Proxy│ │Target│
|
||||
└──────┘ └─────┘ └──────┘
|
||||
│ │ ╚═══════╝ │
|
||||
│ │ │
|
||||
╔═════════════════╗│ │ │
|
||||
║Client uses the ░║│ │ │
|
||||
║ socket opened ║│ │ │
|
||||
║ with proxy ║│ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─>
|
||||
║to communicate ║│ │ │
|
||||
║ ║│ │ │
|
||||
╚═════════════════╝┴───┐ ┌──┴──┐ ┌──┴───┐
|
||||
│Client│ │Proxy│ │Target│
|
||||
└──────┘ └─────┘ └──────┘
|
||||
|
||||
|
||||
# Configure and Building example
|
||||
|
||||
This example requires the proxy address to be configured. You can do this using the menuconfig option.
|
||||
Proxy address and port must be configured in order for this example to work.
|
||||
Proxy address and port must be configured in order for this example to work.
|
||||
|
||||
If using Linux ssh can be used as a proxy for testing.
|
||||
If using Linux ssh can be used as a proxy for testing.
|
||||
|
||||
```
|
||||
ssh -N -v -D 0.0.0.0:1080 localhost
|
||||
@ -70,4 +70,3 @@ ssh -N -v -D 0.0.0.0:1080 localhost
|
||||
# Async operations composition and automatic lifetime control
|
||||
|
||||
For documentation about the structure of this example look into [async\_request README](../async_request/README.md).
|
||||
|
||||
|
@ -183,7 +183,7 @@ void async_connect(asio::io_context &context, std::string proxy, std::string pro
|
||||
std::make_shared<Connection>(context)->start(proxy_resolution,
|
||||
[resolver, host_resolution, completion_handler](std::shared_ptr<Connection> connection) {
|
||||
auto connect_data = std::make_shared<ConnectionData>(socks4::request::connect, *host_resolution, "");
|
||||
ESP_LOGI(TAG, "Sending Request to proxy for host connection.");
|
||||
ESP_LOGI(TAG, "Sending Request to proxy for host connection.");
|
||||
connection->write_async(connect_data->request.buffers(), [connection, connect_data, completion_handler](std::error_code error, std::size_t bytes_received) {
|
||||
if (error) {
|
||||
ESP_LOGE(TAG, "Proxy request write error: %s", error.message().c_str());
|
||||
|
@ -20,122 +20,115 @@ namespace socks4 {
|
||||
|
||||
const unsigned char version = 0x04;
|
||||
|
||||
class request
|
||||
{
|
||||
class request {
|
||||
public:
|
||||
enum command_type
|
||||
{
|
||||
connect = 0x01,
|
||||
bind = 0x02
|
||||
};
|
||||
enum command_type {
|
||||
connect = 0x01,
|
||||
bind = 0x02
|
||||
};
|
||||
|
||||
request(command_type cmd, const asio::ip::tcp::endpoint& endpoint,
|
||||
const std::string& user_id)
|
||||
: version_(version),
|
||||
command_(cmd),
|
||||
user_id_(user_id),
|
||||
null_byte_(0)
|
||||
{
|
||||
// Only IPv4 is supported by the SOCKS 4 protocol.
|
||||
if (endpoint.protocol() != asio::ip::tcp::v4())
|
||||
request(command_type cmd, const asio::ip::tcp::endpoint &endpoint,
|
||||
const std::string &user_id)
|
||||
: version_(version),
|
||||
command_(cmd),
|
||||
user_id_(user_id),
|
||||
null_byte_(0)
|
||||
{
|
||||
throw asio::system_error(
|
||||
asio::error::address_family_not_supported);
|
||||
// Only IPv4 is supported by the SOCKS 4 protocol.
|
||||
if (endpoint.protocol() != asio::ip::tcp::v4()) {
|
||||
throw asio::system_error(
|
||||
asio::error::address_family_not_supported);
|
||||
}
|
||||
|
||||
// Convert port number to network byte order.
|
||||
unsigned short port = endpoint.port();
|
||||
port_high_byte_ = (port >> 8) & 0xff;
|
||||
port_low_byte_ = port & 0xff;
|
||||
|
||||
// Save IP address in network byte order.
|
||||
address_ = endpoint.address().to_v4().to_bytes();
|
||||
}
|
||||
|
||||
// Convert port number to network byte order.
|
||||
unsigned short port = endpoint.port();
|
||||
port_high_byte_ = (port >> 8) & 0xff;
|
||||
port_low_byte_ = port & 0xff;
|
||||
|
||||
// Save IP address in network byte order.
|
||||
address_ = endpoint.address().to_v4().to_bytes();
|
||||
}
|
||||
|
||||
std::array<asio::const_buffer, 7> buffers() const
|
||||
{
|
||||
return
|
||||
std::array<asio::const_buffer, 7> buffers() const
|
||||
{
|
||||
{
|
||||
asio::buffer(&version_, 1),
|
||||
asio::buffer(&command_, 1),
|
||||
asio::buffer(&port_high_byte_, 1),
|
||||
asio::buffer(&port_low_byte_, 1),
|
||||
asio::buffer(address_),
|
||||
asio::buffer(user_id_),
|
||||
asio::buffer(&null_byte_, 1)
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
{
|
||||
asio::buffer(&version_, 1),
|
||||
asio::buffer(&command_, 1),
|
||||
asio::buffer(&port_high_byte_, 1),
|
||||
asio::buffer(&port_low_byte_, 1),
|
||||
asio::buffer(address_),
|
||||
asio::buffer(user_id_),
|
||||
asio::buffer(&null_byte_, 1)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned char version_;
|
||||
unsigned char command_;
|
||||
unsigned char port_high_byte_;
|
||||
unsigned char port_low_byte_;
|
||||
asio::ip::address_v4::bytes_type address_;
|
||||
std::string user_id_;
|
||||
unsigned char null_byte_;
|
||||
unsigned char version_;
|
||||
unsigned char command_;
|
||||
unsigned char port_high_byte_;
|
||||
unsigned char port_low_byte_;
|
||||
asio::ip::address_v4::bytes_type address_;
|
||||
std::string user_id_;
|
||||
unsigned char null_byte_;
|
||||
};
|
||||
|
||||
class reply
|
||||
{
|
||||
class reply {
|
||||
public:
|
||||
enum status_type
|
||||
{
|
||||
request_granted = 0x5a,
|
||||
request_failed = 0x5b,
|
||||
request_failed_no_identd = 0x5c,
|
||||
request_failed_bad_user_id = 0x5d
|
||||
};
|
||||
|
||||
reply()
|
||||
: null_byte_(0),
|
||||
status_()
|
||||
{
|
||||
}
|
||||
|
||||
std::array<asio::mutable_buffer, 5> buffers()
|
||||
{
|
||||
return
|
||||
{
|
||||
{
|
||||
asio::buffer(&null_byte_, 1),
|
||||
asio::buffer(&status_, 1),
|
||||
asio::buffer(&port_high_byte_, 1),
|
||||
asio::buffer(&port_low_byte_, 1),
|
||||
asio::buffer(address_)
|
||||
}
|
||||
enum status_type {
|
||||
request_granted = 0x5a,
|
||||
request_failed = 0x5b,
|
||||
request_failed_no_identd = 0x5c,
|
||||
request_failed_bad_user_id = 0x5d
|
||||
};
|
||||
}
|
||||
|
||||
bool success() const
|
||||
{
|
||||
return null_byte_ == 0 && status_ == request_granted;
|
||||
}
|
||||
reply()
|
||||
: null_byte_(0),
|
||||
status_()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned char status() const
|
||||
{
|
||||
return status_;
|
||||
}
|
||||
std::array<asio::mutable_buffer, 5> buffers()
|
||||
{
|
||||
return {
|
||||
{
|
||||
asio::buffer(&null_byte_, 1),
|
||||
asio::buffer(&status_, 1),
|
||||
asio::buffer(&port_high_byte_, 1),
|
||||
asio::buffer(&port_low_byte_, 1),
|
||||
asio::buffer(address_)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
asio::ip::tcp::endpoint endpoint() const
|
||||
{
|
||||
unsigned short port = port_high_byte_;
|
||||
port = (port << 8) & 0xff00;
|
||||
port = port | port_low_byte_;
|
||||
bool success() const
|
||||
{
|
||||
return null_byte_ == 0 && status_ == request_granted;
|
||||
}
|
||||
|
||||
asio::ip::address_v4 address(address_);
|
||||
unsigned char status() const
|
||||
{
|
||||
return status_;
|
||||
}
|
||||
|
||||
return asio::ip::tcp::endpoint(address, port);
|
||||
}
|
||||
asio::ip::tcp::endpoint endpoint() const
|
||||
{
|
||||
unsigned short port = port_high_byte_;
|
||||
port = (port << 8) & 0xff00;
|
||||
port = port | port_low_byte_;
|
||||
|
||||
asio::ip::address_v4 address(address_);
|
||||
|
||||
return asio::ip::tcp::endpoint(address, port);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned char null_byte_;
|
||||
unsigned char status_;
|
||||
unsigned char port_high_byte_;
|
||||
unsigned char port_low_byte_;
|
||||
asio::ip::address_v4::bytes_type address_;
|
||||
unsigned char null_byte_;
|
||||
unsigned char status_;
|
||||
unsigned char port_high_byte_;
|
||||
unsigned char port_low_byte_;
|
||||
asio::ip::address_v4::bytes_type address_;
|
||||
};
|
||||
|
||||
} // namespace socks4
|
||||
|
@ -1,8 +1,7 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
def test_examples_asio_ssl(dut):
|
||||
dut.expect('Reply: GET / HTTP/1.1')
|
@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include "asio.hpp"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@ -8,78 +13,70 @@
|
||||
using asio::ip::tcp;
|
||||
|
||||
class session
|
||||
: public std::enable_shared_from_this<session>
|
||||
{
|
||||
: public std::enable_shared_from_this<session> {
|
||||
public:
|
||||
session(tcp::socket socket)
|
||||
: socket_(std::move(socket))
|
||||
{
|
||||
}
|
||||
session(tcp::socket socket)
|
||||
: socket_(std::move(socket))
|
||||
{
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
do_read();
|
||||
}
|
||||
void start()
|
||||
{
|
||||
do_read();
|
||||
}
|
||||
|
||||
private:
|
||||
void do_read()
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
socket_.async_read_some(asio::buffer(data_, max_length),
|
||||
[this, self](std::error_code ec, std::size_t length)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
data_[length] = 0;
|
||||
std::cout << data_ << std::endl;
|
||||
do_write(length);
|
||||
}
|
||||
void do_read()
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
socket_.async_read_some(asio::buffer(data_, max_length),
|
||||
[this, self](std::error_code ec, std::size_t length) {
|
||||
if (!ec) {
|
||||
data_[length] = 0;
|
||||
std::cout << data_ << std::endl;
|
||||
do_write(length);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void do_write(std::size_t length)
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
asio::async_write(socket_, asio::buffer(data_, length),
|
||||
[this, self](std::error_code ec, std::size_t length)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
do_read();
|
||||
}
|
||||
void do_write(std::size_t length)
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
asio::async_write(socket_, asio::buffer(data_, length),
|
||||
[this, self](std::error_code ec, std::size_t length) {
|
||||
if (!ec) {
|
||||
do_read();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
tcp::socket socket_;
|
||||
enum { max_length = 1024 };
|
||||
char data_[max_length];
|
||||
tcp::socket socket_;
|
||||
enum { max_length = 1024 };
|
||||
char data_[max_length];
|
||||
};
|
||||
|
||||
class server
|
||||
{
|
||||
class server {
|
||||
public:
|
||||
server(asio::io_context& io_context, short port)
|
||||
: acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
|
||||
{
|
||||
do_accept();
|
||||
}
|
||||
server(asio::io_context &io_context, short port)
|
||||
: acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
|
||||
{
|
||||
do_accept();
|
||||
}
|
||||
|
||||
private:
|
||||
void do_accept()
|
||||
{
|
||||
acceptor_.async_accept(
|
||||
[this](std::error_code ec, tcp::socket socket)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
std::make_shared<session>(std::move(socket))->start();
|
||||
}
|
||||
void do_accept()
|
||||
{
|
||||
acceptor_.async_accept(
|
||||
[this](std::error_code ec, tcp::socket socket) {
|
||||
if (!ec) {
|
||||
std::make_shared<session>(std::move(socket))->start();
|
||||
}
|
||||
|
||||
do_accept();
|
||||
do_accept();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
tcp::acceptor acceptor_;
|
||||
tcp::acceptor acceptor_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import os
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import re
|
||||
import socket
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
def test_examples_protocol_asio_tcp_server(dut):
|
||||
@ -15,7 +15,10 @@ def test_examples_protocol_asio_tcp_server(dut):
|
||||
"""
|
||||
test_msg = b'echo message from client to server'
|
||||
# 2. get the server IP address
|
||||
data = dut.expect(re.compile(b' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30).group(1).decode()
|
||||
data = dut.expect(
|
||||
re.compile(
|
||||
b' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), # noqa: W605
|
||||
timeout=30).group(1).decode()
|
||||
# 3. create tcp client and connect to server
|
||||
dut.expect('ASIO engine is up and running', timeout=1)
|
||||
cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
@ -29,7 +32,8 @@ def test_examples_protocol_asio_tcp_server(dut):
|
||||
pass
|
||||
else:
|
||||
print('Failure!')
|
||||
raise ValueError('Wrong data received from asi tcp server: {} (expected:{})'.format(data, test_msg))
|
||||
raise ValueError(
|
||||
'Wrong data received from asi tcp server: {} (expected:{})'.format(
|
||||
data, test_msg))
|
||||
# 5. check the client message appears also on server terminal
|
||||
dut.expect(test_msg.decode())
|
||||
|
||||
|
@ -20,49 +20,43 @@
|
||||
|
||||
using asio::ip::udp;
|
||||
|
||||
class server
|
||||
{
|
||||
class server {
|
||||
public:
|
||||
server(asio::io_context& io_context, short port)
|
||||
: socket_(io_context, udp::endpoint(udp::v4(), port))
|
||||
{
|
||||
do_receive();
|
||||
}
|
||||
server(asio::io_context &io_context, short port)
|
||||
: socket_(io_context, udp::endpoint(udp::v4(), port))
|
||||
{
|
||||
do_receive();
|
||||
}
|
||||
|
||||
void do_receive()
|
||||
{
|
||||
socket_.async_receive_from(
|
||||
asio::buffer(data_, max_length), sender_endpoint_,
|
||||
[this](std::error_code ec, std::size_t bytes_recvd)
|
||||
{
|
||||
if (!ec && bytes_recvd > 0)
|
||||
{
|
||||
data_[bytes_recvd] = 0;
|
||||
std::cout << data_ << std::endl;
|
||||
do_send(bytes_recvd);
|
||||
}
|
||||
else
|
||||
{
|
||||
void do_receive()
|
||||
{
|
||||
socket_.async_receive_from(
|
||||
asio::buffer(data_, max_length), sender_endpoint_,
|
||||
[this](std::error_code ec, std::size_t bytes_recvd) {
|
||||
if (!ec && bytes_recvd > 0) {
|
||||
data_[bytes_recvd] = 0;
|
||||
std::cout << data_ << std::endl;
|
||||
do_send(bytes_recvd);
|
||||
} else {
|
||||
do_receive();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void do_send(std::size_t length)
|
||||
{
|
||||
socket_.async_send_to(
|
||||
asio::buffer(data_, length), sender_endpoint_,
|
||||
[this](std::error_code /*ec*/, std::size_t bytes /*bytes_sent*/) {
|
||||
do_receive();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void do_send(std::size_t length)
|
||||
{
|
||||
socket_.async_send_to(
|
||||
asio::buffer(data_, length), sender_endpoint_,
|
||||
[this](std::error_code /*ec*/, std::size_t bytes /*bytes_sent*/)
|
||||
{
|
||||
do_receive();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
udp::socket socket_;
|
||||
udp::endpoint sender_endpoint_;
|
||||
enum { max_length = 1024 };
|
||||
char data_[max_length];
|
||||
udp::socket socket_;
|
||||
udp::endpoint sender_endpoint_;
|
||||
enum { max_length = 1024 };
|
||||
char data_[max_length];
|
||||
};
|
||||
|
||||
extern "C" void app_main(void)
|
||||
|
@ -1,9 +1,8 @@
|
||||
import os
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import re
|
||||
import socket
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
def test_examples_protocol_asio_udp_server(dut):
|
||||
"""
|
||||
@ -15,7 +14,10 @@ def test_examples_protocol_asio_udp_server(dut):
|
||||
5. Test evaluates received test message on server stdout
|
||||
"""
|
||||
test_msg = b'echo message from client to server'
|
||||
data = dut.expect(re.compile(b' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30).group(1).decode()
|
||||
data = dut.expect(
|
||||
re.compile(
|
||||
b' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), # noqa: W605
|
||||
timeout=30).group(1).decode()
|
||||
dut.expect('ASIO engine is up and running', timeout=1)
|
||||
cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
cli.settimeout(30)
|
||||
@ -28,6 +30,8 @@ def test_examples_protocol_asio_udp_server(dut):
|
||||
pass
|
||||
else:
|
||||
print('Failure!')
|
||||
raise ValueError('Wrong data received from asio udp server: {} (expected:{})'.format(data, test_msg))
|
||||
raise ValueError(
|
||||
'Wrong data received from asio udp server: {} (expected:{})'.
|
||||
format(data, test_msg))
|
||||
# 5. check the client message appears also on server terminal
|
||||
dut.expect(test_msg.decode())
|
||||
|
@ -19,12 +19,13 @@
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
template <typename Exception>
|
||||
void throw_exception(const Exception& e)
|
||||
void throw_exception(const Exception &e)
|
||||
{
|
||||
ESP_LOGE("esp32_asio_exception", "Caught exception: %s!", e.what());
|
||||
abort();
|
||||
ESP_LOGE("esp32_asio_exception", "Caught exception: %s!", e.what());
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
#endif // CONFIG_COMPILER_CXX_EXCEPTIONS==1 && defined (ASIO_NO_EXCEPTIONS)
|
||||
|
||||
#endif // _ESP_EXCEPTION_H_
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
@ -16,9 +16,9 @@
|
||||
#define SSL_OP_SINGLE_DH_USE 0
|
||||
#define SSL_OP_NO_COMPRESSION 0
|
||||
|
||||
#define SSL_OP_NO_SSLv2 0x01000000L
|
||||
#define SSL_OP_NO_SSLv3 0x02000000L
|
||||
#define SSL_OP_NO_TLSv1 0x04000000L
|
||||
#define SSL_OP_NO_SSLv2 0x01000000L
|
||||
#define SSL_OP_NO_SSLv3 0x02000000L
|
||||
#define SSL_OP_NO_TLSv1 0x04000000L
|
||||
|
||||
#define SSL_VERIFY_NONE 0x00
|
||||
#define SSL_VERIFY_PEER 0x01
|
||||
@ -35,12 +35,14 @@ namespace mbedtls {
|
||||
class engine;
|
||||
class bio;
|
||||
class shared_ctx;
|
||||
} } } // namespace asio::ssl::mbedtls
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::mbedtls
|
||||
|
||||
//
|
||||
// Supply OpenSSL types as aliases to mbedtls classes
|
||||
//
|
||||
using X509_STORE_CTX=void;
|
||||
using BIO=asio::ssl::mbedtls::bio;
|
||||
using SSL_CTX=asio::ssl::mbedtls::shared_ctx;
|
||||
using SSL=asio::ssl::mbedtls::engine;
|
||||
using X509_STORE_CTX = void;
|
||||
using BIO = asio::ssl::mbedtls::bio;
|
||||
using SSL_CTX = asio::ssl::mbedtls::shared_ctx;
|
||||
using SSL = asio::ssl::mbedtls::engine;
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
@ -87,7 +87,7 @@ public:
|
||||
return flags_ & BIO_FLAGS_READ;
|
||||
}
|
||||
|
||||
static std::pair<std::shared_ptr<bio>, std::shared_ptr<bio>> new_pair(const char* error_location)
|
||||
static std::pair<std::shared_ptr<bio>, std::shared_ptr<bio>> new_pair(const char *error_location)
|
||||
{
|
||||
auto b1 = std::shared_ptr<bio>(new (std::nothrow) bio);
|
||||
auto b2 = std::shared_ptr<bio>(new (std::nothrow) bio);
|
||||
@ -110,4 +110,6 @@ private:
|
||||
size_t flags_ {0};
|
||||
};
|
||||
|
||||
} } } // namespace asio::ssl::mbedtls
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::mbedtls
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
@ -11,13 +11,13 @@
|
||||
namespace asio {
|
||||
namespace error {
|
||||
|
||||
const asio::error_category& get_mbedtls_category();
|
||||
const asio::error_category &get_mbedtls_category();
|
||||
} // namespace error
|
||||
|
||||
namespace ssl {
|
||||
namespace mbedtls {
|
||||
|
||||
void throw_alloc_failure(const char* location);
|
||||
void throw_alloc_failure(const char *location);
|
||||
|
||||
const char *error_message(int error_code);
|
||||
|
||||
@ -26,11 +26,10 @@ enum class container {
|
||||
};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
inline T* create(const char * location, Args &&... args)
|
||||
inline T *create(const char *location, Args &&... args)
|
||||
{
|
||||
T* t = new (std::nothrow) T(std::forward<Args>(args)...);
|
||||
if (t == nullptr)
|
||||
{
|
||||
T *t = new (std::nothrow) T(std::forward<Args>(args)...);
|
||||
if (t == nullptr) {
|
||||
throw_alloc_failure(location);
|
||||
}
|
||||
return t;
|
||||
@ -43,12 +42,12 @@ public:
|
||||
const unsigned char *data(container c) const
|
||||
{
|
||||
switch (c) {
|
||||
case container::CERT:
|
||||
return static_cast<const unsigned char *>(cert_chain_.data());
|
||||
case container::CA_CERT:
|
||||
return static_cast<const unsigned char *>(ca_cert_.data());
|
||||
case container::PRIVKEY:
|
||||
return static_cast<const unsigned char *>(private_key_.data());
|
||||
case container::CERT:
|
||||
return static_cast<const unsigned char *>(cert_chain_.data());
|
||||
case container::CA_CERT:
|
||||
return static_cast<const unsigned char *>(ca_cert_.data());
|
||||
case container::PRIVKEY:
|
||||
return static_cast<const unsigned char *>(private_key_.data());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -56,12 +55,12 @@ public:
|
||||
std::size_t size(container c) const
|
||||
{
|
||||
switch (c) {
|
||||
case container::CERT:
|
||||
return cert_chain_.size();
|
||||
case container::CA_CERT:
|
||||
return ca_cert_.size();
|
||||
case container::PRIVKEY:
|
||||
return private_key_.size();
|
||||
case container::CERT:
|
||||
return cert_chain_.size();
|
||||
case container::CA_CERT:
|
||||
return ca_cert_.size();
|
||||
case container::PRIVKEY:
|
||||
return private_key_.size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -80,11 +79,10 @@ public:
|
||||
*/
|
||||
class shared_ctx {
|
||||
public:
|
||||
static SSL_CTX *create(const char* location, context_base::method m)
|
||||
static SSL_CTX *create(const char *location, context_base::method m)
|
||||
{
|
||||
auto wrapped = asio::ssl::mbedtls::create<shared_ctx>(location, m);
|
||||
if (wrapped->ctx_ == nullptr)
|
||||
{
|
||||
if (wrapped->ctx_ == nullptr) {
|
||||
throw_alloc_failure(location);
|
||||
}
|
||||
return wrapped;
|
||||
@ -96,10 +94,12 @@ public:
|
||||
}
|
||||
|
||||
explicit shared_ctx(context_base::method m)
|
||||
:ctx_(std::shared_ptr<context>(new (std::nothrow) context(m))) { }
|
||||
: ctx_(std::shared_ptr<context>(new (std::nothrow) context(m))) { }
|
||||
|
||||
private:
|
||||
std::shared_ptr<mbedtls::context> ctx_;
|
||||
};
|
||||
|
||||
} } } // namespace asio::ssl::mbedtls
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::mbedtls
|
||||
|
@ -23,7 +23,7 @@ const char *error_message(int error_code)
|
||||
return error_buf;
|
||||
}
|
||||
|
||||
void throw_alloc_failure(const char* location)
|
||||
void throw_alloc_failure(const char *location)
|
||||
{
|
||||
asio::error_code ec( MBEDTLS_ERR_SSL_ALLOC_FAILED, asio::error::get_mbedtls_category());
|
||||
asio::detail::throw_error(ec, location);
|
||||
@ -62,7 +62,7 @@ public:
|
||||
verify_mode_ = mode;
|
||||
}
|
||||
|
||||
bio* ext_bio() const
|
||||
bio *ext_bio() const
|
||||
{
|
||||
return bio_.second.get();
|
||||
}
|
||||
@ -95,14 +95,14 @@ public:
|
||||
int write(const void *buffer, int len)
|
||||
{
|
||||
int ret = impl_.write(buffer, len);
|
||||
state_ = ret == len ? IDLE: WRITING;
|
||||
state_ = ret == len ? IDLE : WRITING;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int read(void *buffer, int len)
|
||||
{
|
||||
int ret = impl_.read(buffer, len);
|
||||
state_ = ret == len ? IDLE: READING;
|
||||
state_ = ret == len ? IDLE : READING;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ private:
|
||||
|
||||
static int bio_read(void *ctx, unsigned char *buf, size_t len)
|
||||
{
|
||||
auto bio = static_cast<BIO*>(ctx);
|
||||
auto bio = static_cast<BIO *>(ctx);
|
||||
int read = bio->read(buf, len);
|
||||
if (read <= 0 && bio->should_read()) {
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
@ -127,7 +127,7 @@ private:
|
||||
|
||||
static int bio_write(void *ctx, const unsigned char *buf, size_t len)
|
||||
{
|
||||
auto bio = static_cast<BIO*>(ctx);
|
||||
auto bio = static_cast<BIO *>(ctx);
|
||||
int written = bio->write(buf, len);
|
||||
if (written <= 0 && bio->should_write()) {
|
||||
return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
@ -163,25 +163,27 @@ private:
|
||||
{
|
||||
int mode = MBEDTLS_SSL_VERIFY_UNSET;
|
||||
if (is_client_not_server) {
|
||||
if (verify_mode_ & SSL_VERIFY_PEER)
|
||||
if (verify_mode_ & SSL_VERIFY_PEER) {
|
||||
mode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
else if (verify_mode_ == SSL_VERIFY_NONE)
|
||||
} else if (verify_mode_ == SSL_VERIFY_NONE) {
|
||||
mode = MBEDTLS_SSL_VERIFY_NONE;
|
||||
}
|
||||
} else {
|
||||
if (verify_mode_ & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
|
||||
if (verify_mode_ & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
|
||||
mode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
else if (verify_mode_ & SSL_VERIFY_PEER)
|
||||
} else if (verify_mode_ & SSL_VERIFY_PEER) {
|
||||
mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
|
||||
else if (verify_mode_ == SSL_VERIFY_NONE)
|
||||
} else if (verify_mode_ == SSL_VERIFY_NONE) {
|
||||
mode = MBEDTLS_SSL_VERIFY_NONE;
|
||||
}
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
struct impl {
|
||||
static void print_error(const char* function, int error_code)
|
||||
static void print_error(const char *function, int error_code)
|
||||
{
|
||||
constexpr const char *TAG="mbedtls-engine-impl";
|
||||
constexpr const char *TAG = "mbedtls-engine-impl";
|
||||
ESP_LOGE(TAG, "%s() returned -0x%04X", function, -error_code);
|
||||
ESP_LOGI(TAG, "-0x%04X: %s", -error_code, error_message(error_code));
|
||||
}
|
||||
@ -230,7 +232,7 @@ private:
|
||||
mbedtls_x509_crt_init(&public_cert_);
|
||||
mbedtls_pk_init(&pk_key_);
|
||||
mbedtls_x509_crt_init(&ca_cert_);
|
||||
int ret = mbedtls_ssl_config_defaults(&conf_, is_client_not_server ? MBEDTLS_SSL_IS_CLIENT: MBEDTLS_SSL_IS_SERVER,
|
||||
int ret = mbedtls_ssl_config_defaults(&conf_, is_client_not_server ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
if (ret) {
|
||||
print_error("mbedtls_ssl_config_defaults", ret);
|
||||
@ -290,4 +292,6 @@ private:
|
||||
asio::ssl::verify_mode verify_mode_;
|
||||
};
|
||||
|
||||
} } } // namespace asio::ssl::mbedtls
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::mbedtls
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
@ -14,30 +14,29 @@ namespace asio {
|
||||
namespace error {
|
||||
namespace detail {
|
||||
|
||||
class mbedtls_category : public asio::error_category
|
||||
{
|
||||
class mbedtls_category : public asio::error_category {
|
||||
public:
|
||||
const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT
|
||||
const char *name() const ASIO_ERROR_CATEGORY_NOEXCEPT
|
||||
{
|
||||
return "asio.ssl";
|
||||
}
|
||||
|
||||
std::string message(int value) const
|
||||
{
|
||||
const char* s = asio::ssl::mbedtls::error_message(value);
|
||||
const char *s = asio::ssl::mbedtls::error_message(value);
|
||||
return s ? s : "asio.mbedtls error";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
const asio::error_category& get_mbedtls_category()
|
||||
const asio::error_category &get_mbedtls_category()
|
||||
{
|
||||
static detail::mbedtls_category instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
const asio::error_category& get_ssl_category()
|
||||
const asio::error_category &get_ssl_category()
|
||||
{
|
||||
return asio::error::get_mbedtls_category();
|
||||
}
|
||||
@ -47,9 +46,11 @@ const asio::error_category& get_ssl_category()
|
||||
namespace ssl {
|
||||
namespace error {
|
||||
|
||||
const asio::error_category& get_stream_category()
|
||||
const asio::error_category &get_stream_category()
|
||||
{
|
||||
return asio::error::get_mbedtls_category();
|
||||
}
|
||||
|
||||
} } } // namespace asio::ssl::error
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::error
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
@ -4,7 +4,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
// SPDX-FileContributor: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileContributor: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
@ -22,19 +22,19 @@ namespace ssl {
|
||||
|
||||
|
||||
context::context(context::method m)
|
||||
: handle_(0)
|
||||
: handle_(0)
|
||||
{
|
||||
handle_ = mbedtls::shared_ctx::create("mbedtls-context", m);
|
||||
set_options(no_compression);
|
||||
}
|
||||
|
||||
context::context(context&& other)
|
||||
context::context(context &&other)
|
||||
{
|
||||
handle_ = other.handle_;
|
||||
other.handle_ = 0;
|
||||
}
|
||||
|
||||
context& context::operator=(context&& other)
|
||||
context &context::operator=(context &&other)
|
||||
{
|
||||
context tmp(ASIO_MOVE_CAST(context)(*this));
|
||||
handle_ = other.handle_;
|
||||
@ -60,14 +60,14 @@ void context::set_options(context::options o)
|
||||
}
|
||||
|
||||
ASIO_SYNC_OP_VOID context::set_options(
|
||||
context::options o, asio::error_code& ec)
|
||||
context::options o, asio::error_code &ec)
|
||||
{
|
||||
handle_->get()->options_ = o;
|
||||
ec = asio::error_code();
|
||||
ASIO_SYNC_OP_VOID_RETURN(ec);
|
||||
}
|
||||
|
||||
void context::add_certificate_authority(const const_buffer& ca)
|
||||
void context::add_certificate_authority(const const_buffer &ca)
|
||||
{
|
||||
asio::error_code ec;
|
||||
add_certificate_authority(ca, ec);
|
||||
@ -75,13 +75,13 @@ void context::add_certificate_authority(const const_buffer& ca)
|
||||
}
|
||||
|
||||
ASIO_SYNC_OP_VOID context::add_certificate_authority(
|
||||
const const_buffer& ca, asio::error_code& ec)
|
||||
const const_buffer &ca, asio::error_code &ec)
|
||||
{
|
||||
handle_->get()->ca_cert_ = ca;
|
||||
ASIO_SYNC_OP_VOID_RETURN(asio::error_code());
|
||||
}
|
||||
|
||||
void context::use_certificate_chain(const const_buffer& chain)
|
||||
void context::use_certificate_chain(const const_buffer &chain)
|
||||
{
|
||||
asio::error_code ec;
|
||||
use_certificate_chain(chain, ec);
|
||||
@ -89,14 +89,14 @@ void context::use_certificate_chain(const const_buffer& chain)
|
||||
}
|
||||
|
||||
ASIO_SYNC_OP_VOID context::use_certificate_chain(
|
||||
const const_buffer& chain, asio::error_code& ec)
|
||||
const const_buffer &chain, asio::error_code &ec)
|
||||
{
|
||||
handle_->get()->cert_chain_ = chain;
|
||||
ASIO_SYNC_OP_VOID_RETURN(asio::error_code());
|
||||
}
|
||||
|
||||
void context::use_private_key(
|
||||
const const_buffer& private_key, context::file_format format)
|
||||
const const_buffer &private_key, context::file_format format)
|
||||
{
|
||||
asio::error_code ec;
|
||||
use_private_key(private_key, format, ec);
|
||||
@ -104,8 +104,8 @@ void context::use_private_key(
|
||||
}
|
||||
|
||||
ASIO_SYNC_OP_VOID context::use_private_key(
|
||||
const const_buffer& private_key, context::file_format format,
|
||||
asio::error_code& ec)
|
||||
const const_buffer &private_key, context::file_format format,
|
||||
asio::error_code &ec)
|
||||
{
|
||||
handle_->get()->private_key_ = private_key;
|
||||
ASIO_SYNC_OP_VOID_RETURN(asio::error_code());
|
||||
|
@ -3,7 +3,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
// SPDX-FileContributor: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileContributor: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
@ -24,8 +24,8 @@ namespace ssl {
|
||||
namespace detail {
|
||||
|
||||
|
||||
engine::engine(SSL_CTX* context)
|
||||
: ssl_(nullptr)
|
||||
engine::engine(SSL_CTX *context)
|
||||
: ssl_(nullptr)
|
||||
{
|
||||
ssl_ = mbedtls::create<mbedtls::engine>("mbedtls-engine", context->get());
|
||||
}
|
||||
@ -35,49 +35,47 @@ engine::~engine()
|
||||
delete ssl_;
|
||||
}
|
||||
|
||||
SSL* engine::native_handle()
|
||||
SSL *engine::native_handle()
|
||||
{
|
||||
return ssl_;
|
||||
}
|
||||
|
||||
asio::error_code engine::set_verify_mode(
|
||||
verify_mode v, asio::error_code& ec)
|
||||
verify_mode v, asio::error_code &ec)
|
||||
{
|
||||
ssl_->set_verify_mode(v);
|
||||
return {};
|
||||
}
|
||||
|
||||
engine::want engine::handshake(
|
||||
stream_base::handshake_type type, asio::error_code& ec)
|
||||
stream_base::handshake_type type, asio::error_code &ec)
|
||||
{
|
||||
return perform((type == asio::ssl::stream_base::client)
|
||||
? &engine::do_connect : &engine::do_accept, 0, 0, ec, 0);
|
||||
}
|
||||
|
||||
engine::want engine::shutdown(asio::error_code& ec)
|
||||
engine::want engine::shutdown(asio::error_code &ec)
|
||||
{
|
||||
return perform(&engine::do_shutdown, 0, 0, ec, 0);
|
||||
}
|
||||
|
||||
engine::want engine::write(const asio::const_buffer& data,
|
||||
asio::error_code& ec, std::size_t& bytes_transferred)
|
||||
engine::want engine::write(const asio::const_buffer &data,
|
||||
asio::error_code &ec, std::size_t &bytes_transferred)
|
||||
{
|
||||
if (data.size() == 0)
|
||||
{
|
||||
if (data.size() == 0) {
|
||||
ec = asio::error_code();
|
||||
return engine::want_nothing;
|
||||
}
|
||||
|
||||
return perform(&engine::do_write,
|
||||
const_cast<void*>(data.data()),
|
||||
const_cast<void *>(data.data()),
|
||||
data.size(), ec, &bytes_transferred);
|
||||
}
|
||||
|
||||
engine::want engine::read(const asio::mutable_buffer& data,
|
||||
asio::error_code& ec, std::size_t& bytes_transferred)
|
||||
engine::want engine::read(const asio::mutable_buffer &data,
|
||||
asio::error_code &ec, std::size_t &bytes_transferred)
|
||||
{
|
||||
if (data.size() == 0)
|
||||
{
|
||||
if (data.size() == 0) {
|
||||
ec = asio::error_code();
|
||||
return engine::want_nothing;
|
||||
}
|
||||
@ -87,7 +85,7 @@ engine::want engine::read(const asio::mutable_buffer& data,
|
||||
}
|
||||
|
||||
asio::mutable_buffer engine::get_output(
|
||||
const asio::mutable_buffer& data)
|
||||
const asio::mutable_buffer &data)
|
||||
{
|
||||
int length = ssl_->ext_bio()->read(data.data(), static_cast<int>(data.size()));
|
||||
|
||||
@ -96,7 +94,7 @@ asio::mutable_buffer engine::get_output(
|
||||
}
|
||||
|
||||
asio::const_buffer engine::put_input(
|
||||
const asio::const_buffer& data)
|
||||
const asio::const_buffer &data)
|
||||
{
|
||||
int length = ssl_->ext_bio()->write(data.data(), static_cast<int>(data.size()));
|
||||
|
||||
@ -104,23 +102,22 @@ asio::const_buffer engine::put_input(
|
||||
(length > 0 ? static_cast<std::size_t>(length) : 0));
|
||||
}
|
||||
|
||||
const asio::error_code& engine::map_error_code(
|
||||
asio::error_code& ec) const
|
||||
const asio::error_code &engine::map_error_code(
|
||||
asio::error_code &ec) const
|
||||
{
|
||||
// We only want to map the error::eof code.
|
||||
if (ec != asio::error::eof)
|
||||
if (ec != asio::error::eof) {
|
||||
return ec;
|
||||
}
|
||||
|
||||
// If there's data yet to be read, it's an error.
|
||||
if (ssl_->ext_bio()->wpending())
|
||||
{
|
||||
if (ssl_->ext_bio()->wpending()) {
|
||||
ec = asio::ssl::error::stream_truncated;
|
||||
return ec;
|
||||
}
|
||||
|
||||
// Otherwise, the peer should have negotiated a proper shutdown.
|
||||
if (ssl_->shutdown() != 0)
|
||||
{
|
||||
if (ssl_->shutdown() != 0) {
|
||||
ec = asio::ssl::error::stream_truncated;
|
||||
}
|
||||
|
||||
@ -129,47 +126,39 @@ const asio::error_code& engine::map_error_code(
|
||||
|
||||
// This is a simplified implementation of a generic ssl io operation
|
||||
// original implementation using openssl's SSL object is in asio/include/asio/ssl/detail/impl/engine.ipp
|
||||
engine::want engine::perform(int (engine::* op)(void*, std::size_t),
|
||||
void* data, std::size_t length, asio::error_code& ec,
|
||||
std::size_t* bytes_transferred)
|
||||
engine::want engine::perform(int (engine::* op)(void *, std::size_t),
|
||||
void *data, std::size_t length, asio::error_code &ec,
|
||||
std::size_t *bytes_transferred)
|
||||
{
|
||||
std::size_t pending_output_before = ssl_->ext_bio()->ctrl_pending();
|
||||
int result = (this->*op)(data, length);
|
||||
|
||||
std::size_t pending_output_after = ssl_->ext_bio()->ctrl_pending();
|
||||
|
||||
if (mbedtls::error_codes::is_error(result))
|
||||
{
|
||||
if (mbedtls::error_codes::is_error(result)) {
|
||||
ec = asio::error_code(result, asio::error::get_mbedtls_category());
|
||||
return pending_output_after > pending_output_before ? want_output : want_nothing;
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
if (result == 0) {
|
||||
return pending_output_after > pending_output_before
|
||||
? want_output : want_nothing;
|
||||
}
|
||||
|
||||
if (result > 0 && bytes_transferred)
|
||||
if (result > 0 && bytes_transferred) {
|
||||
*bytes_transferred = static_cast<std::size_t>(result);
|
||||
}
|
||||
|
||||
if (mbedtls::error_codes::want_write(result))
|
||||
{
|
||||
if (mbedtls::error_codes::want_write(result)) {
|
||||
ec = asio::error_code();
|
||||
return want_output_and_retry;
|
||||
}
|
||||
else if (pending_output_after > pending_output_before)
|
||||
{
|
||||
} else if (pending_output_after > pending_output_before) {
|
||||
ec = asio::error_code();
|
||||
return result > 0 ? want_output : want_output_and_retry;
|
||||
}
|
||||
else if (mbedtls::error_codes::want_read(result))
|
||||
{
|
||||
} else if (mbedtls::error_codes::want_read(result)) {
|
||||
ec = asio::error_code();
|
||||
return want_input_and_retry;
|
||||
}
|
||||
else if (ssl_->get_state() == mbedtls::CLOSED)
|
||||
{
|
||||
} else if (ssl_->get_state() == mbedtls::CLOSED) {
|
||||
ec = asio::error::eof;
|
||||
return want_nothing;
|
||||
}
|
||||
@ -178,27 +167,27 @@ engine::want engine::perform(int (engine::* op)(void*, std::size_t),
|
||||
return want_nothing;
|
||||
}
|
||||
|
||||
int engine::do_accept(void*, std::size_t)
|
||||
int engine::do_accept(void *, std::size_t)
|
||||
{
|
||||
return ssl_->accept();
|
||||
}
|
||||
|
||||
int engine::do_connect(void*, std::size_t)
|
||||
int engine::do_connect(void *, std::size_t)
|
||||
{
|
||||
return ssl_->connect();
|
||||
}
|
||||
|
||||
int engine::do_shutdown(void*, std::size_t)
|
||||
int engine::do_shutdown(void *, std::size_t)
|
||||
{
|
||||
return ssl_->shutdown();
|
||||
}
|
||||
|
||||
int engine::do_read(void* data, std::size_t length)
|
||||
int engine::do_read(void *data, std::size_t length)
|
||||
{
|
||||
return ssl_->read(data, length < INT_MAX ? static_cast<int>(length) : INT_MAX);
|
||||
}
|
||||
|
||||
int engine::do_write(void* data, std::size_t length)
|
||||
int engine::do_write(void *data, std::size_t length)
|
||||
{
|
||||
return ssl_->write(data, length < INT_MAX ? static_cast<int>(length) : INT_MAX);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
@ -17,4 +17,6 @@ asio::detail::shared_ptr<openssl_init_base::do_init> openssl_init_base::instance
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} } } // namespace asio::ssl::detail
|
||||
}
|
||||
}
|
||||
} // namespace asio::ssl::detail
|
||||
|
Reference in New Issue
Block a user