Go to the documentation of this file.
15 #include "../stdafx.h"
16 #include "../date_func.h"
17 #include "../map_func.h"
24 #include "../core/endian_func.hpp"
25 #include "../company_base.h"
26 #include "../thread.h"
28 #include "../newgrf_text.h"
29 #include "../strings_func.h"
30 #include "table/strings.h"
35 #include "../safeguards.h"
67 std::unique_lock<std::mutex>
lock(
mutex, std::defer_lock);
68 if (!
lock.try_lock()) {
70 DEBUG(net, 0,
"[udp] %s background UDP loop processing appears to be blocked. Your OS may be low on UDP send buffers.",
name.c_str());
101 if (needs_mutex)
lock.lock();
202 static const uint MIN_CI_SIZE = 54;
217 GetString(company_name, STR_COMPANY_NAME, company_name + max_cname_length - 1);
219 free -= (int)strlen(company_name);
221 if (
free >= 0)
break;
224 assert(max_cname_length > 0);
257 uint8 in_reply_count = 0;
258 size_t packet_len = 0;
265 for (i = 0; i < num_grfs; i++) {
273 if (f ==
nullptr)
continue;
283 in_reply[in_reply_count] = f;
287 if (in_reply_count == 0)
return;
291 for (i = 0; i < in_reply_count; i++) {
341 uint in_request_count = 0;
346 in_request[in_request_count] = c;
350 if (in_request_count > 0) {
356 for (i = 0; i < in_request_count; i++) {
368 if (client_addr->
GetAddress()->ss_family == AF_INET6) {
393 sockaddr_storage addr_storage;
394 memset(&addr_storage, 0,
sizeof(addr_storage));
397 addr_storage.ss_family = AF_INET;
398 ((sockaddr_in*)&addr_storage)->sin_addr.s_addr = TO_LE32(p->
Recv_uint32());
401 addr_storage.ss_family = AF_INET6;
402 byte *addr = (
byte*)&((sockaddr_in6*)&addr_storage)->sin6_addr;
403 for (uint i = 0; i <
sizeof(in6_addr); i++) *addr++ = p->
Recv_uint8();
427 for (i = 0; i < num_grfs; i++) {
454 DEBUG(net, 4,
"[udp] broadcasting to %s", addr.GetHostname());
483 DEBUG(net, 0,
"[udp] searching server");
494 DEBUG(net, 1,
"[udp] removing advertise from master server");
531 DEBUG(net, 1,
"[udp] advertising to master server");
534 static byte session_key_retries = 0;
536 DEBUG(net, 0,
"[udp] advertising to the master server is failing");
537 DEBUG(net, 0,
"[udp] we are not receiving the session key from the server");
538 DEBUG(net, 0,
"[udp] please allow udp packets from %s to you to be delivered", out_addr.
GetAddressAsString(
false).c_str());
539 DEBUG(net, 0,
"[udp] please allow udp packets from you to %s to be delivered", out_addr.
GetAddressAsString(
false).c_str());
542 DEBUG(net, 0,
"[udp] advertising to the master server is failing");
543 DEBUG(net, 0,
"[udp] we are not receiving the acknowledgement from the server");
544 DEBUG(net, 0,
"[udp] this usually means that the master server cannot reach us");
567 static std::chrono::steady_clock::time_point _last_advertisement = {};
589 _last_advertisement = std::chrono::steady_clock::now();
602 DEBUG(net, 1,
"[udp] initializing listeners");
638 DEBUG(net, 1,
"[udp] closed listeners");
The game information that is sent from the server to the clients.
Simple calculated statistics of a company.
@ PACKET_UDP_CLIENT_GET_LIST
Request for serverlist from master server.
Base socket handler for all UDP sockets.
void Recv_string(char *buffer, size_t size, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads a string till it finds a '\0' in the stream.
const sockaddr_storage * GetAddress()
Get the address in its internal representation.
void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf)
Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet.
const std::string name
The name of the socket.
const GRFConfig * FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum, uint32 desired_version)
Find a NewGRF in the scanned list.
@ PACKET_UDP_CLIENT_GET_NEWGRFS
Requests the name for a list of GRFs (GRF_ID and MD5)
void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
Deserializes the NetworkGameInfo struct from the packet.
void ClearGRFConfigList(GRFConfig **config)
Clear a GRF Config list, freeing all nodes.
static uint8 _network_advertise_retries
The number of advertisement retries we did.
void NetworkUDPServerListen()
Start the listening of the UDP server component.
void GetBindAddresses(NetworkAddressList *addresses, uint16 port)
Get the addresses to bind to.
ServerListType
The types of server lists we can get.
uint16 server_port
port the server listens on
std::mutex lock
synchronization for playback status fields
bool _network_server
network-server is active
NetworkGameList * NetworkGameListAddItem(NetworkAddress address)
Add a new item to the linked gamelist.
void SetPort(uint16 port)
Set the port.
@ PACKET_UDP_CLIENT_FIND_SERVER
Queries a game server for game information.
void NetworkPopulateCompanyStats(NetworkCompanyStats *stats)
Populate the company stats.
void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf)
Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet.
static void NetworkUDPAdvertiseThread()
Thread entry point for advertising.
@ PACKET_UDP_SERVER_UNREGISTER
Request to be removed from the server-list.
static UDPSocket _udp_client("Client")
udp client socket
@ PACKET_UDP_SERVER_REGISTER
Packet to register itself to the master server.
static UDPSocket _udp_server("Server")
udp server socket
static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket)
Broadcast to all ips.
void Close() override
Close the given UDP socket.
void Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr) override
The master server sends us a session key.
char hostname[NETWORK_HOSTNAME_LENGTH]
Hostname of the server (if any)
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
ClientSettings _settings_client
The current settings for this game.
void NetworkUDPAdvertise()
Register us to the master server This function checks if it needs to send an advertise.
void UpdateNetworkGameWindow()
Update the network new window because a new server is found on the network.
void NetworkUDPSearchGame()
Find all servers.
GRFStatus status
NOSAVE: GRFStatus, enum.
Some information about a socket, which exists before the actual socket has been created to provide lo...
static const std::chrono::seconds ADVERTISE_RETRY_INTERVAL(10)
re-advertise when no response after this amount of time.
@ SLT_IPv6
Get the IPv6 addresses.
NetworkAddress address
The connection info of the game server.
void Send_uint8(uint8 data)
Package a 8 bits integer in the packet.
uint8 md5sum[16]
MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF)
bool version_compatible
Can we connect to this server or not? (based on server_revision)
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
uint32 grfid
GRF ID (defined by Action 0x08)
static const uint32 ADVERTISE_RETRY_TIMES
give up re-advertising after this much failed retries
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
Query a specific server.
static const uint NETWORK_MAX_GRF_COUNT
Maximum number of GRFs that can be sent.
Basic data to distinguish a GRF.
void FillNetworkGameInfo(NetworkGameInfo &ngi)
Fill a NetworkGameInfo structure with the latest information of the server.
std::atomic< int > receive_iterations_locked
The number of receive iterations the mutex was locked.
void Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr) override
The return of the client's request of the names of some NewGRFs.
uint32 Recv_uint32()
Read a 32 bits integer from the packet.
void NetworkUDPQueryMasterServer()
Request the the server-list from the master server.
bool IsNetworkCompatibleVersion(const char *other)
Checks whether the given version string is compatible with our version.
Information about GRF, used in the game and (part of it) in savegames.
std::vector< NetworkAddress > NetworkAddressList
Type for a list of addresses.
void Receive_MASTER_ACK_REGISTER(Packet *p, NetworkAddress *client_addr) override
The master server acknowledges the registration.
#define DEBUG(name, level,...)
Output a line of debugging information.
void Send_string(const char *data)
Sends a string over the network.
const char * GetHostname()
Get the hostname; in case it wasn't given the IPv4 dotted representation is given.
std::mutex mutex
Mutex for everything that (indirectly) touches the sockets within the handler.
NetworkUDPSocketHandler * socket
The actual socket, which may be nullptr when not initialized yet.
PacketSize size
The size of the whole packet for received packets.
const char * GetGRFStringFromGRFText(const GRFTextList &text_list)
Get a C-string from a GRFText-list.
#define UNKNOWN_GRF_NAME_PLACEHOLDER
For communication about GRFs over the network.
static const uint16 SEND_MTU
Number of bytes we can pack in a single packet.
bool manually
True if the server was added manually.
bool StartNewThread(std::thread *thr, const char *name, TFn &&_Fx, TArgs &&... _Ax)
Start a new thread.
@ MAX_COMPANIES
Maximum number of companies.
void Send_uint16(uint16 data)
Package a 16 bits integer in the packet.
void NetworkUDPRemoveAdvertise(bool blocking)
Remove our advertise from the master-server.
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
@ PACKET_UDP_SERVER_DETAIL_INFO
Reply of the game server about details of the game, such as companies.
bool _networking
are we in networking mode?
static uint16 _network_udp_broadcast
Timeout for the UDP broadcasts.
@ SLT_END
End of 'arrays' marker.
@ SLT_IPv4
Get the IPv4 addresses.
Internal entity of a packet.
static const byte NETWORK_COMPANY_INFO_VERSION
What version of company info is this?
char server_name[NETWORK_NAME_LENGTH]
Server name.
*** Communication with servers (we are client) ***/
@ PACKET_UDP_SERVER_NEWGRFS
Sends the list of NewGRF's requested.
@ PACKET_UDP_SERVER_RESPONSE
Reply of the game server with game information.
void Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr) override
Queries to the server for information about the game.
bool server_advertise
advertise the server to the masterserver
void NetworkBackgroundUDPLoop()
Receive the UDP packets.
static const uint16 NETWORK_MASTER_SERVER_PORT
The default port of the master server (UDP)
*** Communication with clients (we are server) ***/
static const byte NETWORK_MASTER_SERVER_VERSION
What version of master-server-protocol do we use?
bool HasClientQuit() const
Whether the current client connected to the socket has quit.
Wrapper for (un)resolved network addresses; there's no reason to transform a numeric IP to a string a...
static bool _network_udp_server
Is the UDP server started?
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static void DoNetworkUDPQueryServer(NetworkAddress &address, bool needs_mutex, bool manually)
Helper function doing the actual work for querying the server.
void Receive_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr) override
Return of server information to the client.
static size_t GetNumItems()
Returns number of valid items in the pool.
void Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr) override
A client has requested the names of some NewGRFs.
void Send_uint64(uint64 data)
Package a 64 bits integer in the packet.
*** Communication with the masterserver ***/
static const char *const NETWORK_MASTER_SERVER_HOST
DNS hostname of the masterserver.
bool IsResolved() const
Check whether the IP address has been resolved already.
static const uint NETWORK_GRF_NAME_LENGTH
Maximum length of the name of a GRF.
struct GRFConfig * next
NOSAVE: Next item in the linked list.
void NetworkUDPInitialize()
Initialize the whole UDP bit.
void Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr) override
Query for detailed information about companies.
bool Listen()
Start listening on the given host and port.
@ SLT_AUTODETECT
Autodetect the type based on the connection.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
void Receive_MASTER_RESPONSE_LIST(Packet *p, NetworkAddress *client_addr) override
The server sends a list of servers.
bool _network_need_advertise
Whether we need to advertise.
uint8 Recv_uint8()
Read a 8 bits integer from the packet.
void SerializeNetworkGameInfo(Packet *p, const NetworkGameInfo *info)
Serializes the NetworkGameInfo struct to the packet.
Structure with information shown in the game list (GUI)
char server_revision[NETWORK_REVISION_LENGTH]
The version number the server is using (e.g.: 'r304' or 0.5.0)
void NetworkUDPClose()
Close all UDP related stuff.
NetworkSettings network
settings related to the network
uint64 Recv_uint64()
Read a 64 bits integer from the packet.
void SendCompanyInformation(Packet *p, const struct Company *c, const struct NetworkCompanyStats *stats, uint max_len=NETWORK_COMPANY_NAME_LENGTH)
Package some generic company information into a packet.
void ReceivePackets()
Receive a packet at UDP level.
MasterNetworkUDPSocketHandler(NetworkAddressList *addresses)
Create the socket.
static void NetworkUDPRemoveAdvertiseThread()
Thread entry point for de-advertising.
@ FGCM_EXACT
Only find Grfs matching md5sum.
static const std::chrono::minutes ADVERTISE_NORMAL_INTERVAL(15)
interval between advertising.
ServerNetworkUDPSocketHandler(NetworkAddressList *addresses)
Create the socket.
std::shared_ptr< GRFTextList > GRFTextWrapper
Reference counted wrapper around a GRFText pointer.
NetworkGameInfo info
The game information of this server.
static UDPSocket _udp_master("Master")
udp master socket
GRFTextWrapper FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create)
Finds the name of a NewGRF in the list of names for unknown GRFs.
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
char * strecat(char *dst, const char *src, const char *last)
Appends characters from one string to another.
GRFConfig * grfconfig
List of NewGRF files used.
static const char * AddressFamilyAsString(int family)
Convert the address family into a string.
static const char *const NETWORK_MASTER_SERVER_WELCOME_MESSAGE
Message sent to the masterserver to 'identify' this client as OpenTTD.
bool online
False if the server did not respond (default status)
#define lastof(x)
Get the last element of an fixed size array.
NetworkAddressList _broadcast_list
List of broadcast addresses.
void GetAddressAsString(char *buffer, const char *last, bool with_family=true)
Get the address as a string, e.g.
bool compatible
Can we connect to this server or not? (based on server_revision and grf_match.
static void AddGRFTextToList(GRFTextList &list, byte langid, const std::string &text_to_add)
Add a new text to a GRFText list.
void SendPacket(Packet *p, NetworkAddress *recv, bool all=false, bool broadcast=false)
Send a packet over UDP.
void NetworkGameListAddItemDelayed(NetworkGameList *item)
Add a new item to the linked gamelist, but do it delayed in the next tick or so to prevent race condi...
uint16 Recv_uint16()
Read a 16 bits integer from the packet.
const char * GetName() const
Get the name of this grf.
static uint64 _session_key
Session key to register ourselves to the master server.
static const uint NETWORK_COMPANY_NAME_LENGTH
The maximum length of the company name, in bytes including '\0'.