tests/sk/sk_write_timeout.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- write_fully
- main
1 /*
2 this test verifies that the server times out on socket write
3
4 the scenerio is this:
5 1. connect to server
6 2. perform a query (any type of query *should* be sufficient as they
7 all use SK_cd_puts(), which all use SK_puts, which all use
8 SK_write()) that produces LOTS of output - I use "schultz" which
9 produces over 250 Kbyte of data
10 3. wait for a long time (longer than defined in rip.config, currently
11 180 seconds)
12 4. try to write (first one should work)
13 5. try to write again (should notice the closed socket and fail)
14
15 shane, 2001-06-05
16 */
17
18 #include <stdio.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <netinet/tcp.h>
23 #include <netdb.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <time.h>
28 #include <signal.h>
29
30 /* timeout in seconds */
31 #define TIMEOUT 180
32
33 /* query string */
34 #define QUERY "schultz\015\012"
35
36 /* write to a socket */
37 int
38 write_fully(int fd, const char *buf, int buflen)
/* [<][>][^][v][top][bottom][index][help] */
39 {
40 int write_ret;
41 int amt_written;
42
43 amt_written = 0;
44 while (amt_written < buflen) {
45 write_ret = write(fd, buf+amt_written, buflen-amt_written);
46 if (write_ret <= 0) {
47 return write_ret;
48 }
49 amt_written += write_ret;
50 }
51 return amt_written;
52 }
53
54 int
55 main(int argc, char *argv[])
/* [<][>][^][v][top][bottom][index][help] */
56 {
57 const char *server;
58 int port;
59 struct sockaddr_in addr;
60 struct hostent *h;
61 int fd;
62 int opt_val;
63 time_t end_time;
64 struct protoent *proto;
65
66 /* get server name from command line, if specified */
67 if (argc > 1) {
68 server = argv[1];
69 } else {
70 server = "whois.ripe.net";
71 }
72
73 /* get server port from command line, if specified */
74 if (argc > 2) {
75 port = atoi(argv[2]);
76 } else {
77 port = 43;
78 }
79
80 /* figure out server address */
81 memset(&addr, 0, sizeof(struct sockaddr_in));
82 addr.sin_family = AF_INET;
83 addr.sin_addr.s_addr = inet_addr(server);
84 if (addr.sin_addr.s_addr == -1) {
85 h = gethostbyname(server);
86 if (h == NULL) {
87 printf("ERROR: unable to get server address, h_errno=%d\n",h_errno);
88 exit(1);
89 }
90 memcpy(&addr.sin_addr, h->h_addr, sizeof(addr.sin_addr));
91 }
92 addr.sin_port = htons(port);
93
94 /* block signal on write */
95 signal(SIGPIPE, SIG_IGN);
96
97 /* create socket */
98 fd = socket(AF_INET, SOCK_STREAM, 0);
99 if (fd == -1) {
100 printf("ERROR: unable to create socket, errno=%d\n", errno);
101 exit(1);
102 }
103
104 /* disable Nagle's algorithm */
105 proto = getprotobyname("tcp");
106 if (proto == NULL) {
107 printf("ERROR: unable to get TCP protocol number\n");
108 exit(1);
109 }
110 opt_val = 0;
111 if (setsockopt(fd, proto->p_proto, TCP_NODELAY, &opt_val, sizeof(int)) != 0)
112 {
113 printf("ERROR: unable to disable TCP delay, errno=%d\n", errno);
114 exit(1);
115 }
116
117 /* connect to server */
118 if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0){
119 printf("ERROR: unable to connect to server, errno=%d\n", errno);
120 exit(1);
121 }
122
123 /* send query */
124 if (write_fully(fd, QUERY, sizeof(QUERY)-1) != (sizeof(QUERY)-1)) {
125 printf("ERROR: unable to send query string, errno=%d\n", errno);
126 exit(1);
127 }
128
129 /* wait for hangup */
130 sleep(TIMEOUT);
131
132 end_time = time(NULL) + TIMEOUT;
133 do {
134 /* try to write */
135 if (write_fully(fd, QUERY, sizeof(QUERY)-1) != (sizeof(QUERY)-1)) {
136 if (errno != EPIPE) {
137 printf("ERROR: unable to query server, errno=%d\n", errno);
138 exit(1);
139 } else {
140 /*
141 * THIS IS OUR SUCCESS CASE!!!
142 */
143 printf("SUCCESS: server dropped our connection\n");
144 exit(0);
145 }
146 }
147
148 /* wait some more time */
149 sleep(1);
150 } while (time(NULL) < end_time);
151
152 printf("ERROR: server never hung up\n");
153 return(1);
154 }
155
156