## tests/sk/sk_write_timeout.c

/* [<][>][^][v][top][bottom][index][help] */

## DEFINITIONS

This source file includes following functions.

1. write_fully
2. 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

/* [<][>][^][v][top][bottom][index][help] */