Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
3d232106
Commit
3d232106
authored
Oct 31, 2022
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/neverlord/caf-net-additions'
parents
a0c97282
617955aa
Changes
26
Show whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
636 additions
and
396 deletions
+636
-396
examples/length_prefix_framing/chat-client.cpp
examples/length_prefix_framing/chat-client.cpp
+5
-1
examples/length_prefix_framing/chat-server.cpp
examples/length_prefix_framing/chat-server.cpp
+5
-1
examples/qtsupport/qt_group_chat.cpp
examples/qtsupport/qt_group_chat.cpp
+2
-1
libcaf_core/caf/async/consumer_adapter.hpp
libcaf_core/caf/async/consumer_adapter.hpp
+5
-0
libcaf_core/caf/async/producer_adapter.hpp
libcaf_core/caf/async/producer_adapter.hpp
+5
-0
libcaf_core/caf/flow/observable.hpp
libcaf_core/caf/flow/observable.hpp
+7
-1
libcaf_net/CMakeLists.txt
libcaf_net/CMakeLists.txt
+2
-0
libcaf_net/caf/detail/flow_bridge_base.hpp
libcaf_net/caf/detail/flow_bridge_base.hpp
+153
-0
libcaf_net/caf/net/binary/flow_bridge.hpp
libcaf_net/caf/net/binary/flow_bridge.hpp
+18
-122
libcaf_net/caf/net/length_prefix_framing.hpp
libcaf_net/caf/net/length_prefix_framing.hpp
+102
-94
libcaf_net/caf/net/multiplexer.hpp
libcaf_net/caf/net/multiplexer.hpp
+11
-4
libcaf_net/caf/net/ssl/connection.hpp
libcaf_net/caf/net/ssl/connection.hpp
+1
-1
libcaf_net/caf/net/ssl/context.hpp
libcaf_net/caf/net/ssl/context.hpp
+63
-5
libcaf_net/caf/net/ssl/password.hpp
libcaf_net/caf/net/ssl/password.hpp
+47
-0
libcaf_net/caf/net/ssl/verify.hpp
libcaf_net/caf/net/ssl/verify.hpp
+40
-0
libcaf_net/caf/net/web_socket/accept.hpp
libcaf_net/caf/net/web_socket/accept.hpp
+5
-0
libcaf_net/caf/net/web_socket/flow_bridge.hpp
libcaf_net/caf/net/web_socket/flow_bridge.hpp
+28
-130
libcaf_net/src/net/multiplexer.cpp
libcaf_net/src/net/multiplexer.cpp
+29
-16
libcaf_net/src/net/pollset_updater.cpp
libcaf_net/src/net/pollset_updater.cpp
+3
-3
libcaf_net/src/net/ssl/acceptor.cpp
libcaf_net/src/net/ssl/acceptor.cpp
+2
-2
libcaf_net/src/net/ssl/context.cpp
libcaf_net/src/net/ssl/context.cpp
+52
-7
libcaf_net/src/net/ssl/password.cpp
libcaf_net/src/net/ssl/password.cpp
+13
-0
libcaf_net/src/net/ssl/startup.cpp
libcaf_net/src/net/ssl/startup.cpp
+6
-0
libcaf_net/src/net/ssl/verify.cpp
libcaf_net/src/net/ssl/verify.cpp
+23
-0
libcaf_net/test/net/length_prefix_framing.cpp
libcaf_net/test/net/length_prefix_framing.cpp
+3
-2
libcaf_net/test/net/ssl/transport.cpp
libcaf_net/test/net/ssl/transport.cpp
+6
-6
No files found.
examples/length_prefix_framing/chat-client.cpp
View file @
3d232106
...
@@ -19,8 +19,12 @@
...
@@ -19,8 +19,12 @@
// -- convenience type aliases -------------------------------------------------
// -- convenience type aliases -------------------------------------------------
// The trait for translating between bytes on the wire and flow items. The
// binary default trait operates on binary::frame items.
using
trait
=
caf
::
net
::
binary
::
default_trait
;
// Takes care converting a byte stream into a sequence of messages on the wire.
// Takes care converting a byte stream into a sequence of messages on the wire.
using
lpf
=
caf
::
net
::
length_prefix_framing
;
using
lpf
=
caf
::
net
::
length_prefix_framing
::
bind
<
trait
>
;
// An implicitly shared type for storing a binary frame.
// An implicitly shared type for storing a binary frame.
using
bin_frame
=
caf
::
net
::
binary
::
frame
;
using
bin_frame
=
caf
::
net
::
binary
::
frame
;
...
...
examples/length_prefix_framing/chat-server.cpp
View file @
3d232106
...
@@ -17,8 +17,12 @@
...
@@ -17,8 +17,12 @@
// -- convenience type aliases -------------------------------------------------
// -- convenience type aliases -------------------------------------------------
// The trait for translating between bytes on the wire and flow items. The
// binary default trait operates on binary::frame items.
using
trait
=
caf
::
net
::
binary
::
default_trait
;
// Takes care converting a byte stream into a sequence of messages on the wire.
// Takes care converting a byte stream into a sequence of messages on the wire.
using
lpf
=
caf
::
net
::
length_prefix_framing
;
using
lpf
=
caf
::
net
::
length_prefix_framing
::
bind
<
trait
>
;
// An implicitly shared type for storing a binary frame.
// An implicitly shared type for storing a binary frame.
using
bin_frame
=
caf
::
net
::
binary
::
frame
;
using
bin_frame
=
caf
::
net
::
binary
::
frame
;
...
...
examples/qtsupport/qt_group_chat.cpp
View file @
3d232106
...
@@ -75,7 +75,8 @@ int caf_main(actor_system& sys, const config& cfg) {
...
@@ -75,7 +75,8 @@ int caf_main(actor_system& sys, const config& cfg) {
auto
[
lpf_pull
,
app_push
]
=
make_spsc_buffer_resource
<
bin_frame
>
();
auto
[
lpf_pull
,
app_push
]
=
make_spsc_buffer_resource
<
bin_frame
>
();
auto
[
app_pull
,
lpf_push
]
=
make_spsc_buffer_resource
<
bin_frame
>
();
auto
[
app_pull
,
lpf_push
]
=
make_spsc_buffer_resource
<
bin_frame
>
();
// Spin up the network backend.
// Spin up the network backend.
using
lpf
=
caf
::
net
::
length_prefix_framing
;
using
trait
=
caf
::
net
::
binary
::
default_trait
;
using
lpf
=
caf
::
net
::
length_prefix_framing
::
bind
<
trait
>
;
auto
conn
=
lpf
::
run
(
sys
,
*
fd
,
std
::
move
(
lpf_pull
),
std
::
move
(
lpf_push
));
auto
conn
=
lpf
::
run
(
sys
,
*
fd
,
std
::
move
(
lpf_pull
),
std
::
move
(
lpf_push
));
// Spin up Qt.
// Spin up Qt.
auto
[
argc
,
argv
]
=
cfg
.
c_args_remainder
();
auto
[
argc
,
argv
]
=
cfg
.
c_args_remainder
();
...
...
libcaf_core/caf/async/consumer_adapter.hpp
View file @
3d232106
...
@@ -140,6 +140,11 @@ public:
...
@@ -140,6 +140,11 @@ public:
impl_
->
cancel
();
impl_
->
cancel
();
}
}
consumer_adapter
&
operator
=
(
std
::
nullptr_t
)
{
impl_
=
nullptr
;
return
*
this
;
}
template
<
class
Policy
>
template
<
class
Policy
>
read_result
pull
(
Policy
policy
,
T
&
result
)
{
read_result
pull
(
Policy
policy
,
T
&
result
)
{
if
(
impl_
)
if
(
impl_
)
...
...
libcaf_core/caf/async/producer_adapter.hpp
View file @
3d232106
...
@@ -107,6 +107,11 @@ public:
...
@@ -107,6 +107,11 @@ public:
// nop
// nop
}
}
producer_adapter
&
operator
=
(
std
::
nullptr_t
)
{
impl_
=
nullptr
;
return
*
this
;
}
~
producer_adapter
()
{
~
producer_adapter
()
{
if
(
impl_
)
if
(
impl_
)
impl_
->
close
();
impl_
->
close
();
...
...
libcaf_core/caf/flow/observable.hpp
View file @
3d232106
...
@@ -607,6 +607,9 @@ auto observable<T>::merge(Inputs&&... xs) {
...
@@ -607,6 +607,9 @@ auto observable<T>::merge(Inputs&&... xs) {
static_assert
(
static_assert
(
sizeof
...(
Inputs
)
>
0
,
sizeof
...(
Inputs
)
>
0
,
"merge without arguments expects this observable to emit observables"
);
"merge without arguments expects this observable to emit observables"
);
static_assert
(
(
std
::
is_same_v
<
Out
,
output_type_t
<
std
::
decay_t
<
Inputs
>>>
&&
...),
"can only merge observables with the same observed type"
);
using
impl_t
=
op
::
merge
<
Out
>
;
using
impl_t
=
op
::
merge
<
Out
>
;
return
make_observable
<
impl_t
>
(
ctx
(),
*
this
,
std
::
forward
<
Inputs
>
(
xs
)...);
return
make_observable
<
impl_t
>
(
ctx
(),
*
this
,
std
::
forward
<
Inputs
>
(
xs
)...);
}
}
...
@@ -622,7 +625,10 @@ auto observable<T>::concat(Inputs&&... xs) {
...
@@ -622,7 +625,10 @@ auto observable<T>::concat(Inputs&&... xs) {
}
else
{
}
else
{
static_assert
(
static_assert
(
sizeof
...(
Inputs
)
>
0
,
sizeof
...(
Inputs
)
>
0
,
"merge without arguments expects this observable to emit observables"
);
"concat without arguments expects this observable to emit observables"
);
static_assert
(
(
std
::
is_same_v
<
Out
,
output_type_t
<
std
::
decay_t
<
Inputs
>>>
&&
...),
"can only concatenate observables with the same observed type"
);
using
impl_t
=
op
::
concat
<
Out
>
;
using
impl_t
=
op
::
concat
<
Out
>
;
return
make_observable
<
impl_t
>
(
ctx
(),
*
this
,
std
::
forward
<
Inputs
>
(
xs
)...);
return
make_observable
<
impl_t
>
(
ctx
(),
*
this
,
std
::
forward
<
Inputs
>
(
xs
)...);
}
}
...
...
libcaf_net/CMakeLists.txt
View file @
3d232106
...
@@ -67,9 +67,11 @@ caf_add_component(
...
@@ -67,9 +67,11 @@ caf_add_component(
src/net/ssl/context.cpp
src/net/ssl/context.cpp
src/net/ssl/dtls.cpp
src/net/ssl/dtls.cpp
src/net/ssl/format.cpp
src/net/ssl/format.cpp
src/net/ssl/password.cpp
src/net/ssl/startup.cpp
src/net/ssl/startup.cpp
src/net/ssl/tls.cpp
src/net/ssl/tls.cpp
src/net/ssl/transport.cpp
src/net/ssl/transport.cpp
src/net/ssl/verify.cpp
src/net/stream_oriented.cpp
src/net/stream_oriented.cpp
src/net/stream_socket.cpp
src/net/stream_socket.cpp
src/net/stream_transport.cpp
src/net/stream_transport.cpp
...
...
libcaf_net/caf/detail/flow_bridge_base.hpp
0 → 100644
View file @
3d232106
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#pragma once
#include "caf/async/consumer_adapter.hpp"
#include "caf/async/producer_adapter.hpp"
#include "caf/async/spsc_buffer.hpp"
#include "caf/fwd.hpp"
#include "caf/net/flow_connector.hpp"
#include "caf/sec.hpp"
#include <utility>
namespace
caf
::
detail
{
/// Translates between a message-oriented transport and data flows.
template
<
class
UpperLayer
,
class
LowerLayer
,
class
Trait
>
class
flow_bridge_base
:
public
UpperLayer
{
public:
using
input_type
=
typename
Trait
::
input_type
;
using
output_type
=
typename
Trait
::
output_type
;
/// Type for the consumer adapter. We consume the output of the application.
using
consumer_type
=
async
::
consumer_adapter
<
output_type
>
;
/// Type for the producer adapter. We produce the input of the application.
using
producer_type
=
async
::
producer_adapter
<
input_type
>
;
using
connector_pointer
=
net
::
flow_connector_ptr
<
Trait
>
;
flow_bridge_base
(
async
::
execution_context_ptr
loop
,
connector_pointer
conn
)
:
loop_
(
std
::
move
(
loop
)),
conn_
(
std
::
move
(
conn
))
{
// nop
}
virtual
bool
write
(
const
output_type
&
item
)
=
0
;
bool
running
()
const
noexcept
{
return
in_
||
out_
;
}
void
self_ref
(
disposable
ref
)
{
self_ref_
=
std
::
move
(
ref
);
}
// -- implementation of the lower_layer --------------------------------------
error
start
(
LowerLayer
*
down
,
const
settings
&
cfg
)
override
{
CAF_ASSERT
(
down
!=
nullptr
);
down_
=
down
;
auto
[
err
,
pull
,
push
]
=
conn_
->
on_request
(
cfg
);
if
(
!
err
)
{
auto
do_wakeup
=
make_action
([
this
]
{
if
(
running
())
prepare_send
();
});
auto
do_resume
=
make_action
([
this
]
{
down_
->
request_messages
();
});
auto
do_cancel
=
make_action
([
this
]
{
if
(
!
running
())
{
down_
->
shutdown
();
}
});
in_
=
consumer_type
::
make
(
pull
.
try_open
(),
loop_
,
std
::
move
(
do_wakeup
));
out_
=
producer_type
::
make
(
push
.
try_open
(),
loop_
,
std
::
move
(
do_resume
),
std
::
move
(
do_cancel
));
conn_
=
nullptr
;
if
(
running
())
return
none
;
else
return
make_error
(
sec
::
runtime_error
,
"cannot init flow bridge: no buffers"
);
}
else
{
conn_
=
nullptr
;
return
err
;
}
}
void
prepare_send
()
override
{
input_type
tmp
;
while
(
down_
->
can_send_more
())
{
switch
(
in_
.
pull
(
async
::
delay_errors
,
tmp
))
{
case
async
:
:
read_result
::
ok
:
if
(
!
write
(
tmp
))
{
abort
(
trait_
.
last_error
());
down_
->
shutdown
(
trait_
.
last_error
());
return
;
}
break
;
case
async
:
:
read_result
::
stop
:
in_
=
nullptr
;
abort
(
error
{});
down_
->
shutdown
();
return
;
case
async
:
:
read_result
::
abort
:
in_
=
nullptr
;
abort
(
in_
.
abort_reason
());
down_
->
shutdown
(
in_
.
abort_reason
());
return
;
default:
// try later
return
;
}
}
}
bool
done_sending
()
override
{
return
!
in_
.
has_consumer_event
();
}
void
abort
(
const
error
&
reason
)
override
{
CAF_LOG_TRACE
(
CAF_ARG
(
reason
));
if
(
out_
)
{
if
(
!
reason
||
reason
==
sec
::
connection_closed
||
reason
==
sec
::
socket_disconnected
||
reason
==
sec
::
disposed
)
out_
.
close
();
else
out_
.
abort
(
reason
);
out_
=
nullptr
;
}
if
(
in_
)
{
in_
.
cancel
();
in_
=
nullptr
;
}
self_ref_
=
nullptr
;
}
protected:
LowerLayer
*
down_
;
/// The output of the application. Serialized to the socket.
consumer_type
in_
;
/// The input to the application. Deserialized from the socket.
producer_type
out_
;
/// Converts between raw bytes and native C++ objects.
Trait
trait_
;
/// Our event loop.
async
::
execution_context_ptr
loop_
;
/// Initializes the bridge. Disposed (set to null) after initializing.
connector_pointer
conn_
;
/// Type-erased handle to the @ref socket_manager. This reference is important
/// to keep the bridge alive while the manager is not registered for writing
/// or reading.
disposable
self_ref_
;
};
}
// namespace caf::detail
libcaf_net/caf/net/binary/flow_bridge.hpp
View file @
3d232106
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
#include "caf/async/consumer_adapter.hpp"
#include "caf/async/consumer_adapter.hpp"
#include "caf/async/producer_adapter.hpp"
#include "caf/async/producer_adapter.hpp"
#include "caf/async/spsc_buffer.hpp"
#include "caf/async/spsc_buffer.hpp"
#include "caf/detail/flow_bridge_base.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/net/binary/lower_layer.hpp"
#include "caf/net/binary/lower_layer.hpp"
#include "caf/net/binary/upper_layer.hpp"
#include "caf/net/binary/upper_layer.hpp"
...
@@ -17,153 +18,48 @@
...
@@ -17,153 +18,48 @@
namespace
caf
::
net
::
binary
{
namespace
caf
::
net
::
binary
{
/// Convenience alias for referring to the base type of @ref flow_bridge.
template
<
class
Trait
>
using
flow_bridge_base_t
=
detail
::
flow_bridge_base
<
upper_layer
,
lower_layer
,
Trait
>
;
/// Translates between a message-oriented transport and data flows.
/// Translates between a message-oriented transport and data flows.
template
<
class
Trait
>
template
<
class
Trait
>
class
flow_bridge
:
public
upper_layer
{
class
flow_bridge
:
public
flow_bridge_base_t
<
Trait
>
{
public:
public:
using
super
=
flow_bridge_base_t
<
Trait
>
;
using
input_type
=
typename
Trait
::
input_type
;
using
input_type
=
typename
Trait
::
input_type
;
using
output_type
=
typename
Trait
::
output_type
;
using
output_type
=
typename
Trait
::
output_type
;
/// Type for the consumer adapter. We consume the output of the application.
using
consumer_type
=
async
::
consumer_adapter
<
output_type
>
;
/// Type for the producer adapter. We produce the input of the application.
using
producer_type
=
async
::
producer_adapter
<
input_type
>
;
using
connector_pointer
=
flow_connector_ptr
<
Trait
>
;
using
connector_pointer
=
flow_connector_ptr
<
Trait
>
;
explicit
flow_bridge
(
async
::
execution_context_ptr
loop
,
using
super
::
super
;
connector_pointer
conn
)
:
loop_
(
std
::
move
(
loop
)),
conn_
(
std
::
move
(
conn
))
{
// nop
}
static
std
::
unique_ptr
<
flow_bridge
>
make
(
async
::
execution_context_ptr
loop
,
static
std
::
unique_ptr
<
flow_bridge
>
make
(
async
::
execution_context_ptr
loop
,
connector_pointer
conn
)
{
connector_pointer
conn
)
{
return
std
::
make_unique
<
flow_bridge
>
(
std
::
move
(
loop
),
std
::
move
(
conn
));
return
std
::
make_unique
<
flow_bridge
>
(
std
::
move
(
loop
),
std
::
move
(
conn
));
}
}
bool
write
(
const
output_type
&
item
)
{
bool
write
(
const
output_type
&
item
)
override
{
down_
->
begin_message
();
super
::
down_
->
begin_message
();
auto
&
bytes
=
down_
->
message_buffer
();
auto
&
bytes
=
super
::
down_
->
message_buffer
();
return
trait_
.
convert
(
item
,
bytes
)
&&
down_
->
end_message
();
return
super
::
trait_
.
convert
(
item
,
bytes
)
&&
super
::
down_
->
end_message
();
}
bool
running
()
const
noexcept
{
return
in_
||
out_
;
}
void
self_ref
(
disposable
ref
)
{
self_ref_
=
std
::
move
(
ref
);
}
}
// -- implementation of binary::lower_layer ----------------------------------
// -- implementation of binary::lower_layer ----------------------------------
error
start
(
binary
::
lower_layer
*
down
,
const
settings
&
cfg
)
override
{
CAF_ASSERT
(
down
!=
nullptr
);
down_
=
down
;
auto
[
err
,
pull
,
push
]
=
conn_
->
on_request
(
cfg
);
if
(
!
err
)
{
auto
do_wakeup
=
make_action
([
this
]
{
prepare_send
();
if
(
!
running
())
down_
->
shutdown
();
});
auto
do_resume
=
make_action
([
this
]
{
down_
->
request_messages
();
});
auto
do_cancel
=
make_action
([
this
]
{
if
(
!
running
())
{
down_
->
shutdown
();
}
});
in_
=
consumer_type
::
make
(
pull
.
try_open
(),
loop_
,
std
::
move
(
do_wakeup
));
out_
=
producer_type
::
make
(
push
.
try_open
(),
loop_
,
std
::
move
(
do_resume
),
std
::
move
(
do_cancel
));
conn_
=
nullptr
;
if
(
in_
&&
out_
)
{
return
none
;
}
else
{
return
make_error
(
sec
::
runtime_error
,
"cannot init flow bridge: no buffers"
);
}
}
else
{
conn_
=
nullptr
;
return
err
;
}
}
void
prepare_send
()
override
{
input_type
tmp
;
while
(
down_
->
can_send_more
())
{
switch
(
in_
.
pull
(
async
::
delay_errors
,
tmp
))
{
case
async
:
:
read_result
::
ok
:
if
(
!
write
(
tmp
))
{
down_
->
shutdown
(
trait_
.
last_error
());
return
;
}
break
;
case
async
:
:
read_result
::
stop
:
down_
->
shutdown
();
break
;
case
async
:
:
read_result
::
abort
:
down_
->
shutdown
(
in_
.
abort_reason
());
break
;
default:
// try later
return
;
}
}
}
bool
done_sending
()
override
{
return
!
in_
.
has_consumer_event
();
}
void
abort
(
const
error
&
reason
)
override
{
CAF_LOG_TRACE
(
CAF_ARG
(
reason
));
if
(
out_
)
{
if
(
reason
==
sec
::
connection_closed
||
reason
==
sec
::
socket_disconnected
||
reason
==
sec
::
disposed
)
out_
.
close
();
else
out_
.
abort
(
reason
);
}
in_
.
cancel
();
self_ref_
=
nullptr
;
}
ptrdiff_t
consume
(
byte_span
buf
)
override
{
ptrdiff_t
consume
(
byte_span
buf
)
override
{
if
(
!
out_
)
if
(
!
super
::
out_
)
return
-
1
;
return
-
1
;
input_type
val
;
input_type
val
;
if
(
!
trait_
.
convert
(
buf
,
val
))
if
(
!
super
::
trait_
.
convert
(
buf
,
val
))
return
-
1
;
return
-
1
;
if
(
out_
.
push
(
std
::
move
(
val
))
==
0
)
if
(
super
::
out_
.
push
(
std
::
move
(
val
))
==
0
)
down_
->
suspend_reading
();
super
::
down_
->
suspend_reading
();
return
static_cast
<
ptrdiff_t
>
(
buf
.
size
());
return
static_cast
<
ptrdiff_t
>
(
buf
.
size
());
}
}
private:
lower_layer
*
down_
;
/// The output of the application. Serialized to the socket.
consumer_type
in_
;
/// The input to the application. Deserialized from the socket.
producer_type
out_
;
/// Converts between raw bytes and native C++ objects.
Trait
trait_
;
/// Our event loop.
async
::
execution_context_ptr
loop_
;
/// Initializes the bridge. Disposed (set to null) after initializing.
connector_pointer
conn_
;
/// Type-erased handle to the @ref socket_manager. This reference is important
/// to keep the bridge alive while the manager is not registered for writing
/// or reading.
disposable
self_ref_
;
};
};
}
// namespace caf::net::binary
}
// namespace caf::net::binary
libcaf_net/caf/net/length_prefix_framing.hpp
View file @
3d232106
...
@@ -56,27 +56,32 @@ public:
...
@@ -56,27 +56,32 @@ public:
// -- high-level factory functions -------------------------------------------
// -- high-level factory functions -------------------------------------------
/// Binds a trait class to the framing protocol to enable a high-level API for
/// operating on flows.
template
<
class
Trait
>
struct
bind
{
/// Describes the one-time connection event.
/// Describes the one-time connection event.
using
connect_event_t
using
connect_event_t
=
cow_tuple
<
async
::
consumer_resource
<
binary
::
frame
>
,
// Socket to App.
=
cow_tuple
<
async
::
consumer_resource
<
typename
Trait
::
input_type
>
,
async
::
producer_resource
<
binary
::
frame
>>
;
// App to Socket.
async
::
producer_resource
<
typename
Trait
::
output_type
>>
;
/// Runs length-prefix framing on given connection.
/// Runs length-prefix framing on given connection.
/// @param sys The host system.
/// @param sys The host system.
/// @param conn A connected stream socket or SSL connection, depending on the
/// @param conn A connected stream socket or SSL connection, depending on
/// the
/// `Transport`.
/// `Transport`.
/// @param pull Source for pulling data to send.
/// @param pull Source for pulling data to send.
/// @param push Source for pushing received data.
/// @param push Source for pushing received data.
template
<
class
Connection
>
template
<
class
Connection
>
static
disposable
run
(
actor_system
&
sys
,
Connection
conn
,
static
disposable
async
::
consumer_resource
<
binary
::
frame
>
pull
,
run
(
actor_system
&
sys
,
Connection
conn
,
async
::
producer_resource
<
binary
::
frame
>
push
)
{
async
::
consumer_resource
<
typename
Trait
::
output_type
>
pull
,
using
trait_t
=
binary
::
default_trait
;
async
::
producer_resource
<
typename
Trait
::
input_type
>
push
)
{
using
transport_t
=
typename
Connection
::
transport_type
;
using
transport_t
=
typename
Connection
::
transport_type
;
auto
mpx
=
sys
.
network_manager
().
mpx_ptr
();
auto
mpx
=
sys
.
network_manager
().
mpx_ptr
();
auto
fc
=
flow_connector
<
trait_
t
>::
make_trivial
(
std
::
move
(
pull
),
auto
fc
=
flow_connector
<
Trai
t
>::
make_trivial
(
std
::
move
(
pull
),
std
::
move
(
push
));
std
::
move
(
push
));
auto
bridge
=
binary
::
flow_bridge
<
trait_
t
>::
make
(
mpx
,
std
::
move
(
fc
));
auto
bridge
=
binary
::
flow_bridge
<
Trai
t
>::
make
(
mpx
,
std
::
move
(
fc
));
auto
bridge_ptr
=
bridge
.
get
();
auto
bridge_ptr
=
bridge
.
get
();
auto
impl
=
length_prefix_framing
::
make
(
std
::
move
(
bridge
));
auto
impl
=
length_prefix_framing
::
make
(
std
::
move
(
bridge
));
auto
transport
=
transport_t
::
make
(
std
::
move
(
conn
),
std
::
move
(
impl
));
auto
transport
=
transport_t
::
make
(
std
::
move
(
conn
),
std
::
move
(
impl
));
...
@@ -88,16 +93,18 @@ public:
...
@@ -88,16 +93,18 @@ public:
/// Runs length-prefix framing on given connection.
/// Runs length-prefix framing on given connection.
/// @param sys The host system.
/// @param sys The host system.
/// @param conn A connected stream socket or SSL connection, depending on the
/// @param conn A connected stream socket or SSL connection, depending on
/// the
/// `Transport`.
/// `Transport`.
/// @param init Function object for setting up the created flows.
/// @param init Function object for setting up the created flows.
template
<
class
Connection
,
class
Init
>
template
<
class
Connection
,
class
Init
>
static
disposable
run
(
actor_system
&
sys
,
Connection
conn
,
Init
init
)
{
static
disposable
run
(
actor_system
&
sys
,
Connection
conn
,
Init
init
)
{
using
app_in_t
=
typename
Trait
::
input_type
;
using
app_out_t
=
typename
Trait
::
output_type
;
static_assert
(
std
::
is_invocable_v
<
Init
,
connect_event_t
&&>
,
static_assert
(
std
::
is_invocable_v
<
Init
,
connect_event_t
&&>
,
"invalid signature found for init"
);
"invalid signature found for init"
);
using
frame_t
=
binary
::
frame
;
auto
[
app_pull
,
fd_push
]
=
async
::
make_spsc_buffer_resource
<
app_in_t
>
();
auto
[
fd_pull
,
app_push
]
=
async
::
make_spsc_buffer_resource
<
frame_t
>
();
auto
[
fd_pull
,
app_push
]
=
async
::
make_spsc_buffer_resource
<
app_out_t
>
();
auto
[
app_pull
,
fd_push
]
=
async
::
make_spsc_buffer_resource
<
frame_t
>
();
auto
result
=
run
(
sys
,
std
::
move
(
conn
),
std
::
move
(
fd_pull
),
auto
result
=
run
(
sys
,
std
::
move
(
conn
),
std
::
move
(
fd_pull
),
std
::
move
(
fd_push
));
std
::
move
(
fd_push
));
init
(
connect_event_t
{
std
::
move
(
app_pull
),
std
::
move
(
app_push
)});
init
(
connect_event_t
{
std
::
move
(
app_pull
),
std
::
move
(
app_push
)});
...
@@ -113,12 +120,11 @@ public:
...
@@ -113,12 +120,11 @@ public:
/// Describes the per-connection event.
/// Describes the per-connection event.
using
accept_event_t
using
accept_event_t
=
cow_tuple
<
async
::
consumer_resource
<
binary
::
frame
>
,
// Socket to App.
=
cow_tuple
<
async
::
consumer_resource
<
typename
Trait
::
input_type
>
,
async
::
producer_resource
<
binary
::
frame
>>
;
// App to Socket.
async
::
producer_resource
<
typename
Trait
::
output_type
>>
;
/// Convenience function for creating an event listener resource and an
/// Convenience function for creating an event listener resource and an
/// @ref acceptor_resource_t via @ref async::make_spsc_buffer_resource.
/// @ref acceptor_resource_t via @ref async::make_spsc_buffer_resource.
template
<
class
...
Ts
>
static
auto
make_accept_event_resources
()
{
static
auto
make_accept_event_resources
()
{
return
async
::
make_spsc_buffer_resource
<
accept_event_t
>
();
return
async
::
make_spsc_buffer_resource
<
accept_event_t
>
();
}
}
...
@@ -131,7 +137,8 @@ public:
...
@@ -131,7 +137,8 @@ public:
/// configuration parameter is `max-connections`.
/// configuration parameter is `max-connections`.
template
<
class
Acceptor
>
template
<
class
Acceptor
>
static
disposable
accept
(
actor_system
&
sys
,
Acceptor
acc
,
static
disposable
accept
(
actor_system
&
sys
,
Acceptor
acc
,
acceptor_resource_t
out
,
const
settings
&
cfg
=
{})
{
acceptor_resource_t
out
,
const
settings
&
cfg
=
{})
{
using
transport_t
=
typename
Acceptor
::
transport_type
;
using
transport_t
=
typename
Acceptor
::
transport_type
;
using
trait_t
=
binary
::
default_trait
;
using
trait_t
=
binary
::
default_trait
;
using
factory_t
=
cf_impl
<
transport_t
>
;
using
factory_t
=
cf_impl
<
transport_t
>
;
...
@@ -153,6 +160,7 @@ public:
...
@@ -153,6 +160,7 @@ public:
return
{};
return
{};
}
}
}
}
};
// -- implementation of stream_oriented::upper_layer -------------------------
// -- implementation of stream_oriented::upper_layer -------------------------
...
...
libcaf_net/caf/net/multiplexer.hpp
View file @
3d232106
...
@@ -4,10 +4,6 @@
...
@@ -4,10 +4,6 @@
#pragma once
#pragma once
#include <memory>
#include <mutex>
#include <thread>
#include "caf/action.hpp"
#include "caf/action.hpp"
#include "caf/async/execution_context.hpp"
#include "caf/async/execution_context.hpp"
#include "caf/detail/atomic_ref_counted.hpp"
#include "caf/detail/atomic_ref_counted.hpp"
...
@@ -19,6 +15,11 @@
...
@@ -19,6 +15,11 @@
#include "caf/ref_counted.hpp"
#include "caf/ref_counted.hpp"
#include "caf/unordered_flat_map.hpp"
#include "caf/unordered_flat_map.hpp"
#include <deque>
#include <memory>
#include <mutex>
#include <thread>
extern
"C"
{
extern
"C"
{
struct
pollfd
;
struct
pollfd
;
...
@@ -150,6 +151,9 @@ public:
...
@@ -150,6 +151,9 @@ public:
/// Applies all pending updates.
/// Applies all pending updates.
void
apply_updates
();
void
apply_updates
();
/// Runs all pending actions.
void
run_actions
();
/// Sets the thread ID to `std::this_thread::id()`.
/// Sets the thread ID to `std::this_thread::id()`.
void
set_thread_id
();
void
set_thread_id
();
...
@@ -213,6 +217,9 @@ protected:
...
@@ -213,6 +217,9 @@ protected:
/// Signals whether shutdown has been requested.
/// Signals whether shutdown has been requested.
bool
shutting_down_
=
false
;
bool
shutting_down_
=
false
;
/// Pending actions via `schedule`.
std
::
deque
<
action
>
pending_actions_
;
/// Keeps track of watched disposables.
/// Keeps track of watched disposables.
std
::
vector
<
disposable
>
watched_
;
std
::
vector
<
disposable
>
watched_
;
...
...
libcaf_net/caf/net/ssl/connection.hpp
View file @
3d232106
...
@@ -69,7 +69,7 @@ public:
...
@@ -69,7 +69,7 @@ public:
/// from a client.
/// from a client.
[[
nodiscard
]]
ptrdiff_t
accept
();
[[
nodiscard
]]
ptrdiff_t
accept
();
/// Gracefully closes the SSL connection.
/// Gracefully closes the SSL connection
without closing the socket
.
ptrdiff_t
close
();
ptrdiff_t
close
();
// -- reading and writing ----------------------------------------------------
// -- reading and writing ----------------------------------------------------
...
...
libcaf_net/caf/net/ssl/context.hpp
View file @
3d232106
...
@@ -8,9 +8,12 @@
...
@@ -8,9 +8,12 @@
#include "caf/net/ssl/dtls.hpp"
#include "caf/net/ssl/dtls.hpp"
#include "caf/net/ssl/format.hpp"
#include "caf/net/ssl/format.hpp"
#include "caf/net/ssl/fwd.hpp"
#include "caf/net/ssl/fwd.hpp"
#include "caf/net/ssl/password.hpp"
#include "caf/net/ssl/tls.hpp"
#include "caf/net/ssl/tls.hpp"
#include "caf/net/ssl/verify.hpp"
#include "caf/net/stream_socket.hpp"
#include "caf/net/stream_socket.hpp"
#include <cstring>
#include <string>
#include <string>
namespace
caf
::
net
::
ssl
{
namespace
caf
::
net
::
ssl
{
...
@@ -27,6 +30,9 @@ public:
...
@@ -27,6 +30,9 @@ public:
/// The opaque implementation type.
/// The opaque implementation type.
struct
impl
;
struct
impl
;
/// Stores additional data provided by the user.
struct
user_data
;
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
context
()
=
delete
;
context
()
=
delete
;
...
@@ -65,6 +71,30 @@ public:
...
@@ -65,6 +71,30 @@ public:
return
pimpl_
==
nullptr
;
return
pimpl_
==
nullptr
;
}
}
/// Overrides the verification mode for this context.
/// @note calls @c SSL_CTX_set_verify
void
set_verify_mode
(
verify_t
flags
);
/// Overrides the callback to obtain the password for encrypted PEM files.
/// @note calls @c SSL_CTX_set_default_passwd_cb
template
<
typename
PasswordCallback
>
void
set_password_callback
(
PasswordCallback
callback
)
{
set_password_callback_impl
(
password
::
make_callback
(
std
::
move
(
callback
)));
}
/// Overrides the callback to obtain the password for encrypted PEM files with
/// a function that always returns @p password.
/// @note calls @c SSL_CTX_set_default_passwd_cb
void
set_password
(
std
::
string
password
)
{
auto
cb
=
[
pw
=
std
::
move
(
password
)](
char
*
buf
,
int
len
,
password
::
purpose
)
{
strncpy
(
buf
,
pw
.
c_str
(),
static_cast
<
size_t
>
(
len
));
buf
[
len
-
1
]
=
'\0'
;
return
static_cast
<
int
>
(
pw
.
size
());
};
set_password_callback
(
std
::
move
(
cb
));
}
// -- native handles ---------------------------------------------------------
// -- native handles ---------------------------------------------------------
/// Reinterprets `native_handle` as the native implementation type and takes
/// Reinterprets `native_handle` as the native implementation type and takes
...
@@ -111,29 +141,57 @@ public:
...
@@ -111,29 +141,57 @@ public:
/// e.g., `9d66eef0.0` and `9d66eef0.1`.
/// e.g., `9d66eef0.0` and `9d66eef0.1`.
/// @returns `true` on success, `false` otherwise and `last_error` can be used
/// @returns `true` on success, `false` otherwise and `last_error` can be used
/// to retrieve a human-readable error representation.
/// to retrieve a human-readable error representation.
[[
nodiscard
]]
bool
load_verify_dir
(
const
char
*
path
);
/// @note Calls @c SSL_CTX_load_verify_locations
[[
nodiscard
]]
bool
add_verify_path
(
const
char
*
path
);
/// @copydoc add_verify_path
[[
nodiscard
]]
bool
add_verify_path
(
const
std
::
string
&
path
)
{
return
add_verify_path
(
path
.
c_str
());
}
/// Loads a CA certificate file.
/// Loads a CA certificate file.
/// @param path Null-terminated string with a path to a single PEM file.
/// @param path Null-terminated string with a path to a single PEM file.
/// @returns `true` on success, `false` otherwise and `last_error` can be used
/// @returns `true` on success, `false` otherwise and `last_error` can be used
/// to retrieve a human-readable error representation.
/// to retrieve a human-readable error representation.
/// @note Calls @c SSL_CTX_load_verify_locations
[[
nodiscard
]]
bool
load_verify_file
(
const
char
*
path
);
[[
nodiscard
]]
bool
load_verify_file
(
const
char
*
path
);
/// @copydoc load_verify_file
[[
nodiscard
]]
bool
load_verify_file
(
const
std
::
string
&
path
)
{
return
load_verify_file
(
path
.
c_str
());
}
/// Loads the first certificate found in given file.
/// Loads the first certificate found in given file.
/// @param path Null-terminated string with a path to a single PEM file.
/// @param path Null-terminated string with a path to a single PEM file.
[[
nodiscard
]]
bool
use_certificate_from_file
(
const
char
*
path
,
[[
nodiscard
]]
bool
use_certificate_file
(
const
char
*
path
,
format
file_format
);
format
file_format
);
/// Loads a certificate chain from a PEM-formatted file.
/// @note calls @c SSL_CTX_use_certificate_chain_file
[[
nodiscard
]]
bool
use_certificate_chain_file
(
const
char
*
path
);
/// @copydoc use_certificate_chain_file
[[
nodiscard
]]
bool
use_certificate_chain_file
(
const
std
::
string
&
path
)
{
return
use_certificate_chain_file
(
path
.
c_str
());
}
/// Loads the first private key found in given file.
/// Loads the first private key found in given file.
[[
nodiscard
]]
bool
use_private_key_from_file
(
const
char
*
path
,
[[
nodiscard
]]
bool
use_private_key_file
(
const
char
*
path
,
format
file_format
);
format
file_format
);
/// @copydoc use_private_key_file
[[
nodiscard
]]
bool
use_private_key_file
(
const
std
::
string
&
path
,
format
file_format
)
{
return
use_private_key_file
(
path
.
c_str
(),
file_format
);
}
private:
private:
constexpr
explicit
context
(
impl
*
ptr
)
:
pimpl_
(
ptr
)
{
constexpr
explicit
context
(
impl
*
ptr
)
:
pimpl_
(
ptr
)
{
// nop
// nop
}
}
void
set_password_callback_impl
(
password
::
callback_ptr
callback
);
impl
*
pimpl_
;
impl
*
pimpl_
;
user_data
*
data_
=
nullptr
;
};
};
}
// namespace caf::net::ssl
}
// namespace caf::net::ssl
libcaf_net/caf/net/ssl/password.hpp
0 → 100644
View file @
3d232106
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#include "caf/default_enum_inspect.hpp"
#include "caf/detail/net_export.hpp"
#include "caf/fwd.hpp"
#include <memory>
namespace
caf
::
net
::
ssl
::
password
{
/// Purpose of PEM password.
enum
class
purpose
{
/// SSL asks the password is reading/decryption.
reading
,
/// SSL asks the password is for writing/encryption.
writing
};
class
CAF_NET_EXPORT
callback
{
public:
virtual
~
callback
();
/// Reads the password into the buffer @p buf of size @p len.
/// @returns Written characters on success, -1 otherwise.
virtual
int
operator
()(
char
*
buf
,
int
len
,
purpose
flag
)
=
0
;
};
using
callback_ptr
=
std
::
unique_ptr
<
callback
>
;
template
<
class
PasswordCallback
>
callback_ptr
make_callback
(
PasswordCallback
callback
)
{
struct
impl
:
callback
{
explicit
impl
(
PasswordCallback
&&
cb
)
:
cb_
(
std
::
move
(
cb
))
{
// nop
}
int
operator
()(
char
*
buf
,
int
len
,
purpose
flag
)
override
{
return
cb_
(
buf
,
len
,
flag
);
}
PasswordCallback
cb_
;
};
return
std
::
make_unique
<
impl
>
(
std
::
move
(
callback
));
}
}
// namespace caf::net::ssl::password
libcaf_net/caf/net/ssl/verify.hpp
0 → 100644
View file @
3d232106
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#include "caf/default_enum_inspect.hpp"
#include "caf/detail/net_export.hpp"
#include "caf/fwd.hpp"
#include <string>
namespace
caf
::
net
::
ssl
{
/// Bitmask type for the SSL verification mode.
enum
class
verify_t
{};
namespace
verify
{
CAF_NET_EXPORT
extern
const
verify_t
none
;
CAF_NET_EXPORT
extern
const
verify_t
peer
;
CAF_NET_EXPORT
extern
const
verify_t
fail_if_no_peer_cert
;
CAF_NET_EXPORT
extern
const
verify_t
client_once
;
}
// namespace verify
constexpr
int
to_integer
(
verify_t
x
)
{
return
static_cast
<
int
>
(
x
);
}
inline
verify_t
&
operator
|=
(
verify_t
&
x
,
verify_t
y
)
noexcept
{
return
x
=
static_cast
<
verify_t
>
(
to_integer
(
x
)
|
to_integer
(
y
));
}
constexpr
verify_t
operator
|
(
verify_t
x
,
verify_t
y
)
noexcept
{
return
static_cast
<
verify_t
>
(
to_integer
(
x
)
|
to_integer
(
y
));
}
}
// namespace caf::net::ssl
libcaf_net/caf/net/web_socket/accept.hpp
View file @
3d232106
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
#include "caf/detail/accept_handler.hpp"
#include "caf/detail/accept_handler.hpp"
#include "caf/detail/connection_factory.hpp"
#include "caf/detail/connection_factory.hpp"
#include "caf/net/flow_connector.hpp"
#include "caf/net/flow_connector.hpp"
#include "caf/net/middleman.hpp"
#include "caf/net/ssl/acceptor.hpp"
#include "caf/net/ssl/acceptor.hpp"
#include "caf/net/ssl/transport.hpp"
#include "caf/net/ssl/transport.hpp"
#include "caf/net/web_socket/default_trait.hpp"
#include "caf/net/web_socket/default_trait.hpp"
...
@@ -36,6 +37,10 @@ using accept_event_t
...
@@ -36,6 +37,10 @@ using accept_event_t
template
<
class
...
Ts
>
template
<
class
...
Ts
>
using
acceptor_resource_t
=
async
::
producer_resource
<
accept_event_t
<
Ts
...
>>
;
using
acceptor_resource_t
=
async
::
producer_resource
<
accept_event_t
<
Ts
...
>>
;
/// A consumer resource for processing accepted connections.
template
<
class
...
Ts
>
using
listener_resource_t
=
async
::
consumer_resource
<
accept_event_t
<
Ts
...
>>
;
/// Convenience function for creating an event listener resource and an
/// Convenience function for creating an event listener resource and an
/// @ref acceptor_resource_t via @ref async::make_spsc_buffer_resource.
/// @ref acceptor_resource_t via @ref async::make_spsc_buffer_resource.
template
<
class
...
Ts
>
template
<
class
...
Ts
>
...
...
libcaf_net/caf/net/web_socket/flow_bridge.hpp
View file @
3d232106
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
#include "caf/async/consumer_adapter.hpp"
#include "caf/async/consumer_adapter.hpp"
#include "caf/async/producer_adapter.hpp"
#include "caf/async/producer_adapter.hpp"
#include "caf/async/spsc_buffer.hpp"
#include "caf/async/spsc_buffer.hpp"
#include "caf/detail/flow_bridge_base.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/net/flow_connector.hpp"
#include "caf/net/flow_connector.hpp"
#include "caf/net/web_socket/lower_layer.hpp"
#include "caf/net/web_socket/lower_layer.hpp"
...
@@ -18,170 +19,67 @@
...
@@ -18,170 +19,67 @@
namespace
caf
::
net
::
web_socket
{
namespace
caf
::
net
::
web_socket
{
/// Convenience alias for referring to the base type of @ref flow_bridge.
template
<
class
Trait
>
using
flow_bridge_base_t
=
detail
::
flow_bridge_base
<
upper_layer
,
lower_layer
,
Trait
>
;
/// Translates between a message-oriented transport and data flows.
/// Translates between a message-oriented transport and data flows.
template
<
class
Trait
>
template
<
class
Trait
>
class
flow_bridge
:
public
web_socket
::
upper_layer
{
class
flow_bridge
:
public
flow_bridge_base_t
<
Trait
>
{
public:
public:
using
super
=
flow_bridge_base_t
<
Trait
>
;
using
input_type
=
typename
Trait
::
input_type
;
using
input_type
=
typename
Trait
::
input_type
;
using
output_type
=
typename
Trait
::
output_type
;
using
output_type
=
typename
Trait
::
output_type
;
/// Type for the consumer adapter. We consume the output of the application.
using
consumer_type
=
async
::
consumer_adapter
<
output_type
>
;
/// Type for the producer adapter. We produce the input of the application.
using
producer_type
=
async
::
producer_adapter
<
input_type
>
;
using
request_type
=
request
<
Trait
>
;
using
connector_pointer
=
flow_connector_ptr
<
Trait
>
;
using
connector_pointer
=
flow_connector_ptr
<
Trait
>
;
explicit
flow_bridge
(
async
::
execution_context_ptr
loop
,
using
super
::
super
;
connector_pointer
conn
)
:
loop_
(
std
::
move
(
loop
)),
conn_
(
std
::
move
(
conn
))
{
// nop
}
static
std
::
unique_ptr
<
flow_bridge
>
make
(
async
::
execution_context_ptr
loop
,
static
std
::
unique_ptr
<
flow_bridge
>
make
(
async
::
execution_context_ptr
loop
,
connector_pointer
conn
)
{
connector_pointer
conn
)
{
return
std
::
make_unique
<
flow_bridge
>
(
std
::
move
(
loop
),
std
::
move
(
conn
));
return
std
::
make_unique
<
flow_bridge
>
(
std
::
move
(
loop
),
std
::
move
(
conn
));
}
}
bool
write
(
const
output_type
&
item
)
{
bool
write
(
const
output_type
&
item
)
override
{
if
(
trait_
.
converts_to_binary
(
item
))
{
if
(
super
::
trait_
.
converts_to_binary
(
item
))
{
down_
->
begin_binary_message
();
super
::
down_
->
begin_binary_message
();
auto
&
bytes
=
down_
->
binary_message_buffer
();
auto
&
bytes
=
super
::
down_
->
binary_message_buffer
();
return
trait_
.
convert
(
item
,
bytes
)
&&
down_
->
end_binary_message
();
return
super
::
trait_
.
convert
(
item
,
bytes
)
&&
super
::
down_
->
end_binary_message
();
}
else
{
}
else
{
down_
->
begin_text_message
();
super
::
down_
->
begin_text_message
();
auto
&
text
=
down_
->
text_message_buffer
();
auto
&
text
=
super
::
down_
->
text_message_buffer
();
return
trait_
.
convert
(
item
,
text
)
&&
down_
->
end_text_message
();
return
super
::
trait_
.
convert
(
item
,
text
)
&&
super
::
down_
->
end_text_message
();
}
}
}
}
bool
running
()
const
noexcept
{
return
in_
||
out_
;
}
void
self_ref
(
disposable
ref
)
{
self_ref_
=
std
::
move
(
ref
);
}
// -- implementation of web_socket::lower_layer ------------------------------
// -- implementation of web_socket::lower_layer ------------------------------
error
start
(
web_socket
::
lower_layer
*
down
,
const
settings
&
cfg
)
override
{
down_
=
down
;
auto
[
err
,
pull
,
push
]
=
conn_
->
on_request
(
cfg
);
if
(
!
err
)
{
auto
do_wakeup
=
make_action
([
this
]
{
prepare_send
();
if
(
!
running
())
down_
->
shutdown
();
});
auto
do_resume
=
make_action
([
this
]
{
down_
->
request_messages
();
});
auto
do_cancel
=
make_action
([
this
]
{
if
(
!
running
())
down_
->
shutdown
();
});
in_
=
consumer_type
::
make
(
pull
.
try_open
(),
loop_
,
std
::
move
(
do_wakeup
));
out_
=
producer_type
::
make
(
push
.
try_open
(),
loop_
,
std
::
move
(
do_resume
),
std
::
move
(
do_cancel
));
conn_
=
nullptr
;
if
(
running
())
return
none
;
else
return
make_error
(
sec
::
runtime_error
,
"cannot init flow bridge: no buffers"
);
}
else
{
conn_
=
nullptr
;
return
err
;
}
}
void
prepare_send
()
override
{
input_type
tmp
;
while
(
down_
->
can_send_more
())
{
switch
(
in_
.
pull
(
async
::
delay_errors
,
tmp
))
{
case
async
:
:
read_result
::
ok
:
if
(
!
write
(
tmp
))
{
down_
->
shutdown
(
trait_
.
last_error
());
return
;
}
break
;
case
async
:
:
read_result
::
stop
:
down_
->
shutdown
();
break
;
case
async
:
:
read_result
::
abort
:
down_
->
shutdown
(
in_
.
abort_reason
());
break
;
default:
// try later
return
;
}
}
}
bool
done_sending
()
override
{
return
!
in_
.
has_consumer_event
();
}
void
abort
(
const
error
&
reason
)
override
{
CAF_LOG_TRACE
(
CAF_ARG
(
reason
));
if
(
out_
)
{
if
(
reason
==
sec
::
connection_closed
||
reason
==
sec
::
socket_disconnected
||
reason
==
sec
::
disposed
)
{
out_
.
close
();
}
else
{
out_
.
abort
(
reason
);
}
}
in_
.
cancel
();
self_ref_
=
nullptr
;
}
ptrdiff_t
consume_binary
(
byte_span
buf
)
override
{
ptrdiff_t
consume_binary
(
byte_span
buf
)
override
{
if
(
!
out_
)
if
(
!
super
::
out_
)
return
-
1
;
return
-
1
;
input_type
val
;
input_type
val
;
if
(
!
trait_
.
convert
(
buf
,
val
))
if
(
!
super
::
trait_
.
convert
(
buf
,
val
))
return
-
1
;
return
-
1
;
if
(
out_
.
push
(
std
::
move
(
val
))
==
0
)
if
(
super
::
out_
.
push
(
std
::
move
(
val
))
==
0
)
down_
->
suspend_reading
();
super
::
down_
->
suspend_reading
();
return
static_cast
<
ptrdiff_t
>
(
buf
.
size
());
return
static_cast
<
ptrdiff_t
>
(
buf
.
size
());
}
}
ptrdiff_t
consume_text
(
std
::
string_view
buf
)
override
{
ptrdiff_t
consume_text
(
std
::
string_view
buf
)
override
{
if
(
!
out_
)
if
(
!
super
::
out_
)
return
-
1
;
return
-
1
;
input_type
val
;
input_type
val
;
if
(
!
trait_
.
convert
(
buf
,
val
))
if
(
!
super
::
trait_
.
convert
(
buf
,
val
))
return
-
1
;
return
-
1
;
if
(
out_
.
push
(
std
::
move
(
val
))
==
0
)
if
(
super
::
out_
.
push
(
std
::
move
(
val
))
==
0
)
down_
->
suspend_reading
();
super
::
down_
->
suspend_reading
();
return
static_cast
<
ptrdiff_t
>
(
buf
.
size
());
return
static_cast
<
ptrdiff_t
>
(
buf
.
size
());
}
}
private:
web_socket
::
lower_layer
*
down_
;
/// The output of the application. Serialized to the socket.
consumer_type
in_
;
/// The input to the application. Deserialized from the socket.
producer_type
out_
;
/// Converts between raw bytes and native C++ objects.
Trait
trait_
;
/// Runs callbacks in the I/O event loop.
async
::
execution_context_ptr
loop_
;
/// Initializes the bridge. Disposed (set to null) after initializing.
connector_pointer
conn_
;
/// Type-erased handle to the @ref socket_manager. This reference is important
/// to keep the bridge alive while the manager is not registered for writing
/// or reading.
disposable
self_ref_
;
};
};
}
// namespace caf::net::web_socket
}
// namespace caf::net::web_socket
libcaf_net/src/net/multiplexer.cpp
View file @
3d232106
...
@@ -171,8 +171,12 @@ void multiplexer::deref_execution_context() const noexcept {
...
@@ -171,8 +171,12 @@ void multiplexer::deref_execution_context() const noexcept {
void
multiplexer
::
schedule
(
action
what
)
{
void
multiplexer
::
schedule
(
action
what
)
{
CAF_LOG_TRACE
(
""
);
CAF_LOG_TRACE
(
""
);
if
(
std
::
this_thread
::
get_id
()
==
tid_
)
{
pending_actions_
.
push_back
(
what
);
}
else
{
auto
ptr
=
std
::
move
(
what
).
as_intrusive_ptr
().
release
();
auto
ptr
=
std
::
move
(
what
).
as_intrusive_ptr
().
release
();
write_to_pipe
(
pollset_updater
::
code
::
run_action
,
ptr
);
write_to_pipe
(
pollset_updater
::
code
::
run_action
,
ptr
);
}
}
}
void
multiplexer
::
watch
(
disposable
what
)
{
void
multiplexer
::
watch
(
disposable
what
)
{
...
@@ -309,6 +313,7 @@ void multiplexer::poll() {
...
@@ -309,6 +313,7 @@ void multiplexer::poll() {
void
multiplexer
::
apply_updates
()
{
void
multiplexer
::
apply_updates
()
{
CAF_LOG_DEBUG
(
"apply"
<<
updates_
.
size
()
<<
"updates"
);
CAF_LOG_DEBUG
(
"apply"
<<
updates_
.
size
()
<<
"updates"
);
for
(;;)
{
if
(
!
updates_
.
empty
())
{
if
(
!
updates_
.
empty
())
{
for
(
auto
&
[
fd
,
update
]
:
updates_
)
{
for
(
auto
&
[
fd
,
update
]
:
updates_
)
{
if
(
auto
index
=
index_of
(
fd
);
index
==
-
1
)
{
if
(
auto
index
=
index_of
(
fd
);
index
==
-
1
)
{
...
@@ -327,6 +332,14 @@ void multiplexer::apply_updates() {
...
@@ -327,6 +332,14 @@ void multiplexer::apply_updates() {
}
}
updates_
.
clear
();
updates_
.
clear
();
}
}
while
(
!
pending_actions_
.
empty
())
{
auto
next
=
std
::
move
(
pending_actions_
.
front
());
pending_actions_
.
pop_front
();
next
.
run
();
}
if
(
updates_
.
empty
())
return
;
}
}
}
void
multiplexer
::
set_thread_id
()
{
void
multiplexer
::
set_thread_id
()
{
...
...
libcaf_net/src/net/pollset_updater.cpp
View file @
3d232106
...
@@ -45,9 +45,9 @@ void pollset_updater::handle_read_event() {
...
@@ -45,9 +45,9 @@ void pollset_updater::handle_read_event() {
auto
as_mgr
=
[](
intptr_t
ptr
)
{
auto
as_mgr
=
[](
intptr_t
ptr
)
{
return
intrusive_ptr
{
reinterpret_cast
<
socket_manager
*>
(
ptr
),
false
};
return
intrusive_ptr
{
reinterpret_cast
<
socket_manager
*>
(
ptr
),
false
};
};
};
auto
run_action
=
[
](
intptr_t
ptr
)
{
auto
add_action
=
[
this
](
intptr_t
ptr
)
{
auto
f
=
action
{
intrusive_ptr
{
reinterpret_cast
<
action
::
impl
*>
(
ptr
),
false
}};
auto
f
=
action
{
intrusive_ptr
{
reinterpret_cast
<
action
::
impl
*>
(
ptr
),
false
}};
f
.
run
(
);
mpx_
->
pending_actions_
.
push_back
(
std
::
move
(
f
)
);
};
};
for
(;;)
{
for
(;;)
{
CAF_ASSERT
((
buf_
.
size
()
-
buf_size_
)
>
0
);
CAF_ASSERT
((
buf_
.
size
()
-
buf_size_
)
>
0
);
...
@@ -65,7 +65,7 @@ void pollset_updater::handle_read_event() {
...
@@ -65,7 +65,7 @@ void pollset_updater::handle_read_event() {
mpx_
->
do_start
(
as_mgr
(
ptr
));
mpx_
->
do_start
(
as_mgr
(
ptr
));
break
;
break
;
case
code
:
:
run_action
:
case
code
:
:
run_action
:
run
_action
(
ptr
);
add
_action
(
ptr
);
break
;
break
;
case
code
:
:
shutdown
:
case
code
:
:
shutdown
:
CAF_ASSERT
(
ptr
==
0
);
CAF_ASSERT
(
ptr
==
0
);
...
...
libcaf_net/src/net/ssl/acceptor.cpp
View file @
3d232106
...
@@ -33,11 +33,11 @@ acceptor::make_with_cert_file(tcp_accept_socket fd, const char* cert_file_path,
...
@@ -33,11 +33,11 @@ acceptor::make_with_cert_file(tcp_accept_socket fd, const char* cert_file_path,
if
(
!
ctx
)
{
if
(
!
ctx
)
{
return
{
make_error
(
sec
::
runtime_error
,
"unable to create SSL context"
)};
return
{
make_error
(
sec
::
runtime_error
,
"unable to create SSL context"
)};
}
}
if
(
!
ctx
->
use_certificate_f
rom_f
ile
(
cert_file_path
,
file_format
))
{
if
(
!
ctx
->
use_certificate_file
(
cert_file_path
,
file_format
))
{
return
{
make_error
(
sec
::
runtime_error
,
"unable to load certificate file"
,
return
{
make_error
(
sec
::
runtime_error
,
"unable to load certificate file"
,
ctx
->
last_error_string
())};
ctx
->
last_error_string
())};
}
}
if
(
!
ctx
->
use_private_key_f
rom_f
ile
(
key_file_path
,
file_format
))
{
if
(
!
ctx
->
use_private_key_file
(
key_file_path
,
file_format
))
{
return
{
make_error
(
sec
::
runtime_error
,
"unable to load private key file"
,
return
{
make_error
(
sec
::
runtime_error
,
"unable to load private key file"
,
ctx
->
last_error_string
())};
ctx
->
last_error_string
())};
}
}
...
...
libcaf_net/src/net/ssl/context.cpp
View file @
3d232106
...
@@ -23,22 +23,34 @@ auto native(context::impl* ptr) {
...
@@ -23,22 +23,34 @@ auto native(context::impl* ptr) {
}
// namespace
}
// namespace
// -- member types -------------------------------------------------------------
struct
context
::
user_data
{
password
::
callback_ptr
pw_callback
;
};
// -- constructors, destructors, and assignment operators ----------------------
// -- constructors, destructors, and assignment operators ----------------------
context
::
context
(
context
&&
other
)
{
context
::
context
(
context
&&
other
)
{
pimpl_
=
other
.
pimpl_
;
pimpl_
=
other
.
pimpl_
;
other
.
pimpl_
=
nullptr
;
other
.
pimpl_
=
nullptr
;
data_
=
other
.
data_
;
other
.
data_
=
nullptr
;
}
}
context
&
context
::
operator
=
(
context
&&
other
)
{
context
&
context
::
operator
=
(
context
&&
other
)
{
SSL_CTX_free
(
native
(
pimpl_
));
SSL_CTX_free
(
native
(
pimpl_
));
pimpl_
=
other
.
pimpl_
;
pimpl_
=
other
.
pimpl_
;
other
.
pimpl_
=
nullptr
;
other
.
pimpl_
=
nullptr
;
delete
data_
;
data_
=
other
.
data_
;
other
.
data_
=
nullptr
;
return
*
this
;
return
*
this
;
}
}
context
::~
context
()
{
context
::~
context
()
{
SSL_CTX_free
(
native
(
pimpl_
));
// Already checks for NULL.
SSL_CTX_free
(
native
(
pimpl_
));
// Already checks for NULL.
delete
data_
;
}
}
// -- factories ----------------------------------------------------------------
// -- factories ----------------------------------------------------------------
...
@@ -147,6 +159,34 @@ expected<context> context::make_client(dtls vmin, dtls vmax) {
...
@@ -147,6 +159,34 @@ expected<context> context::make_client(dtls vmin, dtls vmax) {
return
{
make_error
(
sec
::
logic_error
,
errstr
)};
return
{
make_error
(
sec
::
logic_error
,
errstr
)};
}
}
// -- properties ---------------------------------------------------------------
void
context
::
set_verify_mode
(
verify_t
flags
)
{
auto
ptr
=
native
(
pimpl_
);
SSL_CTX_set_verify
(
ptr
,
to_integer
(
flags
),
SSL_CTX_get_verify_callback
(
ptr
));
}
namespace
{
int
c_password_callback
(
char
*
buf
,
int
size
,
int
rwflag
,
void
*
ptr
)
{
if
(
ptr
==
nullptr
)
return
-
1
;
auto
flag
=
static_cast
<
password
::
purpose
>
(
rwflag
);
auto
fn
=
static_cast
<
password
::
callback
*>
(
ptr
);
return
(
*
fn
)(
buf
,
size
,
flag
);
}
}
// namespace
void
context
::
set_password_callback_impl
(
password
::
callback_ptr
callback
)
{
if
(
data_
==
nullptr
)
data_
=
new
user_data
;
auto
ptr
=
native
(
pimpl_
);
data_
->
pw_callback
=
std
::
move
(
callback
);
SSL_CTX_set_default_passwd_cb
(
ptr
,
c_password_callback
);
SSL_CTX_set_default_passwd_cb_userdata
(
ptr
,
data_
->
pw_callback
.
get
());
}
// -- native handles -----------------------------------------------------------
// -- native handles -----------------------------------------------------------
context
context
::
from_native
(
void
*
native_handle
)
{
context
context
::
from_native
(
void
*
native_handle
)
{
...
@@ -217,7 +257,7 @@ bool context::set_default_verify_paths() {
...
@@ -217,7 +257,7 @@ bool context::set_default_verify_paths() {
return
SSL_CTX_set_default_verify_paths
(
native
(
pimpl_
))
==
1
;
return
SSL_CTX_set_default_verify_paths
(
native
(
pimpl_
))
==
1
;
}
}
bool
context
::
load_verify_dir
(
const
char
*
path
)
{
bool
context
::
add_verify_path
(
const
char
*
path
)
{
ERR_clear_error
();
ERR_clear_error
();
return
SSL_CTX_load_verify_locations
(
native
(
pimpl_
),
nullptr
,
path
)
==
1
;
return
SSL_CTX_load_verify_locations
(
native
(
pimpl_
),
nullptr
,
path
)
==
1
;
}
}
...
@@ -227,16 +267,21 @@ bool context::load_verify_file(const char* path) {
...
@@ -227,16 +267,21 @@ bool context::load_verify_file(const char* path) {
return
SSL_CTX_load_verify_locations
(
native
(
pimpl_
),
path
,
nullptr
)
==
1
;
return
SSL_CTX_load_verify_locations
(
native
(
pimpl_
),
path
,
nullptr
)
==
1
;
}
}
bool
context
::
use_certificate_from_file
(
const
char
*
path
,
format
file_format
)
{
bool
context
::
use_certificate_file
(
const
char
*
path
,
format
file_format
)
{
ERR_clear_error
();
auto
nff
=
native
(
file_format
);
return
SSL_CTX_use_certificate_file
(
native
(
pimpl_
),
path
,
nff
)
==
1
;
}
bool
context
::
use_certificate_chain_file
(
const
char
*
path
)
{
ERR_clear_error
();
ERR_clear_error
();
return
SSL_CTX_use_certificate_file
(
native
(
pimpl_
),
path
,
native
(
file_format
))
return
SSL_CTX_use_certificate_chain_file
(
native
(
pimpl_
),
path
)
==
1
;
==
1
;
}
}
bool
context
::
use_private_key_f
rom_f
ile
(
const
char
*
path
,
format
file_format
)
{
bool
context
::
use_private_key_file
(
const
char
*
path
,
format
file_format
)
{
ERR_clear_error
();
ERR_clear_error
();
return
SSL_CTX_use_PrivateKey_file
(
native
(
pimpl_
),
path
,
native
(
file_format
))
auto
nff
=
native
(
file_format
);
==
1
;
return
SSL_CTX_use_PrivateKey_file
(
native
(
pimpl_
),
path
,
nff
)
==
1
;
}
}
}
// namespace caf::net::ssl
}
// namespace caf::net::ssl
libcaf_net/src/net/ssl/password.cpp
0 → 100644
View file @
3d232106
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#include "caf/net/ssl/password.hpp"
namespace
caf
::
net
::
ssl
::
password
{
callback
::~
callback
()
{
// nop
}
}
// namespace caf::net::ssl::password
libcaf_net/src/net/ssl/startup.cpp
View file @
3d232106
...
@@ -62,6 +62,8 @@ void startup() {
...
@@ -62,6 +62,8 @@ void startup() {
CRYPTO_set_dynlock_create_callback
(
dynlock_create
);
CRYPTO_set_dynlock_create_callback
(
dynlock_create
);
CRYPTO_set_dynlock_lock_callback
(
dynlock_lock
);
CRYPTO_set_dynlock_lock_callback
(
dynlock_lock
);
CRYPTO_set_dynlock_destroy_callback
(
dynlock_destroy
);
CRYPTO_set_dynlock_destroy_callback
(
dynlock_destroy
);
#else
OPENSSL_init_ssl
(
0
,
nullptr
);
#endif
#endif
}
}
...
@@ -72,6 +74,10 @@ void cleanup() {
...
@@ -72,6 +74,10 @@ void cleanup() {
CRYPTO_set_dynlock_lock_callback
(
nullptr
);
CRYPTO_set_dynlock_lock_callback
(
nullptr
);
CRYPTO_set_dynlock_destroy_callback
(
nullptr
);
CRYPTO_set_dynlock_destroy_callback
(
nullptr
);
mutexes
.
clear
();
mutexes
.
clear
();
#else
ERR_free_strings
();
EVP_cleanup
();
CRYPTO_cleanup_all_ex_data
();
#endif
#endif
}
}
...
...
libcaf_net/src/net/ssl/verify.cpp
0 → 100644
View file @
3d232106
#include "caf/net/ssl/verify.hpp"
#include <openssl/ssl.h>
namespace
caf
::
net
::
ssl
::
verify
{
namespace
{
constexpr
verify_t
i2v
(
int
x
)
{
return
static_cast
<
verify_t
>
(
x
);
}
}
// namespace
const
verify_t
none
=
i2v
(
SSL_VERIFY_NONE
);
const
verify_t
peer
=
i2v
(
SSL_VERIFY_PEER
);
const
verify_t
fail_if_no_peer_cert
=
i2v
(
SSL_VERIFY_FAIL_IF_NO_PEER_CERT
);
const
verify_t
client_once
=
i2v
(
SSL_VERIFY_CLIENT_ONCE
);
}
// namespace caf::net::ssl::verify
libcaf_net/test/net/length_prefix_framing.cpp
View file @
3d232106
...
@@ -215,7 +215,6 @@ SCENARIO("calling suspend_reading temporarily halts receiving of messages") {
...
@@ -215,7 +215,6 @@ SCENARIO("calling suspend_reading temporarily halts receiving of messages") {
app_ptr
->
continue_reading
();
app_ptr
->
continue_reading
();
mpx
->
apply_updates
();
mpx
->
apply_updates
();
mpx
->
poll_once
(
true
);
mpx
->
poll_once
(
true
);
CHECK_EQ
(
mpx
->
mask_of
(
mgr
),
net
::
operation
::
read
);
while
(
mpx
->
num_socket_managers
()
>
1u
)
while
(
mpx
->
num_socket_managers
()
>
1u
)
mpx
->
poll_once
(
true
);
mpx
->
poll_once
(
true
);
if
(
CHECK_EQ
(
buf
->
size
(),
5u
))
{
if
(
CHECK_EQ
(
buf
->
size
(),
5u
))
{
...
@@ -248,7 +247,9 @@ SCENARIO("length_prefix_framing::run translates between flows and socket I/O") {
...
@@ -248,7 +247,9 @@ SCENARIO("length_prefix_framing::run translates between flows and socket I/O") {
caf
::
actor_system
sys
{
cfg
};
caf
::
actor_system
sys
{
cfg
};
auto
buf
=
std
::
make_shared
<
std
::
vector
<
std
::
string
>>
();
auto
buf
=
std
::
make_shared
<
std
::
vector
<
std
::
string
>>
();
caf
::
actor
hdl
;
caf
::
actor
hdl
;
net
::
length_prefix_framing
::
run
(
sys
,
fd2
,
[
&
](
auto
event
)
{
using
trait
=
net
::
binary
::
default_trait
;
using
lpf
=
net
::
length_prefix_framing
::
bind
<
trait
>
;
lpf
::
run
(
sys
,
fd2
,
[
&
](
auto
event
)
{
hdl
=
sys
.
spawn
([
event
,
buf
](
event_based_actor
*
self
)
{
hdl
=
sys
.
spawn
([
event
,
buf
](
event_based_actor
*
self
)
{
auto
[
pull
,
push
]
=
event
.
data
();
auto
[
pull
,
push
]
=
event
.
data
();
pull
.
observe_on
(
self
)
pull
.
observe_on
(
self
)
...
...
libcaf_net/test/net/ssl/transport.cpp
View file @
3d232106
...
@@ -112,12 +112,12 @@ void dummy_tls_server(stream_socket fd, const char* cert_file,
...
@@ -112,12 +112,12 @@ void dummy_tls_server(stream_socket fd, const char* cert_file,
auto
guard
=
detail
::
make_scope_guard
([
fd
]
{
close
(
fd
);
});
auto
guard
=
detail
::
make_scope_guard
([
fd
]
{
close
(
fd
);
});
// Get and configure our SSL context.
// Get and configure our SSL context.
auto
ctx
=
unbox
(
ssl
::
context
::
make_server
(
ssl
::
tls
::
any
));
auto
ctx
=
unbox
(
ssl
::
context
::
make_server
(
ssl
::
tls
::
any
));
if
(
!
ctx
.
use_certificate_f
rom_f
ile
(
cert_file
,
ssl
::
format
::
pem
))
{
if
(
!
ctx
.
use_certificate_file
(
cert_file
,
ssl
::
format
::
pem
))
{
std
::
cerr
<<
"*** failed to load certificate_file: "
std
::
cerr
<<
"*** failed to load certificate_file: "
<<
ctx
.
last_error_string
()
<<
'\n'
;
<<
ctx
.
last_error_string
()
<<
'\n'
;
return
;
return
;
}
}
if
(
!
ctx
.
use_private_key_f
rom_f
ile
(
key_file
,
ssl
::
format
::
pem
))
{
if
(
!
ctx
.
use_private_key_file
(
key_file
,
ssl
::
format
::
pem
))
{
std
::
cerr
<<
"*** failed to load private key file: "
std
::
cerr
<<
"*** failed to load private key file: "
<<
ctx
.
last_error_string
()
<<
'\n'
;
<<
ctx
.
last_error_string
()
<<
'\n'
;
return
;
return
;
...
@@ -231,9 +231,9 @@ SCENARIO("ssl::transport::make_server performs the server handshake") {
...
@@ -231,9 +231,9 @@ SCENARIO("ssl::transport::make_server performs the server handshake") {
mpx
->
set_thread_id
();
mpx
->
set_thread_id
();
std
::
ignore
=
mpx
->
init
();
std
::
ignore
=
mpx
->
init
();
auto
ctx
=
unbox
(
ssl
::
context
::
make_server
(
ssl
::
tls
::
any
));
auto
ctx
=
unbox
(
ssl
::
context
::
make_server
(
ssl
::
tls
::
any
));
REQUIRE
(
ctx
.
use_certificate_f
rom_f
ile
(
cert_1_pem_path
,
//
REQUIRE
(
ctx
.
use_certificate_file
(
cert_1_pem_path
,
//
ssl
::
format
::
pem
));
ssl
::
format
::
pem
));
REQUIRE
(
ctx
.
use_private_key_f
rom_f
ile
(
key_1_pem_path
,
//
REQUIRE
(
ctx
.
use_private_key_file
(
key_1_pem_path
,
//
ssl
::
format
::
pem
));
ssl
::
format
::
pem
));
auto
conn
=
unbox
(
ctx
.
new_connection
(
server_fd
));
auto
conn
=
unbox
(
ctx
.
new_connection
(
server_fd
));
auto
done
=
std
::
make_shared
<
bool
>
(
false
);
auto
done
=
std
::
make_shared
<
bool
>
(
false
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment