pull/2/head
Jeff Weston 2019-09-11 11:32:15 -04:00
parent c74826c08f
commit 48a5d68c05
6 changed files with 81 additions and 46 deletions

View File

@ -61,6 +61,7 @@ class NormApp : public NormController, public ProtoApp
unsigned int input_length; unsigned int input_length;
bool input_active; bool input_active;
bool push_stream; bool push_stream;
NormStreamObject::FlushType msg_flush_mode;
bool input_messaging; // stream input mode bool input_messaging; // stream input mode
UINT16 input_msg_length; UINT16 input_msg_length;
UINT16 input_msg_index; UINT16 input_msg_index;
@ -110,7 +111,8 @@ NormApp::NormApp()
: session_mgr(GetTimerMgr(), GetSocketNotifier()), : session_mgr(GetTimerMgr(), GetSocketNotifier()),
session(NULL), tx_stream(NULL), rx_stream(NULL), input(NULL), output(NULL), session(NULL), tx_stream(NULL), rx_stream(NULL), input(NULL), output(NULL),
input_index(0), input_length(0), input_active(false), input_index(0), input_length(0), input_active(false),
push_stream(false), input_messaging(false), input_msg_length(0), input_msg_index(0), push_stream(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), output_index(0), output_messaging(false), output_msg_length(0), output_msg_sync(false),
address(NULL), port(0), ttl(3), tx_rate(64000.0), cc_enable(false), address(NULL), port(0), ttl(3), tx_rate(64000.0), cc_enable(false),
segment_size(1024), ndata(32), nparity(16), auto_parity(0), extra_parity(0), segment_size(1024), ndata(32), nparity(16), auto_parity(0), extra_parity(0),
@ -152,6 +154,7 @@ const char* const NormApp::cmd_list[] =
"+cc", // congestion control on/off "+cc", // congestion control on/off
"+rate", // tx date rate (bps) "+rate", // tx date rate (bps)
"-push", // push stream writes for real-time messaging "-push", // push stream writes for real-time messaging
"+flush", // message flushing mode ("none", "passive", or "active")
"+input", // send stream input "+input", // send stream input
"+output", // recv stream output "+output", // recv stream output
"+minput", // send message stream input "+minput", // send message stream input
@ -516,6 +519,21 @@ bool NormApp::ProcessCommand(const char* cmd, const char* val)
{ {
push_stream = true; push_stream = true;
} }
else if (!strncmp("flush", cmd, len))
{
int valLen = strlen(val);
if (!strncmp("none", val, valLen))
msg_flush_mode = NormStreamObject::FLUSH_NONE;
else if (!strncmp("passive", val, valLen))
msg_flush_mode = NormStreamObject::FLUSH_PASSIVE;
else if (!strncmp("active", val, valLen))
msg_flush_mode = NormStreamObject::FLUSH_ACTIVE;
else
{
DMSG(0, "NormApp::ProcessCommand(flush) invalid msg flush mode!\n");
return false;
}
}
else if (!strncmp("processor", cmd, len)) else if (!strncmp("processor", cmd, len))
{ {
if (!post_processor->SetCommand(val)) if (!post_processor->SetCommand(val))
@ -605,8 +623,8 @@ void NormApp::DoInputReady(ProtoDispatcher::Descriptor /*descriptor*/,
void NormApp::OnInputReady() void NormApp::OnInputReady()
{ {
//TRACE("NormApp::OnInputReady() ...\n"); //DMSG(0, "NormApp::OnInputReady() ...\n");
bool flush = false; NormStreamObject::FlushType flushType = NormStreamObject::FLUSH_NONE;
// write to the stream while input is available _and_ // write to the stream while input is available _and_
// the stream has buffer space for input // the stream has buffer space for input
while (input) while (input)
@ -682,7 +700,7 @@ void NormApp::OnInputReady()
} }
if (stdin != input) fclose(input); if (stdin != input) fclose(input);
input = NULL; input = NULL;
flush = true; flushType = NormStreamObject::FLUSH_ACTIVE;
} }
else if (ferror(input)) else if (ferror(input))
{ {
@ -705,10 +723,10 @@ void NormApp::OnInputReady()
unsigned int writeLength = input_length;// ? input_length - input_index : 0; unsigned int writeLength = input_length;// ? input_length - input_index : 0;
if (writeLength || flush) if (writeLength || (NormStreamObject::FLUSH_NONE != flushType))
{ {
unsigned int wroteLength = tx_stream->Write(input_buffer+input_index, unsigned int wroteLength = tx_stream->Write(input_buffer+input_index,
writeLength, flush, false, writeLength, flushType, false,
push_stream); push_stream);
input_length -= wroteLength; input_length -= wroteLength;
if (0 == input_length) if (0 == input_length)
@ -722,8 +740,8 @@ void NormApp::OnInputReady()
{ {
input_msg_index = 0; input_msg_index = 0;
input_msg_length = 0; input_msg_length = 0;
// Mark EOM // Mark EOM _and_ flush
tx_stream->Write(NULL, 0, false, true, false); tx_stream->Write(NULL, 0, msg_flush_mode, true, false);
} }
} }
if (wroteLength < writeLength) if (wroteLength < writeLength)
@ -792,7 +810,7 @@ void NormApp::Notify(NormController::Event event,
case RX_OBJECT_NEW: case RX_OBJECT_NEW:
{ {
//TRACE("NormApp::Notify(RX_OBJECT_NEW) ...\n"); //DMSG(0, "NormApp::Notify(RX_OBJECT_NEW) ...\n");
// It's up to the app to "accept" the object // It's up to the app to "accept" the object
switch (object->GetType()) switch (object->GetType())
{ {
@ -863,7 +881,7 @@ void NormApp::Notify(NormController::Event event,
} }
case RX_OBJECT_INFO: case RX_OBJECT_INFO:
//TRACE("NormApp::Notify(RX_OBJECT_INFO) ...\n"); //DMSG(0, "NormApp::Notify(RX_OBJECT_INFO) ...\n");
switch(object->GetType()) switch(object->GetType())
{ {
case NormObject::FILE: case NormObject::FILE:
@ -903,7 +921,7 @@ void NormApp::Notify(NormController::Event event,
break; break;
case RX_OBJECT_UPDATE: case RX_OBJECT_UPDATE:
//TRACE("NormApp::Notify(RX_OBJECT_UPDATE) ...\n"); //DMSG(0, "NormApp::Notify(RX_OBJECT_UPDATE) ...\n");
switch (object->GetType()) switch (object->GetType())
{ {
case NormObject::FILE: case NormObject::FILE:
@ -949,7 +967,6 @@ void NormApp::Notify(NormController::Event event,
findMsgSync = false; findMsgSync = false;
} }
if(!((NormStreamObject*)object)->Read(output_buffer+output_index, if(!((NormStreamObject*)object)->Read(output_buffer+output_index,
&readLength, findMsgSync)) &readLength, findMsgSync))
{ {
@ -965,11 +982,7 @@ void NormApp::Notify(NormController::Event event,
} }
else else
{ {
if (readLength > 0) if (readLength > 0) output_msg_sync = true;
output_msg_sync = true;
TRACE("read %d bytes (index:%d) %hu...\n", readLength, output_index,
*((UINT16*)(output_buffer+output_index)));
} }
if (readLength) if (readLength)
@ -1037,7 +1050,7 @@ void NormApp::Notify(NormController::Event event,
case RX_OBJECT_COMPLETE: case RX_OBJECT_COMPLETE:
{ {
//TRACE("NormApp::Notify(RX_OBJECT_COMPLETE) ...\n"); //DMSG(0, "NormApp::Notify(RX_OBJECT_COMPLETE) ...\n");
switch(object->GetType()) switch(object->GetType())
{ {
case NormObject::FILE: case NormObject::FILE:
@ -1222,7 +1235,7 @@ bool NormApp::OnStartup(int argc, const char*const* argv)
void NormApp::OnShutdown() void NormApp::OnShutdown()
{ {
//TRACE("NormApp::OnShutdown() ...\n"); //DMSG(0, "NormApp::OnShutdown() ...\n");
session_mgr.Destroy(); session_mgr.Destroy();
if (input) if (input)
{ {

View File

@ -369,7 +369,7 @@ class NormMsg
UINT16 length; UINT16 length;
UINT16 header_length; UINT16 header_length;
UINT16 header_length_base; UINT16 header_length_base;
ProtoAddress addr; // src or dst address ProtoAddress addr; // src or dst address
NormMsg* prev; NormMsg* prev;
NormMsg* next; NormMsg* next;

View File

@ -369,7 +369,7 @@ bool NormObject::AppendRepairAdv(NormCmdRepairAdvMsg& cmd)
{ {
NormBlockId currentId = nextId; NormBlockId currentId = nextId;
nextId++; nextId++;
//TRACE("NormObject::AppendRepairAdv() testing block:%lu nextId:%lu endId:%lu\n", //DMSG(0, "NormObject::AppendRepairAdv() testing block:%lu nextId:%lu endId:%lu\n",
// (UINT32)currentId, (UINT32)nextId, (UINT32)endId); // (UINT32)currentId, (UINT32)nextId, (UINT32)endId);
bool repairEntireBlock = repair_mask.Test(currentId); bool repairEntireBlock = repair_mask.Test(currentId);
if (repairEntireBlock) if (repairEntireBlock)
@ -848,10 +848,10 @@ bool NormObject::AppendRepairRequest(NormNackMsg& nack,
} // end if (appendRequest) } // end if (appendRequest)
nextId++; nextId++;
iterating = GetNextPending(nextId); iterating = GetNextPending(nextId);
//TRACE("got next pending>%lu result:%d\n", (UINT32)nextId, iterating); //DMSG(0, "got next pending>%lu result:%d\n", (UINT32)nextId, iterating);
iterating = iterating && (flush || (nextId <= max_pending_block)); iterating = iterating && (flush || (nextId <= max_pending_block));
} // end while (iterating || (0 != consecutiveCount)) } // end while (iterating || (0 != consecutiveCount))
//TRACE("bailed ...\n"); //DMSG(0, "bailed ...\n");
} }
else else
{ {
@ -984,7 +984,11 @@ void NormObject::HandleObjectMessage(const NormObjectMsg& msg,
if (payloadLength < payloadMax) if (payloadLength < payloadMax)
memset(segment+payloadLength, 0, payloadMax-payloadLength); memset(segment+payloadLength, 0, payloadMax-payloadLength);
if (data.FlagIsSet(NormObjectMsg::FLAG_MSG_START)) if (data.FlagIsSet(NormObjectMsg::FLAG_MSG_START))
{
segment[payloadMax] = NormObjectMsg::FLAG_MSG_START; segment[payloadMax] = NormObjectMsg::FLAG_MSG_START;
//DMSG(0, "starting segment payload len>%hu msg_len>%hu\n",
// payloadLength, ntohs(*((UINT16*)(segment+8)))) ;
}
else else
segment[payloadMax] = 0; segment[payloadMax] = 0;
block->AttachSegment(segmentId, segment); block->AttachSegment(segmentId, segment);
@ -1285,7 +1289,16 @@ bool NormObject::NextServerMsg(NormObjectMsg* msg)
#ifdef SIMULATE #ifdef SIMULATE
payloadMax = MIN(payloadMax, SIM_PAYLOAD_MAX); payloadMax = MIN(payloadMax, SIM_PAYLOAD_MAX);
#endif // SIMULATE #endif // SIMULATE
if (buffer[payloadMax]) data->SetFlag(NormObjectMsg::FLAG_MSG_START); if (buffer[payloadMax])
{
data->SetFlag(NormObjectMsg::FLAG_MSG_START);
//DMSG(0, "read start segment len:%hu\n", ntohs(*((UINT16*)(buffer+2))));
//DMSG(0, " message len:%hu\n", ntohs(*((UINT16*)(buffer+8))));
}
else
{
//DMSG(0, "non-start segment read ...\n");
}
} }
// Perform incremental FEC encoding as needed // Perform incremental FEC encoding as needed
@ -1826,7 +1839,7 @@ bool NormStreamObject::StreamUpdateStatus(NormBlockId blockId)
else else
{ {
// Stream broken // Stream broken
//TRACE("NormObject::StreamUpdateStatus() broken 1 ...\n"); //DMSG(0, "NormObject::StreamUpdateStatus() broken 1 ...\n");
return false; return false;
} }
} }
@ -1836,7 +1849,7 @@ bool NormStreamObject::StreamUpdateStatus(NormBlockId blockId)
if (delta > NormBlockId(pending_mask.Size())) if (delta > NormBlockId(pending_mask.Size()))
{ {
// Stream broken // Stream broken
//TRACE("NormObject::StreamUpdateStatus() broken 2 ...\n"); //DMSG(0, "NormObject::StreamUpdateStatus() broken 2 ...\n");
return false; return false;
} }
else else
@ -1950,7 +1963,7 @@ bool NormStreamObject::WriteSegment(NormBlockId blockId,
if (tempOffset == read_offset) if (tempOffset == read_offset)
{ {
// App didn't want any data here, purge segment // App didn't want any data here, purge segment
TRACE("NormStreamObject::WriteSegment() app didn't want data ?!\n"); DMSG(0, "NormStreamObject::WriteSegment() app didn't want data ?!\n");
ASSERT(0); ASSERT(0);
char* s = block->DetachSegment(read_index.segment); char* s = block->DetachSegment(read_index.segment);
segment_pool.Put(s); segment_pool.Put(s);
@ -1994,7 +2007,7 @@ bool NormStreamObject::WriteSegment(NormBlockId blockId,
{ {
char* s = segment_pool.Get(); char* s = segment_pool.Get();
ASSERT(s != NULL); // for now, this should always succeed ASSERT(s != NULL); // for now, this should always succeed
UINT16 payloadLength = NormDataMsg::ReadStreamPayloadLength(segment); UINT16 payloadLength = NormDataMsg::ReadStreamPayloadLength(segment) + NormDataMsg::GetStreamPayloadHeaderLength();
UINT16 payloadMax = segment_size + NormDataMsg::GetStreamPayloadHeaderLength(); UINT16 payloadMax = segment_size + NormDataMsg::GetStreamPayloadHeaderLength();
#ifdef SIMULATE #ifdef SIMULATE
payloadMax = MIN(SIM_PAYLOAD_MAX, payloadMax); payloadMax = MIN(SIM_PAYLOAD_MAX, payloadMax);
@ -2002,6 +2015,7 @@ bool NormStreamObject::WriteSegment(NormBlockId blockId,
#endif // SIMULATE #endif // SIMULATE
memcpy(s, segment, payloadLength); memcpy(s, segment, payloadLength);
s[payloadMax] = segment[payloadMax]; s[payloadMax] = segment[payloadMax];
block->AttachSegment(segmentId, s); block->AttachSegment(segmentId, s);
block->SetPending(segmentId); block->SetPending(segmentId);
ASSERT(block->Segment(segmentId) == s); ASSERT(block->Segment(segmentId) == s);
@ -2083,6 +2097,7 @@ bool NormStreamObject::Read(char* buffer, unsigned int* buflen, bool findMsgStar
LocalNodeId(), index, length); LocalNodeId(), index, length);
read_offset = segmentOffset; read_offset = segmentOffset;
*buflen = bytesRead; *buflen = bytesRead;
ASSERT(0);
return false; return false;
} }
@ -2129,6 +2144,7 @@ bool NormStreamObject::Read(char* buffer, unsigned int* buflen, bool findMsgStar
#else #else
memcpy(buffer+bytesRead, segment+index+NormDataMsg::GetStreamPayloadHeaderLength(), count); memcpy(buffer+bytesRead, segment+index+NormDataMsg::GetStreamPayloadHeaderLength(), count);
#endif // if/else SIMULATE #endif // if/else SIMULATE
index += count; index += count;
bytesRead += count; bytesRead += count;
read_offset += count; read_offset += count;
@ -2153,7 +2169,7 @@ bool NormStreamObject::Read(char* buffer, unsigned int* buflen, bool findMsgStar
} // end NormStreamObject::Read() } // end NormStreamObject::Read()
unsigned long NormStreamObject::Write(const char* buffer, unsigned long len, unsigned long NormStreamObject::Write(const char* buffer, unsigned long len,
bool flush, bool eom, bool push) FlushType flushType, bool eom, bool push)
{ {
unsigned long nBytes = 0; unsigned long nBytes = 0;
do do
@ -2256,15 +2272,13 @@ unsigned long NormStreamObject::Write(const char* buffer, unsigned long len,
simCount = MIN(count, simCount); simCount = MIN(count, simCount);
memcpy(segment+index+NormDataMsg::GetStreamPayloadHeaderLength(), buffer+nBytes, simCount); memcpy(segment+index+NormDataMsg::GetStreamPayloadHeaderLength(), buffer+nBytes, simCount);
#else #else
TRACE("stream write copying %d bytes:index>%d nBytes>%d segment_size>%d space>%d\n",
count, index, nBytes, segment_size, space);
memcpy(segment+index+NormDataMsg::GetStreamPayloadHeaderLength(), buffer+nBytes, count); memcpy(segment+index+NormDataMsg::GetStreamPayloadHeaderLength(), buffer+nBytes, count);
#endif // if/else SIMULATE #endif // if/else SIMULATE
NormDataMsg::WriteStreamPayloadLength(segment, index+count); NormDataMsg::WriteStreamPayloadLength(segment, index+count);
nBytes += count; nBytes += count;
write_offset += count; write_offset += count;
// Is the segment full? or flushing // Is the segment full? or flushing
if ((count == space) || ((flush || eom) && (index > 0) && (nBytes == len))) if ((count == space) || ((FLUSH_NONE != flushType) && (0 != index) && (nBytes == len)))
{ {
block->SetPending(write_index.segment); block->SetPending(write_index.segment);
if (++write_index.segment >= ndata) if (++write_index.segment >= ndata)
@ -2280,16 +2294,16 @@ unsigned long NormStreamObject::Write(const char* buffer, unsigned long len,
{ {
if (eom) if (eom)
msg_start = true; msg_start = true;
if (flush) if (FLUSH_ACTIVE == flushType)
flush_pending = true; flush_pending = true;
else else
flush_pending = false; flush_pending = false;
} }
else else
{ {
flush = false; flushType = FLUSH_NONE;
} }
if (nBytes || flush) session->TouchServer(); if (nBytes || (FLUSH_NONE != flushType)) session->TouchServer();
return nBytes; return nBytes;
} // end NormStreamObject::Write() } // end NormStreamObject::Write()

View File

@ -264,8 +264,18 @@ class NormStreamObject : public NormObject
const char* infoPtr = NULL, const char* infoPtr = NULL,
UINT16 infoLen = 0); UINT16 infoLen = 0);
void Close(); void Close();
bool Accept(unsigned long bufferSize); bool Accept(unsigned long bufferSize);
enum FlushType
{
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);
unsigned long Write(const char* buffer, unsigned long len, FlushType flushType, bool eom, bool push);
bool StreamUpdateStatus(NormBlockId blockId); bool StreamUpdateStatus(NormBlockId blockId);
void StreamResync(NormBlockId nextBlockId) void StreamResync(NormBlockId nextBlockId)
{stream_next_id = nextBlockId;} {stream_next_id = nextBlockId;}
@ -278,8 +288,6 @@ class NormStreamObject : public NormObject
NormSegmentId segmentId, NormSegmentId segmentId,
char* buffer); char* buffer);
bool Read(char* buffer, unsigned int* buflen, bool findMsgStart = false);
unsigned long Write(const char* buffer, unsigned long len, bool flush, bool eom, bool push);
// For receive stream, we can rewind to earliest buffered offset // For receive stream, we can rewind to earliest buffered offset
void Rewind(); void Rewind();

View File

@ -447,7 +447,7 @@ void NormSession::QueueMessage(NormMsg* msg)
double delta = currentTime.tv_sec - lastTime.tv_sec; double delta = currentTime.tv_sec - lastTime.tv_sec;
delta += (((double)currentTime.tv_usec)*1.0e-06 - delta += (((double)currentTime.tv_usec)*1.0e-06 -
((double)lastTime.tv_usec)*1.0e-06); ((double)lastTime.tv_usec)*1.0e-06);
TRACE("NormSession::QueueMessage() deltaT:%lf\n", delta); DMSG(0, "NormSession::QueueMessage() deltaT:%lf\n", delta);
} }
lastTime = currentTime; lastTime = currentTime;
*/ */
@ -793,7 +793,7 @@ void NormTrace(const struct timeval& currentTime,
{ {
const UINT16* x = (const UINT16*)data.GetPayloadData(); const UINT16* x = (const UINT16*)data.GetPayloadData();
if (data.FlagIsSet(NormObjectMsg::FLAG_MSG_START)) if (data.FlagIsSet(NormObjectMsg::FLAG_MSG_START))
DMSG(0, "start byte>%hu ", ntohs(*x)); DMSG(0, "start byte>%hu ", ntohs(x[0]));
} }
break; break;
} }
@ -1111,7 +1111,7 @@ void NormSession::ServerHandleCCFeedback(NormNodeId nodeId,
// adjust rate using current rtt for node // adjust rate using current rtt for node
ccRate = CalculateRate(nominal_packet_size, ccRtt, ccLoss); ccRate = CalculateRate(nominal_packet_size, ccRtt, ccLoss);
} }
//TRACE("NormSession::ServerHandleCCFeedback() node>%lu rate>%lf (rtt>%lf loss>%lf slow_start>%d)\n", //DMSG(0, "NormSession::ServerHandleCCFeedback() node>%lu rate>%lf (rtt>%lf loss>%lf slow_start>%d)\n",
// nodeId, ccRate * 8.0 / 1000.0, ccRtt, ccLoss, (0 != (ccFlags & NormCC::START))); // nodeId, ccRate * 8.0 / 1000.0, ccRtt, ccLoss, (0 != (ccFlags & NormCC::START)));
// Keep the active CLR (if there is one) at the head of the list // Keep the active CLR (if there is one) at the head of the list
@ -2155,7 +2155,7 @@ bool NormSession::SendMessage(NormMsg& msg)
bool drop = (UniformRand(100.0) < tx_loss_rate); bool drop = (UniformRand(100.0) < tx_loss_rate);
if (drop || (clientMsg && client_silent)) if (drop || (clientMsg && client_silent))
{ {
//TRACE("TX MESSAGE DROPPED! (tx_loss_rate:%lf\n", tx_loss_rate); //DMSG(0, "TX MESSAGE DROPPED! (tx_loss_rate:%lf\n", tx_loss_rate);
} }
else else
{ {
@ -2365,7 +2365,7 @@ void NormSession::AdjustRate(bool onResponse)
double scale = tx_rate / sent_rate; double scale = tx_rate / sent_rate;
scale = MAX(1.0, scale); scale = MAX(1.0, scale);
scale = 1.0; scale = 1.0;
//TRACE("NormSession::AdjustRate() slow start clr>%lu rate>%lf tx_rate>%lf sent_rate>%lf\n", //DMSG(0, "NormSession::AdjustRate() slow start clr>%lu rate>%lf tx_rate>%lf sent_rate>%lf\n",
// clr->Id(), clr->GetRate() * 8.0/1000.0, tx_rate * 8.0/1000.0, sent_rate * 8.0/1000.0); // clr->Id(), clr->GetRate() * 8.0/1000.0, tx_rate * 8.0/1000.0, sent_rate * 8.0/1000.0);
tx_rate = clr->GetRate() * scale; tx_rate = clr->GetRate() * scale;
} }
@ -2383,14 +2383,14 @@ void NormSession::AdjustRate(bool onResponse)
tx_rate = clrRate; tx_rate = clrRate;
} }
} }
//TRACE("NormSession::AdjustRate() regular rate adjust clr>%lu rate>%lf (rtt>%lf loss>%lf slow_start>%d)\n", //DMSG(0, "NormSession::AdjustRate() regular rate adjust clr>%lu rate>%lf (rtt>%lf loss>%lf slow_start>%d)\n",
// clr->Id(), tx_rate*8.0/1000.0, clr->GetRtt(), clr->GetLoss(), cc_slow_start); // clr->Id(), tx_rate*8.0/1000.0, clr->GetRtt(), clr->GetLoss(), cc_slow_start);
} }
else if (clr) else if (clr)
{ {
// (TBD) fix CC feedback aging ... // (TBD) fix CC feedback aging ...
/*int feedbackAge = abs((int)cc_sequence - (int)clr->GetCCSequence()); /*int feedbackAge = abs((int)cc_sequence - (int)clr->GetCCSequence());
TRACE("NormSession::AdjustRate() feedback age>%d (%d - %d\n", DMSG(0, "NormSession::AdjustRate() feedback age>%d (%d - %d\n",
feedbackAge, cc_sequence, clr->GetCCSequence()); feedbackAge, cc_sequence, clr->GetCCSequence());
if (feedbackAge > 50) if (feedbackAge > 50)

View File

@ -32,6 +32,6 @@
#ifndef _NORM_VERSION #ifndef _NORM_VERSION
#define _NORM_VERSION #define _NORM_VERSION
#define VERSION "1.1b3" #define VERSION "1.1b4"
#endif // _NORM_VERSION #endif // _NORM_VERSION