From 5fdf255a2da7736a791a8a35f9652ea5ac14fe06 Mon Sep 17 00:00:00 2001 From: Sepalani Date: Sun, 10 Jul 2022 20:12:07 +0400 Subject: [PATCH] Common/Network: Make Build() methods const --- Source/Core/Common/Network.cpp | 74 +++++++++++++------------ Source/Core/Common/Network.h | 4 +- Source/Core/Core/HW/EXI/BBA/BuiltIn.cpp | 12 ++-- 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/Source/Core/Common/Network.cpp b/Source/Core/Common/Network.cpp index 1ee5496fcc..f35308a5ab 100644 --- a/Source/Core/Common/Network.cpp +++ b/Source/Core/Common/Network.cpp @@ -355,34 +355,36 @@ TCPPacket::TCPPacket(const MACAddress& destination, const MACAddress& source, { } -std::vector TCPPacket::Build() +std::vector TCPPacket::Build() const { std::vector result; - result.reserve(Size()); + result.reserve(Size()); // Useful not to invalidate .data() pointers - // recalc size - ip_header.total_len = htons(static_cast(IPv4Header::SIZE + ipv4_options.size() + - TCPHeader::SIZE + tcp_options.size() + data.size())); - - // copy data + // Copy data InsertObj(&result, eth_header); + u8* const ip_ptr = result.data() + result.size(); InsertObj(&result, ip_header); result.insert(result.end(), ipv4_options.begin(), ipv4_options.end()); - const std::size_t tcp_offset = result.size(); - - tcp_header.checksum = 0; - const u16 props = (ntohs(tcp_header.properties) & 0xfff) | - (static_cast((tcp_options.size() + TCPHeader::SIZE) & 0x3c) << 10); - tcp_header.properties = htons(props); - const u8* tcp_ptr = reinterpret_cast(&tcp_header); - result.insert(result.end(), tcp_ptr, tcp_ptr + TCPHeader::SIZE); + u8* const tcp_ptr = result.data() + result.size(); + InsertObj(&result, tcp_header); result.insert(result.end(), tcp_options.begin(), tcp_options.end()); result.insert(result.end(), data.begin(), data.end()); - tcp_header.checksum = ComputeTCPNetworkChecksum( - ip_header.source_addr, ip_header.destination_addr, &result[tcp_offset], - static_cast(result.size() - tcp_offset), IPPROTO_TCP); - std::copy(tcp_ptr, tcp_ptr + TCPHeader::SIZE, result.begin() + tcp_offset); + // Adjust size and checksum fields + const u16 tcp_length = static_cast(TCPHeader::SIZE + tcp_options.size() + data.size()); + const u16 tcp_properties = + (ntohs(tcp_header.properties) & 0xfff) | + (static_cast((tcp_options.size() + TCPHeader::SIZE) & 0x3c) << 10); + Common::BitCastPtr(tcp_ptr + offsetof(TCPHeader, properties)) = htons(tcp_properties); + + const u16 ip_total_len = static_cast(IPv4Header::SIZE + ipv4_options.size() + tcp_length); + Common::BitCastPtr(ip_ptr + offsetof(IPv4Header, total_len)) = htons(ip_total_len); + + auto checksum_bitcast_ptr = Common::BitCastPtr(tcp_ptr + offsetof(TCPHeader, checksum)); + checksum_bitcast_ptr = u16(0); + checksum_bitcast_ptr = ComputeTCPNetworkChecksum( + ip_header.source_addr, ip_header.destination_addr, tcp_ptr, tcp_length, IPPROTO_TCP); + return result; } @@ -401,31 +403,31 @@ UDPPacket::UDPPacket(const MACAddress& destination, const MACAddress& source, { } -std::vector UDPPacket::Build() +std::vector UDPPacket::Build() const { std::vector result; - result.reserve(Size()); + result.reserve(Size()); // Useful not to invalidate .data() pointers - // recalc size - ip_header.total_len = htons( - static_cast(IPv4Header::SIZE + ipv4_options.size() + UDPHeader::SIZE + data.size())); - udp_header.length = htons(static_cast(UDPHeader::SIZE + data.size())); - - // copy data + // Copy data InsertObj(&result, eth_header); + u8* const ip_ptr = result.data() + result.size(); InsertObj(&result, ip_header); result.insert(result.end(), ipv4_options.begin(), ipv4_options.end()); - const std::size_t udp_offset = result.size(); - - udp_header.checksum = 0; - const u8* udp_ptr = reinterpret_cast(&udp_header); - result.insert(result.end(), udp_ptr, udp_ptr + UDPHeader::SIZE); + u8* const udp_ptr = result.data() + result.size(); + InsertObj(&result, udp_header); result.insert(result.end(), data.begin(), data.end()); - udp_header.checksum = ComputeTCPNetworkChecksum( - ip_header.source_addr, ip_header.destination_addr, &result[udp_offset], - static_cast(result.size() - udp_offset), IPPROTO_UDP); - std::copy(udp_ptr, udp_ptr + UDPHeader::SIZE, result.begin() + udp_offset); + // Adjust size and checksum fields + const u16 udp_length = static_cast(UDPHeader::SIZE + data.size()); + Common::BitCastPtr(udp_ptr + offsetof(UDPHeader, length)) = htons(udp_length); + + const u16 ip_total_len = static_cast(IPv4Header::SIZE + ipv4_options.size() + udp_length); + Common::BitCastPtr(ip_ptr + offsetof(IPv4Header, total_len)) = htons(ip_total_len); + + auto checksum_bitcast_ptr = Common::BitCastPtr(udp_ptr + offsetof(UDPHeader, checksum)); + checksum_bitcast_ptr = u16(0); + checksum_bitcast_ptr = ComputeTCPNetworkChecksum( + ip_header.source_addr, ip_header.destination_addr, udp_ptr, udp_length, IPPROTO_UDP); return result; } diff --git a/Source/Core/Common/Network.h b/Source/Core/Common/Network.h index e3b319bc6b..27eaad7c42 100644 --- a/Source/Core/Common/Network.h +++ b/Source/Core/Common/Network.h @@ -202,7 +202,7 @@ struct TCPPacket TCPPacket(); TCPPacket(const MACAddress& destination, const MACAddress& source, const sockaddr_in& from, const sockaddr_in& to, u32 seq, u32 ack, u16 flags); - std::vector Build(); + std::vector Build() const; u16 Size() const; EthernetHeader eth_header; @@ -220,7 +220,7 @@ struct UDPPacket UDPPacket(); UDPPacket(const MACAddress& destination, const MACAddress& source, const sockaddr_in& from, const sockaddr_in& to, const std::vector& payload); - std::vector Build(); + std::vector Build() const; u16 Size() const; EthernetHeader eth_header; diff --git a/Source/Core/Core/HW/EXI/BBA/BuiltIn.cpp b/Source/Core/Core/HW/EXI/BBA/BuiltIn.cpp index 8dfbf59764..78ba89bc78 100644 --- a/Source/Core/Core/HW/EXI/BBA/BuiltIn.cpp +++ b/Source/Core/Core/HW/EXI/BBA/BuiltIn.cpp @@ -142,7 +142,7 @@ void CEXIETHERNET::BuiltInBBAInterface::HandleDHCP(const Common::UDPPacket& pack reply.AddOption(3, ip_part); // router ip reply.AddOption(255, {}); // end - Common::UDPPacket response(bba_mac, m_fake_mac, from, to, reply.Build()); + const Common::UDPPacket response(bba_mac, m_fake_mac, from, to, reply.Build()); WriteToQueue(response.Build()); } @@ -179,8 +179,8 @@ StackRef* CEXIETHERNET::BuiltInBBAInterface::GetTCPSlot(u16 src_port, u16 dst_po std::vector BuildFINFrame(StackRef* ref) { - Common::TCPPacket result(ref->bba_mac, ref->my_mac, ref->from, ref->to, ref->seq_num, - ref->ack_num, TCP_FLAG_FIN | TCP_FLAG_ACK | TCP_FLAG_RST); + const Common::TCPPacket result(ref->bba_mac, ref->my_mac, ref->from, ref->to, ref->seq_num, + ref->ack_num, TCP_FLAG_FIN | TCP_FLAG_ACK | TCP_FLAG_RST); for (auto& tcp_buf : ref->tcp_buffers) tcp_buf.used = false; @@ -189,8 +189,8 @@ std::vector BuildFINFrame(StackRef* ref) std::vector BuildAckFrame(StackRef* ref) { - Common::TCPPacket result(ref->bba_mac, ref->my_mac, ref->from, ref->to, ref->seq_num, - ref->ack_num, TCP_FLAG_ACK); + const Common::TCPPacket result(ref->bba_mac, ref->my_mac, ref->from, ref->to, ref->seq_num, + ref->ack_num, TCP_FLAG_ACK); return result.Build(); } @@ -498,7 +498,7 @@ std::optional> TryGetDataFromSocket(StackRef* ref) ref->from.sin_port = htons(remote_port); ref->from.sin_addr.s_addr = htonl(ref->target.toInteger()); const std::vector udp_data(buffer.begin(), buffer.begin() + datasize); - Common::UDPPacket packet(ref->bba_mac, ref->my_mac, ref->from, ref->to, udp_data); + const Common::UDPPacket packet(ref->bba_mac, ref->my_mac, ref->from, ref->to, udp_data); return packet.Build(); } break;