Fixed bugs in sigtransport.
Notify sigtran when a new sctp connection has been established. Set custom names to transport thread and transport mutex for debugging. git-svn-id: http://yate.null.ro/svn/yate/trunk@5338 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
7f62a2c8fc
commit
7d449a804e
|
@ -49,6 +49,10 @@
|
||||||
; linger: int; How much to block waiting for socket to close.
|
; linger: int; How much to block waiting for socket to close.
|
||||||
;linger = 0
|
;linger = 0
|
||||||
|
|
||||||
|
; listen-notify: boolean: True to notify the upper layer that a new incoming connection has been established
|
||||||
|
; Default to true
|
||||||
|
;listen-notify=true
|
||||||
|
|
||||||
|
|
||||||
; SCTP parameters
|
; SCTP parameters
|
||||||
; NOTE these parameters will be set only for SCTP sockets
|
; NOTE these parameters will be set only for SCTP sockets
|
||||||
|
|
|
@ -219,6 +219,25 @@ bool SIGTRAN::getSocketParams(const String& params, NamedList& result)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SIGTRAN::hasTransportThread()
|
||||||
|
{
|
||||||
|
m_transMutex.lock();
|
||||||
|
RefPointer<SIGTransport> trans = m_trans;
|
||||||
|
m_transMutex.unlock();
|
||||||
|
if (!trans)
|
||||||
|
return false;
|
||||||
|
return trans->hasThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SIGTRAN::stopTransportThread()
|
||||||
|
{
|
||||||
|
m_transMutex.lock();
|
||||||
|
RefPointer<SIGTransport> trans = m_trans;
|
||||||
|
m_transMutex.unlock();
|
||||||
|
if (trans)
|
||||||
|
trans->stopThread();
|
||||||
|
}
|
||||||
|
|
||||||
// Attach or detach an user adaptation layer
|
// Attach or detach an user adaptation layer
|
||||||
void SIGTransport::attach(SIGTRAN* sigtran)
|
void SIGTransport::attach(SIGTRAN* sigtran)
|
||||||
{
|
{
|
||||||
|
@ -238,9 +257,9 @@ u_int32_t SIGTransport::defPort() const
|
||||||
bool SIGTransport::processMSG(unsigned char msgVersion, unsigned char msgClass,
|
bool SIGTransport::processMSG(unsigned char msgVersion, unsigned char msgClass,
|
||||||
unsigned char msgType, const DataBlock& msg, int streamId) const
|
unsigned char msgType, const DataBlock& msg, int streamId) const
|
||||||
{
|
{
|
||||||
XDebug(this,DebugAll,"Received message class %s type %s (0x%02X)",
|
XDebug(this,DebugAll,"Received message class %s type %s (0x%02X) on stream %d",
|
||||||
lookup(msgClass,s_classes,"Unknown"),
|
lookup(msgClass,s_classes,"Unknown"),
|
||||||
SIGTRAN::typeName(msgClass,msgType,"Unknown"),msgType);
|
SIGTRAN::typeName(msgClass,msgType,"Unknown"),msgType,streamId);
|
||||||
return alive() && m_sigtran && m_sigtran->processMSG(msgVersion,msgClass,msgType,msg,streamId);
|
return alive() && m_sigtran && m_sigtran->processMSG(msgVersion,msgClass,msgType,msg,streamId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,9 +275,9 @@ bool SIGTransport::transmitMSG(unsigned char msgVersion, unsigned char msgClass,
|
||||||
{
|
{
|
||||||
if (!alive())
|
if (!alive())
|
||||||
return false;
|
return false;
|
||||||
XDebug(this,DebugAll,"Sending message class %s type %s (0x%02X)",
|
XDebug(this,DebugAll,"Sending message class %s type %s (0x%02X) on stream %d",
|
||||||
lookup(msgClass,s_classes,"Unknown"),
|
lookup(msgClass,s_classes,"Unknown"),
|
||||||
SIGTRAN::typeName(msgClass,msgType,"Unknown"),msgType);
|
SIGTRAN::typeName(msgClass,msgType,"Unknown"),msgType,streamId);
|
||||||
|
|
||||||
if (!connected(streamId)) {
|
if (!connected(streamId)) {
|
||||||
Debug(this,DebugMild,"Cannot send message, stream %d not connected [%p]",
|
Debug(this,DebugMild,"Cannot send message, stream %d not connected [%p]",
|
||||||
|
@ -283,6 +302,15 @@ bool SIGTransport::transmitMSG(unsigned char msgVersion, unsigned char msgClass,
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SIGTransport::transportNotify(SIGTransport* newTransport, const SocketAddr& addr)
|
||||||
|
{
|
||||||
|
if (alive() && m_sigtran) {
|
||||||
|
return m_sigtran->transportNotify(newTransport,addr);
|
||||||
|
}
|
||||||
|
TelEngine::destruct(newTransport);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class SIGAdaptation
|
* Class SIGAdaptation
|
||||||
|
@ -501,6 +529,36 @@ static const TokenDict s_clientStates[] = {
|
||||||
};
|
};
|
||||||
#undef MAKE_NAME
|
#undef MAKE_NAME
|
||||||
|
|
||||||
|
static const TokenDict s_uaErrors[] = {
|
||||||
|
{ "Invalid Version", SIGAdaptation::InvalidVersion },
|
||||||
|
{ "Invalid Interface Identifier", SIGAdaptation::InvalidIID },
|
||||||
|
{ "Unsupported Message Class", SIGAdaptation::UnsupportedMessageClass },
|
||||||
|
{ "Unsupported Message Type", SIGAdaptation::UnsupportedMessageType },
|
||||||
|
{ "Unsupported Traffic Handling Mode", SIGAdaptation::UnsupportedTrafficMode },
|
||||||
|
{ "Unexpected Message", SIGAdaptation::UnexpectedMessage },
|
||||||
|
{ "Protocol Error", SIGAdaptation::ProtocolError },
|
||||||
|
{ "Unsupported Interface Identifier Type", SIGAdaptation::UnsupportedIIDType },
|
||||||
|
{ "Invalid Stream Identifier", SIGAdaptation::InvalidStreamIdentifier },
|
||||||
|
{ "Unassigned TEI", SIGAdaptation::UnassignedTEI },
|
||||||
|
{ "Unrecognized SAPI", SIGAdaptation::UnrecognizedSAPI },
|
||||||
|
{ "Invalid TEI, SAPI combination", SIGAdaptation::InvalidTEISAPI },
|
||||||
|
{ "Refused - Management Blocking", SIGAdaptation::ManagementBlocking },
|
||||||
|
{ "ASP Identifier Required", SIGAdaptation::ASPIDRequired },
|
||||||
|
{ "Invalid ASP Identifier", SIGAdaptation::InvalidASPID },
|
||||||
|
{ "ASP Active for Interface Identifier(s)", SIGAdaptation::ASPActiveIID },
|
||||||
|
{ "Invalid Parameter Value ", SIGAdaptation::InvalidParameterValue },
|
||||||
|
{ "Parameter Field Error", SIGAdaptation::ParameterFieldError },
|
||||||
|
{ "Unexpected Parameter", SIGAdaptation::UnexpectedParameter },
|
||||||
|
{ "Destination Status Unknown", SIGAdaptation::DestinationStatusUnknown },
|
||||||
|
{ "Invalid Network Appearance", SIGAdaptation::InvalidNetworkAppearance },
|
||||||
|
{ "Missing Parameter", SIGAdaptation::MissingParameter },
|
||||||
|
{ "Invalid Routing Context", SIGAdaptation::InvalidRoutingContext },
|
||||||
|
{ "No Configured AS for ASP", SIGAdaptation::NotConfiguredAS },
|
||||||
|
{ "Subsystem Status Unknown", SIGAdaptation::SubsystemStatusUnknown },
|
||||||
|
{ "Invalid loadsharing label", SIGAdaptation::InvalidLoadsharingLabel },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
static const TokenDict s_trafficModes[] = {
|
static const TokenDict s_trafficModes[] = {
|
||||||
{ "unused", SIGAdaptation::TrafficUnused },
|
{ "unused", SIGAdaptation::TrafficUnused },
|
||||||
{ "override", SIGAdaptation::TrafficOverride },
|
{ "override", SIGAdaptation::TrafficOverride },
|
||||||
|
@ -682,7 +740,7 @@ bool SIGAdaptClient::processMgmtMSG(unsigned char msgType, const DataBlock& msg,
|
||||||
setState(AspDown);
|
setState(AspDown);
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
Debug(this,DebugWarn,"SG reported error %u",errCode);
|
Debug(this,DebugWarn,"SG reported error %u: %s",errCode,lookup(errCode,s_uaErrors,"Unknown"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -907,6 +965,13 @@ SS7M2PA::~SS7M2PA()
|
||||||
DDebug(this,DebugAll,"Destroying SS7M2PA [%p]",this);
|
DDebug(this,DebugAll,"Destroying SS7M2PA [%p]",this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SS7M2PA::destroyed()
|
||||||
|
{
|
||||||
|
stopTransportThread();
|
||||||
|
SIGTRAN::attach(0);
|
||||||
|
SS7Layer2::destroyed();
|
||||||
|
}
|
||||||
|
|
||||||
bool SS7M2PA::initialize(const NamedList* config)
|
bool SS7M2PA::initialize(const NamedList* config)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -924,6 +989,7 @@ bool SS7M2PA::initialize(const NamedList* config)
|
||||||
resolveConfig(YSTRING("basename"),params,config)) {
|
resolveConfig(YSTRING("basename"),params,config)) {
|
||||||
params.addParam("basename",params);
|
params.addParam("basename",params);
|
||||||
params.addParam("protocol","ss7");
|
params.addParam("protocol","ss7");
|
||||||
|
params.addParam("listen-notify","false");
|
||||||
SIGTransport* tr = YSIGCREATE(SIGTransport,¶ms);
|
SIGTransport* tr = YSIGCREATE(SIGTransport,¶ms);
|
||||||
if (!tr)
|
if (!tr)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1930,7 +1996,7 @@ bool SS7M2UA::processMGMT(unsigned char msgType, const DataBlock& msg, int strea
|
||||||
m_linkState = LinkDown;
|
m_linkState = LinkDown;
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
Debug(this,DebugWarn,"M2UA SG reported error %u",errCode);
|
Debug(this,DebugWarn,"M2UA SG reported error %u: %s",errCode,lookup(errCode,s_uaErrors,"Unknown"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2101,6 +2167,9 @@ bool SS7M2UA::operational() const
|
||||||
return (m_linkState >= LinkUp) && !m_rpo;
|
return (m_linkState >= LinkUp) && !m_rpo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ISDNIUAClient
|
||||||
|
*/
|
||||||
|
|
||||||
bool ISDNIUAClient::processMSG(unsigned char msgVersion, unsigned char msgClass,
|
bool ISDNIUAClient::processMSG(unsigned char msgVersion, unsigned char msgClass,
|
||||||
unsigned char msgType, const DataBlock& msg, int streamId)
|
unsigned char msgType, const DataBlock& msg, int streamId)
|
||||||
|
@ -2240,7 +2309,7 @@ bool ISDNIUA::processMGMT(unsigned char msgType, const DataBlock& msg, int strea
|
||||||
multipleFrameReleased(localTei(),false,true);
|
multipleFrameReleased(localTei(),false,true);
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
Debug(this,DebugWarn,"IUA SG reported error %u",errCode);
|
Debug(this,DebugWarn,"IUA SG reported error %u: %s",errCode,lookup(errCode,s_uaErrors,"Unknown"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4355,6 +4355,27 @@ public:
|
||||||
virtual bool getSocketParams(const String& params, NamedList& result)
|
virtual bool getSocketParams(const String& params, NamedList& result)
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that a new incomming connection has been made
|
||||||
|
* NOTE newTransport needs to be destroyed if will not be used
|
||||||
|
* @param newTransport The new created transport
|
||||||
|
* @param addr The newly created transport socket address
|
||||||
|
* @return True if the newTransport will be used.
|
||||||
|
*/
|
||||||
|
virtual bool transportNotify(SIGTransport* newTransport, const SocketAddr& addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the transport thread is still running
|
||||||
|
* @return True if the thread is still running.
|
||||||
|
*/
|
||||||
|
virtual bool hasThread()
|
||||||
|
{ return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the transport thread
|
||||||
|
*/
|
||||||
|
virtual void stopThread()
|
||||||
|
{ }
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -4598,6 +4619,27 @@ public:
|
||||||
* @return True if operation was successful, false if an error occurred
|
* @return True if operation was successful, false if an error occurred
|
||||||
*/
|
*/
|
||||||
bool getSocketParams(const String& params, NamedList& result);
|
bool getSocketParams(const String& params, NamedList& result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification that a new incomming connection has been made
|
||||||
|
* @param newTransport The new created transport
|
||||||
|
* @param addr The newly created transport socket address
|
||||||
|
* @return True if the newTransport will be used.
|
||||||
|
*/
|
||||||
|
virtual bool transportNotify(SIGTransport* newTransport, const SocketAddr& addr)
|
||||||
|
{ TelEngine::destruct(newTransport); return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the transport thread is running
|
||||||
|
* @return true if the transport thread is running
|
||||||
|
*/
|
||||||
|
bool hasTransportThread();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the transport thread
|
||||||
|
*/
|
||||||
|
void stopTransportThread();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Process a complete message
|
* Process a complete message
|
||||||
|
@ -4636,6 +4678,35 @@ public:
|
||||||
TrafficBroadcast = 3,
|
TrafficBroadcast = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Errors {
|
||||||
|
InvalidVersion = 0x01,
|
||||||
|
InvalidIID = 0x02,
|
||||||
|
UnsupportedMessageClass = 0x03,
|
||||||
|
UnsupportedMessageType = 0x04,
|
||||||
|
UnsupportedTrafficMode = 0x05,
|
||||||
|
UnexpectedMessage = 0x06,
|
||||||
|
ProtocolError = 0x07,
|
||||||
|
UnsupportedIIDType = 0x08,
|
||||||
|
InvalidStreamIdentifier = 0x09,
|
||||||
|
UnassignedTEI = 0x0a,
|
||||||
|
UnrecognizedSAPI = 0x0b,
|
||||||
|
InvalidTEISAPI = 0x0c,
|
||||||
|
ManagementBlocking = 0x0d,
|
||||||
|
ASPIDRequired = 0x0e,
|
||||||
|
InvalidASPID = 0x0f,
|
||||||
|
ASPActiveIID = 0x10,
|
||||||
|
InvalidParameterValue = 0x11,
|
||||||
|
ParameterFieldError = 0x12,
|
||||||
|
UnexpectedParameter = 0x13,
|
||||||
|
DestinationStatusUnknown = 0x14,
|
||||||
|
InvalidNetworkAppearance = 0x15,
|
||||||
|
MissingParameter = 0x16,
|
||||||
|
InvalidRoutingContext = 0x19,
|
||||||
|
NotConfiguredAS = 0x1a,
|
||||||
|
SubsystemStatusUnknown = 0x1b,
|
||||||
|
InvalidLoadsharingLabel = 0x1c
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
|
@ -5535,7 +5606,6 @@ protected:
|
||||||
/**
|
/**
|
||||||
* Process a notification generated by the attached data link
|
* Process a notification generated by the attached data link
|
||||||
* @param link Data link that generated the notification
|
* @param link Data link that generated the notification
|
||||||
* @return True if notification was processed
|
|
||||||
*/
|
*/
|
||||||
virtual void notify(SS7Layer2* link) = 0;
|
virtual void notify(SS7Layer2* link) = 0;
|
||||||
};
|
};
|
||||||
|
@ -7087,6 +7157,17 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool control(M2PAOperations oper, NamedList* params = 0);
|
virtual bool control(M2PAOperations oper, NamedList* params = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a control operation. Operations can change the link status or
|
||||||
|
* can query the aligned status.
|
||||||
|
* @param oper Operation to execute
|
||||||
|
* @param params Optional parameters for the operation
|
||||||
|
* @return True if the command completed successfully, for query operations
|
||||||
|
* also indicates the data link is aligned and operational
|
||||||
|
*/
|
||||||
|
virtual bool control(SS7Layer2::Operation oper, NamedList* params = 0)
|
||||||
|
{ return control((M2PAOperations)oper,params); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the current link status indications
|
* Retrieve the current link status indications
|
||||||
* @return Link status indication bits
|
* @return Link status indication bits
|
||||||
|
@ -7235,6 +7316,7 @@ protected:
|
||||||
*/
|
*/
|
||||||
void retransData();
|
void retransData();
|
||||||
|
|
||||||
|
virtual void destroyed();
|
||||||
private:
|
private:
|
||||||
void dumpMsg(u_int8_t version, u_int8_t mClass, u_int8_t type,
|
void dumpMsg(u_int8_t version, u_int8_t mClass, u_int8_t type,
|
||||||
const DataBlock& data, int stream, bool send);
|
const DataBlock& data, int stream, bool send);
|
||||||
|
|
|
@ -51,7 +51,7 @@ class TransportWorker
|
||||||
friend class TransportThread;
|
friend class TransportThread;
|
||||||
public:
|
public:
|
||||||
inline TransportWorker()
|
inline TransportWorker()
|
||||||
: m_thread(0)
|
: m_thread(0), m_threadMutex(true,"TransportThread")
|
||||||
{ }
|
{ }
|
||||||
virtual ~TransportWorker() { stop(); }
|
virtual ~TransportWorker() { stop(); }
|
||||||
virtual bool readData() = 0;
|
virtual bool readData() = 0;
|
||||||
|
@ -61,11 +61,22 @@ public:
|
||||||
bool running();
|
bool running();
|
||||||
bool start(Thread::Priority prio = Thread::Normal);
|
bool start(Thread::Priority prio = Thread::Normal);
|
||||||
inline void resetThread()
|
inline void resetThread()
|
||||||
{ m_thread = 0; }
|
{
|
||||||
|
Lock myLock(m_threadMutex);
|
||||||
|
m_thread = 0;
|
||||||
|
}
|
||||||
|
virtual const char* getTransportName() = 0;
|
||||||
|
inline bool hasThread()
|
||||||
|
{
|
||||||
|
Lock myLock(m_threadMutex);
|
||||||
|
return m_thread != 0;
|
||||||
|
}
|
||||||
|
void exitThread();
|
||||||
protected:
|
protected:
|
||||||
void stop();
|
void stop();
|
||||||
private:
|
private:
|
||||||
TransportThread* m_thread;
|
TransportThread* m_thread;
|
||||||
|
Mutex m_threadMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SockRef : public RefObject
|
class SockRef : public RefObject
|
||||||
|
@ -88,16 +99,23 @@ class TransportThread : public Thread
|
||||||
{
|
{
|
||||||
friend class TransportWorker;
|
friend class TransportWorker;
|
||||||
public:
|
public:
|
||||||
inline TransportThread(TransportWorker* worker, Priority prio = Normal)
|
inline TransportThread(TransportWorker* worker, String* tName, Priority prio = Normal)
|
||||||
: Thread("SignallingTransporter",prio), m_worker(worker), m_exit(false)
|
: Thread(*tName,prio), m_worker(worker), m_exit(false), m_threadName(tName), m_cleanWorker(true)
|
||||||
{ }
|
{ }
|
||||||
virtual ~TransportThread();
|
virtual ~TransportThread();
|
||||||
virtual void run();
|
virtual void run();
|
||||||
void exitThread()
|
void exitThread()
|
||||||
{ m_exit = true; }
|
{
|
||||||
|
m_cleanWorker = false;
|
||||||
|
m_exit = true;
|
||||||
|
}
|
||||||
|
void resetWorker()
|
||||||
|
{ m_worker = 0; }
|
||||||
private:
|
private:
|
||||||
TransportWorker* m_worker;
|
TransportWorker* m_worker;
|
||||||
bool m_exit;
|
bool m_exit;
|
||||||
|
String* m_threadName;
|
||||||
|
bool m_cleanWorker;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ListenerThread : public Thread
|
class ListenerThread : public Thread
|
||||||
|
@ -116,7 +134,7 @@ private:
|
||||||
bool m_stream;
|
bool m_stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TReader : public TransportWorker, public Mutex
|
class TReader : public TransportWorker, public Mutex, public RefObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline TReader()
|
inline TReader()
|
||||||
|
@ -158,7 +176,8 @@ public:
|
||||||
Down
|
Down
|
||||||
};
|
};
|
||||||
virtual bool initialize(const NamedList* config);
|
virtual bool initialize(const NamedList* config);
|
||||||
Transport(const NamedList& params);
|
Transport(const NamedList& params, String* mutexName);
|
||||||
|
Transport(TransportType type, String* mutexName);
|
||||||
~Transport();
|
~Transport();
|
||||||
inline unsigned char getVersion(unsigned char* buf) const
|
inline unsigned char getVersion(unsigned char* buf) const
|
||||||
{ return buf[0]; }
|
{ return buf[0]; }
|
||||||
|
@ -179,6 +198,8 @@ public:
|
||||||
{ return m_state; }
|
{ return m_state; }
|
||||||
inline void resetListener()
|
inline void resetListener()
|
||||||
{ m_listener = 0; }
|
{ m_listener = 0; }
|
||||||
|
inline void startReading()
|
||||||
|
{ if (m_reader) m_reader->start(); }
|
||||||
bool addSocket(Socket* socket,SocketAddr& adress);
|
bool addSocket(Socket* socket,SocketAddr& adress);
|
||||||
virtual bool reliable() const
|
virtual bool reliable() const
|
||||||
{ return m_type == Sctp || m_type == Tcp; }
|
{ return m_type == Sctp || m_type == Tcp; }
|
||||||
|
@ -196,6 +217,10 @@ public:
|
||||||
static SignallingComponent* create(const String& type, NamedList& params);
|
static SignallingComponent* create(const String& type, NamedList& params);
|
||||||
virtual bool transmitMSG(const DataBlock& header, const DataBlock& msg, int streamId = 0);
|
virtual bool transmitMSG(const DataBlock& header, const DataBlock& msg, int streamId = 0);
|
||||||
virtual bool getSocketParams(const String& params, NamedList& result);
|
virtual bool getSocketParams(const String& params, NamedList& result);
|
||||||
|
virtual void destroyed();
|
||||||
|
|
||||||
|
virtual bool hasThread();
|
||||||
|
virtual void stopThread();
|
||||||
private:
|
private:
|
||||||
TReader* m_reader;
|
TReader* m_reader;
|
||||||
Mutex m_readerMutex;
|
Mutex m_readerMutex;
|
||||||
|
@ -203,9 +228,11 @@ private:
|
||||||
int m_type;
|
int m_type;
|
||||||
int m_state;
|
int m_state;
|
||||||
ListenerThread* m_listener;
|
ListenerThread* m_listener;
|
||||||
const NamedList m_config;
|
NamedList m_config;
|
||||||
bool m_endpoint;
|
bool m_endpoint;
|
||||||
bool m_supportEvents;
|
bool m_supportEvents;
|
||||||
|
bool m_listenNotify;
|
||||||
|
String* m_mutexName;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StreamReader : public TReader
|
class StreamReader : public TReader
|
||||||
|
@ -224,9 +251,11 @@ public:
|
||||||
virtual bool sendBuffer(int streamId = 0);
|
virtual bool sendBuffer(int streamId = 0);
|
||||||
virtual bool getSocketParams(const String& params, NamedList& result);
|
virtual bool getSocketParams(const String& params, NamedList& result);
|
||||||
virtual void reset()
|
virtual void reset()
|
||||||
{ m_transport->resetReader(this); }
|
{ if (m_transport) m_transport->resetReader(this); }
|
||||||
void connectionDown(bool stop = true);
|
void connectionDown(bool stop = true);
|
||||||
void stopThread();
|
void stopThread();
|
||||||
|
virtual const char* getTransportName()
|
||||||
|
{ return m_transport ? m_transport->debugName() : ""; }
|
||||||
private:
|
private:
|
||||||
Transport* m_transport;
|
Transport* m_transport;
|
||||||
Socket* m_socket;
|
Socket* m_socket;
|
||||||
|
@ -258,6 +287,8 @@ public:
|
||||||
bool bindSocket();
|
bool bindSocket();
|
||||||
void reconnectSocket();
|
void reconnectSocket();
|
||||||
void updateTransportStatus(int status);
|
void updateTransportStatus(int status);
|
||||||
|
virtual const char* getTransportName()
|
||||||
|
{ return m_transport ? m_transport->debugName() : ""; }
|
||||||
private:
|
private:
|
||||||
Transport* m_transport;
|
Transport* m_transport;
|
||||||
Socket* m_socket;
|
Socket* m_socket;
|
||||||
|
@ -279,7 +310,20 @@ private:
|
||||||
static TransportModule plugin;
|
static TransportModule plugin;
|
||||||
YSIGFACTORY2(Transport);
|
YSIGFACTORY2(Transport);
|
||||||
static long s_maxDownAllowed = 10000000;
|
static long s_maxDownAllowed = 10000000;
|
||||||
|
static ObjList s_names;
|
||||||
|
Mutex s_namesMutex(false,"TransportNames");
|
||||||
|
|
||||||
|
static void addName(String* name)
|
||||||
|
{
|
||||||
|
Lock myLock(s_namesMutex);
|
||||||
|
s_names.append(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void removeName(String* name)
|
||||||
|
{
|
||||||
|
Lock myLock(s_namesMutex);
|
||||||
|
s_names.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
static const TokenDict s_transType[] = {
|
static const TokenDict s_transType[] = {
|
||||||
{ "none", Transport::None },
|
{ "none", Transport::None },
|
||||||
|
@ -359,6 +403,7 @@ bool ListenerThread::init(const NamedList& param)
|
||||||
Debug("ListenerThread",DebugConf,"Could not obtain SctpSocket");
|
Debug("ListenerThread",DebugConf,"Could not obtain SctpSocket");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
delete m_socket;
|
||||||
m_socket = soc;
|
m_socket = soc;
|
||||||
m_socket->create(AF_INET,m_stream ? SOCK_STREAM : SOCK_SEQPACKET,IPPROTO_SCTP);
|
m_socket->create(AF_INET,m_stream ? SOCK_STREAM : SOCK_SEQPACKET,IPPROTO_SCTP);
|
||||||
break;
|
break;
|
||||||
|
@ -472,9 +517,10 @@ bool ListenerThread::addAddress(const NamedList ¶m)
|
||||||
|
|
||||||
TransportThread::~TransportThread()
|
TransportThread::~TransportThread()
|
||||||
{
|
{
|
||||||
|
DDebug("TransportThread",DebugAll,"Destroying TransportThread [%p]",this);
|
||||||
if (m_worker)
|
if (m_worker)
|
||||||
m_worker->resetThread();
|
m_worker->resetThread();
|
||||||
DDebug(DebugAll,"Destroying Transport Thread [%p]",this);
|
removeName(m_threadName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransportThread::run()
|
void TransportThread::run()
|
||||||
|
@ -490,27 +536,35 @@ void TransportThread::run()
|
||||||
else
|
else
|
||||||
Thread::msleep(5,true);
|
Thread::msleep(5,true);
|
||||||
}
|
}
|
||||||
|
if (!m_worker)
|
||||||
|
return;
|
||||||
m_worker->resetThread();
|
m_worker->resetThread();
|
||||||
|
if (m_cleanWorker)
|
||||||
m_worker->reset();
|
m_worker->reset();
|
||||||
m_worker = 0;
|
m_worker = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TReader::~TReader()
|
TReader::~TReader()
|
||||||
{
|
{
|
||||||
Debug(DebugAll,"Destroying TReader [%p]",this);
|
DDebug(DebugAll,"Destroying TReader [%p]",this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** TransportWorker class */
|
/** TransportWorker class */
|
||||||
|
|
||||||
bool TransportWorker::running()
|
bool TransportWorker::running()
|
||||||
{
|
{
|
||||||
|
Lock myLock(m_threadMutex);
|
||||||
return m_thread && m_thread->running();
|
return m_thread && m_thread->running();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TransportWorker::start(Thread::Priority prio)
|
bool TransportWorker::start(Thread::Priority prio)
|
||||||
{
|
{
|
||||||
if (!m_thread)
|
Lock myLock(m_threadMutex);
|
||||||
m_thread = new TransportThread(this,prio);
|
if (!m_thread) {
|
||||||
|
String* name = new String(getTransportName());
|
||||||
|
addName(name);
|
||||||
|
m_thread = new TransportThread(this,name,prio);
|
||||||
|
}
|
||||||
if (m_thread->running() || m_thread->startup())
|
if (m_thread->running() || m_thread->startup())
|
||||||
return true;
|
return true;
|
||||||
m_thread->cancel(true);
|
m_thread->cancel(true);
|
||||||
|
@ -520,15 +574,31 @@ bool TransportWorker::start(Thread::Priority prio)
|
||||||
|
|
||||||
void TransportWorker::stop()
|
void TransportWorker::stop()
|
||||||
{
|
{
|
||||||
|
Lock myLock(m_threadMutex);
|
||||||
if (!(m_thread && m_thread->running()))
|
if (!(m_thread && m_thread->running()))
|
||||||
return;
|
return;
|
||||||
m_thread->exitThread();
|
m_thread->exitThread();
|
||||||
for (unsigned int i = 2 * Thread::idleMsec(); i--; ) {
|
|
||||||
|
if (m_thread == Thread::current()) {
|
||||||
|
m_thread->resetWorker();
|
||||||
|
m_thread = 0;
|
||||||
|
DDebug(DebugWarn,"Stopping TransportWorker from itself!! %p ", this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
myLock.drop();
|
||||||
|
while (true) {
|
||||||
Thread::msleep(1);
|
Thread::msleep(1);
|
||||||
if (!m_thread)
|
if (!m_thread)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_thread = 0;
|
}
|
||||||
|
|
||||||
|
void TransportWorker::exitThread()
|
||||||
|
{
|
||||||
|
Lock myLock(m_threadMutex);
|
||||||
|
if (!m_thread)
|
||||||
|
return;
|
||||||
|
m_thread->exitThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -542,6 +612,7 @@ SignallingComponent* Transport::create(const String& type, NamedList& name)
|
||||||
Configuration cfg(Engine::configFile("sigtransport"));
|
Configuration cfg(Engine::configFile("sigtransport"));
|
||||||
cfg.load();
|
cfg.load();
|
||||||
|
|
||||||
|
NamedString* listenNotify = name.getParam(YSTRING("listen-notify"));
|
||||||
const char* sectName = name.getValue("basename");
|
const char* sectName = name.getValue("basename");
|
||||||
NamedList* config = cfg.getSection(sectName);
|
NamedList* config = cfg.getSection(sectName);
|
||||||
if (!name.getBoolValue(YSTRING("local-config"),false))
|
if (!name.getBoolValue(YSTRING("local-config"),false))
|
||||||
|
@ -552,15 +623,30 @@ SignallingComponent* Transport::create(const String& type, NamedList& name)
|
||||||
} else
|
} else
|
||||||
name.copyParams(*config);
|
name.copyParams(*config);
|
||||||
|
|
||||||
return new Transport(*config);
|
if (listenNotify)
|
||||||
|
config->setParam(listenNotify->name(),*listenNotify);
|
||||||
|
String* mName = new String("TransportReader:");
|
||||||
|
mName->append(*config);
|
||||||
|
addName(mName);
|
||||||
|
return new Transport(*config,mName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Transport::Transport(const NamedList ¶m)
|
Transport::Transport(const NamedList ¶m, String* mutexName)
|
||||||
: m_reader(0), m_readerMutex(true,"TransportReader"), m_state(Down),
|
: m_reader(0), m_readerMutex(true,*mutexName), m_streamer(false), m_state(Down),
|
||||||
m_listener(0), m_config(param), m_endpoint(true), m_supportEvents(true)
|
m_listener(0), m_config(param), m_endpoint(true), m_supportEvents(true),
|
||||||
|
m_listenNotify(true), m_mutexName(mutexName)
|
||||||
{
|
{
|
||||||
setName("Transport:" + param);
|
setName("Transport:" + param);
|
||||||
Debug(this,DebugAll,"Transport created (%p)",this);
|
DDebug(this,DebugAll,"Transport created (%p)",this);
|
||||||
|
m_listenNotify = param.getBoolValue("listen-notify",true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Transport::Transport(TransportType type, String* mutexName)
|
||||||
|
: m_reader(0), m_readerMutex(true,*mutexName), m_streamer(true), m_type(type), m_state(Down),
|
||||||
|
m_listener(0), m_config(""), m_endpoint(true), m_supportEvents(true),
|
||||||
|
m_listenNotify(false), m_mutexName(mutexName)
|
||||||
|
{
|
||||||
|
DDebug(this,DebugInfo,"Creating new Transport [%p]",this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Transport::~Transport()
|
Transport::~Transport()
|
||||||
|
@ -570,19 +656,31 @@ Transport::~Transport()
|
||||||
while (m_listener)
|
while (m_listener)
|
||||||
Thread::yield();
|
Thread::yield();
|
||||||
Debug(this,DebugAll,"Destroying Transport [%p]",this);
|
Debug(this,DebugAll,"Destroying Transport [%p]",this);
|
||||||
delete m_reader;
|
TelEngine::destruct(m_reader);
|
||||||
|
removeName(m_mutexName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transport::destroyed()
|
||||||
|
{
|
||||||
|
m_readerMutex.lock();
|
||||||
|
TReader* tmp = m_reader;
|
||||||
m_reader = 0;
|
m_reader = 0;
|
||||||
|
m_readerMutex.unlock();
|
||||||
|
TelEngine::destruct(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transport::resetReader(TReader* caller)
|
void Transport::resetReader(TReader* caller)
|
||||||
{
|
{
|
||||||
if (!caller)
|
if (!caller)
|
||||||
return;
|
return;
|
||||||
|
if (m_reader) {
|
||||||
m_readerMutex.lock();
|
m_readerMutex.lock();
|
||||||
if (caller == m_reader)
|
if (caller == m_reader)
|
||||||
m_reader = 0;
|
m_reader = 0;
|
||||||
m_readerMutex.unlock();
|
m_readerMutex.unlock();
|
||||||
delete caller;
|
}
|
||||||
|
if (m_listener)
|
||||||
|
TelEngine::destruct(caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Transport::control(const NamedList ¶m)
|
bool Transport::control(const NamedList ¶m)
|
||||||
|
@ -655,6 +753,7 @@ bool Transport::initialize(const NamedList* params)
|
||||||
bindSocket();
|
bindSocket();
|
||||||
}
|
}
|
||||||
m_reader->start();
|
m_reader->start();
|
||||||
|
lock.drop();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,7 +823,7 @@ bool Transport::bindSocket()
|
||||||
addr.host(address);
|
addr.host(address);
|
||||||
addr.port(port);
|
addr.port(port);
|
||||||
if (!socket->bind(addr)) {
|
if (!socket->bind(addr)) {
|
||||||
Debug(DebugMild,"Unable to bind to %s:%u: %d: %s",
|
Debug(this,DebugMild,"Unable to bind to %s:%u: %d: %s",
|
||||||
addr.host().c_str(),addr.port(),errno,strerror(errno));
|
addr.host().c_str(),addr.port(),errno,strerror(errno));
|
||||||
socket->terminate();
|
socket->terminate();
|
||||||
delete socket;
|
delete socket;
|
||||||
|
@ -737,10 +836,8 @@ bool Transport::bindSocket()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Lock lock(m_readerMutex);
|
Lock lock(m_readerMutex);
|
||||||
if (!m_reader) {
|
if (!m_reader)
|
||||||
Debug(this,DebugFail,"Bind socket null reader!!");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
m_reader->setSocket(socket);
|
m_reader->setSocket(socket);
|
||||||
int linger = m_config.getIntValue("linger",0);
|
int linger = m_config.getIntValue("linger",0);
|
||||||
socket->setLinger(linger);
|
socket->setLinger(linger);
|
||||||
|
@ -919,10 +1016,8 @@ void Transport::setStatus(int status)
|
||||||
lookup(m_state,s_transStatus,"?"),lookup(status,s_transStatus,"?"),this);
|
lookup(m_state,s_transStatus,"?"),lookup(status,s_transStatus,"?"),this);
|
||||||
m_state = status;
|
m_state = status;
|
||||||
Lock mylock(m_readerMutex);
|
Lock mylock(m_readerMutex);
|
||||||
if (!m_reader) {
|
if (!m_reader)
|
||||||
Debug(this,DebugFail,"setStatus null reader");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
m_reader->m_canSend = true;
|
m_reader->m_canSend = true;
|
||||||
mylock.drop();
|
mylock.drop();
|
||||||
notifyLayer((status == Up) ? SignallingInterface::LinkUp : SignallingInterface::LinkDown);
|
notifyLayer((status == Up) ? SignallingInterface::LinkUp : SignallingInterface::LinkDown);
|
||||||
|
@ -938,36 +1033,51 @@ u_int32_t Transport::getMsgLen(unsigned char* buf)
|
||||||
bool Transport::transmitMSG(const DataBlock& header, const DataBlock& msg, int streamId)
|
bool Transport::transmitMSG(const DataBlock& header, const DataBlock& msg, int streamId)
|
||||||
{
|
{
|
||||||
Lock lock(m_readerMutex);
|
Lock lock(m_readerMutex);
|
||||||
if (!m_reader) {
|
RefPointer<TReader> reader = m_reader;
|
||||||
DDebug(this,DebugMild,"Cannot send message, no reader set [%p]",this);
|
if (!reader)
|
||||||
return false;
|
return false;
|
||||||
}
|
lock.drop();
|
||||||
bool ret = m_reader->sendMSG(header,msg,streamId);
|
return reader->sendMSG(header,msg,streamId);;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Transport::addSocket(Socket* socket,SocketAddr& adress)
|
bool Transport::addSocket(Socket* socket,SocketAddr& socketAddress)
|
||||||
{
|
{
|
||||||
|
if (m_listenNotify) {
|
||||||
|
String* name = new String("Transport:");
|
||||||
|
name->append(socketAddress.host() + ":");
|
||||||
|
name->append((int)socketAddress.port());
|
||||||
|
addName(name);
|
||||||
|
Transport* newTrans = new Transport((TransportType)m_type,name);
|
||||||
|
if (!transportNotify(newTrans,socketAddress)) {
|
||||||
|
DDebug(this,DebugInfo,"New transport wasn't accepted!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!newTrans->addSocket(socket,socketAddress)) {
|
||||||
|
newTrans->setStatus(Down);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
Lock lock(m_readerMutex);
|
Lock lock(m_readerMutex);
|
||||||
if (transType() == Up)
|
if (transType() == Up)
|
||||||
return false;
|
return false;
|
||||||
if (m_reader) {
|
if (m_reader) {
|
||||||
StreamReader* sr = static_cast<StreamReader*>(m_reader);
|
StreamReader* sr = static_cast<StreamReader*>(m_reader);
|
||||||
m_reader = 0;
|
m_reader = 0;
|
||||||
sr->reconnect();
|
TelEngine::destruct(sr);
|
||||||
}
|
}
|
||||||
SocketAddr addr(AF_INET);
|
if (!m_config.c_str()) {
|
||||||
String address, adr = m_config.getValue("remote");
|
m_config.assign(String(socketAddress.host().c_str()) << ":" << socketAddress.port());
|
||||||
int port = defPort();
|
setName(m_config);
|
||||||
resolveAddress(adr,address,port);
|
}
|
||||||
addr.host(address);
|
socket->setBlocking(false);
|
||||||
addr.port(port);
|
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case Sctp :
|
case Sctp :
|
||||||
{
|
{
|
||||||
Socket* sock = 0;
|
Socket* sock = 0;
|
||||||
Message m("socket.sctp");
|
Message m("socket.sctp");
|
||||||
m.addParam("handle",String(socket->handle()));
|
m.addParam("handle",String(socket->detach()));
|
||||||
|
delete socket;
|
||||||
SockRef* s = new SockRef(&sock);
|
SockRef* s = new SockRef(&sock);
|
||||||
m.userData(s);
|
m.userData(s);
|
||||||
TelEngine::destruct(s);
|
TelEngine::destruct(s);
|
||||||
|
@ -988,10 +1098,11 @@ bool Transport::addSocket(Socket* socket,SocketAddr& adress)
|
||||||
ppid = m_config.getIntValue("payload",ppid);
|
ppid = m_config.getIntValue("payload",ppid);
|
||||||
if (ppid > 0)
|
if (ppid > 0)
|
||||||
soc->setPayload(ppid);
|
soc->setPayload(ppid);
|
||||||
|
soc->setBlocking(false);
|
||||||
if (m_streamer)
|
if (m_streamer)
|
||||||
m_reader = new StreamReader(this,soc);
|
m_reader = new StreamReader(this,soc);
|
||||||
else
|
else
|
||||||
m_reader = new MessageReader(this,soc,addr);
|
Debug(this,DebugStub,"Add socket requested to create sctp message reader!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Unix :
|
case Unix :
|
||||||
|
@ -999,17 +1110,33 @@ bool Transport::addSocket(Socket* socket,SocketAddr& adress)
|
||||||
m_reader = new StreamReader(this,socket);
|
m_reader = new StreamReader(this,socket);
|
||||||
break;
|
break;
|
||||||
case Udp :
|
case Udp :
|
||||||
m_reader = new MessageReader(this,socket,addr);
|
Debug(this,DebugStub,"Add socket requested to create message reader for UDP socket type!");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Debug(this,DebugWarn,"Unknown socket type %d",m_type);
|
Debug(this,DebugWarn,"Unknown socket type %d",m_type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_reader->start();
|
|
||||||
setStatus(Up);
|
setStatus(Up);
|
||||||
|
m_reader->start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Transport::hasThread()
|
||||||
|
{
|
||||||
|
Lock lock(m_readerMutex);
|
||||||
|
if (!m_reader)
|
||||||
|
return false;
|
||||||
|
return m_reader->hasThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transport::stopThread()
|
||||||
|
{
|
||||||
|
Lock lock(m_readerMutex);
|
||||||
|
if (m_reader)
|
||||||
|
m_reader->exitThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class StreamReader
|
* class StreamReader
|
||||||
*/
|
*/
|
||||||
|
@ -1080,8 +1207,8 @@ bool StreamReader::sendBuffer(int streamId)
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
if (m_socket->updateError() && !m_socket->canRetry()) {
|
if (m_socket->updateError() && !m_socket->canRetry()) {
|
||||||
mylock.drop();
|
m_reconnect = true;
|
||||||
connectionDown();
|
m_canSend = false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1096,8 +1223,8 @@ bool StreamReader::sendBuffer(int streamId)
|
||||||
}
|
}
|
||||||
if (m_transport->status() == Transport::Up)
|
if (m_transport->status() == Transport::Up)
|
||||||
if (!s->valid()) {
|
if (!s->valid()) {
|
||||||
mylock.drop();
|
m_reconnect = true;
|
||||||
connectionDown();
|
m_canSend = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
@ -1108,8 +1235,8 @@ bool StreamReader::sendBuffer(int streamId)
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
if (!m_socket->canRetry()) {
|
if (!m_socket->canRetry()) {
|
||||||
Debug(m_transport,DebugMild,"Send error detected. %s",strerror(errno));
|
Debug(m_transport,DebugMild,"Send error detected. %s",strerror(errno));
|
||||||
mylock.drop();
|
m_reconnect = true;
|
||||||
connectionDown();
|
m_canSend = false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1200,7 +1327,7 @@ bool StreamReader::readData()
|
||||||
m_totalPacketLen = m_transport->getMsgLen(auxBuf);
|
m_totalPacketLen = m_transport->getMsgLen(auxBuf);
|
||||||
if (m_totalPacketLen >= 8 && m_totalPacketLen < MAX_BUF_SIZE) {
|
if (m_totalPacketLen >= 8 && m_totalPacketLen < MAX_BUF_SIZE) {
|
||||||
m_totalPacketLen -= 8;
|
m_totalPacketLen -= 8;
|
||||||
XDebug(m_transport,DebugAll,"Expecting %d bytes of packet data",m_totalPacketLen);
|
XDebug(m_transport,DebugAll,"Expecting %d bytes of packet data %d",m_totalPacketLen,stream);
|
||||||
if (!m_totalPacketLen) {
|
if (!m_totalPacketLen) {
|
||||||
m_transport->setStatus(Transport::Up);
|
m_transport->setStatus(Transport::Up);
|
||||||
m_transport->processMSG(m_transport->getVersion((unsigned char*)m_headerBuffer.data()),
|
m_transport->processMSG(m_transport->getVersion((unsigned char*)m_headerBuffer.data()),
|
||||||
|
@ -1381,6 +1508,7 @@ bool MessageReader::sendMSG(const DataBlock& header, const DataBlock& msg, int s
|
||||||
while (m_socket && m_socket->select(0,&sendOk,&error,Thread::idleUsec())) {
|
while (m_socket && m_socket->select(0,&sendOk,&error,Thread::idleUsec())) {
|
||||||
if (error) {
|
if (error) {
|
||||||
DDebug(m_transport,DebugAll,"Send error detected. %s",strerror(errno));
|
DDebug(m_transport,DebugAll,"Send error detected. %s",strerror(errno));
|
||||||
|
mylock.drop();
|
||||||
updateTransportStatus(Transport::Down);
|
updateTransportStatus(Transport::Down);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1414,7 +1542,7 @@ bool MessageReader::sendMSG(const DataBlock& header, const DataBlock& msg, int s
|
||||||
ret = true;
|
ret = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DDebug(m_transport,DebugMild,"Error sending message %d %d %s",len,totalLen,strerror(errno));
|
DDebug(m_transport,DebugMild,"Error sending message %d %d %s %s %d",len,totalLen,strerror(errno),m_remote.host().c_str(),m_remote.port());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1485,8 +1613,8 @@ bool MessageReader::readData()
|
||||||
DDebug(m_transport,DebugNote,"Message error [%p] %d",m_socket,flags);
|
DDebug(m_transport,DebugNote,"Message error [%p] %d",m_socket,flags);
|
||||||
if (m_transport->status() != Transport::Up)
|
if (m_transport->status() != Transport::Up)
|
||||||
return false;
|
return false;
|
||||||
Lock lock(m_sending);
|
|
||||||
updateTransportStatus(Transport::Initiating);
|
updateTransportStatus(Transport::Initiating);
|
||||||
|
Lock lock(m_sending);
|
||||||
Debug(m_transport,DebugInfo,"Terminating socket [%p] Reason: connection down!",m_socket);
|
Debug(m_transport,DebugInfo,"Terminating socket [%p] Reason: connection down!",m_socket);
|
||||||
m_socket->terminate();
|
m_socket->terminate();
|
||||||
delete m_socket;
|
delete m_socket;
|
||||||
|
|
Loading…
Reference in New Issue