blob: 93c559b9baa38815bcdd1acffc15dba84d6c75b1 [file] [log] [blame]
// Copyright 2022 The Fuchsia 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 "udp_serde_test_util.h"
namespace fnet = fuchsia_net;
namespace {
constexpr uint16_t kPort = 80;
constexpr size_t kPayloadSize = 41;
constexpr int64_t kTimestampNanos = 42;
constexpr uint8_t kIpTos = 43;
constexpr uint8_t kIpv6Tclass = 45;
constexpr uint8_t kIpv6PktInfoIfIdx = 47;
constexpr uint64_t kZoneIndex = 48;
} // namespace
std::ostream& operator<<(std::ostream& out, const span& span) {
out << '[';
const std::ios_base::fmtflags flags = out.flags();
out.flags(std::ios::hex | std::ios::showbase);
for (auto it = span.begin(); it != span.end(); ++it) {
if (it != span.begin()) {
out << ", ";
}
out << static_cast<unsigned int>(*it);
}
out.flags(flags);
out << ']';
return out;
}
IpAddrType AddrKind::ToAddrType() const {
switch (kind_) {
case Kind::V4:
return IpAddrType::Ipv4;
case Kind::V6:
return IpAddrType::Ipv6;
}
}
fsocket::wire::SendMsgMeta TestSendMsgMeta::GetFidl(fidl::Arena<512>& alloc, bool with_data) const {
fidl::WireTableBuilder<fsocket::wire::SendMsgMeta> meta_builder =
fsocket::wire::SendMsgMeta::Builder(alloc);
if (with_data) {
fnet::wire::SocketAddress socket_addr;
fidl::WireTableBuilder<fsocket::wire::DatagramSocketSendControlData> dgram_builder =
fsocket::wire::DatagramSocketSendControlData::Builder(alloc);
fidl::WireTableBuilder<fsocket::wire::NetworkSocketSendControlData> network_builder =
fsocket::wire::NetworkSocketSendControlData::Builder(alloc);
switch (kind_.GetKind()) {
case AddrKind::Kind::V4: {
fnet::wire::Ipv4Address ipv4_addr;
ipv4_addr.addr = kIPv4Addr;
fnet::wire::Ipv4SocketAddress ipv4_socket_addr;
ipv4_socket_addr.address = ipv4_addr;
ipv4_socket_addr.port = kPort;
socket_addr = fnet::wire::SocketAddress::WithIpv4(alloc, ipv4_socket_addr);
fidl::WireTableBuilder<fsocket::wire::IpSendControlData> ip_builder =
fsocket::wire::IpSendControlData::Builder(alloc);
ip_builder.ttl(kIpTtl);
network_builder.ip(ip_builder.Build());
} break;
case AddrKind::Kind::V6: {
fnet::wire::Ipv6Address ipv6_addr;
ipv6_addr.addr = kIPv6Addr;
fnet::wire::Ipv6SocketAddress ipv6_socket_addr;
ipv6_socket_addr.address = ipv6_addr;
ipv6_socket_addr.port = kPort;
ipv6_socket_addr.zone_index = kZoneIndex;
socket_addr = fnet::wire::SocketAddress::WithIpv6(alloc, ipv6_socket_addr);
fidl::WireTableBuilder<fsocket::wire::Ipv6SendControlData> ip_builder =
fsocket::wire::Ipv6SendControlData::Builder(alloc);
ip_builder.hoplimit(kIpv6Hoplimit);
fsocket::wire::Ipv6PktInfoSendControlData pktinfo = {
.iface = kIpv6PktInfoIfIdx,
.local_addr = ipv6_addr,
};
ip_builder.pktinfo(pktinfo);
network_builder.ipv6(ip_builder.Build());
}
}
dgram_builder.network(network_builder.Build());
meta_builder.control(dgram_builder.Build());
meta_builder.to(socket_addr);
}
return meta_builder.Build();
}
SendMsgMeta TestSendMsgMeta::GetCStruct() const {
return {
.cmsg_set = CmsgSet(),
.addr_type = AddrType(),
.port = Port(),
.zone_index = ZoneIndex(),
};
}
const uint8_t* TestSendMsgMeta::Addr() const {
switch (kind_.GetKind()) {
case AddrKind::Kind::V4:
return kIPv4Addr.data();
case AddrKind::Kind::V6:
return kIPv6Addr.data();
}
}
SendAndRecvCmsgSet TestSendMsgMeta::CmsgSet() const {
SendAndRecvCmsgSet cmsg_set = {
.has_ip_ttl = false,
.has_ipv6_hoplimit = false,
.has_ipv6_pktinfo = false,
};
switch (kind_.GetKind()) {
case AddrKind::Kind::V4:
cmsg_set.has_ip_ttl = true;
cmsg_set.ip_ttl = kIpTtl;
break;
case AddrKind::Kind::V6:
cmsg_set.has_ipv6_hoplimit = true;
cmsg_set.ipv6_hoplimit = kIpv6Hoplimit;
cmsg_set.has_ipv6_pktinfo = true;
cmsg_set.ipv6_pktinfo.if_index = kIpv6PktInfoIfIdx;
memcpy(cmsg_set.ipv6_pktinfo.addr, kIPv6Addr.data(), sizeof(kIPv6Addr));
break;
}
return cmsg_set;
}
size_t TestSendMsgMeta::AddrLen() const { return kind_.Len(); }
IpAddrType TestSendMsgMeta::AddrType() const { return kind_.ToAddrType(); }
uint16_t TestSendMsgMeta::Port() const { return kPort; }
uint64_t TestSendMsgMeta::ZoneIndex() const {
switch (kind_.GetKind()) {
case AddrKind::Kind::V6:
return kZoneIndex;
case AddrKind::Kind::V4:
return 0;
}
}
std::pair<RecvMsgMeta, ConstBuffer> TestRecvMsgMeta::GetSerializeInput(bool with_data) const {
RecvMsgMeta meta = {
.cmsg_set =
{
.has_timestamp_nanos = false,
.has_ip_tos = false,
.has_ipv6_tclass = false,
.send_and_recv =
{
.has_ip_ttl = false,
.has_ipv6_hoplimit = false,
.has_ipv6_pktinfo = false,
},
},
.payload_size = kPayloadSize,
.port = kPort,
};
if (with_data) {
meta.cmsg_set.has_timestamp_nanos = true;
meta.cmsg_set.timestamp_nanos = kTimestampNanos;
}
switch (kind_.GetKind()) {
case AddrKind::Kind::V4:
if (with_data) {
meta.addr_type = IpAddrType::Ipv4;
meta.cmsg_set.has_ip_tos = true;
meta.cmsg_set.ip_tos = kIpTos;
meta.cmsg_set.send_and_recv.has_ip_ttl = true;
meta.cmsg_set.send_and_recv.ip_ttl = kIpTtl;
}
meta.addr_type = IpAddrType::Ipv4;
return {
meta,
ConstBuffer{
.buf = kIPv4Addr.data(),
.buf_size = kIPv4Addr.size(),
},
};
case AddrKind::Kind::V6: {
const ConstBuffer kIPv6AddrBuf = {
.buf = kIPv6Addr.data(),
.buf_size = kIPv6Addr.size(),
};
if (with_data) {
meta.addr_type = IpAddrType::Ipv6;
meta.cmsg_set.has_ipv6_tclass = true;
meta.cmsg_set.ipv6_tclass = kIpv6Tclass;
meta.cmsg_set.send_and_recv.has_ipv6_hoplimit = true;
meta.cmsg_set.send_and_recv.ipv6_hoplimit = kIpv6Hoplimit;
meta.cmsg_set.send_and_recv.has_ipv6_pktinfo = true;
meta.cmsg_set.send_and_recv.ipv6_pktinfo = {
.if_index = kIpv6PktInfoIfIdx,
};
memcpy(meta.cmsg_set.send_and_recv.ipv6_pktinfo.addr, kIPv6AddrBuf.buf,
kIPv6AddrBuf.buf_size);
}
meta.addr_type = IpAddrType::Ipv6;
meta.zone_index = kZoneIndex;
return {
meta,
kIPv6AddrBuf,
};
} break;
}
}
DeserializeRecvMsgMetaResult TestRecvMsgMeta::GetExpectedDeserializeResult() const {
const auto& [recv_meta, addr] = GetSerializeInput();
DeserializeRecvMsgMetaResult res = {
.err = DeserializeRecvMsgMetaErrorNone,
.has_addr = true,
.addr =
{
.addr_type = recv_meta.addr_type,
},
.payload_size = recv_meta.payload_size,
.port = recv_meta.port,
.zone_index = recv_meta.zone_index,
.cmsg_set = recv_meta.cmsg_set,
};
memcpy(res.addr.addr, addr.buf, addr.buf_size);
return res;
}