Files @ r27569:6a9aa0750697
Branch filter:

Location: cpp/openttd-patchpack/source/src/network/core/address.h - annotation

Rubidium
Codechange: remove need for GetDParamX
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r10828:d8d68d002525
r10828:d8d68d002525
r16851:b5784600e35e
r16851:b5784600e35e
r10828:d8d68d002525
r10828:d8d68d002525
r11590:2bff4ec7f0ca
r25813:ea6d38b6c3a1
r11590:2bff4ec7f0ca
r11591:dcfe7b4a6015
r24274:24301225307d
r11591:dcfe7b4a6015
r23538:8df50944b27a
r27384:b919ab98bb53
r10828:d8d68d002525
r10828:d8d68d002525
r10828:d8d68d002525
r10828:d8d68d002525
r10828:d8d68d002525
r10828:d8d68d002525
r10828:d8d68d002525
r10828:d8d68d002525
r25391:cb427a94fd46
r25391:cb427a94fd46
r25391:cb427a94fd46
r25391:cb427a94fd46
r10828:d8d68d002525
r11553:665b4b3ba421
r11553:665b4b3ba421
r11553:665b4b3ba421
r11553:665b4b3ba421
r11553:665b4b3ba421
r11553:665b4b3ba421
r11553:665b4b3ba421
r11592:12c71fbe8d50
r10828:d8d68d002525
r10828:d8d68d002525
r17622:d9f6f6845b5d
r17622:d9f6f6845b5d
r17622:d9f6f6845b5d
r11545:27d3f758c0c0
r11649:7c14ee641f09
r11551:57af1dbb6426
r17886:18d13f57e663
r17886:18d13f57e663
r10828:d8d68d002525
r10828:d8d68d002525
r10828:d8d68d002525
r10828:d8d68d002525
r17622:d9f6f6845b5d
r17622:d9f6f6845b5d
r17622:d9f6f6845b5d
r11555:622725a26a6d
r11649:7c14ee641f09
r17886:18d13f57e663
r17886:18d13f57e663
r11555:622725a26a6d
r11555:622725a26a6d
r11555:622725a26a6d
r11555:622725a26a6d
r11555:622725a26a6d
r11555:622725a26a6d
r10828:d8d68d002525
r17622:d9f6f6845b5d
r10828:d8d68d002525
r11567:a288e946756b
r10828:d8d68d002525
r25391:cb427a94fd46
r17886:18d13f57e663
r17886:18d13f57e663
r10828:d8d68d002525
r25391:cb427a94fd46
r25391:cb427a94fd46
r25391:cb427a94fd46
r25391:cb427a94fd46
r25391:cb427a94fd46
r11597:39dbd2f0af04
r11545:27d3f758c0c0
r11567:a288e946756b
r11546:a4422f41f18b
r10828:d8d68d002525
r10828:d8d68d002525
r25685:28affbeede23
r24274:24301225307d
r11545:27d3f758c0c0
r11544:5b7269ee2600
r11544:5b7269ee2600
r11551:57af1dbb6426
r11551:57af1dbb6426
r11551:57af1dbb6426
r11649:7c14ee641f09
r11551:57af1dbb6426
r11551:57af1dbb6426
r11551:57af1dbb6426
r11551:57af1dbb6426
r11551:57af1dbb6426
r11551:57af1dbb6426
r11545:27d3f758c0c0
r11546:a4422f41f18b
r11546:a4422f41f18b
r11546:a4422f41f18b
r10828:d8d68d002525
r10828:d8d68d002525
r10828:d8d68d002525
r10828:d8d68d002525
r10828:d8d68d002525
r17886:18d13f57e663
r10828:d8d68d002525
r11546:a4422f41f18b
r11597:39dbd2f0af04
r25684:297b887b048e
r11572:9d570d041dd0
r11572:9d570d041dd0
r11546:a4422f41f18b
r11546:a4422f41f18b
r11574:e29f5f02e7d5
r11546:a4422f41f18b
r11677:627f7f0cc1a2
r11546:a4422f41f18b
r11574:e29f5f02e7d5
r11574:e29f5f02e7d5
r11579:997fbf83d583
r11574:e29f5f02e7d5
r11574:e29f5f02e7d5
r11546:a4422f41f18b
r11547:d8613f4c59f9
r11550:baebd05afdd5
r11564:f44f0aa8c0c3
r11564:f44f0aa8c0c3
r11590:2bff4ec7f0ca
r11564:f44f0aa8c0c3
r11677:627f7f0cc1a2
r11564:f44f0aa8c0c3
r11574:e29f5f02e7d5
r11574:e29f5f02e7d5
r11574:e29f5f02e7d5
r11574:e29f5f02e7d5
r11574:e29f5f02e7d5
r11574:e29f5f02e7d5
r11590:2bff4ec7f0ca
r11590:2bff4ec7f0ca
r11677:627f7f0cc1a2
r11590:2bff4ec7f0ca
r11590:2bff4ec7f0ca
r11590:2bff4ec7f0ca
r11739:0fd5c23f2ad1
r11739:0fd5c23f2ad1
r11739:0fd5c23f2ad1
r11739:0fd5c23f2ad1
r11739:0fd5c23f2ad1
r11739:0fd5c23f2ad1
r11739:0fd5c23f2ad1
r11739:0fd5c23f2ad1
r11739:0fd5c23f2ad1
r11590:2bff4ec7f0ca
r11590:2bff4ec7f0ca
r11590:2bff4ec7f0ca
r11590:2bff4ec7f0ca
r11574:e29f5f02e7d5
r11677:627f7f0cc1a2
r11574:e29f5f02e7d5
r11574:e29f5f02e7d5
r11564:f44f0aa8c0c3
r11564:f44f0aa8c0c3
r11622:2661de6c808c
r11843:07fb5d356fc9
r11843:07fb5d356fc9
r11843:07fb5d356fc9
r25827:5a9ded1a0c1a
r25827:5a9ded1a0c1a
r25397:c741c77120c8
r10828:d8d68d002525
r10828:d8d68d002525
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25814:efd9cb732234
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r25813:ea6d38b6c3a1
r16851:b5784600e35e
/*
 * This file is part of OpenTTD.
 * 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.
 * 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.
 * 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 <http://www.gnu.org/licenses/>.
 */

