@@ -27,7 +27,7 @@ namespace http {
27
27
CProxySharedData sharedData;
28
28
29
29
CProxyClient::CProxyClient (boost::asio::io_service& io_service, boost::asio::ssl::context& context, http::server::cWebem *webEm)
30
- : _socket(io_service, context),
30
+ : _context( context),
31
31
_io_service (io_service),
32
32
doStop(false ),
33
33
b_Connected(false ),
@@ -49,6 +49,7 @@ namespace http {
49
49
}
50
50
m_pWebEm = webEm;
51
51
m_pDomServ = NULL ;
52
+ _socket.reset (new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(_io_service, _context));
52
53
}
53
54
54
55
void CProxyClient::WriteSlaveData (const std::string &token, const char *pData, size_t Length)
@@ -75,10 +76,7 @@ namespace http {
75
76
76
77
void CProxyClient::Reconnect ()
77
78
{
78
-
79
- std::string address = " my.domoticz.com" ;
80
- std::string port = " 9999" ;
81
-
79
+ b_Connected = false ;
82
80
if (we_locked_prefs_mutex) {
83
81
// avoid deadlock if we got a read or write error in between handle_handshake() and HandleAuthresp()
84
82
we_locked_prefs_mutex = false ;
@@ -87,41 +85,57 @@ namespace http {
87
85
if (doStop) {
88
86
return ;
89
87
}
90
- if (b_Connected) {
91
- _socket.lowest_layer ().close ();
88
+ if (_socket->lowest_layer ().is_open ()) {
89
+ boost::system::error_code ec;
90
+ _socket->lowest_layer ().cancel (ec);
91
+ _socket->lowest_layer ().shutdown (boost::asio::socket_base::shutdown_both, ec);
92
+ _socket->lowest_layer ().close (ec);
92
93
}
93
- sleep_seconds (15 );
94
- b_Connected = false ;
94
+ timer_.expires_from_now (boost::posix_time::seconds (15 ));
95
+ timer_.async_wait (boost::bind (&CProxyClient::ContinueConnect, shared_from_this (), boost::asio::placeholders::error));
96
+ }
97
+
98
+ void CProxyClient::ContinueConnect (const boost::system::error_code& error)
99
+ {
100
+ std::string address = " my.domoticz.com" ;
101
+ std::string port = " 9999" ;
102
+
103
+ _socket.reset (new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(_io_service, _context));
104
+ // set timeout timer
105
+ timer_.expires_from_now (boost::posix_time::seconds (timeout_));
106
+ timer_.async_wait (boost::bind (&CProxyClient::handle_timeout, shared_from_this (), boost::asio::placeholders::error));
95
107
boost::asio::ip::tcp::resolver resolver (_io_service);
96
108
boost::asio::ip::tcp::resolver::query query (address, port);
97
109
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve (query);
98
110
boost::asio::ip::tcp::endpoint endpoint = *iterator;
99
- _socket. lowest_layer ().async_connect (endpoint,
111
+ _socket-> lowest_layer ().async_connect (endpoint,
100
112
boost::bind (&CProxyClient::handle_connect, shared_from_this (),
101
113
boost::asio::placeholders::error, iterator));
102
114
}
103
115
104
116
void CProxyClient::handle_connect (const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
105
117
{
118
+ if (doStop) {
119
+ return ;
120
+ }
106
121
if (!error)
107
122
{
108
- _socket. async_handshake (boost::asio::ssl::stream_base::client,
123
+ _socket-> async_handshake (boost::asio::ssl::stream_base::client,
109
124
boost::bind (&CProxyClient::handle_handshake, shared_from_this (),
110
125
boost::asio::placeholders::error));
111
126
}
112
- else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator ())
127
+ else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator ())
113
128
{
114
- _socket. lowest_layer ().close ();
129
+ _socket-> lowest_layer ().close ();
115
130
boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
116
- _socket. lowest_layer ().async_connect (endpoint,
131
+ _socket-> lowest_layer ().async_connect (endpoint,
117
132
boost::bind (&CProxyClient::handle_connect, shared_from_this (),
118
133
boost::asio::placeholders::error, ++endpoint_iterator));
119
134
}
120
135
else
121
136
{
122
137
if (!doStop) {
123
138
_log.Log (LOG_ERROR, " PROXY: Connect failed, reconnecting: %s" , error.message ().c_str ());
124
- b_Connected = true ; // signal re-connect
125
139
Reconnect ();
126
140
}
127
141
}
@@ -131,12 +145,15 @@ namespace http {
131
145
{
132
146
if (error != boost::asio::error::operation_aborted) {
133
147
_log.Log (LOG_ERROR, " PROXY: timeout occurred, reconnecting" );
134
- _socket. lowest_layer (). close (); // should induce a reconnect in handle_read with error != 0
148
+ Reconnect ();
135
149
}
136
150
}
137
151
138
152
void CProxyClient::handle_write (const boost::system::error_code& error, size_t bytes_transferred)
139
153
{
154
+ if (doStop) {
155
+ return ;
156
+ }
140
157
boost::unique_lock<boost::mutex>(writeMutex);
141
158
if (bytes_transferred < writePdu->length ()) {
142
159
_log.Log (LOG_ERROR, " PROXY: Only wrote %ld of %ld bytes." , bytes_transferred, writePdu->length ());
@@ -158,7 +175,7 @@ namespace http {
158
175
writePdu = pdu;
159
176
_writebuf.clear (); // make sure
160
177
_writebuf.push_back (boost::asio::buffer (writePdu->content (), writePdu->length ()));
161
- boost::asio::async_write (_socket, _writebuf, boost::bind (&CProxyClient::handle_write, shared_from_this (), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
178
+ boost::asio::async_write (* _socket, _writebuf, boost::bind (&CProxyClient::handle_write, shared_from_this (), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
162
179
}
163
180
164
181
void CProxyClient::MyWrite (pdu_type type, CValueLengthPart ¶meters)
@@ -197,6 +214,9 @@ namespace http {
197
214
198
215
void CProxyClient::handle_handshake (const boost::system::error_code& error)
199
216
{
217
+ if (doStop) {
218
+ return ;
219
+ }
200
220
if (!error)
201
221
{
202
222
// lock until we have a valid api id
@@ -209,10 +229,8 @@ namespace http {
209
229
}
210
230
else
211
231
{
212
- if (!doStop) {
213
- _log.Log (LOG_ERROR, " PROXY: Handshake failed, reconnecting: %s" , error.message ().c_str ());
214
- Reconnect ();
215
- }
232
+ _log.Log (LOG_ERROR, " PROXY: Handshake failed, reconnecting: %s" , error.message ().c_str ());
233
+ Reconnect ();
216
234
}
217
235
}
218
236
@@ -225,7 +243,7 @@ namespace http {
225
243
timer_.expires_from_now (boost::posix_time::seconds (timeout_));
226
244
timer_.async_wait (boost::bind (&CProxyClient::handle_timeout, shared_from_this (), boost::asio::placeholders::error));
227
245
228
- _socket. async_read_some (buf,
246
+ _socket-> async_read_some (buf,
229
247
boost::bind (&CProxyClient::handle_read, shared_from_this (), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)
230
248
);
231
249
}
@@ -529,6 +547,9 @@ namespace http {
529
547
void CProxyClient::handle_read (const boost::system::error_code& error, size_t bytes_transferred)
530
548
{
531
549
// data read, no need for timeouts anymore
550
+ if (!b_Connected || doStop) {
551
+ return ;
552
+ }
532
553
timer_.cancel ();
533
554
if (!error)
534
555
{
@@ -560,14 +581,17 @@ namespace http {
560
581
561
582
void CProxyClient::Stop ()
562
583
{
584
+ timer_.cancel (); // to be sure
563
585
if (we_locked_prefs_mutex) {
564
586
we_locked_prefs_mutex = false ;
565
587
sharedData.UnlockPrefsMutex ();
566
588
}
567
589
568
590
doStop = true ;
569
591
// signal end of WriteThread
570
- _socket.lowest_layer ().close ();
592
+ boost::system::error_code ec;
593
+ _socket->shutdown (ec);
594
+ _socket->lowest_layer ().close (ec);
571
595
}
572
596
573
597
void CProxyClient::SetSharedServer (tcp::server::CTCPServerProxied *domserv)
@@ -581,6 +605,7 @@ namespace http {
581
605
582
606
CProxyManager::CProxyManager (const std::string& doc_root, http::server::cWebem *webEm, tcp::server::CTCPServer *domServ)
583
607
{
608
+ m_pDocRoot = doc_root;
584
609
m_pWebEm = webEm;
585
610
m_pDomServ = domServ;
586
611
m_thread = NULL ;
@@ -590,14 +615,14 @@ namespace http {
590
615
CProxyManager::~CProxyManager ()
591
616
{
592
617
if (m_thread) {
593
- m_thread-> join () ;
618
+ delete m_thread;
594
619
}
595
620
}
596
621
597
622
int CProxyManager::Start (bool first)
598
623
{
599
624
_first = first;
600
- m_thread = new boost::thread (boost::bind (&CProxyManager::StartThread, this ));
625
+ m_thread = new boost::thread (boost::bind (&CProxyManager::StartThread, shared_from_this () ));
601
626
return 1 ;
602
627
}
603
628
@@ -624,10 +649,11 @@ namespace http {
624
649
625
650
void CProxyManager::Stop ()
626
651
{
627
- proxyclient->Stop ();
628
- io_service.stop ();
629
- m_thread->interrupt ();
630
- m_thread->join ();
652
+ if (m_thread) {
653
+ io_service.post (boost::bind (&CProxyClient::Stop, proxyclient));
654
+ delete m_thread;
655
+ m_thread = NULL ;
656
+ }
631
657
}
632
658
633
659
boost::shared_ptr<CProxyClient> CProxyManager::GetProxyForMaster (DomoticzTCP *master) {
0 commit comments