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