2 Unix SMB/CIFS implementation.
4 local testing of socket routines.
6 Copyright (C) Andrew Tridgell 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "lib/socket/socket.h"
24 #include "lib/events/events.h"
25 #include "system/network.h"
26 #include "lib/socket/netif.h"
27 #include "torture/torture.h"
28 #include "param/param.h"
29 #include "libcli/resolve/resolve.h"
32 basic testing of udp routines
34 static bool test_udp(struct torture_context
*tctx
)
36 struct socket_context
*sock1
, *sock2
;
38 struct socket_address
*srv_addr
, *from_addr
, *localhost
;
39 size_t size
= 100 + (random() % 100);
40 DATA_BLOB blob
, blob2
;
42 TALLOC_CTX
*mem_ctx
= tctx
;
43 struct interface
*ifaces
;
45 load_interfaces(tctx
, lpcfg_interfaces(tctx
->lp_ctx
), &ifaces
);
47 status
= socket_create("ip", SOCKET_TYPE_DGRAM
, &sock1
, 0);
48 torture_assert_ntstatus_ok(tctx
, status
, "creating DGRAM IP socket 1");
49 talloc_steal(mem_ctx
, sock1
);
51 status
= socket_create("ip", SOCKET_TYPE_DGRAM
, &sock2
, 0);
52 torture_assert_ntstatus_ok(tctx
, status
, "creating DGRAM IP socket 1");
53 talloc_steal(mem_ctx
, sock2
);
55 localhost
= socket_address_from_strings(sock1
, sock1
->backend_name
,
56 iface_best_ip(ifaces
, "127.0.0.1"), 0);
58 torture_assert(tctx
, localhost
, "Localhost not found");
60 status
= socket_listen(sock1
, localhost
, 0, 0);
61 torture_assert_ntstatus_ok(tctx
, status
, "listen on socket 1");
63 srv_addr
= socket_get_my_addr(sock1
, mem_ctx
);
64 torture_assert(tctx
, srv_addr
!= NULL
&&
65 strcmp(srv_addr
->addr
, iface_best_ip(ifaces
, "127.0.0.1")) == 0,
67 "Expected server address of %s but got %s",
68 iface_best_ip(ifaces
, "127.0.0.1"), srv_addr
? srv_addr
->addr
: NULL
));
70 torture_comment(tctx
, "server port is %d\n", srv_addr
->port
);
72 blob
= data_blob_talloc(mem_ctx
, NULL
, size
);
73 blob2
= data_blob_talloc(mem_ctx
, NULL
, size
);
74 generate_random_buffer(blob
.data
, blob
.length
);
77 status
= socket_sendto(sock2
, &blob
, &sent
, srv_addr
);
78 torture_assert_ntstatus_ok(tctx
, status
, "sendto() on socket 2");
80 status
= socket_recvfrom(sock1
, blob2
.data
, size
, &nread
,
82 torture_assert_ntstatus_ok(tctx
, status
, "recvfrom() on socket 1");
84 torture_assert_str_equal(tctx
, from_addr
->addr
, srv_addr
->addr
,
87 torture_assert_int_equal(tctx
, nread
, size
, "Unexpected recvfrom size");
89 torture_assert_mem_equal(tctx
, blob2
.data
, blob
.data
, size
,
90 "Bad data in recvfrom");
92 generate_random_buffer(blob
.data
, blob
.length
);
93 status
= socket_sendto(sock1
, &blob
, &sent
, from_addr
);
94 torture_assert_ntstatus_ok(tctx
, status
, "sendto() on socket 1");
96 status
= socket_recvfrom(sock2
, blob2
.data
, size
, &nread
,
98 torture_assert_ntstatus_ok(tctx
, status
, "recvfrom() on socket 2");
99 torture_assert_str_equal(tctx
, from_addr
->addr
, srv_addr
->addr
,
100 "Unexpected recvfrom addr");
102 torture_assert_int_equal(tctx
, nread
, size
, "Unexpected recvfrom size");
104 torture_assert_int_equal(tctx
, from_addr
->port
, srv_addr
->port
,
105 "Unexpected recvfrom port");
107 torture_assert_mem_equal(tctx
, blob2
.data
, blob
.data
, size
,
108 "Bad data in recvfrom");
116 basic testing of tcp routines
118 static bool test_tcp(struct torture_context
*tctx
)
120 struct socket_context
*sock1
, *sock2
, *sock3
;
122 struct socket_address
*srv_addr
, *from_addr
, *localhost
;
123 size_t size
= 100 + (random() % 100);
124 DATA_BLOB blob
, blob2
;
126 TALLOC_CTX
*mem_ctx
= tctx
;
127 struct tevent_context
*ev
= tctx
->ev
;
128 struct interface
*ifaces
;
130 status
= socket_create("ip", SOCKET_TYPE_STREAM
, &sock1
, 0);
131 torture_assert_ntstatus_ok(tctx
, status
, "creating IP stream socket 1");
132 talloc_steal(mem_ctx
, sock1
);
134 status
= socket_create("ip", SOCKET_TYPE_STREAM
, &sock2
, 0);
135 torture_assert_ntstatus_ok(tctx
, status
, "creating IP stream socket 1");
136 talloc_steal(mem_ctx
, sock2
);
138 load_interfaces(tctx
, lpcfg_interfaces(tctx
->lp_ctx
), &ifaces
);
139 localhost
= socket_address_from_strings(sock1
, sock1
->backend_name
,
140 iface_best_ip(ifaces
, "127.0.0.1"), 0);
141 torture_assert(tctx
, localhost
, "Localhost not found");
143 status
= socket_listen(sock1
, localhost
, 0, 0);
144 torture_assert_ntstatus_ok(tctx
, status
, "listen on socket 1");
146 srv_addr
= socket_get_my_addr(sock1
, mem_ctx
);
147 torture_assert(tctx
, srv_addr
&& srv_addr
->addr
,
148 "Unexpected socket_get_my_addr NULL\n");
150 torture_assert_str_equal(tctx
, srv_addr
->addr
, iface_best_ip(ifaces
, "127.0.0.1"),
151 "Unexpected server address");
153 torture_comment(tctx
, "server port is %d\n", srv_addr
->port
);
155 status
= socket_connect_ev(sock2
, NULL
, srv_addr
, 0, ev
);
156 torture_assert_ntstatus_ok(tctx
, status
, "connect() on socket 2");
158 status
= socket_accept(sock1
, &sock3
);
159 torture_assert_ntstatus_ok(tctx
, status
, "accept() on socket 1");
160 talloc_steal(mem_ctx
, sock3
);
163 blob
= data_blob_talloc(mem_ctx
, NULL
, size
);
164 blob2
= data_blob_talloc(mem_ctx
, NULL
, size
);
165 generate_random_buffer(blob
.data
, blob
.length
);
168 status
= socket_send(sock2
, &blob
, &sent
);
169 torture_assert_ntstatus_ok(tctx
, status
, "send() on socket 2");
171 status
= socket_recv(sock3
, blob2
.data
, size
, &nread
);
172 torture_assert_ntstatus_ok(tctx
, status
, "recv() on socket 3");
174 from_addr
= socket_get_peer_addr(sock3
, mem_ctx
);
176 torture_assert(tctx
, from_addr
&& from_addr
->addr
,
177 "Unexpected recvfrom addr NULL");
179 torture_assert_str_equal(tctx
, from_addr
->addr
, srv_addr
->addr
,
180 "Unexpected recvfrom addr");
182 torture_assert_int_equal(tctx
, nread
, size
, "Unexpected recvfrom size");
184 torture_assert_mem_equal(tctx
, blob2
.data
, blob
.data
, size
,
189 struct torture_suite
*torture_local_socket(TALLOC_CTX
*mem_ctx
)
191 struct torture_suite
*suite
= torture_suite_create(mem_ctx
,
194 torture_suite_add_simple_test(suite
, "udp", test_udp
);
195 torture_suite_add_simple_test(suite
, "tcp", test_tcp
);