1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "platform/impl/socket_address_posix.h" 6 7 #include <cstring> 8 #include <vector> 9 10 #include "util/osp_logging.h" 11 12 namespace openscreen { 13 SocketAddressPosix(const struct sockaddr & address)14SocketAddressPosix::SocketAddressPosix(const struct sockaddr& address) { 15 if (address.sa_family == AF_INET) { 16 memcpy(&internal_address_, &address, sizeof(struct sockaddr_in)); 17 RecomputeEndpoint(IPAddress::Version::kV4); 18 } else if (address.sa_family == AF_INET6) { 19 memcpy(&internal_address_, &address, sizeof(struct sockaddr_in6)); 20 RecomputeEndpoint(IPAddress::Version::kV6); 21 } else { 22 // Not IPv4 or IPv6. 23 OSP_NOTREACHED(); 24 } 25 } 26 SocketAddressPosix(const IPEndpoint & endpoint)27SocketAddressPosix::SocketAddressPosix(const IPEndpoint& endpoint) 28 : endpoint_(endpoint) { 29 if (endpoint.address.IsV4()) { 30 internal_address_.v4.sin_family = AF_INET; 31 internal_address_.v4.sin_port = htons(endpoint.port); 32 endpoint.address.CopyToV4( 33 reinterpret_cast<uint8_t*>(&internal_address_.v4.sin_addr.s_addr)); 34 } else { 35 OSP_DCHECK(endpoint.address.IsV6()); 36 37 internal_address_.v6.sin6_family = AF_INET6; 38 internal_address_.v6.sin6_flowinfo = 0; 39 internal_address_.v6.sin6_scope_id = 0; 40 internal_address_.v6.sin6_port = htons(endpoint.port); 41 endpoint.address.CopyToV6( 42 reinterpret_cast<uint8_t*>(&internal_address_.v6.sin6_addr)); 43 } 44 } 45 address()46struct sockaddr* SocketAddressPosix::address() { 47 switch (version()) { 48 case IPAddress::Version::kV4: 49 return reinterpret_cast<struct sockaddr*>(&internal_address_.v4); 50 case IPAddress::Version::kV6: 51 return reinterpret_cast<struct sockaddr*>(&internal_address_.v6); 52 default: 53 OSP_NOTREACHED(); 54 } 55 } 56 address() const57const struct sockaddr* SocketAddressPosix::address() const { 58 switch (version()) { 59 case IPAddress::Version::kV4: 60 return reinterpret_cast<const struct sockaddr*>(&internal_address_.v4); 61 case IPAddress::Version::kV6: 62 return reinterpret_cast<const struct sockaddr*>(&internal_address_.v6); 63 default: 64 OSP_NOTREACHED(); 65 } 66 } 67 size() const68socklen_t SocketAddressPosix::size() const { 69 switch (version()) { 70 case IPAddress::Version::kV4: 71 return sizeof(struct sockaddr_in); 72 case IPAddress::Version::kV6: 73 return sizeof(struct sockaddr_in6); 74 default: 75 OSP_NOTREACHED(); 76 } 77 } 78 RecomputeEndpoint()79void SocketAddressPosix::RecomputeEndpoint() { 80 RecomputeEndpoint(endpoint_.address.version()); 81 } 82 RecomputeEndpoint(IPAddress::Version version)83void SocketAddressPosix::RecomputeEndpoint(IPAddress::Version version) { 84 switch (version) { 85 case IPAddress::Version::kV4: 86 endpoint_.address = IPAddress(IPAddress::Version::kV4, 87 reinterpret_cast<const uint8_t*>( 88 &internal_address_.v4.sin_addr.s_addr)); 89 endpoint_.port = ntohs(internal_address_.v4.sin_port); 90 break; 91 case IPAddress::Version::kV6: 92 endpoint_.address = IPAddress(IPAddress::Version::kV6, 93 internal_address_.v6.sin6_addr.s6_addr); 94 endpoint_.port = ntohs(internal_address_.v6.sin6_port); 95 break; 96 } 97 } 98 99 } // namespace openscreen 100