r3546 - in trunk: libminisip/source libmsip/include/libmsip libmsip/source libmsip/source/transports

mikma at minisip.org mikma at minisip.org
Sun Dec 2 18:57:25 CET 2007


Author: mikma
Date: 2007-12-02 18:57:24 +0100 (Sun, 02 Dec 2007)
New Revision: 3546

Modified:
   trunk/libminisip/source/Minisip.cxx
   trunk/libmsip/include/libmsip/SipTransport.h
   trunk/libmsip/source/SipLayerTransport.cxx
   trunk/libmsip/source/SipLayerTransport.h
   trunk/libmsip/source/SipStackInternal.cxx
   trunk/libmsip/source/SipStackInternal.h
   trunk/libmsip/source/transports/SipTransportDtlsUdp.cxx
   trunk/libmsip/source/transports/SipTransportDtlsUdp.h
   trunk/libmsip/source/transports/SipTransportTcp.cxx
   trunk/libmsip/source/transports/SipTransportTcp.h
   trunk/libmsip/source/transports/SipTransportTls.cxx
   trunk/libmsip/source/transports/SipTransportTls.h
   trunk/libmsip/source/transports/SipTransportUdp.cxx
   trunk/libmsip/source/transports/SipTransportUdp.h
Log:
Improve SIP(S) server start-up. If the preferred SIP or SIPS ports are in use
by another program, then restart the SIP and/or SIPS servers using a
dynamic port instead. This results in all SIP servers using the
same local port number, and so are all SIPS servers.



Modified: trunk/libminisip/source/Minisip.cxx
===================================================================
--- trunk/libminisip/source/Minisip.cxx	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libminisip/source/Minisip.cxx	2007-12-02 17:57:24 UTC (rev 3546)
@@ -353,8 +353,9 @@
 
 		MRef<UDPSocket*> udpSocket = new UDPSocket( phoneConf->sipStackConfig->preferedLocalSipPort );
 
-		//FIXME: We should not update the prefered port
-		phoneConf->sipStackConfig->preferedLocalSipPort = ipProvider->getExternalPort( udpSocket );
+		// TODO call getExternalPort on the real UDPSocket:s
+		// when they are created
+		phoneConf->sipStackConfig->externalContactUdpPort = ipProvider->getExternalPort( udpSocket );
 		phoneConf->sipStackConfig->localIpString = externalContactIP;
 		phoneConf->sipStackConfig->externalContactIP = externalContactIP;
 		if( ip6Provider )

Modified: trunk/libmsip/include/libmsip/SipTransport.h
===================================================================
--- trunk/libmsip/include/libmsip/SipTransport.h	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/include/libmsip/SipTransport.h	2007-12-02 17:57:24 UTC (rev 3546)
@@ -72,9 +72,13 @@
 		 */
 		virtual int32_t getSocketType() const=0;
 
-		/** Setup a new listening socket */
-		virtual MRef<SipSocketServer *> createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const std::string &ipString, int32_t prefPort, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL ) = 0;
 		/**
+		 * Setup a new listening socket.
+		 * @arg prefPort Port to listen on. If 0, then it contains
+		 * the chosen dynamic port after returning.
+		 */
+		virtual MRef<SipSocketServer *> createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const std::string &ipString, int32_t &prefPort, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL ) = 0;
+		/**
 		 * Setup a new connection, implemented by
 		 * connection-oriented transports only
 		 */

Modified: trunk/libmsip/source/SipLayerTransport.cxx
===================================================================
--- trunk/libmsip/source/SipLayerTransport.cxx	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/SipLayerTransport.cxx	2007-12-02 17:57:24 UTC (rev 3546)
@@ -342,8 +342,8 @@
 		cert_chain(cchain), cert_db(cert_db_), tls_ctx(NULL)
 {
 	contactUdpPort=0;
-	contactTcpPort=0;
-	contactTlsPort=0;
+	contactSipPort=0;
+	contactSipsPort=0;
 	manager = new SocketServer();
 	manager->start();
 }
@@ -1241,10 +1241,12 @@
 }
 
 
