r3487 - in trunk/libmsip: . include/libmsip source source/transports

mikma at minisip.org mikma at minisip.org
Sun Nov 18 18:06:31 CET 2007


Author: mikma
Date: 2007-11-18 18:06:31 +0100 (Sun, 18 Nov 2007)
New Revision: 3487

Added:
   trunk/libmsip/source/transports/SipTransportDtlsUdp.cxx
   trunk/libmsip/source/transports/SipTransportDtlsUdp.h
Modified:
   trunk/libmsip/Makefile.am
   trunk/libmsip/configure.ac
   trunk/libmsip/include/libmsip/SipStack.h
   trunk/libmsip/source/SipLayerTransport.cxx
   trunk/libmsip/source/SipLayerTransport.h
   trunk/libmsip/source/SipStack.cxx
   trunk/libmsip/source/SipStackInternal.cxx
   trunk/libmsip/source/SipStackInternal.h
   trunk/libmsip/source/transports/SipTransport.cxx
   trunk/libmsip/source/transports/SipTransport.h
   trunk/libmsip/source/transports/SipTransportTls.cxx
Log:
* Add an implementation of DTLS-UDP transport protocol. Support for DTLS
  in libmcrypto, depending on OpenSSL 0.9.8f or later,
  is auto-detected by configure. 

* Implement SipTransportRegistry::findTransportByName.

SipStackInternal:
SipLayerTransport:
* Replace startXXXServer with startServer which take a transport name and
  transport reference respectively as parameter. This makes it easier
  to add new transport protocols.

* Replace startXXXServer with startServer 


Modified: trunk/libmsip/Makefile.am
===================================================================
--- trunk/libmsip/Makefile.am	2007-11-18 16:46:54 UTC (rev 3486)
+++ trunk/libmsip/Makefile.am	2007-11-18 17:06:31 UTC (rev 3487)
@@ -19,6 +19,11 @@
 libmsip_la_DEPENDENCIES = $(res_obj)
 endif OS_WIN
 
+if HAVE_DTLS
+msip_dtls_src =      source/transports/SipTransportDtlsUdp.h \
+		     source/transports/SipTransportDtlsUdp.cxx
+endif HAVE_DTLS
+
 msip_src =           source/SipDialogConfig.cxx \
 		     source/SipAuthenticationDigest.cxx \
 		     source/SipStack.cxx \
@@ -64,6 +69,7 @@
 		     source/transports/SipTransportTcp.cxx \
 		     source/transports/SipTransportTls.h \
 		     source/transports/SipTransportTls.cxx \
+		     $(msip_dtls_src) \
                      source/dialogs/SipTransitionUtils.cxx \
 		     source/dialogs/SipDialog.cxx \
 		     source/dialogs/SipDialogRegister.cxx \

Modified: trunk/libmsip/configure.ac
===================================================================
--- trunk/libmsip/configure.ac	2007-11-18 16:46:54 UTC (rev 3486)
+++ trunk/libmsip/configure.ac	2007-11-18 17:06:31 UTC (rev 3487)
@@ -45,6 +45,10 @@
 AM_MINISIP_CHECK_LIBMCRYPTO([0.3.0])
 AM_MINISIP_CHECK_COMPLETE
 
+dnl Checks for DTLS support in libmcrypto
+AM_MINISIP_CHECK_LIBMCRYPTO_DTLS([have_dtls=yes], [have_dtls=no])
+AM_CONDITIONAL(HAVE_DTLS, test "${have_dtls}" = "yes")
+
 dnl Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS([malloc.h stdlib.h string.h unistd.h])

Modified: trunk/libmsip/include/libmsip/SipStack.h
===================================================================
--- trunk/libmsip/include/libmsip/SipStack.h	2007-11-18 16:46:54 UTC (rev 3486)
+++ trunk/libmsip/include/libmsip/SipStack.h	2007-11-18 17:06:31 UTC (rev 3487)
@@ -271,6 +271,13 @@
 		void startTlsServer();
 
 		/**
+		 * Start a SIP(S) server
+		 * @param transportName Name of the transport plugin,
+		 * one of UDP, TCP, TLS etc.
+		 */
+		void startServer( const std::string &transportName );
+
+		/**
 		@return the port in use, depending on the transport.
 		@param usesStun (default false), found in SipSoftPhoneConfiguration::useSTUN
 		*/

