blob: 2746752d8002376af0f27cb7c775e87be5722cce [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
Donald E Curtisa8736442015-08-05 15:48:13 -07002 * Copyright 2012 The WebRTC Project Authors. All rights reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
Donald E Curtisa8736442015-08-05 15:48:13 -07004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "examples/peerconnection/client/peer_connection_client.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000012
Danil Chapovalovb9201b02022-08-17 17:12:29 +020013#include "api/units/time_delta.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "examples/peerconnection/client/defaults.h"
15#include "rtc_base/checks.h"
16#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "rtc_base/net_helpers.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000018
henrike@webrtc.org28e20752013-07-10 00:45:36 +000019namespace {
20
21// This is our magical hangup signal.
Danil Chapovalovb9201b02022-08-17 17:12:29 +020022constexpr char kByeMessage[] = "BYE";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000023// Delay between server connection retries, in milliseconds
Danil Chapovalovb9201b02022-08-17 17:12:29 +020024constexpr webrtc::TimeDelta kReconnectDelay = webrtc::TimeDelta::Seconds(2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000025
Niels Möllerd0b88792021-08-12 10:32:30 +020026rtc::Socket* CreateClientSocket(int family) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000027 rtc::Thread* thread = rtc::Thread::Current();
nisseede5da42017-01-12 05:15:36 -080028 RTC_DCHECK(thread != NULL);
Niels Möllerd0b88792021-08-12 10:32:30 +020029 return thread->socketserver()->CreateSocket(family, SOCK_STREAM);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000030}
31
jbauch70625e52015-12-09 14:18:14 -080032} // namespace
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033
34PeerConnectionClient::PeerConnectionClient()
Tomas Gunnarsson77baeee2020-09-24 22:39:21 +020035 : callback_(NULL), resolver_(NULL), state_(NOT_CONNECTED), my_id_(-1) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
Danil Chapovalovb9201b02022-08-17 17:12:29 +020037PeerConnectionClient::~PeerConnectionClient() = default;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038
39void PeerConnectionClient::InitSocketSignals() {
nisseede5da42017-01-12 05:15:36 -080040 RTC_DCHECK(control_socket_.get() != NULL);
41 RTC_DCHECK(hanging_get_.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000042 control_socket_->SignalCloseEvent.connect(this,
Yves Gerey665174f2018-06-19 15:03:05 +020043 &PeerConnectionClient::OnClose);
44 hanging_get_->SignalCloseEvent.connect(this, &PeerConnectionClient::OnClose);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000045 control_socket_->SignalConnectEvent.connect(this,
Yves Gerey665174f2018-06-19 15:03:05 +020046 &PeerConnectionClient::OnConnect);
47 hanging_get_->SignalConnectEvent.connect(
48 this, &PeerConnectionClient::OnHangingGetConnect);
49 control_socket_->SignalReadEvent.connect(this, &PeerConnectionClient::OnRead);
50 hanging_get_->SignalReadEvent.connect(
51 this, &PeerConnectionClient::OnHangingGetRead);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000052}
53
54int PeerConnectionClient::id() const {
55 return my_id_;
56}
57
58bool PeerConnectionClient::is_connected() const {
59 return my_id_ != -1;
60}
61
62const Peers& PeerConnectionClient::peers() const {
63 return peers_;
64}
65
66void PeerConnectionClient::RegisterObserver(
67 PeerConnectionClientObserver* callback) {
nisseede5da42017-01-12 05:15:36 -080068 RTC_DCHECK(!callback_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069 callback_ = callback;
70}
71
Yves Gerey665174f2018-06-19 15:03:05 +020072void PeerConnectionClient::Connect(const std::string& server,
73 int port,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074 const std::string& client_name) {
nisseede5da42017-01-12 05:15:36 -080075 RTC_DCHECK(!server.empty());
76 RTC_DCHECK(!client_name.empty());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000077
78 if (state_ != NOT_CONNECTED) {
Harald Alvestrandef5b21e2021-11-27 21:31:08 +000079 RTC_LOG(LS_WARNING)
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080 << "The client must not be connected before you can call Connect()";
81 callback_->OnServerConnectionFailure();
82 return;
83 }
84
85 if (server.empty() || client_name.empty()) {
86 callback_->OnServerConnectionFailure();
87 return;
88 }
89
90 if (port <= 0)
91 port = kDefaultServerPort;
92
93 server_address_.SetIP(server);
94 server_address_.SetPort(port);
95 client_name_ = client_name;
96
tfarina20a34612015-11-02 16:20:22 -080097 if (server_address_.IsUnresolvedIP()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000098 state_ = RESOLVING;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000099 resolver_ = new rtc::AsyncResolver();
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000100 resolver_->SignalDone.connect(this, &PeerConnectionClient::OnResolveResult);
101 resolver_->Start(server_address_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000102 } else {
103 DoConnect();
104 }
105}
106
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000107void PeerConnectionClient::OnResolveResult(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000108 rtc::AsyncResolverInterface* resolver) {
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000109 if (resolver_->GetError() != 0) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000110 callback_->OnServerConnectionFailure();
111 resolver_->Destroy(false);
112 resolver_ = NULL;
113 state_ = NOT_CONNECTED;
114 } else {
115 server_address_ = resolver_->address();
116 DoConnect();
117 }
118}
119
120void PeerConnectionClient::DoConnect() {
121 control_socket_.reset(CreateClientSocket(server_address_.ipaddr().family()));
122 hanging_get_.reset(CreateClientSocket(server_address_.ipaddr().family()));
123 InitSocketSignals();
124 char buffer[1024];
Niels Mölleraba06332018-10-16 15:14:15 +0200125 snprintf(buffer, sizeof(buffer), "GET /sign_in?%s HTTP/1.0\r\n\r\n",
Yves Gerey665174f2018-06-19 15:03:05 +0200126 client_name_.c_str());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000127 onconnect_data_ = buffer;
128
129 bool ret = ConnectControlSocket();
130 if (ret)
131 state_ = SIGNING_IN;
132 if (!ret) {
133 callback_->OnServerConnectionFailure();
134 }
135}
136
137bool PeerConnectionClient::SendToPeer(int peer_id, const std::string& message) {
138 if (state_ != CONNECTED)
139 return false;
140
nisseede5da42017-01-12 05:15:36 -0800141 RTC_DCHECK(is_connected());
142 RTC_DCHECK(control_socket_->GetState() == rtc::Socket::CS_CLOSED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000143 if (!is_connected() || peer_id == -1)
144 return false;
145
146 char headers[1024];
Niels Mölleraba06332018-10-16 15:14:15 +0200147 snprintf(headers, sizeof(headers),
Yves Gerey665174f2018-06-19 15:03:05 +0200148 "POST /message?peer_id=%i&to=%i HTTP/1.0\r\n"
Niels Mölleraba06332018-10-16 15:14:15 +0200149 "Content-Length: %zu\r\n"
Yves Gerey665174f2018-06-19 15:03:05 +0200150 "Content-Type: text/plain\r\n"
151 "\r\n",
152 my_id_, peer_id, message.length());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000153 onconnect_data_ = headers;
154 onconnect_data_ += message;
155 return ConnectControlSocket();
156}
157
158bool PeerConnectionClient::SendHangUp(int peer_id) {
159 return SendToPeer(peer_id, kByeMessage);
160}
161
162bool PeerConnectionClient::IsSendingMessage() {
163 return state_ == CONNECTED &&
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000164 control_socket_->GetState() != rtc::Socket::CS_CLOSED;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000165}
166
167bool PeerConnectionClient::SignOut() {
168 if (state_ == NOT_CONNECTED || state_ == SIGNING_OUT)
169 return true;
170
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000171 if (hanging_get_->GetState() != rtc::Socket::CS_CLOSED)
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000172 hanging_get_->Close();
173
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000174 if (control_socket_->GetState() == rtc::Socket::CS_CLOSED) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000175 state_ = SIGNING_OUT;
176
177 if (my_id_ != -1) {
178 char buffer[1024];
Niels Mölleraba06332018-10-16 15:14:15 +0200179 snprintf(buffer, sizeof(buffer),
Yves Gerey665174f2018-06-19 15:03:05 +0200180 "GET /sign_out?peer_id=%i HTTP/1.0\r\n\r\n", my_id_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181 onconnect_data_ = buffer;
182 return ConnectControlSocket();
183 } else {
184 // Can occur if the app is closed before we finish connecting.
185 return true;
186 }
187 } else {
188 state_ = SIGNING_OUT_WAITING;
189 }
190
191 return true;
192}
193
194void PeerConnectionClient::Close() {
195 control_socket_->Close();
196 hanging_get_->Close();
197 onconnect_data_.clear();
198 peers_.clear();
199 if (resolver_ != NULL) {
200 resolver_->Destroy(false);
201 resolver_ = NULL;
202 }
203 my_id_ = -1;
204 state_ = NOT_CONNECTED;
205}
206
207bool PeerConnectionClient::ConnectControlSocket() {
nisseede5da42017-01-12 05:15:36 -0800208 RTC_DCHECK(control_socket_->GetState() == rtc::Socket::CS_CLOSED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209 int err = control_socket_->Connect(server_address_);
210 if (err == SOCKET_ERROR) {
211 Close();
212 return false;
213 }
214 return true;
215}
216
Niels Möllerd0b88792021-08-12 10:32:30 +0200217void PeerConnectionClient::OnConnect(rtc::Socket* socket) {
nisseede5da42017-01-12 05:15:36 -0800218 RTC_DCHECK(!onconnect_data_.empty());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000219 size_t sent = socket->Send(onconnect_data_.c_str(), onconnect_data_.length());
nisseede5da42017-01-12 05:15:36 -0800220 RTC_DCHECK(sent == onconnect_data_.length());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000221 onconnect_data_.clear();
222}
223
Niels Möllerd0b88792021-08-12 10:32:30 +0200224void PeerConnectionClient::OnHangingGetConnect(rtc::Socket* socket) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000225 char buffer[1024];
Niels Mölleraba06332018-10-16 15:14:15 +0200226 snprintf(buffer, sizeof(buffer), "GET /wait?peer_id=%i HTTP/1.0\r\n\r\n",
Yves Gerey665174f2018-06-19 15:03:05 +0200227 my_id_);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000228 int len = static_cast<int>(strlen(buffer));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000229 int sent = socket->Send(buffer, len);
nisseede5da42017-01-12 05:15:36 -0800230 RTC_DCHECK(sent == len);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000231}
232
233void PeerConnectionClient::OnMessageFromPeer(int peer_id,
234 const std::string& message) {
235 if (message.length() == (sizeof(kByeMessage) - 1) &&
236 message.compare(kByeMessage) == 0) {
237 callback_->OnPeerDisconnected(peer_id);
238 } else {
239 callback_->OnMessageFromPeer(peer_id, message);
240 }
241}
242
243bool PeerConnectionClient::GetHeaderValue(const std::string& data,
244 size_t eoh,
245 const char* header_pattern,
246 size_t* value) {
nisseede5da42017-01-12 05:15:36 -0800247 RTC_DCHECK(value != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 size_t found = data.find(header_pattern);
249 if (found != std::string::npos && found < eoh) {
250 *value = atoi(&data[found + strlen(header_pattern)]);
251 return true;
252 }
253 return false;
254}
255
Yves Gerey665174f2018-06-19 15:03:05 +0200256bool PeerConnectionClient::GetHeaderValue(const std::string& data,
257 size_t eoh,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000258 const char* header_pattern,
259 std::string* value) {
nisseede5da42017-01-12 05:15:36 -0800260 RTC_DCHECK(value != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261 size_t found = data.find(header_pattern);
262 if (found != std::string::npos && found < eoh) {
263 size_t begin = found + strlen(header_pattern);
264 size_t end = data.find("\r\n", begin);
265 if (end == std::string::npos)
266 end = eoh;
267 value->assign(data.substr(begin, end - begin));
268 return true;
269 }
270 return false;
271}
272
Niels Möllerd0b88792021-08-12 10:32:30 +0200273bool PeerConnectionClient::ReadIntoBuffer(rtc::Socket* socket,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000274 std::string* data,
275 size_t* content_length) {
276 char buffer[0xffff];
277 do {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200278 int bytes = socket->Recv(buffer, sizeof(buffer), nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000279 if (bytes <= 0)
280 break;
281 data->append(buffer, bytes);
282 } while (true);
283
284 bool ret = false;
285 size_t i = data->find("\r\n\r\n");
286 if (i != std::string::npos) {
Harald Alvestrand97597c02021-11-04 12:01:23 +0000287 RTC_LOG(LS_INFO) << "Headers received";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000288 if (GetHeaderValue(*data, i, "\r\nContent-Length: ", content_length)) {
289 size_t total_response_size = (i + 4) + *content_length;
290 if (data->length() >= total_response_size) {
291 ret = true;
292 std::string should_close;
293 const char kConnection[] = "\r\nConnection: ";
294 if (GetHeaderValue(*data, i, kConnection, &should_close) &&
295 should_close.compare("close") == 0) {
296 socket->Close();
297 // Since we closed the socket, there was no notification delivered
298 // to us. Compensate by letting ourselves know.
299 OnClose(socket, 0);
300 }
301 } else {
302 // We haven't received everything. Just continue to accept data.
303 }
304 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100305 RTC_LOG(LS_ERROR) << "No content length field specified by the server.";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000306 }
307 }
308 return ret;
309}
310
Niels Möllerd0b88792021-08-12 10:32:30 +0200311void PeerConnectionClient::OnRead(rtc::Socket* socket) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000312 size_t content_length = 0;
313 if (ReadIntoBuffer(socket, &control_data_, &content_length)) {
314 size_t peer_id = 0, eoh = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200315 bool ok =
316 ParseServerResponse(control_data_, content_length, &peer_id, &eoh);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 if (ok) {
318 if (my_id_ == -1) {
319 // First response. Let's store our server assigned ID.
nisseede5da42017-01-12 05:15:36 -0800320 RTC_DCHECK(state_ == SIGNING_IN);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000321 my_id_ = static_cast<int>(peer_id);
nisseede5da42017-01-12 05:15:36 -0800322 RTC_DCHECK(my_id_ != -1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323
324 // The body of the response will be a list of already connected peers.
325 if (content_length) {
326 size_t pos = eoh + 4;
327 while (pos < control_data_.size()) {
328 size_t eol = control_data_.find('\n', pos);
329 if (eol == std::string::npos)
330 break;
331 int id = 0;
332 std::string name;
333 bool connected;
334 if (ParseEntry(control_data_.substr(pos, eol - pos), &name, &id,
Yves Gerey665174f2018-06-19 15:03:05 +0200335 &connected) &&
336 id != my_id_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337 peers_[id] = name;
338 callback_->OnPeerConnected(id, name);
339 }
340 pos = eol + 1;
341 }
342 }
nisseede5da42017-01-12 05:15:36 -0800343 RTC_DCHECK(is_connected());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000344 callback_->OnSignedIn();
345 } else if (state_ == SIGNING_OUT) {
346 Close();
347 callback_->OnDisconnected();
348 } else if (state_ == SIGNING_OUT_WAITING) {
349 SignOut();
350 }
351 }
352
353 control_data_.clear();
354
355 if (state_ == SIGNING_IN) {
nisseede5da42017-01-12 05:15:36 -0800356 RTC_DCHECK(hanging_get_->GetState() == rtc::Socket::CS_CLOSED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000357 state_ = CONNECTED;
358 hanging_get_->Connect(server_address_);
359 }
360 }
361}
362
Niels Möllerd0b88792021-08-12 10:32:30 +0200363void PeerConnectionClient::OnHangingGetRead(rtc::Socket* socket) {
Harald Alvestrand97597c02021-11-04 12:01:23 +0000364 RTC_LOG(LS_INFO) << __FUNCTION__;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000365 size_t content_length = 0;
366 if (ReadIntoBuffer(socket, &notification_data_, &content_length)) {
367 size_t peer_id = 0, eoh = 0;
Yves Gerey665174f2018-06-19 15:03:05 +0200368 bool ok =
369 ParseServerResponse(notification_data_, content_length, &peer_id, &eoh);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000370
371 if (ok) {
372 // Store the position where the body begins.
373 size_t pos = eoh + 4;
374
375 if (my_id_ == static_cast<int>(peer_id)) {
376 // A notification about a new member or a member that just
377 // disconnected.
378 int id = 0;
379 std::string name;
380 bool connected = false;
381 if (ParseEntry(notification_data_.substr(pos), &name, &id,
382 &connected)) {
383 if (connected) {
384 peers_[id] = name;
385 callback_->OnPeerConnected(id, name);
386 } else {
387 peers_.erase(id);
388 callback_->OnPeerDisconnected(id);
389 }
390 }
391 } else {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000392 OnMessageFromPeer(static_cast<int>(peer_id),
393 notification_data_.substr(pos));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000394 }
395 }
396
397 notification_data_.clear();
398 }
399
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000400 if (hanging_get_->GetState() == rtc::Socket::CS_CLOSED &&
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000401 state_ == CONNECTED) {
402 hanging_get_->Connect(server_address_);
403 }
404}
405
406bool PeerConnectionClient::ParseEntry(const std::string& entry,
407 std::string* name,
408 int* id,
409 bool* connected) {
nisseede5da42017-01-12 05:15:36 -0800410 RTC_DCHECK(name != NULL);
411 RTC_DCHECK(id != NULL);
412 RTC_DCHECK(connected != NULL);
413 RTC_DCHECK(!entry.empty());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000414
415 *connected = false;
416 size_t separator = entry.find(',');
417 if (separator != std::string::npos) {
418 *id = atoi(&entry[separator + 1]);
419 name->assign(entry.substr(0, separator));
420 separator = entry.find(',', separator + 1);
421 if (separator != std::string::npos) {
422 *connected = atoi(&entry[separator + 1]) ? true : false;
423 }
424 }
425 return !name->empty();
426}
427
428int PeerConnectionClient::GetResponseStatus(const std::string& response) {
429 int status = -1;
430 size_t pos = response.find(' ');
431 if (pos != std::string::npos)
432 status = atoi(&response[pos + 1]);
433 return status;
434}
435
436bool PeerConnectionClient::ParseServerResponse(const std::string& response,
437 size_t content_length,
438 size_t* peer_id,
439 size_t* eoh) {
440 int status = GetResponseStatus(response.c_str());
441 if (status != 200) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100442 RTC_LOG(LS_ERROR) << "Received error from server";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000443 Close();
444 callback_->OnDisconnected();
445 return false;
446 }
447
448 *eoh = response.find("\r\n\r\n");
nisseede5da42017-01-12 05:15:36 -0800449 RTC_DCHECK(*eoh != std::string::npos);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000450 if (*eoh == std::string::npos)
451 return false;
452
453 *peer_id = -1;
454
Philipp Hancke0240cf82020-09-07 22:13:42 +0200455 // See comment in peer_channel.cc for why we use the Pragma header.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000456 GetHeaderValue(response, *eoh, "\r\nPragma: ", peer_id);
457
458 return true;
459}
460
Niels Möllerd0b88792021-08-12 10:32:30 +0200461void PeerConnectionClient::OnClose(rtc::Socket* socket, int err) {
Harald Alvestrand97597c02021-11-04 12:01:23 +0000462 RTC_LOG(LS_INFO) << __FUNCTION__;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000463
464 socket->Close();
465
466#ifdef WIN32
467 if (err != WSAECONNREFUSED) {
468#else
469 if (err != ECONNREFUSED) {
470#endif
471 if (socket == hanging_get_.get()) {
472 if (state_ == CONNECTED) {
473 hanging_get_->Close();
474 hanging_get_->Connect(server_address_);
475 }
476 } else {
477 callback_->OnMessageSent(err);
478 }
479 } else {
480 if (socket == control_socket_.get()) {
Harald Alvestrandef5b21e2021-11-27 21:31:08 +0000481 RTC_LOG(LS_WARNING) << "Connection refused; retrying in 2 seconds";
Danil Chapovalovb9201b02022-08-17 17:12:29 +0200482 rtc::Thread::Current()->PostDelayedTask(
483 SafeTask(safety_.flag(), [this] { DoConnect(); }), kReconnectDelay);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000484 } else {
485 Close();
486 callback_->OnDisconnected();
487 }
488 }
489}