/* * Copyright (c) 2002-2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: t-net-0.c,v 1.24 2005/05/31 21:00:28 ca Exp $") #include "sm/assert.h" #include "sm/error.h" #include "sm/test.h" #include "sm/io.h" #include "sm/ctype.h" #include "smi-net.h" #include "sm/unixsock.h" #include "timing.h" #include #define SM_CHECK_NET_UNIX 1 static char *nsocket = "./cltsrv"; #include "t-net-common.c" /* ** CLIENT -- write wr characters to localhost:port ** ** Parameters: ** ip -- IP address to use ** port -- port ** wr -- number of chars to send ** delay -- sleep time before close ** bsize -- buffer size to use ** timeout -- timeout ** both -- if >0: do write and read ("both" times) ** sets double buffering ** iter -- number of iterations (writing data) ** net -- use an INET (or LOCAL) socket ** ** Returns: ** none */ static void client(char *ip, int port, int wr, int delay, int bsize, int timeout, int both, int iter, bool net) { int fd; sm_ret_T ret; if (Verbose > 1) fprintf(stderr, "clt: connect\n"); if (net) (void) net_client_connect(ip, port, &fd); else (void) unix_client_connect(nsocket, &fd); if (Verbose > 1) fprintf(stderr, "clt: connected=%d\n", fd); SM_TEST(fd >= 0); if (fd < 0) return; while (iter-- > 0) { ret = write_sock(fd, wr, delay, bsize, timeout, both); SM_TEST(sm_is_success(ret)); if (!sm_is_success(ret)) { if (Verbose > 0) fprintf(stderr, "client: error %x\n", ret); return; } } } /* ** SERVER -- receive rd characters on localhost:port ** ** Parameters: ** ip -- IP address to use ** port -- port ** rd -- number of chars to receive ** rep -- loop through all of this rep times ** delay -- sleep time before close ** bsize -- buffer size to use ** backlog -- size of listen queue ** timeout -- timeout ** both -- if >0: do write and read ("both" times) ** sets double buffering ** iter -- number of iterations (reading data) ** net -- use an INET (or LOCAL) socket ** ** Returns: ** none */ static void server(char *ip, int port, int rd, int rep, int delay, int bsize, int backlog, int timeout, int both, int iter, bool net) { int fd, lfd; sm_ret_T res; struct sockaddr addr; sockaddr_len_T addrlen; res = 0; lfd = fd = -1; if (net) lfd = netserverlisten(ip, port, backlog); else lfd = unix_server_listen(nsocket, 10); SM_TEST(lfd >= 0); if (lfd < 0) return; while (rep-- > 0) { addrlen = sizeof(addr); if (Verbose > 1) fprintf(stderr, "srv: accept\n"); if (net) fd = net_server_accept(lfd, &addr, &addrlen); else fd = unix_server_accept(lfd, &addr, &addrlen); SM_TEST(fd >= 0); if (fd < 0) goto err; while (iter-- > 0) { res = read_sock(fd, rd, delay, bsize, timeout, both); if (sm_is_err(res)) goto err; } fd = -1; if (Verbose > 0) fprintf(stderr, "srv: read_sock done=%x\n", res); if (sm_is_err(res)) goto err; } err: if (fd >= 0) close(fd); if (lfd >= 0) close(lfd); } int main(int argc, char *argv[]) { bool clt, any; int c, port, rd, wr, rep, delay, backlog, bsize, timeout, both, iter; char *ip; bool net; sm_ret_T res; opterr = 0; clt = true; any = false; port = SM_DEFPORT; rd = wr = 0; rep = 1; delay = 0; bsize = 0; backlog = 20; timeout = 5; Verbose = 0; both = 0; iter = 1; ip = "127.0.0.1"; net = true; while ((c = getopt(argc, argv, "b:Bc:d:i:I:l:p:r:R:s:St:TuU:V")) != -1) { any = true; switch (c) { case 'B': both++; break; case 'b': bsize = atoi(optarg); break; case 'c': clt = true; wr = atoi(optarg); break; case 'd': delay = atoi(optarg); break; case 'i': iter = atoi(optarg); break; case 'I': ip = strdup(optarg); if (ip == NULL) { fprintf(stderr, "out of memory"); return 1; } break; case 'l': backlog = atoi(optarg); break; case 'p': port = atoi(optarg); break; case 'r': rep = atoi(optarg); break; case 'R': both = atoi(optarg); break; case 's': clt = false; rd = atoi(optarg); break; case 't': timeout = atoi(optarg); break; case 'u': net = false; break; case 'S': fprintf(stderr, "sizeof sm_file_T: %d\n", sizeof(sm_file_T)); fprintf(stderr, "sizeof sm_stream_T: %d\n", sizeof(sm_stream_T)); fprintf(stderr, "sizeof smbuf_T: %d\n", sizeof(smbuf_T)); break; case 'T': Timing = true; break; case 'U': nsocket = strdup(optarg); if (nsocket == NULL) { fprintf(stderr, "out of memory"); return 1; } break; case 'V': ++Verbose; break; default: usage(argv[0]); return 1; } } sm_test_begin(argc, argv, "test net 0"); res = net_startup(); SM_TEST(sm_is_success(res)); if (!sm_is_success(res)) return sm_test_end(); if (!any) goto end; if (clt) client(ip, port, wr, delay, bsize, timeout, both, iter, net); else { (void) unlink(nsocket); server(ip, port, rd, rep, delay, bsize, backlog, timeout, both, iter, net); } end: net_shutdown(); (void) unlink(nsocket); return sm_test_end(); }