v1.2b2
parent
718455beb5
commit
7fdb889444
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,258 @@
|
|||
#ifndef _NORM_API
|
||||
#define _NORM_API
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#endif // WIN32
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// IMPORTANT NOTICE
|
||||
// The NORM API is _very_ much in a developmental phase
|
||||
// right now. So, although this code is available in
|
||||
// source code distribution, it is very much subject
|
||||
// to change in future revisions. The goal of the NORM
|
||||
// API _will_ be to provide a stable base of function calls
|
||||
// for applications to use, even as the underlying NORM
|
||||
// C++ code continues to evolve. But, until this notice
|
||||
// is removed, the API shouldn't be considered final.
|
||||
|
||||
|
||||
typedef const void* NormInstanceHandle;
|
||||
extern const NormInstanceHandle NORM_INSTANCE_INVALID;
|
||||
|
||||
NormInstanceHandle NormCreateInstance();
|
||||
void NormDestroyInstance(NormInstanceHandle instanceHandle);
|
||||
|
||||
// NORM session creation and control
|
||||
typedef const void* NormSessionHandle;
|
||||
extern const NormSessionHandle NORM_SESSION_INVALID;
|
||||
typedef unsigned long NormNodeId;
|
||||
extern const NormNodeId NORM_NODE_NONE;
|
||||
extern const NormNodeId NORM_NODE_ANY;
|
||||
|
||||
NormSessionHandle NormCreateSession(NormInstanceHandle instanceHandle,
|
||||
const char* sessionAddress,
|
||||
unsigned short sessionPort,
|
||||
NormNodeId localNodeId);
|
||||
|
||||
void NormDestroySession(NormSessionHandle sessionHandle);
|
||||
|
||||
// Session management and parameters
|
||||
|
||||
void NormSetTransmitRate(NormSessionHandle sessionHandle,
|
||||
double bitsPerSecond);
|
||||
|
||||
void NormSetGrttEstimate(NormSessionHandle sessionHandle,
|
||||
double grttEstimate);
|
||||
|
||||
NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle);
|
||||
|
||||
bool NormSetLoopback(NormSessionHandle sessionHandle, bool state);
|
||||
|
||||
// Debug parameters
|
||||
void NormSetMessageTrace(NormSessionHandle sessionHandle, bool state);
|
||||
void NormSetTxLoss(NormSessionHandle sessionHandle, double percent);
|
||||
void NormSetRxLoss(NormSessionHandle sessionHandle, double percent);
|
||||
|
||||
// Sender control & parameters
|
||||
bool NormStartSender(NormSessionHandle sessionHandle,
|
||||
unsigned long bufferSpace,
|
||||
unsigned short segmentSize,
|
||||
unsigned char numData,
|
||||
unsigned char numParity);
|
||||
|
||||
void NormStopSender(NormSessionHandle sessionHandle);
|
||||
|
||||
bool NormAddAckingNode(NormSessionHandle sessionHandle,
|
||||
NormNodeId nodeId);
|
||||
|
||||
void NormRemoveAckingNode(NormSessionHandle sessionHandle,
|
||||
NormNodeId nodeId);
|
||||
|
||||
|
||||
// Receiver control & parameters
|
||||
bool NormStartReceiver(NormSessionHandle sessionHandle,
|
||||
unsigned long bufferSpace);
|
||||
|
||||
void NormStopReceiver(NormSessionHandle sessionHandle);
|
||||
|
||||
void NormSetDefaultUnicastNack(NormSessionHandle sessionHandle,
|
||||
bool state);
|
||||
|
||||
typedef const void* NormNodeHandle;
|
||||
extern const NormNodeHandle NORM_NODE_INVALID;
|
||||
typedef const void* NormObjectHandle;
|
||||
extern const NormObjectHandle NORM_OBJECT_INVALID;
|
||||
typedef unsigned short NormObjectTransportId;
|
||||
|
||||
enum NormNackingMode
|
||||
{
|
||||
NORM_NACK_NONE,
|
||||
NORM_NACK_INFO_ONLY,
|
||||
NORM_NACK_NORMAL
|
||||
};
|
||||
|
||||
enum NormRepairBoundary
|
||||
{
|
||||
NORM_BOUNDARY_BLOCK,
|
||||
NORM_BOUNDARY_OBJECT
|
||||
};
|
||||
|
||||
|
||||
NormNodeId NormGetNodeId(NormNodeHandle nodeHandle);
|
||||
|
||||
NormRepairBoundary NormGetNodeRepairBoundary(NormNodeHandle nodeHandle);
|
||||
|
||||
void NormSetNodeRepairBoundary(NormNodeHandle nodeHandle,
|
||||
NormRepairBoundary repairBoundary);
|
||||
|
||||
void NormSetDefaultRepairBoundary(NormSessionHandle sessionHandle,
|
||||
NormRepairBoundary repairBoundary);
|
||||
|
||||
// General NormObject functions
|
||||
|
||||
enum NormObjectType
|
||||
{
|
||||
NORM_OBJECT_NONE,
|
||||
NORM_OBJECT_DATA,
|
||||
NORM_OBJECT_FILE,
|
||||
NORM_OBJECT_STREAM
|
||||
};
|
||||
|
||||
|
||||
NormObjectType NormGetObjectType(NormObjectHandle objectHandle);
|
||||
|
||||
|
||||
bool NormGetObjectInfo(NormObjectHandle objectHandle,
|
||||
char* infoBuffer,
|
||||
unsigned short* infoLen);
|
||||
|
||||
NormObjectTransportId NormGetObjectTransportId(NormObjectHandle objectHandle);
|
||||
|
||||
void NormCancelObject(NormObjectHandle objectHandle);
|
||||
|
||||
|
||||
void NormRetainObject(NormObjectHandle objectHandle);
|
||||
void NormReleaseObject(NormObjectHandle objectHandle);
|
||||
|
||||
|
||||
// Receiver-only NormObject functions
|
||||
NormNackingMode NormGetObjectNackingMode(NormObjectHandle objectHandle);
|
||||
|
||||
void NormSetObjectNackingMode(NormObjectHandle objectHandle,
|
||||
NormNackingMode nackingMode);
|
||||
|
||||
void NormSetNodeNackingMode(NormNodeHandle nodeHandle,
|
||||
NormNackingMode nackingMode);
|
||||
|
||||
void NormSetDefaultNackingMode(NormSessionHandle sessionHandle,
|
||||
NormNackingMode nackingMode);
|
||||
|
||||
// Sender-only NormObject functions
|
||||
bool NormSetWatermark(NormSessionHandle sessionHandle,
|
||||
NormObjectHandle objectHandle);
|
||||
|
||||
|
||||
// NormStreamObject functions
|
||||
|
||||
NormObjectHandle NormOpenStream(NormSessionHandle sessionHandle,
|
||||
unsigned long bufferSize);
|
||||
|
||||
void NormCloseStream(NormObjectHandle streamHandle);
|
||||
|
||||
enum NormFlushMode
|
||||
{
|
||||
NORM_FLUSH_NONE,
|
||||
NORM_FLUSH_PASSIVE,
|
||||
NORM_FLUSH_ACTIVE
|
||||
};
|
||||
|
||||
void NormSetStreamFlushMode(NormObjectHandle streamHandle,
|
||||
NormFlushMode flushMode);
|
||||
|
||||
void NormSetStreamPushMode(NormObjectHandle streamHandle,
|
||||
bool state);
|
||||
|
||||
unsigned int NormWriteStream(NormObjectHandle streamHandle,
|
||||
const char* buffer,
|
||||
unsigned int numBytes);
|
||||
|
||||
void NormFlushStream(NormObjectHandle streamHandle);
|
||||
|
||||
void NormMarkStreamEom(NormObjectHandle streamHandle);
|
||||
|
||||
bool NormReadStream(NormObjectHandle streamHandle,
|
||||
char* buffer,
|
||||
unsigned int* numBytes);
|
||||
|
||||
// NormFileObject Functions
|
||||
NormObjectHandle NormQueueFile(NormSessionHandle sessionHandle,
|
||||
const char* fileName,
|
||||
const char* infoPtr = (const char*)0,
|
||||
unsigned int infoLen = 0);
|
||||
|
||||
bool NormSetCacheDirectory(NormInstanceHandle instanceHandle,
|
||||
const char* cachePath);
|
||||
|
||||
bool NormGetFileName(NormObjectHandle fileHandle,
|
||||
char* nameBuffer,
|
||||
unsigned int bufferLen);
|
||||
|
||||
bool NormSetFileName(NormObjectHandle fileHandle,
|
||||
const char* fileName);
|
||||
|
||||
// NormDataObject Functions
|
||||
bool NormQueueData(const char* dataPtr,
|
||||
unsigned long dataLen,
|
||||
const char* infoPtr = (const char*)0,
|
||||
unsigned int infoLen = 0);
|
||||
|
||||
// NORM Event Notification Routines
|
||||
|
||||
enum NormEventType
|
||||
{
|
||||
NORM_EVENT_INVALID = 0,
|
||||
NORM_TX_QUEUE_VACANCY,
|
||||
NORM_TX_QUEUE_EMPTY,
|
||||
NORM_TX_OBJECT_SENT,
|
||||
NORM_TX_OBJECT_PURGED,
|
||||
NORM_LOCAL_SERVER_CLOSED,
|
||||
NORM_REMOTE_SERVER_NEW,
|
||||
NORM_REMOTE_SERVER_INACTIVE,
|
||||
NORM_REMOTE_SERVER_ACTIVE,
|
||||
NORM_RX_OBJECT_NEW,
|
||||
NORM_RX_OBJECT_INFO,
|
||||
NORM_RX_OBJECT_UPDATE,
|
||||
NORM_RX_OBJECT_COMPLETED,
|
||||
NORM_RX_OBJECT_ABORTED
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NormEventType type;
|
||||
NormSessionHandle session;
|
||||
NormNodeHandle sender;
|
||||
NormObjectHandle object;
|
||||
} NormEvent;
|
||||
|
||||
|
||||
// This call blocks until the next NormEvent is ready unless asynchronous
|
||||
// notification is used (see below)
|
||||
bool NormGetNextEvent(NormInstanceHandle instanceHandle, NormEvent* theEvent);
|
||||
|
||||
// The "NormGetDescriptor()" function returns a HANDLE (WIN32) or
|
||||
// a file descriptor (UNIX) which can be used for async notification
|
||||
// of pending NORM events. On WIN32, the returned HANDLE can be used
|
||||
// with system calls like "WaitForSingleEvent()", and on Unix the
|
||||
// returned descriptor can be used in a "select()" call. If this type
|
||||
// of asynchronous notification is used, calls to "NormGetNextEvent()" will
|
||||
// not block.
|
||||
|
||||
#ifdef WIN32
|
||||
HANDLE NormGetDescriptor(NormInstanceHandle instanceHandle);
|
||||
#else
|
||||
int NormGetDescriptor(NormInstanceHandle instanceHandle);
|
||||
#endif // if/else WIN32/UNIX
|
||||
|
||||
#endif // _NORM_API
|
||||
|
|
@ -11,6 +11,11 @@
|
|||
#include <stdlib.h>
|
||||
#include <ctype.h> // for "isspace()"
|
||||
|
||||
#ifdef UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h> // for "waitpid()"
|
||||
#endif // UNIX
|
||||
|
||||
// Command-line application using Protolib EventDispatcher
|
||||
class NormApp : public NormController, public ProtoApp
|
||||
{
|
||||
|
|
@ -64,8 +69,8 @@ class NormApp : public NormController, public ProtoApp
|
|||
unsigned int input_index;
|
||||
unsigned int input_length;
|
||||
bool input_active;
|
||||
bool push_stream;
|
||||
NormStreamObject::FlushType msg_flush_mode;
|
||||
bool push_mode;
|
||||
NormStreamObject::FlushMode msg_flush_mode;
|
||||
bool input_messaging; // stream input mode
|
||||
UINT16 input_msg_length;
|
||||
UINT16 input_msg_index;
|
||||
|
|
@ -79,6 +84,7 @@ class NormApp : public NormController, public ProtoApp
|
|||
char* address; // session address
|
||||
UINT16 port; // session port number
|
||||
UINT8 ttl;
|
||||
bool loopback;
|
||||
char* interface_name; // for multi-home hosts
|
||||
double tx_rate; // bits/sec
|
||||
bool cc_enable;
|
||||
|
|
@ -90,6 +96,8 @@ class NormApp : public NormController, public ProtoApp
|
|||
UINT8 auto_parity;
|
||||
UINT8 extra_parity;
|
||||
double backoff_factor;
|
||||
double grtt_estimate; // initial grtt estimate
|
||||
double group_size;
|
||||
unsigned long tx_buffer_size; // bytes
|
||||
NormFileList tx_file_list;
|
||||
double tx_object_interval;
|
||||
|
|
@ -118,13 +126,15 @@ NormApp::NormApp()
|
|||
session_mgr(GetTimerMgr(), GetSocketNotifier()),
|
||||
session(NULL), tx_stream(NULL), rx_stream(NULL), input(NULL), output(NULL),
|
||||
input_index(0), input_length(0), input_active(false),
|
||||
push_stream(false), msg_flush_mode(NormStreamObject::FLUSH_PASSIVE),
|
||||
push_mode(false), msg_flush_mode(NormStreamObject::FLUSH_PASSIVE),
|
||||
input_messaging(false), input_msg_length(0), input_msg_index(0),
|
||||
output_index(0), output_messaging(false), output_msg_length(0), output_msg_sync(false),
|
||||
address(NULL), port(0), ttl(3), interface_name(NULL),
|
||||
address(NULL), port(0), ttl(3), loopback(false), interface_name(NULL),
|
||||
tx_rate(64000.0), cc_enable(false),
|
||||
segment_size(1024), ndata(32), nparity(16), auto_parity(0), extra_parity(0),
|
||||
backoff_factor(NormSession::DEFAULT_BACKOFF_FACTOR),
|
||||
grtt_estimate(NormSession::DEFAULT_GRTT_ESTIMATE),
|
||||
group_size(NormSession::DEFAULT_GSIZE_ESTIMATE),
|
||||
tx_buffer_size(1024*1024),
|
||||
tx_object_interval(0.0), tx_repeat_count(0), tx_repeat_interval(2.0), tx_repeat_clear(true),
|
||||
rx_buffer_size(1024*1024), rx_cache_path(NULL), unicast_nacks(false), silent_client(false),
|
||||
|
|
@ -153,16 +163,33 @@ NormApp::~NormApp()
|
|||
if (post_processor) delete post_processor;
|
||||
}
|
||||
|
||||
// NOTE on message flushing mode:
|
||||
//
|
||||
// "none" - messages are aggregated to make NORM_DATA
|
||||
// payloads a full "segmentSize"
|
||||
//
|
||||
// "passive" - At the end-of-message, short NORM_DATA
|
||||
// payloads are sent as needed so that
|
||||
// the message is immediately sent
|
||||
// (i.e. not held for aggregation)
|
||||
// "active" - Same as "passive", plus NORM_CMD(FLUSH)
|
||||
// messages are generated until new
|
||||
// message is written to stream
|
||||
// (This helps keep receivers in sync
|
||||
// with sender when intermittent message
|
||||
// traffic is sent)
|
||||
|
||||
|
||||
const char* const NormApp::cmd_list[] =
|
||||
{
|
||||
"+debug", // debug level
|
||||
"+log", // log file name
|
||||
"-trace", // message tracing on
|
||||
"+trace", // message tracing on
|
||||
"+txloss", // tx packet loss percent (for testing)
|
||||
"+rxloss", // rx packet loss percent (for testing)
|
||||
"+address", // session destination address
|
||||
"+ttl", // multicast hop count scope
|
||||
"+loopback", // "off" or "on" to recv our own packets
|
||||
"+interface", // multicast interface name to use
|
||||
"+cc", // congestion control on/off
|
||||
"+rate", // tx date rate (bps)
|
||||
|
|
@ -184,18 +211,19 @@ const char* const NormApp::cmd_list[] =
|
|||
"+auto", // Number of FEC packets to proactively send (<= nparity)
|
||||
"+extra", // Number of extra FEC packets sent in response to repair requests
|
||||
"+backoff", // Backoff factor to use
|
||||
"+grtt", // Set sender's initial GRTT estimate
|
||||
"+gsize", // Set sender's group size estimate
|
||||
"+txbuffer", // Size of sender's buffer
|
||||
"+rxbuffer", // Size receiver allocates for buffering each sender
|
||||
"-unicastNacks", // unicast instead of multicast feedback messages
|
||||
"-silentClient", // "silent" (non-nacking) client (EMCON mode)
|
||||
"+processor", // receive file post processing command
|
||||
"+instance", // specify norm instance name for commands
|
||||
"+instance", // specify norm instance name for remote control commands
|
||||
NULL
|
||||
};
|
||||
|
||||
void NormApp::OnControlEvent(ProtoSocket& /*theSocket*/, ProtoSocket::Event theEvent)
|
||||
{
|
||||
TRACE("NormApp::OnControlEvent() ...\n");
|
||||
switch (theEvent)
|
||||
{
|
||||
case ProtoSocket::RECV:
|
||||
|
|
@ -205,7 +233,7 @@ void NormApp::OnControlEvent(ProtoSocket& /*theSocket*/, ProtoSocket::Event theE
|
|||
if (control_pipe.Recv(buffer, len))
|
||||
{
|
||||
buffer[len] = '\0';
|
||||
TRACE("norm: received command \"%s\"\n", buffer);
|
||||
DMSG(0, "norm: received command \"%s\"\n", buffer);
|
||||
char* cmd = buffer;
|
||||
char* val = NULL;
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
|
|
@ -214,6 +242,7 @@ void NormApp::OnControlEvent(ProtoSocket& /*theSocket*/, ProtoSocket::Event theE
|
|||
{
|
||||
buffer[i++] = '\0';
|
||||
val = buffer + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!OnCommand(cmd, val))
|
||||
|
|
@ -288,8 +317,16 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
|
|||
}
|
||||
else if (!strncmp("trace", cmd, len))
|
||||
{
|
||||
tracing = true;
|
||||
if (session) session->SetTrace(true);
|
||||
if (!strcmp("on", val))
|
||||
tracing = true;
|
||||
else if (!strcmp("off", val))
|
||||
tracing = false;
|
||||
else
|
||||
{
|
||||
DMSG(0, "NormApp::OnCommand(trace) invalid argument!\n");
|
||||
return false;
|
||||
}
|
||||
if (session) session->SetTrace(tracing);
|
||||
}
|
||||
else if (!strncmp("txloss", cmd, len))
|
||||
{
|
||||
|
|
@ -346,12 +383,38 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
|
|||
else if (!strncmp("ttl", cmd, len))
|
||||
{
|
||||
int ttlTemp = atoi(val);
|
||||
if ((ttlTemp < 1) || (ttlTemp > 255))
|
||||
if ((ttlTemp < 0) || (ttlTemp > 255))
|
||||
{
|
||||
DMSG(0, "NormApp::OnCommand(ttl) invalid value!\n");
|
||||
return false;
|
||||
}
|
||||
ttl = ttlTemp;
|
||||
bool result = session ? session->SetTTL((UINT8)ttlTemp) : true;
|
||||
ttl = result ? ttlTemp : ttl;
|
||||
if (!result)
|
||||
{
|
||||
DMSG(0, "NormApp::OnCommand(ttl) error setting socket ttl!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!strncmp("loopback", cmd, len))
|
||||
{
|
||||
bool loopTemp = loopback;
|
||||
if (!strcmp("on", val))
|
||||
loopTemp = true;
|
||||
else if (!strcmp("off", val))
|
||||
loopTemp = false;
|
||||
else
|
||||
{
|
||||
DMSG(0, "NormApp::OnCommand(loopback) invalid argument!\n");
|
||||
return false;
|
||||
}
|
||||
bool result = session ? session->SetLoopback(loopTemp) : true;
|
||||
loopback = result ? loopTemp : loopback;
|
||||
if (!result)
|
||||
{
|
||||
DMSG(0, "NormApp::OnCommand(loopback) error setting socket loopback!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!strncmp("interface", cmd, len))
|
||||
{
|
||||
|
|
@ -580,12 +643,34 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
|
|||
double backoffFactor = atof(val);
|
||||
if (backoffFactor < 0)
|
||||
{
|
||||
DMSG(0, "NormSimAgent::OnCommand(backoff) invalid txRate!\n");
|
||||
DMSG(0, "NormApp::OnCommand(backoff) invalid value!\n");
|
||||
return false;
|
||||
}
|
||||
backoff_factor = backoffFactor;
|
||||
if (session) session->SetBackoffFactor(backoffFactor);
|
||||
}
|
||||
else if (!strncmp("grtt", cmd, len))
|
||||
{
|
||||
double grttEstimate = atof(val);
|
||||
if (grttEstimate < 0)
|
||||
{
|
||||
DMSG(0, "NormApp::OnCommand(grtt) invalid value!\n");
|
||||
return false;
|
||||
}
|
||||
grtt_estimate = grttEstimate;
|
||||
if (session) session->ServerSetGrtt(grttEstimate);
|
||||
}
|
||||
else if (!strncmp("gsize", cmd, len))
|
||||
{
|
||||
double groupSize = atof(val);
|
||||
if (groupSize < 0)
|
||||
{
|
||||
DMSG(0, "NormApp::OnCommand(gsize) invalid value!\n");
|
||||
return false;
|
||||
}
|
||||
group_size = groupSize;
|
||||
if (session) session->ServerSetGroupSize(groupSize);
|
||||
}
|
||||
else if (!strncmp("txbuffer", cmd, len))
|
||||
{
|
||||
if (1 != sscanf(val, "%lu", &tx_buffer_size))
|
||||
|
|
@ -614,7 +699,8 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
|
|||
}
|
||||
else if (!strncmp("push", cmd, len))
|
||||
{
|
||||
push_stream = true;
|
||||
push_mode = true;
|
||||
if (tx_stream) tx_stream->SetPushMode(push_mode);
|
||||
}
|
||||
else if (!strncmp("flush", cmd, len))
|
||||
{
|
||||
|
|
@ -630,6 +716,7 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
|
|||
DMSG(0, "NormApp::OnCommand(flush) invalid msg flush mode!\n");
|
||||
return false;
|
||||
}
|
||||
if (tx_stream) tx_stream->SetFlushMode(msg_flush_mode);
|
||||
}
|
||||
else if (!strncmp("processor", cmd, len))
|
||||
{
|
||||
|
|
@ -644,12 +731,10 @@ bool NormApp::OnCommand(const char* cmd, const char* val)
|
|||
// First, try to connect to see if instance is already running
|
||||
if (control_pipe.Connect(val))
|
||||
{
|
||||
TRACE("connected to \"%s\"\n", val);
|
||||
control_remote = true;
|
||||
}
|
||||
else if (control_pipe.Listen(val))
|
||||
{
|
||||
TRACE("listening as \"%s\"\n", val);
|
||||
control_remote = false;
|
||||
}
|
||||
else
|
||||
|
|
@ -740,7 +825,7 @@ void NormApp::OnInputReady()
|
|||
{
|
||||
|
||||
//DMSG(0, "NormApp::OnInputReady() ...\n");
|
||||
NormStreamObject::FlushType flushType = NormStreamObject::FLUSH_NONE;
|
||||
bool endOfStream = false;
|
||||
// write to the stream while input is available _and_
|
||||
// the stream has buffer space for input
|
||||
while (input)
|
||||
|
|
@ -816,7 +901,8 @@ void NormApp::OnInputReady()
|
|||
}
|
||||
if (stdin != input) fclose(input);
|
||||
input = NULL;
|
||||
flushType = NormStreamObject::FLUSH_ACTIVE;
|
||||
endOfStream = true;
|
||||
tx_stream->SetFlushMode(NormStreamObject::FLUSH_ACTIVE);
|
||||
}
|
||||
else if (ferror(input))
|
||||
{
|
||||
|
|
@ -839,11 +925,10 @@ void NormApp::OnInputReady()
|
|||
|
||||
unsigned int writeLength = input_length;// ? input_length - input_index : 0;
|
||||
|
||||
if (writeLength || (NormStreamObject::FLUSH_NONE != flushType))
|
||||
if (writeLength || endOfStream)
|
||||
{
|
||||
unsigned int wroteLength = tx_stream->Write(input_buffer+input_index,
|
||||
writeLength, flushType, false,
|
||||
push_stream);
|
||||
writeLength, false);
|
||||
input_length -= wroteLength;
|
||||
if (0 == input_length)
|
||||
input_index = 0;
|
||||
|
|
@ -857,7 +942,9 @@ void NormApp::OnInputReady()
|
|||
input_msg_index = 0;
|
||||
input_msg_length = 0;
|
||||
// Mark EOM _and_ flush
|
||||
tx_stream->Write(NULL, 0, msg_flush_mode, true, false);
|
||||
tx_stream->Write(NULL, 0, true);
|
||||
// No need to explicitly flush with "flush mode" set.
|
||||
//tx_stream->Flush();
|
||||
}
|
||||
}
|
||||
if (wroteLength < writeLength)
|
||||
|
|
@ -890,7 +977,7 @@ void NormApp::OnInputReady()
|
|||
#endif // if/else WIN32/UNIX
|
||||
input_active = true;
|
||||
else
|
||||
DMSG(0, "NormApp::Notify(TX_QUEUE_EMPTY) error adding input notification!\n");
|
||||
DMSG(0, "NormApp::OnInputReady() error adding input notification!\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -992,6 +1079,9 @@ void NormApp::Notify(NormController::Event event,
|
|||
case NormObject::DATA:
|
||||
DMSG(0, "NormApp::Notify() FILE/DATA objects not _yet_ supported...\n");
|
||||
break;
|
||||
|
||||
case NormObject::NONE:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1032,6 +1122,7 @@ void NormApp::Notify(NormController::Event event,
|
|||
}
|
||||
case NormObject::DATA:
|
||||
case NormObject::STREAM:
|
||||
case NormObject::NONE:
|
||||
break;
|
||||
} // end switch(object->GetType())
|
||||
break;
|
||||
|
|
@ -1042,6 +1133,8 @@ void NormApp::Notify(NormController::Event event,
|
|||
{
|
||||
case NormObject::FILE:
|
||||
// (TBD) update reception progress display when applicable
|
||||
// Call object->SetNotifyOnUpdate(true) here to keep
|
||||
// the update notifications coming. Otherwise they stop!
|
||||
break;
|
||||
|
||||
case NormObject::STREAM:
|
||||
|
|
@ -1161,17 +1254,22 @@ void NormApp::Notify(NormController::Event event,
|
|||
case NormObject::DATA:
|
||||
DMSG(0, "NormApp::Notify() DATA objects not _yet_ supported...\n");
|
||||
break;
|
||||
case NormObject::NONE:
|
||||
break;
|
||||
} // end switch (object->GetType())
|
||||
break;
|
||||
|
||||
case RX_OBJECT_COMPLETE:
|
||||
case RX_OBJECT_COMPLETED:
|
||||
{
|
||||
// (TBD) if we're not archiving files we should
|
||||
// manage our cache, deleting the cache
|
||||
// on shutdown ...
|
||||
//DMSG(0, "NormApp::Notify(RX_OBJECT_COMPLETE) ...\n");
|
||||
switch(object->GetType())
|
||||
{
|
||||
case NormObject::FILE:
|
||||
{
|
||||
const char* filePath = ((NormFileObject*)object)->Path();
|
||||
const char* filePath = ((NormFileObject*)object)->GetPath();
|
||||
//DMSG(0, "norm: Completed rx file: %s\n", filePath);
|
||||
if (post_processor->IsEnabled())
|
||||
{
|
||||
|
|
@ -1189,9 +1287,15 @@ void NormApp::Notify(NormController::Event event,
|
|||
case NormObject::DATA:
|
||||
ASSERT(0);
|
||||
break;
|
||||
case NormObject::NONE:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DMSG(4, "NormApp::Notify() unhandled event: %d\n", event);
|
||||
}
|
||||
} // end switch(event)
|
||||
} // end NormApp::Notify()
|
||||
|
||||
|
|
@ -1315,14 +1419,17 @@ bool NormApp::OnStartup(int argc, const char*const* argv)
|
|||
session->SetTrace(tracing);
|
||||
session->SetTxLoss(tx_loss);
|
||||
session->SetRxLoss(rx_loss);
|
||||
session->SetBackoffFactor(backoff_factor);
|
||||
session->SetTTL(ttl);
|
||||
session->SetLoopback(loopback);
|
||||
|
||||
if (input || !tx_file_list.IsEmpty())
|
||||
{
|
||||
NormObjectId baseId = (unsigned short)(rand() * (65535.0/ (double)RAND_MAX));
|
||||
session->ServerSetBaseObjectId(baseId);
|
||||
|
||||
session->SetCongestionControl(cc_enable);
|
||||
session->SetBackoffFactor(backoff_factor);
|
||||
session->ServerSetGrtt(grtt_estimate);
|
||||
session->ServerSetGroupSize(group_size);
|
||||
if (!session->StartServer(tx_buffer_size, segment_size, ndata, nparity, interface_name))
|
||||
{
|
||||
DMSG(0, "NormApp::OnStartup() start server error!\n");
|
||||
|
|
@ -1341,6 +1448,8 @@ bool NormApp::OnStartup(int argc, const char*const* argv)
|
|||
session_mgr.Destroy();
|
||||
return false;
|
||||
}
|
||||
tx_stream->SetFlushMode(msg_flush_mode);
|
||||
tx_stream->SetPushMode(push_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1407,6 +1516,10 @@ void NormApp::SignalHandler(int sigNum)
|
|||
{
|
||||
NormApp* app = static_cast<NormApp*>(ProtoApp::GetApp());
|
||||
if (app->post_processor) app->post_processor->OnDeath();
|
||||
// The use of "waitpid()" here is a work-around for
|
||||
// an IRIX SIGCHLD issue
|
||||
int status;
|
||||
while (waitpid(-1, &status, WNOHANG) > 0);
|
||||
signal(SIGCHLD, SignalHandler);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,7 +378,9 @@ bool NormBitmask::Add(const NormBitmask& b)
|
|||
if (b.num_bits > num_bits) return false;
|
||||
for(unsigned int i = 0; i < b.mask_len; i++)
|
||||
mask[i] |= b.mask[i];
|
||||
if (b.first_set < first_set) first_set = b.first_set;
|
||||
if ((b.first_set < first_set) &&
|
||||
(b.first_set < b.num_bits))
|
||||
first_set = b.first_set;
|
||||
return true;
|
||||
} // end NormBitmask::Add()
|
||||
|
||||
|
|
@ -406,13 +408,14 @@ bool NormBitmask::XCopy(const NormBitmask& b)
|
|||
for (unsigned int i = begin; i < len; i++)
|
||||
mask[i] = b.mask[i] & ~mask[i];
|
||||
if (len < mask_len) memset(&mask[len], 0, mask_len - len);
|
||||
if (b.first_set < first_set)
|
||||
UINT32 theFirst = (b.first_set < b.num_bits) ? b.first_set : num_bits;
|
||||
if (theFirst < first_set)
|
||||
{
|
||||
first_set = b.first_set;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_set = b.first_set;
|
||||
first_set = theFirst;
|
||||
if (!GetNextSet(first_set)) first_set = num_bits;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -425,6 +428,7 @@ bool NormBitmask::Multiply(const NormBitmask& b)
|
|||
for(unsigned int i = 0; i < len; i++)
|
||||
mask[i] |= b.mask[i];
|
||||
if (len < mask_len) memset(&mask[len], 0, mask_len - len);
|
||||
|
||||
if (b.first_set > first_set)
|
||||
{
|
||||
first_set = b.first_set;
|
||||
|
|
@ -557,7 +561,7 @@ bool NormSlidingMask::CanSet(UINT32 index) const
|
|||
|
||||
bool NormSlidingMask::Set(UINT32 index)
|
||||
{
|
||||
ASSERT(CanSet(index));
|
||||
//ASSERT(CanSet(index));
|
||||
if (IsSet())
|
||||
{
|
||||
// Determine position with respect to current start
|
||||
|
|
|
|||
|
|
@ -218,8 +218,8 @@ void NormEncoder::Encode(const char *data, char **pVec)
|
|||
*/
|
||||
|
||||
NormDecoder::NormDecoder()
|
||||
: npar(0), vector_size(0),
|
||||
Lambda(NULL), sVec(NULL), oVec(NULL)
|
||||
: npar(0), vector_size(0), Lambda(NULL),
|
||||
sVec(NULL), oVec(NULL), scratch(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#include "normFile.h"
|
||||
|
||||
#include <string.h> // for strerror()
|
||||
|
|
@ -63,7 +62,7 @@ bool NormFile::Open(const char* thePath, int theFlags)
|
|||
if (mkdir(tempPath, 0755))
|
||||
#endif // if/else WIN32/UNIX
|
||||
{
|
||||
DMSG(0, "NormFile::Rename() mkdir(%s) error: %s\n",
|
||||
DMSG(0, "NormFile::Open() mkdir(%s) error: %s\n",
|
||||
tempPath, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
|
@ -159,10 +158,21 @@ bool NormFile::Rename(const char* oldName, const char* newName)
|
|||
if (!strcmp(oldName, newName)) return true; // no change required
|
||||
// Make sure the new file name isn't an existing "busy" file
|
||||
// (This also builds sub-directories as needed)
|
||||
if (NormFile::IsLocked(newName)) return false;
|
||||
if (NormFile::IsLocked(newName))
|
||||
{
|
||||
DMSG(0, "NormFile::Rename() error: file is locked\n");
|
||||
return false;
|
||||
}
|
||||
#ifdef WIN32
|
||||
// In Win32, the new file can't already exist
|
||||
if (NormFile::Exists(newName)) _unlink(newName);
|
||||
if (NormFile::Exists(newName))
|
||||
{
|
||||
if (0 != _unlink(newName))
|
||||
{
|
||||
DMSG(0, "NormFile::Rename() _unlink() error: %s\n", GetErrorString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// In Win32, the old file can't be open
|
||||
int oldFlags = 0;
|
||||
if (IsOpen())
|
||||
|
|
@ -171,7 +181,7 @@ bool NormFile::Rename(const char* oldName, const char* newName)
|
|||
oldFlags &= ~(O_CREAT | O_TRUNC); // unset these
|
||||
Close();
|
||||
}
|
||||
#else
|
||||
#endif // WIN32
|
||||
// Create sub-directories as needed.
|
||||
char tempPath[PATH_MAX];
|
||||
strncpy(tempPath, newName, PATH_MAX);
|
||||
|
|
@ -198,29 +208,44 @@ bool NormFile::Rename(const char* oldName, const char* newName)
|
|||
{
|
||||
ptr = strchr(ptr, PROTO_PATH_DELIMITER);
|
||||
if (ptr) *ptr = '\0';
|
||||
#ifdef WIN32
|
||||
if (0 != _mkdir(tempPath))
|
||||
#else
|
||||
if (mkdir(tempPath, 0755))
|
||||
#endif // if/else WIN32/UNIX
|
||||
{
|
||||
DMSG(0, "NormFile::Rename() mkdir(%s) error: %s\n",
|
||||
tempPath, strerror(errno));
|
||||
tempPath, GetErrorString());
|
||||
return false;
|
||||
}
|
||||
if (ptr) *ptr++ = PROTO_PATH_DELIMITER;
|
||||
}
|
||||
#endif // if/else WIN32
|
||||
|
||||
if (rename(oldName, newName))
|
||||
{
|
||||
DMSG(0, "NormFile::Rename() rename() error: %s\n", strerror(errno));
|
||||
#ifdef WIN32
|
||||
//if (oldFlags) Open(oldName, oldFlags);
|
||||
if (oldFlags)
|
||||
{
|
||||
if (Open(oldName, oldFlags))
|
||||
offset = 0;
|
||||
else
|
||||
DMSG(0, "NormFile::Rename() error re-opening file w/ old name\n");
|
||||
}
|
||||
#endif // WIN32
|
||||
return false;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WIN32
|
||||
// (TBD) Is the file offset OK doing this???
|
||||
//if (oldFlags) Open(newName, oldFlags);
|
||||
if (oldFlags)
|
||||
{
|
||||
if (Open(newName, oldFlags))
|
||||
offset = 0;
|
||||
else
|
||||
DMSG(0, "NormFile::Rename() error opening file w/ new name\n");
|
||||
}
|
||||
#endif // WIN32
|
||||
return true;
|
||||
}
|
||||
|
|
@ -234,7 +259,7 @@ int NormFile::Read(char* buffer, int len)
|
|||
#else
|
||||
int result = read(fd, buffer, len);
|
||||
#endif // if/else WIN32
|
||||
if (result > 0) offset += result;
|
||||
if (result > 0) offset += (off_t)result;
|
||||
return result;
|
||||
} // end NormFile::Read()
|
||||
|
||||
|
|
@ -246,7 +271,7 @@ int NormFile::Write(const char* buffer, int len)
|
|||
#else
|
||||
int result = write(fd, buffer, len);
|
||||
#endif // if/else WIN32
|
||||
if (result > 0) offset += result;
|
||||
if (result > 0) offset += (off_t)result;
|
||||
return result;
|
||||
} // end NormFile::Write()
|
||||
|
||||
|
|
|
|||
|
|
@ -29,14 +29,14 @@ bool NormMsg::InitFromBuffer(UINT16 msgLength)
|
|||
case DATA:
|
||||
// (TBD) look at "fec_id" to determine "fec_payload_id" size
|
||||
// (we _assume_ "fec_id" == 129 here
|
||||
if ((unsigned char)buffer[NormDataMsg::FEC_ID_OFFSET] == 129)
|
||||
if ((unsigned char)buffer[NormObjectMsg::FEC_ID_OFFSET] == 129)
|
||||
{
|
||||
header_length_base = 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
DMSG(0, "NormMsg::InitFromBuffer(DATA) unknown fec_id value: %u\n",
|
||||
buffer[NormDataMsg::FEC_ID_OFFSET]);
|
||||
buffer[NormObjectMsg::FEC_ID_OFFSET]);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
|
@ -54,7 +54,7 @@ bool NormMsg::InitFromBuffer(UINT16 msgLength)
|
|||
else
|
||||
{
|
||||
DMSG(0, "NormMsg::InitFromBuffer(FLUSH|SQUELCH) unknown fec_id value: %u\n",
|
||||
buffer[NormDataMsg::FEC_ID_OFFSET]);
|
||||
buffer[NormCmdFlushMsg::FEC_ID_OFFSET]);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
|
@ -420,7 +420,7 @@ unsigned char NormQuantizeRtt(double rtt)
|
|||
else if (rtt < NORM_RTT_MIN)
|
||||
rtt = NORM_RTT_MIN;
|
||||
if (rtt < 3.3e-05)
|
||||
return ((unsigned char)ceil((rtt*NORM_RTT_MIN)) - 1);
|
||||
return ((unsigned char)((rtt/NORM_RTT_MIN)) - 1);
|
||||
else
|
||||
return ((unsigned char)(ceil(255.0 - (13.0*log(NORM_RTT_MAX/rtt)))));
|
||||
} // end NormQuantizeRtt()
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ const UINT8 NORM_PROTOCOL_VERSION = 1;
|
|||
|
||||
const int NORM_ROBUST_FACTOR = 20; // default robust factor
|
||||
|
||||
|
||||
// Pick a random number from 0..max
|
||||
inline double UniformRand(double max)
|
||||
{
|
||||
|
|
@ -46,7 +45,7 @@ const double NORM_RTT_MAX = 1000.0;
|
|||
inline double NormUnquantizeRtt(unsigned char qrtt)
|
||||
{
|
||||
return ((qrtt < 31) ?
|
||||
(((double)(qrtt+1))/(double)NORM_RTT_MIN) :
|
||||
(((double)(qrtt+1))*(double)NORM_RTT_MIN) :
|
||||
(NORM_RTT_MAX/exp(((double)(255-qrtt))/(double)13.0)));
|
||||
}
|
||||
unsigned char NormQuantizeRtt(double rtt);
|
||||
|
|
@ -95,6 +94,7 @@ inline double NormUnquantizeRate(unsigned short rate)
|
|||
}
|
||||
|
||||
// This class is used to describe object "size" and/or "offset"
|
||||
// (TBD) This hokey implementation should use "off_t"
|
||||
class NormObjectSize
|
||||
{
|
||||
public:
|
||||
|
|
@ -103,6 +103,13 @@ class NormObjectSize
|
|||
NormObjectSize(UINT32 size) : msb(0), lsb(size) {}
|
||||
NormObjectSize(UINT16 size) : msb(0), lsb(size) {}
|
||||
NormObjectSize(const NormObjectSize& size) : msb(size.msb), lsb(size.lsb) {}
|
||||
NormObjectSize(off_t size)
|
||||
{
|
||||
lsb = size & 0x00000000ffffffff;
|
||||
size >>= 32;
|
||||
ASSERT(0 == (size & 0xffff0000));
|
||||
msb = size & 0x0000ffff;
|
||||
}
|
||||
|
||||
UINT16 MSB() const {return msb;}
|
||||
UINT32 LSB() const {return lsb;}
|
||||
|
|
@ -150,15 +157,24 @@ class NormObjectSize
|
|||
}
|
||||
NormObjectSize operator*(const NormObjectSize& b) const;
|
||||
NormObjectSize operator/(const NormObjectSize& b) const;
|
||||
off_t GetOffset() const
|
||||
{
|
||||
off_t offset = msb;
|
||||
offset <<= 32;
|
||||
offset += lsb;
|
||||
return offset;
|
||||
}
|
||||
|
||||
private:
|
||||
UINT16 msb;
|
||||
UINT32 lsb;
|
||||
}; // end class NormObjectSize
|
||||
|
||||
typedef UINT32 NormNodeId;
|
||||
const NormNodeId NORM_NODE_INVALID = 0x00000000;
|
||||
const NormNodeId NORM_NODE_ANY = 0xffffffff;
|
||||
#ifndef _NORM_API
|
||||
typedef unsigned long NormNodeId;
|
||||
const NormNodeId NORM_NODE_NONE = 0x00000000;
|
||||
const NormNodeId NORM_NODE_ANY = 0xffffffff;
|
||||
#endif // !_NORM_API
|
||||
|
||||
class NormObjectId
|
||||
{
|
||||
|
|
@ -167,18 +183,12 @@ class NormObjectId
|
|||
NormObjectId(UINT16 id) {value = id;}
|
||||
NormObjectId(const NormObjectId& id) {value = id.value;}
|
||||
operator UINT16() const {return value;}
|
||||
int operator-(const NormObjectId& id) const
|
||||
{
|
||||
int result = value - id.value;
|
||||
return ((0 == (result & 0x00008000)) ?
|
||||
(result & 0x0000ffff) :
|
||||
(((result != 0x00008000) || (value < id.value)) ?
|
||||
result | 0xffff0000 : result));
|
||||
}
|
||||
INT16 operator-(const NormObjectId& id) const
|
||||
{return ((INT16)(value - id.value));}
|
||||
bool operator<(const NormObjectId& id) const
|
||||
{return ((*this - id) < 0);}
|
||||
{return (((short)(value - id.value)) < 0);}
|
||||
bool operator>(const NormObjectId& id) const
|
||||
{return ((*this - id) > 0);}
|
||||
{return (((INT16)(value - id.value)) > 0);}
|
||||
bool operator<=(const NormObjectId& id) const
|
||||
{return ((value == id.value) || (*this<id));}
|
||||
bool operator>=(const NormObjectId& id) const
|
||||
|
|
@ -187,7 +197,7 @@ class NormObjectId
|
|||
{return (value == id.value);}
|
||||
bool operator!=(const NormObjectId& id) const
|
||||
{return (value != id.value);}
|
||||
NormObjectId& operator++(int ) {value++; return *this;}
|
||||
NormObjectId& operator++(int) {value++; return *this;}
|
||||
|
||||
private:
|
||||
UINT16 value;
|
||||
|
|
@ -204,17 +214,17 @@ class NormBlockId
|
|||
{return (value == (UINT32)id);}
|
||||
bool operator!=(const NormBlockId& id) const
|
||||
{return (value != (UINT32)id);}
|
||||
long operator-(const NormBlockId& id) const
|
||||
{return ((long)value - id.value);}
|
||||
INT32 operator-(const NormBlockId& id) const
|
||||
{return ((INT32)value - id.value);}
|
||||
bool operator<(const NormBlockId& id) const
|
||||
{return ((*this - id) < 0);}
|
||||
{return (((INT32)(value-id.value)) < 0);}
|
||||
bool operator>(const NormBlockId& id) const
|
||||
{return ((*this - id) > 0);}
|
||||
{return (((INT32)(value-id.value)) > 0);}
|
||||
NormBlockId& operator++(int ) {value++; return *this;}
|
||||
|
||||
private:
|
||||
UINT32 value;
|
||||
}; // end class NormObjectId
|
||||
}; // end class NormBlockId
|
||||
|
||||
typedef UINT16 NormSymbolId;
|
||||
typedef NormSymbolId NormSegmentId;
|
||||
|
|
@ -361,7 +371,7 @@ class NormMsg
|
|||
void ExtendHeaderLength(UINT16 len)
|
||||
{
|
||||
header_length += len;
|
||||
length = header_length;
|
||||
length += len;
|
||||
buffer[HDR_LEN_OFFSET] = header_length >> 2;
|
||||
}
|
||||
|
||||
|
|
@ -624,6 +634,7 @@ class NormDataMsg : public NormObjectMsg
|
|||
return (length - dataIndex);
|
||||
}
|
||||
|
||||
|
||||
// These routines are only applicable to messages containing NORM_OBJECT_STREAM content
|
||||
// Some static helper routines for reading/writing embedded payload length/offsets
|
||||
static UINT16 GetStreamPayloadHeaderLength() {return (PAYLOAD_DATA_OFFSET);}
|
||||
|
|
@ -1049,7 +1060,7 @@ class NormRepairRequest
|
|||
void SetForm(NormRepairRequest::Form theForm) {form = theForm;}
|
||||
void ResetFlags() {flags = 0;}
|
||||
void SetFlag(NormRepairRequest::Flag theFlag) {flags |= theFlag;}
|
||||
void UnsetFlag(NormRepairRequest::Flag theFlag) {flags &= ~theFlag;}
|
||||
void ClearFlag(NormRepairRequest::Flag theFlag) {flags &= ~theFlag;}
|
||||
|
||||
// Returns length (each repair item requires 8 bytes of space)
|
||||
bool AppendRepairItem(const NormObjectId& objectId,
|
||||
|
|
@ -1417,6 +1428,7 @@ class NormAckMsg : public NormMsg
|
|||
{
|
||||
UINT16 len = MIN(payloadLen, segmentSize);
|
||||
memcpy(buffer+header_length, payload, len);
|
||||
length += len;
|
||||
return (payloadLen <= segmentSize);
|
||||
}
|
||||
|
||||
|
|
@ -1439,7 +1451,7 @@ class NormAckMsg : public NormMsg
|
|||
UINT16 GetPayloadLength() const {return (length - header_length);}
|
||||
const char* GetPayload() const {return (buffer + header_length);}
|
||||
|
||||
private:
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
SERVER_ID_OFFSET = MSG_OFFSET,
|
||||
|
|
@ -1451,6 +1463,75 @@ class NormAckMsg : public NormMsg
|
|||
};
|
||||
}; // end class NormAckMsg
|
||||
|
||||
class NormAckFlushMsg : public NormAckMsg
|
||||
{
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
SetType(ACK);
|
||||
SetBaseHeaderLength(ACK_HEADER_LEN);
|
||||
SetAckType(NormAck::FLUSH);
|
||||
SetFecId(129); // only one supported for the moment
|
||||
buffer[RESERVED_OFFSET] = 0;
|
||||
length = ACK_HEADER_LEN+PAYLOAD_LENGTH;
|
||||
}
|
||||
|
||||
// Note: must apply any header exts _before_ the payload is set
|
||||
void SetFecId(UINT8 fecId)
|
||||
{buffer[header_length+FEC_ID_OFFSET] = fecId;}
|
||||
void SetObjectId(NormObjectId objectId)
|
||||
{*((UINT16*)(buffer+header_length+OBJ_ID_OFFSET)) = htons((UINT16)objectId);}
|
||||
void SetFecBlockId(const NormBlockId& blockId)
|
||||
{
|
||||
UINT32 temp32 = htonl((UINT32)blockId);
|
||||
memcpy(buffer+header_length+BLOCK_ID_OFFSET, &temp32, 4);
|
||||
}
|
||||
void SetFecBlockLen(UINT16 blockLen)
|
||||
{
|
||||
blockLen = htons(blockLen);
|
||||
memcpy(buffer+header_length+BLOCK_LEN_OFFSET, &blockLen, 2);
|
||||
}
|
||||
void SetFecSymbolId(UINT16 symbolId)
|
||||
{
|
||||
symbolId = htons(symbolId);
|
||||
memcpy(buffer+header_length+SYMBOL_ID_OFFSET, &symbolId, 2);
|
||||
}
|
||||
|
||||
// Message processing
|
||||
UINT8 GetFecId() {return buffer[header_length+FEC_ID_OFFSET];}
|
||||
NormObjectId GetObjectId() const
|
||||
{
|
||||
return (ntohs(*((UINT16*)(buffer+header_length+OBJ_ID_OFFSET))));
|
||||
}
|
||||
NormBlockId GetFecBlockId() const
|
||||
{
|
||||
return (ntohl(*((UINT32*)(buffer+header_length+BLOCK_ID_OFFSET))));
|
||||
}
|
||||
UINT16 GetFecBlockLen() const
|
||||
{
|
||||
return (ntohs(*((UINT16*)(buffer+header_length+BLOCK_LEN_OFFSET))));
|
||||
}
|
||||
UINT16 GetFecSymbolId() const
|
||||
{
|
||||
return (ntohs(*((UINT16*)(buffer+header_length+SYMBOL_ID_OFFSET))));
|
||||
}
|
||||
|
||||
private:
|
||||
// These are the payload offsets for "fec_id" = 129
|
||||
// "fec_payload_id" field
|
||||
enum
|
||||
{
|
||||
FEC_ID_OFFSET = 0,
|
||||
RESERVED_OFFSET = FEC_ID_OFFSET + 1,
|
||||
OBJ_ID_OFFSET = RESERVED_OFFSET + 1,
|
||||
BLOCK_ID_OFFSET = OBJ_ID_OFFSET + 2,
|
||||
BLOCK_LEN_OFFSET = BLOCK_ID_OFFSET + 4,
|
||||
SYMBOL_ID_OFFSET = BLOCK_LEN_OFFSET + 2,
|
||||
PAYLOAD_LENGTH = SYMBOL_ID_OFFSET + 2
|
||||
};
|
||||
|
||||
}; // end class NormAckFlushMsg
|
||||
|
||||
class NormReportMsg : public NormMsg
|
||||
{
|
||||
// (TBD)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -14,8 +14,10 @@ class NormNode
|
|||
friend class NormNodeListIterator;
|
||||
|
||||
public:
|
||||
NormNode(class NormSession* theSession, NormNodeId nodeId);
|
||||
NormNode(class NormSession& theSession, NormNodeId nodeId);
|
||||
virtual ~NormNode();
|
||||
void Retain();
|
||||
void Release();
|
||||
|
||||
const ProtoAddress& GetAddress() const {return addr;}
|
||||
void SetAddress(const ProtoAddress& address) {addr = address;}
|
||||
|
|
@ -24,12 +26,13 @@ class NormNode
|
|||
inline const NormNodeId& LocalNodeId() const;
|
||||
|
||||
protected:
|
||||
class NormSession* session;
|
||||
class NormSession& session;
|
||||
|
||||
private:
|
||||
NormNodeId id;
|
||||
ProtoAddress addr;
|
||||
// We keep NormNodes in a binary tree
|
||||
unsigned int reference_count;
|
||||
// We keep NormNodes in a binary tree (TBD) make this a ProtoTree
|
||||
NormNode* parent;
|
||||
NormNode* right;
|
||||
NormNode* left;
|
||||
|
|
@ -99,24 +102,24 @@ class NormLossEstimator2
|
|||
unsigned int LastLossInterval() {return history[1];}
|
||||
|
||||
private:
|
||||
enum {DEPTH = 8};
|
||||
enum {DEPTH = 8};
|
||||
// Members
|
||||
bool init;
|
||||
unsigned long lag_mask;
|
||||
unsigned int lag_depth;
|
||||
unsigned long lag_test_bit;
|
||||
unsigned short lag_index;
|
||||
bool init;
|
||||
unsigned long lag_mask;
|
||||
unsigned int lag_depth;
|
||||
unsigned long lag_test_bit;
|
||||
unsigned short lag_index;
|
||||
|
||||
unsigned short event_window;
|
||||
unsigned short event_index;
|
||||
double event_window_time;
|
||||
double event_index_time;
|
||||
bool seeking_loss_event;
|
||||
unsigned short event_window;
|
||||
unsigned short event_index;
|
||||
double event_window_time;
|
||||
double event_index_time;
|
||||
bool seeking_loss_event;
|
||||
|
||||
bool no_loss;
|
||||
double initial_loss;
|
||||
bool no_loss;
|
||||
double initial_loss;
|
||||
|
||||
double loss_interval; // EWMA of loss event interval
|
||||
double loss_interval; // EWMA of loss event interval
|
||||
|
||||
unsigned long history[9]; // loss interval history
|
||||
double discount[9];
|
||||
|
|
@ -137,11 +140,33 @@ class NormLossEstimator2
|
|||
|
||||
}; // end class NormLossEstimator2
|
||||
|
||||
class NormAckingNode : public NormNode
|
||||
{
|
||||
public:
|
||||
NormAckingNode(class NormSession& theSession, NormNodeId nodeId);
|
||||
~NormAckingNode();
|
||||
bool IsPending() const
|
||||
{return (!ack_received &&( req_count > 0));}
|
||||
void Reset(unsigned int maxAttempts = NORM_ROBUST_FACTOR)
|
||||
{
|
||||
ack_received = false;
|
||||
req_count = maxAttempts;
|
||||
}
|
||||
void DecrementReqCount() {if (req_count > 0) req_count--;}
|
||||
unsigned int GetReqCount() const {return req_count;}
|
||||
bool AckReceived() const {return ack_received;}
|
||||
void MarkAckReceived() {ack_received = true;}
|
||||
|
||||
private:
|
||||
bool ack_received; // was ack received?
|
||||
unsigned int req_count; // remaining request attempts
|
||||
|
||||
}; // end NormAckingNode
|
||||
|
||||
class NormCCNode : public NormNode
|
||||
{
|
||||
public:
|
||||
NormCCNode(class NormSession* theSession, NormNodeId nodeId);
|
||||
NormCCNode(class NormSession& theSession, NormNodeId nodeId);
|
||||
~NormCCNode();
|
||||
|
||||
bool IsClr() const {return is_clr;}
|
||||
|
|
@ -182,9 +207,26 @@ class NormServerNode : public NormNode
|
|||
public:
|
||||
enum ObjectStatus {OBJ_INVALID, OBJ_NEW, OBJ_PENDING, OBJ_COMPLETE};
|
||||
|
||||
NormServerNode(class NormSession* theSession, NormNodeId nodeId);
|
||||
enum RepairBoundary {BLOCK_BOUNDARY, OBJECT_BOUNDARY};
|
||||
|
||||
NormServerNode(class NormSession& theSession, NormNodeId nodeId);
|
||||
~NormServerNode();
|
||||
|
||||
// Parameters
|
||||
NormObject::NackingMode GetDefaultNackingMode() const
|
||||
{return default_nacking_mode;}
|
||||
void SetDefaultNackingMode(NormObject::NackingMode nackingMode)
|
||||
{default_nacking_mode = nackingMode;}
|
||||
|
||||
NormServerNode::RepairBoundary GetRepairBoundary() const
|
||||
{return repair_boundary;}
|
||||
// (TBD) force an appropriate RepairCheck on boundary change???
|
||||
void SetRepairBoundary(RepairBoundary repairBoundary)
|
||||
{repair_boundary = repairBoundary;}
|
||||
|
||||
bool UnicastNacks() {return unicast_nacks;}
|
||||
void SetUnicastNacks(bool state) {unicast_nacks = state;}
|
||||
|
||||
bool UpdateLossEstimate(const struct timeval& currentTime,
|
||||
unsigned short theSequence,
|
||||
bool ecnStatus = false);
|
||||
|
|
@ -201,10 +243,15 @@ class NormServerNode : public NormNode
|
|||
void HandleNackMessage(const NormNackMsg& nack);
|
||||
void HandleAckMessage(const NormAckMsg& ack);
|
||||
|
||||
bool Open(UINT16 sessionId, UINT16 segmentSize, UINT16 numData, UINT16 numParity);
|
||||
void Activate();
|
||||
void Close();
|
||||
bool Open(UINT16 sessionId);
|
||||
UINT16 GetSessionId() {return session_id;}
|
||||
bool IsOpen() const {return is_open;}
|
||||
void Close();
|
||||
bool AllocateBuffers(UINT16 segmentSize, UINT16 numData, UINT16 numParity);
|
||||
bool BuffersAllocated() {return (0 != segment_size);}
|
||||
void FreeBuffers();
|
||||
void Activate();
|
||||
|
||||
|
||||
bool SyncTest(const NormObjectMsg& msg) const;
|
||||
void Sync(NormObjectId objectId);
|
||||
|
|
@ -234,7 +281,7 @@ class NormServerNode : public NormNode
|
|||
}
|
||||
void SetPending(NormObjectId objectId);
|
||||
|
||||
void DeleteObject(NormObject* obj);
|
||||
void DeleteObject(NormObject* obj, int which);
|
||||
|
||||
UINT16 SegmentSize() {return segment_size;}
|
||||
UINT16 BlockSize() {return ndata;}
|
||||
|
|
@ -287,6 +334,9 @@ class NormServerNode : public NormNode
|
|||
|
||||
|
||||
private:
|
||||
bool PassiveRepairCheck(NormObjectId objectId,
|
||||
NormBlockId blockId,
|
||||
NormSegmentId segmentId);
|
||||
void RepairCheck(NormObject::CheckLevel checkLevel,
|
||||
NormObjectId objectId,
|
||||
NormBlockId blockId,
|
||||
|
|
@ -295,66 +345,80 @@ class NormServerNode : public NormNode
|
|||
bool OnActivityTimeout(ProtoTimer& theTimer);
|
||||
bool OnRepairTimeout(ProtoTimer& theTimer);
|
||||
bool OnCCTimeout(ProtoTimer& theTimer);
|
||||
bool OnAckTimeout(ProtoTimer& theTimer);
|
||||
|
||||
void AttachCCFeedback(NormAckMsg& ack);
|
||||
void HandleRepairContent(const char* buffer, UINT16 bufferLen);
|
||||
|
||||
UINT16 session_id;
|
||||
bool synchronized;
|
||||
NormObjectId sync_id; // only valid if(synchronized)
|
||||
NormObjectId next_id; // only valid if(synchronized)
|
||||
UINT16 session_id;
|
||||
bool synchronized;
|
||||
NormObjectId sync_id; // only valid if(synchronized)
|
||||
NormObjectId next_id; // only valid if(synchronized)
|
||||
NormObjectId max_pending_object; // index for NACK construction
|
||||
NormObjectId current_object_id; // index for suppression
|
||||
UINT16 max_pending_range; // max range of pending objs allowed
|
||||
|
||||
bool is_open;
|
||||
UINT16 segment_size;
|
||||
UINT16 ndata;
|
||||
UINT16 nparity;
|
||||
bool is_open;
|
||||
UINT16 segment_size;
|
||||
UINT16 ndata;
|
||||
UINT16 nparity;
|
||||
|
||||
NormObjectTable rx_table;
|
||||
NormSlidingMask rx_pending_mask;
|
||||
NormSlidingMask rx_repair_mask;
|
||||
NormBlockPool block_pool;
|
||||
NormSegmentPool segment_pool;
|
||||
NormDecoder decoder;
|
||||
UINT16* erasure_loc;
|
||||
NormObjectTable rx_table;
|
||||
NormSlidingMask rx_pending_mask;
|
||||
NormSlidingMask rx_repair_mask;
|
||||
RepairBoundary repair_boundary;
|
||||
NormObject::NackingMode default_nacking_mode;
|
||||
bool unicast_nacks;
|
||||
NormBlockPool block_pool;
|
||||
NormSegmentPool segment_pool;
|
||||
NormDecoder decoder;
|
||||
UINT16* erasure_loc;
|
||||
|
||||
ProtoTimer activity_timer;
|
||||
ProtoTimer repair_timer;
|
||||
NormObjectId current_object_id; // index for suppression
|
||||
NormObjectId max_pending_object; // index for NACK construction
|
||||
bool server_active;
|
||||
ProtoTimer activity_timer;
|
||||
ProtoTimer repair_timer;
|
||||
|
||||
// Watermark acknowledgement
|
||||
ProtoTimer ack_timer;
|
||||
NormObjectId watermark_object_id;
|
||||
NormBlockId watermark_block_id;
|
||||
NormSegmentId watermark_segment_id;
|
||||
|
||||
// Remote server grtt measurement state
|
||||
double grtt_estimate;
|
||||
UINT8 grtt_quantized;
|
||||
struct timeval grtt_send_time;
|
||||
struct timeval grtt_recv_time;
|
||||
double gsize_estimate;
|
||||
UINT8 gsize_quantized;
|
||||
double backoff_factor;
|
||||
double grtt_estimate;
|
||||
UINT8 grtt_quantized;
|
||||
struct timeval grtt_send_time;
|
||||
struct timeval grtt_recv_time;
|
||||
double gsize_estimate;
|
||||
UINT8 gsize_quantized;
|
||||
double backoff_factor;
|
||||
|
||||
// Remote server congestion control state
|
||||
NormLossEstimator2 loss_estimator;
|
||||
UINT16 cc_sequence;
|
||||
bool cc_enable;
|
||||
double cc_rate; // ccRate at start of cc_timer
|
||||
ProtoTimer cc_timer;
|
||||
double rtt_estimate;
|
||||
UINT8 rtt_quantized;
|
||||
bool rtt_confirmed;
|
||||
bool is_clr;
|
||||
bool is_plr;
|
||||
bool slow_start;
|
||||
double send_rate; // sender advertised rate
|
||||
double recv_rate; // measured recv rate
|
||||
struct timeval prev_update_time; // for recv_rate measurement
|
||||
unsigned long recv_accumulator; // for recv_rate measurement
|
||||
double nominal_packet_size;
|
||||
NormLossEstimator2 loss_estimator;
|
||||
UINT16 cc_sequence;
|
||||
bool cc_enable;
|
||||
double cc_rate; // ccRate at start of cc_timer
|
||||
ProtoTimer cc_timer;
|
||||
double rtt_estimate;
|
||||
UINT8 rtt_quantized;
|
||||
bool rtt_confirmed;
|
||||
bool is_clr;
|
||||
bool is_plr;
|
||||
bool slow_start;
|
||||
double send_rate; // sender advertised rate
|
||||
double recv_rate; // measured recv rate
|
||||
struct timeval prev_update_time; // for recv_rate measurement
|
||||
unsigned long recv_accumulator; // for recv_rate measurement
|
||||
double nominal_packet_size;
|
||||
|
||||
// For statistics tracking
|
||||
unsigned long recv_total; // total recvd accumulator
|
||||
unsigned long recv_goodput; // goodput recvd accumulator
|
||||
unsigned long resync_count;
|
||||
unsigned long nack_count;
|
||||
unsigned long suppress_count;
|
||||
unsigned long completion_count;
|
||||
unsigned long failure_count; // usually due to re-syncs
|
||||
unsigned long recv_total; // total recvd accumulator
|
||||
unsigned long recv_goodput; // goodput recvd accumulator
|
||||
unsigned long resync_count;
|
||||
unsigned long nack_count;
|
||||
unsigned long suppress_count;
|
||||
unsigned long completion_count;
|
||||
unsigned long failure_count; // usually due to re-syncs
|
||||
|
||||
}; // end class NormServerNode
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -14,6 +14,7 @@ class NormObject
|
|||
public:
|
||||
enum Type
|
||||
{
|
||||
NONE,
|
||||
DATA,
|
||||
FILE,
|
||||
STREAM
|
||||
|
|
@ -21,6 +22,7 @@ class NormObject
|
|||
|
||||
enum CheckLevel
|
||||
{
|
||||
TO_OBJECT,
|
||||
THRU_INFO,
|
||||
TO_BLOCK,
|
||||
THRU_SEGMENT,
|
||||
|
|
@ -28,7 +30,21 @@ class NormObject
|
|||
THRU_OBJECT
|
||||
};
|
||||
|
||||
enum NackingMode
|
||||
{
|
||||
NACK_NONE,
|
||||
NACK_INFO_ONLY,
|
||||
NACK_NORMAL
|
||||
};
|
||||
|
||||
virtual ~NormObject();
|
||||
void Retain();
|
||||
void Release();
|
||||
unsigned int GetReferenceCount() {return reference_count;}
|
||||
|
||||
// This must be reset after each update
|
||||
void SetNotifyOnUpdate(bool state)
|
||||
{notify_on_update = state;}
|
||||
|
||||
// Object information
|
||||
NormObject::Type GetType() const {return type;}
|
||||
|
|
@ -39,19 +55,33 @@ class NormObject
|
|||
UINT16 GetInfoLength() const {return info_len;}
|
||||
bool IsStream() const {return (STREAM == type);}
|
||||
|
||||
class NormSession& GetSession() const {return session;}
|
||||
NormNodeId LocalNodeId() const;
|
||||
class NormServerNode* GetServer() {return server;}
|
||||
class NormServerNode* GetServer() const {return server;}
|
||||
NormNodeId GetServerNodeId() const;
|
||||
|
||||
bool IsOpen() {return (0 != segment_size);}
|
||||
// Opens (inits) object for tx operation
|
||||
bool Open(const NormObjectSize& objectSize,
|
||||
const char* infoPtr,
|
||||
UINT16 infoLen);
|
||||
UINT16 infoLen,
|
||||
UINT16 segmentSize,
|
||||
UINT16 numData,
|
||||
UINT16 numParity);
|
||||
// Opens (inits) object for rx operation
|
||||
bool Open(const NormObjectSize& objectSize, bool hasInfo)
|
||||
{return Open(objectSize, (char*)NULL, hasInfo ? 1 : 0);}
|
||||
bool Open(const NormObjectSize& objectSize,
|
||||
bool hasInfo,
|
||||
UINT16 segmentSize,
|
||||
UINT16 numData,
|
||||
UINT16 numParity)
|
||||
{
|
||||
return Open(objectSize, (char*)NULL, hasInfo ? 1 : 0,
|
||||
segmentSize, numData, numParity);
|
||||
}
|
||||
void Close();
|
||||
|
||||
|
||||
|
||||
virtual bool WriteSegment(NormBlockId blockId,
|
||||
NormSegmentId segmentId,
|
||||
const char* buffer) = 0;
|
||||
|
|
@ -59,9 +89,17 @@ class NormObject
|
|||
NormSegmentId segmentId,
|
||||
char* buffer) = 0;
|
||||
|
||||
NackingMode GetNackingMode() const {return nacking_mode;}
|
||||
void SetNackingMode(NackingMode nackingMode)
|
||||
{
|
||||
nacking_mode = nackingMode;
|
||||
// (TBD) initiate an appropriate NormServerNode::RepairCheck
|
||||
// to prompt repair process if needed
|
||||
}
|
||||
|
||||
// These are only valid after object is open
|
||||
NormBlockId GetFinalBlockId() const {return final_block_id;}
|
||||
UINT32 GetBlockSize(NormBlockId blockId)
|
||||
UINT32 GetBlockSize(NormBlockId blockId) const
|
||||
{
|
||||
return (((UINT32)blockId < large_block_count) ? large_block_size :
|
||||
small_block_size);
|
||||
|
|
@ -114,6 +152,7 @@ class NormObject
|
|||
return result;
|
||||
}
|
||||
|
||||
bool FindRepairIndex(NormBlockId& blockId, NormSegmentId& segmentId) const;
|
||||
|
||||
// Methods available to server for transmission
|
||||
bool NextServerMsg(NormObjectMsg* msg);
|
||||
|
|
@ -141,6 +180,7 @@ class NormObject
|
|||
NormBlock* FindBlock(NormBlockId blockId) {return block_buffer.Find(blockId);}
|
||||
bool ActivateRepairs();
|
||||
bool IsRepairSet(NormBlockId blockId) {return repair_mask.Test(blockId);}
|
||||
bool IsPendingSet(NormBlockId blockId) {return pending_mask.Test(blockId);}
|
||||
bool AppendRepairAdv(NormCmdRepairAdvMsg& cmd);
|
||||
|
||||
NormBlockId GetMaxPendingBlockId() const {return max_pending_block;}
|
||||
|
|
@ -161,7 +201,8 @@ class NormObject
|
|||
// Used by receiver for resource management scheme
|
||||
NormBlock* StealNewestBlock(bool excludeBlock, NormBlockId excludeId = 0);
|
||||
NormBlock* StealOldestBlock(bool excludeBlock, NormBlockId excludeId = 0);
|
||||
|
||||
bool PassiveRepairCheck(NormBlockId blockId,
|
||||
NormSegmentId segmentId);
|
||||
bool ClientRepairCheck(CheckLevel level,
|
||||
NormBlockId blockId,
|
||||
NormSegmentId segmentId,
|
||||
|
|
@ -178,15 +219,16 @@ class NormObject
|
|||
|
||||
protected:
|
||||
NormObject(Type theType,
|
||||
class NormSession* theSession,
|
||||
class NormSession& theSession,
|
||||
class NormServerNode* theServer,
|
||||
const NormObjectId& objectId);
|
||||
|
||||
void Accept() {accepted = true;}
|
||||
|
||||
NormObject::Type type;
|
||||
class NormSession* session;
|
||||
class NormSession& session;
|
||||
class NormServerNode* server; // NULL value indicates local (tx) object
|
||||
unsigned int reference_count;
|
||||
NormObjectId transport_id;
|
||||
|
||||
NormObjectSize object_size;
|
||||
|
|
@ -194,9 +236,9 @@ class NormObject
|
|||
UINT16 ndata;
|
||||
UINT16 nparity;
|
||||
NormBlockBuffer block_buffer;
|
||||
bool pending_info;
|
||||
bool pending_info; // set when we need to send or recv info
|
||||
NormSlidingMask pending_mask;
|
||||
bool repair_info;
|
||||
bool repair_info; // client: set when
|
||||
NormSlidingMask repair_mask;
|
||||
NormBlockId current_block_id; // for suppression
|
||||
NormSegmentId next_segment_id; // for suppression
|
||||
|
|
@ -208,11 +250,14 @@ class NormObject
|
|||
UINT32 small_block_size;
|
||||
NormBlockId final_block_id;
|
||||
UINT16 final_segment_size;
|
||||
|
||||
NackingMode nacking_mode;
|
||||
char* info;
|
||||
UINT16 info_len;
|
||||
|
||||
// Here are some members used to let us know
|
||||
// our status with respect to the rest of the world
|
||||
bool accepted;
|
||||
bool notify_on_update;
|
||||
|
||||
NormObject* next;
|
||||
}; // end class NormObject
|
||||
|
|
@ -221,7 +266,7 @@ class NormObject
|
|||
class NormFileObject : public NormObject
|
||||
{
|
||||
public:
|
||||
NormFileObject(class NormSession* theSession,
|
||||
NormFileObject(class NormSession& theSession,
|
||||
class NormServerNode* theServer,
|
||||
const NormObjectId& objectId);
|
||||
~NormFileObject();
|
||||
|
|
@ -231,7 +276,8 @@ class NormFileObject : public NormObject
|
|||
UINT16 infoLen = 0);
|
||||
bool Accept(const char* thePath);
|
||||
void Close();
|
||||
const char* Path() {return path;}
|
||||
|
||||
const char* GetPath() {return path;}
|
||||
bool Rename(const char* newPath)
|
||||
{
|
||||
bool result = file.Rename(path, newPath);
|
||||
|
|
@ -254,11 +300,44 @@ class NormFileObject : public NormObject
|
|||
NormObjectSize small_block_length;
|
||||
}; // end class NormFileObject
|
||||
|
||||
class NormDataObject : public NormObject
|
||||
{
|
||||
// (TBD) allow support of greater than 4GB size data objects
|
||||
public:
|
||||
NormDataObject(class NormSession& theSession,
|
||||
class NormServerNode* theServer,
|
||||
const NormObjectId& objectId);
|
||||
~NormDataObject();
|
||||
|
||||
bool Open(char* dataPtr,
|
||||
UINT32 dataLen,
|
||||
const char* infoPtr = NULL,
|
||||
UINT16 infoLen = 0);
|
||||
bool Accept(char* dataPtr, UINT32 dataMax);
|
||||
void Close();
|
||||
|
||||
const char* GetData() {return data_ptr;}
|
||||
|
||||
virtual bool WriteSegment(NormBlockId blockId,
|
||||
NormSegmentId segmentId,
|
||||
const char* buffer);
|
||||
|
||||
virtual UINT16 ReadSegment(NormBlockId blockId,
|
||||
NormSegmentId segmentId,
|
||||
char* buffer);
|
||||
|
||||
private:
|
||||
NormObjectSize large_block_length;
|
||||
NormObjectSize small_block_length;
|
||||
char* data_ptr;
|
||||
UINT32 data_max;
|
||||
}; // end class NormDataObject
|
||||
|
||||
|
||||
class NormStreamObject : public NormObject
|
||||
{
|
||||
public:
|
||||
NormStreamObject(class NormSession* theSession,
|
||||
NormStreamObject(class NormSession& theSession,
|
||||
class NormServerNode* theServer,
|
||||
const NormObjectId& objectId);
|
||||
~NormStreamObject();
|
||||
|
|
@ -269,19 +348,35 @@ class NormStreamObject : public NormObject
|
|||
void Close();
|
||||
bool Accept(UINT32 bufferSize);
|
||||
|
||||
enum FlushType
|
||||
enum FlushMode
|
||||
{
|
||||
FLUSH_NONE, // no flush action taken
|
||||
FLUSH_PASSIVE, // pending queued data is transmitted, but no CMD(FLUSH) sent
|
||||
FLUSH_ACTIVE // pending queued data is transmitted, _and_ active CMD(FLUSH)
|
||||
};
|
||||
bool Read(char* buffer, unsigned int* buflen, bool findMsgStart = false);
|
||||
UINT32 Write(const char* buffer, UINT32 len, FlushType flushType, bool eom, bool push);
|
||||
|
||||
void SetFlushMode(FlushMode flushMode) {flush_mode = flushMode;}
|
||||
void Flush(bool eom = false)
|
||||
{
|
||||
FlushMode oldFlushMode = flush_mode;
|
||||
SetFlushMode(FLUSH_ACTIVE);
|
||||
Write(NULL, 0, eom);
|
||||
SetFlushMode(oldFlushMode);
|
||||
}
|
||||
void SetPushMode(bool state) {push_mode = state;}
|
||||
|
||||
bool Read(char* buffer, unsigned int* buflen, bool findMsgStart = false);
|
||||
UINT32 Write(const char* buffer, UINT32 len, bool eom = false);
|
||||
|
||||
bool SyncOffsetIsValid() {return sync_offset_valid;}
|
||||
UINT32 GetSyncOffset() {return sync_offset;}
|
||||
UINT32 GetCurrentReadOffset() {return read_offset;}
|
||||
|
||||
bool StreamUpdateStatus(NormBlockId blockId);
|
||||
void StreamResync(NormBlockId nextBlockId)
|
||||
{stream_next_id = nextBlockId;}
|
||||
{
|
||||
stream_next_id = nextBlockId;
|
||||
}
|
||||
void StreamAdvance();
|
||||
|
||||
virtual bool WriteSegment(NormBlockId blockId,
|
||||
|
|
@ -309,6 +404,10 @@ class NormStreamObject : public NormObject
|
|||
{return (write_index.segment ? (write_index.segment-1) :
|
||||
(ndata-1));}
|
||||
|
||||
NormBlockId GetNextBlockId() const
|
||||
{return (server ? read_index.block : write_index.block);}
|
||||
NormSegmentId GetNextSegmentId() const
|
||||
{return (server ? read_index.segment : write_index.segment);}
|
||||
private:
|
||||
class Index
|
||||
{
|
||||
|
|
@ -320,6 +419,8 @@ class NormStreamObject : public NormObject
|
|||
bool stream_sync;
|
||||
NormBlockId stream_sync_id;
|
||||
NormBlockId stream_next_id;
|
||||
UINT32 sync_offset;
|
||||
bool sync_offset_valid;
|
||||
|
||||
NormBlockPool block_pool;
|
||||
NormSegmentPool segment_pool;
|
||||
|
|
@ -330,6 +431,8 @@ class NormStreamObject : public NormObject
|
|||
UINT32 read_offset;
|
||||
bool flush_pending;
|
||||
bool msg_start;
|
||||
FlushMode flush_mode;
|
||||
bool push_mode;
|
||||
}; // end class NormStreamObject
|
||||
|
||||
#ifdef SIMULATE
|
||||
|
|
@ -338,7 +441,7 @@ class NormStreamObject : public NormObject
|
|||
class NormSimObject : public NormObject
|
||||
{
|
||||
public:
|
||||
NormSimObject(class NormSession* theSession,
|
||||
NormSimObject(class NormSession& theSession,
|
||||
class NormServerNode* theServer,
|
||||
const NormObjectId& objectId);
|
||||
~NormSimObject();
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ void NormPostProcessor::GetCommand(char* buffer, unsigned int buflen)
|
|||
|
||||
bool NormPostProcessor::SetCommand(const char* cmd)
|
||||
{
|
||||
|
||||
// 1) Delete old command resources
|
||||
if (process_argv)
|
||||
{
|
||||
|
|
@ -81,10 +80,10 @@ bool NormPostProcessor::SetCommand(const char* cmd)
|
|||
{
|
||||
argCount++;
|
||||
while (!isspace(*ptr) && ('\0' != *ptr)) ptr++;
|
||||
while (isspace(*ptr) && ('\0' != *ptr)) ptr++;
|
||||
}
|
||||
if (!argCount) return true; // post processing disabled
|
||||
|
||||
|
||||
// 3) Allocate new process_argv array (2 extra slots, one for "target",
|
||||
// and one for terminating NULL pointer.
|
||||
if (!(process_argv = new char*[argCount+2]))
|
||||
|
|
@ -115,7 +114,8 @@ bool NormPostProcessor::SetCommand(const char* cmd)
|
|||
}
|
||||
strncpy(arg, argStart, argLength);
|
||||
arg[argLength] = '\0';
|
||||
process_argv[index] = arg;
|
||||
process_argv[index++] = arg;
|
||||
while (isspace(*ptr) && ('\0' != *ptr)) ptr++;
|
||||
}
|
||||
return true;
|
||||
} // end NormPostProcessor::SetCommand()
|
||||
|
|
|
|||
|
|
@ -257,6 +257,7 @@ bool NormBlock::ActivateRepairs(UINT16 numParity)
|
|||
if (repair_mask.IsSet())
|
||||
{
|
||||
pending_mask.Add(repair_mask);
|
||||
ASSERT(pending_mask.IsSet());
|
||||
repair_mask.Clear();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -390,7 +391,7 @@ bool NormBlock::HandleSegmentRequest(NormSegmentId nextId, NormSegmentId lastId,
|
|||
return increasedRepair;
|
||||
} // end NormBlock::HandleSegmentRequest()
|
||||
|
||||
|
||||
// (TBD) this should return true is something is appending, false otherwise
|
||||
bool NormBlock::AppendRepairAdv(NormCmdRepairAdvMsg& cmd,
|
||||
NormObjectId objectId,
|
||||
bool repairInfo,
|
||||
|
|
@ -433,7 +434,13 @@ bool NormBlock::AppendRepairAdv(NormCmdRepairAdvMsg& cmd,
|
|||
if (form != prevForm)
|
||||
{
|
||||
if (NormRepairRequest::INVALID != prevForm)
|
||||
cmd.PackRepairRequest(req); // (TBD) error check
|
||||
{
|
||||
if (0 == cmd.PackRepairRequest(req))
|
||||
{
|
||||
DMSG(0, "NormBlock::AppendRepairAdv() warning: full msg\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
req.SetForm(form);
|
||||
cmd.AttachRepairRequest(req, segmentSize); // (TBD) error check
|
||||
prevForm = form;
|
||||
|
|
@ -460,12 +467,16 @@ bool NormBlock::AppendRepairAdv(NormCmdRepairAdvMsg& cmd,
|
|||
}
|
||||
} // end while (nextId < totalSize)
|
||||
if (NormRepairRequest::INVALID != prevForm)
|
||||
cmd.PackRepairRequest(req); // (TBD) error check
|
||||
{
|
||||
if (0 == cmd.PackRepairRequest(req))
|
||||
DMSG(0, "NormBlock::AppendRepairAdv() warning: full msg\n");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} // end NormBlock::AppendRepairAdv()
|
||||
|
||||
// Called by client
|
||||
// (TBD) this should return true iff something appended, false otherwise
|
||||
bool NormBlock::AppendRepairRequest(NormNackMsg& nack,
|
||||
UINT16 numData,
|
||||
UINT16 numParity,
|
||||
|
|
@ -527,7 +538,13 @@ bool NormBlock::AppendRepairRequest(NormNackMsg& nack,
|
|||
if (form != prevForm)
|
||||
{
|
||||
if (NormRepairRequest::INVALID != prevForm)
|
||||
nack.PackRepairRequest(req); // (TBD) error check
|
||||
{
|
||||
if (0 == nack.PackRepairRequest(req))
|
||||
{
|
||||
DMSG(0, "NormBlock::AppendRepairRequest() warning: full NACK msg\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
nack.AttachRepairRequest(req, segmentSize); // (TBD) error check
|
||||
req.SetForm(form);
|
||||
prevForm = form;
|
||||
|
|
@ -554,76 +571,10 @@ bool NormBlock::AppendRepairRequest(NormNackMsg& nack,
|
|||
}
|
||||
} // end while (nextId < lastId)
|
||||
if (NormRepairRequest::INVALID != prevForm)
|
||||
nack.PackRepairRequest(req); // (TBD) error check
|
||||
|
||||
/*
|
||||
// old code begins here
|
||||
NormSegmentId prevId = nextId;
|
||||
while ((nextId <= lastId) || (segmentCount > 0))
|
||||
{
|
||||
// force break of possible ending consec. series
|
||||
if (nextId == lastId) nextId++;
|
||||
if (segmentCount && (segmentCount == (nextId - prevId)))
|
||||
{
|
||||
segmentCount++; // consecutive series continues
|
||||
}
|
||||
else
|
||||
{
|
||||
NormRepairRequest::Form nextForm;
|
||||
switch(segmentCount)
|
||||
{
|
||||
case 0:
|
||||
nextForm = NormRepairRequest::INVALID;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
nextForm = NormRepairRequest::ITEMS;
|
||||
break;
|
||||
default:
|
||||
nextForm = NormRepairRequest::RANGES;
|
||||
break;
|
||||
} // end switch(reqCount)
|
||||
if (prevForm != nextForm)
|
||||
{
|
||||
if (NormRepairRequest::INVALID != prevForm)
|
||||
nack.PackRepairRequest(req); // (TBD) error check
|
||||
if (NormRepairRequest::INVALID != nextForm)
|
||||
{
|
||||
nack.AttachRepairRequest(req, segmentSize);
|
||||
req.SetForm(nextForm);
|
||||
req.SetFlag(NormRepairRequest::SEGMENT);
|
||||
if (pendingInfo) req.SetFlag(NormRepairRequest::INFO);
|
||||
}
|
||||
prevForm = nextForm;
|
||||
}
|
||||
if (NormRepairRequest::INVALID != nextForm)
|
||||
DMSG(6, "NormBlock::AppendRepairRequest() SEGMENT request\n");
|
||||
switch (nextForm)
|
||||
{
|
||||
case NormRepairRequest::ITEMS:
|
||||
req.AppendRepairItem(objectId, id, prevId); // (TBD) error check
|
||||
if (2 == reqCount)
|
||||
req.AppendRepairItem(objectId, id, prevId+1); // (TBD) error check
|
||||
break;
|
||||
case NormRepairRequest::RANGES:
|
||||
req.AppendRepairItem(objectId, id, prevId); // (TBD) error check
|
||||
req.AppendRepairItem(objectId, id, prevId+reqCount-1); // (TBD) error check
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} // end switch(nextForm)
|
||||
prevId = nextId;
|
||||
if (nextId < lastId)
|
||||
segmentCount = 1;
|
||||
else
|
||||
segmentCount = 0;
|
||||
} // end if/else (reqCount && (reqCount == (nextId - prevId)))
|
||||
nextId++;
|
||||
if (nextId <= lastId) nextId = pending_mask.NextSet(nextId);
|
||||
} // end while(nextId <= lastId)
|
||||
if (NormRepairRequest::INVALID != prevForm)
|
||||
nack.PackRepairRequest(req); // (TBD) error check
|
||||
*/
|
||||
if (0 == nack.PackRepairRequest(req))
|
||||
DMSG(0, "NormBlock::AppendRepairRequest() warning: full NACK msg\n");
|
||||
}
|
||||
return true;
|
||||
} // end NormBlock::AppendRepairRequest()
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -13,11 +13,20 @@ class NormController
|
|||
public:
|
||||
enum Event
|
||||
{
|
||||
EVENT_INVALID = 0,
|
||||
TX_QUEUE_VACANCY,
|
||||
TX_QUEUE_EMPTY,
|
||||
TX_OBJECT_SENT,
|
||||
TX_OBJECT_PURGED,
|
||||
LOCAL_SERVER_CLOSED,
|
||||
REMOTE_SERVER_NEW,
|
||||
REMOTE_SERVER_INACTIVE,
|
||||
REMOTE_SERVER_ACTIVE,
|
||||
RX_OBJECT_NEW,
|
||||
RX_OBJECT_INFO,
|
||||
RX_OBJECT_UPDATE,
|
||||
RX_OBJECT_COMPLETE,
|
||||
RX_OBJECT_COMPLETED,
|
||||
RX_OBJECT_ABORTED
|
||||
};
|
||||
|
||||
virtual void Notify(NormController::Event event,
|
||||
|
|
@ -54,9 +63,10 @@ class NormSessionMgr
|
|||
}
|
||||
|
||||
void ActivateTimer(ProtoTimer& timer) {timer_mgr.ActivateTimer(timer);}
|
||||
ProtoTimerMgr& GetTimerMgr() {return timer_mgr;}
|
||||
ProtoSocket::Notifier& GetSocketNotifier() {return socket_notifier;}
|
||||
ProtoTimerMgr& GetTimerMgr() const {return timer_mgr;}
|
||||
ProtoSocket::Notifier& GetSocketNotifier() const {return socket_notifier;}
|
||||
|
||||
NormController* GetController() const {return controller;}
|
||||
private:
|
||||
ProtoTimerMgr& timer_mgr;
|
||||
ProtoSocket::Notifier& socket_notifier;
|
||||
|
|
@ -86,26 +96,34 @@ class NormSession
|
|||
static const UINT16 DEFAULT_NPARITY;
|
||||
|
||||
// General methods
|
||||
const NormNodeId& LocalNodeId() {return local_node_id;}
|
||||
const NormNodeId& LocalNodeId() const {return local_node_id;}
|
||||
bool Open(const char* interfaceName = NULL);
|
||||
void Close();
|
||||
bool IsOpen() {return (rx_socket.IsOpen() || tx_socket.IsOpen());}
|
||||
const ProtoAddress& Address() {return address;}
|
||||
void SetAddress(const ProtoAddress& addr) {address = addr;}
|
||||
bool SetTTL(UINT8 theTTL)
|
||||
{
|
||||
bool result = tx_socket.IsOpen() ? tx_socket.SetTTL(theTTL) : true;
|
||||
ttl = result ? theTTL : ttl;
|
||||
return result;
|
||||
}
|
||||
bool SetLoopback(bool state)
|
||||
{
|
||||
bool result = tx_socket.IsOpen() ? tx_socket.SetLoopback(state) : true;
|
||||
loopback = result ? state : loopback;
|
||||
return result;
|
||||
}
|
||||
static double CalculateRate(double size, double rtt, double loss);
|
||||
|
||||
NormSessionMgr& GetSessionMgr() {return session_mgr;}
|
||||
|
||||
// Session parameters
|
||||
double TxRate() {return (tx_rate * 8.0);}
|
||||
// (TBD) watch timer scheduling and min/max bounds
|
||||
void SetTxRate(double txRate) {tx_rate = txRate / 8.0;}
|
||||
void SetTxRate(double txRate);
|
||||
double BackoffFactor() {return backoff_factor;}
|
||||
void SetBackoffFactor(double value) {backoff_factor = value;}
|
||||
void SetLoopback(bool state)
|
||||
{
|
||||
rx_socket.SetLoopback(state);
|
||||
tx_socket.SetLoopback(state);
|
||||
}
|
||||
bool CongestionControl() {return cc_enable;}
|
||||
void SetCongestionControl(bool state) {cc_enable = state;}
|
||||
|
||||
|
|
@ -130,11 +148,12 @@ class NormSession
|
|||
next_tx_object_id = IsServer() ? next_tx_object_id : baseId;
|
||||
session_id = IsServer() ? session_id : (UINT16)baseId;
|
||||
}
|
||||
bool StartServer(unsigned long bufferSpace,
|
||||
UINT16 segmentSize,
|
||||
UINT16 numData,
|
||||
UINT16 numParity,
|
||||
const char* interfaceName = NULL);
|
||||
bool IsServer() {return is_server;}
|
||||
bool StartServer(UINT32 bufferSpace,
|
||||
UINT16 segmentSize,
|
||||
UINT16 numData,
|
||||
UINT16 numParity,
|
||||
const char* interfaceName = NULL);
|
||||
void StopServer();
|
||||
NormStreamObject* QueueTxStream(UINT32 bufferSize,
|
||||
const char* infoPtr = NULL,
|
||||
|
|
@ -142,15 +161,27 @@ class NormSession
|
|||
NormFileObject* QueueTxFile(const char* path,
|
||||
const char* infoPtr = NULL,
|
||||
UINT16 infoLen = 0);
|
||||
NormDataObject* QueueTxData(const char* dataPtr,
|
||||
UINT32 dataLen,
|
||||
const char* infoPtr = NULL,
|
||||
UINT16 infoLen = 0);
|
||||
void DeleteTxObject(NormObject* obj);
|
||||
|
||||
bool IsServer() {return is_server;}
|
||||
UINT16 ServerSegmentSize() {return segment_size;}
|
||||
UINT16 ServerBlockSize() {return ndata;}
|
||||
UINT16 ServerNumParity() {return nparity;}
|
||||
UINT16 ServerAutoParity() {return auto_parity;}
|
||||
// postive ack mgmnt
|
||||
void ServerSetWatermark(NormObjectId objectId,
|
||||
NormBlockId blockId,
|
||||
NormSegmentId segmentId);
|
||||
bool ServerAddAckingNode(NormNodeId nodeId);
|
||||
void ServerRemoveAckingNode(NormNodeId nodeId);
|
||||
|
||||
|
||||
UINT16 ServerSegmentSize() const {return segment_size;}
|
||||
UINT16 ServerBlockSize() const {return ndata;}
|
||||
UINT16 ServerNumParity() const {return nparity;}
|
||||
UINT16 ServerAutoParity() const {return auto_parity;}
|
||||
void ServerSetAutoParity(UINT16 autoParity)
|
||||
{ASSERT(autoParity <= nparity); auto_parity = autoParity;}
|
||||
UINT16 ServerExtraParity() {return extra_parity;}
|
||||
UINT16 ServerExtraParity() const {return extra_parity;}
|
||||
void ServerSetExtraParity(UINT16 extraParity)
|
||||
{extra_parity = extraParity;}
|
||||
|
||||
|
|
@ -161,6 +192,13 @@ class NormSession
|
|||
objectId = (UINT16)index;
|
||||
return result;
|
||||
}
|
||||
bool ServerGetFirstRepairPending(NormObjectId& objectId)
|
||||
{
|
||||
UINT32 index;
|
||||
bool result = tx_repair_mask.GetFirstSet(index);
|
||||
objectId = (UINT16)index;
|
||||
return result;
|
||||
}
|
||||
|
||||
double ServerGrtt() {return grtt_advertised;}
|
||||
void ServerSetGrtt(double grttValue)
|
||||
|
|
@ -192,15 +230,7 @@ class NormSession
|
|||
void ServerPutFreeSegment(char* segment) {segment_pool.Put(segment);}
|
||||
|
||||
|
||||
void PromptServer()
|
||||
{
|
||||
if (!tx_timer.IsActive())
|
||||
{
|
||||
tx_timer.SetInterval(0.0);
|
||||
ActivateTimer(tx_timer);
|
||||
}
|
||||
}
|
||||
|
||||
void PromptServer() {QueueMessage(NULL);}
|
||||
|
||||
void TouchServer()
|
||||
{
|
||||
|
|
@ -213,13 +243,23 @@ class NormSession
|
|||
bool StartClient(unsigned long bufferSpace,
|
||||
const char* interfaceName = NULL);
|
||||
void StopClient();
|
||||
bool IsClient() {return is_client;}
|
||||
unsigned long RemoteServerBufferSize()
|
||||
bool IsClient() const {return is_client;}
|
||||
unsigned long RemoteServerBufferSize() const
|
||||
{return remote_server_buffer_size;}
|
||||
void SetUnicastNacks(bool state) {unicast_nacks = state;}
|
||||
bool UnicastNacks() {return unicast_nacks;}
|
||||
bool UnicastNacks() const {return unicast_nacks;}
|
||||
void ClientSetSilent(bool state) {client_silent = state;}
|
||||
bool ClientIsSilent() {return client_silent;}
|
||||
bool ClientIsSilent() const {return client_silent;}
|
||||
|
||||
NormObject::NackingMode ClientGetDefaultNackingMode() const
|
||||
{return default_nacking_mode;}
|
||||
void ClientSetDefaultNackingMode(NormObject::NackingMode nackingMode)
|
||||
{default_nacking_mode = nackingMode;}
|
||||
|
||||
NormServerNode::RepairBoundary ClientGetDefaultRepairBoundary() const
|
||||
{return default_repair_boundary;}
|
||||
void ClientSetDefaultRepairBoundary(NormServerNode::RepairBoundary repairBoundary)
|
||||
{default_repair_boundary = repairBoundary;}
|
||||
|
||||
// Debug settings
|
||||
void SetTrace(bool state) {trace = state;}
|
||||
|
|
@ -239,13 +279,12 @@ class NormSession
|
|||
~NormSession();
|
||||
|
||||
void Serve();
|
||||
bool QueueTxObject(NormObject* obj, bool touchServer = true);
|
||||
void DeleteTxObject(NormObject* obj);
|
||||
bool QueueTxObject(NormObject* obj);
|
||||
|
||||
|
||||
bool OnTxTimeout(ProtoTimer& theTimer);
|
||||
bool OnRepairTimeout(ProtoTimer& theTimer);
|
||||
bool OnFlushTimeout(ProtoTimer& theTimer);
|
||||
bool OnWatermarkTimeout(ProtoTimer& theTimer);
|
||||
bool OnProbeTimeout(ProtoTimer& theTimer);
|
||||
bool OnReportTimeout(ProtoTimer& theTimer);
|
||||
|
||||
|
|
@ -271,6 +310,7 @@ class NormSession
|
|||
void AdjustRate(bool onResponse);
|
||||
bool ServerQueueSquelch(NormObjectId objectId);
|
||||
void ServerQueueFlush();
|
||||
bool ServerQueueWatermarkFlush();
|
||||
bool ServerBuildRepairAdv(NormCmdRepairAdvMsg& cmd);
|
||||
void ServerUpdateGroupSize();
|
||||
|
||||
|
|
@ -282,102 +322,111 @@ class NormSession
|
|||
void ClientHandleNackMessage(const NormNackMsg& nack);
|
||||
void ClientHandleAckMessage(const NormAckMsg& ack);
|
||||
|
||||
NormSessionMgr& session_mgr;
|
||||
bool notify_pending;
|
||||
ProtoTimer tx_timer;
|
||||
ProtoSocket tx_socket;
|
||||
ProtoSocket rx_socket;
|
||||
NormMessageQueue message_queue;
|
||||
NormMessageQueue message_pool;
|
||||
ProtoTimer report_timer;
|
||||
UINT16 tx_sequence;
|
||||
NormSessionMgr& session_mgr;
|
||||
bool notify_pending;
|
||||
ProtoTimer tx_timer;
|
||||
ProtoSocket tx_socket;
|
||||
ProtoSocket rx_socket;
|
||||
NormMessageQueue message_queue;
|
||||
NormMessageQueue message_pool;
|
||||
ProtoTimer report_timer;
|
||||
UINT16 tx_sequence;
|
||||
|
||||
// General session parameters
|
||||
NormNodeId local_node_id;
|
||||
ProtoAddress address; // session destination address & port
|
||||
UINT8 ttl; // session multicast ttl
|
||||
double tx_rate; // bytes per second
|
||||
double backoff_factor;
|
||||
NormNodeId local_node_id;
|
||||
ProtoAddress address; // session destination address & port
|
||||
UINT8 ttl; // session multicast ttl
|
||||
bool loopback; // to receive own traffic
|
||||
double tx_rate; // bytes per second
|
||||
double backoff_factor;
|
||||
|
||||
// Server parameters and state
|
||||
bool is_server;
|
||||
UINT16 session_id;
|
||||
UINT16 segment_size;
|
||||
UINT16 ndata;
|
||||
UINT16 nparity;
|
||||
UINT16 auto_parity;
|
||||
UINT16 extra_parity;
|
||||
bool is_server;
|
||||
UINT16 session_id;
|
||||
UINT16 segment_size;
|
||||
UINT16 ndata;
|
||||
UINT16 nparity;
|
||||
UINT16 auto_parity;
|
||||
UINT16 extra_parity;
|
||||
|
||||
NormObjectTable tx_table;
|
||||
NormSlidingMask tx_pending_mask;
|
||||
NormSlidingMask tx_repair_mask;
|
||||
ProtoTimer repair_timer;
|
||||
NormBlockPool block_pool;
|
||||
NormSegmentPool segment_pool;
|
||||
NormEncoder encoder;
|
||||
NormObjectTable tx_table;
|
||||
NormSlidingMask tx_pending_mask;
|
||||
NormSlidingMask tx_repair_mask;
|
||||
ProtoTimer repair_timer;
|
||||
NormBlockPool block_pool;
|
||||
NormSegmentPool segment_pool;
|
||||
NormEncoder encoder;
|
||||
|
||||
NormObjectId next_tx_object_id;
|
||||
unsigned int tx_cache_count_min;
|
||||
unsigned int tx_cache_count_max;
|
||||
NormObjectSize tx_cache_size_max;
|
||||
ProtoTimer flush_timer;
|
||||
int flush_count;
|
||||
bool posted_tx_queue_empty;
|
||||
ProtoTimer watermark_timer;
|
||||
int watermark_count;
|
||||
// (TBD) watermark_object_id, watermark_block_id, watermark_symbol_id
|
||||
NormObjectId next_tx_object_id;
|
||||
unsigned int tx_cache_count_min;
|
||||
unsigned int tx_cache_count_max;
|
||||
NormObjectSize tx_cache_size_max;
|
||||
ProtoTimer flush_timer;
|
||||
int flush_count;
|
||||
bool posted_tx_queue_empty;
|
||||
|
||||
// For postive acknowledgement collection
|
||||
NormNodeTree acking_node_tree;
|
||||
unsigned int acking_node_count;
|
||||
bool watermark_pending;
|
||||
NormObjectId watermark_object_id;
|
||||
NormBlockId watermark_block_id;
|
||||
NormSegmentId watermark_segment_id;
|
||||
unsigned int acks_collected;
|
||||
|
||||
// for unicast nack/cc feedback suppression
|
||||
bool advertise_repairs;
|
||||
bool suppress_nonconfirmed;
|
||||
double suppress_rate;
|
||||
double suppress_rtt;
|
||||
bool advertise_repairs;
|
||||
bool suppress_nonconfirmed;
|
||||
double suppress_rate;
|
||||
double suppress_rtt;
|
||||
|
||||
ProtoTimer probe_timer; // GRTT/congestion control probes
|
||||
bool probe_proactive;
|
||||
bool probe_pending; // true while CMD(CC) enqueued
|
||||
bool probe_reset;
|
||||
ProtoTimer probe_timer; // GRTT/congestion control probes
|
||||
bool probe_proactive;
|
||||
bool probe_pending; // true while CMD(CC) enqueued
|
||||
bool probe_reset;
|
||||
|
||||
double grtt_interval; // current GRTT update interval
|
||||
double grtt_interval_min; // minimum GRTT update interval
|
||||
double grtt_interval_max; // maximum GRTT update interval
|
||||
double grtt_interval; // current GRTT update interval
|
||||
double grtt_interval_min; // minimum GRTT update interval
|
||||
double grtt_interval_max; // maximum GRTT update interval
|
||||
|
||||
double grtt_max;
|
||||
unsigned int grtt_decrease_delay_count;
|
||||
bool grtt_response;
|
||||
double grtt_current_peak;
|
||||
double grtt_measured;
|
||||
double grtt_age;
|
||||
double grtt_advertised;
|
||||
UINT8 grtt_quantized;
|
||||
double gsize_measured;
|
||||
double gsize_advertised;
|
||||
UINT8 gsize_quantized;
|
||||
double grtt_max;
|
||||
unsigned int grtt_decrease_delay_count;
|
||||
bool grtt_response;
|
||||
double grtt_current_peak;
|
||||
double grtt_measured;
|
||||
double grtt_age;
|
||||
double grtt_advertised;
|
||||
UINT8 grtt_quantized;
|
||||
double gsize_measured;
|
||||
double gsize_advertised;
|
||||
UINT8 gsize_quantized;
|
||||
|
||||
// Server congestion control parameters
|
||||
bool cc_enable;
|
||||
UINT8 cc_sequence;
|
||||
NormNodeList cc_node_list;
|
||||
bool cc_slow_start;
|
||||
double sent_rate; // measured sent rate
|
||||
struct timeval prev_update_time; // for sent_rate measurement
|
||||
unsigned long sent_accumulator; // for sent_rate measurement
|
||||
double nominal_packet_size;
|
||||
bool cc_enable;
|
||||
UINT8 cc_sequence;
|
||||
NormNodeList cc_node_list;
|
||||
bool cc_slow_start;
|
||||
double sent_rate; // measured sent rate
|
||||
struct timeval prev_update_time; // for sent_rate measurement
|
||||
unsigned long sent_accumulator; // for sent_rate measurement
|
||||
double nominal_packet_size;
|
||||
|
||||
// Client parameters
|
||||
bool is_client;
|
||||
NormNodeTree server_tree;
|
||||
unsigned long remote_server_buffer_size;
|
||||
bool unicast_nacks;
|
||||
bool client_silent;
|
||||
bool is_client;
|
||||
NormNodeTree server_tree;
|
||||
unsigned long remote_server_buffer_size;
|
||||
bool unicast_nacks;
|
||||
bool client_silent;
|
||||
NormServerNode::RepairBoundary default_repair_boundary;
|
||||
NormObject::NackingMode default_nacking_mode;
|
||||
|
||||
// Protocol test/debug parameters
|
||||
bool trace;
|
||||
double tx_loss_rate; // for correlated loss
|
||||
double rx_loss_rate; // for uncorrelated loss
|
||||
bool trace;
|
||||
double tx_loss_rate; // for correlated loss
|
||||
double rx_loss_rate; // for uncorrelated loss
|
||||
|
||||
// Linkers
|
||||
NormSession* next;
|
||||
NormSession* next;
|
||||
}; // end class NormSession
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -831,7 +831,7 @@ void NormSimAgent::Notify(NormController::Event event,
|
|||
break;
|
||||
} // end switch (object->GetType())
|
||||
break;
|
||||
case RX_OBJECT_COMPLETE:
|
||||
case RX_OBJECT_COMPLETED:
|
||||
{
|
||||
switch(object->GetType())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,231 @@
|
|||
////////////////////////////////////////////////////
|
||||
// This is a test application for experimenting
|
||||
// with the NORM API implementation during its
|
||||
// development. A better-documented and complete
|
||||
// example of the NORM API usage will be provided
|
||||
// when the NORM API is more complete.
|
||||
|
||||
#include "normApi.h"
|
||||
#include "protokit.h" // for protolib debug, stuff, etc
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef UNIX
|
||||
#include <unistd.h> // for "sleep()"
|
||||
#endif // UNIX
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
printf("normTest starting ...\n");
|
||||
|
||||
SetDebugLevel(4);
|
||||
|
||||
NormInstanceHandle instance = NormCreateInstance();
|
||||
|
||||
#ifdef WIN32
|
||||
const char* cachePath = "C:\\Adamson\\Temp\\cache\\";
|
||||
#else
|
||||
const char* cachePath = "/tmp/";
|
||||
#endif // if/else WIN32/UNIX
|
||||
|
||||
NormSetCacheDirectory(instance, cachePath);
|
||||
|
||||
NormSessionHandle session = NormCreateSession(instance,
|
||||
"224.1.2.3",
|
||||
6003,
|
||||
NORM_NODE_ANY);
|
||||
|
||||
NormSetMessageTrace(session, true);
|
||||
|
||||
NormSetTxLoss(session, 10.0); // 1% packet loss
|
||||
|
||||
NormSetGrttEstimate(session, 0.1);//0.001); // 1 msec initial grtt
|
||||
|
||||
NormSetTransmitRate(session, 1.0e+05); // in bits/second
|
||||
|
||||
NormSetDefaultRepairBoundary(session, NORM_BOUNDARY_BLOCK);
|
||||
|
||||
// Uncomment to receive own traffic
|
||||
NormSetLoopback(session, true);
|
||||
|
||||
// Uncomment this line to participate as a receiver
|
||||
NormStartReceiver(session, 1024*1024);
|
||||
|
||||
// Uncomment the following line to start sender
|
||||
NormStartSender(session, 1024*1024, 1024, 64, 0);
|
||||
|
||||
NormAddAckingNode(session, NormGetLocalNodeId(session));
|
||||
|
||||
NormObjectHandle stream = NORM_OBJECT_INVALID;
|
||||
const char* filePath = "/home/adamson/images/art/giger/giger205.jpg";
|
||||
const char* fileName = "ferrari.jpg";
|
||||
|
||||
// Uncomment this line to send a stream instead of the file
|
||||
stream = NormOpenStream(session, 1024*1024);
|
||||
NormSetStreamFlushMode(stream, NORM_FLUSH_NONE);
|
||||
|
||||
int index = -1; // used to monitor reliable stream reception
|
||||
int sendCount = 0;
|
||||
int sendMax = 200;
|
||||
NormEvent theEvent;
|
||||
while (NormGetNextEvent(instance, &theEvent))
|
||||
{
|
||||
switch (theEvent.type)
|
||||
{
|
||||
case NORM_TX_QUEUE_EMPTY:
|
||||
if (NORM_OBJECT_INVALID != stream)
|
||||
{
|
||||
// Write a message to the "stream"
|
||||
char buffer[1024];
|
||||
sprintf(buffer, "normTest says hello %d ...\n", sendCount++);
|
||||
unsigned int len = strlen(buffer);
|
||||
TRACE("writing to stream ...\n");
|
||||
if (len != NormWriteStream(stream, buffer, len))
|
||||
TRACE("incomplete write:%u\n", len);
|
||||
else
|
||||
{
|
||||
NormFlushStream(stream);
|
||||
NormSetWatermark(session, stream);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NormObjectHandle txFile =
|
||||
NormQueueFile(session,
|
||||
filePath,
|
||||
fileName,
|
||||
strlen(fileName));
|
||||
// Repeatedly queue our file for sending
|
||||
if (NORM_OBJECT_INVALID == txFile)
|
||||
{
|
||||
DMSG(0, "normTest: error queuing file: %s\n", filePath);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("QUEUED FILE ...\n");
|
||||
NormSetWatermark(session, txFile);
|
||||
}
|
||||
sendCount++;
|
||||
}
|
||||
break;
|
||||
|
||||
case NORM_TX_OBJECT_PURGED:
|
||||
DMSG(3, "normTest: NORM_TX_OBJECT_PURGED event ...\n");
|
||||
break;
|
||||
|
||||
case NORM_RX_OBJECT_NEW:
|
||||
DMSG(3, "normTest: NORM_RX_OBJECT_NEW event ...\n");
|
||||
break;
|
||||
|
||||
case NORM_RX_OBJECT_INFO:
|
||||
// Assume info contains '/' delimited <path/fileName> string
|
||||
if (NORM_OBJECT_FILE == NormGetObjectType(theEvent.object))
|
||||
{
|
||||
NormObjectTransportId id = NormGetObjectTransportId(theEvent.object);
|
||||
if (0 != (id & 0x01))
|
||||
{
|
||||
//NormCancelObject(theEvent.object);
|
||||
//break;
|
||||
}
|
||||
|
||||
char fileName[PATH_MAX];
|
||||
strcpy(fileName, cachePath);
|
||||
int pathLen = strlen(fileName);
|
||||
unsigned short nameLen = PATH_MAX - pathLen;
|
||||
NormGetObjectInfo(theEvent.object, fileName+pathLen, &nameLen);
|
||||
fileName[nameLen + pathLen] = '\0';
|
||||
char* ptr = fileName + 5;
|
||||
while ('\0' != *ptr)
|
||||
{
|
||||
if ('/' == *ptr) *ptr = PROTO_PATH_DELIMITER;
|
||||
ptr++;
|
||||
}
|
||||
if (!NormSetFileName(theEvent.object, fileName))
|
||||
TRACE("normTest: NormSetFileName(%s) error\n", fileName);
|
||||
DMSG(3, "normTest: recv'd info for file: %s\n", fileName);
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case NORM_RX_OBJECT_UPDATE:
|
||||
{
|
||||
//TRACE("normTest: NORM_RX_OBJECT_UPDATE event ...\n");
|
||||
if (NORM_OBJECT_STREAM != NormGetObjectType(theEvent.object))
|
||||
break;
|
||||
char buffer[1024];
|
||||
unsigned int len = 1023;
|
||||
do
|
||||
{
|
||||
len = 1023;
|
||||
if (NormReadStream(theEvent.object, buffer, &len))
|
||||
{
|
||||
buffer[len] = '\0';
|
||||
if (len)
|
||||
{
|
||||
TRACE("normTest: recvd(%u):\n\"%s\"\n", len, buffer);
|
||||
// This while() loop is cheesy test, looking for broken stream
|
||||
//
|
||||
char* ptr = buffer;
|
||||
while ((ptr = strstr(ptr, "hello")))
|
||||
{
|
||||
int value;
|
||||
if (1 == sscanf(ptr, "hello %d", &value))
|
||||
{
|
||||
if (index >= 0)
|
||||
{
|
||||
if (1 != (value - index))
|
||||
TRACE("WARNING! possible break? value:%d index:%d\n",
|
||||
value, index);
|
||||
}
|
||||
index = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("couldn't find index\n");
|
||||
}
|
||||
ptr += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("normTest: error reading stream\n");
|
||||
break;
|
||||
}
|
||||
} while (0 != len);
|
||||
break;
|
||||
}
|
||||
|
||||
case NORM_RX_OBJECT_COMPLETED:
|
||||
TRACE("normTest: NORM_RX_OBJECT_COMPLETED event ...\n");
|
||||
break;
|
||||
|
||||
case NORM_RX_OBJECT_ABORTED:
|
||||
TRACE("normTest: NORM_RX_OBJECT_ABORTED event ...\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
TRACE("Got event type: %d\n", theEvent.type);
|
||||
} // end switch(theEvent.type)
|
||||
|
||||
// Break after sending "sendMax" messages or files
|
||||
if (sendCount >= sendMax) break;
|
||||
|
||||
} // end while (NormGetNextEvent())
|
||||
|
||||
fprintf(stderr, "normTest shutting down in 30 sec ...\n");
|
||||
#ifdef WIN32
|
||||
Sleep(30000);
|
||||
#else
|
||||
sleep(30); // allows time for cleanup if we're sending to someone else
|
||||
#endif // if/else WIN32/UNIX
|
||||
|
||||
NormCloseStream(stream);
|
||||
NormStopReceiver(session);
|
||||
NormStopSender(session);
|
||||
NormDestroySession(session);
|
||||
NormDestroyInstance(instance);
|
||||
|
||||
fprintf(stderr, "normTest: Done.\n");
|
||||
return 0;
|
||||
} // end main()
|
||||
|
|
@ -32,6 +32,6 @@
|
|||
|
||||
#ifndef _NORM_VERSION
|
||||
#define _NORM_VERSION
|
||||
#define VERSION "1.2b1"
|
||||
#define VERSION "1.2b2"
|
||||
#endif // _NORM_VERSION
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class RaftApp : public ProtoApp
|
|||
const char* const RaftApp::CMD_LIST[] =
|
||||
{
|
||||
"+debug", // debug <level>
|
||||
"+listen", // recv [<mcastAddr>/]<port>
|
||||
"+listen", // recv [<mcastAddr>/]<port>
|
||||
"+dest", // send <addr>/<port>
|
||||
"+rtspProxy", // rtsp <rtspUrl>
|
||||
NULL
|
||||
|
|
@ -467,7 +467,7 @@ void RaftApp::OnClientSocketEvent(ProtoSocket& /*theSocket*/,
|
|||
while (rtsp_client_socket.Recv(buffer, buflen))
|
||||
{
|
||||
buffer[buflen] = '\0';
|
||||
TRACE("%s");
|
||||
TRACE("%s", buffer);
|
||||
}
|
||||
TRACE("\n");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ for {set i 2} {$i <= $numNodes} {incr i} {
|
|||
}
|
||||
$ns_ at 0.0 "$norm(1) sendFile 64000"
|
||||
|
||||
$ns_ at 3000.0 "finish $ns_ $f $nf"
|
||||
$ns_ at 300.0 "finish $ns_ $f $nf"
|
||||
|
||||
proc finish {ns_ f nf} {
|
||||
$ns_ flush-trace
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ NS = ../ns
|
|||
|
||||
INCLUDES = $(TCL_INCL_PATH) $(SYSTEM_INCLUDES) -I$(UNIX) -I$(COMMON) -I$(PROTOLIB)/common
|
||||
|
||||
CFLAGS = -DPROTO_DEBUG -DUNIX -O -fPIC $(SYSTEM_HAVES) $(INCLUDES)
|
||||
CFLAGS = -g -DPROTO_DEBUG -DUNIX -D_FILE_OFFSET_BITS=64 -O -fPIC $(SYSTEM_HAVES) $(INCLUDES)
|
||||
|
||||
LDFLAGS = $(SYSTEM_LDFLAGS)
|
||||
|
||||
|
|
@ -84,6 +84,14 @@ APP_OBJ = $(APP_SRC:.cpp=.o)
|
|||
norm: $(APP_OBJ) libnorm.a $(LIBPROTO)
|
||||
$(CC) $(CFLAGS) -o $@ $(APP_OBJ) $(LDFLAGS) libnorm.a $(LIBPROTO) $(LIBS)
|
||||
|
||||
|
||||
# (normTest) test of NORM API
|
||||
TEST_SRC = $(COMMON)/normApi.cpp $(COMMON)/normTest.cpp
|
||||
TEST_OBJ = $(TEST_SRC:.cpp=.o)
|
||||
|
||||
normTest: $(TEST_OBJ) libnorm.a $(LIBPROTO)
|
||||
$(CC) $(CFLAGS) -o $@ $(TEST_OBJ) $(LDFLAGS) libnorm.a $(LIBPROTO) $(LIBS)
|
||||
|
||||
# (raft) command-line reliable tunnel helper
|
||||
RAFT_SRC = $(COMMON)/raft.cpp
|
||||
RAFT_OBJ = $(RAFT_SRC:.cpp=.o)
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ SYSTEM_LIBS = -ldl
|
|||
# (We export these for other Makefiles as needed)
|
||||
#
|
||||
|
||||
SYSTEM_HAVES = -DLINUX -DHAVE_IPV6 -DHAVE_GETLOGIN -DHAVE_LOCKF \
|
||||
-DHAVE_OLD_SIGNALHANDLER -DHAVE_DIRFD -DHAVE_ASSERT $(NETSEC)
|
||||
SYSTEM_HAVES = -DLINUX -DHAVE_IPV6 -DHAVE_GETLOGIN -D_FILE_OFFSET_BITS=64 -DHAVE_LOCKF \
|
||||
-DHAVE_OLD_SIGNALHANDLER -DHAVE_DIRFD -DHAVE_ASSERT
|
||||
|
||||
SYSTEM_SRC =
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
# (Where to find X11 libraries, etc)
|
||||
#
|
||||
|
||||
SYSTEM_INCLUDES = -I/usr/X11R6/include
|
||||
SYSTEM_LDFLAGS = -L/usr/X11R6/lib
|
||||
SYSTEM_LIBS =
|
||||
SYSTEM_INCLUDES =
|
||||
SYSTEM_LDFLAGS =
|
||||
SYSTEM_LIBS = -lresolv
|
||||
|
||||
# 2) System specific capabilities
|
||||
# Must choose appropriate for the following:
|
||||
|
|
@ -36,15 +36,16 @@ SYSTEM_LIBS =
|
|||
# (We export these for other Makefiles as needed)
|
||||
#
|
||||
|
||||
export SYSTEM_HAVES = -DMACOSX -DHAVE_IPV6 -DHAVE_ASSERT -DHAVE_GETLOGIN -DHAVE_FLOCK -DHAVE_DIRFD $(DNETSEC) -DSOCKLEN_T=int
|
||||
SYSTEM_HAVES = -DMACOSX -DHAVE_IPV6 -DHAVE_ASSERT -DHAVE_GETLOGIN -DHAVE_FLOCK \
|
||||
-D_FILE_OFFSET_BITS=64 -DHAVE_DIRFD -DSOCKLEN_T=int
|
||||
|
||||
SYSTEM_SRC = bsdRouteMgr.cpp
|
||||
|
||||
# The "SYSTEM" keyword can be used for dependent makes
|
||||
SYSTEM = macosx
|
||||
|
||||
export CC = g++
|
||||
export RANLIB = ranlib
|
||||
export AR = ar
|
||||
CC = g++
|
||||
RANLIB = ranlib
|
||||
AR = ar
|
||||
|
||||
include Makefile.common
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
# 1) System specific additional libraries, include paths, etc
|
||||
# (Where to find X11 libraries, etc)
|
||||
#
|
||||
SYSTEM_INCLUDES = -I/usr/openwin/include
|
||||
SYSTEM_LDFLAGS = -L/usr/openwin/lib -R/usr/openwin/lib
|
||||
SYSTEM_INCLUDES =
|
||||
SYSTEM_LDFLAGS =
|
||||
SYSTEM_LIBS = -ldl -lnsl -lsocket -lresolv
|
||||
|
||||
# 2) System specific capabilities
|
||||
|
|
@ -35,7 +35,8 @@ SYSTEM_LIBS = -ldl -lnsl -lsocket -lresolv
|
|||
# (We export these for other Makefiles as needed)
|
||||
#
|
||||
|
||||
SYSTEM_HAVES = -DHAVE_IPV6 -DHAVE_ASSERT -DHAVE_CUSERID -DHAVE_LOCKF $(NETSEC) -DSOLARIS
|
||||
SYSTEM_HAVES = -DHAVE_IPV6 -DHAVE_ASSERT -DHAVE_CUSERID -DHAVE_LOCKF \
|
||||
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DSOLARIS
|
||||
|
||||
SYSTEM = solaris
|
||||
|
||||
|
|
|
|||
|
|
@ -234,6 +234,10 @@ bool UnixPostProcessor::ProcessFile(const char* path)
|
|||
// Restore signal handlers for parent
|
||||
signal(SIGTERM, sigtermHandler);
|
||||
signal(SIGINT, sigintHandler);
|
||||
// The use of "waitpid()" here is a work-around
|
||||
// for an IRIX SIGCHLD issue
|
||||
int status;
|
||||
while (waitpid(-1, &status, WNOHANG) > 0);
|
||||
signal(SIGCHLD, sigchldHandler);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,24 @@ Package=<4>
|
|||
|
||||
###############################################################################
|
||||
|
||||
Project: "normTest"=..\normTest.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name NormLib
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Protokit
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
|
|
|
|||
BIN
win32/Norm.opt
BIN
win32/Norm.opt
Binary file not shown.
|
|
@ -0,0 +1,106 @@
|
|||
# Microsoft Developer Studio Project File - Name="normTest" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=normTest - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "normTest.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "normTest.mak" CFG="normTest - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "normTest - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "normTest - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "normTest - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\common" /I "..\protolib\common" /I "..\protolib\win32" /D "NDEBUG" /D "PROTO_DEBUG" /D "HAVE_IPV6" /D "HAVE_ASSERT" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 iphlpapi.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "normTest - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\common" /I "..\protolib\common" /I "..\protolib\win32" /D "_DEBUG" /D "PROTO_DEBUG" /D "HAVE_IPV6" /D "HAVE_ASSERT" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 iphlpapi.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "normTest - Win32 Release"
|
||||
# Name "normTest - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\common\normApi.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\common\normTest.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
Loading…
Reference in New Issue