-void SipLayerTransport::startServer( MRef<SipTransport*> transport, const string &ipString, const string &ip6String, int32_t prefPort, int32_t externalUdpPort, MRef<CertificateChain *> certChain, MRef<CertificateSet *> cert_db){
+void SipLayerTransport::startServer( MRef<SipTransport*> transport, const string &ipString, const string &ip6String, int32_t &prefPort, int32_t externalUdpPort, MRef<CertificateChain *> certChain, MRef<CertificateSet *> cert_db){
 	MRef<SipSocketServer *> server;
+	MRef<SipSocketServer *> server6;
+	int32_t port = prefPort;
 
-	server = transport->createServer( this, false, ipString, prefPort, cert_db, certChain );
+	server = transport->createServer( this, false, ipString, port, cert_db, certChain );
 
 	if( !server ){
 		mdbg << "SipLayerTransport: startServer failed to create server" << endl;
@@ -1255,37 +1257,65 @@
 		server->setExternalPort( externalUdpPort );
 	}
 
-	addServer( server );
-
 	if( transport->getName() == "UDP" ){
 		contactUdpPort = server->getExternalPort();
 	}
 	else if( transport->isSecure() ){
-		contactTlsPort = server->getExternalPort();
+		contactSipsPort = server->getExternalPort();
 	}
 	else{
-		contactTcpPort = server->getExternalPort();
+		contactSipPort = server->getExternalPort();
 	}
 
 	if( ip6String != "" ){
-		MRef<SipSocketServer *> server6;
-
-		server6 = transport->createServer( this, true, ip6String, prefPort, cert_db, certChain );
+		server6 = transport->createServer( this, true, ip6String, port, cert_db, certChain );
 		// IPv6 doesn't need different external udp port
 		// since it never is NATed.
+	}
+
+	addServer( server );
+	if( server6 )
 		addServer( server6 );
-	}
+
+	prefPort = port;
 }
 
+void SipLayerTransport::stopServer( MRef<SipTransport*> transport ){
+	MRef<SipSocketServer *> server =
+		findServer( transport->getSocketType(), false );
 
-int32_t SipLayerTransport::getLocalSipPort( const string &transport ) {
-	if (transport=="TCP" || transport=="tcp")
-		return contactTcpPort;
-	if (transport=="TLS" || transport=="tls")
-		return contactTlsPort;
-	if (transport=="DTLS-UDP" || transport=="dtls-udp")
-		return contactTlsPort;
-	return contactUdpPort;
+	MRef<SipSocketServer *> server6 =
+		findServer( transport->getSocketType(), true );
+
+	// First stop both the IPv4 and IPv6 servers
+	if( server )
+		server->stop();
+	if( server6 )
+		server6->stop();
+
+	// then wait for both threads to exit.
+	if( server )
+		server->join();
+	if( server6 )
+		server6->join();
 }
 
+int32_t SipLayerTransport::getLocalSipPort( const string &transportName ) {
+	if( transportName == "UDP" || transportName == "udp" ){
+		return contactUdpPort;
+	}
 
+	MRef<SipTransport*> transport =
+		SipTransportRegistry::getInstance()->findTransportByName( transportName );
+
+	if( !transport ){
+		return 0;
+	}
+
+	if( transport->isSecure() ){
+		return contactSipsPort;
+	}
+	else {
+		return contactSipPort;
+	}
+}

Modified: trunk/libmsip/source/SipLayerTransport.h
===================================================================
--- trunk/libmsip/source/SipLayerTransport.h	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/SipLayerTransport.h	2007-12-02 17:57:24 UTC (rev 3546)
@@ -81,8 +81,10 @@
 
 		void datagramSocketRead(MRef<DatagramSocket *> sock);
 
-		void startServer( MRef<SipTransport*> transport, const std::string & ipString, const std::string & ip6String, int32_t prefPort, int32_t externalUdpPort, MRef<CertificateChain *> certChain = NULL, MRef<CertificateSet *> cert_db = NULL);
+		void startServer( MRef<SipTransport*> transport, const std::string & ipString, const std::string & ip6String, int32_t &prefPort, int32_t externalUdpPort, MRef<CertificateChain *> certChain = NULL, MRef<CertificateSet *> cert_db = NULL);
 
+		void stopServer( MRef<SipTransport*> transport );
+
 		int32_t getLocalSipPort( const std::string &transport );
 
 	protected:
@@ -143,8 +145,8 @@
 		 * the low layer socket values. 
 		 */
 		int contactUdpPort;
-		int contactTcpPort;
-		int contactTlsPort;
+		int contactSipPort;
+		int contactSipsPort;
 
 		Mutex serversLock;
 		std::list<MRef<SipSocketServer *> > servers;

Modified: trunk/libmsip/source/SipStackInternal.cxx
===================================================================
--- trunk/libmsip/source/SipStackInternal.cxx	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/SipStackInternal.cxx	2007-12-02 17:57:24 UTC (rev 3546)
@@ -406,6 +406,43 @@
 }
 
 void SipStackInternal::startServers(){
+	startSipServers();
+	startSipsServers();
+}
+
+void SipStackInternal::startSipServers(){
+	int32_t port = config->preferedLocalSipPort;
+
+	try {
+		startServers( false, port );
+	} catch ( const BindFailed &bf ){
+		stopServers( false );
+		// Retry with a dynamic port
+		// choosen by the first started transport
+		port = 0;
+		startServers( false, port );
+	}
+
+	mdbg << "SIP servers started on port " << port << endl;
+}
+
+void SipStackInternal::startSipsServers(){
+	int32_t port = config->preferedLocalSipsPort;
+
+	try {
+		startServers( true, port );
+	} catch ( const BindFailed &bf ){
+		stopServers( true );
+		// Retry with a dynamic port
+		// choosen by the first started transport
+		port = 0;
+		startServers( true, port );
+	}
+
+	mdbg << "SIPS servers started on port " << port << endl;
+}
+
+void SipStackInternal::startServers( bool secure, int32_t &prefPort ){
 	list<MRef<SipTransportConfig*> >::const_iterator i;
 	list<MRef<SipTransportConfig*> >::const_iterator last =
 		config->transports.end();
@@ -415,20 +452,26 @@
 
 		if( !transportConfig->isEnabled() )
 			continue;
-#ifdef DEBUG_OUTPUT
-		mout << "SipStack: Starting " << name << " transport worker thread" << endl;
-#endif
 
+		MRef<SipTransport*> transport =
+			SipTransportRegistry::getInstance()->findTransportByName( name );
+		if( !transport ){
+			merr << "Failed to start " << transport->getName() << " server, unsupported" << endl;
+			continue;
+		}
+
+		if( secure != transport->isSecure() ){
+			// Only start on type SIP or SIPS
+			continue;
+		}
+
+		mdbg << "SipStack: Starting " << name << " transport worker thread" << endl;
+
 // 			if( !phoneconfig->defaultIdentity->getSim() || phoneconfig->defaultIdentity->getSim()->getCertificateChain().isNull() ){
 // 				merr << "Certificate needed for TLS server. You will not be able to receive incoming TLS connections." << endl;
 // 			}
 
-		try{
-			startServer( name );
-		}catch( NetworkException &e ){
-			//FIXME: This happens when binding to the IPv6 address
-			merr << "Error: Failed to create to " << name << " socket: "<< e.what()<<endl;
-		}
+		startServer( transport, prefPort );
 	}
 }
 
