You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.1 KiB
100 lines
3.1 KiB
// Copyright 2019 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "platform/impl/socket_address_posix.h"
|
|
|
|
#include <cstring>
|
|
#include <vector>
|
|
|
|
#include "util/osp_logging.h"
|
|
|
|
namespace openscreen {
|
|
|
|
SocketAddressPosix::SocketAddressPosix(const struct sockaddr& address) {
|
|
if (address.sa_family == AF_INET) {
|
|
memcpy(&internal_address_, &address, sizeof(struct sockaddr_in));
|
|
RecomputeEndpoint(IPAddress::Version::kV4);
|
|
} else if (address.sa_family == AF_INET6) {
|
|
memcpy(&internal_address_, &address, sizeof(struct sockaddr_in6));
|
|
RecomputeEndpoint(IPAddress::Version::kV6);
|
|
} else {
|
|
// Not IPv4 or IPv6.
|
|
OSP_NOTREACHED();
|
|
}
|
|
}
|
|
|
|
SocketAddressPosix::SocketAddressPosix(const IPEndpoint& endpoint)
|
|
: endpoint_(endpoint) {
|
|
if (endpoint.address.IsV4()) {
|
|
internal_address_.v4.sin_family = AF_INET;
|
|
internal_address_.v4.sin_port = htons(endpoint.port);
|
|
endpoint.address.CopyToV4(
|
|
reinterpret_cast<uint8_t*>(&internal_address_.v4.sin_addr.s_addr));
|
|
} else {
|
|
OSP_DCHECK(endpoint.address.IsV6());
|
|
|
|
internal_address_.v6.sin6_family = AF_INET6;
|
|
internal_address_.v6.sin6_flowinfo = 0;
|
|
internal_address_.v6.sin6_scope_id = 0;
|
|
internal_address_.v6.sin6_port = htons(endpoint.port);
|
|
endpoint.address.CopyToV6(
|
|
reinterpret_cast<uint8_t*>(&internal_address_.v6.sin6_addr));
|
|
}
|
|
}
|
|
|
|
struct sockaddr* SocketAddressPosix::address() {
|
|
switch (version()) {
|
|
case IPAddress::Version::kV4:
|
|
return reinterpret_cast<struct sockaddr*>(&internal_address_.v4);
|
|
case IPAddress::Version::kV6:
|
|
return reinterpret_cast<struct sockaddr*>(&internal_address_.v6);
|
|
default:
|
|
OSP_NOTREACHED();
|
|
}
|
|
}
|
|
|
|
const struct sockaddr* SocketAddressPosix::address() const {
|
|
switch (version()) {
|
|
case IPAddress::Version::kV4:
|
|
return reinterpret_cast<const struct sockaddr*>(&internal_address_.v4);
|
|
case IPAddress::Version::kV6:
|
|
return reinterpret_cast<const struct sockaddr*>(&internal_address_.v6);
|
|
default:
|
|
OSP_NOTREACHED();
|
|
}
|
|
}
|
|
|
|
socklen_t SocketAddressPosix::size() const {
|
|
switch (version()) {
|
|
case IPAddress::Version::kV4:
|
|
return sizeof(struct sockaddr_in);
|
|
case IPAddress::Version::kV6:
|
|
return sizeof(struct sockaddr_in6);
|
|
default:
|
|
OSP_NOTREACHED();
|
|
}
|
|
}
|
|
|
|
void SocketAddressPosix::RecomputeEndpoint() {
|
|
RecomputeEndpoint(endpoint_.address.version());
|
|
}
|
|
|
|
void SocketAddressPosix::RecomputeEndpoint(IPAddress::Version version) {
|
|
switch (version) {
|
|
case IPAddress::Version::kV4:
|
|
endpoint_.address = IPAddress(IPAddress::Version::kV4,
|
|
reinterpret_cast<const uint8_t*>(
|
|
&internal_address_.v4.sin_addr.s_addr));
|
|
endpoint_.port = ntohs(internal_address_.v4.sin_port);
|
|
break;
|
|
case IPAddress::Version::kV6:
|
|
endpoint_.address = IPAddress(IPAddress::Version::kV6,
|
|
internal_address_.v6.sin6_addr.s6_addr);
|
|
endpoint_.port = ntohs(internal_address_.v6.sin6_port);
|
|
break;
|
|
}
|
|
}
|
|
|
|
} // namespace openscreen
|