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] */