Modernize client code (#6250)
[oweals/minetest.git] / src / socket.h
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef SOCKET_HEADER
21 #define SOCKET_HEADER
22
23 #ifdef _WIN32
24 #ifndef _WIN32_WINNT
25         #define _WIN32_WINNT 0x0501
26 #endif
27         #include <windows.h>
28         #include <winsock2.h>
29         #include <ws2tcpip.h>
30 #else
31         #include <sys/socket.h>
32         #include <netinet/in.h>
33 #endif
34
35 #include <ostream>
36 #include <string.h>
37 #include "irrlichttypes.h"
38 #include "exceptions.h"
39
40 extern bool socket_enable_debug_output;
41
42 class SocketException : public BaseException
43 {
44 public:
45         SocketException(const std::string &s):
46                 BaseException(s)
47         {
48         }
49 };
50
51 class ResolveError : public BaseException
52 {
53 public:
54         ResolveError(const std::string &s):
55                 BaseException(s)
56         {
57         }
58 };
59
60 class SendFailedException : public BaseException
61 {
62 public:
63         SendFailedException(const std::string &s):
64                 BaseException(s)
65         {
66         }
67 };
68
69 void sockets_init();
70 void sockets_cleanup();
71
72 class IPv6AddressBytes
73 {
74 public:
75         u8 bytes[16];
76         IPv6AddressBytes() { memset(bytes, 0, 16); }
77 };
78
79 class Address
80 {
81 public:
82         Address();
83         Address(u32 address, u16 port);
84         Address(u8 a, u8 b, u8 c, u8 d, u16 port);
85         Address(const IPv6AddressBytes *ipv6_bytes, u16 port);
86         bool operator==(const Address &address);
87         bool operator!=(const Address &address);
88         // Resolve() may throw ResolveError (address is unchanged in this case)
89         void Resolve(const char *name);
90         struct sockaddr_in getAddress() const;
91         unsigned short getPort() const;
92         void setAddress(u32 address);
93         void setAddress(u8 a, u8 b, u8 c, u8 d);
94         void setAddress(const IPv6AddressBytes *ipv6_bytes);
95         struct sockaddr_in6 getAddress6() const;
96         int getFamily() const;
97         bool isIPv6() const;
98         bool isZero() const;
99         void setPort(unsigned short port);
100         void print(std::ostream *s) const;
101         std::string serializeString() const;
102 private:
103         unsigned int m_addr_family = 0;
104         union
105         {
106                 struct sockaddr_in  ipv4;
107                 struct sockaddr_in6 ipv6;
108         } m_address;
109         u16 m_port = 0; // Port is separate from sockaddr structures
110 };
111
112 class UDPSocket
113 {
114 public:
115         UDPSocket() { }
116         UDPSocket(bool ipv6);
117         ~UDPSocket();
118         void Bind(Address addr);
119
120         bool init(bool ipv6, bool noExceptions = false);
121
122         //void Close();
123         //bool IsOpen();
124         void Send(const Address & destination, const void * data, int size);
125         // Returns -1 if there is no data
126         int Receive(Address & sender, void * data, int size);
127         int GetHandle(); // For debugging purposes only
128         void setTimeoutMs(int timeout_ms);
129         // Returns true if there is data, false if timeout occurred
130         bool WaitData(int timeout_ms);
131 private:
132         int m_handle;
133         int m_timeout_ms;
134         int m_addr_family;
135 };
136
137 #endif
138