Monero
net_helper.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 
30 #pragma once
31 
32 //#include <Winsock2.h>
33 //#include <Ws2tcpip.h>
34 #include <atomic>
35 #include <string>
36 #include <boost/version.hpp>
37 #include <boost/asio/io_context.hpp>
38 #include <boost/asio/ip/tcp.hpp>
39 #include <boost/asio/read.hpp>
40 #include <boost/asio/ssl.hpp>
41 #include <boost/asio/steady_timer.hpp>
42 #include <boost/thread/future.hpp>
43 #include <boost/lambda/bind.hpp>
44 #include <boost/lambda/lambda.hpp>
45 #include <boost/system/error_code.hpp>
46 #include <boost/utility/string_ref.hpp>
47 #include <functional>
48 #include "net/net_utils_base.h"
49 #include "net/net_ssl.h"
50 #include "misc_language.h"
51 
52 #undef MONERO_DEFAULT_LOG_CATEGORY
53 #define MONERO_DEFAULT_LOG_CATEGORY "net"
54 
55 #ifndef MAKE_IP
56 #define MAKE_IP( a1, a2, a3, a4 ) (a1|(a2<<8)|(a3<<16)|(a4<<24))
57 #endif
58 
59 
60 namespace epee
61 {
62 namespace net_utils
63 {
65  {
66  boost::unique_future<boost::asio::ip::tcp::socket>
67  operator()(const std::string& addr, const std::string& port, boost::asio::steady_timer&) const;
68  };
69 
70 
72  {
74  {
78  };
79 
80 
81 
82  struct handler_obj
83  {
84  handler_obj(boost::system::error_code& error, size_t& bytes_transferred):ref_error(error), ref_bytes_transferred(bytes_transferred)
85  {}
87  {}
88 
89  boost::system::error_code& ref_error;
91 
92  void operator()(const boost::system::error_code& error, // Result of operation.
93  std::size_t bytes_transferred // Number of bytes read.
94  )
95  {
96  ref_error = error;
97  ref_bytes_transferred = bytes_transferred;
98  }
99  };
100 
101  public:
102  inline
104  m_io_service(),
105  m_ctx(boost::asio::ssl::context::tlsv12),
106  m_ssl_socket(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_service, m_ctx)),
109  m_initialized(true),
110  m_connected(false),
111  m_deadline(m_io_service, std::chrono::steady_clock::time_point::max()),
112  m_shutdowned(false),
113  m_bytes_sent(0),
115  {
116  check_deadline();
117  }
118 
133  using connect_func = boost::unique_future<boost::asio::ip::tcp::socket>(const std::string&, const std::string&, boost::asio::steady_timer&);
134 
135  inline
137  {
138  //profile_tools::local_coast lc("~blocked_mode_client()", 3);
139  try { shutdown(); }
140  catch(...) { /* ignore */ }
141  }
142 
143  inline void set_ssl(ssl_options_t ssl_options)
144  {
145  if (ssl_options)
146  m_ctx = ssl_options.create_context();
147  else
148  m_ctx = boost::asio::ssl::context(boost::asio::ssl::context::tlsv12);
149  m_ssl_options = std::move(ssl_options);
150  }
151 
152  inline
153  bool connect(const std::string& addr, int port, std::chrono::milliseconds timeout)
154  {
155  return connect(addr, std::to_string(port), timeout);
156  }
157 
158  inline
159  try_connect_result_t try_connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout)
160  {
161  m_deadline.expires_after(timeout);
162  boost::unique_future<boost::asio::ip::tcp::socket> connection = m_connector(addr, port, m_deadline);
163  for (;;)
164  {
165  m_io_service.restart();
166  m_io_service.run_one();
167 
168  if (connection.is_ready())
169  break;
170  }
171 
172  m_ssl_socket->next_layer() = connection.get();
173  m_deadline.cancel();
174  if (m_ssl_socket->next_layer().is_open())
175  {
176  m_connected = true;
177  m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
178  // SSL Options
180  {
182  {
184  {
185  boost::system::error_code ignored_ec;
186  m_ssl_socket->next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
187  m_ssl_socket->next_layer().close();
188  m_connected = false;
189  return CONNECT_NO_SSL;
190  }
191  else
192  {
193  MWARNING("Failed to establish SSL connection");
194  m_connected = false;
195  return CONNECT_FAILURE;
196  }
197  }
198  }
199  return CONNECT_SUCCESS;
200  }else
201  {
202  MWARNING("Some problems at connect, expected open socket");
203  return CONNECT_FAILURE;
204  }
205 
206  }
207 
208  inline
209  bool connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout)
210  {
211  m_connected = false;
212  try
213  {
214  m_ssl_socket->next_layer().close();
215 
216  // Set SSL options
217  // disable sslv2
218  m_ssl_socket.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_service, m_ctx));
219 
220  // Get a list of endpoints corresponding to the server name.
221 
222  try_connect_result_t try_connect_result = try_connect(addr, port, timeout);
223  if (try_connect_result == CONNECT_FAILURE)
224  return false;
226  {
227  if (try_connect_result == CONNECT_NO_SSL)
228  {
229  MERROR("SSL handshake failed on an autodetect connection, reconnecting without SSL");
231  if (try_connect(addr, port, timeout) != CONNECT_SUCCESS)
232  return false;
233  }
234  }
235  }
236  catch(const boost::system::system_error& er)
237  {
238  MDEBUG("Some problems at connect, message: " << er.what());
239  return false;
240  }
241  catch(...)
242  {
243  MDEBUG("Some fatal problems.");
244  return false;
245  }
246 
247  return true;
248  }
250  void set_connector(std::function<connect_func> connector)
251  {
252  m_connector = std::move(connector);
253  }
254 
255  inline
256  bool disconnect()
257  {
258  try
259  {
260  if(m_connected)
261  {
262  m_connected = false;
263  if(m_ssl_options)
264  shutdown_ssl();
265  m_ssl_socket->next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both);
266  }
267  }
268  catch(const boost::system::system_error& /*er*/)
269  {
270  //LOG_ERROR("Some problems at disconnect, message: " << er.what());
271  return false;
272  }
273  catch(...)
274  {
275  //LOG_ERROR("Some fatal problems.");
276  return false;
277  }
278  return true;
279  }
280 
281 
282  inline
283  bool send(const boost::string_ref buff, std::chrono::milliseconds timeout)
284  {
285 
286  try
287  {
288  m_deadline.expires_after(timeout);
289 
290  // Set up the variable that receives the result of the asynchronous
291  // operation. The error code is set to would_block to signal that the
292  // operation is incomplete. Asio guarantees that its asynchronous
293  // operations will never fail with would_block, so any other value in
294  // ec indicates completion.
295  boost::system::error_code ec = boost::asio::error::would_block;
296 
297  // Start the asynchronous operation itself. The boost::lambda function
298  // object is used as a callback and will update the ec variable when the
299  // operation completes. The blocking_udp_client.cpp example shows how you
300  // can use boost::bind rather than boost::lambda.
301  async_write(buff.data(), buff.size(), ec);
302 
303  // Block until the asynchronous operation has completed.
304  while (ec == boost::asio::error::would_block)
305  {
306  m_io_service.restart();
307  m_io_service.run_one();
308  }
309 
310  if (ec)
311  {
312  LOG_PRINT_L3("Problems at write: " << ec.message());
313  m_connected = false;
314  return false;
315  }else
316  {
317  m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
318  m_bytes_sent += buff.size();
319  }
320  }
321 
322  catch(const boost::system::system_error& er)
323  {
324  LOG_ERROR("Some problems at connect, message: " << er.what());
325  return false;
326  }
327  catch(...)
328  {
329  LOG_ERROR("Some fatal problems.");
330  return false;
331  }
332 
333  return true;
334  }
335 
336  inline
337  bool send(const void* data, size_t sz)
338  {
339  try
340  {
341  /*
342  m_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
343 
344  // Set up the variable that receives the result of the asynchronous
345  // operation. The error code is set to would_block to signal that the
346  // operation is incomplete. Asio guarantees that its asynchronous
347  // operations will never fail with would_block, so any other value in
348  // ec indicates completion.
349  boost::system::error_code ec = boost::asio::error::would_block;
350 
351  // Start the asynchronous operation itself. The boost::lambda function
352  // object is used as a callback and will update the ec variable when the
353  // operation completes. The blocking_udp_client.cpp example shows how you
354  // can use boost::bind rather than boost::lambda.
355  boost::asio::async_write(m_socket, boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1);
356 
357  // Block until the asynchronous operation has completed.
358  while (ec == boost::asio::error::would_block)
359  {
360  m_io_service.run_one();
361  }
362  */
363  boost::system::error_code ec;
364 
365  size_t writen = write(data, sz, ec);
366 
367  if (!writen || ec)
368  {
369  LOG_PRINT_L3("Problems at write: " << ec.message());
370  m_connected = false;
371  return false;
372  }else
373  {
374  m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
375  m_bytes_sent += sz;
376  }
377  }
378 
379  catch(const boost::system::system_error& er)
380  {
381  LOG_ERROR("Some problems at send, message: " << er.what());
382  m_connected = false;
383  return false;
384  }
385  catch(...)
386  {
387  LOG_ERROR("Some fatal problems.");
388  return false;
389  }
390 
391  return true;
392  }
393 
394  bool is_connected(bool *ssl = NULL)
395  {
396  if (!m_connected || !m_ssl_socket->next_layer().is_open())
397  return false;
398  if (ssl)
400  return true;
401  }
402 
403  inline
404  bool recv(std::string& buff, std::chrono::milliseconds timeout)
405  {
406 
407  try
408  {
409  // Set a deadline for the asynchronous operation. Since this function uses
410  // a composed operation (async_read_until), the deadline applies to the
411  // entire operation, rather than individual reads from the socket.
412  m_deadline.expires_after(timeout);
413 
414  // Set up the variable that receives the result of the asynchronous
415  // operation. The error code is set to would_block to signal that the
416  // operation is incomplete. Asio guarantees that its asynchronous
417  // operations will never fail with would_block, so any other value in
418  // ec indicates completion.
419  //boost::system::error_code ec = boost::asio::error::would_block;
420 
421  // Start the asynchronous operation itself. The boost::lambda function
422  // object is used as a callback and will update the ec variable when the
423  // operation completes. The blocking_udp_client.cpp example shows how you
424  // can use boost::bind rather than boost::lambda.
425 
426  boost::system::error_code ec = boost::asio::error::would_block;
427  size_t bytes_transfered = 0;
428 
429  handler_obj hndlr(ec, bytes_transfered);
430 
431  static const size_t max_size = 16384;
432  buff.resize(max_size);
433 
434  async_read(&buff[0], max_size, boost::asio::transfer_at_least(1), hndlr);
435 
436  // Block until the asynchronous operation has completed.
437  while (ec == boost::asio::error::would_block && !m_shutdowned)
438  {
439  m_io_service.restart();
440  m_io_service.run_one();
441  }
442 
443 
444  if (ec)
445  {
446  MTRACE("READ ENDS: Connection err_code " << ec.value());
447  if(ec == boost::asio::error::eof)
448  {
449  MTRACE("Connection err_code eof.");
450  //connection closed there, empty
451  buff.clear();
452  return true;
453  }
454 
455  MDEBUG("Problems at read: " << ec.message());
456  m_connected = false;
457  return false;
458  }else
459  {
460  MTRACE("READ ENDS: Success. bytes_tr: " << bytes_transfered);
461  m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
462  }
463 
464  /*if(!bytes_transfered)
465  return false;*/
466 
467  m_bytes_received += bytes_transfered;
468  buff.resize(bytes_transfered);
469  return true;
470  }
471 
472  catch(const boost::system::system_error& er)
473  {
474  LOG_ERROR("Some problems at read, message: " << er.what());
475  m_connected = false;
476  return false;
477  }
478  catch(...)
479  {
480  LOG_ERROR("Some fatal problems at read.");
481  return false;
482  }
483 
484 
485 
486  return false;
487 
488  }
489 
490  inline bool recv_n(std::string& buff, int64_t sz, std::chrono::milliseconds timeout)
491  {
492 
493  try
494  {
495  // Set a deadline for the asynchronous operation. Since this function uses
496  // a composed operation (async_read_until), the deadline applies to the
497  // entire operation, rather than individual reads from the socket.
498  m_deadline.expires_after(timeout);
499 
500  // Set up the variable that receives the result of the asynchronous
501  // operation. The error code is set to would_block to signal that the
502  // operation is incomplete. Asio guarantees that its asynchronous
503  // operations will never fail with would_block, so any other value in
504  // ec indicates completion.
505  //boost::system::error_code ec = boost::asio::error::would_block;
506 
507  // Start the asynchronous operation itself. The boost::lambda function
508  // object is used as a callback and will update the ec variable when the
509  // operation completes. The blocking_udp_client.cpp example shows how you
510  // can use boost::bind rather than boost::lambda.
511 
512  buff.resize(static_cast<size_t>(sz));
513  boost::system::error_code ec = boost::asio::error::would_block;
514  size_t bytes_transfered = 0;
515 
516 
517  handler_obj hndlr(ec, bytes_transfered);
518  async_read((char*)buff.data(), buff.size(), boost::asio::transfer_at_least(buff.size()), hndlr);
519 
520  // Block until the asynchronous operation has completed.
521  while (ec == boost::asio::error::would_block && !m_shutdowned)
522  {
523  m_io_service.run_one();
524  }
525 
526  if (ec)
527  {
528  LOG_PRINT_L3("Problems at read: " << ec.message());
529  m_connected = false;
530  return false;
531  }else
532  {
533  m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
534  }
535 
536  m_bytes_received += bytes_transfered;
537  if(bytes_transfered != buff.size())
538  {
539  LOG_ERROR("Transferred mismatch with transfer_at_least value: m_bytes_transferred=" << bytes_transfered << " at_least value=" << buff.size());
540  return false;
541  }
542 
543  return true;
544  }
545 
546  catch(const boost::system::system_error& er)
547  {
548  LOG_ERROR("Some problems at read, message: " << er.what());
549  m_connected = false;
550  return false;
551  }
552  catch(...)
553  {
554  LOG_ERROR("Some fatal problems at read.");
555  return false;
556  }
557 
558 
559 
560  return false;
561  }
562 
563  bool shutdown()
564  {
565  m_deadline.cancel();
566  boost::system::error_code ec;
567  if(m_ssl_options)
568  shutdown_ssl();
569  m_ssl_socket->next_layer().cancel(ec);
570  if(ec)
571  MDEBUG("Problems at cancel: " << ec.message());
572  m_ssl_socket->next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
573  if(ec)
574  MDEBUG("Problems at shutdown: " << ec.message());
575  m_ssl_socket->next_layer().close(ec);
576  if(ec)
577  MDEBUG("Problems at close: " << ec.message());
578  m_shutdowned = true;
579  m_connected = false;
580  return true;
581  }
582 
583  boost::asio::io_context& get_io_service()
584  {
585  return m_io_service;
586  }
587 
589  {
590  return m_ssl_socket->next_layer();
591  }
592 
594  {
595  return m_bytes_sent;
596  }
597 
599  {
600  return m_bytes_received;
601  }
602 
603  private:
604 
606  {
607  // Check whether the deadline has passed. We compare the deadline against
608  // the current time since a new asynchronous operation may have moved the
609  // deadline before this actor had a chance to run.
610  if (m_deadline.expiry() <= std::chrono::steady_clock::now())
611  {
612  // The deadline has passed. The socket is closed so that any outstanding
613  // asynchronous operations are cancelled. This allows the blocked
614  // connect(), read_line() or write_line() functions to return.
615  LOG_PRINT_L3("Timed out socket");
616  m_connected = false;
617  m_ssl_socket->next_layer().close();
618 
619  // There is no longer an active deadline. The expiry is set to positive
620  // infinity so that the actor takes no action until a new deadline is set.
621  m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
622  }
623 
624  // Put the actor back to sleep.
625  m_deadline.async_wait(boost::bind(&blocked_mode_client::check_deadline, this));
626  }
627 
628  void shutdown_ssl() {
629  // ssl socket shutdown blocks if server doesn't respond. We close after 2 secs
630  boost::system::error_code ec = boost::asio::error::would_block;
631  m_deadline.expires_after(std::chrono::milliseconds(2000));
632  m_ssl_socket->async_shutdown(boost::lambda::var(ec) = boost::lambda::_1);
633  while (ec == boost::asio::error::would_block)
634  {
635  m_io_service.restart();
636  m_io_service.run_one();
637  }
638  // Ignore "short read" error
639  if (ec.category() == boost::asio::error::get_ssl_category() &&
640  ec.value() !=
641 #if BOOST_VERSION >= 106200
642  boost::asio::ssl::error::stream_truncated
643 #else // older Boost supports only OpenSSL 1.0, so 1.0-only macros are appropriate
644  ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ)
645 #endif
646  )
647  MDEBUG("Problems at ssl shutdown: " << ec.message());
648  }
649 
650  protected:
651  bool write(const void* data, size_t sz, boost::system::error_code& ec)
652  {
653  bool success;
655  success = boost::asio::write(*m_ssl_socket, boost::asio::buffer(data, sz), ec);
656  else
657  success = boost::asio::write(m_ssl_socket->next_layer(), boost::asio::buffer(data, sz), ec);
658  return success;
659  }
660 
661  void async_write(const void* data, size_t sz, boost::system::error_code& ec)
662  {
664  boost::asio::async_write(*m_ssl_socket, boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1);
665  else
666  boost::asio::async_write(m_ssl_socket->next_layer(), boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1);
667  }
668 
669  void async_read(char* buff, size_t sz, boost::asio::detail::transfer_at_least_t transfer_at_least, handler_obj& hndlr)
670  {
672  boost::asio::async_read(m_ssl_socket->next_layer(), boost::asio::buffer(buff, sz), transfer_at_least, hndlr);
673  else
674  boost::asio::async_read(*m_ssl_socket, boost::asio::buffer(buff, sz), transfer_at_least, hndlr);
675 
676  }
677 
678  protected:
679  boost::asio::io_context m_io_service;
681  std::shared_ptr<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> m_ssl_socket;
682  std::function<connect_func> m_connector;
686  boost::asio::steady_timer m_deadline;
687  std::atomic<bool> m_shutdowned;
688  std::atomic<uint64_t> m_bytes_sent;
689  std::atomic<uint64_t> m_bytes_received;
690  };
691 }
692 }
693 
void async_write(const void *data, size_t sz, boost::system::error_code &ec)
Definition: net_helper.h:661
void set_connector(std::function< connect_func > connector)
Change the connection routine (proxy, etc.)
Definition: net_helper.h:250
boost::asio::ssl::context m_ctx
Definition: net_helper.h:680
boost::system::error_code & ref_error
Definition: net_helper.h:89
void check_deadline()
Definition: net_helper.h:605
Definition: net_helper.h:71
Definition: net_ssl.h:76
uint64_t get_bytes_received() const
Definition: net_helper.h:598
void set_ssl(ssl_options_t ssl_options)
Definition: net_helper.h:143
std::shared_ptr< boost::asio::ssl::stream< boost::asio::ip::tcp::socket > > m_ssl_socket
Definition: net_helper.h:681
Definition: portable_binary_archive.hpp:29
var
Definition: console.py:92
size_t & ref_bytes_transferred
Definition: net_helper.h:90
::std::string string
Definition: gtest-port.h:1097
bool shutdown()
Definition: net_helper.h:563
bool send(const void *data, size_t sz)
Definition: net_helper.h:337
std::string data
Definition: base58.cpp:37
std::unique_ptr< void, close > socket
Unique ZMQ socket handle, calls zmq_close on destruction.
Definition: zmq.h:108
bool m_initialized
Definition: net_helper.h:684
boost::unique_future< boost::asio::ip::tcp::socket >(const std::string &, const std::string &, boost::asio::steady_timer &) connect_func
Definition: net_helper.h:133
bool is_connected(bool *ssl=NULL)
Definition: net_helper.h:394
bool disconnect()
Definition: net_helper.h:256
bool connect(const std::string &addr, const std::string &port, std::chrono::milliseconds timeout)
Definition: net_helper.h:209
handler_obj(boost::system::error_code &error, size_t &bytes_transferred)
Definition: net_helper.h:84
void shutdown_ssl()
Definition: net_helper.h:628
const T buffer
Definition: byte_slice.cpp:83
ssl_options_t m_ssl_options
Definition: net_helper.h:683
bool connect(const std::string &addr, int port, std::chrono::milliseconds timeout)
Definition: net_helper.h:153
std::atomic< bool > m_shutdowned
Definition: net_helper.h:687
Represents a single connection from a client.
Definition: abstract_tcp_server2.h:95
unsigned __int64 uint64_t
Definition: stdint.h:136
boost::asio::steady_timer m_deadline
Definition: net_helper.h:686
ssl_support_t support
Definition: net_ssl.h:84
std::unique_ptr< void, terminate > context
Unique ZMQ context handle, calls zmq_term on destruction.
Definition: zmq.h:105
bool write(const void *data, size_t sz, boost::system::error_code &ec)
Definition: net_helper.h:651
void operator()(const boost::system::error_code &error, std::size_t bytes_transferred)
Definition: net_helper.h:92
bool success
Definition: cold-transaction.cpp:57
boost::endian::big_uint32_t ip
Definition: socks.cpp:62
boost::endian::big_uint16_t port
Definition: socks.cpp:61
blocked_mode_client()
Definition: net_helper.h:103
TODO: (mj-xmr) This will be reduced in an another PR.
Definition: byte_slice.h:39
const T & move(const T &t)
Definition: gtest-port.h:1317
Definition: net_helper.h:64
boost::asio::io_context & get_io_service()
Definition: net_helper.h:583
signed __int64 int64_t
Definition: stdint.h:135
~blocked_mode_client()
Definition: net_helper.h:136
std::function< connect_func > m_connector
Definition: net_helper.h:682
bool m_connected
Definition: net_helper.h:685
try_connect_result_t
Definition: net_helper.h:73
handler_obj(const handler_obj &other_obj)
Definition: net_helper.h:86
try_connect_result_t try_connect(const std::string &addr, const std::string &port, std::chrono::milliseconds timeout)
Definition: net_helper.h:159
bool recv_n(std::string &buff, int64_t sz, std::chrono::milliseconds timeout)
Definition: net_helper.h:490
boost::asio::io_context m_io_service
Definition: net_helper.h:679
uint64_t get_bytes_sent() const
Definition: net_helper.h:593
std::string to_string(t_connection_type type)
Definition: connection_basic.cpp:70
boost::asio::ssl::context create_context() const
Definition: net_ssl.cpp:304
void async_read(char *buff, size_t sz, boost::asio::detail::transfer_at_least_t transfer_at_least, handler_obj &hndlr)
Definition: net_helper.h:669
bool handshake(boost::asio::io_context &io_context, boost::asio::ssl::stream< boost::asio::ip::tcp::socket > &socket, boost::asio::ssl::stream_base::handshake_type type, boost::asio::const_buffer buffer={}, const std::string &host={}, std::chrono::milliseconds timeout=std::chrono::seconds(15)) const
Definition: net_ssl.cpp:554
error
Tracks LMDB error codes.
Definition: error.h:44
boost::asio::ip::tcp::socket & get_socket()
Definition: net_helper.h:588
std::atomic< uint64_t > m_bytes_received
Definition: net_helper.h:689
boost::unique_future< boost::asio::ip::tcp::socket > operator()(const std::string &addr, const std::string &port, boost::asio::steady_timer &) const
Definition: net_helper.cpp:22
bool send(const boost::string_ref buff, std::chrono::milliseconds timeout)
Definition: net_helper.h:283
bool recv(std::string &buff, std::chrono::milliseconds timeout)
Definition: net_helper.h:404
std::atomic< uint64_t > m_bytes_sent
Definition: net_helper.h:688
static epee::net_utils::http::http_simple_client_template< dummy_client > client
Definition: http-client.cpp:62