Files
@ r11589:553d24b1005c
Branch filter:
Location: cpp/openttd-patchpack/source/src/network/core/address.h
r11589:553d24b1005c
5.9 KiB
text/x-c
(svn r15967) -Codechange: do not access NetworkSocketHandler::has_quit directly
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 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | /* $Id$ */
/** @file core/address.h Wrapper for network addresses. */
#ifndef NETWORK_ADDRESS_H
#define NETWORK_ADDRESS_H
#ifdef ENABLE_NETWORK
#include "os_abstraction.h"
/**
* 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:
char *hostname; ///< The hostname, NULL if there isn't one
size_t address_length; ///< The length of the resolved address
sockaddr_storage address; ///< The resolved address
/**
* 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);
/**
* Resolve this address into a socket
* @param family the type of 'protocol' (IPv4, IPv6)
* @param socktype the type of socket (TCP, UDP, etc)
* @param flags the flags to send to getaddrinfo
* @param func the inner working while looping over the address info
* @return the resolved socket or INVALID_SOCKET.
*/
SOCKET Resolve(int family, int socktype, int flags, LoopProc func);
public:
/**
* Create a network address based on a resolved IP and port
* @param ip the resolved ip
* @param port the port
*/
NetworkAddress(in_addr_t ip, uint16 port) :
hostname(NULL),
address_length(sizeof(sockaddr))
{
memset(&this->address, 0, sizeof(this->address));
this->address.ss_family = AF_INET;
((struct sockaddr_in*)&this->address)->sin_addr.s_addr = ip;
this->SetPort(port);
}
/**
* Create a network address based on a resolved IP and port
* @param address the IP address with port
*/
NetworkAddress(struct sockaddr_storage &address, size_t address_length) :
hostname(NULL),
address_length(address_length),
address(address)
{
}
/**
* Create a network address based on a resolved IP and port
* @param address the IP address with port
*/
NetworkAddress(sockaddr *address, size_t address_length) :
hostname(NULL),
address_length(address_length)
{
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 ip the unresolved hostname
* @param port the port
* @param family the address family
*/
NetworkAddress(const char *hostname = "0.0.0.0", uint16 port = 0, int family = AF_INET) :
hostname(strdup(hostname)),
address_length(0)
{
memset(&this->address, 0, sizeof(this->address));
this->address.ss_family = family;
this->SetPort(port);
}
/**
* Make a clone of another address
* @param address the address to clone
*/
NetworkAddress(const NetworkAddress &address) :
hostname(address.hostname == NULL ? NULL : strdup(address.hostname)),
address_length(address.address_length),
address(address.address)
{
}
/** Clean up our mess */
~NetworkAddress()
{
free(hostname);
}
/**
* Get the hostname; in case it wasn't given the
* IPv4 dotted representation is given.
* @return the hostname
*/
const char *GetHostname();
/**
* Get the address as a string, e.g. 127.0.0.1:12345.
* @return the address
*/
const char *GetAddressAsString();
/**
* Get the address in it's internal representation.
* @return the address
*/
const sockaddr_storage *GetAddress();
/**
* Get the (valid) length of the address.
* @return the length
*/
size_t GetAddressLength()
{
/* Resolve it if we didn't do it already */
if (!this->IsResolved()) this->GetAddress();
return this->address_length;
}
/**
* Get the port
* @return the port
*/
uint16 GetPort() const;
/**
* Set the port
* @param port set the port number
*/
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->address_length != 0;
}
/**
* Checks whether this IP address is contained by the given netmask.
* @param netmask the netmask in CIDR notation to test against.
* @note netmask without /n assumes all bits need to match.
* @return true if this IP is within the netmask.
*/
bool IsInNetmask(char *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.
*/
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.
*/
bool operator < (NetworkAddress address)
{
return this->CompareTo(address) < 0;
}
/**
* Assign another address to ourself
* @param other obviously the address to assign to us
* @return 'this'
*/
NetworkAddress& operator = (const NetworkAddress &other)
{
if (this != &other) { // protect against invalid self-assignment
free(this->hostname);
memcpy(this, &other, sizeof(*this));
if (other.hostname != NULL) this->hostname = strdup(other.hostname);
}
return *this;
}
/**
* Connect to the given address.
* @return the connected socket or INVALID_SOCKET.
*/
SOCKET Connect();
/**
* Make the given socket listen.
* @param family the type of 'protocol' (IPv4, IPv6)
* @param socktype the type of socket (TCP, UDP, etc)
* @return the listening socket or INVALID_SOCKET.
*/
SOCKET Listen(int family, int socktype);
};
#endif /* ENABLE_NETWORK */
#endif /* NETWORK_ADDRESS_H */
|