Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(754)

Side by Side Diff: webrtc/api/peerconnection.cc

Issue 2587133004: Reland of: Adding error output param to SetConfiguration, using new RTCError type. (Closed)
Patch Set: Fixing compile error in less confusing way. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/api/peerconnection.h ('k') | webrtc/api/peerconnection_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 30 matching lines...) Expand all
41 #include "webrtc/media/sctp/sctptransport.h" 41 #include "webrtc/media/sctp/sctptransport.h"
42 #include "webrtc/pc/channelmanager.h" 42 #include "webrtc/pc/channelmanager.h"
43 #include "webrtc/system_wrappers/include/field_trial.h" 43 #include "webrtc/system_wrappers/include/field_trial.h"
44 44
45 namespace { 45 namespace {
46 46
47 using webrtc::DataChannel; 47 using webrtc::DataChannel;
48 using webrtc::MediaConstraintsInterface; 48 using webrtc::MediaConstraintsInterface;
49 using webrtc::MediaStreamInterface; 49 using webrtc::MediaStreamInterface;
50 using webrtc::PeerConnectionInterface; 50 using webrtc::PeerConnectionInterface;
51 using webrtc::RTCError;
52 using webrtc::RTCErrorType;
51 using webrtc::RtpSenderInternal; 53 using webrtc::RtpSenderInternal;
52 using webrtc::RtpSenderInterface; 54 using webrtc::RtpSenderInterface;
53 using webrtc::RtpSenderProxy; 55 using webrtc::RtpSenderProxy;
54 using webrtc::RtpSenderProxyWithInternal; 56 using webrtc::RtpSenderProxyWithInternal;
55 using webrtc::StreamCollection; 57 using webrtc::StreamCollection;
56 58
57 static const char kDefaultStreamLabel[] = "default"; 59 static const char kDefaultStreamLabel[] = "default";
58 static const char kDefaultAudioTrackLabel[] = "defaulta0"; 60 static const char kDefaultAudioTrackLabel[] = "defaulta0";
59 static const char kDefaultVideoTrackLabel[] = "defaultv0"; 61 static const char kDefaultVideoTrackLabel[] = "defaultv0";
60 62
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 *host = in_str.substr(0, colonpos); 202 *host = in_str.substr(0, colonpos);
201 } else { 203 } else {
202 *host = in_str; 204 *host = in_str;
203 } 205 }
204 } 206 }
205 return !host->empty(); 207 return !host->empty();
206 } 208 }
207 209
208 // Adds a STUN or TURN server to the appropriate list, 210 // Adds a STUN or TURN server to the appropriate list,
209 // by parsing |url| and using the username/password in |server|. 211 // by parsing |url| and using the username/password in |server|.
210 bool ParseIceServerUrl(const PeerConnectionInterface::IceServer& server, 212 RTCErrorType ParseIceServerUrl(
211 const std::string& url, 213 const PeerConnectionInterface::IceServer& server,
212 cricket::ServerAddresses* stun_servers, 214 const std::string& url,
213 std::vector<cricket::RelayServerConfig>* turn_servers) { 215 cricket::ServerAddresses* stun_servers,
216 std::vector<cricket::RelayServerConfig>* turn_servers) {
214 // draft-nandakumar-rtcweb-stun-uri-01 217 // draft-nandakumar-rtcweb-stun-uri-01
215 // stunURI = scheme ":" stun-host [ ":" stun-port ] 218 // stunURI = scheme ":" stun-host [ ":" stun-port ]
216 // scheme = "stun" / "stuns" 219 // scheme = "stun" / "stuns"
217 // stun-host = IP-literal / IPv4address / reg-name 220 // stun-host = IP-literal / IPv4address / reg-name
218 // stun-port = *DIGIT 221 // stun-port = *DIGIT
219 222
220 // draft-petithuguenin-behave-turn-uris-01 223 // draft-petithuguenin-behave-turn-uris-01
221 // turnURI = scheme ":" turn-host [ ":" turn-port ] 224 // turnURI = scheme ":" turn-host [ ":" turn-port ]
222 // [ "?transport=" transport ] 225 // [ "?transport=" transport ]
223 // scheme = "turn" / "turns" 226 // scheme = "turn" / "turns"
224 // transport = "udp" / "tcp" / transport-ext 227 // transport = "udp" / "tcp" / transport-ext
225 // transport-ext = 1*unreserved 228 // transport-ext = 1*unreserved
226 // turn-host = IP-literal / IPv4address / reg-name 229 // turn-host = IP-literal / IPv4address / reg-name
227 // turn-port = *DIGIT 230 // turn-port = *DIGIT
228 RTC_DCHECK(stun_servers != nullptr); 231 RTC_DCHECK(stun_servers != nullptr);
229 RTC_DCHECK(turn_servers != nullptr); 232 RTC_DCHECK(turn_servers != nullptr);
230 std::vector<std::string> tokens; 233 std::vector<std::string> tokens;
231 cricket::ProtocolType turn_transport_type = cricket::PROTO_UDP; 234 cricket::ProtocolType turn_transport_type = cricket::PROTO_UDP;
232 RTC_DCHECK(!url.empty()); 235 RTC_DCHECK(!url.empty());
233 rtc::tokenize_with_empty_tokens(url, '?', &tokens); 236 rtc::tokenize_with_empty_tokens(url, '?', &tokens);
234 std::string uri_without_transport = tokens[0]; 237 std::string uri_without_transport = tokens[0];
235 // Let's look into transport= param, if it exists. 238 // Let's look into transport= param, if it exists.
236 if (tokens.size() == kTurnTransportTokensNum) { // ?transport= is present. 239 if (tokens.size() == kTurnTransportTokensNum) { // ?transport= is present.
237 std::string uri_transport_param = tokens[1]; 240 std::string uri_transport_param = tokens[1];
238 rtc::tokenize_with_empty_tokens(uri_transport_param, '=', &tokens); 241 rtc::tokenize_with_empty_tokens(uri_transport_param, '=', &tokens);
239 if (tokens[0] != kTransport) { 242 if (tokens[0] != kTransport) {
240 LOG(LS_WARNING) << "Invalid transport parameter key."; 243 LOG(LS_WARNING) << "Invalid transport parameter key.";
241 return false; 244 return RTCErrorType::SYNTAX_ERROR;
242 } 245 }
243 if (tokens.size() < 2 || 246 if (tokens.size() < 2 ||
244 !cricket::StringToProto(tokens[1].c_str(), &turn_transport_type) || 247 !cricket::StringToProto(tokens[1].c_str(), &turn_transport_type) ||
245 (turn_transport_type != cricket::PROTO_UDP && 248 (turn_transport_type != cricket::PROTO_UDP &&
246 turn_transport_type != cricket::PROTO_TCP)) { 249 turn_transport_type != cricket::PROTO_TCP)) {
247 LOG(LS_WARNING) << "Transport param should always be udp or tcp."; 250 LOG(LS_WARNING) << "Transport param should always be udp or tcp.";
248 return false; 251 return RTCErrorType::SYNTAX_ERROR;
249 } 252 }
250 } 253 }
251 254
252 std::string hoststring; 255 std::string hoststring;
253 ServiceType service_type; 256 ServiceType service_type;
254 if (!GetServiceTypeAndHostnameFromUri(uri_without_transport, 257 if (!GetServiceTypeAndHostnameFromUri(uri_without_transport,
255 &service_type, 258 &service_type,
256 &hoststring)) { 259 &hoststring)) {
257 LOG(LS_WARNING) << "Invalid transport parameter in ICE URI: " << url; 260 LOG(LS_WARNING) << "Invalid transport parameter in ICE URI: " << url;
258 return false; 261 return RTCErrorType::SYNTAX_ERROR;
259 } 262 }
260 263
261 // GetServiceTypeAndHostnameFromUri should never give an empty hoststring 264 // GetServiceTypeAndHostnameFromUri should never give an empty hoststring
262 RTC_DCHECK(!hoststring.empty()); 265 RTC_DCHECK(!hoststring.empty());
263 266
264 // Let's break hostname. 267 // Let's break hostname.
265 tokens.clear(); 268 tokens.clear();
266 rtc::tokenize_with_empty_tokens(hoststring, '@', &tokens); 269 rtc::tokenize_with_empty_tokens(hoststring, '@', &tokens);
267 270
268 std::string username(server.username); 271 std::string username(server.username);
269 if (tokens.size() > kTurnHostTokensNum) { 272 if (tokens.size() > kTurnHostTokensNum) {
270 LOG(LS_WARNING) << "Invalid user@hostname format: " << hoststring; 273 LOG(LS_WARNING) << "Invalid user@hostname format: " << hoststring;
271 return false; 274 return RTCErrorType::SYNTAX_ERROR;
272 } 275 }
273 if (tokens.size() == kTurnHostTokensNum) { 276 if (tokens.size() == kTurnHostTokensNum) {
274 if (tokens[0].empty() || tokens[1].empty()) { 277 if (tokens[0].empty() || tokens[1].empty()) {
275 LOG(LS_WARNING) << "Invalid user@hostname format: " << hoststring; 278 LOG(LS_WARNING) << "Invalid user@hostname format: " << hoststring;
276 return false; 279 return RTCErrorType::SYNTAX_ERROR;
277 } 280 }
278 username.assign(rtc::s_url_decode(tokens[0])); 281 username.assign(rtc::s_url_decode(tokens[0]));
279 hoststring = tokens[1]; 282 hoststring = tokens[1];
280 } else { 283 } else {
281 hoststring = tokens[0]; 284 hoststring = tokens[0];
282 } 285 }
283 286
284 int port = kDefaultStunPort; 287 int port = kDefaultStunPort;
285 if (service_type == TURNS) { 288 if (service_type == TURNS) {
286 port = kDefaultStunTlsPort; 289 port = kDefaultStunTlsPort;
287 turn_transport_type = cricket::PROTO_TLS; 290 turn_transport_type = cricket::PROTO_TLS;
288 } 291 }
289 292
290 std::string address; 293 std::string address;
291 if (!ParseHostnameAndPortFromString(hoststring, &address, &port)) { 294 if (!ParseHostnameAndPortFromString(hoststring, &address, &port)) {
292 LOG(WARNING) << "Invalid hostname format: " << uri_without_transport; 295 LOG(WARNING) << "Invalid hostname format: " << uri_without_transport;
293 return false; 296 return RTCErrorType::SYNTAX_ERROR;
294 } 297 }
295 298
296 if (port <= 0 || port > 0xffff) { 299 if (port <= 0 || port > 0xffff) {
297 LOG(WARNING) << "Invalid port: " << port; 300 LOG(WARNING) << "Invalid port: " << port;
298 return false; 301 return RTCErrorType::SYNTAX_ERROR;
299 } 302 }
300 303
301 switch (service_type) { 304 switch (service_type) {
302 case STUN: 305 case STUN:
303 case STUNS: 306 case STUNS:
304 stun_servers->insert(rtc::SocketAddress(address, port)); 307 stun_servers->insert(rtc::SocketAddress(address, port));
305 break; 308 break;
306 case TURN: 309 case TURN:
307 case TURNS: { 310 case TURNS: {
311 if (username.empty() || server.password.empty()) {
312 // The WebRTC spec requires throwing an InvalidAccessError when username
313 // or credential are ommitted; this is the native equivalent.
314 return RTCErrorType::INVALID_PARAMETER;
315 }
308 cricket::RelayServerConfig config = cricket::RelayServerConfig( 316 cricket::RelayServerConfig config = cricket::RelayServerConfig(
309 address, port, username, server.password, turn_transport_type); 317 address, port, username, server.password, turn_transport_type);
310 if (server.tls_cert_policy == 318 if (server.tls_cert_policy ==
311 PeerConnectionInterface::kTlsCertPolicyInsecureNoCheck) { 319 PeerConnectionInterface::kTlsCertPolicyInsecureNoCheck) {
312 config.tls_cert_policy = 320 config.tls_cert_policy =
313 cricket::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK; 321 cricket::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK;
314 } 322 }
315 turn_servers->push_back(config); 323 turn_servers->push_back(config);
316 break; 324 break;
317 } 325 }
318 case INVALID:
319 default: 326 default:
320 LOG(WARNING) << "Configuration not supported: " << url; 327 // We shouldn't get to this point with an invalid service_type, we should
321 return false; 328 // have returned an error already.
329 RTC_DCHECK(false) << "Unexpected service type";
330 return RTCErrorType::INTERNAL_ERROR;
322 } 331 }
323 return true; 332 return RTCErrorType::NONE;
324 } 333 }
325 334
326 // Check if we can send |new_stream| on a PeerConnection. 335 // Check if we can send |new_stream| on a PeerConnection.
327 bool CanAddLocalMediaStream(webrtc::StreamCollectionInterface* current_streams, 336 bool CanAddLocalMediaStream(webrtc::StreamCollectionInterface* current_streams,
328 webrtc::MediaStreamInterface* new_stream) { 337 webrtc::MediaStreamInterface* new_stream) {
329 if (!new_stream || !current_streams) { 338 if (!new_stream || !current_streams) {
330 return false; 339 return false;
331 } 340 }
332 if (current_streams->find(new_stream->label()) != nullptr) { 341 if (current_streams->find(new_stream->label()) != nullptr) {
333 LOG(LS_ERROR) << "MediaStream with label " << new_stream->label() 342 LOG(LS_ERROR) << "MediaStream with label " << new_stream->label()
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 for (auto& receiver : receivers) { 434 for (auto& receiver : receivers) {
426 if (receiver->media_type() == media_type) { 435 if (receiver->media_type() == media_type) {
427 if (!channel) { 436 if (!channel) {
428 receiver->internal()->Stop(); 437 receiver->internal()->Stop();
429 } 438 }
430 static_cast<RECEIVER*>(receiver->internal())->SetChannel(channel); 439 static_cast<RECEIVER*>(receiver->internal())->SetChannel(channel);
431 } 440 }
432 } 441 }
433 } 442 }
434 443
444 // Helper to set an error and return from a method.
445 bool SafeSetError(webrtc::RTCErrorType type, webrtc::RTCError* error) {
446 if (error) {
447 error->set_type(type);
448 }
449 return type == webrtc::RTCErrorType::NONE;
450 }
451
435 } // namespace 452 } // namespace
436 453
437 namespace webrtc { 454 namespace webrtc {
438 455
439 static const char* const kRtcErrorNames[] = { 456 static const char* const kRTCErrorTypeNames[] = {
440 "NONE", 457 "NONE",
441 "UNSUPPORTED_PARAMETER", 458 "UNSUPPORTED_PARAMETER",
442 "INVALID_PARAMETER", 459 "INVALID_PARAMETER",
443 "INVALID_RANGE", 460 "INVALID_RANGE",
444 "SYNTAX_ERROR", 461 "SYNTAX_ERROR",
445 "INVALID_STATE", 462 "INVALID_STATE",
446 "INVALID_MODIFICATION", 463 "INVALID_MODIFICATION",
447 "NETWORK_ERROR", 464 "NETWORK_ERROR",
448 "INTERNAL_ERROR", 465 "INTERNAL_ERROR",
449 }; 466 };
467 static_assert(static_cast<int>(RTCErrorType::INTERNAL_ERROR) ==
468 (arraysize(kRTCErrorTypeNames) - 1),
469 "kRTCErrorTypeNames must have as many strings as RTCErrorType "
470 "has values.");
450 471
451 std::ostream& operator<<(std::ostream& stream, RtcError error) { 472 std::ostream& operator<<(std::ostream& stream, RTCErrorType error) {
452 int index = static_cast<int>(error); 473 int index = static_cast<int>(error);
453 RTC_CHECK(index < static_cast<int>(sizeof(kRtcErrorNames) / 474 return stream << kRTCErrorTypeNames[index];
454 sizeof(kRtcErrorNames[0]))); 475 }
455 return stream << kRtcErrorNames[index]; 476
477 bool PeerConnectionInterface::RTCConfiguration::operator==(
478 const PeerConnectionInterface::RTCConfiguration& o) const {
479 // This static_assert prevents us from accidentally breaking operator==.
480 struct stuff_being_tested_for_equality {
481 IceTransportsType type;
482 IceServers servers;
483 BundlePolicy bundle_policy;
484 RtcpMuxPolicy rtcp_mux_policy;
485 TcpCandidatePolicy tcp_candidate_policy;
486 CandidateNetworkPolicy candidate_network_policy;
487 int audio_jitter_buffer_max_packets;
488 bool audio_jitter_buffer_fast_accelerate;
489 int ice_connection_receiving_timeout;
490 int ice_backup_candidate_pair_ping_interval;
491 ContinualGatheringPolicy continual_gathering_policy;
492 std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
493 bool prioritize_most_likely_ice_candidate_pairs;
494 struct cricket::MediaConfig media_config;
495 bool disable_ipv6;
496 bool enable_rtp_data_channel;
497 bool enable_quic;
498 rtc::Optional<int> screencast_min_bitrate;
499 rtc::Optional<bool> combined_audio_video_bwe;
500 rtc::Optional<bool> enable_dtls_srtp;
501 int ice_candidate_pool_size;
502 bool prune_turn_ports;
503 bool presume_writable_when_fully_relayed;
504 bool enable_ice_renomination;
505 bool redetermine_role_on_ice_restart;
506 };
507 static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
508 "Did you add something to RTCConfiguration and forget to "
509 "update operator==?");
510 return type == o.type && servers == o.servers &&
511 bundle_policy == o.bundle_policy &&
512 rtcp_mux_policy == o.rtcp_mux_policy &&
513 tcp_candidate_policy == o.tcp_candidate_policy &&
514 candidate_network_policy == o.candidate_network_policy &&
515 audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets &&
516 audio_jitter_buffer_fast_accelerate ==
517 o.audio_jitter_buffer_fast_accelerate &&
518 ice_connection_receiving_timeout ==
519 o.ice_connection_receiving_timeout &&
520 ice_backup_candidate_pair_ping_interval ==
521 o.ice_backup_candidate_pair_ping_interval &&
522 continual_gathering_policy == o.continual_gathering_policy &&
523 certificates == o.certificates &&
524 prioritize_most_likely_ice_candidate_pairs ==
525 o.prioritize_most_likely_ice_candidate_pairs &&
526 media_config == o.media_config && disable_ipv6 == o.disable_ipv6 &&
527 enable_rtp_data_channel == o.enable_rtp_data_channel &&
528 enable_quic == o.enable_quic &&
529 screencast_min_bitrate == o.screencast_min_bitrate &&
530 combined_audio_video_bwe == o.combined_audio_video_bwe &&
531 enable_dtls_srtp == o.enable_dtls_srtp &&
532 ice_candidate_pool_size == o.ice_candidate_pool_size &&
533 prune_turn_ports == o.prune_turn_ports &&
534 presume_writable_when_fully_relayed ==
535 o.presume_writable_when_fully_relayed &&
536 enable_ice_renomination == o.enable_ice_renomination &&
537 redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart;
538 }
539
540 bool PeerConnectionInterface::RTCConfiguration::operator!=(
541 const PeerConnectionInterface::RTCConfiguration& o) const {
542 return !(*this == o);
456 } 543 }
457 544
458 // Generate a RTCP CNAME when a PeerConnection is created. 545 // Generate a RTCP CNAME when a PeerConnection is created.
459 std::string GenerateRtcpCname() { 546 std::string GenerateRtcpCname() {
460 std::string cname; 547 std::string cname;
461 if (!rtc::CreateRandomString(kRtcpCnameLength, &cname)) { 548 if (!rtc::CreateRandomString(kRtcpCnameLength, &cname)) {
462 LOG(LS_ERROR) << "Failed to generate CNAME."; 549 LOG(LS_ERROR) << "Failed to generate CNAME.";
463 RTC_DCHECK(false); 550 RTC_DCHECK(false);
464 } 551 }
465 return cname; 552 return cname;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 for (auto& kv : session_options->transport_options) { 634 for (auto& kv : session_options->transport_options) {
548 kv.second.ice_restart = ice_restart; 635 kv.second.ice_restart = ice_restart;
549 } 636 }
550 637
551 if (!constraints) { 638 if (!constraints) {
552 return true; 639 return true;
553 } 640 }
554 return mandatory_constraints_satisfied == constraints->GetMandatory().size(); 641 return mandatory_constraints_satisfied == constraints->GetMandatory().size();
555 } 642 }
556 643
557 bool ParseIceServers(const PeerConnectionInterface::IceServers& servers, 644 RTCErrorType ParseIceServers(
558 cricket::ServerAddresses* stun_servers, 645 const PeerConnectionInterface::IceServers& servers,
559 std::vector<cricket::RelayServerConfig>* turn_servers) { 646 cricket::ServerAddresses* stun_servers,
647 std::vector<cricket::RelayServerConfig>* turn_servers) {
560 for (const webrtc::PeerConnectionInterface::IceServer& server : servers) { 648 for (const webrtc::PeerConnectionInterface::IceServer& server : servers) {
561 if (!server.urls.empty()) { 649 if (!server.urls.empty()) {
562 for (const std::string& url : server.urls) { 650 for (const std::string& url : server.urls) {
563 if (url.empty()) { 651 if (url.empty()) {
564 LOG(LS_ERROR) << "Empty uri."; 652 LOG(LS_ERROR) << "Empty uri.";
565 return false; 653 return RTCErrorType::SYNTAX_ERROR;
566 } 654 }
567 if (!ParseIceServerUrl(server, url, stun_servers, turn_servers)) { 655 RTCErrorType err =
568 return false; 656 ParseIceServerUrl(server, url, stun_servers, turn_servers);
657 if (err != RTCErrorType::NONE) {
658 return err;
569 } 659 }
570 } 660 }
571 } else if (!server.uri.empty()) { 661 } else if (!server.uri.empty()) {
572 // Fallback to old .uri if new .urls isn't present. 662 // Fallback to old .uri if new .urls isn't present.
573 if (!ParseIceServerUrl(server, server.uri, stun_servers, turn_servers)) { 663 RTCErrorType err =
574 return false; 664 ParseIceServerUrl(server, server.uri, stun_servers, turn_servers);
665 if (err != RTCErrorType::NONE) {
666 return err;
575 } 667 }
576 } else { 668 } else {
577 LOG(LS_ERROR) << "Empty uri."; 669 LOG(LS_ERROR) << "Empty uri.";
578 return false; 670 return RTCErrorType::SYNTAX_ERROR;
579 } 671 }
580 } 672 }
581 // Candidates must have unique priorities, so that connectivity checks 673 // Candidates must have unique priorities, so that connectivity checks
582 // are performed in a well-defined order. 674 // are performed in a well-defined order.
583 int priority = static_cast<int>(turn_servers->size() - 1); 675 int priority = static_cast<int>(turn_servers->size() - 1);
584 for (cricket::RelayServerConfig& turn_server : *turn_servers) { 676 for (cricket::RelayServerConfig& turn_server : *turn_servers) {
585 // First in the list gets highest priority. 677 // First in the list gets highest priority.
586 turn_server.priority = priority--; 678 turn_server.priority = priority--;
587 } 679 }
588 return true; 680 return RTCErrorType::NONE;
589 } 681 }
590 682
591 PeerConnection::PeerConnection(PeerConnectionFactory* factory) 683 PeerConnection::PeerConnection(PeerConnectionFactory* factory)
592 : factory_(factory), 684 : factory_(factory),
593 observer_(NULL), 685 observer_(NULL),
594 uma_observer_(NULL), 686 uma_observer_(NULL),
595 signaling_state_(kStable), 687 signaling_state_(kStable),
596 ice_connection_state_(kIceConnectionNew), 688 ice_connection_state_(kIceConnectionNew),
597 ice_gathering_state_(kIceGatheringNew), 689 ice_gathering_state_(kIceGatheringNew),
598 event_log_(RtcEventLog::Create()), 690 event_log_(RtcEventLog::Create()),
(...skipping 26 matching lines...) Expand all
625 network_thread()->Invoke<void>(RTC_FROM_HERE, 717 network_thread()->Invoke<void>(RTC_FROM_HERE,
626 [this] { port_allocator_.reset(nullptr); }); 718 [this] { port_allocator_.reset(nullptr); });
627 } 719 }
628 720
629 bool PeerConnection::Initialize( 721 bool PeerConnection::Initialize(
630 const PeerConnectionInterface::RTCConfiguration& configuration, 722 const PeerConnectionInterface::RTCConfiguration& configuration,
631 std::unique_ptr<cricket::PortAllocator> allocator, 723 std::unique_ptr<cricket::PortAllocator> allocator,
632 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator, 724 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
633 PeerConnectionObserver* observer) { 725 PeerConnectionObserver* observer) {
634 TRACE_EVENT0("webrtc", "PeerConnection::Initialize"); 726 TRACE_EVENT0("webrtc", "PeerConnection::Initialize");
635 RTC_DCHECK(observer != nullptr); 727 if (!allocator) {
728 LOG(LS_ERROR) << "PeerConnection initialized without a PortAllocator? "
729 << "This shouldn't happen if using PeerConnectionFactory.";
730 return false;
731 }
636 if (!observer) { 732 if (!observer) {
733 // TODO(deadbeef): Why do we do this?
734 LOG(LS_ERROR) << "PeerConnection initialized without a "
735 << "PeerConnectionObserver";
637 return false; 736 return false;
638 } 737 }
639 observer_ = observer; 738 observer_ = observer;
640
641 port_allocator_ = std::move(allocator); 739 port_allocator_ = std::move(allocator);
642 740
643 // The port allocator lives on the network thread and should be initialized 741 // The port allocator lives on the network thread and should be initialized
644 // there. 742 // there.
645 if (!network_thread()->Invoke<bool>( 743 if (!network_thread()->Invoke<bool>(
646 RTC_FROM_HERE, rtc::Bind(&PeerConnection::InitializePortAllocator_n, 744 RTC_FROM_HERE, rtc::Bind(&PeerConnection::InitializePortAllocator_n,
647 this, configuration))) { 745 this, configuration))) {
648 return false; 746 return false;
649 } 747 }
650 748
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 1391
1294 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer); 1392 SetSessionDescriptionMsg* msg = new SetSessionDescriptionMsg(observer);
1295 signaling_thread()->Post(RTC_FROM_HERE, this, 1393 signaling_thread()->Post(RTC_FROM_HERE, this,
1296 MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg); 1394 MSG_SET_SESSIONDESCRIPTION_SUCCESS, msg);
1297 } 1395 }
1298 1396
1299 PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() { 1397 PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() {
1300 return configuration_; 1398 return configuration_;
1301 } 1399 }
1302 1400
1303 bool PeerConnection::SetConfiguration(const RTCConfiguration& configuration) { 1401 bool PeerConnection::SetConfiguration(const RTCConfiguration& configuration,
1402 RTCError* error) {
1304 TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration"); 1403 TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration");
1305 1404
1306 if (session_->local_description() && 1405 if (session_->local_description() &&
1307 configuration.ice_candidate_pool_size != 1406 configuration.ice_candidate_pool_size !=
1308 configuration_.ice_candidate_pool_size) { 1407 configuration_.ice_candidate_pool_size) {
1309 LOG(LS_ERROR) << "Can't change candidate pool size after calling " 1408 LOG(LS_ERROR) << "Can't change candidate pool size after calling "
1310 "SetLocalDescription."; 1409 "SetLocalDescription.";
1311 return false; 1410 return SafeSetError(RTCErrorType::INVALID_MODIFICATION, error);
1312 }
1313 // TODO(deadbeef): Return false and log an error if there are any unsupported
1314 // modifications.
1315 if (port_allocator_) {
1316 if (!network_thread()->Invoke<bool>(
1317 RTC_FROM_HERE,
1318 rtc::Bind(&PeerConnection::ReconfigurePortAllocator_n, this,
1319 configuration))) {
1320 LOG(LS_ERROR) << "Failed to apply configuration to PortAllocator.";
1321 return false;
1322 }
1323 } 1411 }
1324 1412
1325 // TODO(deadbeef): Shouldn't have to hop to the network thread twice... 1413 // The simplest (and most future-compatible) way to tell if the config was
1326 session_->SetIceConfig(session_->ParseIceConfig(configuration)); 1414 // modified in an invalid way is to copy each property we do support
1415 // modifying, then use operator==. There are far more properties we don't
1416 // support modifying than those we do, and more could be added.
1417 RTCConfiguration modified_config = configuration_;
1418 modified_config.servers = configuration.servers;
1419 modified_config.type = configuration.type;
1420 modified_config.ice_candidate_pool_size =
1421 configuration.ice_candidate_pool_size;
1422 modified_config.prune_turn_ports = configuration.prune_turn_ports;
1423 if (configuration != modified_config) {
1424 LOG(LS_ERROR) << "Modifying the configuration in an unsupported way.";
1425 return SafeSetError(RTCErrorType::INVALID_MODIFICATION, error);
1426 }
1427
1428 // Note that this isn't possible through chromium, since it's an unsigned
1429 // short in WebIDL.
1430 if (configuration.ice_candidate_pool_size < 0 ||
1431 configuration.ice_candidate_pool_size > UINT16_MAX) {
1432 return SafeSetError(RTCErrorType::INVALID_RANGE, error);
1433 }
1434
1435 // Parse ICE servers before hopping to network thread.
1436 cricket::ServerAddresses stun_servers;
1437 std::vector<cricket::RelayServerConfig> turn_servers;
1438 RTCErrorType parse_error =
1439 ParseIceServers(configuration.servers, &stun_servers, &turn_servers);
1440 if (parse_error != RTCErrorType::NONE) {
1441 return SafeSetError(parse_error, error);
1442 }
1443
1444 // In theory this shouldn't fail.
1445 if (!network_thread()->Invoke<bool>(
1446 RTC_FROM_HERE,
1447 rtc::Bind(&PeerConnection::ReconfigurePortAllocator_n, this,
1448 stun_servers, turn_servers, modified_config.type,
1449 modified_config.ice_candidate_pool_size,
1450 modified_config.prune_turn_ports))) {
1451 LOG(LS_ERROR) << "Failed to apply configuration to PortAllocator.";
1452 return SafeSetError(RTCErrorType::INTERNAL_ERROR, error);
1453 }
1327 1454
1328 // As described in JSEP, calling setConfiguration with new ICE servers or 1455 // As described in JSEP, calling setConfiguration with new ICE servers or
1329 // candidate policy must set a "needs-ice-restart" bit so that the next offer 1456 // candidate policy must set a "needs-ice-restart" bit so that the next offer
1330 // triggers an ICE restart which will pick up the changes. 1457 // triggers an ICE restart which will pick up the changes.
1331 if (configuration.servers != configuration_.servers || 1458 if (modified_config.servers != configuration_.servers ||
1332 configuration.type != configuration_.type) { 1459 modified_config.type != configuration_.type ||
1460 modified_config.prune_turn_ports != configuration_.prune_turn_ports) {
1333 session_->SetNeedsIceRestartFlag(); 1461 session_->SetNeedsIceRestartFlag();
1334 } 1462 }
1335 configuration_ = configuration; 1463 configuration_ = modified_config;
1336 return true; 1464 return SafeSetError(RTCErrorType::NONE, error);
1337 } 1465 }
1338 1466
1339 bool PeerConnection::AddIceCandidate( 1467 bool PeerConnection::AddIceCandidate(
1340 const IceCandidateInterface* ice_candidate) { 1468 const IceCandidateInterface* ice_candidate) {
1341 TRACE_EVENT0("webrtc", "PeerConnection::AddIceCandidate"); 1469 TRACE_EVENT0("webrtc", "PeerConnection::AddIceCandidate");
1342 if (IsClosed()) { 1470 if (IsClosed()) {
1343 return false; 1471 return false;
1344 } 1472 }
1345 return session_->ProcessIceMessage(ice_candidate); 1473 return session_->ProcessIceMessage(ice_candidate);
1346 } 1474 }
1347 1475
1348 bool PeerConnection::RemoveIceCandidates( 1476 bool PeerConnection::RemoveIceCandidates(
1349 const std::vector<cricket::Candidate>& candidates) { 1477 const std::vector<cricket::Candidate>& candidates) {
1350 TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates"); 1478 TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates");
1351 return session_->RemoveRemoteIceCandidates(candidates); 1479 return session_->RemoveRemoteIceCandidates(candidates);
1352 } 1480 }
1353 1481
1354 void PeerConnection::RegisterUMAObserver(UMAObserver* observer) { 1482 void PeerConnection::RegisterUMAObserver(UMAObserver* observer) {
1355 TRACE_EVENT0("webrtc", "PeerConnection::RegisterUmaObserver"); 1483 TRACE_EVENT0("webrtc", "PeerConnection::RegisterUmaObserver");
1356 uma_observer_ = observer; 1484 uma_observer_ = observer;
1357 1485
1358 if (session_) { 1486 if (session_) {
1359 session_->set_metrics_observer(uma_observer_); 1487 session_->set_metrics_observer(uma_observer_);
1360 } 1488 }
1361 1489
1362 // Send information about IPv4/IPv6 status. 1490 // Send information about IPv4/IPv6 status.
1363 if (uma_observer_ && port_allocator_) { 1491 if (uma_observer_) {
1364 port_allocator_->SetMetricsObserver(uma_observer_); 1492 port_allocator_->SetMetricsObserver(uma_observer_);
1365 if (port_allocator_->flags() & cricket::PORTALLOCATOR_ENABLE_IPV6) { 1493 if (port_allocator_->flags() & cricket::PORTALLOCATOR_ENABLE_IPV6) {
1366 uma_observer_->IncrementEnumCounter( 1494 uma_observer_->IncrementEnumCounter(
1367 kEnumCounterAddressFamily, kPeerConnection_IPv6, 1495 kEnumCounterAddressFamily, kPeerConnection_IPv6,
1368 kPeerConnectionAddressFamilyCounter_Max); 1496 kPeerConnectionAddressFamilyCounter_Max);
1369 } else { 1497 } else {
1370 uma_observer_->IncrementEnumCounter( 1498 uma_observer_->IncrementEnumCounter(
1371 kEnumCounterAddressFamily, kPeerConnection_IPv4, 1499 kEnumCounterAddressFamily, kPeerConnection_IPv4,
1372 kPeerConnectionAddressFamilyCounter_Max); 1500 kPeerConnectionAddressFamilyCounter_Max);
1373 } 1501 }
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after
2366 return channel; 2494 return channel;
2367 } 2495 }
2368 } 2496 }
2369 return nullptr; 2497 return nullptr;
2370 } 2498 }
2371 2499
2372 bool PeerConnection::InitializePortAllocator_n( 2500 bool PeerConnection::InitializePortAllocator_n(
2373 const RTCConfiguration& configuration) { 2501 const RTCConfiguration& configuration) {
2374 cricket::ServerAddresses stun_servers; 2502 cricket::ServerAddresses stun_servers;
2375 std::vector<cricket::RelayServerConfig> turn_servers; 2503 std::vector<cricket::RelayServerConfig> turn_servers;
2376 if (!ParseIceServers(configuration.servers, &stun_servers, &turn_servers)) { 2504 if (ParseIceServers(configuration.servers, &stun_servers, &turn_servers) !=
2505 RTCErrorType::NONE) {
2377 return false; 2506 return false;
2378 } 2507 }
2379 2508
2380 port_allocator_->Initialize(); 2509 port_allocator_->Initialize();
2381 2510
2382 // To handle both internal and externally created port allocator, we will 2511 // To handle both internal and externally created port allocator, we will
2383 // enable BUNDLE here. 2512 // enable BUNDLE here.
2384 int portallocator_flags = port_allocator_->flags(); 2513 int portallocator_flags = port_allocator_->flags();
2385 portallocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET | 2514 portallocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
2386 cricket::PORTALLOCATOR_ENABLE_IPV6; 2515 cricket::PORTALLOCATOR_ENABLE_IPV6;
(...skipping 25 matching lines...) Expand all
2412 2541
2413 // Call this last since it may create pooled allocator sessions using the 2542 // Call this last since it may create pooled allocator sessions using the
2414 // properties set above. 2543 // properties set above.
2415 port_allocator_->SetConfiguration(stun_servers, turn_servers, 2544 port_allocator_->SetConfiguration(stun_servers, turn_servers,
2416 configuration.ice_candidate_pool_size, 2545 configuration.ice_candidate_pool_size,
2417 configuration.prune_turn_ports); 2546 configuration.prune_turn_ports);
2418 return true; 2547 return true;
2419 } 2548 }
2420 2549
2421 bool PeerConnection::ReconfigurePortAllocator_n( 2550 bool PeerConnection::ReconfigurePortAllocator_n(
2422 const RTCConfiguration& configuration) { 2551 const cricket::ServerAddresses& stun_servers,
2423 cricket::ServerAddresses stun_servers; 2552 const std::vector<cricket::RelayServerConfig>& turn_servers,
2424 std::vector<cricket::RelayServerConfig> turn_servers; 2553 IceTransportsType type,
2425 if (!ParseIceServers(configuration.servers, &stun_servers, &turn_servers)) { 2554 int candidate_pool_size,
2426 return false; 2555 bool prune_turn_ports) {
2427 }
2428 port_allocator_->set_candidate_filter( 2556 port_allocator_->set_candidate_filter(
2429 ConvertIceTransportTypeToCandidateFilter(configuration.type)); 2557 ConvertIceTransportTypeToCandidateFilter(type));
2430 // Call this last since it may create pooled allocator sessions using the 2558 // Call this last since it may create pooled allocator sessions using the
2431 // candidate filter set above. 2559 // candidate filter set above.
2432 return port_allocator_->SetConfiguration( 2560 return port_allocator_->SetConfiguration(
2433 stun_servers, turn_servers, configuration.ice_candidate_pool_size, 2561 stun_servers, turn_servers, candidate_pool_size, prune_turn_ports);
2434 configuration.prune_turn_ports);
2435 } 2562 }
2436 2563
2437 bool PeerConnection::StartRtcEventLog_w(rtc::PlatformFile file, 2564 bool PeerConnection::StartRtcEventLog_w(rtc::PlatformFile file,
2438 int64_t max_size_bytes) { 2565 int64_t max_size_bytes) {
2439 return event_log_->StartLogging(file, max_size_bytes); 2566 return event_log_->StartLogging(file, max_size_bytes);
2440 } 2567 }
2441 2568
2442 void PeerConnection::StopRtcEventLog_w() { 2569 void PeerConnection::StopRtcEventLog_w() {
2443 event_log_->StopLogging(); 2570 event_log_->StopLogging();
2444 } 2571 }
2445 } // namespace webrtc 2572 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/api/peerconnection.h ('k') | webrtc/api/peerconnection_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698