home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume34 / fsp / part03 / client_lib.c next >
Encoding:
C/C++ Source or Header  |  1992-12-18  |  4.0 KB  |  147 lines

  1.     /*********************************************************************\
  2.     *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  3.     *                                                                     *
  4.     *  You may copy or modify this file in any manner you wish, provided  *
  5.     *  that this notice is always included, and that you hold the author  *
  6.     *  harmless for any loss or damage resulting from the installation or *
  7.     *  use of this software.                                              *
  8.     \*********************************************************************/
  9.  
  10. #include "client_def.h"
  11.  
  12. extern int errno;
  13.  
  14. static int myfd;
  15. static struct sockaddr_in server_addr;
  16. static unsigned short myseq = 0;
  17. static unsigned short key;
  18.  
  19. int client_trace      = 0;
  20. int client_intr_state = 0;
  21. unsigned long target_delay    = 3000L;    /* expected max delay     */
  22. unsigned long busy_delay        = 3000L;    /* busy retransmit timer */
  23. unsigned long idle_delay    = 3000L;    /* idle retransmit timer */
  24. unsigned long udp_sent_time;
  25.  
  26. UBUF *client_interact(cmd,pos,l1,p1,l2,p2)
  27.     unsigned cmd, l1, l2;
  28.     unsigned long pos;
  29.     unsigned char *p1, *p2;
  30. {
  31.     struct sockaddr_in from;
  32.     UBUF sbuf;
  33.     static UBUF rbuf;
  34.     unsigned char *s, *t, *d;
  35.     unsigned u, n, sum, mask, mlen;
  36.     int retval, bytes, retry_send, retry_recv;
  37.     unsigned long w_delay;
  38.  
  39.     sbuf.cmd = cmd;
  40.     sbuf.len = htons(l1);
  41.     sbuf.pos = htonl(pos);
  42.  
  43.     client_intr_state = 1;
  44.  
  45.     for(u = l1, d = (unsigned char *) sbuf.buf; u--; *d++ = *p1++);
  46.     for(u = l2                      ; u--; *d++ = *p2++);
  47.     mlen = d - (unsigned char *) &sbuf;
  48.  
  49.     key = client_get_key();
  50.  
  51.     for(retry_send = 0; ; retry_send++)
  52.     {
  53.     sbuf.key = key;
  54.     sbuf.seq = (myseq & 0xfffc) | (retry_send & 0x0003);
  55.     sbuf.sum = 0;
  56.  
  57.     for(t = (unsigned char *) &sbuf, sum = n = mlen; n--; sum += *t++);
  58.     sbuf.sum = sum + (sum >> 8);
  59.  
  60.     switch(retry_send)    /* adaptive retry delay adjustments */
  61.     {
  62.         case  0: busy_delay = (target_delay+(busy_delay<<3)-busy_delay)>>3;
  63.              w_delay = busy_delay;
  64.              break;
  65.  
  66.         case  1: busy_delay = busy_delay + (busy_delay >> 1);
  67.              w_delay = busy_delay;
  68.              if(client_trace) write(2,"R",1);
  69.              break;
  70.  
  71.         default: if(idle_delay < 5*60*1000) idle_delay = idle_delay << 1;
  72.              w_delay = idle_delay;
  73.              if(client_trace) write(2,"I",1);
  74.              break;
  75.     }
  76.  
  77.     if(sendto(myfd,&sbuf,mlen,0,&server_addr,sizeof(server_addr)) == -1)
  78.                         { perror("sendto"); exit(1); }
  79.     udp_sent_time = time((time_t *) 0);
  80.     mask = 1 << myfd;
  81.  
  82.     for(retry_recv = 0; ; retry_recv++)
  83.     {
  84.         if(retry_recv) write(2,"E",1);
  85.  
  86.         retval = _x_select(&mask, w_delay);
  87.  
  88.         if((retval == -1) && (errno == EINTR)) continue;
  89.  
  90.         if(retval == 1)    /* an incoming message is waiting */
  91.         {
  92.         bytes = sizeof(from);
  93.         if((bytes = recvfrom(myfd,(char*)&rbuf,sizeof(rbuf),0,
  94.                     &from,&bytes)) < UBUF_HSIZE) continue;
  95.  
  96.         s = (unsigned char *) &rbuf;
  97.         d = s + bytes;
  98.         u = rbuf.sum; rbuf.sum = 0;
  99.         for(t = s, sum = 0; t < d; sum += *t++);
  100.         sum = (sum + (sum >> 8)) & 0xff;
  101.         if(sum != u) continue;  /* wrong check sum */
  102.  
  103.         rbuf.len = htons(rbuf.len);
  104.         rbuf.pos = htonl(rbuf.pos);
  105.  
  106.         if((rbuf.seq & 0xfffc) != myseq) continue;  /* wrong seq # */
  107.         if(rbuf.len+UBUF_HSIZE  > bytes) continue;  /* truncated.  */
  108.  
  109.         myseq = (myseq + 0x0004) & 0xfffc;  /* seq for next request */
  110.         key   = rbuf.key;            /* key for next request */
  111.  
  112.         client_put_key(key);
  113.  
  114.         if(client_intr_state == 2)
  115.         {
  116.             if(!key_persists) client_done();
  117.             exit(1);
  118.         }
  119.  
  120.         return(&rbuf);
  121.  
  122.         } else break;   /* go back to re-transmit buffer again */
  123.     }
  124.     }
  125. }
  126.  
  127. init_client(host,port,myport)
  128.     char *host;
  129.     int   port;
  130.     int myport;
  131. {
  132.     busy_delay = idle_delay = target_delay;
  133.  
  134.     if((myfd = _x_udp(&myport)) == -1)
  135.         { perror("socket open"); exit(1); }
  136.  
  137.     if(_x_adr(host,port,&server_addr) == -1)
  138.         { perror("server addr"); exit(1); } 
  139.  
  140.     client_init_key(server_addr.sin_addr.s_addr,port,getpid());
  141. }
  142.  
  143. client_done()
  144. {
  145.     (void) client_interact(CC_BYE,0L,0,NULLP,0,NULLP);
  146. }
  147.