xref: /original-bsd/usr.sbin/timed/timed/acksend.c (revision f0203ecd)
1 /*
2  * Copyright (c) 1985 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)acksend.c	2.7 (Berkeley) 06/01/90";
10 #endif /* not lint */
11 
12 #include "globals.h"
13 #include <protocols/timed.h>
14 
15 #define RECEIVED	0
16 #define LOST	 	1
17 #define SECFORACK	1	/* seconds */
18 #define USECFORACK	0	/* microseconds */
19 #define MAXCOUNT	5
20 
21 struct tsp *answer;
22 
23 /*
24  * Acksend implements reliable datagram transmission by using sequence
25  * numbers and retransmission when necessary.
26  * `name' is the name of the destination
27  * `addr' is the address to send to
28  * If `name' is ANYADDR, this routine implements reliable broadcast.
29  */
30 
31 struct tsp *acksend(message, addr, name, ack, net)
32 struct tsp *message;
33 struct sockaddr_in *addr;
34 char *name;
35 int ack;
36 struct netinfo *net;
37 {
38 	int count;
39 	int flag;
40 	extern u_short sequence;
41 	struct timeval tout;
42 	struct tsp *readmsg();
43 
44 	count = 0;
45 
46 	message->tsp_vers = TSPVERSION;
47 	message->tsp_seq = sequence;
48 	if (trace) {
49 		fprintf(fd, "acksend: ");
50 		if (name == ANYADDR)
51 			fprintf(fd, "broadcast: ");
52 		else
53 			fprintf(fd, "%s: ", name);
54 		print(message, addr);
55 	}
56 	bytenetorder(message);
57 	do {
58 		if (sendto(sock, (char *)message, sizeof(struct tsp), 0, addr,
59 		    sizeof(struct sockaddr_in)) < 0) {
60 			syslog(LOG_ERR, "acksend: sendto: %m");
61 			exit(1);
62 		}
63 		tout.tv_sec = SECFORACK;
64 		tout.tv_usec = USECFORACK;
65 		answer  = readmsg(ack, name, &tout, net);
66 		if (answer != NULL) {
67 			if (answer->tsp_seq != sequence) {
68 				if (trace)
69 					fprintf(fd, "acksend: seq # %d != %d\n",
70 					    answer->tsp_seq, sequence);
71 				continue;
72 			}
73 			flag = RECEIVED;
74 		} else {
75 			flag = LOST;
76 			if (++count == MAXCOUNT) {
77 				break;
78 			}
79 		}
80 	} while (flag != RECEIVED);
81 	sequence++;
82 	return(answer);
83 }
84