Files
@ r26123:a265ab51722a
Branch filter:
Location: cpp/openttd-patchpack/source/src/network/core/address.h
r26123:a265ab51722a
6.8 KiB
text/x-c
Codechange: Add support for additional command result values.
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | /*
* 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"
#include "../../core/smallmap_type.hpp"
#include <string>
class NetworkAddress;
typedef std::vector<NetworkAddress> NetworkAddressList; ///< Type for a list of addresses.
typedef SmallMap<NetworkAddress, SOCKET> SocketList; ///< 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 */
|