acksend.c revision 330897
1121936Sharti/*-
2121936Sharti * SPDX-License-Identifier: BSD-3-Clause
3121936Sharti *
4121936Sharti * Copyright (c) 1985, 1993
5121936Sharti *	The Regents of the University of California.  All rights reserved.
6121936Sharti *
7121936Sharti * Redistribution and use in source and binary forms, with or without
8121936Sharti * modification, are permitted provided that the following conditions
9121936Sharti * are met:
10121936Sharti * 1. Redistributions of source code must retain the above copyright
11121936Sharti *    notice, this list of conditions and the following disclaimer.
12121936Sharti * 2. Redistributions in binary form must reproduce the above copyright
13121936Sharti *    notice, this list of conditions and the following disclaimer in the
14121936Sharti *    documentation and/or other materials provided with the distribution.
15121936Sharti * 4. Neither the name of the University nor the names of its contributors
16121936Sharti *    may be used to endorse or promote products derived from this software
17121936Sharti *    without specific prior written permission.
18121936Sharti *
19121936Sharti * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20121936Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21121936Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22121936Sharti * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23121936Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24121936Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25121936Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26121936Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27121936Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28121936Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29121936Sharti * SUCH DAMAGE.
30121936Sharti */
31121936Sharti
32121936Sharti#ifndef lint
33121936Sharti#if 0
34121936Shartistatic char sccsid[] = "@(#)acksend.c	8.1 (Berkeley) 6/6/93";
35121936Sharti#endif
36121936Shartistatic const char rcsid[] =
37121936Sharti  "$FreeBSD: stable/11/usr.sbin/timed/timed/acksend.c 330897 2018-03-14 03:19:51Z eadler $";
38121936Sharti#endif /* not lint */
39121936Sharti
40121936Sharti#include "globals.h"
41121936Sharti
42121936Shartistruct tsp *answer;
43121936Sharti
44121936Shartiextern u_short sequence;
45121936Sharti
46121936Shartivoid
47121936Shartixmit(int type, u_int seq, struct sockaddr_in *addr)
48121936Sharti{
49121936Sharti	static struct tsp msg;
50121936Sharti
51121936Sharti	msg.tsp_type = type;
52121936Sharti	msg.tsp_seq = seq;
53121936Sharti	msg.tsp_vers = TSPVERSION;
54121936Sharti	(void)strcpy(msg.tsp_name, hostname);
55121936Sharti	bytenetorder(&msg);
56121936Sharti	if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0,
57121936Sharti		   (struct sockaddr*)addr, sizeof(struct sockaddr)) < 0) {
58121936Sharti		trace_sendto_err(addr->sin_addr);
59121936Sharti	}
60121936Sharti}
61121936Sharti
62121936Sharti
63121936Sharti/*
64121936Sharti * Acksend implements reliable datagram transmission by using sequence
65121936Sharti * numbers and retransmission when necessary.
66121936Sharti * If `name' is ANYADDR, this routine implements reliable broadcast.
67121936Sharti *
68121936Sharti * Because this function calls readmsg(), none of its args may be in
69121936Sharti *	a message provided by readmsg().
70121936Sharti * message		this message
71121936Sharti * addr			to here
72121936Sharti * ack			look for this ack
73121936Sharti * net			receive from this network
74121936Sharti * bad			1=losing patience
75121936Sharti */
76121936Shartistruct tsp *
77121936Shartiacksend(struct tsp *message, struct sockaddr_in *addr, char *name,
78121936Sharti	int ack, struct netinfo *net, int bad)
79121936Sharti{
80121936Sharti	struct timeval twait;
81121936Sharti	int count;
82121936Sharti	long msec;
83121936Sharti
84121936Sharti	message->tsp_vers = TSPVERSION;
85121936Sharti	message->tsp_seq = sequence;
86121936Sharti	if (trace) {
87121936Sharti		fprintf(fd, "acksend: to %s: ",
88121936Sharti			(name == ANYADDR ? "broadcast" : name));
89121936Sharti		print(message, addr);
90121936Sharti	}
91121936Sharti	bytenetorder(message);
92121936Sharti
93121936Sharti	msec = 200;
94121936Sharti	count = bad ? 1 : 5;	/* 5 packets in 6.4 seconds */
95121936Sharti	answer = NULL;
96121936Sharti	do {
97121936Sharti		if (!answer) {
98121936Sharti			/* do not go crazy transmitting just because the
99121936Sharti			 * other guy cannot keep our sequence numbers
100121936Sharti			 * straight.
101121936Sharti			 */
102121936Sharti			if (sendto(sock, (char *)message, sizeof(struct tsp),
103121936Sharti				   0, (struct sockaddr*)addr,
104121936Sharti				   sizeof(struct sockaddr)) < 0) {
105121936Sharti				trace_sendto_err(addr->sin_addr);
106121936Sharti				break;
107121936Sharti			}
108121936Sharti		}
109121936Sharti
110121936Sharti		mstotvround(&twait, msec);
111121936Sharti		answer  = readmsg(ack, name, &twait, net);
112121936Sharti		if (answer != NULL) {
113121936Sharti			if (answer->tsp_seq != sequence) {
114121936Sharti				if (trace)
115121936Sharti					fprintf(fd,"acksend: seq # %u!=%u\n",
116121936Sharti						answer->tsp_seq, sequence);
117121936Sharti				continue;
118121936Sharti			}
119121936Sharti			break;
120121936Sharti		}
121121936Sharti
122121936Sharti		msec *= 2;
123121936Sharti	} while (--count > 0);
124121936Sharti	sequence++;
125121936Sharti
126121936Sharti	return(answer);
127121936Sharti}
128121936Sharti