Added error flag used to avoid stream re-connect when terminated with error and have nothing to send. Fixed stream idle timer usage.

git-svn-id: http://yate.null.ro/svn/yate/trunk@2917 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2009-11-10 15:27:47 +00:00
parent a9a4088db4
commit 803f4e27f1
3 changed files with 45 additions and 8 deletions

View File

@ -97,9 +97,9 @@ static const String s_googleMailNode = "http://mail.google.com/xmpp/client/caps"
#define JB_PING_TIMEOUT_MIN 10000
#define JB_PING_TIMEOUT_MAX JB_PING_INTERVAL_MIN
// Idle
#define JB_IDLE_INTERVAL 43200000 // 12h
#define JB_IDLE_INTERVAL_MIN 3600000 // 1h
#define JB_IDLE_INTERVAL_MAX 86400000 // 24h
#define JB_IDLE_INTERVAL 3600000 // 1h
#define JB_IDLE_INTERVAL_MIN 600000 // 10min
#define JB_IDLE_INTERVAL_MAX 21600000 // 6h
/*
@ -770,7 +770,7 @@ void JBEngine::initialize(const NamedList& params)
m_pingTimeout = fixValue(params,"stream_pingtimeout",
JB_PING_TIMEOUT,JB_PING_TIMEOUT_MIN,JB_PING_TIMEOUT_MAX);
m_idleTimeout = fixValue(params,"stream_idletimeout",
JB_IDLE_INTERVAL,JB_IDLE_INTERVAL_MIN,JB_IDLE_INTERVAL_MAX,true);
JB_IDLE_INTERVAL,JB_IDLE_INTERVAL_MIN,JB_IDLE_INTERVAL_MAX);
m_initialized = true;
}

View File

@ -98,6 +98,7 @@ const TokenDict JBStream::s_flagName[] = {
{"dialback", DialbackOnly},
{"allowplainauth", AllowPlainAuth},
{"register", RegisterUser},
{"error", InError},
// Internal flags
{"roster_requested", RosterRequested},
{"online", AvailableResource},
@ -576,6 +577,20 @@ void JBStream::terminate(int location, bool destroy, XmlElement* xml, int error,
}
bool sendEndTag = true;
destroy = destroy || final || flag(NoAutoRestart);
// Set error flag
if (state() == Running) {
if (error != XMPPError::NoError)
m_flags |= InError;
else
m_flags &= ~InError;
}
else
m_flags |= InError;
if (flag(InError)) {
// Reset re-connect counter if not internal policy error
if (location || error != XMPPError::Policy)
m_restart = 0;
}
if (error == XMPPError::NoError && m_engine->exiting())
error = XMPPError::Shutdown;
// Last check for sendEndTag
@ -661,7 +676,11 @@ bool JBStream::canProcess(u_int64_t time)
}
if (state() == Idle) {
// Re-connect
// Don't connect if we are in error and have nothing to send
if (m_restart) {
if (flag(InError) && !m_pending.skipNull())
return false;
m_flags &= ~InError;
changeState(Connecting);
m_restart--;
m_engine->connectStream(this);
@ -767,8 +786,7 @@ void JBStream::process(u_int64_t time)
if (!getJids(xml,from,to))
break;
// Restart the idle timer
if (m_state == Running && m_engine->m_idleTimeout)
m_idleTimeout = time + m_engine->m_idleTimeout;
setIdleTimer(time);
// Check if a received stanza is valid and allowed in current state
if (!checkStanzaRecv(xml,from,to))
break;
@ -1202,8 +1220,6 @@ void JBStream::changeState(State newState, u_int64_t time)
return;
DDebug(this,DebugAll,"Changing state from '%s' to '%s' [%p]",
stateName(),lookup(newState,s_stateName),this);
// Always reset the idle timer: something happened
m_idleTimeout = m_engine->m_idleTimeout ? time + m_engine->m_idleTimeout : 0;
// Set/reset state depending data
switch (m_state) {
case WaitStart:
@ -1249,6 +1265,7 @@ void JBStream::changeState(State newState, u_int64_t time)
break;
case Running:
m_flags |= StreamSecured | StreamAuthenticated;
m_flags &= ~InError;
m_setupTimeout = 0;
m_startTimeout = 0;
if (m_state != Running)
@ -1267,6 +1284,8 @@ void JBStream::changeState(State newState, u_int64_t time)
default: ;
}
m_state = newState;
if (m_state == Running)
setIdleTimer(time);
}
// Check for pending events. Set the last event
@ -1342,6 +1361,7 @@ bool JBStream::sendPending(bool streamOnly)
u_int32_t len;
const char* data = eout->getData(len);
if (writeSocket(data,len)) {
setIdleTimer();
// Adjust element's buffer. Remove it from list on completion
eout->dataSent(len);
unsigned int rest = eout->dataCount();
@ -1441,6 +1461,16 @@ bool JBStream::dropXml(XmlElement*& xml, const char* reason)
return true;
}
// Set the idle timer in Running state
void JBStream::setIdleTimer(u_int64_t msecNow)
{
// Set only for c2s in Running state
if (m_type != c2s || m_state != Running || !m_engine->m_idleTimeout)
return;
m_idleTimeout = msecNow + m_engine->m_idleTimeout;
XDebug(this,DebugAll,"Idle timeout set to " FMT64 "ms [%p]",m_idleTimeout,this);
}
// Process incoming elements in Challenge state
// Return false if stream termination was initiated
bool JBStream::processChallenge(XmlElement* xml, const JabberID& from, const JabberID& to)

View File

@ -508,6 +508,7 @@ public:
// offered by server the stream will be terminated
DialbackOnly = 0x00000008,// Outgoing s2s dialback stream
RegisterUser = 0x00000010,// Outgoing c2s register new user
InError = 0x00000080,// The stream was terminated with error
// Flags to be managed by the upper layer
RosterRequested = 0x00000100,// c2s: the roster was already requested
AvailableResource = 0x00000200,// c2s: available presence was sent/received
@ -1054,6 +1055,12 @@ protected:
m_features.remove(XMPPNamespace::Tls);
}
/**
* Set the idle timer in Running state
* @param msecNow Current time in milliseconds
*/
void setIdleTimer(u_int64_t msecNow = Time::msecNow());
State m_state; // Stream state
String m_id; // Stream id
JabberID m_local; // Local peer's jid