aboutsummaryrefslogtreecommitdiff
path: root/src/shared/net/connection.hh
blob: 70ed6e42b611bb0e9556d485490581e482c257e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#ifndef SHARED_NET_CONNECTION_HH_
#define SHARED_NET_CONNECTION_HH_

#include <algorithm>
#include <ctype.h>
#include <optional>
#include <string>
#include <type_traits>
#include <list>

#include "shared/net/net.hh"
#include "shared/net/packet.hh"
#include "shared/net/proto.hh"

namespace shared {
namespace net {

using socket_t = int;

class connection {
public:
    using upacket_t = std::shared_ptr<upacket>;
    using rpacket_t = std::shared_ptr<rpacket>;

private:
    static constexpr std::size_t MAX_PACKET_SIZE = 65536;

    struct sockets {
        socket_t rsock;
        socket_t usock; // connected in constructor
        std::string address;
        std::string port;
    };
    std::optional<sockets> socks;
    std::optional<std::string> bad_reason;
    std::list<upacket_t> upackets;
    std::list<rpacket_t> rpackets;

private:
    bool maybe_send(const packet& packet, const socket_t& sock) noexcept;

public:
    connection(const socket_t& rsock); // requires connected rsocket
    connection(const connection&) = delete;
    connection(connection&& other) noexcept;
    connection& operator=(connection&& other) noexcept;
    ~connection() noexcept;

public:
    bool good() const noexcept {
        return !bad_reason.has_value() && this->socks.has_value();
    }
    std::string get_bad_reason() const noexcept { return *this->bad_reason; }
    std::string get_address() const noexcept { return this->socks->address; }

public:
    // When an identical packet is sent to multiple people, the functions using
    // rpacket_t should be used to avoid unnecessary compression.
    void rsend_packet(const rpacket_t& packet) noexcept;
    void usend_packet(const upacket_t& packet) noexcept;
    void rsend_packet(rpacket&& packet) noexcept;
    void usend_packet(upacket&& packet) noexcept;

public:
    std::optional<proto::packet> rrecv_packet() noexcept;
    std::optional<proto::packet> urecv_packet() noexcept;
    std::optional<proto::packet> recv_packet() noexcept; // from either

public:
    void poll();  // call to send potentially queued packets
    void close(); // call to close sockets
};

} // namespace net
} // namespace shared

#endif