Electroneum
Toggle main menu visibility
Loading...
Searching...
No Matches
zmq_server.cpp
Go to the documentation of this file.
1
// Copyright (c) 2016-2019, The Monero Project
2
//
3
// All rights reserved.
4
//
5
// Redistribution and use in source and binary forms, with or without modification, are
6
// permitted provided that the following conditions are met:
7
//
8
// 1. Redistributions of source code must retain the above copyright notice, this list of
9
// conditions and the following disclaimer.
10
//
11
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12
// of conditions and the following disclaimer in the documentation and/or other
13
// materials provided with the distribution.
14
//
15
// 3. Neither the name of the copyright holder nor the names of its contributors may be
16
// used to endorse or promote products derived from this software without specific
17
// prior written permission.
18
//
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29
#include "
zmq_server.h
"
30
31
#include <chrono>
32
#include <cstdint>
33
#include <system_error>
34
35
namespace
cryptonote
36
{
37
38
namespace
39
{
40
constexpr
const
int
num_zmq_threads = 1;
41
constexpr
const
std::int64_t max_message_size = 10 * 1024 * 1024;
// 10 MiB
42
constexpr
const
std::chrono::seconds linger_timeout{2};
// wait period for pending out messages
43
}
44
45
namespace
rpc
46
{
47
48
ZmqServer::ZmqServer
(
RpcHandler
& h) :
49
handler(h),
50
context(zmq_init(num_zmq_threads))
51
{
52
if
(!context)
53
ELECTRONEUM_ZMQ_THROW
(
"Unable to create ZMQ context"
);
54
}
55
56
ZmqServer::~ZmqServer
()
57
{
58
}
59
60
void
ZmqServer::serve
()
61
{
62
try
63
{
64
// socket must close before `zmq_term` will exit.
65
const
net::zmq::socket
socket = std::move(rep_socket);
66
if
(!socket)
67
{
68
MERROR
(
"ZMQ RPC server reply socket is null"
);
69
return
;
70
}
71
72
while
(1)
73
{
74
const
std::string
message
=
ELECTRONEUM_UNWRAP
(
net::zmq::receive
(socket.get()));
75
MDEBUG
(
"Received RPC request: \""
<<
message
<<
"\""
);
76
const
std::string& response = handler.handle(
message
);
77
78
ELECTRONEUM_UNWRAP
(
net::zmq::send
(
epee::strspan<std::uint8_t>
(response), socket.get()));
79
MDEBUG
(
"Sent RPC reply: \""
<< response <<
"\""
);
80
}
81
}
82
catch
(
const
std::system_error& e)
83
{
84
if
(e.code() !=
net::zmq::make_error_code
(ETERM))
85
MERROR
(
"ZMQ RPC Server Error: "
<< e.what());
86
}
87
catch
(
const
std::exception& e)
88
{
89
MERROR
(
"ZMQ RPC Server Error: "
<< e.what());
90
}
91
catch
(...)
92
{
93
MERROR
(
"Unknown error in ZMQ RPC server"
);
94
}
95
}
96
97
bool
ZmqServer::addIPCSocket
(
const
boost::string_ref
address
,
const
boost::string_ref port)
98
{
99
MERROR
(
"ZmqServer::addIPCSocket not yet implemented!"
);
100
return
false
;
101
}
102
103
bool
ZmqServer::addTCPSocket
(boost::string_ref
address
, boost::string_ref port)
104
{
105
if
(!context)
106
{
107
MERROR
(
"ZMQ RPC Server already shutdown"
);
108
return
false
;
109
}
110
111
rep_socket.reset(zmq_socket(context.get(), ZMQ_REP));
112
if
(!rep_socket)
113
{
114
ELECTRONEUM_LOG_ZMQ_ERROR
(
"ZMQ RPC Server socket create failed"
);
115
return
false
;
116
}
117
118
if
(zmq_setsockopt(rep_socket.get(), ZMQ_MAXMSGSIZE, std::addressof(max_message_size),
sizeof
(max_message_size)) != 0)
119
{
120
ELECTRONEUM_LOG_ZMQ_ERROR
(
"Failed to set maximum incoming message size"
);
121
return
false
;
122
}
123
124
static
constexpr
const
int
linger_value = std::chrono::milliseconds{linger_timeout}.count();
125
if
(zmq_setsockopt(rep_socket.get(), ZMQ_LINGER, std::addressof(linger_value),
sizeof
(linger_value)) != 0)
126
{
127
ELECTRONEUM_LOG_ZMQ_ERROR
(
"Failed to set linger timeout"
);
128
return
false
;
129
}
130
131
if
(
address
.empty())
132
address
=
"*"
;
133
if
(port.empty())
134
port =
"*"
;
135
136
std::string bind_address =
"tcp://"
;
137
bind_address.append(
address
.data(),
address
.size());
138
bind_address +=
":"
;
139
bind_address.append(port.data(), port.size());
140
141
if
(zmq_bind(rep_socket.get(), bind_address.c_str()) < 0)
142
{
143
ELECTRONEUM_LOG_ZMQ_ERROR
(
"ZMQ RPC Server bind failed"
);
144
return
false
;
145
}
146
return
true
;
147
}
148
149
void
ZmqServer::run
()
150
{
151
run_thread = boost::thread(boost::bind(&
ZmqServer::serve
,
this
));
152
}
153
154
void
ZmqServer::stop
()
155
{
156
if
(!run_thread.joinable())
157
return
;
158
159
context.reset();
// destroying context terminates all calls
160
run_thread.join();
161
}
162
163
164
}
// namespace cryptonote
165
166
}
// namespace rpc
cryptonote::rpc::RpcHandler
Definition
rpc_handler.h:52
cryptonote::rpc::ZmqServer::addIPCSocket
bool addIPCSocket(boost::string_ref address, boost::string_ref port)
Definition
zmq_server.cpp:97
cryptonote::rpc::ZmqServer::ZmqServer
ZmqServer(RpcHandler &h)
Definition
zmq_server.cpp:48
cryptonote::rpc::ZmqServer::run
void run()
Definition
zmq_server.cpp:149
cryptonote::rpc::ZmqServer::serve
void serve()
Definition
zmq_server.cpp:60
cryptonote::rpc::ZmqServer::~ZmqServer
~ZmqServer()
Definition
zmq_server.cpp:56
cryptonote::rpc::ZmqServer::stop
void stop()
Definition
zmq_server.cpp:154
cryptonote::rpc::ZmqServer::addTCPSocket
bool addTCPSocket(boost::string_ref address, boost::string_ref port)
Definition
zmq_server.cpp:103
message
std::string message("Message requiring signing")
ELECTRONEUM_UNWRAP
#define ELECTRONEUM_UNWRAP(...)
Definition
expect.h:60
MERROR
#define MERROR(x)
Definition
misc_log_ex.h:73
MDEBUG
#define MDEBUG(x)
Definition
misc_log_ex.h:76
cryptonote::rpc
Definition
daemon_handler.cpp:43
cryptonote
Holds cryptonote related classes and helpers.
Definition
ban.cpp:40
epee::strspan
span< const T > strspan(const std::string &s) noexcept
make a span from a std::string
Definition
span.h:171
net::zmq::send
expect< void > send(const epee::span< const std::uint8_t > payload, void *const socket, const int flags) noexcept
Definition
zmq.cpp:182
net::zmq::make_error_code
std::error_code make_error_code(int code) noexcept
Definition
zmq.h:64
net::zmq::receive
expect< std::string > receive(void *const socket, const int flags)
Definition
zmq.cpp:175
net::zmq::socket
std::unique_ptr< void, close > socket
Unique ZMQ socket handle, calls zmq_close on destruction.
Definition
zmq.h:101
address
const char * address
Definition
multisig.cpp:37
ELECTRONEUM_LOG_ZMQ_ERROR
#define ELECTRONEUM_LOG_ZMQ_ERROR(...)
Print a message followed by the current ZMQ error message.
Definition
zmq.h:46
ELECTRONEUM_ZMQ_THROW
#define ELECTRONEUM_ZMQ_THROW(msg)
Throw an exception with a custom msg, current ZMQ error code, filename, and line number.
Definition
zmq.h:53
zmq_server.h
src
rpc
zmq_server.cpp
Generated on
for Electroneum by
1.17.0