]> git.lizzy.rs Git - minetest.git/blob - src/network/connectionthreads.h
Fix hash implementation for SerializedBlockCache
[minetest.git] / src / network / connectionthreads.h
1 /*
2 Minetest
3 Copyright (C) 2013-2017 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2017 celeron55, Loic Blot <loic.blot@unix-experience.fr>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #pragma once
22
23 #include <cassert>
24 #include "threading/thread.h"
25 #include "connection.h"
26
27 namespace con
28 {
29
30 class Connection;
31
32 struct OutgoingPacket
33 {
34         session_t peer_id;
35         u8 channelnum;
36         SharedBuffer<u8> data;
37         bool reliable;
38         bool ack;
39
40         OutgoingPacket(session_t peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_,
41                         bool reliable_,bool ack_=false):
42                 peer_id(peer_id_),
43                 channelnum(channelnum_),
44                 data(data_),
45                 reliable(reliable_),
46                 ack(ack_)
47         {
48         }
49 };
50
51 class ConnectionSendThread : public Thread
52 {
53
54 public:
55         friend class UDPPeer;
56
57         ConnectionSendThread(unsigned int max_packet_size, float timeout);
58
59         void *run();
60
61         void Trigger();
62
63         void setParent(Connection *parent)
64         {
65                 assert(parent != NULL); // Pre-condition
66                 m_connection = parent;
67         }
68
69         void setPeerTimeout(float peer_timeout) { m_timeout = peer_timeout; }
70
71 private:
72         void runTimeouts(float dtime);
73         void rawSend(const BufferedPacket *p);
74         bool rawSendAsPacket(session_t peer_id, u8 channelnum,
75                         const SharedBuffer<u8> &data, bool reliable);
76
77         void processReliableCommand(ConnectionCommandPtr &c);
78         void processNonReliableCommand(ConnectionCommandPtr &c);
79         void serve(Address bind_address);
80         void connect(Address address);
81         void disconnect();
82         void disconnect_peer(session_t peer_id);
83         void send(session_t peer_id, u8 channelnum, const SharedBuffer<u8> &data);
84         void sendReliable(ConnectionCommandPtr &c);
85         void sendToAll(u8 channelnum, const SharedBuffer<u8> &data);
86         void sendToAllReliable(ConnectionCommandPtr &c);
87
88         void sendPackets(float dtime);
89
90         void sendAsPacket(session_t peer_id, u8 channelnum, const SharedBuffer<u8> &data,
91                         bool ack = false);
92
93         void sendAsPacketReliable(BufferedPacketPtr &p, Channel *channel);
94
95         bool packetsQueued();
96
97         Connection *m_connection = nullptr;
98         unsigned int m_max_packet_size;
99         float m_timeout;
100         std::queue<OutgoingPacket> m_outgoing_queue;
101         Semaphore m_send_sleep_semaphore;
102
103         unsigned int m_iteration_packets_avaialble;
104         unsigned int m_max_commands_per_iteration = 1;
105         unsigned int m_max_data_packets_per_iteration;
106         unsigned int m_max_packets_requeued = 256;
107 };
108
109 class ConnectionReceiveThread : public Thread
110 {
111 public:
112         ConnectionReceiveThread(unsigned int max_packet_size);
113
114         void *run();
115
116         void setParent(Connection *parent)
117         {
118                 assert(parent); // Pre-condition
119                 m_connection = parent;
120         }
121
122 private:
123         void receive(SharedBuffer<u8> &packetdata, bool &packet_queued);
124
125         // Returns next data from a buffer if possible
126         // If found, returns true; if not, false.
127         // If found, sets peer_id and dst
128         bool getFromBuffers(session_t &peer_id, SharedBuffer<u8> &dst);
129
130         bool checkIncomingBuffers(
131                         Channel *channel, session_t &peer_id, SharedBuffer<u8> &dst);
132
133         /*
134                 Processes a packet with the basic header stripped out.
135                 Parameters:
136                         packetdata: Data in packet (with no base headers)
137                         peer_id: peer id of the sender of the packet in question
138                         channelnum: channel on which the packet was sent
139                         reliable: true if recursing into a reliable packet
140         */
141         SharedBuffer<u8> processPacket(Channel *channel,
142                         const SharedBuffer<u8> &packetdata, session_t peer_id,
143                         u8 channelnum, bool reliable);
144
145         SharedBuffer<u8> handlePacketType_Control(Channel *channel,
146                         const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
147                         bool reliable);
148         SharedBuffer<u8> handlePacketType_Original(Channel *channel,
149                         const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
150                         bool reliable);
151         SharedBuffer<u8> handlePacketType_Split(Channel *channel,
152                         const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
153                         bool reliable);
154         SharedBuffer<u8> handlePacketType_Reliable(Channel *channel,
155                         const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
156                         bool reliable);
157
158         struct PacketTypeHandler
159         {
160                 SharedBuffer<u8> (ConnectionReceiveThread::*handler)(Channel *channel,
161                                 const SharedBuffer<u8> &packet, Peer *peer, u8 channelnum,
162                                 bool reliable);
163         };
164
165         static const PacketTypeHandler packetTypeRouter[PACKET_TYPE_MAX];
166
167         Connection *m_connection = nullptr;
168 };
169 }