xref: /original-bsd/usr.sbin/timed/timed/acksend.c (revision 92a0c623)
1 /*-
2  * Copyright (c) 1985, 1993 The 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	5.1 (Berkeley) 05/11/93";
10 #endif /* not lint */
11 
12 #ifdef sgi
13 #ident "$Revision: 1.6 $"
14 #endif
15 
16 #include "globals.h"
17 
18 struct tsp *answer;
19 
20 extern u_short sequence;
21 
22 void
23 xmit(type, seq, addr)
24 	int type;
25 	u_int seq;
26 	struct sockaddr_in *addr;
27 {
28 	static struct tsp msg;
29 
30 	msg.tsp_type = type;
31 	msg.tsp_seq = seq;
32 	msg.tsp_vers = TSPVERSION;
33 	(void)strcpy(msg.tsp_name, hostname);
34 	bytenetorder(&msg);
35 	if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0,
36 		   (struct sockaddr*)addr, sizeof(struct sockaddr)) < 0) {
37 		trace_sendto_err(addr->sin_addr);
38 	}
39 }
40 
41 
42 /*
43  * Acksend implements reliable datagram transmission by using sequence
44  * numbers and retransmission when necessary.
45  * If `name' is ANYADDR, this routine implements reliable broadcast.
46  *
47  * Because this function calls readmsg(), none of its args may be in
48  *	a message provided by readmsg().
49  */
50 struct tsp *
51 acksend(message, addr, name, ack, net, bad)
52 	struct tsp *message;			/* this message */
53 	struct sockaddr_in *addr;		/* to here */
54 	char *name;
55 	int ack;				/* look for this ack */
56 	struct netinfo *net;			/* receive from this network */
57 	int bad;				/* 1=losing patience */
58 {
59 	struct timeval twait;
60 	int count;
61 	long msec;
62 
63 	message->tsp_vers = TSPVERSION;
64 	message->tsp_seq = sequence;
65 	if (trace) {
66 		fprintf(fd, "acksend: to %s: ",
67 			(name == ANYADDR ? "broadcast" : name));
68 		print(message, addr);
69 	}
70 	bytenetorder(message);
71 
72 	msec = 200;
73 	count = bad ? 1 : 5;	/* 5 packets in 6.4 seconds */
74 	answer = 0;
75 	do {
76 		if (!answer) {
77 			/* do not go crazy transmitting just because the
78 			 * other guy cannot keep our sequence numbers
79 			 * straight.
80 			 */
81 			if (sendto(sock, (char *)message, sizeof(struct tsp),
82 				   0, (struct sockaddr*)addr,
83 				   sizeof(struct sockaddr)) < 0) {
84 				trace_sendto_err(addr->sin_addr);
85 				break;
86 			}
87 		}
88 
89 		mstotvround(&twait, msec);
90 		answer  = readmsg(ack, name, &twait, net);
91 		if (answer != 0) {
92 			if (answer->tsp_seq != sequence) {
93 				if (trace)
94 					fprintf(fd,"acksend: seq # %u!=%u\n",
95 						answer->tsp_seq, sequence);
96 				continue;
97 			}
98 			break;
99 		}
100 
101 		msec *= 2;
102 	} while (--count > 0);
103 	sequence++;
104 
105 	return(answer);
106 }
107