From 86395f53634b3ef1ce76a7f1e5edfdb61f8ffd80 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 25 Oct 2014 15:24:26 -0700 Subject: Fix header ranking --- src/net/fwd.hpp | 9 +- src/net/ip.cpp | 3 +- src/net/ip.hpp | 2 - src/net/packets.cpp | 106 -------- src/net/packets.hpp | 585 -------------------------------------------- src/net/socket.cpp | 16 +- src/net/socket.hpp | 19 +- src/net/timer.hpp | 3 - src/net/timestamp-utils.cpp | 72 ++++++ src/net/timestamp-utils.hpp | 54 ++++ 10 files changed, 150 insertions(+), 719 deletions(-) delete mode 100644 src/net/packets.cpp delete mode 100644 src/net/packets.hpp create mode 100644 src/net/timestamp-utils.cpp create mode 100644 src/net/timestamp-utils.hpp (limited to 'src/net') diff --git a/src/net/fwd.hpp b/src/net/fwd.hpp index 2097772..5de8450 100644 --- a/src/net/fwd.hpp +++ b/src/net/fwd.hpp @@ -20,6 +20,13 @@ #include "../sanity.hpp" +#include "../ints/fwd.hpp" // rank 1 +#include "../strings/fwd.hpp" // rank 1 +#include "../compat/fwd.hpp" // rank 2 +#include "../generic/fwd.hpp" // rank 3 +#include "../io/fwd.hpp" // rank 4 +// net/fwd.hpp is rank 5 + namespace tmwa { @@ -28,6 +35,4 @@ class Session; class IP4Address; class TimerData; - -enum class RecvResult; } // namespace tmwa diff --git a/src/net/ip.cpp b/src/net/ip.cpp index bfc2028..4ec022b 100644 --- a/src/net/ip.cpp +++ b/src/net/ip.cpp @@ -22,8 +22,7 @@ #include "../strings/vstring.hpp" #include "../io/cxxstdio.hpp" - -#include "../mmo/extract.hpp" +#include "../io/extract.hpp" #include "../poison.hpp" diff --git a/src/net/ip.hpp b/src/net/ip.hpp index e9e71f4..ab45c56 100644 --- a/src/net/ip.hpp +++ b/src/net/ip.hpp @@ -25,8 +25,6 @@ #include #include -#include "../strings/fwd.hpp" - namespace tmwa { diff --git a/src/net/packets.cpp b/src/net/packets.cpp deleted file mode 100644 index 3cba856..0000000 --- a/src/net/packets.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "packets.hpp" -// packets.cpp - palatable socket buffer accessors -// -// Copyright © 2014 Ben Longbons -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "../io/cxxstdio.hpp" -#include "../io/write.hpp" - -#include "../poison.hpp" - - -namespace tmwa -{ -size_t packet_avail(Session *s) -{ - return s->rdata_size - s->rdata_pos; -} - -bool packet_fetch(Session *s, size_t offset, Byte *data, size_t sz) -{ - if (packet_avail(s) < offset + sz) - return false; - const Byte *start = reinterpret_cast(&s->rdata[s->rdata_pos + offset]); - const Byte *end = start + sz; - std::copy(start, end, data); - return true; -} -void packet_discard(Session *s, size_t sz) -{ - s->rdata_pos += sz; - - assert (s->rdata_size >= s->rdata_pos); -} -bool packet_send(Session *s, const Byte *data, size_t sz) -{ - if (s->wdata_size + sz > s->max_wdata) - { - realloc_fifo(s, s->max_rdata, s->max_wdata << 1); - PRINTF("socket: %d wdata expanded to %zu bytes.\n"_fmt, s, s->max_wdata); - } - if (!s->max_wdata || !s->wdata) - { - return false; - } - s->wdata_size += sz; - - Byte *end = reinterpret_cast(&s->wdata[s->wdata_size + 0]); - Byte *start = end - sz; - std::copy(data, data + sz, start); - return true; -} - -void packet_dump(io::WriteFile& logfp, Session *s) -{ - FPRINTF(logfp, - "---- 00-01-02-03-04-05-06-07 08-09-0A-0B-0C-0D-0E-0F\n"_fmt); - char tmpstr[16 + 1] {}; - int i; - for (i = 0; i < packet_avail(s); i++) - { - if ((i & 15) == 0) - FPRINTF(logfp, "%04X "_fmt, i); - Byte rfifob_ib; - packet_fetch(s, i, &rfifob_ib, 1); - uint8_t rfifob_i = rfifob_ib.value; - FPRINTF(logfp, "%02x "_fmt, rfifob_i); - if (rfifob_i > 0x1f) - tmpstr[i % 16] = rfifob_i; - else - tmpstr[i % 16] = '.'; - if ((i - 7) % 16 == 0) // -8 + 1 - FPRINTF(logfp, " "_fmt); - else if ((i + 1) % 16 == 0) - { - FPRINTF(logfp, " %s\n"_fmt, tmpstr); - std::fill(tmpstr + 0, tmpstr + 17, '\0'); - } - } - if (i % 16 != 0) - { - for (int j = i; j % 16 != 0; j++) - { - FPRINTF(logfp, " "_fmt); - if ((j - 7) % 16 == 0) // -8 + 1 - FPRINTF(logfp, " "_fmt); - } - FPRINTF(logfp, " %s\n"_fmt, tmpstr); - } - FPRINTF(logfp, "\n"_fmt); -} -} // namespace tmwa diff --git a/src/net/packets.hpp b/src/net/packets.hpp deleted file mode 100644 index 5cc377c..0000000 --- a/src/net/packets.hpp +++ /dev/null @@ -1,585 +0,0 @@ -#pragma once -// packets.hpp - palatable socket buffer accessors -// -// Copyright © 2014 Ben Longbons -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "fwd.hpp" - -#include - -#include "../compat/cast.hpp" - -#include "../ints/little.hpp" - -#include "../io/fwd.hpp" - -// TODO ordering violation, should invert -#include "../proto2/fwd.hpp" - -#include "socket.hpp" - - -namespace tmwa -{ -struct Buffer -{ - std::vector bytes; -}; - -enum class RecvResult -{ - Incomplete, - Complete, - Error, -}; - -enum class SendResult -{ - Success, - Fail, -}; - - -size_t packet_avail(Session *s); -void packet_dump(io::WriteFile& out, Session *s); - -bool packet_fetch(Session *s, size_t offset, Byte *data, size_t sz); -void packet_discard(Session *s, size_t sz); -bool packet_send(Session *s, const Byte *data, size_t sz); - -inline -bool packet_peek_id(Session *s, uint16_t *packet_id) -{ - Little16 id; - bool okay = packet_fetch(s, 0, reinterpret_cast(&id), 2); - if (okay) - { - if (!network_to_native(packet_id, id)) - { - s->set_eof(); - return false; - } - } - return okay; -} - -inline -void send_buffer(Session *s, const Buffer& buffer) -{ - bool ok = !buffer.bytes.empty() && packet_send(s, buffer.bytes.data(), buffer.bytes.size()); - if (!ok) - s->set_eof(); -} - -template -__attribute__((warn_unused_result)) -RecvResult net_recv_fpacket(Session *s, NetPacket_Fixed& fixed) -{ - bool ok = packet_fetch(s, 0, reinterpret_cast(&fixed), sizeof(NetPacket_Fixed)); - if (ok) - { - packet_discard(s, sizeof(NetPacket_Fixed)); - return RecvResult::Complete; - } - return RecvResult::Incomplete; -} - -template -__attribute__((warn_unused_result)) -RecvResult net_recv_ppacket(Session *s, NetPacket_Payload& payload) -{ - bool ok = packet_fetch(s, 0, reinterpret_cast(&payload), sizeof(NetPacket_Payload)); - if (ok) - { - packet_discard(s, sizeof(NetPacket_Payload)); - return RecvResult::Complete; - } - return RecvResult::Incomplete; -} - -template -__attribute__((warn_unused_result)) -RecvResult net_recv_vpacket(Session *s, NetPacket_Head& head, std::vector>& repeat) -{ - bool ok = packet_fetch(s, 0, reinterpret_cast(&head), sizeof(NetPacket_Head)); - if (ok) - { - Packet_Head 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(NetPacket_Head)) - return RecvResult::Error; - size_t bytes_repeat = nat.magic_packet_length - sizeof(NetPacket_Head); - if (bytes_repeat % sizeof(NetPacket_Repeat)) - return RecvResult::Error; - repeat.resize(bytes_repeat / sizeof(NetPacket_Repeat)); - if (packet_fetch(s, sizeof(NetPacket_Head), reinterpret_cast(repeat.data()), bytes_repeat)) - { - packet_discard(s, nat.magic_packet_length); - return RecvResult::Complete; - } - return RecvResult::Incomplete; - } - return RecvResult::Incomplete; -} - -template -__attribute__((warn_unused_result)) -RecvResult net_recv_opacket(Session *s, NetPacket_Head& head, bool *has_opt, NetPacket_Option& opt) -{ - bool ok = packet_fetch(s, 0, reinterpret_cast(&head), sizeof(NetPacket_Head)); - if (ok) - { - Packet_Head 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(NetPacket_Head)) - return RecvResult::Error; - size_t bytes_repeat = nat.magic_packet_length - sizeof(NetPacket_Head); - if (bytes_repeat % sizeof(NetPacket_Option)) - return RecvResult::Error; - size_t has_opt_pls = bytes_repeat / sizeof(NetPacket_Option); - if (has_opt_pls > 1) - return RecvResult::Error; - *has_opt = has_opt_pls; - if (!*has_opt || packet_fetch(s, sizeof(NetPacket_Head), reinterpret_cast(&opt), sizeof(NetPacket_Option))) - { - packet_discard(s, nat.magic_packet_length); - return RecvResult::Complete; - } - return RecvResult::Incomplete; - } - return RecvResult::Incomplete; -} - - -template -Buffer create_fpacket(const Packet_Fixed& fixed) -{ - static_assert(id == Packet_Fixed::PACKET_ID, "Packet_Fixed::PACKET_ID"); - static_assert(size == sizeof(NetPacket_Fixed), "sizeof(NetPacket_Fixed)"); - - Buffer buf; - buf.bytes.resize(sizeof(NetPacket_Fixed)); - auto& net_fixed = reinterpret_cast&>( - *(buf.bytes.begin() + 0)); - if (!native_to_network(&net_fixed, fixed)) - { - return Buffer(); - } - return buf; -} - -template -Buffer create_ppacket(Packet_Payload& payload) -{ - static_assert(id == Packet_Payload::PACKET_ID, "Packet_Payload::PACKET_ID"); - - if (id != 0x8000) - payload.magic_packet_length = sizeof(NetPacket_Payload); - - Buffer buf; - buf.bytes.resize(sizeof(NetPacket_Payload)); - auto& net_payload = reinterpret_cast&>( - *(buf.bytes.begin() + 0)); - if (!native_to_network(&net_payload, payload)) - { - return Buffer(); - } - return buf; -} - -template -Buffer create_vpacket(Packet_Head& head, const std::vector>& repeat) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "sizeof(NetPacket_Head)"); - static_assert(id == Packet_Repeat::PACKET_ID, "Packet_Repeat::PACKET_ID"); - static_assert(repeatsize == sizeof(NetPacket_Repeat), "sizeof(NetPacket_Repeat)"); - - // since these are already allocated, can't overflow address space - size_t total_size = sizeof(NetPacket_Head) + repeat.size() * sizeof(NetPacket_Repeat); - // truncates - head.magic_packet_length = total_size; - if (head.magic_packet_length != total_size) - { - return Buffer(); - } - - Buffer buf; - buf.bytes.resize(total_size); - auto& net_head = reinterpret_cast&>( - *(buf.bytes.begin() + 0)); - if (!native_to_network(&net_head, head)) - { - return Buffer(); - } - for (size_t i = 0; i < repeat.size(); ++i) - { - auto& net_repeat_i = reinterpret_cast&>( - *(buf.bytes.begin() - + sizeof(NetPacket_Head) - + i * sizeof(NetPacket_Repeat))); - if (!native_to_network(&net_repeat_i, repeat[i])) - { - return Buffer(); - } - } - return buf; -} - -template -Buffer create_opacket(Packet_Head& head, bool has_opt, const Packet_Option& opt) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "sizeof(NetPacket_Head)"); - static_assert(id == Packet_Option::PACKET_ID, "Packet_Option::PACKET_ID"); - static_assert(optsize == sizeof(NetPacket_Option), "sizeof(NetPacket_Option)"); - - // since these are already allocated, can't overflow address space - size_t total_size = sizeof(NetPacket_Head) + has_opt * sizeof(NetPacket_Option); - // truncates - head.magic_packet_length = total_size; - if (head.magic_packet_length != total_size) - { - return Buffer(); - } - - Buffer buf; - buf.bytes.resize(total_size); - - auto& net_head = reinterpret_cast&>( - *(buf.bytes.begin() + 0)); - if (!native_to_network(&net_head, head)) - { - return Buffer(); - } - if (has_opt) - { - auto& net_opt = reinterpret_cast&>( - *(buf.bytes.begin() - + sizeof(NetPacket_Head))); - if (!native_to_network(&net_opt, opt)) - { - return Buffer(); - } - } - - return buf; -} - -template -void send_fpacket(Session *s, const Packet_Fixed& fixed) -{ - Buffer pkt = create_fpacket(fixed); - send_buffer(s, pkt); -} - -template -void send_ppacket(Session *s, Packet_Payload& payload) -{ - Buffer pkt = create_ppacket(payload); - send_buffer(s, pkt); -} - -template -void send_vpacket(Session *s, Packet_Head& head, const std::vector>& repeat) -{ - Buffer pkt = create_vpacket(head, repeat); - send_buffer(s, pkt); -} - -template -void send_opacket(Session *s, Packet_Head& head, bool has_opt, const Packet_Option& opt) -{ - Buffer pkt = create_opacket(head, has_opt, opt); - send_buffer(s, pkt); -} - -template -__attribute__((warn_unused_result)) -RecvResult recv_fpacket(Session *s, Packet_Fixed& fixed) -{ - static_assert(id == Packet_Fixed::PACKET_ID, "Packet_Fixed::PACKET_ID"); - static_assert(size == sizeof(NetPacket_Fixed), "NetPacket_Fixed"); - - NetPacket_Fixed net_fixed; - RecvResult rv = net_recv_fpacket(s, net_fixed); - if (rv == RecvResult::Complete) - { - if (!network_to_native(&fixed, net_fixed)) - return RecvResult::Error; - assert (fixed.magic_packet_id == Packet_Fixed::PACKET_ID); - } - return rv; -} - -template -__attribute__((warn_unused_result)) -RecvResult recv_ppacket(Session *s, Packet_Payload& payload) -{ - static_assert(id == Packet_Payload::PACKET_ID, "Packet_Payload::PACKET_ID"); - - NetPacket_Payload net_payload; - RecvResult rv = net_recv_ppacket(s, net_payload); - if (rv == RecvResult::Complete) - { - if (!network_to_native(&payload, net_payload)) - return RecvResult::Error; - assert (payload.magic_packet_id == Packet_Payload::PACKET_ID); - if (id == 0x8000) - { - // 0x8000 is special - if (packet_avail(s) < payload.magic_packet_length) - return RecvResult::Incomplete; - payload.magic_packet_length = 4; - return RecvResult::Complete; - } - if (payload.magic_packet_length != sizeof(net_payload)) - return RecvResult::Error; - } - return rv; -} - -template -__attribute__((warn_unused_result)) -RecvResult recv_vpacket(Session *s, Packet_Head& head, std::vector>& repeat) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "NetPacket_Head"); - static_assert(id == Packet_Repeat::PACKET_ID, "Packet_Repeat::PACKET_ID"); - static_assert(repeatsize == sizeof(NetPacket_Repeat), "NetPacket_Repeat"); - - NetPacket_Head net_head; - std::vector> net_repeat; - RecvResult rv = net_recv_vpacket(s, net_head, net_repeat); - if (rv == RecvResult::Complete) - { - if (!network_to_native(&head, net_head)) - return RecvResult::Error; - assert (head.magic_packet_id == Packet_Head::PACKET_ID); - - repeat.resize(net_repeat.size()); - for (size_t i = 0; i < net_repeat.size(); ++i) - { - if (!network_to_native(&repeat[i], net_repeat[i])) - return RecvResult::Error; - } - } - return rv; -} - -template -__attribute__((warn_unused_result)) -RecvResult recv_opacket(Session *s, Packet_Head& head, bool *has_opt, Packet_Option& opt) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "NetPacket_Head"); - static_assert(id == Packet_Option::PACKET_ID, "Packet_Option::PACKET_ID"); - static_assert(optsize == sizeof(NetPacket_Option), "NetPacket_Option"); - - NetPacket_Head net_head; - NetPacket_Option net_opt; - RecvResult rv = net_recv_opacket(s, net_head, has_opt, net_opt); - if (rv == RecvResult::Complete) - { - if (!network_to_native(&head, net_head)) - return RecvResult::Error; - assert (head.magic_packet_id == Packet_Head::PACKET_ID); - - if (*has_opt) - { - if (!network_to_native(&opt, net_opt)) - return RecvResult::Error; - } - } - return rv; -} - - -// convenience for trailing strings - -template -Buffer create_vpacket(Packet_Head& head, const XString& repeat) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "NetPacket_Head"); - static_assert(id == Packet_Repeat::PACKET_ID, "Packet_Repeat::PACKET_ID"); - static_assert(repeatsize == sizeof(NetPacket_Repeat), "NetPacket_Repeat"); - static_assert(repeatsize == 1, "repeatsize"); - - // since it's already allocated, it can't overflow address space - size_t total_length = sizeof(NetPacket_Head) + (repeat.size() + 1) * sizeof(NetPacket_Repeat); - head.magic_packet_length = total_length; - if (head.magic_packet_length != total_length) - { - return Buffer(); - } - - Buffer buf; - buf.bytes.resize(total_length); - auto& net_head = reinterpret_cast&>( - *(buf.bytes.begin() + 0)); - std::vector> net_repeat(repeat.size() + 1); - if (!native_to_network(&net_head, head)) - { - return Buffer(); - } - for (size_t i = 0; i < repeat.size(); ++i) - { - auto& net_repeat_i = reinterpret_cast&>( - *(buf.bytes.begin() - + sizeof(NetPacket_Head) - + i)); - net_repeat_i.c = Byte{static_cast(repeat[i])}; - } - auto& net_repeat_repeat_size = reinterpret_cast&>( - *(buf.bytes.begin() - + sizeof(NetPacket_Head) - + repeat.size())); - net_repeat_repeat_size.c = Byte{static_cast('\0')}; - return buf; -} - -template -void send_vpacket(Session *s, Packet_Head& head, const XString& repeat) -{ - Buffer pkt = create_vpacket(head, repeat); - send_buffer(s, pkt); -} - -template -__attribute__((warn_unused_result)) -RecvResult recv_vpacket(Session *s, Packet_Head& head, AString& repeat) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "NetPacket_Head"); - static_assert(id == Packet_Repeat::PACKET_ID, "Packet_Repeat::PACKET_ID"); - static_assert(repeatsize == sizeof(NetPacket_Repeat), "NetPacket_Repeat"); - static_assert(repeatsize == 1, "repeatsize"); - - NetPacket_Head net_head; - std::vector> net_repeat; - RecvResult rv = net_recv_vpacket(s, net_head, net_repeat); - assert (head.magic_packet_id == Packet_Head::PACKET_ID); - if (rv == RecvResult::Complete) - { - if (!network_to_native(&head, net_head)) - return RecvResult::Error; - // reinterpret_cast is needed to correctly handle an empty vector - const char *begin = sign_cast(net_repeat.data()); - const char *end = begin + net_repeat.size(); - end = std::find(begin, end, '\0'); - repeat = XString(begin, end, nullptr); - } - return rv; -} - - -// if there is nothing in the head but the id and length, use the below - -template -Buffer create_packet_repeatonly(const std::vector>& v) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "repeat headsize"); - static_assert(headsize == 4, "repeat headsize"); - static_assert(id == Packet_Repeat::PACKET_ID, "Packet_Repeat::PACKET_ID"); - static_assert(repeatsize == sizeof(NetPacket_Repeat), "sizeof(NetPacket_Repeat)"); - - Packet_Head head; - return create_vpacket(head, v); -} - -template -void send_packet_repeatonly(Session *s, const std::vector>& v) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "repeat headsize"); - static_assert(headsize == 4, "repeat headsize"); - static_assert(id == Packet_Repeat::PACKET_ID, "Packet_Repeat::PACKET_ID"); - static_assert(repeatsize == sizeof(NetPacket_Repeat), "sizeof(NetPacket_Repeat)"); - - Packet_Head head; - send_vpacket(s, head, v); -} - -template -__attribute__((warn_unused_result)) -RecvResult recv_packet_repeatonly(Session *s, std::vector>& v) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "repeat headsize"); - static_assert(headsize == 4, "repeat headsize"); - static_assert(id == Packet_Repeat::PACKET_ID, "Packet_Repeat::PACKET_ID"); - static_assert(repeatsize == sizeof(NetPacket_Repeat), "sizeof(NetPacket_Repeat)"); - - Packet_Head head; - return recv_vpacket(s, head, v); -} - - -// and the combination of both of the above - -template -Buffer create_packet_repeatonly(const XString& repeat) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "repeat headsize"); - static_assert(headsize == 4, "repeat headsize"); - static_assert(id == Packet_Repeat::PACKET_ID, "Packet_Repeat::PACKET_ID"); - static_assert(repeatsize == sizeof(NetPacket_Repeat), "sizeof(NetPacket_Repeat)"); - static_assert(repeatsize == 1, "repeatsize"); - - Packet_Head head; - return create_vpacket(head, repeat); -} - -template -void send_packet_repeatonly(Session *s, const XString& repeat) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "repeat headsize"); - static_assert(headsize == 4, "repeat headsize"); - static_assert(id == Packet_Repeat::PACKET_ID, "Packet_Repeat::PACKET_ID"); - static_assert(repeatsize == sizeof(NetPacket_Repeat), "sizeof(NetPacket_Repeat)"); - static_assert(repeatsize == 1, "repeatsize"); - - Packet_Head head; - send_vpacket(s, head, repeat); -} - -template -__attribute__((warn_unused_result)) -RecvResult recv_packet_repeatonly(Session *s, AString& repeat) -{ - static_assert(id == Packet_Head::PACKET_ID, "Packet_Head::PACKET_ID"); - static_assert(headsize == sizeof(NetPacket_Head), "repeat headsize"); - static_assert(headsize == 4, "repeat headsize"); - static_assert(id == Packet_Repeat::PACKET_ID, "Packet_Repeat::PACKET_ID"); - static_assert(repeatsize == sizeof(NetPacket_Repeat), "sizeof(NetPacket_Repeat)"); - static_assert(repeatsize == 1, "repeatsize"); - - Packet_Head head; - return recv_vpacket(s, head, repeat); -} -} // namespace tmwa diff --git a/src/net/socket.cpp b/src/net/socket.cpp index a01cd81..fce45fb 100644 --- a/src/net/socket.cpp +++ b/src/net/socket.cpp @@ -34,10 +34,6 @@ #include "../io/cxxstdio.hpp" -// TODO get rid of ordering violations -#include "../mmo/utils.hpp" -#include "../mmo/core.hpp" - #include "timer.hpp" #include "../poison.hpp" @@ -399,7 +395,7 @@ void realloc_fifo(Session *s, size_t rfifo_size, size_t wfifo_size) } } -void do_sendrecv(interval_t next_ms) +bool do_sendrecv(interval_t next_ms) { bool any = false; io::FD_Set rfd = readfds, wfd; @@ -419,9 +415,9 @@ void do_sendrecv(interval_t next_ms) { PRINTF("Shutting down - nothing to do\n"_fmt); // TODO hoist this - runflag = false; + return false; } - return; + return true; } struct timeval timeout; { @@ -431,7 +427,7 @@ void do_sendrecv(interval_t next_ms) timeout.tv_usec = next_us.count(); } if (io::FD_Set::select(fd_max, &rfd, &wfd, nullptr, &timeout) <= 0) - return; + return true; for (io::FD i : iter_fds()) { Session *s = get_session(i); @@ -451,9 +447,10 @@ void do_sendrecv(interval_t next_ms) s->func_recv(s); } } + return true; } -void do_parsepacket(void) +bool do_parsepacket(void) { for (io::FD i : iter_fds()) { @@ -483,5 +480,6 @@ void do_parsepacket(void) /// Reclaim buffer space for what was read RFIFOFLUSH(s); } + return true; } } // namespace tmwa diff --git a/src/net/socket.hpp b/src/net/socket.hpp index 576ef85..d6caefd 100644 --- a/src/net/socket.hpp +++ b/src/net/socket.hpp @@ -22,20 +22,19 @@ #include "fwd.hpp" -#include - #include +#include #include -#include "../compat/iter.hpp" -#include "../compat/rawmem.hpp" -#include "../compat/time_t.hpp" - #include "../strings/astring.hpp" #include "../strings/vstring.hpp" #include "../strings/xstring.hpp" +#include "../compat/iter.hpp" +#include "../compat/rawmem.hpp" +#include "../compat/time_t.hpp" + #include "../generic/dumb_ptr.hpp" #include "../io/fd.hpp" @@ -125,8 +124,8 @@ public: io::FD fd; - friend void do_sendrecv(interval_t next); - friend void do_parsepacket(void); + friend bool do_sendrecv(interval_t next); + friend bool do_parsepacket(void); friend void delete_session(Session *); }; @@ -171,7 +170,7 @@ void delete_session(Session *); /// Make a the internal queues bigger void realloc_fifo(Session *s, size_t rfifo_size, size_t wfifo_size); /// Update all sockets that can be read/written from the queues -void do_sendrecv(interval_t next); +bool do_sendrecv(interval_t next); /// Call the parser function for every socket that has read data -void do_parsepacket(void); +bool do_parsepacket(void); } // namespace tmwa diff --git a/src/net/timer.hpp b/src/net/timer.hpp index 338e339..5e7cc90 100644 --- a/src/net/timer.hpp +++ b/src/net/timer.hpp @@ -21,11 +21,8 @@ // along with this program. If not, see . #include "timer.t.hpp" - #include "fwd.hpp" -#include "../strings/fwd.hpp" - namespace tmwa { diff --git a/src/net/timestamp-utils.cpp b/src/net/timestamp-utils.cpp new file mode 100644 index 0000000..b5873ca --- /dev/null +++ b/src/net/timestamp-utils.cpp @@ -0,0 +1,72 @@ +#include "timestamp-utils.hpp" +// timestamp-utils.cpp - Useful stuff that hasn't been categorized. +// +// Copyright © ????-2004 Athena Dev Teams +// Copyright © 2004-2011 The Mana World Development Team +// Copyright © 2011-2014 Ben Longbons +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include + +#include + +#include "../strings/xstring.hpp" + +#include "../compat/time_t.hpp" + +#include "../io/write.hpp" + +#include "../poison.hpp" + + +namespace tmwa +{ +static_assert(sizeof(timestamp_seconds_buffer) == 20, "seconds buffer"); +static_assert(sizeof(timestamp_milliseconds_buffer) == 24, "millis buffer"); + +void stamp_time(timestamp_seconds_buffer& out, const TimeT *t) +{ + struct tm when = t ? *t : TimeT::now(); + char buf[20]; + strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &when); + out = stringish(VString<19>(strings::really_construct_from_a_pointer, buf)); +} +void stamp_time(timestamp_milliseconds_buffer& out) +{ + struct timeval tv; + gettimeofday(&tv, nullptr); + struct tm when = TimeT(tv.tv_sec); + char buf[24]; + strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &when); + sprintf(buf + 19, ".%03d", static_cast(tv.tv_usec / 1000)); + out = stringish(VString<23>(strings::really_construct_from_a_pointer, buf)); +} + +void log_with_timestamp(io::WriteFile& out, XString line) +{ + if (!line) + { + out.put('\n'); + return; + } + timestamp_milliseconds_buffer tmpstr; + stamp_time(tmpstr); + out.really_put(tmpstr.data(), tmpstr.size()); + out.really_put(": ", 2); + out.put_line(line); +} +} // namespace tmwa diff --git a/src/net/timestamp-utils.hpp b/src/net/timestamp-utils.hpp new file mode 100644 index 0000000..f5b5dce --- /dev/null +++ b/src/net/timestamp-utils.hpp @@ -0,0 +1,54 @@ +#pragma once +// timestamp-utils.hpp - Useful stuff that hasn't been categorized. +// +// Copyright © ????-2004 Athena Dev Teams +// Copyright © 2004-2011 The Mana World Development Team +// Copyright © 2011-2014 Ben Longbons +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "fwd.hpp" + +#include "../strings/vstring.hpp" + + +namespace tmwa +{ +struct timestamp_seconds_buffer : VString<19> {}; +struct timestamp_milliseconds_buffer : VString<23> {}; +void stamp_time(timestamp_seconds_buffer&, const TimeT *t=nullptr); +void stamp_time(timestamp_milliseconds_buffer&); + +void log_with_timestamp(io::WriteFile& out, XString line); + +// TODO VString? +#define TIMESTAMP_DUMMY "YYYY-MM-DD HH:MM:SS" +static_assert(sizeof(TIMESTAMP_DUMMY) == sizeof(timestamp_seconds_buffer), + "timestamp size"); +#define WITH_TIMESTAMP(str) str TIMESTAMP_DUMMY +// str: prefix: YYYY-MM-DD HH:MM:SS +// sizeof: 01234567890123456789012345678 +// str + sizeof: ^ +// -1: ^ +// there's probably a better way to do this now +#define REPLACE_TIMESTAMP(str, t) \ + stamp_time( \ + reinterpret_cast( \ + str + sizeof(str) \ + )[-1], \ + &t \ + ) +} // namespace tmwa -- cgit v1.2.3-70-g09d2