distSOCKET/safesend.c
///////////////////////////////////////////////////////////////////////////////
// Filename: safesend.c
///////////////////////////////////////////////////////////////////////////////
// Purpose: implements "safe" sendto()/recvfrom() functions
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date Time Name Description
// -------- -------- -------- ------------------------------------------------
// 96/03/19 20:04:26 muellerg: created
//
// possible improvements:
//
// use better timeout algorithm (e.g. TCPs). Not done to keep code simpler
///////////////////////////////////////////////////////////////////////////////
// Feature test switches ///////////////////////////// Feature test switches //
/* NONE */
// System headers /////////////////////////////////////////// System headers //
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#ifndef sun
#include <strings.h>
#endif
// Local headers ///////////////////////////////////////////// Local headers //
#include "../common.h"
// Macros /////////////////////////////////////////////////////////// Macros //
/* NONE */
// File scope objects /////////////////////////////////// File scope objects //
struct recinfo; // defined later
const int MAXKEEPSTATE = 1000; // remember the last MAXKEEPSTATE sequence
// numbers sent to the process
const int MAXKEEP = 100; // maximum number of "false" reads
static recinfo *data = NULL; // information from "false" read
static int actnumber = 0; // number of allocated slots
static int firstdata = 0; // number of first data slot to look in
static int nextdata = 0; // number of next slot to use
static unsigned long sequencenumber;// is initialized in initialize() to a
// random number. Sequence numbers are
// used for all outgoing messages
static int MAXRETRY = 10; // how often to retry a message
static int TIMEOUT = 10; // timeout in seconds
static int MAXBUFFER = 16384; // maximum size of messages, some bytes
// needed for own message header
static bool initialized = false; // initialize data only once
static unsigned long crc_32_tab[256];// CRC-32 table
// External variables, functions, and classes ///////////// External objects //
/* NONE */
// Signal catching functions ///////////////////// Signal catching functions //
/* NONE */
// Structures, unions, and class definitions /////////////////// Definitions //
enum messagetype {SEND, ACK}; // type of message
// format of all messages sent and received by the safe functions
struct newmessage
{
unsigned long sequencenumber;// sequence number for this message
messagetype type; // type of message (only for safety)
unsigned long CRC; // checksum
char data[0]; // actual data starts here
};