blob: 62416829a957e03da9db2c41ecbbb608e2266df3 [file] [log] [blame]
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/network/socket_address_parser.h"
#include "base/logging.h"
#include "googleurl/src/url_canon.h"
#include "googleurl/src/url_canon_ip.h"
#include "net/base/net_util.h"
#include "starboard/memory.h"
namespace cobalt {
namespace network {
bool ParseSocketAddress(const char* spec,
const url_parse::Component& host_component,
SbSocketAddress* out_socket_address) {
DCHECK(out_socket_address);
unsigned char address_v4[net::kIPv4AddressSize];
int num_ipv4_components = 0;
// IPv4AddressToNumber will return either IPV4, BROKEN, or NEUTRAL. If the
// input IP address is IPv6, then NEUTRAL will be returned, and a different
// function will be used to covert the hostname to IPv6 address.
// If the return value is IPV4, then address will be in network byte order.
url_canon::CanonHostInfo::Family family = url_canon::IPv4AddressToNumber(
spec, host_component, address_v4, &num_ipv4_components);
switch (family) {
case url_canon::CanonHostInfo::IPV4:
if (num_ipv4_components != net::kIPv4AddressSize) {
return false;
}
SbMemorySet(out_socket_address, 0, sizeof(SbSocketAddress));
out_socket_address->type = kSbSocketAddressTypeIpv4;
DCHECK_GE(sizeof(address_v4),
static_cast<std::size_t>(num_ipv4_components));
SbMemoryCopy(out_socket_address->address, address_v4,
num_ipv4_components);
return true;
case url_canon::CanonHostInfo::NEUTRAL:
#if SB_HAS(IPV6)
unsigned char address_v6[net::kIPv6AddressSize];
if (!url_canon::IPv6AddressToNumber(spec, host_component, address_v6)) {
break;
}
SbMemorySet(out_socket_address, 0, sizeof(SbSocketAddress));
out_socket_address->type = kSbSocketAddressTypeIpv6;
COMPILE_ASSERT(sizeof(address_v6), kIPv6AddressLength);
SbMemoryCopy(out_socket_address->address, address_v6, sizeof(address_v6));
return true;
#else
return false;
#endif
case url_canon::CanonHostInfo::BROKEN:
break;
case url_canon::CanonHostInfo::IPV6:
NOTREACHED() << "Invalid return value from IPv4AddressToNumber.";
break;
default:
NOTREACHED() << "Unexpected return value from IPv4AddressToNumber: "
<< family;
break;
}
return false;
}
} // namespace network
} // namespace cobalt