acksend.c revision 330897
1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1985, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 4. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#ifndef lint 33#if 0 34static char sccsid[] = "@(#)acksend.c 8.1 (Berkeley) 6/6/93"; 35#endif 36static const char rcsid[] = 37 "$FreeBSD: stable/11/usr.sbin/timed/timed/acksend.c 330897 2018-03-14 03:19:51Z eadler $"; 38#endif /* not lint */ 39 40#include "globals.h" 41 42struct tsp *answer; 43 44extern u_short sequence; 45 46void 47xmit(int type, u_int seq, struct sockaddr_in *addr) 48{ 49 static struct tsp msg; 50 51 msg.tsp_type = type; 52 msg.tsp_seq = seq; 53 msg.tsp_vers = TSPVERSION; 54 (void)strcpy(msg.tsp_name, hostname); 55 bytenetorder(&msg); 56 if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0, 57 (struct sockaddr*)addr, sizeof(struct sockaddr)) < 0) { 58 trace_sendto_err(addr->sin_addr); 59 } 60} 61 62 63/* 64 * Acksend implements reliable datagram transmission by using sequence 65 * numbers and retransmission when necessary. 66 * If `name' is ANYADDR, this routine implements reliable broadcast. 67 * 68 * Because this function calls readmsg(), none of its args may be in 69 * a message provided by readmsg(). 70 * message this message 71 * addr to here 72 * ack look for this ack 73 * net receive from this network 74 * bad 1=losing patience 75 */ 76struct tsp * 77acksend(struct tsp *message, struct sockaddr_in *addr, char *name, 78 int ack, struct netinfo *net, int bad) 79{ 80 struct timeval twait; 81 int count; 82 long msec; 83 84 message->tsp_vers = TSPVERSION; 85 message->tsp_seq = sequence; 86 if (trace) { 87 fprintf(fd, "acksend: to %s: ", 88 (name == ANYADDR ? "broadcast" : name)); 89 print(message, addr); 90 } 91 bytenetorder(message); 92 93 msec = 200; 94 count = bad ? 1 : 5; /* 5 packets in 6.4 seconds */ 95 answer = NULL; 96 do { 97 if (!answer) { 98 /* do not go crazy transmitting just because the 99 * other guy cannot keep our sequence numbers 100 * straight. 101 */ 102 if (sendto(sock, (char *)message, sizeof(struct tsp), 103 0, (struct sockaddr*)addr, 104 sizeof(struct sockaddr)) < 0) { 105 trace_sendto_err(addr->sin_addr); 106 break; 107 } 108 } 109 110 mstotvround(&twait, msec); 111 answer = readmsg(ack, name, &twait, net); 112 if (answer != NULL) { 113 if (answer->tsp_seq != sequence) { 114 if (trace) 115 fprintf(fd,"acksend: seq # %u!=%u\n", 116 answer->tsp_seq, sequence); 117 continue; 118 } 119 break; 120 } 121 122 msec *= 2; 123 } while (--count > 0); 124 sequence++; 125 126 return(answer); 127} 128