@@ -442,21 +485,22 @@
 	}
 
 	int32_t port = 0;
-	int32_t externalUdpPort = 0;
-	string ipString = config->localIpString;
 
 	if( transport->isSecure() )
 		port = config->preferedLocalSipsPort;
 	else
 		port = config->preferedLocalSipPort;
 
-	/*
-	  There are three different preferred local ports:
-	  preferedLocalUdpPort - Used by UDP transport only
-	  preferedLocalTcpPort - Used by other SIP transports, TCP etc.
-	  preferedLocalTlsPort - Used by all SIPS transport, TLS and other
-	 */
-	if( transportName == "UDP" ){
+	startServer( transport, port );
+}
+
+
+void SipStackInternal::startServer( MRef<SipTransport*> transport,
+				    int32_t &port ){
+	int32_t externalUdpPort = 0;
+	string ipString = config->localIpString;
+
+	if( transport->getName() == "UDP" ){
 		if( config->externalContactIP.size()>0 ){
 			ipString = config->externalContactIP;
 			externalUdpPort = config->externalContactUdpPort;
@@ -473,7 +517,56 @@
 }
 	
 
+void SipStackInternal::stopServers( bool secure ){
+	list<MRef<SipTransportConfig*> >::const_iterator i;
+	list<MRef<SipTransportConfig*> >::const_iterator last =
+		config->transports.end();
+	for( i = config->transports.begin(); i != last; i++ ){
+		MRef<SipTransportConfig*> transportConfig = (*i);
+		string name = transportConfig->getName();
 
+		if( !transportConfig->isEnabled() )
+			continue;
+
+		MRef<SipTransport*> transport =
+			SipTransportRegistry::getInstance()->findTransportByName( name );
+
+		if( !transport ){
+			mdbg << "Error: Failed to stop " << name << endl;
+			continue;
+		}
+
+		if( secure != transport->isSecure() ){
+			continue;
+		}
+
+		mdbg << "SipStack: Stopping " << name << " transport worker thread" << endl;
+
+		stopServer( transport );
+	}
+}
+
+
+void SipStackInternal::stopServer( const string &transportName ){
+	MRef<SipTransport*> transport =
+		SipTransportRegistry::getInstance()->findTransportByName( transportName );
+
+	if( !transport ){
+		mdbg << "Error: Failed to stop " << transportName << endl;
+		return;
+	}
+
+	stopServer( transport );
+}
+
+void SipStackInternal::stopServer( MRef<SipTransport*> transport ){
+	try{
+		dispatcher->getLayerTransport()->stopServer( transport );
+	}catch( NetworkException &e ){
+		mdbg << "Error: Failed to stop " << transport->getName() << ": "<< e.what()<<endl;
+	}
+}
+
 int32_t SipStackInternal::getLocalSipPort(bool usesStun, const string &transport ) {
 
 	return dispatcher->getLayerTransport()->getLocalSipPort( transport );

Modified: trunk/libmsip/source/SipStackInternal.h
===================================================================
--- trunk/libmsip/source/SipStackInternal.h	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/SipStackInternal.h	2007-12-02 17:57:24 UTC (rev 3546)
@@ -29,6 +29,7 @@
 #include<libmutil/CommandString.h>
 #include<libmsip/SipDialogConfig.h>
 #include<libmsip/SipTimers.h>
+#include<libmsip/SipTransport.h>
 
 #include"SipLayerTransport.h"
 #include"transactions/SipTransaction.h"
@@ -88,14 +89,30 @@
 
 		MRef<SipTransportConfig*> findTransportConfig( const std::string &transportName ) const;
 
+		/** Start all enabled SIP(S) servers */
 		void startServers();
 
-		void startServer( const std::string &tranportName );
+		/** Start all enabled SIP(S) servers */
+		void stopServers();
 
+		void startServer( const std::string &transportName );
+
+		void stopServer( const std::string &transportName );
+
 		int32_t getLocalSipPort(bool usesStun, const std::string &transport);
 
 		void free();
 
+	protected:
+		void startSipServers();
+		void startSipsServers();
+		void startServers( bool secure, int32_t &prefPort );
+		void startServer( MRef<SipTransport*> transport,
+				  int32_t &port );
+
+		void stopServers( bool secure );
+		void stopServer( MRef<SipTransport*> transport );
+
 	private:
 
 		MRef<SipTimers*> timers;

Modified: trunk/libmsip/source/transports/SipTransportDtlsUdp.cxx
===================================================================
--- trunk/libmsip/source/transports/SipTransportDtlsUdp.cxx	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/transports/SipTransportDtlsUdp.cxx	2007-12-02 17:57:24 UTC (rev 3546)
@@ -64,36 +64,18 @@
  *   number here. This can be used for example to implement support for
  *   passing NATs with the help of a STUN server.
  */
-MRef<SipSocketServer *> SipTransportDtlsUdp::createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const string &ipString, int32_t prefPort, MRef<CertificateSet *> cert_db, MRef<CertificateChain *> certChain  )
+MRef<SipSocketServer *> SipTransportDtlsUdp::createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const string &ipString, int32_t &prefPort, MRef<CertificateSet *> cert_db, MRef<CertificateChain *> certChain  )
 {
 	int32_t port = prefPort;
-	int triesLeft=10;
 	MRef<SipSocketServer *> server;
-	bool fail;
 
-	do {
-		fail=false;
-		try {
+	MRef<DatagramSocket *> sock = new UDPSocket( port, ipv6 );
+	MRef<DatagramSocket *> dsock =
+		DTLSSocket::create( sock, certChain->getFirst(), cert_db );
+	server = new DatagramSocketServer( receiver, dsock );
+	server->setExternalIp( ipString );
+	prefPort = sock->getPort();
 
-			MRef<DatagramSocket *> sock = new UDPSocket( port, ipv6 );
-			MRef<DatagramSocket *> dsock =
-				DTLSSocket::create( sock, certChain->getFirst(), cert_db );
-			server = new DatagramSocketServer( receiver, dsock );
-			server->setExternalIp( ipString );
-
-
-		} catch(const BindFailed &bf){
-			fail=true;
-
-			// If the port is already in use, try random port number in the range 2048 to 63488
-			port = rand()%(0xFFFF-4096) + 2048; 
-			triesLeft--;
-			if (!triesLeft)
-				throw;
-
-		}
-	}while(fail);
-
 	return server;
 }
 

Modified: trunk/libmsip/source/transports/SipTransportDtlsUdp.h
===================================================================
--- trunk/libmsip/source/transports/SipTransportDtlsUdp.h	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/transports/SipTransportDtlsUdp.h	2007-12-02 17:57:24 UTC (rev 3546)
@@ -45,7 +45,7 @@
 
 		virtual std::string getNaptrService() const { return "SIPS+D2U"; }
 
-		virtual MRef<SipSocketServer *> createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const std::string &ipString, int32_t prefPort, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL );
+		virtual MRef<SipSocketServer *> createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const std::string &ipString, int32_t &prefPort, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL );
 
 		// MPlugin
 		virtual std::string getName() const { return "DTLS-UDP"; }

