Compare commits
20 Commits
master
...
fb-sqlite-
Author | SHA1 | Date |
---|---|---|
Claudius Holeksa | 2af95c3664 | |
Claudius Holeksa | c82d717c2d | |
Claudius Holeksa | 0d06a58798 | |
Claudius Holeksa | d172f458a3 | |
Claudius Holeksa | e571a7ce90 | |
Claudius Holeksa | a5cfca7a12 | |
Claudius Holeksa | ffed345df1 | |
keldu | 0808db94ee | |
Claudius Holeksa | f44b6a1dc8 | |
Claudius Holeksa | b0991ce29b | |
Claudius Holeksa | 60d710cab7 | |
Claudius Holeksa | 28ea7d6708 | |
Claudius Holeksa | 3ff512bfca | |
Claudius Holeksa | 2d8889983a | |
Claudius Holeksa | 5a6f63eadb | |
Claudius Holeksa | 911db65409 | |
Claudius Holeksa | f29d1c6512 | |
Claudius Holeksa | 3cb0434e49 | |
Claudius Holeksa | 7117f23fcd | |
Claudius Holeksa | 6624960f86 |
|
@ -0,0 +1,9 @@
|
|||
with import <nixpkgs> {};
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "forstio";
|
||||
buildInputs = [ scons gnutls clang_12 clang-tools];
|
||||
|
||||
buildPhase = ''
|
||||
'';
|
||||
}
|
|
@ -210,7 +210,7 @@ translateNetworkAddressToUnixNetworkAddress(NetworkAddress &addr) {
|
|||
return static_cast<UnixNetworkAddress *>(arg);
|
||||
}
|
||||
|
||||
auto sock_addrs = SocketAddress::parse(
|
||||
auto sock_addrs = SocketAddress::resolve(
|
||||
std::string_view{arg->address()}, arg->port());
|
||||
|
||||
return UnixNetworkAddress{arg->address(), arg->port(),
|
||||
|
@ -370,8 +370,8 @@ size_t UnixNetworkAddress::unixAddressSize() const { return addresses.size(); }
|
|||
|
||||
UnixNetwork::UnixNetwork(UnixEventPort &event) : event_port{event} {}
|
||||
|
||||
Conveyor<Own<NetworkAddress>> UnixNetwork::parseAddress(const std::string &path,
|
||||
uint16_t port_hint) {
|
||||
Conveyor<Own<NetworkAddress>>
|
||||
UnixNetwork::resolveAddress(const std::string &path, uint16_t port_hint) {
|
||||
std::string_view addr_view{path};
|
||||
{
|
||||
std::string_view begins_with = "unix:";
|
||||
|
@ -381,7 +381,7 @@ Conveyor<Own<NetworkAddress>> UnixNetwork::parseAddress(const std::string &path,
|
|||
}
|
||||
|
||||
std::vector<SocketAddress> addresses =
|
||||
SocketAddress::parse(addr_view, port_hint);
|
||||
SocketAddress::resolve(addr_view, port_hint);
|
||||
|
||||
return Conveyor<Own<NetworkAddress>>{
|
||||
heap<UnixNetworkAddress>(path, port_hint, std::move(addresses))};
|
||||
|
|
|
@ -379,8 +379,8 @@ public:
|
|||
|
||||
socklen_t getRawLength() const { return address_length; }
|
||||
|
||||
static std::vector<SocketAddress> parse(std::string_view str,
|
||||
uint16_t port_hint) {
|
||||
static std::vector<SocketAddress> resolve(std::string_view str,
|
||||
uint16_t port_hint) {
|
||||
std::vector<SocketAddress> results;
|
||||
|
||||
struct ::addrinfo *head;
|
||||
|
@ -437,8 +437,8 @@ private:
|
|||
public:
|
||||
UnixNetwork(UnixEventPort &event_port);
|
||||
|
||||
Conveyor<Own<NetworkAddress>> parseAddress(const std::string &address,
|
||||
uint16_t port_hint = 0) override;
|
||||
Conveyor<Own<NetworkAddress>>
|
||||
resolveAddress(const std::string &address, uint16_t port_hint = 0) override;
|
||||
|
||||
Own<Server> listen(NetworkAddress &addr) override;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ public:
|
|||
};
|
||||
|
||||
class EventLoop;
|
||||
class WaitScope;
|
||||
/*
|
||||
* Event class similar to capn'proto.
|
||||
* https://github.com/capnproto/capnproto
|
||||
|
@ -219,9 +220,10 @@ public:
|
|||
ErrorOr<FixVoid<T>> take();
|
||||
|
||||
/** @todo implement
|
||||
* Specifically pump elements through this chain
|
||||
* Specifically pump elements through this chain with the provided
|
||||
* wait_scope
|
||||
*/
|
||||
void poll();
|
||||
void poll(WaitScope &wait_scope);
|
||||
|
||||
// helper
|
||||
static Conveyor<T> toConveyor(Own<ConveyorNode> node,
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <string_view>
|
||||
#include <variant>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
namespace saw {
|
||||
|
|
|
@ -156,10 +156,18 @@ public:
|
|||
virtual ~Network() = default;
|
||||
|
||||
/**
|
||||
* Parse the provided string and uint16 to the preferred storage method
|
||||
* Resolve the provided string and uint16 to the preferred storage method
|
||||
*/
|
||||
virtual Conveyor<Own<NetworkAddress>>
|
||||
parseAddress(const std::string &addr, uint16_t port_hint = 0) = 0;
|
||||
resolveAddress(const std::string &addr, uint16_t port_hint = 0) = 0;
|
||||
|
||||
/**
|
||||
* Parse the provided string and uint16 to the preferred storage method
|
||||
* Since no dns request is made here, no async conveyors have to be used.
|
||||
*/
|
||||
/// @todo implement
|
||||
// virtual Own<NetworkAddress> parseAddress(const std::string& addr,
|
||||
// uint16_t port_hint = 0) = 0;
|
||||
|
||||
/**
|
||||
* Set up a listener on this address
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#include "io_auth.h"
|
||||
|
||||
namespace saw {
|
||||
Peer::Peer(const std::string &identity_) : identity_value{identity_} {}
|
||||
Peer::Peer(std::string &&identity_) : identity_value{std::move(identity_)} {}
|
||||
|
||||
const std::string &Peer::identity() const { return identity_value; }
|
||||
} // namespace saw
|
|
@ -0,0 +1,53 @@
|
|||
#pragma once
|
||||
|
||||
#include "io.h"
|
||||
|
||||
namespace saw {
|
||||
class Peer {
|
||||
public:
|
||||
Peer(const std::string &ident);
|
||||
Peer(std::string &&ident);
|
||||
|
||||
const std::string &identity() const;
|
||||
|
||||
private:
|
||||
std::string identity_value;
|
||||
};
|
||||
|
||||
class AuthenticatedIoStream {
|
||||
public:
|
||||
// This is the easiest way to implement Authenticated streams.
|
||||
// This is a simple pair of the stream and the peer.
|
||||
|
||||
Own<IoStream> stream;
|
||||
Maybe<Own<Peer>> peer;
|
||||
};
|
||||
|
||||
class AuthenticatedServer {
|
||||
public:
|
||||
virtual ~AuthenticatedServer() = default;
|
||||
|
||||
virtual Conveyor<AuthenticatedIoStream> accept() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Authenticated Network class which provides a peer identity when connecting
|
||||
*/
|
||||
class AuthenticatedNetwork {
|
||||
public:
|
||||
virtual ~AuthenticatedNetwork() = default;
|
||||
|
||||
/**
|
||||
* Connects to the provided address.
|
||||
* Returns as soon as it is authenticated or fails
|
||||
*/
|
||||
virtual Conveyor<AuthenticatedIoStream>
|
||||
connect(NetworkAddress &address) = 0;
|
||||
|
||||
/**
|
||||
* Creates a server listening for connections
|
||||
*/
|
||||
virtual Own<AuthenticatedServer> listen() = 0;
|
||||
};
|
||||
|
||||
} // namespace saw
|
|
@ -1,15 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "async.h"
|
||||
#include "message.h"
|
||||
#include "io.h"
|
||||
#include "message.h"
|
||||
|
||||
namespace saw {
|
||||
|
||||
template <typename Codec, typename Incoming, typename Outgoing, typename InContainer = MessageContainer<Incoming>, typename OutContainer = MessageContainer<Outgoing>, typename BufferT = RingBuffer>
|
||||
template <typename Codec, typename Incoming, typename Outgoing,
|
||||
typename InContainer = MessageContainer<Incoming>,
|
||||
typename OutContainer = MessageContainer<Outgoing>,
|
||||
typename BufferT = RingBuffer>
|
||||
class StreamingIoPeer {
|
||||
private:
|
||||
Own<ConveyorFeeder<HeapMessageRoot<Incoming, InContainer>>> incoming_feeder = nullptr;
|
||||
Own<ConveyorFeeder<HeapMessageRoot<Incoming, InContainer>>>
|
||||
incoming_feeder = nullptr;
|
||||
|
||||
Own<AsyncIoStream> io_stream;
|
||||
|
||||
|
@ -22,8 +26,15 @@ private:
|
|||
SinkConveyor sink_write;
|
||||
|
||||
public:
|
||||
StreamingIoPeer(Own<ConveyorFeeder<HeapMessageRoot<Incoming, InContainer>>> feed, Own<AsyncIoStream> stream, Codec codec, BufferT in, BufferT out);
|
||||
StreamingIoPeer(Own<ConveyorFeeder<HeapMessageRoot<Incoming, InContainer>>> feed, Own<AsyncIoStream> stream);
|
||||
StreamingIoPeer(
|
||||
Own<ConveyorFeeder<HeapMessageRoot<Incoming, InContainer>>> feed,
|
||||
Own<AsyncIoStream> stream, Codec codec, BufferT in, BufferT out);
|
||||
StreamingIoPeer(
|
||||
Own<ConveyorFeeder<HeapMessageRoot<Incoming, InContainer>>> feed,
|
||||
Own<AsyncIoStream> stream);
|
||||
|
||||
SAW_FORBID_COPY(StreamingIoPeer);
|
||||
SAW_FORBID_MOVE(StreamingIoPeer);
|
||||
|
||||
void send(HeapMessageRoot<Outgoing, OutContainer> builder);
|
||||
|
||||
|
@ -32,10 +43,16 @@ public:
|
|||
|
||||
/**
|
||||
* Setup new streaming io peer with the provided network protocols.
|
||||
* This is a convenience wrapper intended for a faster setup of
|
||||
* This is a convenience wrapper intended for a faster setup of
|
||||
*/
|
||||
template <typename Codec, typename Incoming, typename Outgoing, typename InContainer = MessageContainer<Incoming>, typename OutContainer = MessageContainer<Outgoing>, typename BufferT = RingBuffer>
|
||||
std::pair<StreamingIoPeer<Codec, Incoming, Outgoing, InContainer, OutContainer, BufferT>, Conveyor<HeapMessageRoot<Incoming, InContainer>>> newStreamingIoPeer(Own<AsyncIoStream> stream);
|
||||
template <typename Codec, typename Incoming, typename Outgoing,
|
||||
typename InContainer = MessageContainer<Incoming>,
|
||||
typename OutContainer = MessageContainer<Outgoing>,
|
||||
typename BufferT = RingBuffer>
|
||||
std::pair<Own<StreamingIoPeer<Codec, Incoming, Outgoing, InContainer,
|
||||
OutContainer, BufferT>>,
|
||||
Conveyor<HeapMessageRoot<Incoming, InContainer>>>
|
||||
newStreamingIoPeer(Own<AsyncIoStream> stream);
|
||||
|
||||
} // namespace saw
|
||||
|
||||
|
|
|
@ -1,96 +1,112 @@
|
|||
namespace saw {
|
||||
|
||||
template <typename Codec, typename Incoming, typename Outgoing, typename InContainer = MessageContainer<Incoming>, typename OutContainer = MessageContainer<Outgoing>, typename BufferT = RingBuffer>
|
||||
StreamingIoPeer<Codec, Incoming, Outgoing, InContainer, OutContainer, BufferT>::StreamingIoPeer(
|
||||
Own<ConveyorFeeder<HeapMessageRoot<Incoming, InContainer>>> feed,
|
||||
Own<AsyncIoStream> str
|
||||
):
|
||||
StreamingIoPeer{std::move(feed), std::move(str), {}, {}, {}}
|
||||
{
|
||||
}
|
||||
template <typename Codec, typename Incoming, typename Outgoing,
|
||||
typename InContainer, typename OutContainer, typename BufferT>
|
||||
StreamingIoPeer<Codec, Incoming, Outgoing, InContainer, OutContainer, BufferT>::
|
||||
StreamingIoPeer(
|
||||
Own<ConveyorFeeder<HeapMessageRoot<Incoming, InContainer>>> feed,
|
||||
Own<AsyncIoStream> str)
|
||||
: StreamingIoPeer{std::move(feed), std::move(str), {}, {}, {}} {}
|
||||
|
||||
template <typename Codec, typename Incoming, typename Outgoing, typename InContainer = MessageContainer<Incoming>, typename OutContainer = MessageContainer<Outgoing>, typename BufferT = RingBuffer>
|
||||
StreamingIoPeer<Codec, Incoming, Outgoing, InContainer, OutContainer, BufferT>::StreamingIoPeer(
|
||||
Own<ConveyorFeeder<HeapMessageRoot<Incoming, InContainer>>> feed,
|
||||
Own<AsyncIoStream> str, Codec codec, BufferT in, BufferT out):
|
||||
incoming_feeder{std::move(feed)},
|
||||
io_stream{std::move(str)},
|
||||
codec{std::move(codec)},
|
||||
in_buffer{std::move(in)},
|
||||
out_buffer{std::move(out)},
|
||||
sink_read{
|
||||
io_stream->readDone().then([this](size_t bytes) -> ErrorOr<void> {
|
||||
in_buffer.writeAdvance(bytes);
|
||||
template <typename Codec, typename Incoming, typename Outgoing,
|
||||
typename InContainer, typename OutContainer, typename BufferT>
|
||||
StreamingIoPeer<Codec, Incoming, Outgoing, InContainer, OutContainer, BufferT>::
|
||||
StreamingIoPeer(
|
||||
Own<ConveyorFeeder<HeapMessageRoot<Incoming, InContainer>>> feed_,
|
||||
Own<AsyncIoStream> stream_, Codec codec_, BufferT in_, BufferT out_)
|
||||
: incoming_feeder{std::move(feed_)}, io_stream{std::move(stream_)},
|
||||
codec{std::move(codec_)}, in_buffer{std::move(in_)}, out_buffer{std::move(
|
||||
out_)},
|
||||
sink_read{io_stream->readDone()
|
||||
.then([this](size_t bytes) -> ErrorOr<void> {
|
||||
in_buffer.writeAdvance(bytes);
|
||||
|
||||
if(in_buffer.writeSegmentLength() == 0){
|
||||
return criticalError("Message too long");
|
||||
}
|
||||
if (in_buffer.writeSegmentLength() == 0) {
|
||||
return criticalError("Message too long");
|
||||
}
|
||||
|
||||
io_stream->read(&in_buffer.write(), 1, in_buffer.writeSegmentLength());
|
||||
io_stream->read(&in_buffer.write(), 1,
|
||||
in_buffer.writeSegmentLength());
|
||||
|
||||
while(true){
|
||||
auto root = heapMessageRoot<Incoming, InContainer>();
|
||||
auto builder = root.build();
|
||||
while (true) {
|
||||
auto root =
|
||||
heapMessageRoot<Incoming, InContainer>();
|
||||
auto builder = root.build();
|
||||
|
||||
Error error = codec.template decode<Incoming, InContainer>(builder, in_buffer);
|
||||
if(error.isCritical()){
|
||||
return error;
|
||||
}
|
||||
Error error =
|
||||
codec.template decode<Incoming, InContainer>(
|
||||
builder, in_buffer);
|
||||
if (error.isCritical()) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if(!error.failed()){
|
||||
incoming_feeder->handle(std::move(root));
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!error.failed()) {
|
||||
incoming_feeder->feed(std::move(root));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Void{};
|
||||
}).sink([this](Error error){
|
||||
incoming_feeder->fail(error);
|
||||
return Void{};
|
||||
})
|
||||
.sink([this](Error error) {
|
||||
incoming_feeder->fail(error.copyError());
|
||||
|
||||
return error;
|
||||
})
|
||||
},
|
||||
sink_write{
|
||||
io_stream->writeDone().then([this](size_bytes) -> ErrorOr<void> {
|
||||
out_buffer.readAdvance(bytes);
|
||||
if(out_buffer.readCompositeLength() > 0){
|
||||
io_stream->write(&out_buffer.read(), out_buffer.readSegmengtLength());
|
||||
}
|
||||
return error;
|
||||
})},
|
||||
sink_write{io_stream->writeDone()
|
||||
.then([this](size_t bytes) -> ErrorOr<void> {
|
||||
out_buffer.readAdvance(bytes);
|
||||
if (out_buffer.readCompositeLength() > 0) {
|
||||
io_stream->write(&out_buffer.read(),
|
||||
out_buffer.readSegmentLength());
|
||||
}
|
||||
|
||||
return Void{};
|
||||
}).sink();
|
||||
}
|
||||
{
|
||||
return Void{};
|
||||
})
|
||||
.sink()} {
|
||||
io_stream->read(&in_buffer.write(), 1, in_buffer.writeSegmentLength());
|
||||
}
|
||||
|
||||
template <typename Codec, typename Incoming, typename Outgoing, typename InContainer = MessageContainer<Incoming>, typename OutContainer = MessageContainer<Outgoing>, typename BufferT = RingBuffer>
|
||||
void StreamingIoPeer<Codec, Incoming, Outgoing, InContainer, OutContainer, BufferT>::send(HeapMessageRoot<Outgoing, OutContainer> msg){
|
||||
template <typename Codec, typename Incoming, typename Outgoing,
|
||||
typename InContainer, typename OutContainer, typename BufferT>
|
||||
void StreamingIoPeer<Codec, Incoming, Outgoing, InContainer, OutContainer,
|
||||
BufferT>::send(HeapMessageRoot<Outgoing, OutContainer>
|
||||
msg) {
|
||||
bool restart_write = out_buffer.readSegmentLength() == 0;
|
||||
|
||||
Error error = codec.template encode<Outgoing, OutContainer>(msg.read(), out_buffer);
|
||||
if(error.failed()){
|
||||
|
||||
Error error =
|
||||
codec.template encode<Outgoing, OutContainer>(msg.read(), out_buffer);
|
||||
if (error.failed()) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if(restart_write){
|
||||
if (restart_write) {
|
||||
io_stream->write(&out_buffer.read(), out_buffer.readSegmentLength());
|
||||
}
|
||||
|
||||
return noError();
|
||||
}
|
||||
|
||||
template <typename Codec, typename Incoming, typename Outgoing, typename InContainer = MessageContainer<Incoming>, typename OutContainer = MessageContainer<Outgoing>, typename BufferT = RingBuffer>
|
||||
Conveyor<void> StreamingIoPeer<Codec, Incoming, Outgoing, InContainer, OutContainer, BufferT>::onReadDisconnected(){
|
||||
template <typename Codec, typename Incoming, typename Outgoing,
|
||||
typename InContainer, typename OutContainer, typename BufferT>
|
||||
Conveyor<void> StreamingIoPeer<Codec, Incoming, Outgoing, InContainer,
|
||||
OutContainer, BufferT>::onReadDisconnected() {
|
||||
return io_stream->onReadDisconnected();
|
||||
}
|
||||
|
||||
template <typename Codec, typename Incoming, typename Outgoing, typename InContainer = MessageContainer<Incoming>, typename OutContainer = MessageContainer<Outgoing>, typename BufferT = RingBuffer>
|
||||
std::pair<StreamingIoPeer<Codec, Incoming, Outgoing, InContainer, OutContainer, BufferT>, Conveyor<HeapMessageRoot<Incoming, InContainer>>> newStreamingIoPeer(Own<AsyncIoStream> stream){
|
||||
template <typename Codec, typename Incoming, typename Outgoing,
|
||||
typename InContainer, typename OutContainer, typename BufferT>
|
||||
std::pair<Own<StreamingIoPeer<Codec, Incoming, Outgoing, InContainer,
|
||||
OutContainer, BufferT>>,
|
||||
Conveyor<HeapMessageRoot<Incoming, InContainer>>>
|
||||
newStreamingIoPeer(Own<AsyncIoStream> stream) {
|
||||
auto caf = newConveyorAndFeeder<HeapMessageRoot<Incoming, InContainer>>();
|
||||
|
||||
return {{std::move(caf.feeder), std::move(stream)}, std::move(caf.conveyor)};
|
||||
return {heap<StreamingIoPeer<Codec, Incoming, Outgoing, InContainer,
|
||||
OutContainer, BufferT>>(std::move(caf.feeder),
|
||||
std::move(stream)),
|
||||
std::move(caf.conveyor)};
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace saw
|
||||
|
|
|
@ -282,7 +282,7 @@ public:
|
|||
}
|
||||
|
||||
template <StringLiteral Literal>
|
||||
constexpr size_t toIndex() const noexcept {
|
||||
static constexpr size_t toIndex() noexcept {
|
||||
return MessageParameterKeyPackIndex<Literal, Keys...>::Value;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,16 +5,12 @@
|
|||
#include "stream_endian.h"
|
||||
|
||||
namespace saw {
|
||||
/// @todo replace types with these
|
||||
/*
|
||||
* I'm not really sure if anyone will use a union which is
|
||||
* bigger than uint32_t max. At least I hope noone would do this
|
||||
*/
|
||||
using msg_union_id_t = uint32_t;
|
||||
using msg_array_length_t = uint64_t;
|
||||
using msg_packet_length_t = uint64_t;
|
||||
|
||||
class ProtoKelCodec {
|
||||
public:
|
||||
using UnionIdT = uint32_t;
|
||||
using ArrayLengthT = uint64_t;
|
||||
using PacketLengthT = uint64_t;
|
||||
|
||||
private:
|
||||
struct ReadContext {
|
||||
Buffer &buffer;
|
||||
|
@ -27,10 +23,10 @@ private:
|
|||
|
||||
public:
|
||||
struct Limits {
|
||||
msg_packet_length_t packet_size;
|
||||
ProtoKelCodec::PacketLengthT packet_size;
|
||||
|
||||
Limits() : packet_size{4096} {}
|
||||
Limits(msg_packet_length_t ps) : packet_size{ps} {}
|
||||
Limits(ProtoKelCodec::PacketLengthT ps) : packet_size{ps} {}
|
||||
};
|
||||
|
||||
struct Version {
|
||||
|
@ -225,7 +221,8 @@ struct ProtoKelEncodeImpl<
|
|||
Container>::Reader reader,
|
||||
Buffer &buffer) {
|
||||
if (reader.index() == i) {
|
||||
Error error = StreamValue<msg_union_id_t>::encode(i, buffer);
|
||||
Error error =
|
||||
StreamValue<ProtoKelCodec::UnionIdT>::encode(i, buffer);
|
||||
if (error.failed()) {
|
||||
return error;
|
||||
}
|
||||
|
@ -267,7 +264,7 @@ struct ProtoKelEncodeImpl<
|
|||
static size_t
|
||||
size(typename Message<schema::Union<schema::NamedMember<V, K>...>,
|
||||
Container>::Reader reader) {
|
||||
return sizeof(msg_union_id_t) + sizeMembers<0>(reader);
|
||||
return sizeof(ProtoKelCodec::UnionIdT) + sizeMembers<0>(reader);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -276,10 +273,10 @@ struct ProtoKelEncodeImpl<Message<schema::Array<T>, Container>> {
|
|||
static Error
|
||||
encode(typename Message<schema::Array<T>, Container>::Reader data,
|
||||
Buffer &buffer) {
|
||||
msg_array_length_t array_length = data.size();
|
||||
ProtoKelCodec::ArrayLengthT array_length = data.size();
|
||||
{
|
||||
Error error =
|
||||
StreamValue<msg_array_length_t>::encode(array_length, buffer);
|
||||
Error error = StreamValue<ProtoKelCodec::ArrayLengthT>::encode(
|
||||
array_length, buffer);
|
||||
if (error.failed()) {
|
||||
return error;
|
||||
}
|
||||
|
@ -301,7 +298,7 @@ struct ProtoKelEncodeImpl<Message<schema::Array<T>, Container>> {
|
|||
*/
|
||||
static size_t
|
||||
size(typename Message<schema::Array<T>, Container>::Reader data) {
|
||||
size_t members = sizeof(msg_array_length_t);
|
||||
size_t members = sizeof(ProtoKelCodec::ArrayLengthT);
|
||||
for (size_t i = 0; i < data.size(); ++i) {
|
||||
members +=
|
||||
ProtoKelEncodeImpl<typename Container::ElementType>::size(
|
||||
|
@ -438,7 +435,7 @@ struct ProtoKelDecodeImpl<
|
|||
static typename std::enable_if<i == sizeof...(V), Error>::type
|
||||
decodeMembers(typename Message<schema::Union<schema::NamedMember<V, K>...>,
|
||||
Container>::Builder,
|
||||
Buffer &, msg_union_id_t) {
|
||||
Buffer &, ProtoKelCodec::UnionIdT) {
|
||||
return noError();
|
||||
}
|
||||
|
||||
|
@ -447,7 +444,7 @@ struct ProtoKelDecodeImpl<
|
|||
i<sizeof...(V), Error>::type decodeMembers(
|
||||
typename Message<schema::Union<schema::NamedMember<V, K>...>,
|
||||
Container>::Builder builder,
|
||||
Buffer &buffer, msg_union_id_t id) {
|
||||
Buffer &buffer, ProtoKelCodec::UnionIdT id) {
|
||||
|
||||
if (id == i) {
|
||||
Error error =
|
||||
|
@ -464,8 +461,8 @@ struct ProtoKelDecodeImpl<
|
|||
decode(typename Message<schema::Union<schema::NamedMember<V, K>...>,
|
||||
Container>::Builder builder,
|
||||
Buffer &buffer) {
|
||||
msg_union_id_t id = 0;
|
||||
Error error = StreamValue<msg_union_id_t>::decode(id, buffer);
|
||||
ProtoKelCodec::UnionIdT id = 0;
|
||||
Error error = StreamValue<ProtoKelCodec::UnionIdT>::decode(id, buffer);
|
||||
if (error.failed()) {
|
||||
return error;
|
||||
}
|
||||
|
@ -482,10 +479,10 @@ struct ProtoKelDecodeImpl<Message<schema::Array<T>, Container>> {
|
|||
static Error
|
||||
decode(typename Message<schema::Array<T>, Container>::Builder data,
|
||||
Buffer &buffer) {
|
||||
msg_array_length_t array_length = 0;
|
||||
ProtoKelCodec::ArrayLengthT array_length = 0;
|
||||
{
|
||||
Error error =
|
||||
StreamValue<msg_array_length_t>::decode(array_length, buffer);
|
||||
Error error = StreamValue<ProtoKelCodec::ArrayLengthT>::decode(
|
||||
array_length, buffer);
|
||||
if (error.failed()) {
|
||||
return error;
|
||||
}
|
||||
|
@ -510,20 +507,20 @@ Error ProtoKelCodec::encode(typename Message<Schema, Container>::Reader reader,
|
|||
Buffer &buffer) {
|
||||
BufferView view{buffer};
|
||||
|
||||
msg_packet_length_t packet_length =
|
||||
ProtoKelCodec::PacketLengthT packet_length =
|
||||
ProtoKelEncodeImpl<Message<Schema, Container>>::size(reader);
|
||||
// Check the size of the packet for the first
|
||||
// message length description
|
||||
|
||||
Error error =
|
||||
view.writeRequireLength(packet_length + sizeof(msg_packet_length_t));
|
||||
Error error = view.writeRequireLength(packet_length +
|
||||
sizeof(ProtoKelCodec::PacketLengthT));
|
||||
if (error.failed()) {
|
||||
return error;
|
||||
}
|
||||
|
||||
{
|
||||
Error error =
|
||||
StreamValue<msg_packet_length_t>::encode(packet_length, view);
|
||||
Error error = StreamValue<ProtoKelCodec::PacketLengthT>::encode(
|
||||
packet_length, view);
|
||||
if (error.failed()) {
|
||||
return error;
|
||||
}
|
||||
|
@ -546,10 +543,10 @@ Error ProtoKelCodec::decode(
|
|||
const Limits &limits) {
|
||||
BufferView view{buffer};
|
||||
|
||||
msg_packet_length_t packet_length = 0;
|
||||
ProtoKelCodec::PacketLengthT packet_length = 0;
|
||||
{
|
||||
Error error =
|
||||
StreamValue<msg_packet_length_t>::decode(packet_length, view);
|
||||
Error error = StreamValue<ProtoKelCodec::PacketLengthT>::decode(
|
||||
packet_length, view);
|
||||
if (error.failed()) {
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -235,13 +235,13 @@ static ssize_t forst_tls_pull_func(gnutls_transport_ptr_t p, void *data, size_t
|
|||
return static_cast<ssize_t>(length.value());
|
||||
}
|
||||
|
||||
TlsNetwork::TlsNetwork(Network &network) : internal{network} {}
|
||||
TlsNetwork::TlsNetwork(Tls& tls_, Network &network) : tls{tls_},internal{network} {}
|
||||
|
||||
Conveyor<Own<NetworkAddress>> TlsNetwork::parseAddress(const std::string &addr,
|
||||
Conveyor<Own<NetworkAddress>> TlsNetwork::resolveAddress(const std::string &addr,
|
||||
uint16_t port) {
|
||||
/// @todo tls server name needed. Check validity. Won't matter later on, because gnutls should fail anyway. But
|
||||
/// it's better to find the error source sooner rather than later
|
||||
return internal.parseAddress(addr, port);
|
||||
return internal.resolveAddress(addr, port);
|
||||
}
|
||||
|
||||
std::optional<Own<TlsNetwork>> setupTlsNetwork(Network &network) {
|
||||
|
|
|
@ -7,21 +7,7 @@
|
|||
#include <variant>
|
||||
|
||||
namespace saw {
|
||||
class Tls {
|
||||
private:
|
||||
class Impl;
|
||||
Own<Impl> impl;
|
||||
|
||||
public:
|
||||
Tls();
|
||||
~Tls();
|
||||
|
||||
class Options {
|
||||
public:
|
||||
};
|
||||
|
||||
Impl &getImpl();
|
||||
};
|
||||
class Tls;
|
||||
|
||||
class TlsServer final : public Server {
|
||||
private:
|
||||
|
@ -35,13 +21,12 @@ public:
|
|||
|
||||
class TlsNetwork final : public Network {
|
||||
private:
|
||||
Tls tls;
|
||||
Tls& tls;
|
||||
Network &internal;
|
||||
|
||||
public:
|
||||
TlsNetwork(Network &network);
|
||||
TlsNetwork(Tls& tls_, Network &network_);
|
||||
|
||||
Conveyor<Own<NetworkAddress>> parseAddress(const std::string &addr, uint16_t port = 0) override;
|
||||
Conveyor<Own<NetworkAddress>> resolveAddress(const std::string &addr, uint16_t port = 0) override;
|
||||
|
||||
Own<Server> listen(NetworkAddress& address) override;
|
||||
|
||||
|
@ -50,6 +35,36 @@ public:
|
|||
Own<Datagram> datagram(NetworkAddress& address) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tls context class.
|
||||
* Provides tls network class which ensures the usage of tls encrypted connections
|
||||
*/
|
||||
class Tls {
|
||||
private:
|
||||
class Impl;
|
||||
Own<Impl> impl;
|
||||
public:
|
||||
Tls();
|
||||
~Tls();
|
||||
|
||||
struct Version {
|
||||
struct Tls_1_0{};
|
||||
struct Tls_1_1{};
|
||||
struct Tls_1_2{};
|
||||
};
|
||||
|
||||
struct Options {
|
||||
public:
|
||||
Version version;
|
||||
};
|
||||
|
||||
Network& tlsNetwork();
|
||||
|
||||
Impl &getImpl();
|
||||
private:
|
||||
Options options;
|
||||
};
|
||||
|
||||
std::optional<Own<TlsNetwork>> setupTlsNetwork(Network &network);
|
||||
|
||||
} // namespace saw
|
||||
|
|
|
@ -38,8 +38,8 @@ SAW_TEST("Primitive Encoding"){
|
|||
Error error = codec.encode<TestSize>(root.read(), temp_buffer);
|
||||
|
||||
SAW_EXPECT(!error.failed(), error.message());
|
||||
SAW_EXPECT(temp_buffer.readCompositeLength() == (sizeof(value)+sizeof(msg_packet_length_t)), "Bad Size: " + std::to_string(temp_buffer.readCompositeLength()));
|
||||
constexpr size_t pkt_shift = sizeof(msg_packet_length_t);
|
||||
SAW_EXPECT(temp_buffer.readCompositeLength() == (sizeof(value)+sizeof(ProtoKelCodec::PacketLengthT)), "Bad Size: " + std::to_string(temp_buffer.readCompositeLength()));
|
||||
constexpr size_t pkt_shift = sizeof(ProtoKelCodec::PacketLengthT);
|
||||
SAW_EXPECT(temp_buffer[pkt_shift] == 5 && temp_buffer[pkt_shift+1] == 0 && temp_buffer[pkt_shift+2] == 0 && temp_buffer[pkt_shift+3] == 0, "Wrong encoded values");
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include <forstio/error.h>
|
||||
|
||||
namespace saw {
|
||||
namespace tools {
|
||||
/// @todo implement from test code base
|
||||
template<typename Schema, typename Codec>
|
||||
Error cliMessageAnalyzer(Codec& codec, int argc, char** argv){
|
||||
// Parse Args
|
||||
|
||||
// If read is required
|
||||
// Read file into buffer
|
||||
|
||||
// If read is required
|
||||
// Decode file
|
||||
|
||||
// Execute commands
|
||||
|
||||
// If write is required
|
||||
// Encode into buffer
|
||||
// Write to file from buffer
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue