SuperTuxKart
socket_address.hpp
1 // SuperTuxKart - a fun racing game with go-kart
2 // Copyright (C) 2020 SuperTuxKart-Team
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 3
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 
21 #ifndef HEADER_SOCKET_ADDRESS_HPP
22 #define HEADER_SOCKET_ADDRESS_HPP
23 
24 #include "utils/types.hpp"
25 
26 #ifdef WIN32
27 # include <winsock2.h>
28 # include <ws2tcpip.h>
29 #else
30 # include <netdb.h>
31 # include <netinet/in.h>
32 # include <sys/socket.h>
33 #endif
34 #include <enet/enet.h>
35 
36 #include <array>
37 #include <cstring>
38 #include <string>
39 #include <vector>
40 
41 // ============================================================================
47 {
48 private:
49  std::array<char, sizeof(sockaddr_storage)> m_sockaddr;
50 
51  short m_family;
52 public:
53  // ------------------------------------------------------------------------
54  static bool g_ignore_error_message;
55  // ------------------------------------------------------------------------
56  static void unitTesting();
57  // ------------------------------------------------------------------------
58  SocketAddress(uint32_t ip = 0, uint16_t port = 0);
59  // ------------------------------------------------------------------------
61  SocketAddress(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4,
62  uint16_t port = 0);
63  // ------------------------------------------------------------------------
64  SocketAddress(const std::string& str, uint16_t port_number = 0,
65  short family = AF_UNSPEC)
66  {
67  init(str, port_number, family);
68  }
69  // ------------------------------------------------------------------------
70  SocketAddress(const ENetAddress& ea);
71  // ------------------------------------------------------------------------
72  bool operator==(const SocketAddress& other) const;
73  // ------------------------------------------------------------------------
74  bool operator!=(const SocketAddress& other) const;
75  // ------------------------------------------------------------------------
76  void init(const std::string& str, uint16_t port_number = 0,
77  short family = AF_UNSPEC);
78  // ------------------------------------------------------------------------
79  bool isLAN() const;
80  // ------------------------------------------------------------------------
81  bool isUnset() const
82  {
83  if (getPort() == 0)
84  return true;
85  if (m_family == AF_INET && getIP() == 0)
86  return true;
87  return false;
88  }
89  // ------------------------------------------------------------------------
91  void clear()
92  {
93  m_family = AF_INET;
94  m_sockaddr.fill(0);
95  sockaddr_in* in = (sockaddr_in*)m_sockaddr.data();
96  in->sin_family = AF_INET;
97  } // clear
98  // ------------------------------------------------------------------------
99  uint32_t getIP() const;
100  // ------------------------------------------------------------------------
101  uint16_t getPort() const;
102  // ------------------------------------------------------------------------
103  void setIP(uint32_t ip);
104  // ------------------------------------------------------------------------
105  void setPort(uint16_t port);
106  // ------------------------------------------------------------------------
107  std::string toString(bool show_port = true) const;
108  // ------------------------------------------------------------------------
109  sockaddr* getSockaddr() const { return (sockaddr*)m_sockaddr.data(); }
110  // ------------------------------------------------------------------------
111  socklen_t getSocklen() const
112  {
113  if (m_family == AF_INET)
114  return sizeof(sockaddr_in);
115  else if (m_family == AF_INET6)
116  return sizeof(sockaddr_in6);
117  return 0;
118  }
119  // ------------------------------------------------------------------------
120  void setSockAddrIn(short family, sockaddr* new_sockaddr, socklen_t len)
121  {
122  m_family = family;
123  m_sockaddr.fill(0);
124  memcpy(m_sockaddr.data(), new_sockaddr, len);
125  }
126  // ------------------------------------------------------------------------
127  short getFamily() const { return m_family; }
128  // ------------------------------------------------------------------------
129  void setIPv6(const uint8_t* bytes, uint16_t port = 0)
130  {
131  m_family = AF_INET6;
132  m_sockaddr.fill(0);
133  sockaddr_in6* in6 = (sockaddr_in6*)m_sockaddr.data();
134  in6->sin6_family = AF_INET6;
135  memcpy(in6->sin6_addr.s6_addr, bytes, 16);
136  setPort(port);
137  }
138  // ------------------------------------------------------------------------
139  bool isPublicAddressLocalhost() const;
140  // ------------------------------------------------------------------------
143  bool isIPv6() const
144  {
145  if (m_family == AF_INET6)
146  {
147  if (getIP() != 0)
148  return false;
149  return true;
150  }
151  return false;
152  }
153  // ------------------------------------------------------------------------
154  bool isLoopback() const;
155  // ------------------------------------------------------------------------
156  void convertForIPv6Socket(bool ipv6);
157  // ------------------------------------------------------------------------
158  ENetAddress toENetAddress() const;
159 }; // SocketAddress
160 
161 #endif // HEADER_SOCKET_ADDRESS_HPP
Describes a IPv4 or IPv6 address in sockaddr_in(6) format, suitable in using with sendto.
Definition: socket_address.hpp:47
bool isLAN() const
Returns if this IP address belongs to a LAN, i.e.
Definition: socket_address.cpp:485
void setPort(uint16_t port)
Set the port.
Definition: socket_address.cpp:309
void setIP(uint32_t ip)
Sets the ip address.
Definition: socket_address.cpp:296
uint32_t getIP() const
Returns the IPv4 address in decimal, it will handle IPv4 mapped IPv6 address too.
Definition: socket_address.cpp:260
bool isLoopback() const
Returns if this IP is loopback (ie for IPv4 127.0.0.0/8, IPv6 ::1/128)
Definition: socket_address.cpp:452
static void unitTesting()
Unit testing.
Definition: socket_address.cpp:613
void init(const std::string &str, uint16_t port_number=0, short family=AF_UNSPEC)
String initialization (Can be IPv4, IPv6 or domain).
Definition: socket_address.cpp:120
uint16_t getPort() const
Returns the port number.
Definition: socket_address.cpp:279
void clear()
Resets ip and port to 0.
Definition: socket_address.hpp:91
bool operator!=(const SocketAddress &other) const
Compares if ip address and port are not identical.
Definition: socket_address.cpp:542
SocketAddress(uint32_t ip=0, uint16_t port=0)
IPv4 Constructor.
Definition: socket_address.cpp:65
bool isPublicAddressLocalhost() const
Returns this IP address is localhost which its equal to any interface address.
Definition: socket_address.cpp:326
bool operator==(const SocketAddress &other) const
Compares if ip address and port are identical.
Definition: socket_address.cpp:522
bool isIPv6() const
Return true if this is an IPv6 address, if it's an IPv4 mapped IPv6 address it will return false (::f...
Definition: socket_address.hpp:143
Declares the general types that are used by the network.