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