r8520: fixed a pile of warnings from the build farm gcc -Wall output on
[jra/samba/.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
27 #define CHECK_STATUS(status, correct) do { \
28         if (!NT_STATUS_EQUAL(status, correct)) { \
29                 printf("(%s) Incorrect status %s - should be %s\n", \
30                        __location__, nt_errstr(status), nt_errstr(correct)); \
31                 ret = False; \
32                 goto done; \
33         }} while (0)
34
35
36 /*
37   basic testing of udp routines
38 */
39 static BOOL test_udp(TALLOC_CTX *mem_ctx)
40 {
41         struct socket_context *sock1, *sock2;
42         NTSTATUS status;
43         int srv_port, from_port;
44         const char *srv_addr, *from_addr;
45         size_t size = 100 + (random() % 100);
46         DATA_BLOB blob, blob2;
47         size_t sent, nread;
48         BOOL ret = True;
49
50         printf("TESTING UDP SOCKETS\n");
51
52         status = socket_create("ip", SOCKET_TYPE_DGRAM, &sock1, 0);
53         CHECK_STATUS(status, NT_STATUS_OK);
54         talloc_steal(mem_ctx, sock1);
55
56         status = socket_create("ip", SOCKET_TYPE_DGRAM, &sock2, 0);
57         CHECK_STATUS(status, NT_STATUS_OK);
58         talloc_steal(mem_ctx, sock2);
59
60         status = socket_listen(sock1, "127.0.0.1", 0, 0, 0);
61         CHECK_STATUS(status, NT_STATUS_OK);
62
63         srv_addr = socket_get_my_addr(sock1, mem_ctx);
64         if (srv_addr == NULL || strcmp(srv_addr, "127.0.0.1") != 0) {
65                 printf("Expected server address of 127.0.0.1 but got %s\n", srv_addr);
66                 return False;
67         }
68
69         srv_port = socket_get_my_port(sock1);
70         printf("server port is %d\n", srv_port);
71
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);
75
76         sent = size;
77         status = socket_sendto(sock2, &blob, &sent, 0, srv_addr, srv_port);
78         CHECK_STATUS(status, NT_STATUS_OK);
79
80         status = socket_recvfrom(sock1, blob2.data, size, &nread, 0, 
81                                  &from_addr, &from_port);
82         CHECK_STATUS(status, NT_STATUS_OK);
83
84         if (strcmp(from_addr, srv_addr) != 0) {
85                 printf("Unexpected recvfrom addr %s\n", from_addr);
86                 ret = False;
87         }
88         if (nread != size) {
89                 printf("Unexpected recvfrom size %d should be %d\n", (int)nread, (int)size);
90                 ret = False;
91         }
92
93         if (memcmp(blob2.data, blob.data, size) != 0) {
94                 printf("Bad data in recvfrom\n");
95                 ret = False;
96         }
97
98         generate_random_buffer(blob.data, blob.length);
99         status = socket_sendto(sock1, &blob, &sent, 0, from_addr, from_port);
100         CHECK_STATUS(status, NT_STATUS_OK);
101
102         status = socket_recvfrom(sock2, blob2.data, size, &nread, 0, 
103                                  &from_addr, &from_port);
104         CHECK_STATUS(status, NT_STATUS_OK);
105         if (strcmp(from_addr, srv_addr) != 0) {
106                 printf("Unexpected recvfrom addr %s\n", from_addr);
107                 ret = False;
108         }
109         if (nread != size) {
110                 printf("Unexpected recvfrom size %d should be %d\n", (int)nread, (int)size);
111                 ret = False;
112         }
113         if (from_port != srv_port) {
114                 printf("Unexpected recvfrom port %d should be %d\n", 
115                        from_port, srv_port);
116                 ret = False;
117         }
118         if (memcmp(blob2.data, blob.data, size) != 0) {
119                 printf("Bad data in recvfrom\n");
120                 ret = False;
121         }
122
123 done:
124         talloc_free(sock1);
125         talloc_free(sock2);
126
127         return ret;
128 }
129
130 /*
131   basic testing of tcp routines
132 */
133 static BOOL test_tcp(TALLOC_CTX *mem_ctx)
134 {
135         struct socket_context *sock1, *sock2, *sock3;
136         NTSTATUS status;
137         int srv_port, from_port;
138         const char *srv_addr, *from_addr;
139         size_t size = 100 + (random() % 100);
140         DATA_BLOB blob, blob2;
141         size_t sent, nread;
142         BOOL ret = True;
143         struct event_context *ev = event_context_init(mem_ctx);
144
145         printf("TESTING TCP SOCKETS\n");
146
147         status = socket_create("ip", SOCKET_TYPE_STREAM, &sock1, 0);
148         CHECK_STATUS(status, NT_STATUS_OK);
149         talloc_steal(mem_ctx, sock1);
150
151         status = socket_create("ip", SOCKET_TYPE_STREAM, &sock2, 0);
152         CHECK_STATUS(status, NT_STATUS_OK);
153         talloc_steal(mem_ctx, sock2);
154
155         status = socket_listen(sock1, "127.0.0.1", 0, 0, 0);
156         CHECK_STATUS(status, NT_STATUS_OK);
157
158         srv_addr = socket_get_my_addr(sock1, mem_ctx);
159         if (srv_addr == NULL || strcmp(srv_addr, "127.0.0.1") != 0) {
160                 printf("Expected server address of 127.0.0.1 but got %s\n", srv_addr);
161                 return False;
162         }
163
164         srv_port = socket_get_my_port(sock1);
165         printf("server port is %d\n", srv_port);
166
167         status = socket_connect_ev(sock2, NULL, 0, srv_addr, srv_port, 0, ev);
168         CHECK_STATUS(status, NT_STATUS_OK);
169
170         status = socket_accept(sock1, &sock3);
171         CHECK_STATUS(status, NT_STATUS_OK);
172         talloc_steal(mem_ctx, sock3);
173         talloc_free(sock1);
174
175         blob  = data_blob_talloc(mem_ctx, NULL, size);
176         blob2 = data_blob_talloc(mem_ctx, NULL, size);
177         generate_random_buffer(blob.data, blob.length);
178
179         sent = size;
180         status = socket_send(sock2, &blob, &sent, 0);
181         CHECK_STATUS(status, NT_STATUS_OK);
182
183         status = socket_recv(sock3, blob2.data, size, &nread, 0);
184         CHECK_STATUS(status, NT_STATUS_OK);
185
186         from_addr = socket_get_peer_addr(sock3, mem_ctx);
187         from_port = socket_get_peer_port(sock3);
188
189         if (strcmp(from_addr, srv_addr) != 0) {
190                 printf("Unexpected recvfrom addr %s\n", from_addr);
191                 ret = False;
192         }
193         if (nread != size) {
194                 printf("Unexpected recvfrom size %d should be %d\n", (int)nread, (int)size);
195                 ret = False;
196         }
197
198         if (memcmp(blob2.data, blob.data, size) != 0) {
199                 printf("Bad data in recvfrom\n");
200                 ret = False;
201         }
202
203         generate_random_buffer(blob.data, blob.length);
204         status = socket_send(sock3, &blob, &sent, 0);
205         CHECK_STATUS(status, NT_STATUS_OK);
206
207         status = socket_recv(sock2, blob2.data, size, &nread, 0);
208         CHECK_STATUS(status, NT_STATUS_OK);
209
210         from_addr = socket_get_peer_addr(sock2, mem_ctx);
211         from_port = socket_get_peer_port(sock2);
212
213         if (strcmp(from_addr, srv_addr) != 0) {
214                 printf("Unexpected recvfrom addr %s\n", from_addr);
215                 ret = False;
216         }
217         if (nread != size) {
218                 printf("Unexpected recvfrom size %d should be %d\n", (int)nread, (int)size);
219                 ret = False;
220         }
221         if (from_port != srv_port) {
222                 printf("Unexpected recvfrom port %d should be %d\n", 
223                        from_port, srv_port);
224                 ret = False;
225         }
226         if (memcmp(blob2.data, blob.data, size) != 0) {
227                 printf("Bad data in recvfrom\n");
228                 ret = False;
229         }
230
231 done:
232
233         return ret;
234 }
235
236 BOOL torture_local_socket(void) 
237 {
238         BOOL ret = True;
239         TALLOC_CTX *mem_ctx = talloc_new(NULL);
240
241         ret &= test_udp(mem_ctx);
242         ret &= test_tcp(mem_ctx);
243
244         return ret;
245 }