OpenTTD Source 20260311-master-g511d3794ce
tcp.h
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD 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, version 2.
4 * OpenTTD 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.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#ifndef NETWORK_CORE_TCP_H
11#define NETWORK_CORE_TCP_H
12
13#include "address.h"
14#include "packet.h"
15
16#include <atomic>
17#include <chrono>
18#include <thread>
19
27
30private:
31 std::deque<std::unique_ptr<Packet>> packet_queue{};
32 std::unique_ptr<Packet> packet_recv = nullptr;
33
34public:
35 SOCKET sock = INVALID_SOCKET;
36 bool writable = false;
37
42 bool IsConnected() const { return this->sock != INVALID_SOCKET; }
43
44 virtual NetworkRecvStatus CloseConnection(bool error = true);
45 void CloseSocket();
46
47 virtual void SendPacket(std::unique_ptr<Packet> &&packet);
48 SendPacketsState SendPackets(bool closing_down = false);
49
50 virtual std::unique_ptr<Packet> ReceivePacket();
51
52 bool CanSendReceive();
53
58 bool HasSendQueue() { return !this->packet_queue.empty(); }
59
64 NetworkTCPSocketHandler(SOCKET s = INVALID_SOCKET) : sock(s) {}
65 ~NetworkTCPSocketHandler() override;
66};
67
71class TCPConnecter {
72private:
87
88 std::thread resolve_thread;
89 std::atomic<Status> status = Status::Init;
90 std::atomic<bool> killed = false;
91
92 addrinfo *ai = nullptr;
93 std::vector<addrinfo *> addresses;
94 std::map<SOCKET, NetworkAddress> sock_to_address;
95 size_t current_address = 0;
96
97 std::vector<SOCKET> sockets;
98 std::chrono::steady_clock::time_point last_attempt;
99
100 std::string connection_string;
102 int family = AF_UNSPEC;
103
104 static std::vector<std::shared_ptr<TCPConnecter>> connecters;
105
106 void Resolve();
107 void OnResolved(addrinfo *ai);
108 bool TryNextAddress();
109 void Connect(addrinfo *address);
110 virtual bool CheckActivity();
111
112 /* We do not want any other derived classes from this class being able to
113 * access these private members, but it is okay for TCPServerConnecter. */
114 friend class TCPServerConnecter;
115
116 static void ResolveThunk(TCPConnecter *connecter);
117
118public:
119 TCPConnecter() {};
120 TCPConnecter(std::string_view connection_string, uint16_t default_port, const NetworkAddress &bind_address = {}, int family = AF_UNSPEC);
121 virtual ~TCPConnecter();
122
127 virtual void OnConnect([[maybe_unused]] SOCKET s) {}
128
132 virtual void OnFailure() {}
133
134 void Kill();
135
136 static void CheckCallbacks();
137 static void KillAll();
138
145 template <class T, typename... Args>
146 static std::shared_ptr<TCPConnecter> Create(Args&& ... args)
147 {
148 return TCPConnecter::connecters.emplace_back(std::make_shared<T>(std::forward<Args>(args)...));
149 }
150};
151
153class TCPServerConnecter : public TCPConnecter {
154private:
155 SOCKET socket = INVALID_SOCKET;
156
157 bool CheckActivity() override;
158
159public:
161
162 TCPServerConnecter(std::string_view connection_string, uint16_t default_port);
163
164 void SetConnected(SOCKET sock);
165 void SetFailure();
166};
167
168#endif /* NETWORK_CORE_TCP_H */
Wrapper for network addresses.
Wrapper for (un)resolved network addresses; there's no reason to transform a numeric IP to a string a...
Definition address.h:28
NetworkSocketHandler()=default
Create a new unbound socket.
std::deque< std::unique_ptr< Packet > > packet_queue
Packets that are awaiting delivery. Cannot be std::queue as that does not have a clear() function.
Definition tcp.h:31
virtual NetworkRecvStatus CloseConnection(bool error=true)
This will put this socket handler in a close state.
Definition tcp.cpp:40
virtual std::unique_ptr< Packet > ReceivePacket()
Receives a packet for the given client.
Definition tcp.cpp:118
~NetworkTCPSocketHandler() override
Close the socket.
Definition tcp.cpp:18
bool IsConnected() const
Whether this socket is currently bound to a socket.
Definition tcp.h:42
NetworkTCPSocketHandler(SOCKET s=INVALID_SOCKET)
Construct a socket handler for a TCP connection.
Definition tcp.h:64
SOCKET sock
The socket currently connected to.
Definition tcp.h:35
bool writable
Can we write to this socket?
Definition tcp.h:36
virtual void SendPacket(std::unique_ptr< Packet > &&packet)
This function puts the packet in the send-queue and it is send as soon as possible.
Definition tcp.cpp:57
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
Definition tcp.cpp:75
void CloseSocket()
Close the actual socket of the connection.
Definition tcp.cpp:28
bool CanSendReceive()
Check whether this socket can send or receive something.
Definition tcp.cpp:193
std::unique_ptr< Packet > packet_recv
Partially received packet.
Definition tcp.h:32
bool HasSendQueue()
Whether there is something pending in the send queue.
Definition tcp.h:58
Address to a game server.
Definition address.h:185
"Helper" class for creating TCP connections in a non-blocking manner
Definition tcp.h:71
NetworkAddress bind_address
Address we're binding to, if any.
Definition tcp.h:101
void Kill()
Kill this connecter.
std::chrono::steady_clock::time_point last_attempt
Time we last tried to connect.
Definition tcp.h:98
std::atomic< Status > status
The current status of the connecter.
Definition tcp.h:89
std::string connection_string
Current address we are connecting to (before resolving).
Definition tcp.h:100
static std::vector< std::shared_ptr< TCPConnecter > > connecters
List of connections that are currently being created.
Definition tcp.h:104
std::vector< SOCKET > sockets
Pending connect() attempts.
Definition tcp.h:97
static void CheckCallbacks()
Check whether we need to call the callback, i.e.
virtual ~TCPConnecter()
Wait until the resolving is done, then release the sockets.
static std::shared_ptr< TCPConnecter > Create(Args &&... args)
Create the connecter, and initiate connecting by putting it in the collection of TCP connections to m...
Definition tcp.h:146
size_t current_address
Current index in addresses we are trying.
Definition tcp.h:95
void Resolve()
Start resolving the hostname.
virtual void OnFailure()
Callback for when the connection attempt failed.
Definition tcp.h:132
void OnResolved(addrinfo *ai)
Callback when resolving is done.
virtual bool CheckActivity()
Check if there was activity for this connecter.
std::map< SOCKET, NetworkAddress > sock_to_address
Mapping of a socket to the real address it is connecting to. USed for DEBUG statements.
Definition tcp.h:94
static void ResolveThunk(TCPConnecter *connecter)
Thunk to start Resolve() on the right instance.
std::vector< addrinfo * > addresses
Addresses we can connect to.
Definition tcp.h:93
std::thread resolve_thread
Thread used during resolving.
Definition tcp.h:88
static void KillAll()
Kill all connection attempts.
bool TryNextAddress()
Start the connect() for the next address in the list.
std::atomic< bool > killed
Whether this connecter is marked as killed.
Definition tcp.h:90
Status
The current status of the connecter.
Definition tcp.h:80
@ Connected
The connection is established.
Definition tcp.h:85
@ Resolving
The hostname is being resolved (threaded).
Definition tcp.h:82
@ Init
TCPConnecter is created but resolving hasn't started.
Definition tcp.h:81
@ Failure
Resolving failed.
Definition tcp.h:83
@ Connecting
We are currently connecting.
Definition tcp.h:84
virtual void OnConnect(SOCKET s)
Callback when the connection succeeded.
Definition tcp.h:127
void Connect(addrinfo *address)
Start a connection to the indicated address.
addrinfo * ai
getaddrinfo() allocated linked-list of resolved addresses.
Definition tcp.h:92
int family
Family we are using to connect with.
Definition tcp.h:102
void SetConnected(SOCKET sock)
The connection was successfully established.
bool CheckActivity() override
Check if there was activity for this connecter.
ServerAddress server_address
Address we are connecting to.
Definition tcp.h:160
void SetFailure()
The connection couldn't be established.
TCPServerConnecter(std::string_view connection_string, uint16_t default_port)
Create a new connecter for the server.
SOCKET socket
The socket when a connection is established.
Definition tcp.h:155
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
Definition core.h:21
#define T
Climate temperate.
Definition engines.h:91
@ Init
Second step of NewGRF loading; load all actions into memory.
Definition newgrf.h:51
Basic functions to create, fill and read packets.
SendPacketsState
The states of sending the packets.
Definition tcp.h:21
@ SPS_PARTLY_SENT
The packets are partly sent; there are more packets to be sent in the queue.
Definition tcp.h:24
@ SPS_ALL_SENT
All packets in the queue are sent.
Definition tcp.h:25
@ SPS_NONE_SENT
The buffer is still full, so no (parts of) packets could be sent.
Definition tcp.h:23
@ SPS_CLOSED
The connection got closed.
Definition tcp.h:22