Monero
Loading...
Searching...
No Matches
levin_protocol_handler.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_PROTOCOL_HANDLER_H_
30#define _LEVIN_PROTOCOL_HANDLER_H_
31
32#include <boost/uuid/uuid_generators.hpp>
33#include "levin_base.h"
34#include "int-util.h"
35
36#undef MONERO_DEFAULT_LOG_CATEGORY
37#define MONERO_DEFAULT_LOG_CATEGORY "net"
38
39namespace epee
40{
41namespace levin
42{
43 template<class t_connection_context = net_utils::connection_context_base>
50
51 template<class t_connection_context = net_utils::connection_context_base>
53 {
54 public:
55 typedef t_connection_context connection_context;
57
58 protocol_handler(net_utils::i_service_endpoint* psnd_hndlr, config_type& config, t_connection_context& conn_context);
60
61 virtual bool handle_recv(const void* ptr, size_t cb);
62
63 bool after_init_connection(){return true;}
64 private:
70
71
73 t_connection_context& m_conn_context;
75 std::string m_cach_in_buffer;
78 };
79
80 template<class t_connection_context>
88
89 template<class t_connection_context>
91 {
92 if(!m_config.m_pcommands_handler)
93 {
94 LOG_ERROR_CC(m_conn_context, "Command handler not set!");
95 return false;
96 }
97 m_cach_in_buffer.append((const char*)ptr, cb);
98
99 bool is_continue = true;
100 while(is_continue)
101 {
102 switch(m_state)
103 {
105 if(m_cach_in_buffer.size() < sizeof(bucket_head))
106 {
107 if(m_cach_in_buffer.size() >= sizeof(uint64_t) && *((uint64_t*)m_cach_in_buffer.data()) != SWAP64LE(LEVIN_SIGNATURE))
108 {
109 LOG_ERROR_CC(m_conn_context, "Signature mismatch on accepted connection");
110 return false;
111 }
112 is_continue = false;
113 break;
114 }
115 {
116#if BYTE_ORDER == LITTLE_ENDIAN
117 bucket_head &phead = *(bucket_head*)m_cach_in_buffer.data();
118#else
119 bucket_head phead = *(bucket_head*)m_cach_in_buffer.data();
120 phead.m_signature = SWAP64LE(phead.m_signature);
121 phead.m_cb = SWAP64LE(phead.m_cb);
122 phead.m_command = SWAP32LE(phead.m_command);
123 phead.m_return_code = SWAP32LE(phead.m_return_code);
124 phead.m_reservedA = SWAP32LE(phead.m_reservedA);
125 phead.m_reservedB = SWAP32LE(phead.m_reservedB);
126#endif
127 if(LEVIN_SIGNATURE != phead.m_signature)
128 {
129 LOG_ERROR_CC(m_conn_context, "Signature mismatch on accepted connection");
130 return false;
131 }
132 m_current_head = phead;
133 }
134 m_cach_in_buffer.erase(0, sizeof(bucket_head));
136 break;
138 if(m_cach_in_buffer.size() < m_current_head.m_cb)
139 {
140 is_continue = false;
141 break;
142 }
143 {
144 std::string buff_to_invoke;
145 if(m_cach_in_buffer.size() == m_current_head.m_cb)
146 buff_to_invoke.swap(m_cach_in_buffer);
147 else
148 {
149 buff_to_invoke.assign(m_cach_in_buffer, 0, (std::string::size_type)m_current_head.m_cb);
150 m_cach_in_buffer.erase(0, (std::string::size_type)m_current_head.m_cb);
151 }
152
153
154 if(m_current_head.m_have_to_return_data)
155 {
156 std::string return_buff;
157 m_current_head.m_return_code = m_config.m_pcommands_handler->invoke(m_current_head.m_command, buff_to_invoke, return_buff, m_conn_context);
158 m_current_head.m_cb = return_buff.size();
159 m_current_head.m_have_to_return_data = 0;
160
161 return_buff.insert(0, (const char*)&m_current_head, sizeof(m_current_head));
162 if(!m_psnd_hndlr->do_send(byte_slice{std::move(return_buff)}))
163 return false;
164
165 }
166 else
167 m_config.m_pcommands_handler->notify(m_current_head.m_command, buff_to_invoke, m_conn_context);
168 }
170 break;
171 default:
172 LOG_ERROR_CC(m_conn_context, "Undefined state in levin_server_impl::connection_handler, m_state=" << m_state);
173 return false;
174 }
175 }
176
177 return true;
178 }
179
180
181
182
183
184
185
186}
187}
188
189
190
191
192#endif //_LEVIN_PROTOCOL_HANDLER_H_
193
Definition byte_slice.h:69
protocl_handler_config< t_connection_context > config_type
Definition levin_protocol_handler.h:56
bool after_init_connection()
Definition levin_protocol_handler.h:63
t_connection_context connection_context
Definition levin_protocol_handler.h:55
net_utils::i_service_endpoint * m_psnd_hndlr
Definition levin_protocol_handler.h:74
virtual bool handle_recv(const void *ptr, size_t cb)
Definition levin_protocol_handler.h:90
connection_data_state m_state
Definition levin_protocol_handler.h:76
protocol_handler(net_utils::i_service_endpoint *psnd_hndlr, config_type &config, t_connection_context &conn_context)
Definition levin_protocol_handler.h:81
connection_data_state
Definition levin_protocol_handler.h:66
@ conn_state_reading_body
Definition levin_protocol_handler.h:68
@ conn_state_reading_head
Definition levin_protocol_handler.h:67
virtual ~protocol_handler()
Definition levin_protocol_handler.h:59
bucket_head m_current_head
Definition levin_protocol_handler.h:77
config_type & m_config
Definition levin_protocol_handler.h:72
std::string m_cach_in_buffer
Definition levin_protocol_handler.h:75
t_connection_context & m_conn_context
Definition levin_protocol_handler.h:73
#define SWAP64LE
Definition int-util.h:285
#define SWAP32LE
Definition int-util.h:277
#define LEVIN_SIGNATURE
Definition levin_base.h:38
Definition cryptonote_config.h:221
TODO: (mj-xmr) This will be reduced in an another PR.
Definition byte_slice.h:40
#define LOG_ERROR_CC(ct, message)
Definition net_utils_base.h:469
unsigned __int64 uint64_t
Definition stdint.h:136
Definition levin_base.h:48
uint64_t m_signature
Definition levin_base.h:49
int32_t m_return_code
Definition levin_base.h:53
uint32_t m_command
Definition levin_base.h:52
uint32_t m_reservedB
Definition levin_base.h:55
uint64_t m_cb
Definition levin_base.h:50
uint32_t m_reservedA
Definition levin_base.h:54
Definition levin_base.h:91
Definition levin_protocol_handler.h:45
void(* m_pcommands_handler_destroy)(levin_commands_handler< t_connection_context > *)
Definition levin_protocol_handler.h:47
levin_commands_handler< t_connection_context > * m_pcommands_handler
Definition levin_protocol_handler.h:46
~protocl_handler_config()
Definition levin_protocol_handler.h:48
Definition net_utils_base.h:442