Translated using Weblate (Italian)
[oweals/minetest.git] / src / unittest / test_socket.cpp
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 #include "test.h"
21
22 #include "log.h"
23 #include "settings.h"
24 #include "network/socket.h"
25
26 class TestSocket : public TestBase {
27 public:
28         TestSocket()
29         {
30                 if (INTERNET_SIMULATOR == false)
31                         TestManager::registerTestModule(this);
32         }
33
34         const char *getName() { return "TestSocket"; }
35
36         void runTests(IGameDef *gamedef);
37
38         void testIPv4Socket();
39         void testIPv6Socket();
40
41         static const int port = 30003;
42 };
43
44 static TestSocket g_test_instance;
45
46 void TestSocket::runTests(IGameDef *gamedef)
47 {
48         TEST(testIPv4Socket);
49
50         if (g_settings->getBool("enable_ipv6"))
51                 TEST(testIPv6Socket);
52 }
53
54 ////////////////////////////////////////////////////////////////////////////////
55
56 void TestSocket::testIPv4Socket()
57 {
58         Address address(0, 0, 0, 0, port);
59         Address bind_addr(0, 0, 0, 0, port);
60
61         /*
62          * Try to use the bind_address for servers with no localhost address
63          * For example: FreeBSD jails
64          */
65         std::string bind_str = g_settings->get("bind_address");
66         try {
67                 bind_addr.Resolve(bind_str.c_str());
68
69                 if (!bind_addr.isIPv6()) {
70                         address = bind_addr;
71                 }
72         } catch (ResolveError &e) {
73         }
74
75         UDPSocket socket(false);
76         socket.Bind(address);
77
78         const char sendbuffer[] = "hello world!";
79         /*
80          * If there is a bind address, use it.
81          * It's useful in container environments
82          */
83         if (address != Address(0, 0, 0, 0, port))
84                 socket.Send(address, sendbuffer, sizeof(sendbuffer));
85         else
86                 socket.Send(Address(127, 0, 0, 1, port), sendbuffer, sizeof(sendbuffer));
87
88         sleep_ms(50);
89
90         char rcvbuffer[256] = { 0 };
91         Address sender;
92         for (;;) {
93                 if (socket.Receive(sender, rcvbuffer, sizeof(rcvbuffer)) < 0)
94                         break;
95         }
96         //FIXME: This fails on some systems
97         UASSERT(strncmp(sendbuffer, rcvbuffer, sizeof(sendbuffer)) == 0);
98
99         if (address != Address(0, 0, 0, 0, port)) {
100                 UASSERT(sender.getAddress().sin_addr.s_addr ==
101                                 address.getAddress().sin_addr.s_addr);
102         } else {
103                 UASSERT(sender.getAddress().sin_addr.s_addr ==
104                                 Address(127, 0, 0, 1, 0).getAddress().sin_addr.s_addr);
105         }
106 }
107
108 void TestSocket::testIPv6Socket()
109 {
110         Address address6((IPv6AddressBytes *)NULL, port);
111         UDPSocket socket6;
112
113         if (!socket6.init(true, true)) {
114                 /* Note: Failing to create an IPv6 socket is not technically an
115                    error because the OS may not support IPv6 or it may
116                    have been disabled. IPv6 is not /required/ by
117                    minetest and therefore this should not cause the unit
118                    test to fail
119                 */
120                 dstream << "WARNING: IPv6 socket creation failed (unit test)"
121                         << std::endl;
122                 return;
123         }
124
125         const char sendbuffer[] = "hello world!";
126         IPv6AddressBytes bytes;
127         bytes.bytes[15] = 1;
128
129         socket6.Bind(address6);
130
131         try {
132                 socket6.Send(Address(&bytes, port), sendbuffer, sizeof(sendbuffer));
133
134                 sleep_ms(50);
135
136                 char rcvbuffer[256] = { 0 };
137                 Address sender;
138
139                 for(;;) {
140                         if (socket6.Receive(sender, rcvbuffer, sizeof(rcvbuffer)) < 0)
141                                 break;
142                 }
143                 //FIXME: This fails on some systems
144                 UASSERT(strncmp(sendbuffer, rcvbuffer, sizeof(sendbuffer)) == 0);
145                 UASSERT(memcmp(sender.getAddress6().sin6_addr.s6_addr,
146                                 Address(&bytes, 0).getAddress6().sin6_addr.s6_addr, 16) == 0);
147         } catch (SendFailedException &e) {
148                 errorstream << "IPv6 support enabled but not available!"
149                                         << std::endl;
150         }
151 }