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 the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)acksend.c 2.6 (Berkeley) 06/18/88"; 20 #endif /* not lint */ 21 22 #include "globals.h" 23 #include <protocols/timed.h> 24 25 #define RECEIVED 0 26 #define LOST 1 27 #define SECFORACK 1 /* seconds */ 28 #define USECFORACK 0 /* microseconds */ 29 #define MAXCOUNT 5 30 31 struct tsp *answer; 32 33 /* 34 * Acksend implements reliable datagram transmission by using sequence 35 * numbers and retransmission when necessary. 36 * `name' is the name of the destination 37 * `addr' is the address to send to 38 * If `name' is ANYADDR, this routine implements reliable broadcast. 39 */ 40 41 struct tsp *acksend(message, addr, name, ack, net) 42 struct tsp *message; 43 struct sockaddr_in *addr; 44 char *name; 45 int ack; 46 struct netinfo *net; 47 { 48 int count; 49 int flag; 50 extern u_short sequence; 51 struct timeval tout; 52 struct tsp *readmsg(); 53 54 count = 0; 55 56 message->tsp_vers = TSPVERSION; 57 message->tsp_seq = sequence; 58 if (trace) { 59 fprintf(fd, "acksend: "); 60 if (name == ANYADDR) 61 fprintf(fd, "broadcast: "); 62 else 63 fprintf(fd, "%s: ", name); 64 print(message, addr); 65 } 66 bytenetorder(message); 67 do { 68 if (sendto(sock, (char *)message, sizeof(struct tsp), 0, addr, 69 sizeof(struct sockaddr_in)) < 0) { 70 syslog(LOG_ERR, "acksend: sendto: %m"); 71 exit(1); 72 } 73 tout.tv_sec = SECFORACK; 74 tout.tv_usec = USECFORACK; 75 answer = readmsg(ack, name, &tout, net); 76 if (answer != NULL) { 77 if (answer->tsp_seq != sequence) { 78 if (trace) 79 fprintf(fd, "acksend: seq # %d != %d\n", 80 answer->tsp_seq, sequence); 81 continue; 82 } 83 flag = RECEIVED; 84 } else { 85 flag = LOST; 86 if (++count == MAXCOUNT) { 87 break; 88 } 89 } 90 } while (flag != RECEIVED); 91 sequence++; 92 return(answer); 93 } 94