Modified: trunk/libmsip/source/SipLayerTransport.cxx
===================================================================
--- trunk/libmsip/source/SipLayerTransport.cxx	2007-11-18 16:46:54 UTC (rev 3486)
+++ trunk/libmsip/source/SipLayerTransport.cxx	2007-11-18 17:06:31 UTC (rev 3487)
@@ -1182,78 +1182,39 @@
 }
 
 
-void SipLayerTransport::startUdpServer(const string &ipString, const string &ip6String, int32_t localUdpPort, int32_t externalContactUdpPort)
-{
+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;
-/*
-	string ipString;
-	if( config->externalContactIP.size()>0 )
-		ipString = config->externalContactIP;
-	else
-		ipString = config->localIpString;
-*/
-	MRef<SipTransport*> udp =
-		SipTransportRegistry::getInstance()->findTransport("udp");
 
-	server = udp->createServer( this, false, ipString, localUdpPort );
+	server = transport->createServer( this, false, ipString, prefPort, cert_db, certChain );
 
-	if( externalContactUdpPort ){
-		server->setExternalPort( externalContactUdpPort );
+	if( !server ){
+		mdbg << "SipLayerTransport: startServer failed to create server" << endl;
+		return;
 	}
-	addServer( server );
-	contactUdpPort = server->getExternalPort();
 
-	if( /*config->localIp6String*/ ip6String != "" ){
-		MRef<SipSocketServer *> server6;
-		server6 = udp->createServer( this, true, ip6String,localUdpPort );
-		// IPv6 doesn't need different external udp port
-		// since it never is NATed.
-		addServer( server6 );
+	if( externalUdpPort ){
+		server->setExternalPort( externalUdpPort );
 	}
-}
 
-
-void SipLayerTransport::startTcpServer( const string & ipString, const string & ip6String, int32_t prefPort)
-{
-	MRef<SipSocketServer *> server;
-	MRef<SipTransport*> tcp =
-		SipTransportRegistry::getInstance()->findTransport("tcp");
-
-	server = tcp->createServer( this, false, ipString, prefPort);
 	addServer( server );
-	contactTcpPort = server->getExternalPort();
 
-	if( /*config->localIp6String*/ ip6String != "" ){
-		MRef<SipSocketServer *> server6;
-
-		server6 = tcp->createServer( this, true, ip6String, prefPort );
-		addServer( server6 );
+	if( transport->getName() == "UDP" ){
+		contactUdpPort = server->getExternalPort();
 	}
-}
-
-void SipLayerTransport::startTlsServer( const string &ipString, const string &ip6String, int32_t prefPort, MRef<CertificateChain *> certChain, MRef<CertificateSet *> cert_db){
-	MRef<SipSocketServer *> server;
-
-	if( certChain.isNull() || certChain->getFirst().isNull() ){
-		merr << "You need a personal certificate to run "
-			"a TLS server. Please specify one in "
-			"the certificate settings. minisip will "
-			"now disable the TLS server." << endl;
-		return;
+	else if( transport->isSecure() ){
+		contactTlsPort = server->getExternalPort();
 	}
+	else{
+		contactTcpPort = server->getExternalPort();
+	}
 
-	MRef<SipTransport*> tls =
-		SipTransportRegistry::getInstance()->findTransport( "tcp", true );
-
-	server = tls->createServer( this, false, ipString, prefPort, cert_db, certChain );
-	addServer( server );
-	contactTlsPort = server->getExternalPort();
-
-	if( /*config->localIp6String*/ ip6String != "" ){
+	if( ip6String != "" ){
 		MRef<SipSocketServer *> server6;
 
-		server6 = tls->createServer( this, true, ip6String, prefPort, cert_db, certChain );
-		dispatcher->getLayerTransport()->addServer( server6 );
+		server6 = transport->createServer( this, true, ip6String, prefPort, cert_db, certChain );
+		// IPv6 doesn't need different external udp port
+		// since it never is NATed.
+		addServer( server6 );
 	}
 }
 
@@ -1263,6 +1224,8 @@
 		return contactTcpPort;
 	if (transport=="TLS" || transport=="tls")
 		return contactTlsPort;
+	if (transport=="DTLS-UDP" || transport=="dtls-udp")
+		return contactTlsPort;
 	return contactUdpPort;
 }
 

Modified: trunk/libmsip/source/SipLayerTransport.h
===================================================================
--- trunk/libmsip/source/SipLayerTransport.h	2007-11-18 16:46:54 UTC (rev 3486)
+++ trunk/libmsip/source/SipLayerTransport.h	2007-11-18 17:06:31 UTC (rev 3487)
@@ -81,9 +81,7 @@
 
 		void datagramSocketRead(MRef<DatagramSocket *> sock);
 
-		void startUdpServer( const std::string & ipString, const std::string & ip6String, int32_t prefUdpPort, int32_t externalContactUdpPort);
-		void startTcpServer( const std::string & ipString, const std::string & ip6String, int32_t prefPort );
-		void startTlsServer( const std::string & ipString, const std::string & ip6String, int32_t prefPort, MRef<CertificateChain *> certChain, MRef<CertificateSet *> cert_db );
+		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);
 
 		int32_t getLocalSipPort( const std::string &transport );
 

Modified: trunk/libmsip/source/SipStack.cxx
===================================================================
--- trunk/libmsip/source/SipStack.cxx	2007-11-18 16:46:54 UTC (rev 3486)
+++ trunk/libmsip/source/SipStack.cxx	2007-11-18 17:06:31 UTC (rev 3487)
@@ -190,17 +190,21 @@
 }
 
 void SipStack::startUdpServer(){
-	STACK->startUdpServer();
+	STACK->startServer( "UDP" );
 }
 
 void SipStack::startTcpServer(){
-	STACK->startTcpServer();
+	STACK->startServer( "TCP" );
 }
 
 void SipStack::startTlsServer(){
-	STACK->startTlsServer();
+	STACK->startServer( "TLS" );
 }
 
+void SipStack::startServer( const string &transportName ){
+	STACK->startServer( transportName );
+}
+
 int32_t SipStack::getLocalSipPort(bool usesStun, const string &transport ) {
 	return STACK->getLocalSipPort(usesStun, transport);
 }

Modified: trunk/libmsip/source/SipStackInternal.cxx
===================================================================
--- trunk/libmsip/source/SipStackInternal.cxx	2007-11-18 16:46:54 UTC (rev 3486)
+++ trunk/libmsip/source/SipStackInternal.cxx	2007-11-18 17:06:31 UTC (rev 3487)
@@ -68,9 +68,9 @@
 
 #include<libmutil/dbg.h>
 #include<libmcrypto/cert.h>
-#include<libmcrypto/TlsSocket.h>
-#include<libmcrypto/TlsServerSocket.h>
 
+#include"transports/SipTransport.h"
+
 using namespace std;
 
 SipStackInternal::SipStackInternal( MRef<SipStackConfig *> stackConfig )
@@ -379,38 +379,48 @@
 }
 
 
-void SipStackInternal::startUdpServer()
-{
-	string ipString;
+void SipStackInternal::startServer( const string &transportName ){
+	MRef<SipTransport*> transport =
+		SipTransportRegistry::getInstance()->findTransportByName( transportName );
 
-	if( config->externalContactIP.size()>0 )
-		ipString = config->externalContactIP;
-	else
-		ipString = config->localIpString;
+	if( !transport ){
+		merr << "Failed to start " << transportName << " server, unsupported" << endl;
+		return;
+	}
 
-	dispatcher->getLayerTransport()->startUdpServer( ipString, 
-							config->localIp6String, 
-							config->preferedLocalUdpPort, 
-							config->externalContactUdpPort );
-}
+	int32_t port;
+	int32_t externalUdpPort = 0;
+	string ipString = config->localIpString;
 
+	/*
+	  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" ){
+		if( config->externalContactIP.size()>0 ){
+			ipString = config->externalContactIP;
+			externalUdpPort = config->externalContactUdpPort;
+		}
+		port = config->preferedLocalUdpPort;
+	}
+	else{
+		// TODO externalUdpPort for DTLS-UDP 
+		port = transport->isSecure() ? config->preferedLocalTlsPort : config->preferedLocalTcpPort;
+	}
 
-void SipStackInternal::startTcpServer()
-{
-	dispatcher->getLayerTransport()->startTcpServer( config->localIpString, config->localIp6String, config->preferedLocalTcpPort );
-	
-}
-
-void SipStackInternal::startTlsServer(){
-
-	dispatcher->getLayerTransport()->startTlsServer( 
-				config->localIpString, 
+	dispatcher->getLayerTransport()->startServer( transport,
+				ipString, 
 				config->localIp6String, 
-				config->preferedLocalTlsPort, 
+				port, 
+				externalUdpPort,
 				config->cert, 
 				config->cert_db );
 }
+	
 
+
 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-11-18 16:46:54 UTC (rev 3486)
+++ trunk/libmsip/source/SipStackInternal.h	2007-11-18 17:06:31 UTC (rev 3487)
@@ -86,9 +86,7 @@
                 
 		std::string getStackStatusDebugString();
 
-		void startUdpServer();
-		void startTcpServer();
-		void startTlsServer();
+		void startServer( const std::string &tranportName );
 
 		int32_t getLocalSipPort(bool usesStun, const std::string &transport);
 

Modified: trunk/libmsip/source/transports/SipTransport.cxx
===================================================================
--- trunk/libmsip/source/transports/SipTransport.cxx	2007-11-18 16:46:54 UTC (rev 3486)
+++ trunk/libmsip/source/transports/SipTransport.cxx	2007-11-18 17:06:31 UTC (rev 3487)
@@ -26,6 +26,7 @@
 #include"SipTransportUdp.h"
 #include"SipTransportTcp.h"
 #include"SipTransportTls.h"
+#include"SipTransportDtlsUdp.h"
 
 using namespace std;
 
@@ -59,6 +60,9 @@
 	registerPlugin( new SipTransportUdp( NULL ) );
 	registerPlugin( new SipTransportTcp( NULL ) );
 	registerPlugin( new SipTransportTls( NULL ) );
+#ifdef HAVE_DTLS
+	registerPlugin( new SipTransportDtlsUdp( NULL ) );
+#endif
 }
 
 MRef<SipTransport*> SipTransportRegistry::findTransport( const string &protocol, bool secure ) const{
@@ -83,7 +87,7 @@
 
 		if( transport->isSecure() == secure &&
 		    transport->getProtocol() == lcProt ){
-			mdbg << "SipTransport: tranport found!!! =  " << lcProt << endl;
+			mdbg << "SipTransport: transport found!!! =  " << lcProt << endl;
 			return transport;
 		}
 	}
@@ -144,3 +148,13 @@
 
 	return NULL;
 }
+
+MRef<SipTransport*> SipTransportRegistry::findTransportByName( const std::string &name ) const{
+	MRef<MPlugin*> transport = findPlugin( name );
+
+	if( transport ){
+		return dynamic_cast<SipTransport*>(*transport);
+	}
+
+	return NULL;
+}

Modified: trunk/libmsip/source/transports/SipTransport.h
===================================================================
--- trunk/libmsip/source/transports/SipTransport.h	2007-11-18 16:46:54 UTC (rev 3486)
+++ trunk/libmsip/source/transports/SipTransport.h	2007-11-18 17:06:31 UTC (rev 3487)
@@ -97,6 +97,9 @@
 		/** Search for transport by socket type. */
 		MRef<SipTransport*> findTransport( int32_t socketType ) const;
 
+		/** Search for transport by plugin name */  
+		MRef<SipTransport*> findTransportByName( const std::string &name ) const;
+
 	protected:
 		SipTransportRegistry();
 

Copied: trunk/libmsip/source/transports/SipTransportDtlsUdp.cxx (from rev 3485, trunk/libmsip/source/transports/SipTransportUdp.cxx)
===================================================================
--- trunk/libmsip/source/transports/SipTransportDtlsUdp.cxx	                        (rev 0)
+++ trunk/libmsip/source/transports/SipTransportDtlsUdp.cxx	2007-11-18 17:06:31 UTC (rev 3487)
@@ -0,0 +1,102 @@
+/*
+  Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien
+  Copyright (C) 2005-2007  Mikael Magnusson
+  
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/*
+ * Authors: Erik Eliasson <eliasson at it.kth.se>
+ *          Johan Bilien <jobi at via.ecp.fr>
+ *          Mikael Magnusson <mikma at users.sourceforge.net>
+*/
+
+#include<config.h>
+#include<libmnetutil/NetworkException.h>
+#include<libmnetutil/UDPSocket.h>
+#include"SipTransportDtlsUdp.h"
+
+static std::list<std::string> pluginList;
+static int initialized;
+
+using namespace std;
+
+extern "C" LIBMSIP_API
+std::list<std::string> *mdtlsudp_LTX_listPlugins( MRef<Library*> lib ){
+	if( !initialized ){
+		pluginList.push_back("getPlugin");
+		initialized = true;
+	}
+
+	return &pluginList;
+}
+
+extern "C" LIBMSIP_API
+MPlugin * mdtlsudp_LTX_getPlugin( MRef<Library*> lib ){
+	return new SipTransportDtlsUdp( lib );
+}
+
+
+SipTransportDtlsUdp::SipTransportDtlsUdp( MRef<Library*> lib ) : SipTransport( lib ){
+}
+
+SipTransportDtlsUdp::~SipTransportDtlsUdp(){
+}
+
+
+
+/**
+ *
+ * @param externalPort  If the application wishes to override what port
+ *   should be reported for the socket it is possible to specify such a port
+ *   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<SipLayerTransport*> 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 );
+
+
+		} 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;
+}
+
+uint32_t SipTransportDtlsUdp::getVersion() const{
+	return 0x00000001;
+}

Copied: trunk/libmsip/source/transports/SipTransportDtlsUdp.h (from rev 3485, trunk/libmsip/source/transports/SipTransportUdp.h)
===================================================================
--- trunk/libmsip/source/transports/SipTransportDtlsUdp.h	                        (rev 0)
+++ trunk/libmsip/source/transports/SipTransportDtlsUdp.h	2007-11-18 17:06:31 UTC (rev 3487)
@@ -0,0 +1,59 @@
+/*
+  Copyright (C) 2006-2007 Mikael Magnusson
+  
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/*
+ * Authors: Mikael Magnusson <mikma at users.sourceforge.net>
+*/
+
+#ifndef SIP_TRANSPORT_DTLS_UDP_H
+#define SIP_TRANSPORT_DTLS_UDP_H
+
+#include<libmsip/libmsip_config.h>
+
+#include<string>
+#include<libmcrypto/DtlsSocket.h>
+#include"SipTransport.h"
+
+class SipTransportDtlsUdp: public SipTransport{
+	public:
+		SipTransportDtlsUdp( MRef<Library *> lib );
+		virtual ~SipTransportDtlsUdp();
+
+		// SipTransport
+		virtual bool isSecure() const { return true; }
+
+		virtual std::string getProtocol() const { return "udp"; }
+
+		virtual std::string getViaProtocol() const { return "DTLS-UDP"; }
+
+		virtual int32_t getSocketType() const { return SOCKET_TYPE_DTLS_UDP; }
+
+		virtual MRef<SipSocketServer *> createServer( MRef<SipLayerTransport*> 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"; }
+
+		virtual uint32_t getVersion() const;
+
+		virtual std::string getDescription() const { return "SIP Transport DTLS-UDP"; };
+
+		// MObject
+		virtual std::string getMemObjectType() const { return getName(); }
+};
+
+#endif

Modified: trunk/libmsip/source/transports/SipTransportTls.cxx
===================================================================
--- trunk/libmsip/source/transports/SipTransportTls.cxx	2007-11-18 16:46:54 UTC (rev 3486)
+++ trunk/libmsip/source/transports/SipTransportTls.cxx	2007-11-18 17:06:31 UTC (rev 3487)
@@ -66,6 +66,14 @@
 	bool fail;
 	int triesLeft=10;
 
+	if( certChain.isNull() || certChain->getFirst().isNull() ){
+		merr << "You need a personal certificate to run "
+			"a TLS server. Please specify one in "
+			"the certificate settings. minisip will "
+			"now disable the TLS server." << endl;
+		return NULL;
+	}
+
 	do {
 		fail=false;
 		try{



More information about the Minisip-devel mailing list