Line data Source code
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 "socket.h"
24 : #include "settings.h"
25 :
26 1 : class TestSocket : public TestBase {
27 : public:
28 1 : TestSocket()
29 1 : {
30 : if (INTERNET_SIMULATOR == false)
31 1 : TestManager::registerTestModule(this);
32 1 : }
33 :
34 0 : 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 1 : static TestSocket g_test_instance;
45 :
46 0 : void TestSocket::runTests(IGameDef *gamedef)
47 : {
48 0 : TEST(testIPv4Socket);
49 :
50 0 : if (g_settings->getBool("enable_ipv6"))
51 0 : TEST(testIPv6Socket);
52 0 : }
53 :
54 : ////////////////////////////////////////////////////////////////////////////////
55 :
56 0 : void TestSocket::testIPv4Socket()
57 : {
58 0 : Address address(0, 0, 0, 0, port);
59 0 : 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 0 : std::string bind_str = g_settings->get("bind_address");
66 : try {
67 0 : bind_addr.Resolve(bind_str.c_str());
68 :
69 0 : if (!bind_addr.isIPv6()) {
70 0 : address = bind_addr;
71 : }
72 0 : } catch (ResolveError &e) {
73 : }
74 :
75 0 : UDPSocket socket(false);
76 0 : socket.Bind(address);
77 :
78 0 : const char sendbuffer[] = "hello world!";
79 : /*
80 : * If there is a bind address, use it.
81 : * It's useful in container environments
82 : */
83 0 : if (address != Address(0, 0, 0, 0, port))
84 0 : socket.Send(address, sendbuffer, sizeof(sendbuffer));
85 : else
86 0 : socket.Send(Address(127, 0, 0, 1, port), sendbuffer, sizeof(sendbuffer));
87 :
88 0 : sleep_ms(50);
89 :
90 0 : char rcvbuffer[256] = { 0 };
91 0 : Address sender;
92 0 : for (;;) {
93 0 : if (socket.Receive(sender, rcvbuffer, sizeof(rcvbuffer)) < 0)
94 0 : break;
95 : }
96 : //FIXME: This fails on some systems
97 0 : UASSERT(strncmp(sendbuffer, rcvbuffer, sizeof(sendbuffer)) == 0);
98 :
99 0 : if (address != Address(0, 0, 0, 0, port)) {
100 0 : UASSERT(sender.getAddress().sin_addr.s_addr ==
101 0 : address.getAddress().sin_addr.s_addr);
102 : } else {
103 0 : UASSERT(sender.getAddress().sin_addr.s_addr ==
104 0 : Address(127, 0, 0, 1, 0).getAddress().sin_addr.s_addr);
105 : }
106 0 : }
107 :
108 0 : void TestSocket::testIPv6Socket()
109 : {
110 0 : Address address6((IPv6AddressBytes *)NULL, port);
111 0 : UDPSocket socket6;
112 :
113 0 : 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 0 : dstream << "WARNING: IPv6 socket creation failed (unit test)"
121 0 : << std::endl;
122 0 : return;
123 : }
124 :
125 0 : const char sendbuffer[] = "hello world!";
126 0 : IPv6AddressBytes bytes;
127 0 : bytes.bytes[15] = 1;
128 :
129 0 : socket6.Bind(address6);
130 :
131 : try {
132 0 : socket6.Send(Address(&bytes, port), sendbuffer, sizeof(sendbuffer));
133 :
134 0 : sleep_ms(50);
135 :
136 0 : char rcvbuffer[256] = { 0 };
137 0 : Address sender;
138 :
139 0 : for(;;) {
140 0 : if (socket6.Receive(sender, rcvbuffer, sizeof(rcvbuffer)) < 0)
141 0 : break;
142 : }
143 : //FIXME: This fails on some systems
144 0 : UASSERT(strncmp(sendbuffer, rcvbuffer, sizeof(sendbuffer)) == 0);
145 0 : UASSERT(memcmp(sender.getAddress6().sin6_addr.s6_addr,
146 0 : Address(&bytes, 0).getAddress6().sin6_addr.s6_addr, 16) == 0);
147 0 : } catch (SendFailedException &e) {
148 0 : errorstream << "IPv6 support enabled but not available!"
149 0 : << std::endl;
150 : }
151 3 : }
|