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
};