r17586: merge lib/netif into lib/socket and use -lnsl -lsocket on the
[nivanova/samba-autobuild/.git] / source4 / torture / local / socket.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    local testing of socket routines.
5
6    Copyright (C) Andrew Tridgell 2005
7    
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 2 of the License, or
11    (at your option) any later version.
12    
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.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "lib/socket/socket.h"
25 #include "lib/events/events.h"
26 #include "system/network.h"
27 #include "lib/socket/netif.h"
28 #include "torture/torture.h"
29
30 /*
31   basic testing of udp routines
32 */
33 static BOOL test_udp(struct torture_context *test, const void *data)
34 {
35         struct socket_context *sock1, *sock2;
36         NTSTATUS status;
37         struct socket_address *srv_addr, *from_addr, *localhost;
38         size_t size = 100 + (random() % 100);
39         DATA_BLOB blob, blob2;
40         size_t sent, nread;
41         BOOL ret = True;
42
43         status = socket_create("ip", SOCKET_TYPE_DGRAM, &sock1, 0);
44         torture_assert_ntstatus_ok(test, status, "creating DGRAM IP socket 1");
45         talloc_steal(test, sock1);
46
47         status = socket_create("ip", SOCKET_TYPE_DGRAM, &sock2, 0);
48         torture_assert_ntstatus_ok(test, status, "creating DGRAM IP socket 1");
49         talloc_steal(test, sock2);
50
51         localhost = socket_address_from_strings(sock1, sock1->backend_name, 
52                                                 iface_best_ip("127.0.0.1"), 0);
53
54         torture_assert(test, localhost, "Localhost not found");
55
56         status = socket_listen(sock1, localhost, 0, 0);
57         torture_assert_ntstatus_ok(test, status, "listen on socket 1");
58
59         srv_addr = socket_get_my_addr(sock1, test);
60         if (srv_addr == NULL || strcmp(srv_addr->addr, iface_best_ip("127.0.0.1")) != 0) {
61                 torture_fail(test, "Expected server address of %s but got %s",
62                        iface_best_ip("127.0.0.1"), srv_addr ? srv_addr->addr : NULL);
63                 return False;
64         }
65
66         torture_comment(test, "server port is %d", srv_addr->port);
67
68         blob  = data_blob_talloc(test, NULL, size);
69         blob2 = data_blob_talloc(test, NULL, size);
70         generate_random_buffer(blob.data, blob.length);
71
72         sent = size;
73         status = socket_sendto(sock2, &blob, &sent, srv_addr);
74         torture_assert_ntstatus_ok(test, status, "sendto() on socket 2");
75
76         status = socket_recvfrom(sock1, blob2.data, size, &nread, 
77                                  sock1, &from_addr);
78         torture_assert_ntstatus_ok(test, status, "recvfrom() on socket 1");
79
80         if (strcmp(from_addr->addr, srv_addr->addr) != 0) {
81                 torture_fail(test, "Unexpected recvfrom addr %s", from_addr->addr);
82                 return False;
83         }
84         if (nread != size) {
85                 torture_fail(test, "Unexpected recvfrom size %d should be %d\n", 
86                                          (int)nread, (int)size);
87                 return False;
88         }
89
90         torture_assert(test, memcmp(blob2.data, blob.data, size) == 0,
91                 "Bad data in recvfrom");
92
93         generate_random_buffer(blob.data, blob.length);
94         status = socket_sendto(sock1, &blob, &sent, from_addr);
95         torture_assert_ntstatus_ok(test, status, "sendto() on socket 1");
96
97         status = socket_recvfrom(sock2, blob2.data, size, &nread, 
98                                  sock2, &from_addr);
99         torture_assert_ntstatus_ok(test, status, "recvfrom() on socket 2");
100         if (strcmp(from_addr->addr, srv_addr->addr) != 0) {
101                 torture_fail(test, "Unexpected recvfrom addr %s\n", from_addr->addr);
102                 return False;
103         }
104         
105         if (nread != size) {
106                 torture_fail(test, "Unexpected recvfrom size %d should be %d\n", 
107                                          (int)nread, (int)size);
108                 return False;
109         }
110
111         if (from_addr->port != srv_addr->port) {
112                 torture_fail(test, "Unexpected recvfrom port %d should be %d\n", 
113                        from_addr->port, srv_addr->port);
114                 return False;
115         }
116
117         torture_assert(test, memcmp(blob2.data, blob.data, size) == 0, 
118                 "Bad data in recvfrom");
119
120         talloc_free(sock1);
121         talloc_free(sock2);
122
123         return ret;
124 }
125
126 /*
127   basic testing of tcp routines
128 */
129 static BOOL test_tcp(struct torture_context *test, const void *data)
130 {
131         struct socket_context *sock1, *sock2, *sock3;
132         NTSTATUS status;
133         struct socket_address *srv_addr, *from_addr, *localhost;
134         size_t size = 100 + (random() % 100);
135         DATA_BLOB blob, blob2;
136         size_t sent, nread;
137         struct event_context *ev = event_context_init(test);
138
139         status = socket_create("ip", SOCKET_TYPE_STREAM, &sock1, 0);
140         torture_assert_ntstatus_ok(test, status, "creating IP stream socket 1");
141         talloc_steal(test, sock1);
142
143         status = socket_create("ip", SOCKET_TYPE_STREAM, &sock2, 0);
144         torture_assert_ntstatus_ok(test, status, "creating IP stream socket 1");
145         talloc_steal(test, sock2);
146
147         localhost = socket_address_from_strings(sock1, sock1->backend_name, 
148                                                 iface_best_ip("127.0.0.1"), 0);
149         torture_assert(test, localhost, "Localhost not found");
150
151         status = socket_listen(sock1, localhost, 0, 0);
152         torture_assert_ntstatus_ok(test, status, "listen on socket 1");
153
154         srv_addr = socket_get_my_addr(sock1, test);
155         torture_assert(test, srv_addr && srv_addr->addr, 
156                                    "Unexpected socket_get_my_addr NULL\n");
157
158         if (strcmp(srv_addr->addr, iface_best_ip("127.0.0.1")) != 0) {
159                 torture_fail(test, "Expected server address of %s but got %s\n",
160                        iface_best_ip("127.0.0.1"), srv_addr ? srv_addr->addr : NULL);
161                 return False;
162         }
163
164         torture_comment(test, "server port is %d", srv_addr->port);
165
166         status = socket_connect_ev(sock2, NULL, srv_addr, 0, ev);
167         torture_assert_ntstatus_ok(test, status, "connect() on socket 2");
168
169         status = socket_accept(sock1, &sock3);
170         torture_assert_ntstatus_ok(test, status, "accept() on socket 1");
171         talloc_steal(test, sock3);
172         talloc_free(sock1);
173
174         blob  = data_blob_talloc(test, NULL, size);
175         blob2 = data_blob_talloc(test, NULL, size);
176         generate_random_buffer(blob.data, blob.length);
177
178         sent = size;
179         status = socket_send(sock2, &blob, &sent);
180         torture_assert_ntstatus_ok(test, status, "send() on socket 2");
181
182         status = socket_recv(sock3, blob2.data, size, &nread);
183         torture_assert_ntstatus_ok(test, status, "recv() on socket 3");
184
185         from_addr = socket_get_peer_addr(sock3, test);
186
187         torture_assert(test, from_addr && from_addr->addr, 
188                 "Unexpected recvfrom addr NULL");
189
190         if (strcmp(from_addr->addr, srv_addr->addr) != 0) {
191                 torture_fail(test, "Unexpected recvfrom addr %s\n", 
192                                          from_addr ? from_addr->addr : NULL);
193                 return False;
194         }
195         if (nread != size) {
196                 torture_fail(test, "Unexpected recvfrom size %d should be %d\n", 
197                                          (int)nread, (int)size);
198                 return False;
199         }
200
201         torture_assert(test, 
202                                    memcmp(blob2.data, blob.data, size) == 0, 
203                                    "Bad data in recv");
204
205         return True;
206 }
207
208 struct torture_suite *torture_local_socket(TALLOC_CTX *mem_ctx)
209 {
210         struct torture_suite *suite = torture_suite_create(mem_ctx, 
211                                                                                                            "LOCAL-SOCKET");
212
213         torture_suite_add_simple_tcase(suite, "udp", test_udp, NULL);
214         torture_suite_add_simple_tcase(suite, "tcp", test_tcp, NULL);
215
216         return suite;
217 }