# address.h

Go to the documentation of this file.

    00001 /* $Id: address.h 22701 2011-07-30 17:45:37Z rubidium $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #ifndef NETWORK_CORE_ADDRESS_H
    00013 #define NETWORK_CORE_ADDRESS_H
    00014
    00015 #include "os_abstraction.h"
    00016 #include "config.h"
    00017 #include "../../string_func.h"
    00018 #include "../../core/smallmap_type.hpp"
    00019
    00020 #ifdef ENABLE_NETWORK
    00021
    00022 class NetworkAddress;
    00023 typedef SmallVector<NetworkAddress, 4> NetworkAddressList;
    00024 typedef SmallMap<NetworkAddress, SOCKET, 4> SocketList;
    00025
    00031 class NetworkAddress {
    00032 private:
    00033   char hostname[NETWORK_HOSTNAME_LENGTH];
    00034   int address_length;
    00035   sockaddr_storage address;
    00036   bool resolved;
    00037
    00043   typedef SOCKET (*LoopProc)(addrinfo *runp);
    00044
    00045   SOCKET Resolve(int family, int socktype, int flags, SocketList *sockets, LoopProc func);
    00046 public:
    00051   NetworkAddress(struct sockaddr_storage &address, int address_length) :
    00052     address_length(address_length),
    00053     address(address),
    00054     resolved(address_length != 0)
    00055   {
    00056     *this->hostname = '\0';
    00057   }
    00058
    00063   NetworkAddress(sockaddr *address, int address_length) :
    00064     address_length(address_length),
    00065     resolved(address_length != 0)
    00066   {
    00067     *this->hostname = '\0';
    00068     memset(&this->address, 0, sizeof(this->address));
    00069     memcpy(&this->address, address, address_length);
    00070   }
    00071
    00078   NetworkAddress(const char *hostname = "", uint16 port = 0, int family = AF_UNSPEC) :
    00079     address_length(0),
    00080     resolved(false)
    00081   {
    00082     /* Also handle IPv6 bracket enclosed hostnames */
    00083     if (StrEmpty(hostname)) hostname = "";
    00084     if (*hostname == '[') hostname++;
    00085     strecpy(this->hostname, StrEmpty(hostname) ? "" : hostname, lastof(this->hostname));
    00086     char *tmp = strrchr(this->hostname, ']');
    00087     if (tmp != NULL) *tmp = '\0';
    00088
    00089     memset(&this->address, 0, sizeof(this->address));
    00090     this->address.ss_family = family;
    00091     this->SetPort(port);
    00092   }
    00093
    00098   NetworkAddress(const NetworkAddress &address)
    00099   {
    00100     memcpy(this, &address, sizeof(*this));
    00101   }
    00102
    00103   const char *GetHostname();
    00104   void GetAddressAsString(char *buffer, const char *last, bool with_family = true);
    00105   const char *GetAddressAsString(bool with_family = true);
    00106   const sockaddr_storage *GetAddress();
    00107
    00112   int GetAddressLength()
    00113   {
    00114     /* Resolve it if we didn't do it already */
    00115     if (!this->IsResolved()) this->GetAddress();
    00116     return this->address_length;
    00117   }
    00118
    00119   uint16 GetPort() const;
    00120   void SetPort(uint16 port);
    00121
    00126   bool IsResolved() const
    00127   {
    00128     return this->resolved;
    00129   }
    00130
    00131   bool IsFamily(int family);
    00132   bool IsInNetmask(char *netmask);
    00133
    00139   int CompareTo(NetworkAddress &address)
    00140   {
    00141     int r = this->GetAddressLength() - address.GetAddressLength();
    00142     if (r == 0) r = this->address.ss_family - address.address.ss_family;
    00143     if (r == 0) r = memcmp(&this->address, &address.address, this->address_length);
    00144     if (r == 0) r = this->GetPort() - address.GetPort();
    00145     return r;
    00146   }
    00147
    00153   bool operator == (NetworkAddress &address)
    00154   {
    00155     return this->CompareTo(address) == 0;
    00156   }
    00157
    00163   bool operator == (NetworkAddress &address) const
    00164   {
    00165     return const_cast<NetworkAddress*>(this)->CompareTo(address) == 0;
    00166   }
    00172   bool operator != (NetworkAddress address) const
    00173   {
    00174     return const_cast<NetworkAddress*>(this)->CompareTo(address) != 0;
    00175   }
    00176
    00181   bool operator < (NetworkAddress &address)
    00182   {
    00183     return this->CompareTo(address) < 0;
    00184   }
    00185
    00186   SOCKET Connect();
    00187   void Listen(int socktype, SocketList *sockets);
    00188
    00189   static const char *SocketTypeAsString(int socktype);
    00190   static const char *AddressFamilyAsString(int family);
    00191 };
    00192
    00193 #endif /* ENABLE_NETWORK */
    00194 #endif /* NETWORK_CORE_ADDRESS_H */