mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
Reland "ice server parsing: return RTCError with more details"
This is a reland of commit c4b0bde7f2
which changes the name of the new method and adds a deprecated
backward compatible variant with the old name.
Original change's description:
> ice server parsing: return RTCError with more details
>
> surfacing those errors to the API (without specific details) instead of just the logging.
>
> BUG=webrtc:14539
>
> Change-Id: Id907ebeb08b96b0e4225a016a37a12d58889091b
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/278340
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Commit-Queue: Philipp Hancke <phancke@microsoft.com>
> Cr-Commit-Position: refs/heads/main@{#38356}
Bug: webrtc:14539
Change-Id: I0a5482e123f25867582d62101b31ed207b95ea1a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/278962
Commit-Queue: Philipp Hancke <phancke@microsoft.com>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38364}
This commit is contained in:
parent
77ec9f5015
commit
633dc2fd10
4 changed files with 81 additions and 51 deletions
|
@ -155,7 +155,7 @@ std::tuple<bool, absl::string_view, int> ParseHostnameAndPortFromString(
|
|||
|
||||
// Adds a STUN or TURN server to the appropriate list,
|
||||
// by parsing `url` and using the username/password in `server`.
|
||||
RTCErrorType ParseIceServerUrl(
|
||||
RTCError ParseIceServerUrl(
|
||||
const PeerConnectionInterface::IceServer& server,
|
||||
absl::string_view url,
|
||||
cricket::ServerAddresses* stun_servers,
|
||||
|
@ -186,20 +186,24 @@ RTCErrorType ParseIceServerUrl(
|
|||
std::vector<absl::string_view> transport_tokens =
|
||||
rtc::split(tokens[1], '=');
|
||||
if (transport_tokens[0] != kTransport) {
|
||||
RTC_LOG(LS_WARNING) << "Invalid transport parameter key.";
|
||||
return RTCErrorType::SYNTAX_ERROR;
|
||||
LOG_AND_RETURN_ERROR(
|
||||
RTCErrorType::SYNTAX_ERROR,
|
||||
"ICE server parsing failed: Invalid transport parameter key.");
|
||||
}
|
||||
if (transport_tokens.size() < 2) {
|
||||
RTC_LOG(LS_WARNING) << "Transport parameter missing value.";
|
||||
return RTCErrorType::SYNTAX_ERROR;
|
||||
LOG_AND_RETURN_ERROR(
|
||||
RTCErrorType::SYNTAX_ERROR,
|
||||
"ICE server parsing failed: Transport parameter missing value.");
|
||||
}
|
||||
|
||||
absl::optional<cricket::ProtocolType> proto =
|
||||
cricket::StringToProto(transport_tokens[1]);
|
||||
if (!proto ||
|
||||
(*proto != cricket::PROTO_UDP && *proto != cricket::PROTO_TCP)) {
|
||||
RTC_LOG(LS_WARNING) << "Transport parameter should always be udp or tcp.";
|
||||
return RTCErrorType::SYNTAX_ERROR;
|
||||
LOG_AND_RETURN_ERROR(
|
||||
RTCErrorType::SYNTAX_ERROR,
|
||||
"ICE server parsing failed: Transport parameter should "
|
||||
"always be udp or tcp.");
|
||||
}
|
||||
turn_transport_type = *proto;
|
||||
}
|
||||
|
@ -207,8 +211,10 @@ RTCErrorType ParseIceServerUrl(
|
|||
auto [service_type, hoststring] =
|
||||
GetServiceTypeAndHostnameFromUri(uri_without_transport);
|
||||
if (service_type == ServiceType::INVALID) {
|
||||
RTC_LOG(LS_WARNING) << "Invalid transport parameter in ICE URI: " << url;
|
||||
return RTCErrorType::SYNTAX_ERROR;
|
||||
RTC_LOG(LS_ERROR) << "Invalid transport parameter in ICE URI: " << url;
|
||||
LOG_AND_RETURN_ERROR(
|
||||
RTCErrorType::SYNTAX_ERROR,
|
||||
"ICE server parsing failed: Invalid transport parameter in ICE URI");
|
||||
}
|
||||
|
||||
// GetServiceTypeAndHostnameFromUri should never give an empty hoststring
|
||||
|
@ -221,22 +227,25 @@ RTCErrorType ParseIceServerUrl(
|
|||
}
|
||||
|
||||
if (hoststring.find('@') != absl::string_view::npos) {
|
||||
RTC_LOG(LS_WARNING) << "Invalid url: " << uri_without_transport;
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "Note that user-info@ in turn:-urls is long-deprecated.";
|
||||
return RTCErrorType::SYNTAX_ERROR;
|
||||
RTC_LOG(LS_ERROR) << "Invalid url with long deprecated user@host syntax: "
|
||||
<< uri_without_transport;
|
||||
LOG_AND_RETURN_ERROR(RTCErrorType::SYNTAX_ERROR,
|
||||
"ICE server parsing failed: Invalid url with long "
|
||||
"deprecated user@host syntax");
|
||||
}
|
||||
|
||||
auto [success, address, port] =
|
||||
ParseHostnameAndPortFromString(hoststring, default_port);
|
||||
if (!success) {
|
||||
RTC_LOG(LS_WARNING) << "Invalid hostname format: " << uri_without_transport;
|
||||
return RTCErrorType::SYNTAX_ERROR;
|
||||
RTC_LOG(LS_ERROR) << "Invalid hostname format: " << uri_without_transport;
|
||||
LOG_AND_RETURN_ERROR(RTCErrorType::SYNTAX_ERROR,
|
||||
"ICE server parsing failed: Invalid hostname format");
|
||||
}
|
||||
|
||||
if (port <= 0 || port > 0xffff) {
|
||||
RTC_LOG(LS_WARNING) << "Invalid port: " << port;
|
||||
return RTCErrorType::SYNTAX_ERROR;
|
||||
RTC_LOG(LS_ERROR) << "Invalid port: " << port;
|
||||
LOG_AND_RETURN_ERROR(RTCErrorType::SYNTAX_ERROR,
|
||||
"ICE server parsing failed: Invalid port");
|
||||
}
|
||||
|
||||
switch (service_type) {
|
||||
|
@ -249,8 +258,10 @@ RTCErrorType ParseIceServerUrl(
|
|||
if (server.username.empty() || server.password.empty()) {
|
||||
// The WebRTC spec requires throwing an InvalidAccessError when username
|
||||
// or credential are ommitted; this is the native equivalent.
|
||||
RTC_LOG(LS_WARNING) << "TURN server with empty username or password";
|
||||
return RTCErrorType::INVALID_PARAMETER;
|
||||
LOG_AND_RETURN_ERROR(
|
||||
RTCErrorType::INVALID_PARAMETER,
|
||||
"ICE server parsing failed: TURN server with empty "
|
||||
"username or password");
|
||||
}
|
||||
// If the hostname field is not empty, then the server address must be
|
||||
// the resolved IP for that host, the hostname is needed later for TLS
|
||||
|
@ -263,10 +274,11 @@ RTCErrorType ParseIceServerUrl(
|
|||
if (!IPFromString(address, &ip)) {
|
||||
// When hostname is set, the server address must be a
|
||||
// resolved ip address.
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "IceServer has hostname field set, but URI does not "
|
||||
"contain an IP address.";
|
||||
return RTCErrorType::INVALID_PARAMETER;
|
||||
LOG_AND_RETURN_ERROR(
|
||||
RTCErrorType::INVALID_PARAMETER,
|
||||
"ICE server parsing failed: "
|
||||
"IceServer has hostname field set, but URI does not "
|
||||
"contain an IP address.");
|
||||
}
|
||||
socket_address.SetResolvedIP(ip);
|
||||
}
|
||||
|
@ -287,15 +299,16 @@ RTCErrorType ParseIceServerUrl(
|
|||
default:
|
||||
// We shouldn't get to this point with an invalid service_type, we should
|
||||
// have returned an error already.
|
||||
RTC_DCHECK_NOTREACHED() << "Unexpected service type";
|
||||
return RTCErrorType::INTERNAL_ERROR;
|
||||
LOG_AND_RETURN_ERROR(
|
||||
RTCErrorType::INTERNAL_ERROR,
|
||||
"ICE server parsing failed: Unexpected service type");
|
||||
}
|
||||
return RTCErrorType::NONE;
|
||||
return RTCError::OK();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
RTCErrorType ParseIceServers(
|
||||
RTCError ParseIceServersOrError(
|
||||
const PeerConnectionInterface::IceServers& servers,
|
||||
cricket::ServerAddresses* stun_servers,
|
||||
std::vector<cricket::RelayServerConfig>* turn_servers) {
|
||||
|
@ -303,25 +316,26 @@ RTCErrorType ParseIceServers(
|
|||
if (!server.urls.empty()) {
|
||||
for (const std::string& url : server.urls) {
|
||||
if (url.empty()) {
|
||||
RTC_LOG(LS_WARNING) << "Empty uri.";
|
||||
return RTCErrorType::SYNTAX_ERROR;
|
||||
LOG_AND_RETURN_ERROR(RTCErrorType::SYNTAX_ERROR,
|
||||
"ICE server parsing failed: Empty uri.");
|
||||
}
|
||||
RTCErrorType err =
|
||||
RTCError err =
|
||||
ParseIceServerUrl(server, url, stun_servers, turn_servers);
|
||||
if (err != RTCErrorType::NONE) {
|
||||
if (!err.ok()) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
} else if (!server.uri.empty()) {
|
||||
// Fallback to old .uri if new .urls isn't present.
|
||||
RTCErrorType err =
|
||||
RTCError err =
|
||||
ParseIceServerUrl(server, server.uri, stun_servers, turn_servers);
|
||||
if (err != RTCErrorType::NONE) {
|
||||
|
||||
if (!err.ok()) {
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
RTC_LOG(LS_WARNING) << "Empty uri.";
|
||||
return RTCErrorType::SYNTAX_ERROR;
|
||||
LOG_AND_RETURN_ERROR(RTCErrorType::SYNTAX_ERROR,
|
||||
"ICE server parsing failed: Empty uri.");
|
||||
}
|
||||
}
|
||||
// Candidates must have unique priorities, so that connectivity checks
|
||||
|
@ -331,7 +345,14 @@ RTCErrorType ParseIceServers(
|
|||
// First in the list gets highest priority.
|
||||
turn_server.priority = priority--;
|
||||
}
|
||||
return RTCErrorType::NONE;
|
||||
return RTCError::OK();
|
||||
}
|
||||
|
||||
RTCErrorType ParseIceServers(
|
||||
const PeerConnectionInterface::IceServers& servers,
|
||||
cricket::ServerAddresses* stun_servers,
|
||||
std::vector<cricket::RelayServerConfig>* turn_servers) {
|
||||
return ParseIceServersOrError(servers, stun_servers, turn_servers).type();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -27,7 +27,12 @@ namespace webrtc {
|
|||
//
|
||||
// Intended to be used to convert/validate the servers passed into a
|
||||
// PeerConnection through RTCConfiguration.
|
||||
RTC_EXPORT RTCErrorType
|
||||
RTC_EXPORT RTCError
|
||||
ParseIceServersOrError(const PeerConnectionInterface::IceServers& servers,
|
||||
cricket::ServerAddresses* stun_servers,
|
||||
std::vector<cricket::RelayServerConfig>* turn_servers);
|
||||
|
||||
[[deprecated("use ParseIceServersOrError")]] RTC_EXPORT RTCErrorType
|
||||
ParseIceServers(const PeerConnectionInterface::IceServers& servers,
|
||||
cricket::ServerAddresses* stun_servers,
|
||||
std::vector<cricket::RelayServerConfig>* turn_servers);
|
||||
|
|
|
@ -62,8 +62,9 @@ class IceServerParsingTest : public ::testing::Test {
|
|||
server.tls_cert_policy = tls_certificate_policy;
|
||||
server.hostname = hostname;
|
||||
servers.push_back(server);
|
||||
return webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_) ==
|
||||
webrtc::RTCErrorType::NONE;
|
||||
return webrtc::ParseIceServersOrError(servers, &stun_servers_,
|
||||
&turn_servers_)
|
||||
.ok();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -229,8 +230,9 @@ TEST_F(IceServerParsingTest, ParseMultipleUrls) {
|
|||
server.username = "foo";
|
||||
server.password = "bar";
|
||||
servers.push_back(server);
|
||||
EXPECT_EQ(webrtc::RTCErrorType::NONE,
|
||||
webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_));
|
||||
EXPECT_TRUE(
|
||||
webrtc::ParseIceServersOrError(servers, &stun_servers_, &turn_servers_)
|
||||
.ok());
|
||||
EXPECT_EQ(1U, stun_servers_.size());
|
||||
EXPECT_EQ(1U, turn_servers_.size());
|
||||
}
|
||||
|
@ -245,8 +247,10 @@ TEST_F(IceServerParsingTest, TurnServerPrioritiesUnique) {
|
|||
server.username = "foo";
|
||||
server.password = "bar";
|
||||
servers.push_back(server);
|
||||
EXPECT_EQ(webrtc::RTCErrorType::NONE,
|
||||
webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_));
|
||||
|
||||
EXPECT_TRUE(
|
||||
webrtc::ParseIceServersOrError(servers, &stun_servers_, &turn_servers_)
|
||||
.ok());
|
||||
EXPECT_EQ(2U, turn_servers_.size());
|
||||
EXPECT_NE(turn_servers_[0].priority, turn_servers_[1].priority);
|
||||
}
|
||||
|
|
|
@ -596,10 +596,10 @@ RTCError PeerConnection::Initialize(
|
|||
cricket::ServerAddresses stun_servers;
|
||||
std::vector<cricket::RelayServerConfig> turn_servers;
|
||||
|
||||
RTCErrorType parse_error =
|
||||
ParseIceServers(configuration.servers, &stun_servers, &turn_servers);
|
||||
if (parse_error != RTCErrorType::NONE) {
|
||||
return RTCError(parse_error, "ICE server parse failed");
|
||||
RTCError parse_error = ParseIceServersOrError(configuration.servers,
|
||||
&stun_servers, &turn_servers);
|
||||
if (!parse_error.ok()) {
|
||||
return parse_error;
|
||||
}
|
||||
|
||||
// Add the turn logging id to all turn servers
|
||||
|
@ -1519,10 +1519,10 @@ RTCError PeerConnection::SetConfiguration(
|
|||
// Parse ICE servers before hopping to network thread.
|
||||
cricket::ServerAddresses stun_servers;
|
||||
std::vector<cricket::RelayServerConfig> turn_servers;
|
||||
RTCErrorType parse_error =
|
||||
ParseIceServers(configuration.servers, &stun_servers, &turn_servers);
|
||||
if (parse_error != RTCErrorType::NONE) {
|
||||
return RTCError(parse_error, "ICE server parse failed");
|
||||
RTCError parse_error = ParseIceServersOrError(configuration.servers,
|
||||
&stun_servers, &turn_servers);
|
||||
if (!parse_error.ok()) {
|
||||
return parse_error;
|
||||
}
|
||||
// Add the turn logging id to all turn servers
|
||||
for (cricket::RelayServerConfig& turn_server : turn_servers) {
|
||||
|
|
Loading…
Reference in a new issue