acksend.c revision 1553
11553Srgrimes/*- 21553Srgrimes * Copyright (c) 1985, 1993 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 3. All advertising materials mentioning features or use of this software 141553Srgrimes * must display the following acknowledgement: 151553Srgrimes * This product includes software developed by the University of 161553Srgrimes * California, Berkeley and its contributors. 171553Srgrimes * 4. Neither the name of the University nor the names of its contributors 181553Srgrimes * may be used to endorse or promote products derived from this software 191553Srgrimes * without specific prior written permission. 201553Srgrimes * 211553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311553Srgrimes * SUCH DAMAGE. 321553Srgrimes */ 331553Srgrimes 341553Srgrimes#ifndef lint 351553Srgrimesstatic char sccsid[] = "@(#)acksend.c 8.1 (Berkeley) 6/6/93"; 361553Srgrimes#endif /* not lint */ 371553Srgrimes 381553Srgrimes#ifdef sgi 391553Srgrimes#ident "$Revision: 1.6 $" 401553Srgrimes#endif 411553Srgrimes 421553Srgrimes#include "globals.h" 431553Srgrimes 441553Srgrimesstruct tsp *answer; 451553Srgrimes 461553Srgrimesextern u_short sequence; 471553Srgrimes 481553Srgrimesvoid 491553Srgrimesxmit(type, seq, addr) 501553Srgrimes int type; 511553Srgrimes u_int seq; 521553Srgrimes struct sockaddr_in *addr; 531553Srgrimes{ 541553Srgrimes static struct tsp msg; 551553Srgrimes 561553Srgrimes msg.tsp_type = type; 571553Srgrimes msg.tsp_seq = seq; 581553Srgrimes msg.tsp_vers = TSPVERSION; 591553Srgrimes (void)strcpy(msg.tsp_name, hostname); 601553Srgrimes bytenetorder(&msg); 611553Srgrimes if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0, 621553Srgrimes (struct sockaddr*)addr, sizeof(struct sockaddr)) < 0) { 631553Srgrimes trace_sendto_err(addr->sin_addr); 641553Srgrimes } 651553Srgrimes} 661553Srgrimes 671553Srgrimes 681553Srgrimes/* 691553Srgrimes * Acksend implements reliable datagram transmission by using sequence 701553Srgrimes * numbers and retransmission when necessary. 711553Srgrimes * If `name' is ANYADDR, this routine implements reliable broadcast. 721553Srgrimes * 731553Srgrimes * Because this function calls readmsg(), none of its args may be in 741553Srgrimes * a message provided by readmsg(). 751553Srgrimes */ 761553Srgrimesstruct tsp * 771553Srgrimesacksend(message, addr, name, ack, net, bad) 781553Srgrimes struct tsp *message; /* this message */ 791553Srgrimes struct sockaddr_in *addr; /* to here */ 801553Srgrimes char *name; 811553Srgrimes int ack; /* look for this ack */ 821553Srgrimes struct netinfo *net; /* receive from this network */ 831553Srgrimes int bad; /* 1=losing patience */ 841553Srgrimes{ 851553Srgrimes struct timeval twait; 861553Srgrimes int count; 871553Srgrimes long msec; 881553Srgrimes 891553Srgrimes message->tsp_vers = TSPVERSION; 901553Srgrimes message->tsp_seq = sequence; 911553Srgrimes if (trace) { 921553Srgrimes fprintf(fd, "acksend: to %s: ", 931553Srgrimes (name == ANYADDR ? "broadcast" : name)); 941553Srgrimes print(message, addr); 951553Srgrimes } 961553Srgrimes bytenetorder(message); 971553Srgrimes 981553Srgrimes msec = 200; 991553Srgrimes count = bad ? 1 : 5; /* 5 packets in 6.4 seconds */ 1001553Srgrimes answer = 0; 1011553Srgrimes do { 1021553Srgrimes if (!answer) { 1031553Srgrimes /* do not go crazy transmitting just because the 1041553Srgrimes * other guy cannot keep our sequence numbers 1051553Srgrimes * straight. 1061553Srgrimes */ 1071553Srgrimes if (sendto(sock, (char *)message, sizeof(struct tsp), 1081553Srgrimes 0, (struct sockaddr*)addr, 1091553Srgrimes sizeof(struct sockaddr)) < 0) { 1101553Srgrimes trace_sendto_err(addr->sin_addr); 1111553Srgrimes break; 1121553Srgrimes } 1131553Srgrimes } 1141553Srgrimes 1151553Srgrimes mstotvround(&twait, msec); 1161553Srgrimes answer = readmsg(ack, name, &twait, net); 1171553Srgrimes if (answer != 0) { 1181553Srgrimes if (answer->tsp_seq != sequence) { 1191553Srgrimes if (trace) 1201553Srgrimes fprintf(fd,"acksend: seq # %u!=%u\n", 1211553Srgrimes answer->tsp_seq, sequence); 1221553Srgrimes continue; 1231553Srgrimes } 1241553Srgrimes break; 1251553Srgrimes } 1261553Srgrimes 1271553Srgrimes msec *= 2; 1281553Srgrimes } while (--count > 0); 1291553Srgrimes sequence++; 1301553Srgrimes 1311553Srgrimes return(answer); 1321553Srgrimes} 133