Try to bind the IAX socket on a random port if failed to bind on configured one. Fixed socket read/write error reporting.

git-svn-id: http://voip.null.ro/svn/yate@4474 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2011-07-06 11:33:15 +00:00
parent 41dfba4982
commit 77bf052e18
4 changed files with 46 additions and 12 deletions

View File

@ -7,6 +7,10 @@
; addr: ipaddress: IP address to bind to
;addr=0.0.0.0
; force_bind: boolean: Try to use a random port if failed to bind on configured one
; Defaults to yes
;force_bind=yes
; tos: keyword: Type Of Service to set in outgoing UDP packets
; numeric TOS value or: lowdelay, throughput, reliability, mincost
;tos=0

View File

@ -32,7 +32,8 @@ using namespace TelEngine;
IAXEngine::IAXEngine(const char* iface, int port, u_int16_t transListCount, u_int16_t retransCount, u_int16_t retransInterval,
u_int16_t authTimeout, u_int16_t transTimeout, u_int16_t maxFullFrameDataLen,
u_int32_t format, u_int32_t capab, u_int32_t trunkSendInterval, bool authRequired)
u_int32_t format, u_int32_t capab, u_int32_t trunkSendInterval, bool authRequired,
NamedList* params)
: Mutex(true,"IAXEngine"),
m_lastGetEvIndex(0),
m_authRequired(authRequired),
@ -69,8 +70,28 @@ IAXEngine::IAXEngine(const char* iface, int port, u_int16_t transListCount, u_in
addr.host(iface);
addr.port(port);
m_socket.setBlocking(false);
if (!m_socket.bind(addr))
Debug(this,DebugWarn,"Failed to bind socket to %s:%d",c_safe(iface),port);
bool ok = m_socket.bind(addr);
if (!ok) {
bool force = !params || params->getBoolValue("force_bind",true);
String tmp;
Thread::errorString(tmp,m_socket.error());
Debug(this,DebugWarn,"Failed to bind socket on '%s:%d'%s. %d: '%s'",
c_safe(iface),port,force ? " - trying a random port" : "",
m_socket.error(),tmp.c_str());
if (force) {
addr.port(0);
ok = m_socket.bind(addr);
if (!ok)
Debug(this,DebugWarn,"Failed to bind on any port");
else {
ok = m_socket.getSockName(addr);
if (!ok)
Debug(this,DebugWarn,"Failed to retrieve bound address");
}
}
}
if (ok)
Debug(this,DebugInfo,"Bound on '%s:%d'",addr.host().c_str(),addr.port());
m_startLocalCallNo = 1 + (u_int16_t)(Random::random() % IAX2_MAX_CALLNO);
}
@ -219,9 +240,12 @@ void IAXEngine::readSocket(SocketAddr& addr)
while (1) {
int len = m_socket.recvFrom(buf,sizeof(buf),addr);
if (len == Socket::socketError()) {
if (!m_socket.canRetry())
if (!m_socket.canRetry()) {
String tmp;
Thread::errorString(tmp,m_socket.error());
Debug(this,DebugWarn,"Socket read error: %s (%d)",
::strerror(m_socket.error()),m_socket.error());
tmp.c_str(),m_socket.error());
}
Thread::idle(true);
continue;
}
@ -240,9 +264,12 @@ bool IAXEngine::writeSocket(const void* buf, int len, const SocketAddr& addr, IA
}
len = m_socket.sendTo(buf,len,addr);
if (len == Socket::socketError()) {
if (!m_socket.canRetry())
if (!m_socket.canRetry()) {
String tmp;
Thread::errorString(tmp,m_socket.error());
Debug(this,DebugWarn,"Socket write error: %s (%d)",
::strerror(m_socket.error()),m_socket.error());
tmp.c_str(),m_socket.error());
}
#ifdef DEBUG
else
Debug(this,DebugMild,"Socket temporary unavailable: %s (%d)",

View File

@ -2036,10 +2036,12 @@ public:
* @param capab Media capabilities of this engine
* @param trunkSendInterval Send trunk meta frame interval
* @param authRequired Automatically challenge all clients for authentication
* @param params Optional extra parameter list
*/
IAXEngine(const char* iface, int port, u_int16_t transListCount, u_int16_t retransCount, u_int16_t retransInterval,
u_int16_t authTimeout, u_int16_t transTimeout, u_int16_t maxFullFrameDataLen,
u_int32_t format, u_int32_t capab, u_int32_t trunkSendInterval, bool authRequired);
u_int32_t format, u_int32_t capab, u_int32_t trunkSendInterval, bool authRequired,
NamedList* params = 0);
/**
* Destructor

View File

@ -263,7 +263,8 @@ public:
*/
YIAXEngine(const char* iface, int port, u_int16_t transListCount, u_int16_t retransCount, u_int16_t retransInterval,
u_int16_t authTimeout, u_int16_t transTimeout,
u_int16_t maxFullFrameDataLen, u_int32_t trunkSendInterval, bool authRequired);
u_int16_t maxFullFrameDataLen, u_int32_t trunkSendInterval, bool authRequired,
NamedList* params);
virtual ~YIAXEngine()
{}
@ -944,10 +945,10 @@ void YIAXTrunking::run()
YIAXEngine::YIAXEngine(const char* iface, int port, u_int16_t transListCount,
u_int16_t retransCount, u_int16_t retransInterval, u_int16_t authTimeout,
u_int16_t transTimeout, u_int16_t maxFullFrameDataLen,
u_int32_t trunkSendInterval, bool authRequired)
u_int32_t trunkSendInterval, bool authRequired, NamedList* params)
: IAXEngine(iface,port,transListCount,retransCount,retransInterval,authTimeout,
transTimeout,maxFullFrameDataLen,iplugin.defaultCodec(),iplugin.codecs(),
trunkSendInterval,authRequired),
trunkSendInterval,authRequired,params),
m_threadsCreated(false)
{
}
@ -1250,7 +1251,7 @@ void YIAXDriver::initialize()
String iface = s_cfg.getValue("general","addr");
bool authReq = s_cfg.getBoolValue("registrar","auth_required",true);
m_iaxEngine = new YIAXEngine(iface,m_port,transListCount,retransCount,retransInterval,authTimeout,
transTimeout,maxFullFrameDataLen,trunkSendInterval,authReq);
transTimeout,maxFullFrameDataLen,trunkSendInterval,authReq,s_cfg.getSection("general"));
m_iaxEngine->debugChain(this);
int tos = s_cfg.getIntValue("general","tos",dict_tos,0);
if (tos && !m_iaxEngine->socket().setTOS(tos))