diff options
Diffstat (limited to 'src/net/packets.hpp')
-rw-r--r-- | src/net/packets.hpp | 215 |
1 files changed, 93 insertions, 122 deletions
diff --git a/src/net/packets.hpp b/src/net/packets.hpp index 2e3d77c..c0f3ecb 100644 --- a/src/net/packets.hpp +++ b/src/net/packets.hpp @@ -25,7 +25,10 @@ # include "../ints/little.hpp" - #include "../io/fwd.hpp" +# include "../io/fwd.hpp" + +// ordering violation, should invert +# include "../proto2/fwd.hpp" # include "socket.hpp" @@ -66,55 +69,55 @@ bool packet_peek_id(Session *s, uint16_t *packet_id) return okay; } -template<class F> +template<uint16_t id> __attribute__((warn_unused_result)) -SendResult net_send_fpacket(Session *s, const F& fixed) +SendResult net_send_fpacket(Session *s, const NetPacket_Fixed<id>& fixed) { - bool ok = packet_send(s, reinterpret_cast<const Byte *>(&fixed), sizeof(F)); + bool ok = packet_send(s, reinterpret_cast<const Byte *>(&fixed), sizeof(NetPacket_Fixed<id>)); return ok ? SendResult::Success : SendResult::Fail; } -template<class H, class R> +template<uint16_t id> __attribute__((warn_unused_result)) -SendResult net_send_vpacket(Session *s, const H& head, const std::vector<R>& repeat) +SendResult net_send_vpacket(Session *s, const NetPacket_Head<id>& head, const std::vector<NetPacket_Repeat<id>>& repeat) { - bool ok = packet_send(s, reinterpret_cast<const Byte *>(&head), sizeof(H)); - ok &= packet_send(s, reinterpret_cast<const Byte *>(repeat.data()), repeat.size() * sizeof(R)); + bool ok = packet_send(s, reinterpret_cast<const Byte *>(&head), sizeof(NetPacket_Head<id>)); + ok &= packet_send(s, reinterpret_cast<const Byte *>(repeat.data()), repeat.size() * sizeof(NetPacket_Repeat<id>)); return ok ? SendResult::Success : SendResult::Fail; } -template<class F> +template<uint16_t id> __attribute__((warn_unused_result)) -RecvResult net_recv_fpacket(Session *s, F& fixed) +RecvResult net_recv_fpacket(Session *s, NetPacket_Fixed<id>& fixed) { - bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&fixed), sizeof(F)); + bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&fixed), sizeof(NetPacket_Fixed<id>)); if (ok) { - packet_discard(s, sizeof(F)); + packet_discard(s, sizeof(NetPacket_Fixed<id>)); return RecvResult::Complete; } return RecvResult::Incomplete; } -template<class HNat, class H, class R> +template<uint16_t id> __attribute__((warn_unused_result)) -RecvResult net_recv_vpacket(Session *s, H& head, std::vector<R>& repeat) +RecvResult net_recv_vpacket(Session *s, NetPacket_Head<id>& head, std::vector<NetPacket_Repeat<id>>& repeat) { - bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&head), sizeof(H)); + bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&head), sizeof(NetPacket_Head<id>)); if (ok) { - HNat nat; + Packet_Head<id> nat; if (!network_to_native(&nat, head)) return RecvResult::Error; if (packet_avail(s) < nat.magic_packet_length) return RecvResult::Incomplete; - if (nat.magic_packet_length < sizeof(H)) + if (nat.magic_packet_length < sizeof(NetPacket_Head<id>)) return RecvResult::Error; - size_t bytes_repeat = nat.magic_packet_length - sizeof(H); - if (bytes_repeat % sizeof(R)) + size_t bytes_repeat = nat.magic_packet_length - sizeof(NetPacket_Head<id>); + if (bytes_repeat % sizeof(NetPacket_Repeat<id>)) return RecvResult::Error; - repeat.resize(bytes_repeat / sizeof(R)); - if (packet_fetch(s, sizeof(H), reinterpret_cast<Byte *>(repeat.data()), bytes_repeat)) + repeat.resize(bytes_repeat / sizeof(NetPacket_Repeat<id>)); + if (packet_fetch(s, sizeof(NetPacket_Head<id>), reinterpret_cast<Byte *>(repeat.data()), bytes_repeat)) { packet_discard(s, nat.magic_packet_length); return RecvResult::Complete; @@ -125,13 +128,13 @@ RecvResult net_recv_vpacket(Session *s, H& head, std::vector<R>& repeat) } -template<uint16_t id, uint16_t size, class F> -void send_fpacket(Session *s, const F& fixed) +template<uint16_t id, uint16_t size> +void send_fpacket(Session *s, const Packet_Fixed<id>& fixed) { - static_assert(id == F::PACKET_ID, "F::PACKET_ID"); - static_assert(size == sizeof(typename F::NetType), "F::NetType"); + static_assert(id == Packet_Fixed<id>::PACKET_ID, "Packet_Fixed<id>::PACKET_ID"); + static_assert(size == sizeof(NetPacket_Fixed<id>), "sizeof(NetPacket_Fixed<id>)"); - typename F::NetType net_fixed; + NetPacket_Fixed<id> net_fixed; if (!native_to_network(&net_fixed, fixed)) { s->set_eof(); @@ -142,17 +145,17 @@ void send_fpacket(Session *s, const F& fixed) s->set_eof(); } -template<uint16_t id, uint16_t headsize, uint16_t repeatsize, class H, class R> -void send_vpacket(Session *s, H& head, const std::vector<R>& repeat) +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +void send_vpacket(Session *s, Packet_Head<id>& head, const std::vector<Packet_Repeat<id>>& repeat) { - static_assert(id == H::PACKET_ID, "H::PACKET_ID"); - static_assert(headsize == sizeof(typename H::NetType), "H::NetType"); - static_assert(id == R::PACKET_ID, "R::PACKET_ID"); - static_assert(repeatsize == sizeof(typename R::NetType), "R::NetType"); + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "sizeof(NetPacket_Head<id>)"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "sizeof(NetPacket_Repeat<id>)"); - typename H::NetType net_head; + NetPacket_Head<id> net_head; // since these are already allocated, can't overflow address space - size_t total_size = sizeof(typename H::NetType) + repeat.size() * sizeof(typename R::NetType); + size_t total_size = sizeof(NetPacket_Head<id>) + repeat.size() * sizeof(NetPacket_Repeat<id>); // truncates head.magic_packet_length = total_size; if (head.magic_packet_length != total_size) @@ -161,7 +164,7 @@ void send_vpacket(Session *s, H& head, const std::vector<R>& repeat) return; } // TODO potentially avoid the allocation - std::vector<typename R::NetType> net_repeat(repeat.size()); + std::vector<NetPacket_Repeat<id>> net_repeat(repeat.size()); if (!native_to_network(&net_head, head)) { s->set_eof(); @@ -180,16 +183,16 @@ void send_vpacket(Session *s, H& head, const std::vector<R>& repeat) s->set_eof(); } -template<uint16_t id, uint16_t size, class F> +template<uint16_t id, uint16_t size> __attribute__((warn_unused_result)) -RecvResult recv_fpacket(Session *s, F& fixed) +RecvResult recv_fpacket(Session *s, Packet_Fixed<id>& fixed) { - static_assert(id == F::PACKET_ID, "F::PACKET_ID"); - static_assert(size == sizeof(typename F::NetType), "F::NetType"); + static_assert(id == Packet_Fixed<id>::PACKET_ID, "Packet_Fixed<id>::PACKET_ID"); + static_assert(size == sizeof(NetPacket_Fixed<id>), "NetPacket_Fixed<id>"); - typename F::NetType net_fixed; + NetPacket_Fixed<id> net_fixed; RecvResult rv = net_recv_fpacket(s, net_fixed); - assert (fixed.magic_packet_id == F::PACKET_ID); + assert (fixed.magic_packet_id == Packet_Fixed<id>::PACKET_ID); if (rv == RecvResult::Complete) { if (!network_to_native(&fixed, net_fixed)) @@ -198,19 +201,19 @@ RecvResult recv_fpacket(Session *s, F& fixed) return rv; } -template<uint16_t id, uint16_t headsize, uint16_t repeatsize, class H, class R> +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> __attribute__((warn_unused_result)) -RecvResult recv_vpacket(Session *s, H& head, std::vector<R>& repeat) +RecvResult recv_vpacket(Session *s, Packet_Head<id>& head, std::vector<Packet_Repeat<id>>& repeat) { - static_assert(id == H::PACKET_ID, "H::PACKET_ID"); - static_assert(headsize == sizeof(typename H::NetType), "H::NetType"); - static_assert(id == R::PACKET_ID, "R::PACKET_ID"); - static_assert(repeatsize == sizeof(typename R::NetType), "R::NetType"); - - typename H::NetType net_head; - std::vector<typename R::NetType> net_repeat; - RecvResult rv = net_recv_vpacket<H>(s, net_head, net_repeat); - assert (head.magic_packet_id == H::PACKET_ID); + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "NetPacket_Head<id>"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "NetPacket_Repeat<id>"); + + NetPacket_Head<id> net_head; + std::vector<NetPacket_Repeat<id>> net_repeat; + RecvResult rv = net_recv_vpacket(s, net_head, net_repeat); + assert (head.magic_packet_id == Packet_Head<id>::PACKET_ID); if (rv == RecvResult::Complete) { if (!network_to_native(&head, net_head)) @@ -227,22 +230,18 @@ RecvResult recv_vpacket(Session *s, H& head, std::vector<R>& repeat) // convenience for trailing strings -struct VarStringNetType +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +void send_vpacket(Session *s, Packet_Head<id>& head, const XString& repeat) { - char c; -}; + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "NetPacket_Head<id>"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "NetPacket_Repeat<id>"); + static_assert(repeatsize == 1, "repeatsize"); -template<uint16_t id, uint16_t headsize, uint16_t repeatsize, class H> -void send_vpacket(Session *s, H& head, const XString& repeat) -{ - static_assert(id == H::PACKET_ID, "H::PACKET_ID"); - static_assert(headsize == sizeof(typename H::NetType), "H::NetType"); - // static_assert(id == R::PACKET_ID, "R::PACKET_ID"); - static_assert(repeatsize == 1, "R::NetType"); - - typename H::NetType net_head; + NetPacket_Head<id> net_head; // since it's already allocated, it can't overflow address space - size_t total_length = sizeof(typename H::NetType) + (repeat.size() + 1) * sizeof(VarStringNetType); + size_t total_length = sizeof(NetPacket_Head<id>) + (repeat.size() + 1) * sizeof(NetPacket_Repeat<id>); head.magic_packet_length = total_length; if (head.magic_packet_length != total_length) { @@ -250,7 +249,7 @@ void send_vpacket(Session *s, H& head, const XString& repeat) return; } // TODO potentially avoid the allocation - std::vector<VarStringNetType> net_repeat(repeat.size() + 1); + std::vector<NetPacket_Repeat<id>> net_repeat(repeat.size() + 1); if (!native_to_network(&net_head, head)) { s->set_eof(); @@ -258,27 +257,28 @@ void send_vpacket(Session *s, H& head, const XString& repeat) } for (size_t i = 0; i < repeat.size(); ++i) { - net_repeat[i].c = repeat[i]; + net_repeat[i].c = Byte{static_cast<uint8_t>(repeat[i])}; } - net_repeat[repeat.size()].c = '\0'; + net_repeat[repeat.size()].c = Byte{static_cast<uint8_t>('\0')}; SendResult rv = net_send_vpacket(s, net_head, net_repeat); if (rv != SendResult::Success) s->set_eof(); } -template<uint16_t id, uint16_t headsize, uint16_t repeatsize, class H> +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> __attribute__((warn_unused_result)) -RecvResult recv_vpacket(Session *s, H& head, AString& repeat) +RecvResult recv_vpacket(Session *s, Packet_Head<id>& head, AString& repeat) { - static_assert(id == H::PACKET_ID, "H::PACKET_ID"); - static_assert(headsize == sizeof(typename H::NetType), "H::NetType"); - //static_assert(id == R::PACKET_ID, "R::PACKET_ID"); - static_assert(repeatsize == 1, "R::NetType"); - - typename H::NetType net_head; - std::vector<VarStringNetType> net_repeat; - RecvResult rv = net_recv_vpacket<H>(s, net_head, net_repeat); - assert (head.magic_packet_id == H::PACKET_ID); + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "NetPacket_Head<id>"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "NetPacket_Repeat<id>"); + static_assert(repeatsize == 1, "repeatsize"); + + NetPacket_Head<id> net_head; + std::vector<NetPacket_Repeat<id>> net_repeat; + RecvResult rv = net_recv_vpacket(s, net_head, net_repeat); + assert (head.magic_packet_id == Packet_Head<id>::PACKET_ID); if (rv == RecvResult::Complete) { if (!network_to_native(&head, net_head)) @@ -295,59 +295,30 @@ RecvResult recv_vpacket(Session *s, H& head, AString& repeat) // if there is nothing in the head but the id and length, use the below -// TODO make this go away with template specialization - -template<uint16_t PKT_ID> -struct NetCommonPacketHead -{ - Little16 magic_packet_id; - Little16 magic_packet_length; -}; - -template<uint16_t PKT_ID> -struct CommonPacketHead -{ - using NetType = NetCommonPacketHead<PKT_ID>; - static const uint16_t PACKET_ID = PKT_ID; - - uint16_t magic_packet_id = PACKET_ID; - uint16_t magic_packet_length; -}; - -template<uint16_t PKT_ID> -bool native_to_network(NetCommonPacketHead<PKT_ID> *net, CommonPacketHead<PKT_ID> nat) -{ - return native_to_network(&net->magic_packet_id, nat.magic_packet_id) - && native_to_network(&net->magic_packet_length, nat.magic_packet_length); -} - -template<uint16_t PKT_ID> -bool network_to_native(CommonPacketHead<PKT_ID> *nat, NetCommonPacketHead<PKT_ID> net) -{ - return network_to_native(&nat->magic_packet_id, net.magic_packet_id) - && network_to_native(&nat->magic_packet_length, net.magic_packet_length); -} - -template<uint16_t id, uint16_t headsize, uint16_t repeatsize, class R> -void send_packet_repeatonly(Session *s, const std::vector<R>& v) +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +void send_packet_repeatonly(Session *s, const std::vector<Packet_Repeat<id>>& v) { + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "repeat headsize"); static_assert(headsize == 4, "repeat headsize"); - static_assert(id == R::PACKET_ID, "R::PACKET_ID"); - static_assert(repeatsize == sizeof(typename R::NetType), "R::NetType"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "sizeof(NetPacket_Repeat<id>)"); - CommonPacketHead<R::PACKET_ID> head; + Packet_Head<id> head; send_vpacket<id, 4, repeatsize>(s, head, v); } -template<uint16_t id, uint16_t headsize, uint16_t repeatsize, class R> +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> __attribute__((warn_unused_result)) -RecvResult recv_packet_repeatonly(Session *s, std::vector<R>& v) +RecvResult recv_packet_repeatonly(Session *s, std::vector<Packet_Repeat<id>>& v) { + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "repeat headsize"); static_assert(headsize == 4, "repeat headsize"); - static_assert(id == R::PACKET_ID, "R::PACKET_ID"); - static_assert(repeatsize == sizeof(typename R::NetType), "R::NetType"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "sizeof(NetPacket_Repeat<id>)"); - CommonPacketHead<R::PACKET_ID> head; + Packet_Head<id> head; return recv_vpacket<id, 4, repeatsize>(s, head, v); } |