Modified: trunk/libmsip/source/transports/SipTransportTcp.cxx
===================================================================
--- trunk/libmsip/source/transports/SipTransportTcp.cxx	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/transports/SipTransportTcp.cxx	2007-12-02 17:57:24 UTC (rev 3546)
@@ -58,28 +58,17 @@
 
 
 
-MRef<SipSocketServer *> SipTransportTcp::createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const string &ipString, int32_t prefPort, MRef<CertificateSet *> cert_db, MRef<CertificateChain *> certChain )
+MRef<SipSocketServer *> SipTransportTcp::createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const string &ipString, int32_t &prefPort, MRef<CertificateSet *> cert_db, MRef<CertificateChain *> certChain )
 {
 	MRef<ServerSocket *> sock;
 	MRef<SipSocketServer *> server;
 	int32_t port = prefPort;
-	bool fail;
-	int triesLeft=10;
 
-	do {
-		fail=false;
-		try {
-			sock = TcpServerSocket::create( port, ipv6 );
-			server = new StreamSocketServer( receiver, sock );
-			server->setExternalIp( ipString );
+	sock = TcpServerSocket::create( port, ipv6 );
+	server = new StreamSocketServer( receiver, sock );
+	server->setExternalIp( ipString );
 
-		} catch ( const BindFailed &bf ){
-			fail=true;
-			triesLeft--;
-			if (!triesLeft)
-				throw;
-		}
-	} while ( fail );
+	prefPort = sock->getPort();
 
 	return server;
 }

