1 /* 2 * Copyright (c) 1985 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that this notice is preserved and that due credit is given 7 * to the University of California at Berkeley. The name of the University 8 * may not be used to endorse or promote products derived from this 9 * software without specific prior written permission. This software 10 * is provided ``as is'' without express or implied warranty. 11 */ 12 13 #ifndef lint 14 static char sccsid[] = "@(#)acksend.c 2.5 (Berkeley) 12/23/87"; 15 #endif /* not lint */ 16 17 #include "globals.h" 18 #include <protocols/timed.h> 19 20 #define RECEIVED 0 21 #define LOST 1 22 #define SECFORACK 1 /* seconds */ 23 #define USECFORACK 0 /* microseconds */ 24 #define MAXCOUNT 5 25 26 struct tsp *answer; 27 28 /* 29 * Acksend implements reliable datagram transmission by using sequence 30 * numbers and retransmission when necessary. 31 * `name' is the name of the destination 32 * `addr' is the address to send to 33 * If `name' is ANYADDR, this routine implements reliable broadcast. 34 */ 35 36 struct tsp *acksend(message, addr, name, ack, net) 37 struct tsp *message; 38 struct sockaddr_in *addr; 39 char *name; 40 int ack; 41 struct netinfo *net; 42 { 43 int count; 44 int flag; 45 extern u_short sequence; 46 struct timeval tout; 47 struct tsp *readmsg(); 48 49 count = 0; 50 51 message->tsp_vers = TSPVERSION; 52 message->tsp_seq = sequence; 53 if (trace) { 54 fprintf(fd, "acksend: "); 55 if (name == ANYADDR) 56 fprintf(fd, "broadcast: "); 57 else 58 fprintf(fd, "%s: ", name); 59 print(message, addr); 60 } 61 bytenetorder(message); 62 do { 63 if (sendto(sock, (char *)message, sizeof(struct tsp), 0, addr, 64 sizeof(struct sockaddr_in)) < 0) { 65 syslog(LOG_ERR, "acksend: sendto: %m"); 66 exit(1); 67 } 68 tout.tv_sec = SECFORACK; 69 tout.tv_usec = USECFORACK; 70 answer = readmsg(ack, name, &tout, net); 71 if (answer != NULL) { 72 if (answer->tsp_seq != sequence) { 73 if (trace) 74 fprintf(fd, "acksend: seq # %d != %d\n", 75 answer->tsp_seq, sequence); 76 continue; 77 } 78 flag = RECEIVED; 79 } else { 80 flag = LOST; 81 if (++count == MAXCOUNT) { 82 break; 83 } 84 } 85 } while (flag != RECEIVED); 86 sequence++; 87 return(answer); 88 } 89