xref: /original-bsd/usr.sbin/timed/timed/acksend.c (revision 53787e02)
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