root/common/trunk/tests/test_net_udp.c @ 3932

Revision 3932, 12.9 KB (checked in by ucacsva, 7 years ago)

commit_msg_15Nov2006.txt

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * FILE:    test_net_udp.c
3 * AUTHORS: Colin Perkins
4 *
5 * Copyright (c) 2000 University College London
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, is permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *      This product includes software developed by the Computer Science
19 *      Department at University College London
20 * 4. Neither the name of the University nor of the Department may be used
21 *    to endorse or promote products derived from this software without
22 *    specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include "config_unix.h"
37#include "config_win32.h"
38#include "debug.h"
39#include "net_udp.h"
40#include "test_net_udp.h"
41
42#define BUFSIZE 1024
43
44static void randomize(char buf[], int buflen)
45{
46        int     i;
47
48        for (i = 0; i < buflen; i++) {
49                buf[i] = (lrand48() && 0xff00) >> 8;
50        }
51}
52
53void test_net_udp(void)
54{
55        struct timeval   timeout;
56        socket_udp      *s1, *s2;
57        char             buf1[BUFSIZE], buf2[BUFSIZE];
58        const char      *hname;
59        int              rc, i;
60        fd_set           rfd;
61        fd_t             max_fd;
62
63       
64#ifndef WIN32
65
66        /* "BSD" bug test that appears in this function uses fork and
67         * exec, that are not present on WIN32.  Since the original
68         * bug has not been seen on Win32 it's probably not worth
69         * converting to use CreateProcess() */
70
71        int status_parent, status_child;
72
73#endif /* WIN32 */
74
75        srand48(time(NULL));
76
77        /**********************************************************************/
78        /* The first test is to loopback a packet to ourselves...             */
79        printf("UDP/IP networking (IPv4 loopback)...... "); fflush(stdout);
80        s1 = udp_init("127.0.0.1", 5000, 5000, 1);
81        if (s1 == NULL) {
82                printf("fail: cannot initialize socket\n");
83                return;
84        }
85        randomize(buf1, BUFSIZE);
86        randomize(buf2, BUFSIZE);
87        if (udp_send(s1, buf1, BUFSIZE) < 0) {
88                perror("fail");
89                goto abort_loopback;
90        }
91        timeout.tv_sec  = 1;
92        timeout.tv_usec = 0;
93        udp_fd_zero( &rfd, &max_fd );
94        udp_fd_set( &rfd, &max_fd, s1 );
95        rc = udp_select(&rfd, max_fd, &timeout);
96        if (rc < 0) {
97                perror("fail");
98                goto abort_loopback;
99        }
100        if (rc == 0) {
101                printf("fail: no data waiting\n");
102                goto abort_loopback;
103        }
104        if (!udp_fd_isset(&rfd, &max_fd, s1)) {
105                printf("fail: no data on file descriptor\n");
106                goto abort_loopback;
107        }
108        if (udp_recv(s1, buf2, BUFSIZE) < 0) {
109                perror("fail");
110                goto abort_loopback;
111        }
112        if (memcmp(buf1, buf2, BUFSIZE) != 0) {
113                printf("fail: buffer corrupt\n");
114                goto abort_loopback;
115        }
116        printf("pass\n");
117abort_loopback:
118        hname = udp_host_addr(s1); /* we need this for the unicast test... */
119        udp_exit(s1);
120
121        /**********************************************************************/
122        /* Now we send a packet to ourselves via our real network address...  */
123        printf("UDP/IP networking (IPv4 unicast)....... "); fflush(stdout);
124        s1 = udp_init(hname, 5000, 5001, 1);
125        if (s1 == NULL) {
126                printf("fail: cannot initialize socket\n");
127                return;
128        }
129
130        s2 = udp_init(hname, 5001, 5000, 1);
131        if (s2 == NULL) {
132                printf("fail: cannot initialize socket\n");
133                return;
134        }
135
136        randomize(buf1, BUFSIZE);
137        randomize(buf2, BUFSIZE);
138        if (udp_send(s1, buf1, BUFSIZE) < 0) {
139                perror("fail");
140                goto abort_unicast;
141        }
142        timeout.tv_sec  = 1;
143        timeout.tv_usec = 0;
144        udp_fd_zero( &rfd, &max_fd );
145        udp_fd_set( &rfd, &max_fd, s1 );
146        udp_fd_set( &rfd, &max_fd, s2 );
147        rc = udp_select(&rfd, max_fd, &timeout);
148        if (rc < 0) {
149                perror("fail");
150                goto abort_unicast;
151        }
152        if (rc == 0) {
153                printf("fail: no data waiting (no route to %s?)\n", hname);
154                goto abort_unicast;
155        }
156        if (!udp_fd_isset(&rfd, &max_fd, s2)) {
157                printf("fail: no data on file descriptor\n");
158                goto abort_unicast;
159        }
160        if (udp_recv(s2, buf2, BUFSIZE) < 0) {
161                perror("fail");
162                goto abort_unicast;
163        }
164        if (memcmp(buf1, buf2, BUFSIZE) != 0) {
165                printf("fail: buffer corrupt\n");
166                goto abort_unicast;
167        }
168        printf("pass\n");
169abort_unicast:
170        udp_exit(s1);
171        udp_exit(s2);
172
173        /**********************************************************************/
174        /* Loopback a packet to ourselves via multicast...                    */
175        printf("UDP/IP networking (IPv4 multicast)..... "); fflush(stdout);
176        s1 = udp_init("224.2.0.1", 5000, 5000, 1);
177        if (s1 == NULL) {
178                printf("fail: cannot initialize socket\n");
179                return;
180        }
181        randomize(buf1, BUFSIZE);
182        randomize(buf2, BUFSIZE);
183        if (udp_send(s1, buf1, BUFSIZE) < 0) {
184                perror("fail");
185                goto abort_multicast;
186        }
187        timeout.tv_sec  = 1;
188        timeout.tv_usec = 0;
189        udp_fd_zero( &rfd, &max_fd );
190        udp_fd_set( &rfd, &max_fd, s1 );
191        rc = udp_select(&rfd, max_fd, &timeout);
192        if (rc < 0) {
193                perror("fail");
194                goto abort_multicast;
195        }
196        if (rc == 0) {
197                printf("fail: no data waiting (no multicast loopback route?)\n");
198                goto abort_multicast;
199        }
200        if (!udp_fd_isset(&rfd, &max_fd, s1)) {
201                printf("fail: no data on file descriptor\n");
202                goto abort_multicast;
203        }
204        if (udp_recv(s1, buf2, BUFSIZE) < 0) {
205                perror("fail");
206                goto abort_multicast;
207        }
208        if (memcmp(buf1, buf2, BUFSIZE) != 0) {
209                printf("fail: buffer corrupt\n");
210                goto abort_multicast;
211        }
212        printf("pass\n");
213abort_multicast:
214        udp_exit(s1);
215
216        /**********************************************************************/
217        /* Loopback a packet to ourselves via multicast, checking lengths...  */
218        printf("UDP/IP networking (IPv4 length check).. "); fflush(stdout);
219        s1 = udp_init("224.2.0.1", 5000, 5000, 1);
220        if (s1 == NULL) {
221                printf("fail: cannot initialize socket\n");
222                return;
223        }
224        for (i = 1; i < BUFSIZE; i++) {
225                randomize(buf1, i);
226                randomize(buf2, i);
227                if (udp_send(s1, buf1, i) < 0) {
228                        perror("fail");
229                        goto abort_length;
230                }
231                timeout.tv_sec  = 1;
232                timeout.tv_usec = 0;
233                udp_fd_zero( &rfd, &max_fd );
234                udp_fd_set( &rfd, &max_fd, s1 );
235                rc = udp_select(&rfd, max_fd, &timeout);
236                if (rc < 0) {
237                        perror("fail");
238                        goto abort_length;
239                }
240                if (rc == 0) {
241                        printf("fail: no data waiting (no multicast loopback route?)\n");
242                        goto abort_length;
243                }
244                if (!udp_fd_isset(&rfd, &max_fd, s1)) {
245                        printf("fail: no data on file descriptor\n");
246                        goto abort_length;
247                }
248                if (udp_recv(s1, buf2, BUFSIZE) != i) {
249                        perror("fail");
250                        goto abort_length;
251                }
252                if (memcmp(buf1, buf2, i) != 0) {
253                        printf("fail: buffer corrupt\n");
254                        goto abort_length;
255                }
256        }
257        printf("pass\n");
258abort_length:
259        udp_exit(s1);
260
261
262
263#ifdef HAVE_IPv6
264        /**********************************************************************/
265        /* The first test is to loopback a packet to ourselves...             */
266        printf("UDP/IP networking (IPv6 loopback)...... "); fflush(stdout);
267        s1 = udp_init("::1", 5000, 5000, 1);
268        if (s1 == NULL) {
269                printf("fail: cannot initialize socket\n");
270                return;
271        }
272        randomize(buf1, BUFSIZE);
273        randomize(buf2, BUFSIZE);
274        if (udp_send(s1, buf1, BUFSIZE) < 0) {
275                perror("fail");
276                goto abort_loopback_ipv6;
277        }
278        timeout.tv_sec  = 1;
279        timeout.tv_usec = 0;
280        udp_fd_zero( &rfd, &max_fd );
281        udp_fd_set( &rfd, &max_fd, s1 );
282        rc = udp_select(&rfd, max_fd, &timeout);
283        if (rc < 0) {
284                perror("fail");
285                goto abort_loopback_ipv6;
286        }
287        if (rc == 0) {
288                printf("fail: no data waiting\n");
289                goto abort_loopback_ipv6;
290        }
291        if (!udp_fd_isset(&rfd, &max_fd, s1)) {
292                printf("fail: no data on file descriptor\n");
293                goto abort_loopback_ipv6;
294        }
295        if (udp_recv(s1, buf2, BUFSIZE) < 0) {
296                perror("fail");
297                goto abort_loopback_ipv6;
298        }
299        if (memcmp(buf1, buf2, BUFSIZE) != 0) {
300                printf("fail: buffer corrupt\n");
301                goto abort_loopback_ipv6;
302        }
303        printf("pass\n");
304abort_loopback_ipv6:
305        udp_exit(s1);
306
307        /**********************************************************************/
308        /* Loopback a packet to ourselves via multicast. The address is the   */
309        /* SAP address, but we use a different port.                          */
310        printf("UDP/IP networking (IPv6 multicast)..... "); fflush(stdout);
311        s1 = udp_init("ff01::2:7ffe", 5000, 5000, 1);
312        if (s1 == NULL) {
313                printf("fail: cannot initialize socket\n");
314                return;
315        }
316        randomize(buf1, BUFSIZE);
317        randomize(buf2, BUFSIZE);
318        if (udp_send(s1, buf1, BUFSIZE) < 0) {
319                perror("fail");
320                goto abort_multicast_ipv6;
321        }
322        timeout.tv_sec  = 1;
323        timeout.tv_usec = 0;
324        udp_fd_zero( &rfd, &max_fd );
325        udp_fd_set( &rfd, &max_fd, s1 );
326        rc = udp_select(&rfd, max_fd, &timeout);
327        if (rc < 0) {
328                perror("fail");
329                goto abort_multicast_ipv6;
330        }
331        if (rc == 0) {
332                printf("fail: no data waiting (no multicast loopback route?)\n");
333                goto abort_multicast_ipv6;
334        }
335        if (!udp_fd_isset(&rfd, &max_fd, s1)) {
336                printf("fail: no data on file descriptor\n");
337                goto abort_multicast_ipv6;
338        }
339        if (udp_recv(s1, buf2, BUFSIZE) < 0) {
340                perror("fail");
341                goto abort_multicast_ipv6;
342        }
343        if (memcmp(buf1, buf2, BUFSIZE) != 0) {
344                printf("fail: buffer corrupt\n");
345                goto abort_multicast_ipv6;
346        }
347        hname = udp_host_addr(s1); /* we need this for the unicast test... */
348        printf("pass\n");
349abort_multicast_ipv6:
350        udp_exit(s1);
351#else
352        printf("UDP/IP networking (IPv6 loopback)...... disabled\n");
353        printf("UDP/IP networking (IPv6 unicast)....... disabled\n");
354        printf("UDP/IP networking (IPv6 multicast)..... disabled\n");
355#endif
356
357        /**********************************************************************/
358
359#ifdef WIN32
360        printf("UDP/IP networking (FreeBSD bug)........ disabled\n");
361#else
362        printf("UDP/IP networking (FreeBSD bug)........ "); fflush(stdout);
363        status_parent = 0;
364        randomize(buf1, 64);
365        s1 = udp_init("224.2.0.1", 5000, 5000, 1);
366        if (s1 == NULL) {
367                printf("fail (parent): cannot initialize socket\n");
368                return;
369        }
370        rc = fork();
371        if (rc == -1) {
372                printf("fail: cannot fork\n");
373                goto abort_bsd;
374        } else if (rc == 0) {
375                /* child */
376                s2 = udp_init("224.2.0.1", 5000, 5000, 1);
377                if (s2 == NULL) {
378                        printf("fail (child): cannot initialize socket\n");
379                        exit(0);
380                }
381                if (udp_send(s2, buf1, 64) < 0) {
382                        perror("fail (child)");
383                        exit(0);
384                }
385                timeout.tv_sec  = 10;
386                timeout.tv_usec = 0;
387                udp_fd_zero( &rfd, &max_fd );
388                udp_fd_set( &rfd, &max_fd, s2 );
389                rc = udp_select(&rfd, max_fd, &timeout);
390                if (rc < 0) {
391                        perror("fail (child)");
392                        exit(0);
393                }
394                if (rc == 0) {
395                        printf("fail (child): no data waiting (no multicast loopback route?)\n");
396                        exit(0);
397                }
398                if (!udp_fd_isset(&rfd, &max_fd, s2)) {
399                        printf("fail (child): no data on file descriptor\n");
400                        exit(0);
401                }
402                rc = udp_recv(s2, buf2, BUFSIZE);
403                if (rc < 0) {
404                        perror("fail (child)");
405                        exit(0);
406                }
407                if (rc != 64) {
408                        printf("fail (child): read size incorrect (%d != %d)\n", rc, 64);
409                        exit(0);
410                }
411                if (memcmp(buf1, buf2, 64) != 0) {
412                        printf("fail (child): buffer corrupt\n");
413                        exit(0);
414                }
415                udp_exit(s2);
416                exit(1);
417        } else {
418                /* parent */
419                timeout.tv_sec  = 10;
420                timeout.tv_usec = 0;
421                udp_fd_zero( &rfd, &max_fd );
422                udp_fd_set( &rfd, &max_fd, s1 );
423                rc = udp_select(&rfd, max_fd, &timeout);
424                if (rc < 0) {
425                        perror("fail (parent)");
426                        goto abort_bsd;
427                }
428                if (rc == 0) {
429                        printf("fail (parent): no data waiting (no multicast loopback route?)\n");
430                        goto abort_bsd;
431                }
432                if (!udp_fd_isset(&rfd, &max_fd, s1)) {
433                        printf("fail (parent): no data on file descriptor\n");
434                        goto abort_bsd;
435                }
436                rc = udp_recv(s1, buf2, BUFSIZE);
437                if (rc < 0) {
438                        perror("fail (parent)");
439                        goto abort_bsd;
440                }
441                if (rc != 64) {
442                        printf("fail (parent): read size incorrect (%d != %d)\n", rc, 64);
443                        goto abort_bsd;
444                }
445                if (memcmp(buf1, buf2, 64) != 0) {
446                        printf("fail (parent): buffer corrupt\n");
447                        goto abort_bsd;
448                }
449                status_parent = 1;
450        }
451abort_bsd:
452        wait(&status_child);
453        if (status_parent && status_child) {
454                printf("pass\n");
455        }
456        udp_exit(s1);
457#endif /* WIN32 */
458
459        return;
460}
Note: See TracBrowser for help on using the browser.