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