1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)acksend.c 1.1 (Berkeley) 06/22/85"; 9 #endif not lint 10 11 #include "globals.h" 12 #include <protocols/timed.h> 13 14 #define RECEIVED 0 15 #define LOST 1 16 #define SECFORACK 1 /* seconds */ 17 #define USECFORACK 0 /* microseconds */ 18 #define MAXCOUNT 5 19 20 struct tsp *answer; 21 extern int sock; 22 extern struct sockaddr_in server; 23 24 /* 25 * Acksend implements reliable datagram transmission by using sequence 26 * numbers and retransmission when necessary. 27 * `name' is set to name of destination whose address is in global 28 * variable `server'. 29 * If `name' is ANYADDR, this routine implements reliable broadcast. 30 */ 31 32 struct tsp *acksend(message, name, ack) 33 struct tsp *message; 34 char *name; 35 int ack; 36 { 37 int count; 38 int flag; 39 extern u_short sequence; 40 struct timeval tout; 41 struct tsp *readmsg(); 42 int bytenetorder(); 43 44 count = 0; 45 46 do { 47 message->tsp_seq = sequence; 48 if (name == ANYADDR) { 49 broadcast(message); 50 } else { 51 message->tsp_vers = TSPVERSION; 52 bytenetorder(message); 53 if (sendto(sock, (char *)message, sizeof(struct tsp), 54 0, &server, 55 sizeof(struct sockaddr_in)) < 0) { 56 syslog(LOG_ERR, "timed: sendto: %m"); 57 exit(1); 58 } 59 } 60 tout.tv_sec = SECFORACK; 61 tout.tv_usec = USECFORACK; 62 answer = readmsg(ack, name, &tout); 63 if (answer != NULL) { 64 flag = RECEIVED; 65 } else { 66 flag = LOST; 67 if (++count == MAXCOUNT) { 68 break; 69 } 70 } 71 } while (flag != RECEIVED); 72 if (++sequence > MAXSEQ) 73 sequence = 1; 74 return(answer); 75 } 76