XPMP2
X-Plane multiplayer library 2 - using instancing
Network.h
Go to the documentation of this file.
1
31
32#ifndef Network_h
33#define Network_h
34
35#include <sys/types.h>
36#if IBM
37#include <winsock2.h>
38#include <ws2ipdef.h> // required for sockaddr_in6 (?)
39#include <iphlpapi.h> // for GetAdaptersAddresses
40#include <ws2tcpip.h> // for socklen_t
41#include <mswsock.h> // for LPFN_WSARECVMSG
42#else
43#define __APPLE_USE_RFC_3542 // both required for newer constants like IPV6_RECVPKTINFO
44#define _GNU_SOURCE
45#include <sys/socket.h>
46#include <netdb.h>
47#include <ifaddrs.h>
48typedef int SOCKET;
49constexpr SOCKET INVALID_SOCKET = -1;
50#endif
51
52#include <stdexcept>
53
54namespace XPMP2 {
55
58{
59 union {
60 sockaddr sa; // unspecific
61 sockaddr_in sa_in; // AF_INET / IPv4
62 sockaddr_in6 sa_in6; // AF_INET6 / IPv6
63 };
64
66 SockAddrTy() { memset((void*)this, 0, sizeof(SockAddrTy)); }
68 SockAddrTy (const sockaddr* pSa);
69
71 bool operator< (const SockAddrTy& o) const
72 { return std::memcmp(this, &o, sizeof(*this)) < 0; }
74 bool operator== (const SockAddrTy& o) const
75 { return std::memcmp(this, &o, sizeof(*this)) == 0; }
76
77 uint8_t family() const { return (uint8_t) sa.sa_family; }
78 bool isIp4() const { return family() == AF_INET; }
79 bool isIp6() const { return family() == AF_INET6; }
80 socklen_t size () const
81 { return
82 sa.sa_family == AF_INET ? sizeof(sa_in) :
83 sa.sa_family == AF_INET6 ? sizeof(sa_in6) : sizeof(sa); }
84
86 uint16_t port () const {
87 return ntohs(isIp4() ? sa_in.sin_port :
88 isIp6() ? sa_in6.sin6_port : 0);
89 }
91 void setPort (uint16_t port) {
92 if (isIp4()) sa_in.sin_port = htons(port);
93 else if (isIp6()) sa_in6.sin6_port = htons(port);
94 }
95};
96
101class XPMP2_EXPORT NetRuntimeError : public std::runtime_error
102{
103public:
104 std::string errTxt;
105 std::string fullWhat;
106 NetRuntimeError(const std::string& w);
108 const char* what() const noexcept override { return fullWhat.c_str(); }
109};
110
114{
115protected:
117 int f_port = 0;
118 std::string f_addr;
119
120 // the data receive buffer
121 char* buf = NULL;
122 size_t bufSize = 512;
123
124#if IBM
126 LPFN_WSARECVMSG pWSARecvMsg = nullptr;
127#endif
128public:
132 virtual ~SocketNetworking();
133
135 virtual void Open(const std::string& _addr, int _port, size_t _bufSize = 512,
136 unsigned _timeOut_ms = 0, bool _bBroadcast = false);
138 virtual void Connect(const std::string& _addr, int _port, size_t _bufSize,
139 unsigned _timeOut_ms = 0);
141 virtual void Close();
143 inline bool isOpen() const { return (f_socket != INVALID_SOCKET); }
145 void SetBufSize (size_t _bufSize);
147 static std::string GetLastErr();
148
149 // attribute access
150 SOCKET getSocket() const { return f_socket; }
151 int getPort() const { return f_port; }
152 std::string getAddr() const { return f_addr; }
153
155 const char* getBuf () const { return buf ? buf : ""; }
156
158 void setBlocking (bool bBlock);
159
164 long recv(std::string* _pFromAddr = nullptr,
165 SockAddrTy* _pFromSockAddr = nullptr);
171 long timedRecv(int max_wait_ms,
172 std::string* _pFromAddr = nullptr,
173 SockAddrTy* _pFromSockAddr = nullptr);
174
176 virtual bool send(const char* msg);
177
179 bool broadcast (const char* msg);
180
182 static std::string GetAddrString (const SockAddrTy& sa, bool withPort = true);
183
184protected:
186 virtual void GetAddrHints (struct addrinfo& hints) = 0;
187#if IBM
191 int WSARecvMsg(
192 LPWSAMSG lpMsg,
193 LPDWORD lpdwNumberOfBytesRecvd,
194 LPWSAOVERLAPPED lpOverlapped,
195 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
196#endif
197};
198
199
202{
203public:
206
207protected:
209 void GetAddrHints (struct addrinfo& hints) override;
210};
211
212
216{
217protected:
218 std::string multicastAddr;
219 struct addrinfo* pMCAddr = nullptr;
220
221 bool bSendToAll = true;
222 uint32_t oneIntfIdx = 0;
223
225 std::map<SockAddrTy,std::chrono::time_point<std::chrono::steady_clock> > mapSender;
226
227public:
231 UDPMulticast(const std::string& _multicastAddr, int _port,
232 const std::string& _sendIntf,
233 int _ttl=8, size_t _bufSize = 512, unsigned _timeOut_ms = 0);
235 ~UDPMulticast() override;
236
238 const std::string& GetMCAddr() const { return multicastAddr; }
239
242 void Join (const std::string& _multicastAddr, int _port,
243 const std::string& _sendIntf,
244 int _ttl=8, size_t _bufSize = 512, unsigned _timeOut_ms = 0);
245
247 uint8_t GetFamily () const { return pMCAddr ? (uint8_t)pMCAddr->ai_family : AF_UNSPEC; }
248 bool IsIPv4 () const { return GetFamily() == AF_INET; }
249 bool IsIPv6 () const { return GetFamily() == AF_INET6; }
250
252 void SendToDefault ();
254 void SendToAll ();
256 void SendToIntf (uint32_t idx);
257
262 size_t SendMC (const void* _bufSend, size_t _bufSendSize);
263
270 size_t RecvMC (bool bSwitchToRecvIntf,
271 std::string* _pFromAddr = nullptr,
272 SockAddrTy* _pFromSockAddr = nullptr,
273 bool* _pbIntfChanged = nullptr);
274
275protected:
276 void Cleanup ();
278 void GetAddrHints (struct addrinfo& hints) override;
280 void SetSendInterface (const in_addr& addr);
282 void SetSendInterface (uint32_t ifIdx);
283};
284
285
288{
289protected:
290 SOCKET f_session_socket = INVALID_SOCKET;
291 struct sockaddr_in f_session_addr = {};
292#if APL == 1 || LIN == 1
294 SOCKET selfPipe[2] = { INVALID_SOCKET, INVALID_SOCKET };
295#endif
296
297public:
300
301 void Close() override;
302 void CloseListenerOnly();
303
304 void listen (int numConnections = 1);
305 bool accept (bool bUnlisten = false);
306 bool listenAccept (int numConnections = 1);
307
309 bool IsConnected () const { return f_session_socket != INVALID_SOCKET; };
310
312 bool send(const char* msg) override;
313
314protected:
315 void GetAddrHints (struct addrinfo& hints) override;
316};
317
318
321 union {
322 std::uint32_t addr[4] = {0,0,0,0};
323 struct in_addr in_addr;
324 struct in6_addr in6_addr;
325 };
326
330 InetAddrTy (const SockAddrTy& sa) { CopyFrom(sa); }
332 InetAddrTy (const sockaddr* pSa) { CopyFrom(SockAddrTy(pSa)); }
333
335 void CopyFrom (const SockAddrTy& sa);
336
338 bool operator==(const InetAddrTy& o) const
339 { return std::memcmp(this, &o, sizeof(*this)) == 0; }
340
342 bool operator<(const InetAddrTy& o) const
343 { return std::memcmp(this, &o, sizeof(*this)) < 0; }
344
345};
346
348bool XPMP2_EXPORT NetwIsLocalAddr (const InetAddrTy& addr);
350inline bool NetwIsLocalAddr (const SockAddrTy& sa)
351{ return NetwIsLocalAddr(InetAddrTy(sa)); }
353inline bool NetwIsLocalAddr (const sockaddr* pSa)
354{ return NetwIsLocalAddr(InetAddrTy(pSa)); }
355
361std::vector<std::string> XPMP2_EXPORT NetwGetInterfaces (uint8_t family, uint32_t fMust = 0, uint32_t fSkip = 0);
363std::string XPMP2_EXPORT NetwGetInterfaceNames (uint8_t family, uint32_t fMust = 0, uint32_t fSkip = 0);
364
365} // namespace XPMP2
366
367#endif /* Network_h */
constexpr SOCKET INVALID_SOCKET
Definition Network.h:49
int SOCKET
Windows defines SOCKET, so we define it for non-Windows manually.
Definition Network.h:48
#define XPMP2_EXPORT
Definition XPMPExport.h:51
Exception raised by XPMP2::SocketNetworking objects.
Definition Network.h:102
const char * what() const noexcept override
Return the full message, ie. fullWhat
Definition Network.h:108
std::string errTxt
OS text for what errno says, output of strerror_s()
Definition Network.h:104
std::string fullWhat
combines w and errTxt
Definition Network.h:105
Base class for any socket-based networking.
Definition Network.h:114
SOCKET getSocket() const
the socket
Definition Network.h:150
bool isOpen() const
Is a socket open?
Definition Network.h:143
std::string f_addr
Definition Network.h:118
SocketNetworking()
Default constructor is not doing anything.
Definition Network.h:130
const char * getBuf() const
return the buffer
Definition Network.h:155
virtual void GetAddrHints(struct addrinfo &hints)=0
Subclass to tell which addresses to look for.
std::string getAddr() const
the interface address
Definition Network.h:152
int getPort() const
the port
Definition Network.h:151
Listens to TCP connections and opens a session socket upon connect.
Definition Network.h:288
bool IsConnected() const
Connected to a counterparty?
Definition Network.h:309
TCPConnection()
Default constructor is not doing anything.
Definition Network.h:299
UDP Multicast, always binding to INADDR_ANY.
Definition Network.h:216
bool IsIPv6() const
IPv6?
Definition Network.h:249
const std::string & GetMCAddr() const
Return formatted multicast address, including port.
Definition Network.h:238
std::map< SockAddrTy, std::chrono::time_point< std::chrono::steady_clock > > mapSender
Keep a list of sources we received data from to be able to identify new sources.
Definition Network.h:225
std::string multicastAddr
the multicast address
Definition Network.h:218
UDPMulticast()
Default constructor is not doing anything.
Definition Network.h:229
uint8_t GetFamily() const
Protocol family.
Definition Network.h:247
bool IsIPv4() const
IPv4?
Definition Network.h:248
Receives UDP messages.
Definition Network.h:202
UDPReceiver()
Default constructor is not doing anything.
Definition Network.h:205
Definition XPMPAircraft.h:76
std::vector< std::string > NetwGetInterfaces(uint8_t family, uint32_t fMust, uint32_t fSkip)
Return list of known local interfaces.
Definition Network.cpp:301
bool NetwIsLocalAddr(const InetAddrTy &addr)
Is given address a local one?
Definition Network.cpp:1445
std::string NetwGetInterfaceNames(uint8_t family, uint32_t fMust, uint32_t fSkip)
Return comma-separated string will all known local interfaces, calls NetwGetInterfaces()
Definition Network.cpp:315
Numerical IP address, used for both ipv4 and ipv6, for ease of handling.
Definition Network.h:320
InetAddrTy(const sockaddr *pSa)
Take over from structure.
Definition Network.h:332
bool operator<(const InetAddrTy &o) const
Comparison also uses memcmp for defined order.
Definition Network.h:342
bool operator==(const InetAddrTy &o) const
Equality means: all elements are equal.
Definition Network.h:338
InetAddrTy()
Default does nothing.
Definition Network.h:328
InetAddrTy(const SockAddrTy &sa)
Take over from structure.
Definition Network.h:330
Helper definition for all these IPv4/6 differences.
Definition Network.h:58
bool isIp4() const
is this an IPv4 address?
Definition Network.h:78
uint16_t port() const
Get the port number.
Definition Network.h:86
bool isIp6() const
is this an IPv6 address?
Definition Network.h:79
socklen_t size() const
< expected structure size as per protocol family
Definition Network.h:80
uint8_t family() const
return the protocol famaily
Definition Network.h:77
void setPort(uint16_t port)
Set the port number.
Definition Network.h:91
SockAddrTy()
Constructor zeroes out everying.
Definition Network.h:66