Modified: trunk/libmsip/source/transports/SipTransportTcp.h
===================================================================
--- trunk/libmsip/source/transports/SipTransportTcp.h	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/transports/SipTransportTcp.h	2007-12-02 17:57:24 UTC (rev 3546)
@@ -44,7 +44,7 @@
 
 		virtual std::string getNaptrService() const { return "SIP+D2T"; }
 
-		virtual MRef<SipSocketServer *> createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const std::string &ipString, int32_t prefPort, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL );
+		virtual MRef<SipSocketServer *> createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const std::string &ipString, int32_t &prefPort, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL );
 
 		virtual MRef<StreamSocket *> connect( const IPAddress &addr, uint16_t port, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL );
 

Modified: trunk/libmsip/source/transports/SipTransportTls.cxx
===================================================================
--- trunk/libmsip/source/transports/SipTransportTls.cxx	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/transports/SipTransportTls.cxx	2007-12-02 17:57:24 UTC (rev 3546)
@@ -59,13 +59,11 @@
 
 
 
-MRef<SipSocketServer *> SipTransportTls::createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const string &ipString, int32_t prefPort, MRef<CertificateSet *> cert_db, MRef<CertificateChain *> certChain )
+MRef<SipSocketServer *> SipTransportTls::createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const string &ipString, int32_t &prefPort, MRef<CertificateSet *> cert_db, MRef<CertificateChain *> certChain )
 {
 	MRef<ServerSocket *> sock;
 	MRef<SipSocketServer *> server;
 	int32_t port = prefPort;
-	bool fail;
-	int triesLeft=10;
 
 	if( certChain.isNull() || certChain->getFirst().isNull() ){
 		merr << "You need a personal certificate to run "
@@ -75,24 +73,14 @@
 		return NULL;
 	}
 
-	do {
-		fail=false;
-		try{
-			MRef<ServerSocket*> ssock =
-				TcpServerSocket::create( port, ipv6 );
-			sock = TLSServerSocket::create( ssock, /*config->cert*/certChain->getFirst(),
-					/*config->*/cert_db );
-			server = new StreamSocketServer( receiver, sock );
-			server->setExternalIp( ipString );
-		} catch (const BindFailed &bf){
-			fail=true;
-			triesLeft--;
-			if (!triesLeft)
-				throw;
-		}
+	MRef<ServerSocket*> ssock =
+		TcpServerSocket::create( port, ipv6 );
+	sock = TLSServerSocket::create( ssock, certChain->getFirst(),
+					cert_db );
+	server = new StreamSocketServer( receiver, sock );
+	server->setExternalIp( ipString );
+	prefPort = sock->getPort();
 
-	} while (fail);
-
 	return server;
 }
 

