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