/** @file core/address.h Wrapper for network addresses. */

#ifndef NETWORK_CORE_ADDRESS_H
#define NETWORK_CORE_ADDRESS_H

#include "os_abstraction.h"
#include "config.h"
#include "../../company_type.h"
#include "../../string_func.h"


class NetworkAddress;
typedef std::vector<NetworkAddress> NetworkAddressList; ///< Type for a list of addresses.
using SocketList = std::map<SOCKET, NetworkAddress>;    ///< Type for a mapping between address and socket.

/**
 * Wrapper for (un)resolved network addresses; there's no reason to transform
 * a numeric IP to a string and then back again to pass it to functions. It
 * furthermore allows easier delaying of the hostname lookup.
 */
class NetworkAddress {
private:
	std::string hostname;     ///< The hostname
	int address_length;       ///< The length of the resolved address
	sockaddr_storage address; ///< The resolved address
	bool resolved;            ///< Whether the address has been (tried to be) resolved

	/**
	 * Helper function to resolve something to a socket.
	 * @param runp information about the socket to try not
	 * @return the opened socket or INVALID_SOCKET
	 */
	typedef SOCKET (*LoopProc)(addrinfo *runp);

	SOCKET Resolve(int family, int socktype, int flags, SocketList *sockets, LoopProc func);
public:
	/**
	 * Create a network address based on a resolved IP and port.
	 * @param address The IP address with port.
	 * @param address_length The length of the address.
	 */
	NetworkAddress(struct sockaddr_storage &address, int address_length) :
		address_length(address_length),
		address(address),
		resolved(address_length != 0)
	{
	}

	/**
	 * Create a network address based on a resolved IP and port.
	 * @param address The IP address with port.
	 * @param address_length The length of the address.
	 */
	NetworkAddress(sockaddr *address, int address_length) :
		address_length(address_length),
		resolved(address_length != 0)
	{
		memset(&this->address, 0, sizeof(this->address));
		memcpy(&this->address, address, address_length);
	}

