Skip to content

Commit 3cdf68a

Browse files
authored
fix websocket transport (#238)
* fix ws/wss observed address * fix yamux use-after-free ub Signed-off-by: turuslan <[email protected]>
1 parent e0d8e05 commit 3cdf68a

12 files changed

+33
-25
lines changed

CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
cmake_minimum_required(VERSION 3.12)
22

3+
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.27")
4+
cmake_policy(SET CMP0144 NEW)
5+
endif()
6+
37
find_program(CCACHE_FOUND ccache)
48
if (CCACHE_FOUND)
59
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)

include/libp2p/multi/multiaddress.hpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
#include <libp2p/outcome/outcome.hpp>
2020
#include <span>
2121

22+
namespace libp2p {
23+
using ProtoAddrVec = std::vector<std::pair<multi::Protocol, std::string>>;
24+
} // namespace libp2p
25+
2226
namespace libp2p::multi {
2327

2428
/**
@@ -148,8 +152,7 @@ namespace libp2p::multi {
148152
* @return list of pairs with a protocol as the first element and the value
149153
* as the second one
150154
*/
151-
std::vector<std::pair<Protocol, std::string>> getProtocolsWithValues()
152-
const;
155+
ProtoAddrVec getProtocolsWithValues() const;
153156

154157
bool operator==(const Multiaddress &other) const;
155158

include/libp2p/muxer/yamux/yamuxed_connection.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ namespace libp2p::connection {
198198
/// True if waiting for current write operation to complete
199199
bool is_writing_ = false;
200200

201+
std::shared_ptr<Bytes> writing_buf_ = std::make_shared<Bytes>();
202+
201203
/// Write queue
202204
std::deque<WriteQueueItem> write_queue_;
203205

include/libp2p/transport/impl/upgrader_session.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ namespace libp2p::transport {
1919
*/
2020
struct UpgraderSession
2121
: public std::enable_shared_from_this<UpgraderSession> {
22-
using ProtoAddrVec = std::vector<std::pair<multi::Protocol, std::string>>;
2322
using ConnectionCallback =
2423
void(outcome::result<std::shared_ptr<connection::CapableConnection>>);
2524
using HandlerFunc = std::function<ConnectionCallback>;

include/libp2p/transport/tcp/tcp_connection.hpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@ namespace libp2p::transport {
3939
using ConnectCallback = void(const ErrorCode &, const Tcp::endpoint &);
4040
using ConnectCallbackFunc = std::function<ConnectCallback>;
4141

42-
explicit TcpConnection(boost::asio::io_context &ctx);
42+
explicit TcpConnection(boost::asio::io_context &ctx, ProtoAddrVec layers);
4343

44-
TcpConnection(boost::asio::io_context &ctx, Tcp::socket &&socket);
44+
TcpConnection(boost::asio::io_context &ctx,
45+
ProtoAddrVec layers,
46+
Tcp::socket &&socket);
4547

4648
/**
4749
* @brief Resolve service name (DNS).
@@ -122,6 +124,7 @@ namespace libp2p::transport {
122124
outcome::result<void> saveMultiaddresses();
123125

124126
boost::asio::io_context &context_;
127+
ProtoAddrVec layers_;
125128
Tcp::socket socket_;
126129
bool initiator_ = false;
127130
bool connecting_with_timeout_ = false;

include/libp2p/transport/tcp/tcp_listener.hpp

-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ namespace libp2p::transport {
2020
class TcpListener : public TransportListener,
2121
public std::enable_shared_from_this<TcpListener> {
2222
public:
23-
using ProtoAddrVec = std::vector<std::pair<multi::Protocol, std::string>>;
24-
2523
~TcpListener() override = default;
2624

2725
TcpListener(boost::asio::io_context &context,

include/libp2p/transport/tcp/tcp_util.hpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818
namespace libp2p::transport::detail {
1919
template <typename T>
2020
inline outcome::result<multi::Multiaddress> makeAddress(
21-
T &&endpoint,
22-
const std::vector<std::pair<multi::Protocol, std::string>> *layers =
23-
nullptr) {
21+
T &&endpoint, const ProtoAddrVec *layers = nullptr) {
2422
try {
2523
auto address = endpoint.address();
2624
auto port = endpoint.port();
@@ -99,8 +97,6 @@ namespace libp2p::transport::detail {
9997
return {host, port};
10098
}
10199

102-
using ProtoAddrVec = std::vector<std::pair<multi::Protocol, std::string>>;
103-
104100
// Obtain layers string from provided address
105101
inline ProtoAddrVec getLayers(const multi::Multiaddress &address) {
106102
auto v = address.getProtocolsWithValues();

include/libp2p/transport/upgrader.hpp

-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ namespace libp2p::transport {
2323
* and using the chosen protocols to actually upgrade the connections
2424
*/
2525
struct Upgrader {
26-
using ProtoAddrVec = std::vector<std::pair<multi::Protocol, std::string>>;
27-
2826
using RawSPtr = std::shared_ptr<connection::RawConnection>;
2927
using LayerSPtr = std::shared_ptr<connection::LayerConnection>;
3028
using SecSPtr = std::shared_ptr<connection::SecureConnection>;

src/muxer/yamux/yamuxed_connection.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -651,16 +651,17 @@ namespace libp2p::connection {
651651
void YamuxedConnection::doWrite(WriteQueueItem packet) {
652652
assert(!is_writing_);
653653

654-
auto span = BytesIn(packet.packet);
654+
writing_buf_->assign(packet.packet.begin(), packet.packet.end());
655655
auto cb = [wptr{weak_from_this()},
656+
buf{writing_buf_},
656657
packet = std::move(packet)](outcome::result<size_t> res) {
657658
if (auto self = wptr.lock()) {
658659
self->onDataWritten(res, packet.stream_id);
659660
}
660661
};
661662

662663
is_writing_ = true;
663-
writeReturnSize(connection_, span, cb);
664+
writeReturnSize(connection_, *writing_buf_, cb);
664665
}
665666

666667
void YamuxedConnection::onDataWritten(outcome::result<size_t> res,

src/transport/tcp/tcp_connection.cpp

+9-5
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,20 @@ namespace libp2p::transport {
3131
} // namespace
3232

3333
TcpConnection::TcpConnection(boost::asio::io_context &ctx,
34+
ProtoAddrVec layers,
3435
boost::asio::ip::tcp::socket &&socket)
3536
: context_(ctx),
37+
layers_{std::move(layers)},
3638
socket_(std::move(socket)),
3739
connection_phase_done_{false},
3840
deadline_timer_(context_) {
3941
std::ignore = saveMultiaddresses();
4042
}
4143

42-
TcpConnection::TcpConnection(boost::asio::io_context &ctx)
44+
TcpConnection::TcpConnection(boost::asio::io_context &ctx,
45+
ProtoAddrVec layers)
4346
: context_(ctx),
47+
layers_{std::move(layers)},
4448
socket_(context_),
4549
connection_phase_done_{false},
4650
deadline_timer_(context_) {}
@@ -292,15 +296,15 @@ namespace libp2p::transport {
292296
if (!local_multiaddress_) {
293297
auto endpoint(socket_.local_endpoint(ec));
294298
if (!ec) {
295-
OUTCOME_TRY(addr, detail::makeAddress(endpoint));
296-
local_multiaddress_ = std::move(addr);
299+
BOOST_OUTCOME_TRY(local_multiaddress_,
300+
detail::makeAddress(endpoint, &layers_));
297301
}
298302
}
299303
if (!remote_multiaddress_) {
300304
auto endpoint(socket_.remote_endpoint(ec));
301305
if (!ec) {
302-
OUTCOME_TRY(addr, detail::makeAddress(endpoint));
303-
remote_multiaddress_ = std::move(addr);
306+
BOOST_OUTCOME_TRY(remote_multiaddress_,
307+
detail::makeAddress(endpoint, &layers_));
304308
}
305309
}
306310
} else {

src/transport/tcp/tcp_listener.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ namespace libp2p::transport {
9696
return self->handle_(ec);
9797
}
9898

99-
auto conn =
100-
std::make_shared<TcpConnection>(self->context_, std::move(sock));
99+
auto conn = std::make_shared<TcpConnection>(
100+
self->context_, self->layers_, std::move(sock));
101101

102102
auto session = std::make_shared<UpgraderSession>(
103103
self->upgrader_, self->layers_, std::move(conn), self->handle_);

src/transport/tcp/tcp_transport.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ namespace libp2p::transport {
2929
return handler(std::errc::address_family_not_supported);
3030
}
3131

32-
auto conn = std::make_shared<TcpConnection>(*context_);
33-
3432
auto [host, port] = detail::getHostAndTcpPort(address);
3533

3634
auto layers = detail::getLayers(address);
3735

36+
auto conn = std::make_shared<TcpConnection>(*context_, layers);
37+
3838
auto connect = [=,
3939
self{shared_from_this()},
4040
handler{std::move(handler)},

0 commit comments

Comments
 (0)