Modified: trunk/libmsip/source/transports/SipTransportTls.h
===================================================================
--- trunk/libmsip/source/transports/SipTransportTls.h	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/transports/SipTransportTls.h	2007-12-02 17:57:24 UTC (rev 3546)
@@ -44,7 +44,7 @@
 
 		virtual std::string getNaptrService() const { return "SIPS+D2T"; }
 
-		virtual MRef<SipSocketServer *> createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const std::string &ipString, int32_t prefPort, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL );
+		virtual MRef<SipSocketServer *> createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const std::string &ipString, int32_t &prefPort, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL );
 
 		virtual MRef<StreamSocket *> connect( const IPAddress &addr, uint16_t port, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL );
 

Modified: trunk/libmsip/source/transports/SipTransportUdp.cxx
===================================================================
--- trunk/libmsip/source/transports/SipTransportUdp.cxx	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/transports/SipTransportUdp.cxx	2007-12-02 17:57:24 UTC (rev 3546)
@@ -64,34 +64,16 @@
  *   number here. This can be used for example to implement support for
  *   passing NATs with the help of a STUN server.
  */
-MRef<SipSocketServer *> SipTransportUdp::createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const string &ipString, int32_t prefPort, MRef<CertificateSet *> cert_db, MRef<CertificateChain *> certChain  )
+MRef<SipSocketServer *> SipTransportUdp::createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const string &ipString, int32_t &prefPort, MRef<CertificateSet *> cert_db, MRef<CertificateChain *> certChain  )
 {
 	int32_t port = prefPort;
-	int triesLeft=10;
 	MRef<SipSocketServer *> server;
-	bool fail;
 
-	do {
-		fail=false;
-		try {
+	MRef<DatagramSocket *> sock = new UDPSocket( port, ipv6 );
+	server = new DatagramSocketServer( receiver, sock );
+	server->setExternalIp( ipString );
 
-			MRef<DatagramSocket *> sock = new UDPSocket( port, ipv6 );
-			server = new DatagramSocketServer( receiver, sock );
-			server->setExternalIp( ipString );
-
-
-		} catch(const BindFailed &bf){
-			fail=true;
-
-			// If the port is already in use, try random port number in the range 2048 to 63488
-			port = rand()%(0xFFFF-4096) + 2048; 
-			triesLeft--;
-			if (!triesLeft)
-				throw;
-
-		}
-	}while(fail);
-
+	prefPort = sock->getPort();
 	return server;
 }
 

Modified: trunk/libmsip/source/transports/SipTransportUdp.h
===================================================================
--- trunk/libmsip/source/transports/SipTransportUdp.h	2007-12-02 12:44:52 UTC (rev 3545)
+++ trunk/libmsip/source/transports/SipTransportUdp.h	2007-12-02 17:57:24 UTC (rev 3546)
@@ -44,7 +44,7 @@
 
 		virtual std::string getNaptrService() const { return "SIP+D2U"; }
 
-		virtual MRef<SipSocketServer *> createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const std::string &ipString, int32_t prefPort, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL );
+		virtual MRef<SipSocketServer *> createServer( MRef<SipSocketReceiver*> receiver, bool ipv6, const std::string &ipString, int32_t &prefPort, MRef<CertificateSet *> cert_db = NULL, MRef<CertificateChain *> certChain = NULL );
 
 		// MPlugin
 		virtual std::string getName() const { return "UDP"; }



More information about the Minisip-devel mailing list