	/**
	 * Create a network address based on a unresolved host and port
	 * @param hostname the unresolved hostname
	 * @param port the port
	 * @param family the address family
	 */
	NetworkAddress(std::string_view hostname = "", uint16 port = 0, int family = AF_UNSPEC) :
		address_length(0),
		resolved(false)
	{
		if (!hostname.empty() && hostname.front() == '[' && hostname.back() == ']') {
			hostname.remove_prefix(1);
			hostname.remove_suffix(1);
		}
		this->hostname = hostname;

		memset(&this->address, 0, sizeof(this->address));
		this->address.ss_family = family;
		this->SetPort(port);
	}

	const std::string &GetHostname();
	std::string GetAddressAsString(bool with_family = true);
	const sockaddr_storage *GetAddress();

	/**
	 * Get the (valid) length of the address.
	 * @return the length
	 */
	int GetAddressLength()
	{
		/* Resolve it if we didn't do it already */
		if (!this->IsResolved()) this->GetAddress();
		return this->address_length;
	}

	uint16 GetPort() const;
	void SetPort(uint16 port);

	/**
	 * Check whether the IP address has been resolved already
	 * @return true iff the port has been resolved
	 */
	bool IsResolved() const
	{
		return this->resolved;
	}

	bool IsFamily(int family);
	bool IsInNetmask(const std::string &netmask);

	/**
	 * Compare the address of this class with the address of another.
	 * @param address the other address.
	 * @return < 0 if address is less, 0 if equal and > 0 if address is more
	 */
	int CompareTo(NetworkAddress &address)
	{
		int r = this->GetAddressLength() - address.GetAddressLength();
		if (r == 0) r = this->address.ss_family - address.address.ss_family;
		if (r == 0) r = memcmp(&this->address, &address.address, this->address_length);
		if (r == 0) r = this->GetPort() - address.GetPort();
		return r;
	}

	/**
	 * Compare the address of this class with the address of another.
	 * @param address the other address.
	 * @return true if both match.
	 */
	bool operator == (NetworkAddress &address)
	{
		return this->CompareTo(address) == 0;
	}

	/**
	 * Compare the address of this class with the address of another.
	 * @param address the other address.
	 * @return true if both match.
	 */
	bool operator == (NetworkAddress &address) const
	{
		return const_cast<NetworkAddress*>(this)->CompareTo(address) == 0;
	}
	/**
	 * Compare the address of this class with the address of another.
	 * @param address the other address.
	 * @return true if both do not match.
	 */
	bool operator != (NetworkAddress address) const
	{
		return const_cast<NetworkAddress*>(this)->CompareTo(address) != 0;
	}

	/**
	 * Compare the address of this class with the address of another.
	 * @param address the other address.
	 */
	bool operator < (NetworkAddress &address)
	{
		return this->CompareTo(address) < 0;
	}

	void Listen(int socktype, SocketList *sockets);

	static const char *SocketTypeAsString(int socktype);
	static const char *AddressFamilyAsString(int family);
	static NetworkAddress GetPeerAddress(SOCKET sock);
	static NetworkAddress GetSockAddress(SOCKET sock);
	static const std::string GetPeerName(SOCKET sock);
};

/**
 * Types of server addresses we know.
 *
 * Sorting will prefer entries at the top of this list above ones at the bottom.
 */
enum ServerAddressType {
	SERVER_ADDRESS_DIRECT,      ///< Server-address is based on an hostname:port.
	SERVER_ADDRESS_INVITE_CODE, ///< Server-address is based on an invite code.
};

/**
 * Address to a game server.
 *
 * This generalises addresses which are based on different identifiers.
 */
class ServerAddress {
private:
	/**
	 * Create a new ServerAddress object.
	 *
	 * Please use ServerAddress::Parse() instead of calling this directly.
	 *
	 * @param type The type of the ServerAdress.
	 * @param connection_string The connection_string that belongs to this ServerAddress type.
	 */
	ServerAddress(ServerAddressType type, const std::string &connection_string) : type(type), connection_string(connection_string) {}

public:
	ServerAddressType type;        ///< The type of this ServerAddress.
	std::string connection_string; ///< The connection string for this ServerAddress.

	static ServerAddress Parse(const std::string &connection_string, uint16 default_port, CompanyID *company_id = nullptr);
};

#endif /* NETWORK_CORE_ADDRESS_H */