4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
10 /** @file core/address.h Wrapper for network addresses. */
12 #ifndef NETWORK_CORE_ADDRESS_H
13 #define NETWORK_CORE_ADDRESS_H
15 #include "os_abstraction.h"
17 #include "../../string_func.h"
18 #include "../../core/smallmap_type.hpp"
23 typedef SmallVector
<NetworkAddress
, 4> NetworkAddressList
; ///< Type for a list of addresses.
24 typedef SmallMap
<NetworkAddress
, SOCKET
, 4> SocketList
; ///< Type for a mapping between address and socket.
27 * Wrapper for (un)resolved network addresses; there's no reason to transform
28 * a numeric IP to a string and then back again to pass it to functions. It
29 * furthermore allows easier delaying of the hostname lookup.
31 class NetworkAddress
{
33 char hostname
[NETWORK_HOSTNAME_LENGTH
]; ///< The hostname
34 int address_length
; ///< The length of the resolved address
35 sockaddr_storage address
; ///< The resolved address
36 bool resolved
; ///< Whether the address has been (tried to be) resolved
39 * Helper function to resolve something to a socket.
40 * @param runp information about the socket to try not
41 * @return the opened socket or INVALID_SOCKET
43 typedef SOCKET (*LoopProc
)(addrinfo
*runp
);
45 SOCKET
Resolve(int family
, int socktype
, int flags
, SocketList
*sockets
, LoopProc func
);
48 * Create a network address based on a resolved IP and port.
49 * @param address The IP address with port.
50 * @param address_length The length of the address.
52 NetworkAddress(struct sockaddr_storage
&address
, int address_length
) :
53 address_length(address_length
),
55 resolved(address_length
!= 0)
57 *this->hostname
= '\0';
61 * Create a network address based on a resolved IP and port.
62 * @param address The IP address with port.
63 * @param address_length The length of the address.
65 NetworkAddress(sockaddr
*address
, int address_length
) :
66 address_length(address_length
),
67 resolved(address_length
!= 0)
69 *this->hostname
= '\0';
70 memset(&this->address
, 0, sizeof(this->address
));
71 memcpy(&this->address
, address
, address_length
);
75 * Create a network address based on a unresolved host and port
76 * @param hostname the unresolved hostname
77 * @param port the port
78 * @param family the address family
80 NetworkAddress(const char *hostname
= "", uint16 port
= 0, int family
= AF_UNSPEC
) :
84 /* Also handle IPv6 bracket enclosed hostnames */
85 if (StrEmpty(hostname
)) hostname
= "";
86 if (*hostname
== '[') hostname
++;
87 strecpy(this->hostname
, StrEmpty(hostname
) ? "" : hostname
, lastof(this->hostname
));
88 char *tmp
= strrchr(this->hostname
, ']');
89 if (tmp
!= NULL
) *tmp
= '\0';
91 memset(&this->address
, 0, sizeof(this->address
));
92 this->address
.ss_family
= family
;
97 * Make a clone of another address
98 * @param address the address to clone
100 NetworkAddress(const NetworkAddress
&address
)
102 memcpy(this, &address
, sizeof(*this));
105 const char *GetHostname();
106 void GetAddressAsString(char *buffer
, const char *last
, bool with_family
= true);
107 const char *GetAddressAsString(bool with_family
= true);
108 const sockaddr_storage
*GetAddress();
111 * Get the (valid) length of the address.
114 int GetAddressLength()
116 /* Resolve it if we didn't do it already */
117 if (!this->IsResolved()) this->GetAddress();
118 return this->address_length
;
121 uint16
GetPort() const;
122 void SetPort(uint16 port
);
125 * Check whether the IP address has been resolved already
126 * @return true iff the port has been resolved
128 bool IsResolved() const
130 return this->resolved
;
133 bool IsFamily(int family
);
134 bool IsInNetmask(char *netmask
);
137 * Compare the address of this class with the address of another.
138 * @param address the other address.
139 * @return < 0 if address is less, 0 if equal and > 0 if address is more
141 int CompareTo(NetworkAddress
&address
)
143 int r
= this->GetAddressLength() - address
.GetAddressLength();
144 if (r
== 0) r
= this->address
.ss_family
- address
.address
.ss_family
;
145 if (r
== 0) r
= memcmp(&this->address
, &address
.address
, this->address_length
);
146 if (r
== 0) r
= this->GetPort() - address
.GetPort();
151 * Compare the address of this class with the address of another.
152 * @param address the other address.
153 * @return true if both match.
155 bool operator == (NetworkAddress
&address
)
157 return this->CompareTo(address
) == 0;
161 * Compare the address of this class with the address of another.
162 * @param address the other address.
163 * @return true if both match.
165 bool operator == (NetworkAddress
&address
) const
167 return const_cast<NetworkAddress
*>(this)->CompareTo(address
) == 0;
170 * Compare the address of this class with the address of another.
171 * @param address the other address.
172 * @return true if both do not match.
174 bool operator != (NetworkAddress address
) const
176 return const_cast<NetworkAddress
*>(this)->CompareTo(address
) != 0;
180 * Compare the address of this class with the address of another.
181 * @param address the other address.
183 bool operator < (NetworkAddress
&address
)
185 return this->CompareTo(address
) < 0;
189 void Listen(int socktype
, SocketList
*sockets
);
191 static const char *SocketTypeAsString(int socktype
);
192 static const char *AddressFamilyAsString(int family
);
195 #endif /* ENABLE_NETWORK */
196 #endif /* NETWORK_CORE_ADDRESS_H */