Monero
Loading...
Searching...
No Matches
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
60namespace epee
61{
62namespace 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 {
79
80
81
83 {
84 handler_obj(boost::system::error_code& error, size_t& bytes_transferred):ref_error(error), ref_bytes_transferred(bytes_transferred)
85 {}
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)),
111 m_deadline(m_io_service, std::chrono::steady_clock::time_point::max()),
113 m_bytes_sent(0),
115 {
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 {
181 if (!m_ssl_options.handshake(m_io_service, *m_ssl_socket, boost::asio::ssl::stream_base::client, {}, addr, timeout))
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 }
249
250 void set_connector(std::function<connect_func> connector)
251 {
252 m_connector = std::move(connector);
253 }
254
255 inline
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
588 boost::asio::ip::tcp::socket& get_socket()
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
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;
680 boost::asio::ssl::context m_ctx;
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
uint64_t get_bytes_received() const
Definition net_helper.h:598
boost::asio::steady_timer m_deadline
Definition net_helper.h:686
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
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
uint64_t get_bytes_sent() const
Definition net_helper.h:593
bool shutdown()
Definition net_helper.h:563
bool connect(const std::string &addr, const std::string &port, std::chrono::milliseconds timeout)
Definition net_helper.h:209
bool write(const void *data, size_t sz, boost::system::error_code &ec)
Definition net_helper.h:651
try_connect_result_t try_connect(const std::string &addr, const std::string &port, std::chrono::milliseconds timeout)
Definition net_helper.h:159
void set_connector(std::function< connect_func > connector)
Change the connection routine (proxy, etc.).
Definition net_helper.h:250
bool recv(std::string &buff, std::chrono::milliseconds timeout)
Definition net_helper.h:404
void shutdown_ssl()
Definition net_helper.h:628
bool recv_n(std::string &buff, int64_t sz, std::chrono::milliseconds timeout)
Definition net_helper.h:490
std::atomic< bool > m_shutdowned
Definition net_helper.h:687
void async_write(const void *data, size_t sz, boost::system::error_code &ec)
Definition net_helper.h:661
void check_deadline()
Definition net_helper.h:605
~blocked_mode_client()
Definition net_helper.h:136
bool m_connected
Definition net_helper.h:685
std::atomic< uint64_t > m_bytes_received
Definition net_helper.h:689
try_connect_result_t
Definition net_helper.h:74
@ CONNECT_FAILURE
Definition net_helper.h:76
@ CONNECT_NO_SSL
Definition net_helper.h:77
@ CONNECT_SUCCESS
Definition net_helper.h:75
blocked_mode_client()
Definition net_helper.h:103
boost::asio::io_context & get_io_service()
Definition net_helper.h:583
std::function< connect_func > m_connector
Definition net_helper.h:682
bool send(const void *data, size_t sz)
Definition net_helper.h:337
bool connect(const std::string &addr, int port, std::chrono::milliseconds timeout)
Definition net_helper.h:153
boost::asio::io_context m_io_service
Definition net_helper.h:679
bool disconnect()
Definition net_helper.h:256
boost::asio::ip::tcp::socket & get_socket()
Definition net_helper.h:588
bool is_connected(bool *ssl=NULL)
Definition net_helper.h:394
void set_ssl(ssl_options_t ssl_options)
Definition net_helper.h:143
std::atomic< uint64_t > m_bytes_sent
Definition net_helper.h:688
bool send(const boost::string_ref buff, std::chrono::milliseconds timeout)
Definition net_helper.h:283
boost::asio::ssl::context m_ctx
Definition net_helper.h:680
ssl_options_t m_ssl_options
Definition net_helper.h:683
std::shared_ptr< boost::asio::ssl::stream< boost::asio::ip::tcp::socket > > m_ssl_socket
Definition net_helper.h:681
bool m_initialized
Definition net_helper.h:684
Represents a single connection from a client.
Definition abstract_tcp_server2.h:100
Definition net_ssl.h:77
boost::asio::ssl::context create_context() const
Definition net_ssl.cpp:304
bool success
Definition cold-transaction.cpp:57
#define true
#define false
Definition portable_binary_archive.hpp:29
Definition abstract_http_client.h:36
ssl_support_t
Definition net_ssl.h:49
@ e_ssl_support_disabled
Definition net_ssl.h:50
@ e_ssl_support_autodetect
Definition net_ssl.h:52
@ e_ssl_support_enabled
Definition net_ssl.h:51
TODO: (mj-xmr) This will be reduced in an another PR.
Definition byte_slice.h:40
Definition enums.h:68
signed __int64 int64_t
Definition stdint.h:135
unsigned __int64 uint64_t
Definition stdint.h:136
handler_obj(const handler_obj &other_obj)
Definition net_helper.h:86
void operator()(const boost::system::error_code &error, std::size_t bytes_transferred)
Definition net_helper.h:92
boost::system::error_code & ref_error
Definition net_helper.h:89
handler_obj(boost::system::error_code &error, size_t &bytes_transferred)
Definition net_helper.h:84
size_t & ref_bytes_transferred
Definition net_helper.h:90
Definition net_helper.h:65
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
std::string data
Definition base58.cpp:37