Monero
levin_base.h
Go to the documentation of this file.
1 // Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name of the Andrey N. Sabelnikov nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
19 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 //
26 
27 
28 
29 #ifndef _LEVIN_BASE_H_
30 #define _LEVIN_BASE_H_
31 
32 #include <cstdint>
33 
34 #include "byte_stream.h"
35 #include "net_utils_base.h"
36 #include "span.h"
37 
38 #define LEVIN_SIGNATURE 0x0101010101012101LL //Bender's nightmare
39 
40 namespace epee
41 {
42 class byte_slice;
43 namespace levin
44 {
45 #pragma pack(push)
46 #pragma pack(1)
47  struct bucket_head
48  {
54  uint32_t m_reservedA; //probably some flags in future
55  uint32_t m_reservedB; //probably some check sum in future
56  };
57 #pragma pack(pop)
58 
59 
60 #pragma pack(push)
61 #pragma pack(1)
62  struct bucket_head2
63  {
71  };
72 #pragma pack(pop)
73 
74 
75 #define LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED 0
76 #define LEVIN_INITIAL_MAX_PACKET_SIZE 256*1024 // 256 KiB before handshake
77 #define LEVIN_DEFAULT_MAX_PACKET_SIZE 100000000 //100MB by default after handshake
78 
79 #define LEVIN_PACKET_REQUEST 0x00000001
80 #define LEVIN_PACKET_RESPONSE 0x00000002
81 #define LEVIN_PACKET_BEGIN 0x00000004
82 #define LEVIN_PACKET_END 0x00000008
83 
84 
85 #define LEVIN_PROTOCOL_VER_0 0
86 #define LEVIN_PROTOCOL_VER_1 1
87 
88 
89  template<class t_connection_context = net_utils::connection_context_base>
91  {
92  virtual int invoke(int command, const epee::span<const uint8_t> in_buff, byte_stream& buff_out, t_connection_context& context)=0;
93  virtual int notify(int command, const epee::span<const uint8_t> in_buff, t_connection_context& context)=0;
94  virtual void callback(t_connection_context& context){};
95 
96  virtual void on_connection_new(t_connection_context& context){};
97  virtual void on_connection_close(t_connection_context& context){};
98 
100  };
101 
102 #define LEVIN_OK 0
103 #define LEVIN_ERROR_CONNECTION -1
104 #define LEVIN_ERROR_CONNECTION_NOT_FOUND -2
105 #define LEVIN_ERROR_CONNECTION_DESTROYED -3
106 #define LEVIN_ERROR_CONNECTION_TIMEDOUT -4
107 #define LEVIN_ERROR_CONNECTION_NO_DUPLEX_PROTOCOL -5
108 #define LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED -6
109 #define LEVIN_ERROR_FORMAT -7
110 
111 #define DESCRIBE_RET_CODE(code) case code: return #code;
112  inline
113  const char* get_err_descr(int err)
114  {
115  switch(err)
116  {
125  default:
126  return "unknown code";
127  }
128  }
129 
132  {
133  byte_slice finalize(uint32_t command, uint32_t flags, uint32_t return_code, bool expect_response);
134  public:
136 
137  explicit message_writer(std::size_t reserve = 8192);
138 
139  message_writer(const message_writer&) = delete;
140  message_writer(message_writer&&) = default;
141  ~message_writer() = default;
142  message_writer& operator=(const message_writer&) = delete;
144 
146  std::size_t payload_size() const noexcept
147  {
148  return buffer.size() < sizeof(header) ? 0 : buffer.size() - sizeof(header);
149  }
150 
151  byte_slice finalize_invoke(uint32_t command) { return finalize(command, LEVIN_PACKET_REQUEST, 0, true); }
152  byte_slice finalize_notify(uint32_t command) { return finalize(command, LEVIN_PACKET_REQUEST, 0, false); }
154  {
155  return finalize(command, LEVIN_PACKET_RESPONSE, return_code, false);
156  }
157 
160  };
161 
163  bucket_head2 make_header(uint32_t command, uint64_t msg_size, uint32_t flags, bool expect_response) noexcept;
164 
170  byte_slice make_noise_notify(std::size_t noise_bytes);
171 
178  byte_slice make_fragmented_notify(const std::size_t noise_size, int command, message_writer message);
179 }
180 }
181 
182 
183 #endif //_LEVIN_BASE_H_
184 
#define LEVIN_ERROR_CONNECTION_TIMEDOUT
Definition: levin_base.h:106
uint32_t m_protocol_version
Definition: levin_base.h:70
#define LEVIN_ERROR_FORMAT
Definition: levin_base.h:109
void reserve(const T &, std::size_t)
Definition: json_object.h:388
int32_t m_return_code
Definition: levin_base.h:53
uint64_t m_cb
Definition: levin_base.h:50
uint32_t m_command
Definition: levin_base.h:52
#define LEVIN_PACKET_REQUEST
Definition: levin_base.h:79
uint64_t m_cb
Definition: levin_base.h:65
A partial drop-in replacement for std::ostream.
Definition: byte_stream.h:57
const char * get_err_descr(int err)
Definition: levin_base.h:113
#define LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED
Definition: levin_base.h:108
#define LEVIN_PACKET_RESPONSE
Definition: levin_base.h:80
uint32_t m_flags
Definition: levin_base.h:69
Non-owning sequence of data. Does not deep copy.
Definition: span.h:54
uint64_t m_signature
Definition: levin_base.h:64
Definition: levin_base.h:47
std::size_t payload_size() const noexcept
Definition: levin_base.h:146
unsigned char uint8_t
Definition: stdint.h:124
Provides space for levin (p2p) header, so that payload can be sent without copy.
Definition: levin_base.h:131
uint32_t m_reservedA
Definition: levin_base.h:54
#define DESCRIBE_RET_CODE(code)
Definition: levin_base.h:111
int32_t m_return_code
Definition: levin_base.h:68
static int flags
Definition: mdb_load.c:31
uint8_t m_have_to_return_data
Definition: levin_base.h:51
virtual int notify(int command, const epee::span< const uint8_t > in_buff, t_connection_context &context)=0
Definition: levin_base.h:62
unsigned int uint32_t
Definition: stdint.h:126
virtual void callback(t_connection_context &context)
Definition: levin_base.h:94
Definition: levin_base.h:90
unsigned __int64 uint64_t
Definition: stdint.h:136
Definition: byte_slice.h:68
std::unique_ptr< void, terminate > context
Unique ZMQ context handle, calls zmq_term on destruction.
Definition: zmq.h:105
std::size_t size() const noexcept
Definition: byte_stream.h:94
byte_slice finalize_notify(uint32_t command)
Definition: levin_base.h:152
byte_slice finalize_invoke(uint32_t command)
Definition: levin_base.h:151
byte_slice finalize(uint32_t command, uint32_t flags, uint32_t return_code, bool expect_response)
Definition: levin_base.cpp:44
bucket_head2 make_header(uint32_t command, uint64_t msg_size, uint32_t flags, bool expect_response) noexcept
Definition: levin_base.cpp:56
#define LEVIN_ERROR_CONNECTION_NO_DUPLEX_PROTOCOL
Definition: levin_base.h:107
uint32_t m_command
Definition: levin_base.h:67
TODO: (mj-xmr) This will be reduced in an another PR.
Definition: byte_slice.h:39
byte_slice make_noise_notify(std::size_t noise_bytes)
Definition: levin_base.cpp:69
#define LEVIN_ERROR_CONNECTION
Definition: levin_base.h:103
uint64_t m_signature
Definition: levin_base.h:49
message_writer(std::size_t reserve=8192)
Definition: levin_base.cpp:37
message_writer & operator=(const message_writer &)=delete
virtual void on_connection_new(t_connection_context &context)
Definition: levin_base.h:96
#define LEVIN_ERROR_CONNECTION_DESTROYED
Definition: levin_base.h:105
byte_slice finalize_response(uint32_t command, uint32_t return_code)
Definition: levin_base.h:153
bucket_head2 header
Definition: levin_base.h:135
virtual int invoke(int command, const epee::span< const uint8_t > in_buff, byte_stream &buff_out, t_connection_context &context)=0
signed int int32_t
Definition: stdint.h:123
uint32_t m_reservedB
Definition: levin_base.h:55
tuple message
Definition: gtest_output_test.py:331
#define const
Definition: ipfrdr.c:80
uint8_t m_have_to_return_data
Definition: levin_base.h:66
byte_slice make_fragmented_notify(const std::size_t noise_size, int command, message_writer message)
Definition: levin_base.cpp:84
virtual void on_connection_close(t_connection_context &context)
Definition: levin_base.h:97
#define LEVIN_OK
Definition: levin_base.h:102
byte_stream buffer
Has space for levin header until a finalize method is used.
Definition: levin_base.h:159
#define LEVIN_ERROR_CONNECTION_NOT_FOUND
Definition: levin_base.h:104
virtual ~levin_commands_handler()
Definition: levin_base.h:99