new copyright notice
[unix-history] / usr / src / usr.sbin / timed / timed / acksend.c
/*
* Copyright (c) 1985 Regents of the University of California.
* All rights reserved.
*
* %sccs.include.redist.c%
*/
#ifndef lint
static char sccsid[] = "@(#)acksend.c 2.7 (Berkeley) %G%";
#endif /* not lint */
#include "globals.h"
#include <protocols/timed.h>
#define RECEIVED 0
#define LOST 1
#define SECFORACK 1 /* seconds */
#define USECFORACK 0 /* microseconds */
#define MAXCOUNT 5
struct tsp *answer;
/*
* Acksend implements reliable datagram transmission by using sequence
* numbers and retransmission when necessary.
* `name' is the name of the destination
* `addr' is the address to send to
* If `name' is ANYADDR, this routine implements reliable broadcast.
*/
struct tsp *acksend(message, addr, name, ack, net)
struct tsp *message;
struct sockaddr_in *addr;
char *name;
int ack;
struct netinfo *net;
{
int count;
int flag;
extern u_short sequence;
struct timeval tout;
struct tsp *readmsg();
count = 0;
message->tsp_vers = TSPVERSION;
message->tsp_seq = sequence;
if (trace) {
fprintf(fd, "acksend: ");
if (name == ANYADDR)
fprintf(fd, "broadcast: ");
else
fprintf(fd, "%s: ", name);
print(message, addr);
}
bytenetorder(message);
do {
if (sendto(sock, (char *)message, sizeof(struct tsp), 0, addr,
sizeof(struct sockaddr_in)) < 0) {
syslog(LOG_ERR, "acksend: sendto: %m");
exit(1);
}
tout.tv_sec = SECFORACK;
tout.tv_usec = USECFORACK;
answer = readmsg(ack, name, &tout, net);
if (answer != NULL) {
if (answer->tsp_seq != sequence) {
if (trace)
fprintf(fd, "acksend: seq # %d != %d\n",
answer->tsp_seq, sequence);
continue;
}
flag = RECEIVED;
} else {
flag = LOST;
if (++count == MAXCOUNT) {
break;
}
}
} while (flag != RECEIVED);
sequence++;
return(answer);
}