[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#681387: unblock: resiprocate (follow up)




On 08/08/12 00:24, Cyril Brulebois wrote:
> Hello,
> 
> Adam D. Barratt <adam@adam-barratt.org.uk> (04/08/2012):
>> It'd still really want someone from the team to be happy with the
>> changes before unblocking them however.
> 
> I think I won't be against having 1.8.4 in unstable, and see what
> happens on the bug reports front after an extended period of time (say
> 20 days).

20 days is fine - we've already had some feedback on 1.8.4 and now there
is a 1.8.5 release

Would you be happy to accept 1.8.5 on the same terms?

I attach a debdiff and SVN log output (1.8.4 vs. 1.8.5)

Coloured diffs can be browsed at the links referred to in my earlier
email in the bug report.

The debdiff excludes about 2000 lines from the apps/basicB2BUA directory
- it is a new addition to the source tree, but none of it is packaged.

> I see at least constructor-related, inheritance-related changes, method
> additions, and so on.
> 
> While I have read most of those changes are backports to stable
> branches, I can't help thinking actual tests by actual users are always
> a good idea.

Agreed - that is how most of the fixes came into 1.8.5 - e.g. one user
found that the --help output was crashing the program

None of these issues are strictly release critical - but they are all
fixes that provide a better experience of the package.

> No promise on our (possibly) unblocking this package after the said
> period of time.

Understood - do I need to put Closes: #681387 in the changelog for upload?


--- resiprocate-1.8.4/apps/Makefile.in	2012-07-05 15:15:45.000000000 +0000
+++ resiprocate-1.8.5/apps/Makefile.in	2012-08-08 12:51:16.000000000 +0000
@@ -34,6 +34,7 @@
 build_triplet = @build@
 host_triplet = @host@
 @BUILD_ICHAT_GW_TRUE@am__append_1 = ichat-gw
+@BUILD_B2BUA_TRUE@am__append_2 = basicB2BUA
 subdir = apps
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -64,7 +65,7 @@
 	distdir
 ETAGS = etags
 CTAGS = ctags
-DIST_SUBDIRS = clicktocall sipdial ichat-gw
+DIST_SUBDIRS = clicktocall sipdial ichat-gw basicB2BUA
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -217,7 +218,7 @@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-SUBDIRS = clicktocall sipdial $(am__append_1)
+SUBDIRS = clicktocall sipdial $(am__append_1) $(am__append_2)
 all: all-recursive
 
 .SUFFIXES:
diff -Nru resiprocate-1.8.4/apps/sipdial/DialerConfiguration.cpp resiprocate-1.8.5/apps/sipdial/DialerConfiguration.cpp
--- resiprocate-1.8.4/apps/sipdial/DialerConfiguration.cpp	2012-07-05 15:09:56.000000000 +0000
+++ resiprocate-1.8.5/apps/sipdial/DialerConfiguration.cpp	2012-08-08 12:48:27.000000000 +0000
@@ -12,11 +12,11 @@
 using namespace std;
 
 DialerConfiguration::DialerConfiguration() :
-   mDialerIdentity("anonymous@localhost"),
+   mDialerIdentity("sip:anonymous@localhost"),
    mAuthRealm(""),
    mAuthUser(""),
    mAuthPassword(""),
-   mCallerUserAgentAddress(""),
+   mCallerUserAgentAddress("sip:anonymous@localhost"),
    mCallerUserAgentVariety(Generic),
    mTargetPrefix(""),
    mTargetDomain("localhost"),
@@ -25,19 +25,23 @@
 {
 }
 
-DialerConfiguration::DialerConfiguration(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount) :
-   resip::ConfigParse(argc, argv, defaultConfigFilename, skipCount),
-   mDialerIdentity(getConfigData("dialerIdentity", "anonymous@example.org")),
-   mAuthRealm(getConfigData("authRealm", "")),
-   mAuthUser(getConfigData("authUser", "")),
-   mAuthPassword(getConfigData("authPassword", "")),
-   mCallerUserAgentAddress(getConfigData("callerUserAgentAddress", "")),
-   mCallerUserAgentVariety(Generic),
-   mTargetPrefix(getConfigData("targetPrefix", "")),
-   mTargetDomain(getConfigData("targetDomain", "localhost")),
-   mCertPath(getConfigData("certPath", "")),
-   mCADirectory(getConfigData("CADirectory", ""))
+void DialerConfiguration::parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount) 
 {
+   resip::ConfigParse::parseConfig(argc, argv, defaultConfigFilename, skipCount);
+
+   NameAddr _dialerIdentity(getConfigData("dialerIdentity", "sip:anonymous@localhost"));
+   mDialerIdentity = _dialerIdentity;
+   mAuthRealm = getConfigData("authRealm", "");
+   mAuthUser = getConfigData("authUser", "");
+   mAuthPassword = getConfigData("authPassword", "");
+   Uri _callerUserAgentAddress(getConfigData("callerUserAgentAddress", "sip:anonymous@localhost"));
+   mCallerUserAgentAddress = _callerUserAgentAddress;
+   mCallerUserAgentVariety = Generic;
+   mTargetPrefix = getConfigData("targetPrefix", "");
+   mTargetDomain = getConfigData("targetDomain", "localhost");
+   mCertPath = getConfigData("certPath", "");
+   mCADirectory = getConfigData("CADirectory", "");
+
    Data value(getConfigData("callerUserAgentVariety", "Generic"));
    if(value == "LinksysSPA941")
       setCallerUserAgentVariety(LinksysSPA941);
diff -Nru resiprocate-1.8.4/apps/sipdial/DialerConfiguration.hxx resiprocate-1.8.5/apps/sipdial/DialerConfiguration.hxx
--- resiprocate-1.8.4/apps/sipdial/DialerConfiguration.hxx	2012-07-05 15:09:56.000000000 +0000
+++ resiprocate-1.8.5/apps/sipdial/DialerConfiguration.hxx	2012-08-08 12:48:28.000000000 +0000
@@ -15,9 +15,10 @@
 
 public:
    DialerConfiguration();
-   DialerConfiguration(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount);
    virtual ~DialerConfiguration();
 
+   virtual void parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount = 0);
+
    void printHelpText(int argc, char **argv);
    using resip::ConfigParse::getConfigValue;
 
diff -Nru resiprocate-1.8.4/apps/sipdial/sipdialer.cpp resiprocate-1.8.5/apps/sipdial/sipdialer.cpp
--- resiprocate-1.8.4/apps/sipdial/sipdialer.cpp	2012-07-05 15:09:56.000000000 +0000
+++ resiprocate-1.8.5/apps/sipdial/sipdialer.cpp	2012-08-08 12:48:27.000000000 +0000
@@ -34,7 +34,8 @@
 int main(int argc, char *argv[]) 
 {
    Data defaultConfig(getFullFilename());
-   DialerConfiguration dc(argc, argv, defaultConfig, 1);
+   DialerConfiguration dc;
+   dc.parseConfig(argc, argv, defaultConfig, 1);
 
    Data targetUri(argv[1]);
    
diff -Nru resiprocate-1.8.4/b2bua/README.txt resiprocate-1.8.5/b2bua/README.txt
--- resiprocate-1.8.4/b2bua/README.txt	2012-07-05 15:10:45.000000000 +0000
+++ resiprocate-1.8.5/b2bua/README.txt	2012-08-08 12:49:17.000000000 +0000
@@ -11,14 +11,12 @@
 Building
 ========
 
-In the main reSIProcate directory:
+In the main reSIProcate directory, when you run configure, you
+must explicitly request that the library is built:
 
-./configure
-make b2bua
+./configure --with-b2bua
 
-NOTE:  the command `make' or `make all' will NOT build the B2BUA
-  by default.  I have left it out of the default build until
-  it has been tested more extensively by the reSIProcate community.
+NOTE:  configure does NOT include the B2BUA by default.
 
 Background and technical notes
 ==============================
@@ -33,7 +31,7 @@
 
 - It produces a shared object - to produce an executable, 
   the B2BUA class must be instantiated and put to work.
-  Such an example will be added shortly.  A typical
+  Such an example exists in the apps/basicB2BUA directory.  A typical
   implementation of a B2BUA must implement the following
   classes:
   - b2bua::CallRoute
@@ -42,16 +40,18 @@
   - b2bua::B2BUA
 
 - It relies on rtpproxy from http://www.rtpproxy.org to relay
-  the media streams.  I have created various patches for
+  the media streams.  There are also various patches for
   rtpproxy 0.2:
   - rtpproxy sends notification to the B2BUA on media timeout
   - fix a file descriptor bug
   - timeout on either direction
-  The rtpproxy patches are being posted on the rtpproxy mailing
-  list shortly.
+  The rtpproxy patches have been posted on the rtpproxy mailing
+  list:
+
+   http://lists.rtpproxy.org/pipermail/users/2008-May/000016.html
 
 Daniel Pocock
-daniel@readytechnology.co.uk
+daniel@pocock.com.au
 
 
 
diff -Nru resiprocate-1.8.4/configure resiprocate-1.8.5/configure
--- resiprocate-1.8.4/configure	2012-07-05 15:15:44.000000000 +0000
+++ resiprocate-1.8.5/configure	2012-08-08 12:51:16.000000000 +0000
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.67 for resiprocate 1.8.4.
+# Generated by GNU Autoconf 2.67 for resiprocate 1.8.5.
 #
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -698,8 +698,8 @@
 # Identity of this package.
 PACKAGE_NAME='resiprocate'
 PACKAGE_TARNAME='resiprocate'
-PACKAGE_VERSION='1.8.4'
-PACKAGE_STRING='resiprocate 1.8.4'
+PACKAGE_VERSION='1.8.5'
+PACKAGE_STRING='resiprocate 1.8.5'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1476,7 +1476,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures resiprocate 1.8.4 to adapt to many kinds of systems.
+\`configure' configures resiprocate 1.8.5 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1546,7 +1546,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of resiprocate 1.8.4:";;
+     short | recursive ) echo "Configuration of resiprocate 1.8.5:";;
    esac
   cat <<\_ACEOF
 
@@ -1665,7 +1665,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-resiprocate configure 1.8.4
+resiprocate configure 1.8.5
 generated by GNU Autoconf 2.67
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2208,7 +2208,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by resiprocate $as_me 1.8.4, which was
+It was created by resiprocate $as_me 1.8.5, which was
 generated by GNU Autoconf 2.67.  Invocation command line was
 
   $ $0 $@
@@ -3036,7 +3036,7 @@
 
 # Define the identity of the package.
  PACKAGE='resiprocate'
- VERSION='1.8.4'
+ VERSION='1.8.5'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -15702,7 +15702,7 @@
 
 
 
-ac_config_files="$ac_config_files Makefile rutil/dns/ares/Makefile rutil/Makefile rutil/test/Makefile resip/Makefile resip/stack/Makefile resip/stack/test/Makefile resip/dum/Makefile resip/dum/test/Makefile resip/certs/Makefile repro/Makefile repro/reprocmd/Makefile repro/test/Makefile b2bua/Makefile tfm/Makefile tfm/repro/Makefile tfm/tfdum/Makefile apps/Makefile apps/clicktocall/Makefile apps/clicktocall/test/Makefile apps/ichat-gw/Makefile apps/ichat-gw/jabberconnector/Makefile apps/sipdial/Makefile resip.spec reTurn/Makefile reTurn/test/Makefile reTurn/client/Makefile reTurn/client/test/Makefile reflow/Makefile resip/recon/Makefile resip/recon/MOHParkServer/Makefile resip/recon/test/Makefile presSvr/Makefile p2p/s2c/s2c/Makefile p2p/Makefile"
+ac_config_files="$ac_config_files Makefile rutil/dns/ares/Makefile rutil/Makefile rutil/test/Makefile resip/Makefile resip/stack/Makefile resip/stack/test/Makefile resip/dum/Makefile resip/dum/test/Makefile resip/certs/Makefile repro/Makefile repro/reprocmd/Makefile repro/test/Makefile b2bua/Makefile tfm/Makefile tfm/repro/Makefile tfm/tfdum/Makefile apps/Makefile apps/clicktocall/Makefile apps/clicktocall/test/Makefile apps/ichat-gw/Makefile apps/ichat-gw/jabberconnector/Makefile apps/sipdial/Makefile apps/basicB2BUA/Makefile resip.spec reTurn/Makefile reTurn/test/Makefile reTurn/client/Makefile reTurn/client/test/Makefile reflow/Makefile resip/recon/Makefile resip/recon/MOHParkServer/Makefile resip/recon/test/Makefile presSvr/Makefile p2p/s2c/s2c/Makefile p2p/Makefile"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -16342,7 +16342,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by resiprocate $as_me 1.8.4, which was
+This file was extended by resiprocate $as_me 1.8.5, which was
 generated by GNU Autoconf 2.67.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16408,7 +16408,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-resiprocate config.status 1.8.4
+resiprocate config.status 1.8.5
 configured by $0, generated by GNU Autoconf 2.67,
   with options \\"\$ac_cs_config\\"
 
@@ -16914,6 +16914,7 @@
     "apps/ichat-gw/Makefile") CONFIG_FILES="$CONFIG_FILES apps/ichat-gw/Makefile" ;;
     "apps/ichat-gw/jabberconnector/Makefile") CONFIG_FILES="$CONFIG_FILES apps/ichat-gw/jabberconnector/Makefile" ;;
     "apps/sipdial/Makefile") CONFIG_FILES="$CONFIG_FILES apps/sipdial/Makefile" ;;
+    "apps/basicB2BUA/Makefile") CONFIG_FILES="$CONFIG_FILES apps/basicB2BUA/Makefile" ;;
     "resip.spec") CONFIG_FILES="$CONFIG_FILES resip.spec" ;;
     "reTurn/Makefile") CONFIG_FILES="$CONFIG_FILES reTurn/Makefile" ;;
     "reTurn/test/Makefile") CONFIG_FILES="$CONFIG_FILES reTurn/test/Makefile" ;;
diff -Nru resiprocate-1.8.4/configure.ac resiprocate-1.8.5/configure.ac
--- resiprocate-1.8.4/configure.ac	2012-07-05 15:12:17.000000000 +0000
+++ resiprocate-1.8.5/configure.ac	2012-08-08 12:50:52.000000000 +0000
@@ -1,5 +1,5 @@
 
-AC_INIT(resiprocate,1.8.4)
+AC_INIT(resiprocate,1.8.5)
 AC_CONFIG_SRCDIR(repro/repro.cxx)
 
 SO_RELEASE=`echo $PACKAGE_VERSION | cut -f1,2 -d.`
@@ -270,6 +270,7 @@
 	apps/ichat-gw/Makefile \
 	apps/ichat-gw/jabberconnector/Makefile \
 	apps/sipdial/Makefile \
+	apps/basicB2BUA/Makefile \
 	resip.spec \
 	reTurn/Makefile \
 	reTurn/test/Makefile \
diff -Nru resiprocate-1.8.4/debian/changelog resiprocate-1.8.5/debian/changelog
--- resiprocate-1.8.4/debian/changelog	2012-07-13 22:32:24.000000000 +0000
+++ resiprocate-1.8.5/debian/changelog	2012-08-08 13:02:29.000000000 +0000
@@ -1,11 +1,15 @@
-resiprocate (1.8.4-1) unstable; urgency=low
+resiprocate (1.8.5-1) unstable; urgency=low
 
   * New upstream release
   * Make sure repro hashed passwords are not world readable
   * Remove /var/lib/repro on purge (Closes: #675273)
   * Delay in postrm in case process hasn't finished stopping
+  * Fix support for multiple ENUM carriers
+  * Fix issue with help text causing crash
+  * Fix clash between DIGEST and mutual TLS when used concurrently
+  * Proposed for wheezy unblock (Closes: #681387)
 
- -- Daniel Pocock <daniel@pocock.com.au>  Sat, 14 Jul 2012 00:30:10 +0200
+ -- Daniel Pocock <daniel@pocock.com.au>  Wed, 08 Aug 2012 15:02:03 +0200
 
 resiprocate (1.8.2-1) unstable; urgency=low
 
diff -Nru resiprocate-1.8.4/debian/conf/repro.config resiprocate-1.8.5/debian/conf/repro.config
--- resiprocate-1.8.4/debian/conf/repro.config	2012-05-04 13:49:51.000000000 +0000
+++ resiprocate-1.8.5/debian/conf/repro.config	2012-08-08 13:13:05.000000000 +0000
@@ -219,9 +219,30 @@
 # the host parameter determines the type of the connection.
 MySQLPort = 3306
 
+# The Users and MessageSilo database tables are different from the other repro configuration
+# database tables, in that they are accessed at runtime as SIP requests arrive.  It may be
+# desirable to use BerkeleyDb for the other repro tables (which are read at starup time, then
+# cached in memory), and MySQL for the runtime accessed tables; or two seperate MySQL instances
+# for these different table sets.  Use the following settings in order to specify a seperate
+# MySQL instance for use by the Users and MessageSilo tables.
+#
+# WARNING: repro must be compiled with the USE_MYSQL flag in order for this work.
+#
+# Note:  If this setting is left blank then repro will fallback all remaining my sql
+# settings to use the global MySQLServer settings.  If the MySQLServer setting is also
+# blank, then repro will use BerkelyDB for all configuration tables.  See the
+# documentation on the global MySQLServer settings for more details on the following
+# individual settings.
+RuntimeMySQLServer =
+RuntimeMySQLUser = root
+RuntimeMySQLPassword = root
+RuntimeMySQLDatabaseName = repro
+RuntimeMySQLPort = 3306
+
 # If you would like to be able to authenticate uses from a MySQL source other than the repro user
 # database table itself, then specify the query here.  The following conditions apply:
-# 1.  The database table must reside on the same MySQL server instance as the repro database.
+# 1.  The database table must reside on the same MySQL server instance as the repro database
+#     or Runtime tables database.
 # 2.  The statement provided will be UNION'd with the hardcoded repro query, so that auth from
 #     both sources is possible.  Note:  If the same user exists in both tables, then the repro
 #     auth info will be used.
@@ -282,10 +303,20 @@
 # (ie. RequestFilter)
 NumAsyncProcessorWorkerThreads = 2
 
-# Specify domains for which this proxy is authorative (in addition to those specified on web 
+# Specify domains for which this proxy is authorative (in addition to those specified on web
 # interface) - comma separate list
-# Note:  Domains specified here cannot be used when creating users, domains used in user
-#        AORs must be specified on the web interface.
+# Notes: * Domains specified here cannot be used when creating users, domains used in user
+#          AORs must be specified on the web interface.
+#        * In previous versions of repro, localhost, 127.0.0.1, the machine's hostname,
+#          and all interface addresses would automatically be appended to this
+#          configuration parameter.  From now on, such values must be listed
+#          here explicitly if required, e.g.
+#
+#             Domains = localhost, 127.0.0.1, sip-server.example.org, 10.83.73.80
+#
+#          although when using TLS only, it is not desirable or necessary to
+#          add such values.
+#
 Domains =
 
 # Uri to use as Record-Route
@@ -306,6 +337,13 @@
 # Specify a comma separate list of enum suffixes to search for enum dns resolution
 EnumSuffixes =
 
+# Specify the target domain(s) for ENUM logic support.  When a dialed SIP URI
+# is addressed to +number@somedomain,
+# where somedomain is an element of EnumDomains,
+# the ENUM logic will be applied for the number
+# If empty, ENUM is never used
+EnumDomains =
+
 # Specify length of timer C in sec (0 or negative will disable timer C) - default 180
 TimerC = 180
 
@@ -324,6 +362,19 @@
 # (ie. 5, 8, etc.)
 OutboundVersion = 5626
 
+# There are cases where the first hop in a particular network supports the concept of outbound
+# and ensures all messaging for a client is delivered over the same connection used for
+# registration.  This could be a SBC or other NAT traversal aid router that uses the Path
+# header.  However such endpoints may not be 100% compliant with outbound RFC and may not
+# include a ;ob parameter in the path header.  This parameter is required in order for repro
+# to have knowledge that the first hop does support outbound, and it will reject registrations
+# that appear to be using outboud (ie. instanceId and regId) with a 439 (First Hop Lacks Outbound
+# Support).  In this case it can be desirable when using repro as the registrar to not reject
+# REGISTRATION requests that contain an instanceId and regId with a 439.
+# If this setting is enabled, then repro will assume the first hop supports outbound
+# and not return this error.
+AssumeFirstHopSupportsOutbound = false
+
 # Enable use of flow-tokens in non-outbound cases
 # WARNING: Before enabling this, ensure you have a RecordRouteUri setup, or are using
 # the alternate transport specification mechanism and defining a RecordRouteUri per
@@ -365,6 +416,28 @@
 # (whole domain) is for federated SIP proxy-to-proxy communication (RFC 5922)
 EnableCertificateAuthenticator = false
 
+# A static text file that contains mappings of X.509 Common Names to
+# permitted SIP `From:' addresses
+#
+# Without this file, the default behavior of the CertificateAuthenticator
+# ensures that the `From:' address in SIP messages must match the
+# Common Name or one of the subjectAltNames from the X.509 certificate
+#
+# When this file is supplied, the CertificateAuthenticator will continue
+# to allow SIP messages where there is an exact match between the
+# certificate and the `From:' address, but it will also allow
+# the holder of a particular certificate to use any of the `mapped'
+# `From:' addresses specified in the mappings file
+#
+# File format:
+# common name<TAB><mapping>,<mapping>,...
+#
+#    where:
+#        <TAB> is exactly one tab
+#        <mapping> is `user@domain' or just `domain'
+#
+CommonNameMappings = /etc/repro/tlsUserMappings.txt
+
 
 ########################################################
 # DigestAuthenticator Monkey Settings
@@ -416,16 +489,12 @@
 
 # The hostname running MySQL server to connect to for any blocked entries
 # that are configured to used a SQL statement.
-# The value of host may be either a host name or an IP address. If host is "localhost",
-# a connection to the local host is assumed. For Windows, the client connects using a
-# shared-memory connection, if the server has shared-memory connections enabled. Otherwise,
-# TCP/IP is used. For Unix, the client connects using a Unix socket file. For a host value of
-# "." on Windows, the client connects using a named pipe, if the server has named-pipe
-# connections enabled. If named-pipe connections are not enabled, an error occurs.
 # WARNING: repro must be compiled with the USE_MYSQL flag in order for this work.
 #
 # Note:  If this setting is left blank then repro will fallback all remaining my sql
-# settings to use the global MySQLServer settings.
+# settings to use the global RuntimeMySQLServer or MySQLServer settings.  See the
+# documentation on the global MySQLServer settings for more details on the following
+# individual settings.
 RequestFilterMySQLServer =
 
 # The MySQL login ID to use when connecting to the MySQL Server. 
diff -Nru resiprocate-1.8.4/debian/control resiprocate-1.8.5/debian/control
--- resiprocate-1.8.4/debian/control	2012-05-22 17:47:12.000000000 +0000
+++ resiprocate-1.8.5/debian/control	2012-08-04 14:50:52.000000000 +0000
@@ -3,7 +3,7 @@
 Priority: extra
 Maintainer: Debian VoIP Team <pkg-voip-maintainers@lists.alioth.debian.org>
 Uploaders: Daniel Pocock <daniel@pocock.com.au>
-Build-Depends: debhelper (>= 9.0.0), gperf, libasio-dev (>= 1.2.0), libboost-dev, libc-ares-dev (>= 1.6.0), libdb++-dev, libpopt-dev, libssl-dev (>= 0.9.8), perl, libmysqlclient-dev, libradiusclient-ng-dev, libcppunit-dev, autotools-dev, libpcre3-dev, dpkg-dev (>= 1.16.1~)
+Build-Depends: debhelper (>= 9.0.0), gperf, libasio-dev (>= 1.2.0), libboost-dev, libc-ares-dev (>= 1.6.0), libdb++-dev, libpopt-dev, libssl-dev (>= 0.9.8), perl, libmysqlclient-dev, libradiusclient-ng-dev, libcppunit-dev, autotools-dev, libpcre3-dev, dpkg-dev (>= 1.16.1~), libxerces-c-dev
 Homepage: http://www.resiprocate.org/
 Standards-Version: 3.9.3
 DM-Upload-Allowed: yes
diff -Nru resiprocate-1.8.4/debian/repro.init resiprocate-1.8.5/debian/repro.init
--- resiprocate-1.8.4/debian/repro.init	2012-05-20 16:47:47.000000000 +0000
+++ resiprocate-1.8.5/debian/repro.init	2012-08-06 18:47:42.000000000 +0000
@@ -19,6 +19,8 @@
 #PIDFILE="/var/run/${NAME}.pid"
 PIDFILE_DIR=`dirname $PIDFILE`
 
+KILL_SPEC=TERM/20/KILL/5
+
 test -x $DAEMON || exit 1
 umask 002
 
@@ -44,7 +46,7 @@
 	;;
   stop)
 	echo -n "Stopping $DESC: "
-	start-stop-daemon --stop --quiet --oknodo --user $USER --pidfile $PIDFILE --exec $DAEMON
+	start-stop-daemon --stop --quiet --oknodo --user $USER --pidfile $PIDFILE --retry=${KILL_SPEC} --exec $DAEMON
 	echo "$NAME."
 	;;
   status)
@@ -65,7 +67,6 @@
 	echo -n "Restarting $DESC: "
 	#start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON
 	$0 stop
-	sleep 10
 	#start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS
 	$0 start
 	echo "$NAME."
diff -Nru resiprocate-1.8.4/debian/repro.postrm resiprocate-1.8.5/debian/repro.postrm
--- resiprocate-1.8.4/debian/repro.postrm	2012-05-28 13:52:39.000000000 +0000
+++ resiprocate-1.8.5/debian/repro.postrm	2012-08-06 19:01:56.000000000 +0000
@@ -4,10 +4,6 @@
 
 if [ "$1" = "purge" ] ; then
 
-        # wait in case process still shutting down...
-        echo "Waiting for process to stop..."
-        sleep 8
-
         # MySQL uses debconf to get user confirmation before
         # wiping it's lib database directory, a similar
         # approach might be desirable for repro
diff -Nru resiprocate-1.8.4/repro/monkeys/CertificateAuthenticator.cxx resiprocate-1.8.5/repro/monkeys/CertificateAuthenticator.cxx
--- resiprocate-1.8.4/repro/monkeys/CertificateAuthenticator.cxx	2012-07-05 15:09:42.000000000 +0000
+++ resiprocate-1.8.5/repro/monkeys/CertificateAuthenticator.cxx	2012-08-08 12:48:15.000000000 +0000
@@ -27,6 +27,8 @@
 using namespace repro;
 using namespace std;
 
+KeyValueStore::Key CertificateAuthenticator::mCertificateVerifiedKey = Proxy::allocateRequestKeyValueStoreKey();
+
 CertificateAuthenticator::CertificateAuthenticator(ProxyConfig& config,
                                                    resip::SipStack* stack,
                                                    std::set<Data>& trustedPeers,
@@ -37,6 +39,18 @@
 {
 }
 
+CertificateAuthenticator::CertificateAuthenticator(ProxyConfig& config,
+                                                   resip::SipStack* stack,
+                                                   std::set<Data>& trustedPeers,
+                                                   bool thirdPartyRequiresCertificate,
+                                                   CommonNameMappings& commonNameMappings) :
+   Processor("CertificateAuthenticator"),
+   mTrustedPeers(trustedPeers),
+   mThirdPartyRequiresCertificate(thirdPartyRequiresCertificate),
+   mCommonNameMappings(commonNameMappings)
+{
+}
+
 CertificateAuthenticator::~CertificateAuthenticator()
 {
 }
@@ -86,8 +100,15 @@
       {
          if (!rc.getKeyValueStore().getBoolValue(IsTrustedNode::mFromTrustedNodeKey))
          {
+            // peerNames is empty if client certificate mode is `optional'
+            // or if the message didn't come in on TLS transport
+            if(peerNames.empty())
+               return Continue;
             if(authorizedForThisIdentity(peerNames, sipMessage->header(h_From).uri()))
+            {
+               rc.getKeyValueStore().setBoolValue(CertificateAuthenticator::mCertificateVerifiedKey, true);
                return Continue;
+            }
             rc.sendResponse(*auto_ptr<SipMessage>
                             (Helper::makeResponse(*sipMessage, 403, "Authentication Failed for peer cert")));
             return SkipAllChains;
@@ -97,14 +118,24 @@
       }
       else
       {
-         if(mThirdPartyRequiresCertificate && peerNames.size() == 0)
+         // peerNames is empty if client certificate mode is `optional'
+         // or if the message didn't come in on TLS transport
+         if(peerNames.empty())
          {
-            rc.sendResponse(*auto_ptr<SipMessage>
+            if(mThirdPartyRequiresCertificate)
+            {
+               rc.sendResponse(*auto_ptr<SipMessage>
                             (Helper::makeResponse(*sipMessage, 403, "Mutual TLS required to handle that message")));
-            return SkipAllChains;
+               return SkipAllChains;
+            }
+            else
+               return Continue;
          }
          if(authorizedForThisIdentity(peerNames, sipMessage->header(h_From).uri()))
+         {
+            rc.getKeyValueStore().setBoolValue(CertificateAuthenticator::mCertificateVerifiedKey, true);
             return Continue;
+         }
          rc.sendResponse(*auto_ptr<SipMessage>
                             (Helper::makeResponse(*sipMessage, 403, "Authentication Failed for peer cert")));
          return SkipAllChains;
@@ -140,6 +171,23 @@
          DebugLog(<< "Matched certificate name " << i << " against domain " << domain);
          return true;
       }
+      CommonNameMappings::iterator _mapping =
+         mCommonNameMappings.find(i);
+      if(_mapping != mCommonNameMappings.end())
+      {
+         DebugLog(<< "CN mapping(s) exist for the certificate " << i);
+         PermittedFromAddresses& permitted = _mapping->second;
+         if(permitted.find(aor) != permitted.end())
+         {
+            DebugLog(<< "Matched certificate name " << i << " against full AoR " << aor << " by common name mappings");
+            return true;
+         }
+         if(permitted.find(domain) != permitted.end())
+         {
+            DebugLog(<< "Matched certificate name " << i << " against domain " << domain << " by common name mappings");
+            return true;
+         }
+      }
       DebugLog(<< "Certificate name " << i << " doesn't match AoR " << aor << " or domain " << domain);
    }
 
diff -Nru resiprocate-1.8.4/repro/monkeys/CertificateAuthenticator.hxx resiprocate-1.8.5/repro/monkeys/CertificateAuthenticator.hxx
--- resiprocate-1.8.4/repro/monkeys/CertificateAuthenticator.hxx	2012-07-05 15:09:42.000000000 +0000
+++ resiprocate-1.8.5/repro/monkeys/CertificateAuthenticator.hxx	2012-08-08 12:48:15.000000000 +0000
@@ -4,6 +4,8 @@
 #include <set>
 
 #include "rutil/Data.hxx"
+#include "resip/dum/TlsPeerAuthManager.hxx"
+#include "rutil/KeyValueStore.hxx"
 #include "repro/Processor.hxx"
 #include "repro/Dispatcher.hxx"
 #include "repro/ProxyConfig.hxx"
@@ -18,7 +20,10 @@
   class CertificateAuthenticator : public Processor
   {
     public:
+      static resip::KeyValueStore::Key mCertificateVerifiedKey;
+
       CertificateAuthenticator(ProxyConfig& config, resip::SipStack* stack, std::set<resip::Data>& trustedPeers, bool thirdPartyRequiresCertificate = true);
+      CertificateAuthenticator(ProxyConfig& config, resip::SipStack* stack, std::set<resip::Data>& trustedPeers, bool thirdPartyRequiresCertificate, resip::CommonNameMappings& commonNameMappings);
       ~CertificateAuthenticator();
 
       virtual processor_action_t process(RequestContext &);
@@ -29,6 +34,7 @@
 
       std::set<resip::Data> mTrustedPeers;
       bool mThirdPartyRequiresCertificate;
+      resip::CommonNameMappings mCommonNameMappings;
   };
   
 }
diff -Nru resiprocate-1.8.4/repro/monkeys/StaticRoute.cxx resiprocate-1.8.5/repro/monkeys/StaticRoute.cxx
--- resiprocate-1.8.4/repro/monkeys/StaticRoute.cxx	2012-07-05 15:09:42.000000000 +0000
+++ resiprocate-1.8.5/repro/monkeys/StaticRoute.cxx	2012-08-08 12:48:15.000000000 +0000
@@ -4,6 +4,7 @@
 
 #include "resip/stack/SipMessage.hxx"
 #include "resip/stack/Helper.hxx"
+#include "repro/monkeys/CertificateAuthenticator.hxx"
 #include "repro/monkeys/StaticRoute.hxx"
 #include "repro/monkeys/IsTrustedNode.hxx"
 #include "repro/RequestContext.hxx"
@@ -65,7 +66,8 @@
       //}
    }
 
-   if (requireAuth && context.getDigestIdentity().empty())
+   if (requireAuth && context.getDigestIdentity().empty() &&
+      !context.getKeyValueStore().getBoolValue(CertificateAuthenticator::mCertificateVerifiedKey))
    {
       // !rwm! TODO do we need anything more sophisticated to figure out the realm?
       Data realm = msg.header(h_RequestLine).uri().host();
diff -Nru resiprocate-1.8.4/repro/ProxyConfig.cxx resiprocate-1.8.5/repro/ProxyConfig.cxx
--- resiprocate-1.8.4/repro/ProxyConfig.cxx	2012-07-05 15:09:45.000000000 +0000
+++ resiprocate-1.8.5/repro/ProxyConfig.cxx	2012-08-08 12:48:20.000000000 +0000
@@ -19,10 +19,6 @@
 namespace repro 
 {
 
-ProxyConfig::ProxyConfig(int argc, char** argv, const resip::Data& defaultConfigFilename) : ConfigParse(argc, argv, defaultConfigFilename), mStore(0)
-{
-}
-
 ProxyConfig::ProxyConfig() : mStore(0)
 {
 }
@@ -89,10 +85,10 @@
 ProxyConfig::printHelpText(int argc, char **argv)
 {
    cout << "Command line format is:" << endl;
-   cout << "  " << argv[0] << " [<ConfigFilename>] [--<ConfigValueName>=<ConfigValue>] [--<ConfigValueName>=<ConfigValue>] ..." << endl;
+   cout << "  " << removePath(argv[0]) << " [<ConfigFilename>] [--<ConfigValueName>=<ConfigValue>] [--<ConfigValueName>=<ConfigValue>] ..." << endl;
    cout << "Sample Command lines:" << endl;
-   cout << "  " << argv[0] << "repro.config --RecordRouteUri=sip:proxy.sipdomain.com --ForceRecordRouting=true" << endl;
-   cout << "  " << argv[0] << "repro.config /RecordRouteUri:sip:proxy.sipdomain.com /ForceRecordRouting:true" << endl;
+   cout << "  " << removePath(argv[0]) << " repro.config --RecordRouteUri=sip:proxy.sipdomain.com --ForceRecordRouting=true" << endl;
+   cout << "  " << removePath(argv[0]) << " repro.config /RecordRouteUri:sip:proxy.sipdomain.com /ForceRecordRouting:true" << endl;
 }
 
 void 
diff -Nru resiprocate-1.8.4/repro/ProxyConfig.hxx resiprocate-1.8.5/repro/ProxyConfig.hxx
--- resiprocate-1.8.4/repro/ProxyConfig.hxx	2012-07-05 15:09:45.000000000 +0000
+++ resiprocate-1.8.5/repro/ProxyConfig.hxx	2012-08-08 12:48:20.000000000 +0000
@@ -14,7 +14,6 @@
 {
 public:
    ProxyConfig();
-   ProxyConfig(int argc, char** argv, const resip::Data& defaultConfigFilename);
    virtual ~ProxyConfig();
 
    virtual void printHelpText(int argc, char **argv);
diff -Nru resiprocate-1.8.4/repro/Proxy.cxx resiprocate-1.8.5/repro/Proxy.cxx
--- resiprocate-1.8.4/repro/Proxy.cxx	2012-07-05 15:09:45.000000000 +0000
+++ resiprocate-1.8.5/repro/Proxy.cxx	2012-08-08 12:48:20.000000000 +0000
@@ -362,7 +362,7 @@
                         InfoLog (<< "Inserting new RequestContext tid=" << tid
                                   << " -> " << *context);
                         mServerRequestContexts[tid] = context;
-                        DebugLog (<< "RequestContexts: " << InserterP(mServerRequestContexts));
+                        //DebugLog (<< "RequestContexts: " << InserterP(mServerRequestContexts));  For a busy proxy - this generates a HUGE log statement!
                         try
                         {
                            context->process(std::auto_ptr<resip::SipMessage>(sip));
diff -Nru resiprocate-1.8.4/repro/repro.config resiprocate-1.8.5/repro/repro.config
--- resiprocate-1.8.4/repro/repro.config	2012-07-05 15:09:45.000000000 +0000
+++ resiprocate-1.8.5/repro/repro.config	2012-08-08 12:48:20.000000000 +0000
@@ -40,7 +40,7 @@
 TCPPort = 5060
 
 # Local port to listen on for SIP messages over TLS - 0 to disable
-TLSPort = 5061
+TLSPort = 0
 
 # Local port to listen on for SIP messages over DTLS - 0 to disable
 DTLSPort = 0
@@ -304,8 +304,18 @@
 
 # Specify domains for which this proxy is authorative (in addition to those specified on web 
 # interface) - comma separate list
-# Note:  Domains specified here cannot be used when creating users, domains used in user
-#        AORs must be specified on the web interface.
+# Notes: * Domains specified here cannot be used when creating users, domains used in user
+#          AORs must be specified on the web interface.
+#        * In previous versions of repro, localhost, 127.0.0.1, the machine's hostname,
+#          and all interface addresses would automatically be appended to this
+#          configuration parameter.  From now on, such values must be listed
+#          here explicitly if required, e.g.
+#
+#             Domains = localhost, 127.0.0.1, sip-server.example.org, 10.83.73.80
+#
+#          although when using TLS only, it is not desirable or necessary to
+#          add such values.
+#
 Domains =
 
 # Uri to use as Record-Route
@@ -326,6 +336,13 @@
 # Specify a comma separate list of enum suffixes to search for enum dns resolution
 EnumSuffixes =
 
+# Specify the target domain(s) for ENUM logic support.  When a dialed SIP URI
+# is addressed to +number@somedomain,
+# where somedomain is an element of EnumDomains,
+# the ENUM logic will be applied for the number
+# If empty, ENUM is never used
+EnumDomains = 
+
 # Specify length of timer C in sec (0 or negative will disable timer C) - default 180
 TimerC = 180
 
@@ -398,6 +415,28 @@
 # (whole domain) is for federated SIP proxy-to-proxy communication (RFC 5922)
 EnableCertificateAuthenticator = false
 
+# A static text file that contains mappings of X.509 Common Names to
+# permitted SIP `From:' addresses
+#
+# Without this file, the default behavior of the CertificateAuthenticator
+# ensures that the `From:' address in SIP messages must match the 
+# Common Name or one of the subjectAltNames from the X.509 certificate
+#
+# When this file is supplied, the CertificateAuthenticator will continue
+# to allow SIP messages where there is an exact match between the
+# certificate and the `From:' address, but it will also allow
+# the holder of a particular certificate to use any of the `mapped'
+# `From:' addresses specified in the mappings file
+#
+# File format:
+# common name<TAB><mapping>,<mapping>,...
+#
+#    where:
+#        <TAB> is exactly one tab
+#        <mapping> is `user@domain' or just `domain'
+#
+CommonNameMappings = /etc/repro/tlsUserMappings.txt
+
 
 ########################################################
 # DigestAuthenticator Monkey Settings
diff -Nru resiprocate-1.8.4/repro/ReproRunner.cxx resiprocate-1.8.5/repro/ReproRunner.cxx
--- resiprocate-1.8.4/repro/ReproRunner.cxx	2012-07-05 15:09:45.000000000 +0000
+++ resiprocate-1.8.5/repro/ReproRunner.cxx	2012-08-08 12:48:20.000000000 +0000
@@ -2,6 +2,10 @@
 #include "config.h"
 #endif
 
+#include <iostream>
+#include <fstream>
+#include <stdexcept>
+
 #include "rutil/Log.hxx"
 #include "rutil/Logger.hxx"
 #include "rutil/DnsUtil.hxx"
@@ -155,7 +159,8 @@
    Data defaultConfigFilename("repro.config");
    try
    {
-      mProxyConfig = new ProxyConfig(mArgc, mArgv, defaultConfigFilename);
+      mProxyConfig = new ProxyConfig();
+      mProxyConfig->parseConfig(mArgc, mArgv, defaultConfigFilename);
    }
    catch(BaseException& ex)
    {
@@ -478,6 +483,19 @@
       mSipStack->setEnumSuffixes(enumSuffixes);
    }
 
+   // Set any enum domains from configuration
+   std::map<Data,Data> enumDomains;
+   std::vector<Data> _enumDomains;
+   mProxyConfig->getConfigValue("EnumDomains", _enumDomains);
+   if (enumSuffixes.size() > 0)
+   {
+      for(std::vector<Data>::iterator it = _enumDomains.begin(); it != _enumDomains.end(); it++)
+      {
+         enumDomains[*it] = *it;
+      }
+      mSipStack->setEnumDomains(enumDomains);
+   }
+
    // Add stack transports
    bool allTransportsSpecifyRecordRoute=false;
    if(!addTransports(allTransportsSpecifyRecordRoute))
@@ -719,13 +737,18 @@
 
    if (mDum)
    {
-      if(mProxyConfig->getConfigBool("EnableCertificateAuthenticator", false))
+      bool enableCertAuth = mProxyConfig->getConfigBool("EnableCertificateAuthenticator", false);
+      // Maintains existing behavior for non-TLS cert auth users
+      bool digestChallengeThirdParties = !enableCertAuth;
+
+      if(enableCertAuth)
       {
          // TODO: perhaps this should be initialised from the trusted node
          // monkey?  Or should the list of trusted TLS peers be independent
          // from the trusted node list?
          std::set<Data> trustedPeers;
-         SharedPtr<TlsPeerAuthManager> certAuth(new TlsPeerAuthManager(*mDum, mDum->dumIncomingTarget(), trustedPeers));
+         loadCommonNameMappings();
+         SharedPtr<TlsPeerAuthManager> certAuth(new TlsPeerAuthManager(*mDum, mDum->dumIncomingTarget(), trustedPeers, true, mCommonNameMappings));
          mDum->addIncomingFeature(certAuth);
       }
 
@@ -746,7 +769,8 @@
                                                 mAuthRequestDispatcher,
                                                 mProxyConfig->getDataStore()->mAclStore,
                                                 !mProxyConfig->getConfigBool("DisableAuthInt", false) /*useAuthInt*/,
-                                                mProxyConfig->getConfigBool("RejectBadNonces", false)));
+                                                mProxyConfig->getConfigBool("RejectBadNonces", false),
+                                                digestChallengeThirdParties));
          mDum->setServerAuthManager(uasAuth);
       }
 
@@ -957,6 +981,9 @@
       }
    }
 
+   /* All of this logic has been commented out - the sysadmin must explicitly
+      add any of the items below to the Domains config option in repro.config
+
    Data localhostname(DnsUtil::getLocalHostName());
    if(log) InfoLog (<< "Adding local hostname domain " << localhostname );
    tu.addDomain(localhostname);
@@ -980,7 +1007,10 @@
    }
 
    if(log) InfoLog (<< "Adding 127.0.0.1 domain.");
-   tu.addDomain("127.0.0.1");
+   tu.addDomain("127.0.0.1"); */
+
+   if( realm.empty() )
+      realm = "Unconfigured";
 
    return realm;
 }
@@ -1202,6 +1232,66 @@
    chain.addProcessor(processor);
 }
 
+void
+ReproRunner::loadCommonNameMappings()
+{
+   // Already loaded?
+   if(!mCommonNameMappings.empty())
+      return;
+
+   Data mappingsFileName = mProxyConfig->getConfigData("CommonNameMappings", "");
+   if(mappingsFileName.empty())
+      return;
+
+   InfoLog(<< "trying to load common name mappings from file: " << mappingsFileName);
+
+   ifstream mappingsFile(mappingsFileName.c_str());
+   if(!mappingsFile)
+   {
+      throw std::runtime_error("Error opening/reading mappings file");
+   }
+
+   string sline;
+   while(getline(mappingsFile, sline))
+   {
+      Data line(sline);
+      Data cn;
+      PermittedFromAddresses permitted;
+      ParseBuffer pb(line);
+
+      pb.skipWhitespace();
+      const char * anchor = pb.position();
+      if(pb.eof() || *anchor == '#') continue;  // if line is a comment or blank then skip it
+
+      // Look for end of name
+      pb.skipToOneOf("\t");
+      pb.data(cn, anchor);
+      pb.skipChar('\t');
+
+      while(!pb.eof())
+      {
+         pb.skipWhitespace();
+         if(pb.eof())
+            continue;
+
+         Data value;
+         anchor = pb.position();
+         pb.skipToOneOf(",\r\n ");
+         pb.data(value, anchor);
+         if(!value.empty())
+         {
+            StackLog(<< "Loading CN '" << cn << "', found mapping '" << value << "'");
+            permitted.insert(value);
+         }
+         if(!pb.eof())
+            pb.skipChar();
+      }
+
+      DebugLog(<< "Loaded mapping for CN '" << cn << "', " << permitted.size() << " mapping(s)");
+      mCommonNameMappings[cn] = permitted;
+   }
+}
+
 void  // Monkeys
 ReproRunner::makeRequestProcessorChain(ProcessorChain& chain)
 {
@@ -1223,7 +1313,8 @@
       // Should we used the same trustedPeers object that was
       // passed to TlsPeerAuthManager perhaps?
       std::set<Data> trustedPeers;
-      addProcessor(chain, std::auto_ptr<Processor>(new CertificateAuthenticator(*mProxyConfig, mSipStack, trustedPeers)));
+      loadCommonNameMappings();
+      addProcessor(chain, std::auto_ptr<Processor>(new CertificateAuthenticator(*mProxyConfig, mSipStack, trustedPeers, true, mCommonNameMappings)));
    }
 
    // Add digest authenticator monkey - if required
diff -Nru resiprocate-1.8.4/repro/ReproRunner.hxx resiprocate-1.8.5/repro/ReproRunner.hxx
--- resiprocate-1.8.4/repro/ReproRunner.hxx	2012-07-05 15:09:45.000000000 +0000
+++ resiprocate-1.8.5/repro/ReproRunner.hxx	2012-08-08 12:48:19.000000000 +0000
@@ -3,6 +3,7 @@
 
 #include "rutil/Data.hxx"
 #include "rutil/ServerProcess.hxx"
+#include "resip/dum/TlsPeerAuthManager.hxx"
 #include <memory>
 
 namespace resip
@@ -68,6 +69,8 @@
    virtual void makeResponseProcessorChain(repro::ProcessorChain& chain);
    virtual void makeTargetProcessorChain(repro::ProcessorChain& chain);
 
+   virtual void loadCommonNameMappings();
+
    bool mRunning;
    bool mRestarting;
    int mArgc;
@@ -106,6 +109,7 @@
    CommandServer* mCommandServerV6;
    CommandServerThread* mCommandServerThread;
    resip::CongestionManager* mCongestionManager;
+   resip::CommonNameMappings mCommonNameMappings;
 };
 
 }
diff -Nru resiprocate-1.8.4/repro/ReproServerAuthManager.cxx resiprocate-1.8.5/repro/ReproServerAuthManager.cxx
--- resiprocate-1.8.4/repro/ReproServerAuthManager.cxx	2012-07-05 15:09:45.000000000 +0000
+++ resiprocate-1.8.5/repro/ReproServerAuthManager.cxx	2012-08-08 12:48:20.000000000 +0000
@@ -17,8 +17,9 @@
                                                Dispatcher* authRequestDispatcher,
                                                AclStore& aclDb,
                                                bool useAuthInt,
-                                               bool rejectBadNonces):
-   ServerAuthManager(dum, dum.dumIncomingTarget()),
+                                               bool rejectBadNonces,
+                                               bool challengeThirdParties):
+   ServerAuthManager(dum, dum.dumIncomingTarget(), challengeThirdParties),
    mDum(dum),
    mAuthRequestDispatcher(authRequestDispatcher),
    mAclDb(aclDb),
@@ -49,7 +50,7 @@
    assert(msg.isRequest());
    if(!mAclDb.isRequestTrusted(msg))
    {
-      return True;
+      return ServerAuthManager::requiresChallenge(msg);
    }
    else
    {
diff -Nru resiprocate-1.8.4/repro/ReproServerAuthManager.hxx resiprocate-1.8.5/repro/ReproServerAuthManager.hxx
--- resiprocate-1.8.4/repro/ReproServerAuthManager.hxx	2012-07-05 15:09:45.000000000 +0000
+++ resiprocate-1.8.5/repro/ReproServerAuthManager.hxx	2012-08-08 12:48:19.000000000 +0000
@@ -26,7 +26,8 @@
                              Dispatcher* authRequestDispatcher,
                              AclStore& aclDb,
                              bool useAuthInt,
-                             bool rejectBadNonces);
+                             bool rejectBadNonces,
+                             bool challengeThirdParties);
       
       ~ReproServerAuthManager();
       
diff -Nru resiprocate-1.8.4/repro/WebAdmin.cxx resiprocate-1.8.5/repro/WebAdmin.cxx
--- resiprocate-1.8.4/repro/WebAdmin.cxx	2012-07-05 15:09:45.000000000 +0000
+++ resiprocate-1.8.5/repro/WebAdmin.cxx	2012-08-08 12:48:19.000000000 +0000
@@ -1876,11 +1876,11 @@
             localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
             localAddr.sin_port = 0;
 
-            rc = bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr));
+            rc = ::bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr));
             if(rc >= 0) 
             {
                // Connect to server
-               rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr));
+               rc = ::connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr));
                if(rc >= 0) 
                {
                   Data request("<Restart>\r\n  <Request>\r\b  </Request>\r\n</Restart>\r\n");
diff -Nru resiprocate-1.8.4/repro/WinSetup/readme.txt resiprocate-1.8.5/repro/WinSetup/readme.txt
--- resiprocate-1.8.4/repro/WinSetup/readme.txt	2012-07-05 15:09:44.000000000 +0000
+++ resiprocate-1.8.5/repro/WinSetup/readme.txt	2012-08-08 12:48:18.000000000 +0000
@@ -1,5 +1,3 @@
-Repro Version:  Capuchin 0.2 - Feb, 2006
-
 Main Web Site:
 http://www.sipfoundry.org/repro/
 
@@ -7,92 +5,13 @@
 http://wiki.resiprocate.org/wiki/index.php?title=Main_Page#Repro_SIP_Proxy_Server or
 http://wiki.resiprocate.org/
 
-repro --help
-Usage: SSL-Debug\repro [OPTION...]
-  -l, --log-type=syslog|cerr|cout                       where to send logging
-                                                        messages (default:
-                                                        "cout")
-  -v, --log-level=STACK|DEBUG|INFO|WARNING|ALERT        specify the default
-                                                        log level (default:
-                                                        "INFO")
-  -r, --record-route=sip:example.com                    specify uri to use as
-                                                        Record-Route
-  --udp=5060                                            listen on UDP port
-                                                        (default: 5060)
-  --tcp=5060                                            listen on TCP port
-                                                        (default: 5060)
-  -t, --tls-domain=example.com                          act as a TLS server
-                                                        for specified domain
-  --tls=5061                                            add TLS transport on
-                                                        specified port
-                                                        (default: 5061)
-  --dtls=0                                              add DTLS transport on
-                                                        specified port
-                                                        (default: 0)
-  --enable-cert-server                                  run a cert server
-  -c, --cert-path=STRING                                path for certificates
-                                                        (default: c:\sipCerts)
-                                                        (default:
-                                                        "C:\sipCerts")
-  --enable-v6                                           enable IPV6
-  --disable-v4                                          disable IPV4
-  --disable-auth                                        disable DIGEST
-                                                        challenges
-  --disable-web-auth                                    disable HTTP challenges
-  --disable-reg                                         disable registrar
-  -i, --interfaces=sip:10.1.1.1:5065;transport=tls      specify interfaces to
-                                                        add transports to
-  -d, --domains=example.com,foo.com                     specify domains that
-                                                        this proxy is
-                                                        authorative
-  -R, --route=sip:p1.example.com,sip:p2.example.com     specify where to route
-                                                        requests that are in
-                                                        this proxy's domain
-  --reqChainName=STRING                                 name of request chain
-                                                        (default: default)
-  --http=5080                                           run HTTP server on
-                                                        specified port
-                                                        (default: 5080)
-  --recursive-redirect                                  Handle 3xx responses
-                                                        in the proxy
-  --q-value                                             Enable sequential
-                                                        q-value processing
-  --q-value-behavior=STRING                             Specify forking
-                                                        behavior for q-value
-                                                        targets:
-                                                        FULL_SEQUENTIAL,
-                                                        EQUAL_Q_PARALLEL, or
-                                                        FULL_PARALLEL
-  --q-value-cancel-btw-fork-groups                      Whether to cancel
-                                                        groups of parallel
-                                                        forks after the period
-                                                        specified by the
-                                                        --q-value-ms-before-cancel 
-                                                        parameter.
-  --q-value-wait-for-terminate-btw-fork-groups          Whether to wait for
-                                                        parallel fork groups
-                                                        to terminate before
-                                                        starting new
-                                                        fork-groups.
-  --q-value-ms-between-fork-groups=INT                  msec to wait before
-                                                        starting new groups of
-                                                        parallel forks
-  --q-value-ms-before-cancel=INT                        msec to wait before
-                                                        cancelling parallel
-                                                        fork groups
-  -e, --enum-suffix=e164.arpa                           specify enum suffix to
-                                                        search
-  -b, --allow-bad-reg                                   allow To tag in
-                                                        registrations
-  --timer-C=180                                         specify length of
-                                                        timer C in sec (0 or
-                                                        negative will disable
-                                                        timer C)
-  -a, --admin-password=                                 set web administrator
-                                                        password
-  -V, --version                                         show the version number
-
-Help options:
-  -?, --help                                            Show this help message
-  --usage                                               Display brief usage
-                                                        message
+**WARNING - command line options in version 1.8 are not backwards compatible with older releases.
+
+Command line format is:
+
+repro [<ConfigFilename>] [--<ConfigValueName>=<ConfigValue>] [--<ConfigValueName>=<ConfigValue>] 
+
+Sample Command lines:
+repro repro.config --RecordRouteUri=sip:proxy.sipdomain.com --ForceRecordRouting=true
+repro repro.config /RecordRouteUri:sip:proxy.sipdomain.com /ForceRecordRouting:true
+
diff -Nru resiprocate-1.8.4/repro/WinSetup/Setup_10_0.vdproj resiprocate-1.8.5/repro/WinSetup/Setup_10_0.vdproj
--- resiprocate-1.8.4/repro/WinSetup/Setup_10_0.vdproj	2012-07-05 15:09:44.000000000 +0000
+++ resiprocate-1.8.5/repro/WinSetup/Setup_10_0.vdproj	2012-08-08 12:48:18.000000000 +0000
@@ -21,6 +21,18 @@
         }
         "Entry"
         {
+        "MsmKey" = "8:_35F69CCBB8D2405A81D61032D3055B77"
+        "OwnerKey" = "8:_442757485B394E61869D01D8D1BBCC92"
+        "MsmSig" = "8:_UNDEFINED"
+        }
+        "Entry"
+        {
+        "MsmKey" = "8:_442757485B394E61869D01D8D1BBCC92"
+        "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D"
+        "MsmSig" = "8:_UNDEFINED"
+        }
+        "Entry"
+        {
         "MsmKey" = "8:_449747DB7BDE448E8557B9834BB2A62D"
         "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
@@ -33,8 +45,8 @@
         }
         "Entry"
         {
-        "MsmKey" = "8:_A8E3227DFD564209AA92B57B1B750FDE"
-        "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D"
+        "MsmKey" = "8:_731AD5DF4FB949D3A731B82C4CA70F0D"
+        "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
         }
         "Entry"
@@ -160,6 +172,26 @@
             "IsDependency" = "11:FALSE"
             "IsolateTo" = "8:"
             }
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_731AD5DF4FB949D3A731B82C4CA70F0D"
+            {
+            "SourcePath" = "8:..\\repro.config"
+            "TargetName" = "8:repro.config"
+            "Tag" = "8:"
+            "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78"
+            "Condition" = "8:"
+            "Transitive" = "11:FALSE"
+            "Vital" = "11:TRUE"
+            "ReadOnly" = "11:FALSE"
+            "Hidden" = "11:FALSE"
+            "System" = "11:FALSE"
+            "Permanent" = "11:FALSE"
+            "SharedLegacy" = "11:FALSE"
+            "PackageAs" = "3:1"
+            "Register" = "3:1"
+            "Exclude" = "11:FALSE"
+            "IsDependency" = "11:FALSE"
+            "IsolateTo" = "8:"
+            }
             "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B0B648F097BA49E5AF24FE8FAAAA3E44"
             {
             "SourcePath" = "8:..\\VERSION"
@@ -806,11 +838,25 @@
         }
         "MergeModule"
         {
-            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_A8E3227DFD564209AA92B57B1B750FDE"
+            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_35F69CCBB8D2405A81D61032D3055B77"
+            {
+            "UseDynamicProperties" = "11:TRUE"
+            "IsDependency" = "11:TRUE"
+            "SourcePath" = "8:microsoft_vc90_debugcrt_x86.msm"
+                "Properties"
+                {
+                }
+            "LanguageId" = "3:0"
+            "Exclude" = "11:FALSE"
+            "Folder" = "8:"
+            "Feature" = "8:"
+            "IsolateTo" = "8:"
+            }
+            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_442757485B394E61869D01D8D1BBCC92"
             {
             "UseDynamicProperties" = "11:TRUE"
             "IsDependency" = "11:TRUE"
-            "SourcePath" = "8:Microsoft_VC100_DebugCRT_x86.msm"
+            "SourcePath" = "8:policy_9_0_Microsoft_VC90_DebugCRT_x86.msm"
                 "Properties"
                 {
                 }
@@ -825,7 +871,7 @@
         {
             "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_449747DB7BDE448E8557B9834BB2A62D"
             {
-            "SourcePath" = "8:..\\SSL-Debug\\repro.exe"
+            "SourcePath" = "8:..\\Debug\\repro.exe"
             "TargetName" = "8:"
             "Tag" = "8:"
             "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78"
diff -Nru resiprocate-1.8.4/repro/WinSetup/Setup_8_0.vdproj resiprocate-1.8.5/repro/WinSetup/Setup_8_0.vdproj
--- resiprocate-1.8.4/repro/WinSetup/Setup_8_0.vdproj	2012-07-05 15:09:44.000000000 +0000
+++ resiprocate-1.8.5/repro/WinSetup/Setup_8_0.vdproj	2012-08-08 12:48:18.000000000 +0000
@@ -27,6 +27,18 @@
         }
         "Entry"
         {
+        "MsmKey" = "8:_589E4F8781B6EFF5018F0646F96CD14B"
+        "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D"
+        "MsmSig" = "8:_UNDEFINED"
+        }
+        "Entry"
+        {
+        "MsmKey" = "8:_8E41C4D12C3648E1BC1DFEC42392972E"
+        "OwnerKey" = "8:_UNDEFINED"
+        "MsmSig" = "8:_UNDEFINED"
+        }
+        "Entry"
+        {
         "MsmKey" = "8:_B0B648F097BA49E5AF24FE8FAAAA3E44"
         "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
@@ -128,6 +140,46 @@
             "IsDependency" = "11:FALSE"
             "IsolateTo" = "8:"
             }
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_589E4F8781B6EFF5018F0646F96CD14B"
+            {
+            "SourcePath" = "8:IPHLPAPI.DLL"
+            "TargetName" = "8:IPHLPAPI.DLL"
+            "Tag" = "8:"
+            "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78"
+            "Condition" = "8:"
+            "Transitive" = "11:FALSE"
+            "Vital" = "11:TRUE"
+            "ReadOnly" = "11:FALSE"
+            "Hidden" = "11:FALSE"
+            "System" = "11:FALSE"
+            "Permanent" = "11:FALSE"
+            "SharedLegacy" = "11:FALSE"
+            "PackageAs" = "3:1"
+            "Register" = "3:1"
+            "Exclude" = "11:FALSE"
+            "IsDependency" = "11:TRUE"
+            "IsolateTo" = "8:"
+            }
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8E41C4D12C3648E1BC1DFEC42392972E"
+            {
+            "SourcePath" = "8:..\\repro.config"
+            "TargetName" = "8:repro.config"
+            "Tag" = "8:"
+            "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78"
+            "Condition" = "8:"
+            "Transitive" = "11:FALSE"
+            "Vital" = "11:TRUE"
+            "ReadOnly" = "11:FALSE"
+            "Hidden" = "11:FALSE"
+            "System" = "11:FALSE"
+            "Permanent" = "11:FALSE"
+            "SharedLegacy" = "11:FALSE"
+            "PackageAs" = "3:1"
+            "Register" = "3:1"
+            "Exclude" = "11:FALSE"
+            "IsDependency" = "11:FALSE"
+            "IsolateTo" = "8:"
+            }
             "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B0B648F097BA49E5AF24FE8FAAAA3E44"
             {
             "SourcePath" = "8:..\\VERSION"
@@ -348,6 +400,20 @@
             "Icon" = "8:"
             "Feature" = "8:"
             }
+            "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_67AC6DE8B6E64AC1A2DE2739B887577F"
+            {
+            "Name" = "8:repro.config"
+            "Arguments" = "8:"
+            "Description" = "8:"
+            "ShowCmd" = "3:1"
+            "IconIndex" = "3:0"
+            "Transitive" = "11:FALSE"
+            "Target" = "8:_8E41C4D12C3648E1BC1DFEC42392972E"
+            "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8"
+            "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78"
+            "Icon" = "8:"
+            "Feature" = "8:"
+            }
             "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_7CDB993AF3BD44E495FF253FB8E164D9"
             {
             "Name" = "8:Repro SIP Proxy"
@@ -358,7 +424,7 @@
             "Transitive" = "11:FALSE"
             "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D"
             "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8"
-            "WorkingFolder" = "8:"
+            "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78"
             "Icon" = "8:"
             "Feature" = "8:"
             }
@@ -777,7 +843,7 @@
         {
             "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_449747DB7BDE448E8557B9834BB2A62D"
             {
-            "SourcePath" = "8:..\\debug\\repro.exe"
+            "SourcePath" = "8:..\\Debug\\repro.exe"
             "TargetName" = "8:"
             "Tag" = "8:"
             "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78"
diff -Nru resiprocate-1.8.4/repro/WinSetup/Setup_9_0.vdproj resiprocate-1.8.5/repro/WinSetup/Setup_9_0.vdproj
--- resiprocate-1.8.4/repro/WinSetup/Setup_9_0.vdproj	2012-07-05 15:09:44.000000000 +0000
+++ resiprocate-1.8.5/repro/WinSetup/Setup_9_0.vdproj	2012-08-08 12:48:18.000000000 +0000
@@ -33,38 +33,38 @@
         }
         "Entry"
         {
-        "MsmKey" = "8:_5752D824D4BA4CC4AE9A4129533CC084"
-        "OwnerKey" = "8:_UNDEFINED"
+        "MsmKey" = "8:_4D212C1D21C34639B306B0B60769803D"
+        "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D"
         "MsmSig" = "8:_UNDEFINED"
         }
         "Entry"
         {
-        "MsmKey" = "8:_589E4F8781B6EFF5018F0646F96CD14B"
-        "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D"
+        "MsmKey" = "8:_5752D824D4BA4CC4AE9A4129533CC084"
+        "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
         }
         "Entry"
         {
-        "MsmKey" = "8:_61428F82929F493D8B88B795D8D3F1B1"
+        "MsmKey" = "8:_589E4F8781B6EFF5018F0646F96CD14B"
         "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D"
         "MsmSig" = "8:_UNDEFINED"
         }
         "Entry"
         {
-        "MsmKey" = "8:_990B1533EAE8425EB68FFC5FDA644E58"
-        "OwnerKey" = "8:_61428F82929F493D8B88B795D8D3F1B1"
+        "MsmKey" = "8:_9B970858111B46D498BB6728C709EE22"
+        "OwnerKey" = "8:_4D212C1D21C34639B306B0B60769803D"
         "MsmSig" = "8:_UNDEFINED"
         }
         "Entry"
         {
-        "MsmKey" = "8:_B0B648F097BA49E5AF24FE8FAAAA3E44"
+        "MsmKey" = "8:_A06A2BC6896346A8AC7E4F2FDC2B11DF"
         "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
         }
         "Entry"
         {
-        "MsmKey" = "8:_C04E882EF2F696D5E7C5F0B3E3420B6E"
-        "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D"
+        "MsmKey" = "8:_B0B648F097BA49E5AF24FE8FAAAA3E44"
+        "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
         }
     }
@@ -224,10 +224,10 @@
             "IsDependency" = "11:TRUE"
             "IsolateTo" = "8:"
             }
-            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B0B648F097BA49E5AF24FE8FAAAA3E44"
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A06A2BC6896346A8AC7E4F2FDC2B11DF"
             {
-            "SourcePath" = "8:..\\VERSION"
-            "TargetName" = "8:VERSION"
+            "SourcePath" = "8:..\\repro.config"
+            "TargetName" = "8:repro.config"
             "Tag" = "8:"
             "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78"
             "Condition" = "8:"
@@ -244,10 +244,10 @@
             "IsDependency" = "11:FALSE"
             "IsolateTo" = "8:"
             }
-            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C04E882EF2F696D5E7C5F0B3E3420B6E"
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B0B648F097BA49E5AF24FE8FAAAA3E44"
             {
-            "SourcePath" = "8:LIBMYSQL.dll"
-            "TargetName" = "8:LIBMYSQL.dll"
+            "SourcePath" = "8:..\\VERSION"
+            "TargetName" = "8:VERSION"
             "Tag" = "8:"
             "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78"
             "Condition" = "8:"
@@ -260,8 +260,8 @@
             "SharedLegacy" = "11:FALSE"
             "PackageAs" = "3:1"
             "Register" = "3:1"
-            "Exclude" = "11:TRUE"
-            "IsDependency" = "11:TRUE"
+            "Exclude" = "11:FALSE"
+            "IsDependency" = "11:FALSE"
             "IsolateTo" = "8:"
             }
         }
@@ -332,7 +332,7 @@
         "Name" = "8:Microsoft Visual Studio"
         "ProductName" = "8:Repro SIP Proxy"
         "ProductCode" = "8:{1D66F08D-5168-4EC9-B809-CC792E780CA9}"
-        "PackageCode" = "8:{34B673A4-150E-42BF-A6C4-1FB3B1232E8A}"
+        "PackageCode" = "8:{BFCE542D-12FA-45E4-B61E-18BFDCF126C1}"
         "UpgradeCode" = "8:{7BD08495-64E4-4565-A1DC-93954D304A2E}"
         "RestartWWWService" = "11:FALSE"
         "RemovePreviousVersions" = "11:FALSE"
@@ -475,7 +475,7 @@
             "Transitive" = "11:FALSE"
             "Target" = "8:_449747DB7BDE448E8557B9834BB2A62D"
             "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8"
-            "WorkingFolder" = "8:"
+            "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78"
             "Icon" = "8:"
             "Feature" = "8:"
             }
@@ -493,6 +493,20 @@
             "Icon" = "8:"
             "Feature" = "8:"
             }
+            "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_E3DD708E008F4D00A29C2A04F00D7F0C"
+            {
+            "Name" = "8:repro.config"
+            "Arguments" = "8:"
+            "Description" = "8:"
+            "ShowCmd" = "3:1"
+            "IconIndex" = "3:0"
+            "Transitive" = "11:FALSE"
+            "Target" = "8:_A06A2BC6896346A8AC7E4F2FDC2B11DF"
+            "Folder" = "8:_ADAE71E3079D4A2691B0E37C4D87E8F8"
+            "WorkingFolder" = "8:_96F138CFF79546568B8B0A6277D34A78"
+            "Icon" = "8:"
+            "Feature" = "8:"
+            }
         }
         "UserInterface"
         {
@@ -889,7 +903,7 @@
         }
         "MergeModule"
         {
-            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_61428F82929F493D8B88B795D8D3F1B1"
+            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_4D212C1D21C34639B306B0B60769803D"
             {
             "UseDynamicProperties" = "11:TRUE"
             "IsDependency" = "11:TRUE"
@@ -903,7 +917,7 @@
             "Feature" = "8:"
             "IsolateTo" = "8:"
             }
-            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_990B1533EAE8425EB68FFC5FDA644E58"
+            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_9B970858111B46D498BB6728C709EE22"
             {
             "UseDynamicProperties" = "11:TRUE"
             "IsDependency" = "11:TRUE"
diff -Nru resiprocate-1.8.4/repro/WinSetupx64/Setupx64_10_0.vdproj resiprocate-1.8.5/repro/WinSetupx64/Setupx64_10_0.vdproj
--- resiprocate-1.8.4/repro/WinSetupx64/Setupx64_10_0.vdproj	2012-07-05 15:09:39.000000000 +0000
+++ resiprocate-1.8.5/repro/WinSetupx64/Setupx64_10_0.vdproj	2012-08-08 12:48:14.000000000 +0000
@@ -33,8 +33,14 @@
         }
         "Entry"
         {
-        "MsmKey" = "8:_576C874D18C54E7FB65D9C02424C7088"
-        "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D"
+        "MsmKey" = "8:_71F618E7C4DC4C8BB9951979ACAAE6D0"
+        "OwnerKey" = "8:_CB0C4F3295DA49D9A1651EA26C9ED155"
+        "MsmSig" = "8:_UNDEFINED"
+        }
+        "Entry"
+        {
+        "MsmKey" = "8:_8D12D2A1F5184F799E9F0D5FD0668526"
+        "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
         }
         "Entry"
@@ -43,6 +49,12 @@
         "OwnerKey" = "8:_UNDEFINED"
         "MsmSig" = "8:_UNDEFINED"
         }
+        "Entry"
+        {
+        "MsmKey" = "8:_CB0C4F3295DA49D9A1651EA26C9ED155"
+        "OwnerKey" = "8:_449747DB7BDE448E8557B9834BB2A62D"
+        "MsmSig" = "8:_UNDEFINED"
+        }
     }
     "Configurations"
     {
@@ -160,6 +172,26 @@
             "IsDependency" = "11:FALSE"
             "IsolateTo" = "8:"
             }
+            "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8D12D2A1F5184F799E9F0D5FD0668526"
+            {
+            "SourcePath" = "8:..\\repro.config"
+            "TargetName" = "8:repro.config"
+            "Tag" = "8:"
+            "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78"
+            "Condition" = "8:"
+            "Transitive" = "11:FALSE"
+            "Vital" = "11:TRUE"
+            "ReadOnly" = "11:FALSE"
+            "Hidden" = "11:FALSE"
+            "System" = "11:FALSE"
+            "Permanent" = "11:FALSE"
+            "SharedLegacy" = "11:FALSE"
+            "PackageAs" = "3:1"
+            "Register" = "3:1"
+            "Exclude" = "11:FALSE"
+            "IsDependency" = "11:FALSE"
+            "IsolateTo" = "8:"
+            }
             "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B0B648F097BA49E5AF24FE8FAAAA3E44"
             {
             "SourcePath" = "8:..\\VERSION"
@@ -806,11 +838,25 @@
         }
         "MergeModule"
         {
-            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_576C874D18C54E7FB65D9C02424C7088"
+            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_71F618E7C4DC4C8BB9951979ACAAE6D0"
+            {
+            "UseDynamicProperties" = "11:TRUE"
+            "IsDependency" = "11:TRUE"
+            "SourcePath" = "8:microsoft_vc90_debugcrt_x86.msm"
+                "Properties"
+                {
+                }
+            "LanguageId" = "3:0"
+            "Exclude" = "11:FALSE"
+            "Folder" = "8:"
+            "Feature" = "8:"
+            "IsolateTo" = "8:"
+            }
+            "{CEE29DC0-9FBA-4B99-8D47-5BC643D9B626}:_CB0C4F3295DA49D9A1651EA26C9ED155"
             {
             "UseDynamicProperties" = "11:TRUE"
             "IsDependency" = "11:TRUE"
-            "SourcePath" = "8:Microsoft_VC100_DebugCRT_x64.msm"
+            "SourcePath" = "8:policy_9_0_Microsoft_VC90_DebugCRT_x86.msm"
                 "Properties"
                 {
                 }
@@ -825,7 +871,7 @@
         {
             "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_449747DB7BDE448E8557B9834BB2A62D"
             {
-            "SourcePath" = "8:..\\SSL-Debug\\repro.exe"
+            "SourcePath" = "8:..\\Debug\\repro.exe"
             "TargetName" = "8:"
             "Tag" = "8:"
             "Folder" = "8:_96F138CFF79546568B8B0A6277D34A78"
diff -Nru resiprocate-1.8.4/resip/dum/ContactInstanceRecord.hxx resiprocate-1.8.5/resip/dum/ContactInstanceRecord.hxx
--- resiprocate-1.8.4/resip/dum/ContactInstanceRecord.hxx	2012-07-05 15:10:08.000000000 +0000
+++ resiprocate-1.8.5/resip/dum/ContactInstanceRecord.hxx	2012-08-08 12:48:40.000000000 +0000
@@ -12,7 +12,7 @@
 
 namespace resip
 {
-static const UInt64 NeverExpire = 0xFFFFFFFFFFFFFFFFUL;
+static const UInt64 NeverExpire = 0xFFFFFFFFFFFFFFFFULL;
 
 /** A single contact record, bound to an Aor during registration.
 */
diff -Nru resiprocate-1.8.4/resip/dum/InviteSession.cxx resiprocate-1.8.5/resip/dum/InviteSession.cxx
--- resiprocate-1.8.4/resip/dum/InviteSession.cxx	2012-07-05 15:10:08.000000000 +0000
+++ resiprocate-1.8.5/resip/dum/InviteSession.cxx	2012-08-08 12:48:41.000000000 +0000
@@ -999,7 +999,7 @@
 
    virtual void executeCommand()
    {
-      mInviteSession.referCommand(mReferTo, mSessionToReplace, mReferSub);
+      mInviteSession.refer(mReferTo, mSessionToReplace, mReferSub);
    }
 
    virtual EncodeStream& encodeBrief(EncodeStream& strm) const
diff -Nru resiprocate-1.8.4/resip/dum/ServerAuthManager.cxx resiprocate-1.8.5/resip/dum/ServerAuthManager.cxx
--- resiprocate-1.8.4/resip/dum/ServerAuthManager.cxx	2012-07-05 15:10:08.000000000 +0000
+++ resiprocate-1.8.5/resip/dum/ServerAuthManager.cxx	2012-08-08 12:48:41.000000000 +0000
@@ -16,8 +16,9 @@
 using namespace resip;
 using namespace std;
 
-ServerAuthManager::ServerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target) :
-   DumFeature(dum, target)
+ServerAuthManager::ServerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, bool challengeThirdParties) :
+   DumFeature(dum, target),
+   mChallengeThirdParties(challengeThirdParties)
 {
 }
 
@@ -271,6 +272,12 @@
 ServerAuthManager::AsyncBool
 ServerAuthManager::requiresChallenge(const SipMessage& msg)
 {
+   if(!mChallengeThirdParties)
+   {
+      const Uri& fromUri = msg.header(h_From).uri();
+      if(!mDum.isMyDomain(fromUri.host()))
+         return False;
+   }
    return True;  
 }
 
diff -Nru resiprocate-1.8.4/resip/dum/ServerAuthManager.hxx resiprocate-1.8.5/resip/dum/ServerAuthManager.hxx
--- resiprocate-1.8.4/resip/dum/ServerAuthManager.hxx	2012-07-05 15:10:08.000000000 +0000
+++ resiprocate-1.8.5/resip/dum/ServerAuthManager.hxx	2012-08-08 12:48:41.000000000 +0000
@@ -26,7 +26,7 @@
          Rejected
       };
 
-      ServerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target);
+      ServerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, bool challengeThirdParties = true);
       virtual ~ServerAuthManager();
 
       virtual ProcessingResult process(Message* msg);      
@@ -99,6 +99,9 @@
 
       virtual void onAuthSuccess(const SipMessage& msg);
       virtual void onAuthFailure(AuthFailureReason reason, const SipMessage& msg);
+
+   private:
+      bool mChallengeThirdParties;
 };
 
  
diff -Nru resiprocate-1.8.4/resip/dum/test/CommandLineParser.cxx resiprocate-1.8.5/resip/dum/test/CommandLineParser.cxx
--- resiprocate-1.8.4/resip/dum/test/CommandLineParser.cxx	2012-07-05 15:10:05.000000000 +0000
+++ resiprocate-1.8.5/resip/dum/test/CommandLineParser.cxx	2012-08-08 12:48:38.000000000 +0000
@@ -1,3 +1,7 @@
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
 #if defined (HAVE_POPT_H)
 #include <popt.h>
 #endif
diff -Nru resiprocate-1.8.4/resip/dum/TlsPeerAuthManager.cxx resiprocate-1.8.5/resip/dum/TlsPeerAuthManager.cxx
--- resiprocate-1.8.4/resip/dum/TlsPeerAuthManager.cxx	2012-07-05 15:10:08.000000000 +0000
+++ resiprocate-1.8.5/resip/dum/TlsPeerAuthManager.cxx	2012-08-08 12:48:40.000000000 +0000
@@ -21,6 +21,13 @@
 {
 }
 
+TlsPeerAuthManager::TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, std::set<Data>& trustedPeers, bool thirdPartyRequiresCertificate, CommonNameMappings& commonNameMappings) :
+   DumFeature(dum, target),
+   mTrustedPeers(trustedPeers),
+   mThirdPartyRequiresCertificate(thirdPartyRequiresCertificate),
+   mCommonNameMappings(commonNameMappings)
+{
+}
 
 TlsPeerAuthManager::~TlsPeerAuthManager()
 {
@@ -80,6 +87,23 @@
          DebugLog(<< "Matched certificate name " << i << " against domain " << domain);
          return true;
       }
+      CommonNameMappings::iterator _mapping =
+         mCommonNameMappings.find(i);
+      if(_mapping != mCommonNameMappings.end())
+      {
+         DebugLog(<< "CN mapping(s) exist for the certificate " << i);
+         PermittedFromAddresses& permitted = _mapping->second;
+         if(permitted.find(aor) != permitted.end())
+         {
+            DebugLog(<< "Matched certificate name " << i << " against full AoR " << aor << " by common name mappings");
+            return true;
+         }
+         if(permitted.find(domain) != permitted.end())
+         {
+            DebugLog(<< "Matched certificate name " << i << " against domain " << domain << " by common name mappings");
+            return true;
+         }
+      }
       DebugLog(<< "Certificate name " << i << " doesn't match AoR " << aor << " or domain " << domain);
    }
 
@@ -120,7 +144,9 @@
    const std::list<resip::Data> &peerNames = sipMessage->getTlsPeerNames();
    if (mDum.isMyDomain(sipMessage->header(h_From).uri().host()))
    {
-      if (requiresAuthorization(*sipMessage))
+      // peerNames is empty if client certificate mode is `optional'
+      // or if the message didn't come in on TLS transport
+      if (requiresAuthorization(*sipMessage) && !peerNames.empty())
       {
          if(authorizedForThisIdentity(peerNames, sipMessage->header(h_From).uri()))
             return Authorized;
@@ -134,12 +160,19 @@
    }
    else
    {
-      if(mThirdPartyRequiresCertificate && peerNames.size() == 0)
-      {
-         SharedPtr<SipMessage> response(new SipMessage);
-         Helper::makeResponse(*response, *sipMessage, 403, "Mutual TLS required to handle that message");
-         mDum.send(response);
-         return Rejected;
+      // peerNames is empty if client certificate mode is `optional'
+      // or if the message didn't come in on TLS transport
+      if(peerNames.empty())
+      {
+         if(mThirdPartyRequiresCertificate)
+         {
+            SharedPtr<SipMessage> response(new SipMessage);
+            Helper::makeResponse(*response, *sipMessage, 403, "Mutual TLS required to handle that message");
+            mDum.send(response);
+            return Rejected;
+         }
+         else
+            return Skipped;
       }
       if(authorizedForThisIdentity(peerNames, sipMessage->header(h_From).uri()))
          return Authorized;
diff -Nru resiprocate-1.8.4/resip/dum/TlsPeerAuthManager.hxx resiprocate-1.8.5/resip/dum/TlsPeerAuthManager.hxx
--- resiprocate-1.8.4/resip/dum/TlsPeerAuthManager.hxx	2012-07-05 15:10:08.000000000 +0000
+++ resiprocate-1.8.5/resip/dum/TlsPeerAuthManager.hxx	2012-08-08 12:48:41.000000000 +0000
@@ -11,6 +11,8 @@
 {
 class DialogUsageManager;
 
+typedef std::set<Data> PermittedFromAddresses;
+typedef std::map<Data, PermittedFromAddresses> CommonNameMappings;
 
 class TlsPeerAuthManager : public DumFeature
 {
@@ -23,6 +25,7 @@
       };
 
       TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, std::set<Data>& trustedPeers, bool thirdPartyRequiresCertificate = true);
+      TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, std::set<Data>& trustedPeers, bool thirdPartyRequiresCertificate, CommonNameMappings& commonNameMappings);
       virtual ~TlsPeerAuthManager();
 
       virtual ProcessingResult process(Message* msg);      
@@ -42,6 +45,7 @@
 
    private:
       std::set<Data> mTrustedPeers;
+      CommonNameMappings mCommonNameMappings;
       bool mThirdPartyRequiresCertificate;
 };
 
diff -Nru resiprocate-1.8.4/resip/stack/DnsInterface.cxx resiprocate-1.8.5/resip/stack/DnsInterface.cxx
--- resiprocate-1.8.4/resip/stack/DnsInterface.cxx	2012-07-05 15:10:34.000000000 +0000
+++ resiprocate-1.8.5/resip/stack/DnsInterface.cxx	2012-08-08 12:49:09.000000000 +0000
@@ -114,7 +114,8 @@
 void 
 DnsInterface::lookup(DnsResult* res, const Uri& uri)
 {
-   res->lookup(uri, mDnsStub.getEnumSuffixes());   
+   res->lookup(uri, mDnsStub.getEnumSuffixes(),
+      mDnsStub.getEnumDomains());
 }
 
 // DnsResult* 
diff -Nru resiprocate-1.8.4/resip/stack/DnsResult.cxx resiprocate-1.8.5/resip/stack/DnsResult.cxx
--- resiprocate-1.8.4/resip/stack/DnsResult.cxx	2012-07-05 15:10:32.000000000 +0000
+++ resiprocate-1.8.5/resip/stack/DnsResult.cxx	2012-08-08 12:49:07.000000000 +0000
@@ -47,13 +47,58 @@
 
 #define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS
 
+EnumResult::EnumResult(EnumResultSink& resultSink, int order)
+   : mResultSink(resultSink),
+     mOrder(order)
+{
+}
+
+EnumResult::~EnumResult()
+{
+}
+
+void
+EnumResult::onDnsResult(const DNSResult<DnsHostRecord>& result)
+{
+   assert(0);
+   delete this;
+}
+
+void
+EnumResult::onDnsResult(const DNSResult<DnsAAAARecord>& result)
+{
+   assert(0);
+   delete this;
+}
+
+void
+EnumResult::onDnsResult(const DNSResult<DnsSrvRecord>&)
+{
+   assert(0);
+   delete this;
+}
+
+void
+EnumResult::onDnsResult(const DNSResult<DnsNaptrRecord>& result)
+{
+   mResultSink.onEnumResult(result, mOrder);
+   delete this;
+}
+
+void
+EnumResult::onDnsResult(const DNSResult<DnsCnameRecord>&)
+{
+   assert(0);
+   delete this;
+}
+
 DnsResult::DnsResult(DnsInterface& interfaceObj, DnsStub& dns, RRVip& vip, DnsHandler* handler) 
    : mInterface(interfaceObj),
      mDns(dns),
      mVip(vip),
      mHandler(handler),
      mSRVCount(0),
-     mDoingEnum(false),
+     mDoingEnum(0),
      mSips(false),
      mTransport(UNKNOWN_TRANSPORT),
      mPort(-1),
@@ -198,25 +243,33 @@
 }
 
 void
-DnsResult::lookup(const Uri& uri, const std::vector<Data> &enumSuffixes)
+DnsResult::lookup(const Uri& uri, const std::vector<Data> &enumSuffixes,
+   const std::map<Data,Data> &enumDomains)
 {
    DebugLog (<< "DnsResult::lookup " << uri);
    //int type = this->mType;
-   if (!enumSuffixes.empty() && uri.isEnumSearchable())
+   if (!enumSuffixes.empty() && uri.isEnumSearchable() &&
+      enumDomains.find(uri.host()) != enumDomains.end())
    {
       mInputUri = uri;
-      mDoingEnum = true;
+      int order = 0;
       std::vector<Data> enums = uri.getEnumLookups(enumSuffixes);
-      assert(enums.size() <= 1);
+      assert(enums.size() >= 1);
       if (!enums.empty())
       {
-         InfoLog (<< "Doing ENUM lookup on " << *enums.begin());
-         mDns.lookup<RR_NAPTR>(*enums.begin(), Protocol::Enum, this); 
+         mDoingEnum = enums.size();
+         for(std::vector<Data>::iterator it = enums.begin();
+            it != enums.end(); it++)
+         {
+            InfoLog (<< "Doing ENUM lookup on " << *it);
+            mDns.lookup<RR_NAPTR>(*it, Protocol::Enum,
+               new EnumResult(*this, order++)); 
+         }
          return;
       }
    }
 
-   mDoingEnum = false;
+   mDoingEnum = 0;
    lookupInternal(uri);
 }
 
@@ -1112,9 +1165,14 @@
 static Data enumService1("e2u+sip");
 static Data enumService2("sip+e2u");
 void
-DnsResult::onEnumResult(const DNSResult<DnsNaptrRecord>& result)
+DnsResult::onEnumResult(const DNSResult<DnsNaptrRecord>& result, int order)
 {
-   mDoingEnum = false;
+   Lock l(mEnumDestinationsMutex);
+   assert(mDoingEnum > 0);
+
+   mDoingEnum--;
+
+   StackLog(<< "checking result of ENUM query, remaining queries outstanding = " << mDoingEnum);
    
    if (result.status == 0)
    {
@@ -1158,24 +1216,34 @@
          {
             Uri rewrite(best.regexp().apply(Data::from(mInputUri)));
             InfoLog (<< "Rewrote uri " << mInputUri << " -> " << rewrite);
-            mHandler->rewriteRequest(rewrite);
-            lookupInternal(rewrite);
+            mEnumDestinations[order] = rewrite;
          }
          catch (ParseException&  e )
          {
             ErrLog(<<"Caught exception: "<< e);
-            lookupInternal(mInputUri);
+            // we just don't add anything to mEnumDestinations...
+            // later, if mEnumDestinations is empty after all ENUM queries,
+            // it will fall back to mInputUri
          }
       }
+   }
+
+   if(mDoingEnum == 0)
+   {
+      DebugLog(<< "All ENUM DNS queries done, checking for results...");
+      std::map<int,Uri>::iterator it = mEnumDestinations.begin();
+      if(it != mEnumDestinations.end())
+      {
+         DebugLog(<< "Using result for suffix " << (it->first + 1));
+         mHandler->rewriteRequest(it->second);
+         lookupInternal(it->second);
+      }
       else
       {
+         DebugLog(<< "No valid ENUM query result, falling back to request URI");
          lookupInternal(mInputUri);
       }
    }
-   else
-   {
-      lookupInternal(mInputUri);
-   }
 }
 
 void
@@ -1308,14 +1376,7 @@
       return;
    }
 
-   if (mDoingEnum)
-   {
-      onEnumResult(result);
-   }
-   else
-   {
-      onNaptrResult(result);
-   }
+   onNaptrResult(result);
   
 }
 
diff -Nru resiprocate-1.8.4/resip/stack/DnsResult.hxx resiprocate-1.8.5/resip/stack/DnsResult.hxx
--- resiprocate-1.8.4/resip/stack/DnsResult.hxx	2012-07-05 15:10:34.000000000 +0000
+++ resiprocate-1.8.5/resip/stack/DnsResult.hxx	2012-08-08 12:49:09.000000000 +0000
@@ -16,6 +16,7 @@
 #include "resip/stack/Tuple.hxx"
 #include "resip/stack/Transport.hxx"
 #include "resip/stack/Uri.hxx"
+#include "rutil/Condition.hxx"
 #include "rutil/HeapInstanceCounter.hxx"
 #include "rutil/dns/RRVip.hxx"
 #include "rutil/dns/DnsStub.hxx"
@@ -32,7 +33,39 @@
 class DnsAAAARecord;
 class DnsHandler;
 
-class DnsResult : public DnsResultSink
+class EnumResultSink
+{
+   public:
+      virtual void onEnumResult(const DNSResult<DnsNaptrRecord>& result,
+         int order) = 0;
+};
+
+class EnumResult : public DnsResultSink
+{
+   public:
+      EnumResult(EnumResultSink& resultSink, int order);
+      ~EnumResult();
+
+      // DnsResultSink
+      void onDnsResult(const DNSResult<DnsHostRecord>&);
+
+//#ifdef USE_IPV6
+      void onDnsResult(const DNSResult<DnsAAAARecord>&);
+//#endif
+
+      void onDnsResult(const DNSResult<DnsSrvRecord>&);
+      void onDnsResult(const DNSResult<DnsNaptrRecord>&);
+      void onDnsResult(const DNSResult<DnsCnameRecord>&);
+
+      void onEnumResult(const DNSResult<DnsNaptrRecord>& result);
+      void onNaptrResult(const DNSResult<DnsNaptrRecord>& result);
+
+   private:
+      EnumResultSink& mResultSink;
+      int mOrder;
+};
+
+class DnsResult : public DnsResultSink, public EnumResultSink
 {
    public:
       RESIP_HeapCount(DnsResult);
@@ -60,8 +93,11 @@
          @param enumSuffixes If the uri is enum searchable, this is the list of
                   enum suffixes (for example "e164.arpa") that will be used in
                   the attempt to resolve this uri.
+         @param enumDomains The ENUM possibility is only considered if
+                the URI domain part is one of these domains
       */
-      void lookup(const Uri& uri, const std::vector<Data> &enumSuffixes);
+      void lookup(const Uri& uri, const std::vector<Data> &enumSuffixes,
+         const std::map<Data,Data> &enumDomains);
 
       /*!
          Blacklist the last returned result until the specified time (ms)
@@ -189,7 +225,9 @@
       DnsHandler* mHandler;
       int mSRVCount;
       Uri mInputUri;
-      bool mDoingEnum;
+      int mDoingEnum;
+      std::map<int,Uri> mEnumDestinations;
+      resip::Mutex mEnumDestinationsMutex;
       
       bool mSips;
       Data mTarget;
@@ -254,7 +292,7 @@
       void onDnsResult(const DNSResult<DnsNaptrRecord>&);
       void onDnsResult(const DNSResult<DnsCnameRecord>&);
 
-      void onEnumResult(const DNSResult<DnsNaptrRecord>& result);
+      void onEnumResult(const DNSResult<DnsNaptrRecord>& result, int order);
       void onNaptrResult(const DNSResult<DnsNaptrRecord>& result);
       
 
diff -Nru resiprocate-1.8.4/resip/stack/SipStack.cxx resiprocate-1.8.5/resip/stack/SipStack.cxx
--- resiprocate-1.8.4/resip/stack/SipStack.cxx	2012-07-05 15:10:34.000000000 +0000
+++ resiprocate-1.8.5/resip/stack/SipStack.cxx	2012-08-08 12:49:09.000000000 +0000
@@ -926,6 +926,12 @@
 }
 
 void
+SipStack::setEnumDomains(const std::map<Data,Data>& domains)
+{
+   mDnsStub->setEnumDomains(domains);
+}
+
+void
 SipStack::clearDnsCache()
 {
    mDnsStub->clearDnsCache();
diff -Nru resiprocate-1.8.4/resip/stack/SipStack.hxx resiprocate-1.8.5/resip/stack/SipStack.hxx
--- resiprocate-1.8.4/resip/stack/SipStack.hxx	2012-07-05 15:10:33.000000000 +0000
+++ resiprocate-1.8.5/resip/stack/SipStack.hxx	2012-08-08 12:49:08.000000000 +0000
@@ -639,7 +639,7 @@
             do not support epoll, fd_set ends up being used anyway since there 
             is no other choice, but this is hidden from the app.
       */
-      RESIP_DEPRECATED virtual void buildFdSet(FdSet& fdset);
+      RESIP_DEPRECATED(virtual void buildFdSet(FdSet& fdset));
 
       /**
           This allows the executive to give processing time to stack components.
@@ -656,7 +656,7 @@
             do not support epoll, fd_set ends up being used anyway since there 
             is no other choice, but this is hidden from the app.
       */
-      RESIP_DEPRECATED virtual void process(FdSet& fdset);
+      RESIP_DEPRECATED(virtual void process(FdSet& fdset));
 
       /**
          @brief Give processing time to the SipStack components, when operating 
@@ -808,6 +808,16 @@
       void setEnumSuffixes(const std::vector<Data>& suffixes);
 
       /**
+          @brief Specify which domains in the To: Uri will be subject to ENUM
+
+          @details If the Uri hostname/domain is one of these domains,
+          the user part will be considered for ENUM search
+
+          @ingroup resip_config
+      */
+      void setEnumDomains(const std::map<Data,Data>& domains);
+
+      /**
           @brief Clear the DNS Cache
       */
       void clearDnsCache();
diff -Nru resiprocate-1.8.4/resip/stack/StackThread.hxx resiprocate-1.8.5/resip/stack/StackThread.hxx
--- resiprocate-1.8.4/resip/stack/StackThread.hxx	2012-07-05 15:10:34.000000000 +0000
+++ resiprocate-1.8.5/resip/stack/StackThread.hxx	2012-08-08 12:49:09.000000000 +0000
@@ -25,7 +25,7 @@
    public:
       // *sigh* doesn't end up yielding a very good warning, but at least you 
       // get a line number.
-      RESIP_DEPRECATED StackThread(SipStack& stack);
+      RESIP_DEPRECATED(StackThread(SipStack& stack));
       virtual ~StackThread();
       
       virtual void thread();
diff -Nru resiprocate-1.8.4/resip/stack/Uri.cxx resiprocate-1.8.5/resip/stack/Uri.cxx
--- resiprocate-1.8.4/resip/stack/Uri.cxx	2012-07-05 15:10:33.000000000 +0000
+++ resiprocate-1.8.5/resip/stack/Uri.cxx	2012-08-08 12:49:09.000000000 +0000
@@ -250,7 +250,43 @@
 Uri::isEnumSearchable() const
 {
    checkParsed();
-   return (!mUser.empty() && mUser.size() >= 2 && mUser[0] == '+');
+   int digits = 0;
+
+   if(mUser.size() < 4)
+   {
+      StackLog(<< "user part of Uri empty or too short for E.164");
+      return false;
+   }
+
+   // E.164 numbers must begin with a + and have at least
+   // 3 digits
+   if(mUser[0] != '+')
+   {
+      StackLog(<< "user part of Uri does not begin with `+' or too short");
+      return false;
+   }
+
+   // count the digits (skip the leading `+')
+   for(const char* i=user().begin() + 1; i!= user().end(); i++)
+   {
+      if(isdigit(*i))
+         digits++;
+      else
+         if(*i != '-')
+         {
+            StackLog(<< "user part of Uri contains non-digit: " << *i);
+            return false; // Only digits and '-' permitted
+         }
+   }
+   if(digits > 15)
+   {
+      // E.164 only permits 15 digits in a phone number
+      StackLog(<< "user part of Uri contains more than 15 digits");
+      return false;
+   }
+
+   DebugLog(<< "is in E.164 format for ENUM: " << mUser);
+   return true;
 }
 
 std::vector<Data> 
@@ -269,6 +305,7 @@
             prefix += Symbols::DOT;
          }
       }
+      StackLog(<< "E.164 number reversed for ENUM query: " << prefix);
       for (std::vector<Data>::const_iterator j=suffixes.begin(); j != suffixes.end(); ++j)
       {
          results.push_back(prefix + *j);
diff -Nru resiprocate-1.8.4/reSIProcate_10_0.sln resiprocate-1.8.5/reSIProcate_10_0.sln
--- resiprocate-1.8.4/reSIProcate_10_0.sln	2012-07-05 15:12:17.000000000 +0000
+++ resiprocate-1.8.5/reSIProcate_10_0.sln	2012-08-08 12:50:52.000000000 +0000
@@ -26,7 +26,7 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reprolib", "repro\reprolib_10_0.vcxproj", "{31B0654F-E08E-405F-909F-80F86CB14B9E}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "popt", "contrib\popt\popt_10_0.vcxproj", "{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "popt", "contrib\popt\popt_10_0.vcxproj", "{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}"
 EndProject
 Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "ReproSetupx64", "repro\WinSetupx64\Setupx64_10_0.vdproj", "{91601068-BE73-4BE9-8030-143F4620E907}"
 EndProject
@@ -252,22 +252,22 @@
 		{31B0654F-E08E-405F-909F-80F86CB14B9E}.SSL-Release|Win32.Build.0 = SSL-Release|Win32
 		{31B0654F-E08E-405F-909F-80F86CB14B9E}.SSL-Release|x64.ActiveCfg = SSL-Release|x64
 		{31B0654F-E08E-405F-909F-80F86CB14B9E}.SSL-Release|x64.Build.0 = SSL-Release|x64
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.Debug|Win32.ActiveCfg = Debug|Win32
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.Debug|Win32.Build.0 = Debug|Win32
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.Debug|x64.ActiveCfg = Debug|x64
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.Debug|x64.Build.0 = Debug|x64
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.Release|Win32.ActiveCfg = Release|Win32
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.Release|Win32.Build.0 = Release|Win32
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.Release|x64.ActiveCfg = Release|x64
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.Release|x64.Build.0 = Release|x64
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.SSL-Debug|Win32.ActiveCfg = Debug|Win32
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.SSL-Debug|Win32.Build.0 = Debug|Win32
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.SSL-Debug|x64.ActiveCfg = Debug|x64
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.SSL-Debug|x64.Build.0 = Debug|x64
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.SSL-Release|Win32.ActiveCfg = Release|Win32
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.SSL-Release|Win32.Build.0 = Release|Win32
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.SSL-Release|x64.ActiveCfg = Release|x64
-		{BD9B6DDA-3ACC-A361-1FA3-12FB51B48952}.SSL-Release|x64.Build.0 = Release|x64
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.Debug|Win32.Build.0 = Debug|Win32
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.Debug|x64.ActiveCfg = Debug|x64
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.Debug|x64.Build.0 = Debug|x64
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.Release|Win32.ActiveCfg = Release|Win32
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.Release|Win32.Build.0 = Release|Win32
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.Release|x64.ActiveCfg = Release|x64
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.Release|x64.Build.0 = Release|x64
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.SSL-Debug|Win32.ActiveCfg = Debug|Win32
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.SSL-Debug|Win32.Build.0 = Debug|Win32
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.SSL-Debug|x64.ActiveCfg = Debug|x64
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.SSL-Debug|x64.Build.0 = Debug|x64
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.SSL-Release|Win32.ActiveCfg = Release|Win32
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.SSL-Release|Win32.Build.0 = Release|Win32
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.SSL-Release|x64.ActiveCfg = Release|x64
+		{E3BB56BD-E1DA-0360-E97D-56AA69EF23F9}.SSL-Release|x64.Build.0 = Release|x64
 		{91601068-BE73-4BE9-8030-143F4620E907}.Debug|Win32.ActiveCfg = Debug
 		{91601068-BE73-4BE9-8030-143F4620E907}.Debug|x64.ActiveCfg = Debug
 		{91601068-BE73-4BE9-8030-143F4620E907}.Debug|x64.Build.0 = Debug
diff -Nru resiprocate-1.8.4/resip.spec resiprocate-1.8.5/resip.spec
--- resiprocate-1.8.4/resip.spec	2012-07-05 15:15:56.000000000 +0000
+++ resiprocate-1.8.5/resip.spec	2012-08-08 12:51:27.000000000 +0000
@@ -1,5 +1,5 @@
 Name: resiprocate
-Version: 1.8.4
+Version: 1.8.5
 Release: 1
 Summary: Resiprocate SIP Stack
 License: Vovida Software License http://opensource.org/licenses/vovidapl.php
diff -Nru resiprocate-1.8.4/reTurn/ReTurnConfig.cxx resiprocate-1.8.5/reTurn/ReTurnConfig.cxx
--- resiprocate-1.8.4/reTurn/ReTurnConfig.cxx	2012-07-05 15:09:33.000000000 +0000
+++ resiprocate-1.8.5/reTurn/ReTurnConfig.cxx	2012-08-08 12:48:07.000000000 +0000
@@ -37,33 +37,15 @@
    calcUserAuthData();
 }
 
-ReTurnConfig::ReTurnConfig(int argc, char** argv, const resip::Data& defaultConfigFilename) :
-   resip::ConfigParse(argc, argv, defaultConfigFilename),
-   mTurnPort(getConfigUnsignedShort("TurnPort", 3478)),
-   mTlsTurnPort(getConfigUnsignedShort("TlsTurnPort", 5349)),
-   mAltStunPort(getConfigUnsignedShort("AltStunPort", 0)),
-   mTurnAddress(asio::ip::address::from_string(
-      getConfigData("TurnAddress", "0.0.0.0").c_str())),
-   mAltStunAddress(asio::ip::address::from_string(
-      getConfigData("AltStunAddress", "0.0.0.0").c_str())),
-   mAuthenticationMode(LongTermPassword),
-   mAuthenticationRealm(getConfigData("AuthenticationRealm", "reTurn")),
-   mNonceLifetime(getConfigUnsignedLong("NonceLifetime", 3600)),
-   mAllocationPortRangeMin(getConfigUnsignedShort("AllocationPortRangeMin", 49152)),
-   mAllocationPortRangeMax(getConfigUnsignedShort("AllocationPortRangeMax", 65535)),
-   mDefaultAllocationLifetime(getConfigUnsignedLong("DefaultAllocationLifetime", 600)),
-   mMaxAllocationLifetime(getConfigUnsignedLong("MaxAllocationLifetime", 3600)),
-   mMaxAllocationsPerUser(getConfigUnsignedLong("MaxAllocationsPerUser", 0)),
-   mTlsServerCertificateFilename(getConfigData("TlsServerCertificateFilename", "server.pem")),
-   mTlsTempDhFilename(getConfigData("TlsTempDhFilename", "dh512.pem")),
-   mTlsPrivateKeyPassword(getConfigData("TlsPrivateKeyPassword", "")),
-   mLoggingType(getConfigData("LoggingType", "cout")),
-   mLoggingLevel(getConfigData("LoggingLevel", "INFO")),
-   mLoggingFilename(getConfigData("LogFilename", "reTurnServer.log")),
-   mLoggingFileMaxLineCount(getConfigUnsignedLong("LogFileMaxLines", 50000)),
-   mDaemonize(getConfigBool("Daemonize", false)),
-   mPidFile(getConfigData("PidFile", ""))
+void ReTurnConfig::parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename)
 {
+   resip::ConfigParse::parseConfig(argc, argv, defaultConfigFilename);
+
+   mTurnPort = getConfigUnsignedShort("TurnPort", 3478);
+   mTlsTurnPort = getConfigUnsignedShort("TlsTurnPort", 5349);
+   mAltStunPort = getConfigUnsignedShort("AltStunPort", 0);
+   mTurnAddress = asio::ip::address::from_string(getConfigData("TurnAddress", "0.0.0.0").c_str());
+   mAltStunAddress = asio::ip::address::from_string(getConfigData("AltStunAddress", "0.0.0.0").c_str());
    int authMode = getConfigUnsignedShort("AuthenticationMode", 2);
    switch(authMode)
    {
@@ -73,12 +55,28 @@
    default: 
       throw std::runtime_error("Unsupported AuthenticationMode value in config");
    }
+   mAuthenticationRealm = getConfigData("AuthenticationRealm", "reTurn");
+   mNonceLifetime = getConfigUnsignedLong("NonceLifetime", 3600);
+   mAllocationPortRangeMin = getConfigUnsignedShort("AllocationPortRangeMin", 49152);
+   mAllocationPortRangeMax = getConfigUnsignedShort("AllocationPortRangeMax", 65535);
+   mDefaultAllocationLifetime = getConfigUnsignedLong("DefaultAllocationLifetime", 600);
+   mMaxAllocationLifetime = getConfigUnsignedLong("MaxAllocationLifetime", 3600);
+   mMaxAllocationsPerUser = getConfigUnsignedLong("MaxAllocationsPerUser", 0);
+   mTlsServerCertificateFilename = getConfigData("TlsServerCertificateFilename", "server.pem");
+   mTlsTempDhFilename = getConfigData("TlsTempDhFilename", "dh512.pem");
+   mTlsPrivateKeyPassword = getConfigData("TlsPrivateKeyPassword", "");
+   mLoggingType = getConfigData("LoggingType", "cout");
+   mLoggingLevel = getConfigData("LoggingLevel", "INFO");
+   mLoggingFilename = getConfigData("LogFilename", "reTurnServer.log");
+   mLoggingFileMaxLineCount = getConfigUnsignedLong("LogFileMaxLines", 50000);
+   mDaemonize = getConfigBool("Daemonize", false);
+   mPidFile = getConfigData("PidFile", "");
 
    // fork is not possible on Windows
 #ifdef WIN32
    if(mDaemonize)
    {
-      throw std::runtime_error("Unable to fork/daemonize on Windows, please check the config");
+      throw ConfigParse::Exception("Unable to fork/daemonize on Windows, please check the config", __FILE__, __LINE__);
    }
 #endif
 
@@ -87,7 +85,7 @@
 
    if(user.size() == 0 || password.size() == 0)
    {
-      throw std::runtime_error("Missing or invalid credentials (LongTermAuthUsername/LongTermAuthPassword");
+      throw ConfigParse::Exception("Missing or invalid credentials (LongTermAuthUsername/LongTermAuthPassword", __FILE__, __LINE__);
    }
 
    mAuthenticationCredentials[user] = password;
@@ -118,9 +116,9 @@
 ReTurnConfig::printHelpText(int argc, char **argv)
 {
    std::cerr << "Command line format is:" << std::endl;
-   std::cerr << "  " << argv[0] << " [<ConfigFilename>] [--<ConfigValueName>=<ConfigValue>] [--<ConfigValueName>=<ConfigValue>] ..." << std::endl;
+   std::cerr << "  " << removePath(argv[0]) << " [<ConfigFilename>] [--<ConfigValueName>=<ConfigValue>] [--<ConfigValueName>=<ConfigValue>] ..." << std::endl;
    std::cerr << "Sample Command lines:" << std::endl;
-   std::cerr << "  " << argv[0] << "reTurnServer.config --LogLevel=INFO" << std::endl;
+   std::cerr << "  " << removePath(argv[0]) << " reTurnServer.config --LogLevel=INFO" << std::endl;
 }
 
 bool 
diff -Nru resiprocate-1.8.4/reTurn/ReTurnConfig.hxx resiprocate-1.8.5/reTurn/ReTurnConfig.hxx
--- resiprocate-1.8.4/reTurn/ReTurnConfig.hxx	2012-07-05 15:09:34.000000000 +0000
+++ resiprocate-1.8.5/reTurn/ReTurnConfig.hxx	2012-08-08 12:48:07.000000000 +0000
@@ -17,9 +17,10 @@
 {
 public:
    ReTurnConfig();
-   ReTurnConfig(int argc, char** argv, const resip::Data& defaultConfigFilename);
    virtual ~ReTurnConfig();
 
+   virtual void parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename);
+
    void printHelpText(int argc, char **argv);
    using resip::ConfigParse::getConfigValue;
 
diff -Nru resiprocate-1.8.4/reTurn/reTurnServer.cxx resiprocate-1.8.5/reTurn/reTurnServer.cxx
--- resiprocate-1.8.4/reTurn/reTurnServer.cxx	2012-07-05 15:09:34.000000000 +0000
+++ resiprocate-1.8.5/reTurn/reTurnServer.cxx	2012-08-08 12:48:07.000000000 +0000
@@ -61,12 +61,23 @@
 #endif
 
    resip::Data defaultConfig("reTurnServer.config");
-   reTurn::ReTurnConfig reTurnConfig(argc, argv, defaultConfig);
+   reTurn::ReTurnConfig reTurnConfig;
+   try
+   {
+      reTurnConfig.parseConfig(argc, argv, defaultConfig);
+   }
+   catch(std::exception& e)
+   {
+      ErrLog(<< "Exception parsing configuration: " << e.what());
+      exit(-1);
+   }
 
    setPidFile(reTurnConfig.mPidFile);
    // Daemonize if necessary
    if(reTurnConfig.mDaemonize)
+   {
       daemonize();
+   }
 
    try
    {
diff -Nru resiprocate-1.8.4/rutil/compat.hxx resiprocate-1.8.5/rutil/compat.hxx
--- resiprocate-1.8.4/rutil/compat.hxx	2012-07-05 15:10:53.000000000 +0000
+++ resiprocate-1.8.5/rutil/compat.hxx	2012-08-08 12:49:27.000000000 +0000
@@ -196,11 +196,11 @@
 // like prior to that. As for SUNPRO, it uses gcc's frontend, so I would expect 
 // gnu-c function attributes to work, but does it define __GNUC__?
 #if defined(__GNUC__) || (__INTEL_COMPILER > 800)
-#define RESIP_DEPRECATED __attribute__ ((deprecated))
+#define RESIP_DEPRECATED(x) x __attribute__ ((deprecated))
 #elif defined(_MSC_VER)
-#define RESIP_DEPRECATED __declspec(deprecated)
+#define RESIP_DEPRECATED(x) __declspec(deprecated) x
 #else
-#define RESIP_DEPRECATED
+#define RESIP_DEPRECATED(x) x
 #endif
 
 #endif
diff -Nru resiprocate-1.8.4/rutil/ConfigParse.cxx resiprocate-1.8.5/rutil/ConfigParse.cxx
--- resiprocate-1.8.4/rutil/ConfigParse.cxx	2012-07-05 15:10:52.000000000 +0000
+++ resiprocate-1.8.5/rutil/ConfigParse.cxx	2012-08-08 12:49:27.000000000 +0000
@@ -18,10 +18,18 @@
 namespace resip
 {
 
-ConfigParse::ConfigParse(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount) :
-   mSkipCount(skipCount)
+ConfigParse::ConfigParse()
+{
+}
+
+ConfigParse::~ConfigParse()
 {
-   parseCommandLine(argc, argv);  // will fill in mCmdLineConfigFilename if present
+}
+
+void 
+ConfigParse::parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount)
+{
+   parseCommandLine(argc, argv, skipCount);  // will fill in mCmdLineConfigFilename if present
    if(mCmdLineConfigFilename.empty())
    {
       parseConfigFile(defaultConfigFilename);
@@ -32,12 +40,122 @@
    }
 }
 
-ConfigParse::ConfigParse()
+void 
+ConfigParse::parseCommandLine(int argc, char** argv, int skipCount)
 {
+   int startingArgForNameValuePairs = 1 + skipCount;
+   char *firstArg = argv[startingArgForNameValuePairs];
+   // First argument is the configuration filename - it is optional and is never proceeded with a - or /
+#ifdef WIN32
+   if(argc >= (startingArgForNameValuePairs + 1) && firstArg[0] != '-' && firstArg[0] != '/')
+#else
+   if(argc >= (startingArgForNameValuePairs + 1) && firstArg[0] != '-')
+#endif
+   {
+      mCmdLineConfigFilename = firstArg;
+      startingArgForNameValuePairs++;
+   }
+
+   // Loop through command line arguments and process them
+   for(int i = startingArgForNameValuePairs; i < argc; i++)
+   {
+      Data argData(argv[i]);
+
+      // Process all commandNames that don't take values
+      if(isEqualNoCase(argData, "-?") || 
+         isEqualNoCase(argData, "--?") ||
+         isEqualNoCase(argData, "--help") ||
+         isEqualNoCase(argData, "/?"))
+      {
+         printHelpText(argc, argv);
+         exit(1);
+      }
+      else if(argData.at(0) == '-' || argData.at(0) == '/')
+      {
+         Data name;
+         Data value;
+         ParseBuffer pb(argData);
+
+         try
+         {
+            pb.skipChars(Data::toBitset("-/"));  // Skip any leading -'s or /'s
+            const char * anchor = pb.position();
+            pb.skipToOneOf("=:");
+            if(!pb.eof())
+            {
+               pb.data(name, anchor);
+               pb.skipChar();
+               anchor = pb.position();
+               pb.skipToEnd();
+               pb.data(value, anchor);
+
+               //cout << "Command line Name='" << name << "' value='" << value << "'" << endl;
+               insertConfigValue(name, value);
+            }
+            else
+            {
+               cerr << "Invalid command line parameters:"  << endl;
+               cerr << " Name/Value pairs must contain an = or a : between the name and the value" << endl;
+               exit(-1);  // todo - should convert this stuff to exceptions and let user decide to exit or not
+            }
+         }
+         catch(BaseException& ex)
+         {
+            cerr << "Invalid command line parameters:"  << endl;
+            cerr << " Exception parsing Name/Value pairs: " << ex << endl;
+            exit(-1); // todo - should convert this stuff to exceptions and let user decide to exit or not
+         }
+      }
+      else
+      {
+         cerr << "Invalid command line parameters:"  << endl;
+         cerr << " Name/Value pairs must be prefixed with either a -, --, or a /" << endl;
+         exit(-1); // todo - should convert this stuff to exceptions and let user decide to exit or not
+      }
+   }
 }
 
-ConfigParse::~ConfigParse()
+void
+ConfigParse::parseConfigFile(const Data& filename)
 {
+   ifstream configFile(filename.c_str());
+   
+   if(!configFile)
+   {
+      throw Exception("Error opening/reading configuration file", __FILE__, __LINE__);
+   }
+
+   string sline;
+   const char * anchor;
+   while(getline(configFile, sline)) 
+   {
+      Data line(sline);
+      Data name;
+      Data value;
+      ParseBuffer pb(line);
+
+      pb.skipWhitespace();
+      anchor = pb.position();
+      if(pb.eof() || *anchor == '#') continue;  // if line is a comment or blank then skip it
+
+      // Look for end of name
+      pb.skipToOneOf("= \t");
+      pb.data(name,anchor);
+      if(*pb.position()!='=') 
+      {
+         pb.skipToChar('=');
+      }
+      pb.skipChar('=');
+      pb.skipWhitespace();
+      anchor = pb.position();
+      if(!pb.eof())
+      {
+         pb.skipToOneOf("\r\n");
+         pb.data(value, anchor);
+      }
+      //cout << "Config file Name='" << name << "' value='" << value << "'" << endl;
+      insertConfigValue(name, value);
+   }
 }
 
 bool 
@@ -207,122 +325,19 @@
    mConfigValues.insert(ConfigValuesMap::value_type(lowerName, value));
 }
 
-void 
-ConfigParse::parseCommandLine(int argc, char** argv)
-{
-   int startingArgForNameValuePairs = 1 + mSkipCount;
-   char *firstArg = argv[startingArgForNameValuePairs];
-   // First argument is the configuration filename - it is optional and is never proceeded with a - or /
-#ifdef WIN32
-   if(argc >= (startingArgForNameValuePairs + 1) && firstArg[0] != '-' && firstArg[0] != '/')
-#else
-   if(argc >= (startingArgForNameValuePairs + 1) && firstArg[0] != '-')
-#endif
-   {
-      mCmdLineConfigFilename = firstArg;
-      startingArgForNameValuePairs++;
-   }
-
-   // Loop through command line arguments and process them
-   for(int i = startingArgForNameValuePairs; i < argc; i++)
-   {
-      Data argData(argv[i]);
-
-      // Process all commandNames that don't take values
-      if(isEqualNoCase(argData, "-?") || 
-         isEqualNoCase(argData, "--?") ||
-         isEqualNoCase(argData, "--help") ||
-         isEqualNoCase(argData, "/?"))
-      {
-         printHelpText(argc, argv);
-         exit(1);
-      }
-      else if(argData.at(0) == '-' || argData.at(0) == '/')
-      {
-         Data name;
-         Data value;
-         ParseBuffer pb(argData);
-
-         try
-         {
-            pb.skipChars(Data::toBitset("-/"));  // Skip any leading -'s or /'s
-            const char * anchor = pb.position();
-            pb.skipToOneOf("=:");
-            if(!pb.eof())
-            {
-               pb.data(name, anchor);
-               pb.skipChar();
-               anchor = pb.position();
-               pb.skipToEnd();
-               pb.data(value, anchor);
-
-               //cout << "Command line Name='" << name << "' value='" << value << "'" << endl;
-               insertConfigValue(name, value);
-            }
-            else
-            {
-               cerr << "Invalid command line parameters:"  << endl;
-               cerr << " Name/Value pairs must contain an = or a : between the name and the value" << endl;
-               exit(-1);
-            }
-         }
-         catch(BaseException& ex)
-         {
-            cerr << "Invalid command line parameters:"  << endl;
-            cerr << " Exception parsing Name/Value pairs: " << ex << endl;
-            exit(-1);
-         }
-      }
-      else
-      {
-         cerr << "Invalid command line parameters:"  << endl;
-         cerr << " Name/Value pairs must be prefixed with either a -, --, or a /" << endl;
-         exit(-1);
-      }
-   }
-}
-
-void
-ConfigParse::parseConfigFile(const Data& filename)
+resip::Data
+ConfigParse::removePath(const resip::Data& fileAndPath)
 {
-   ifstream configFile(filename.c_str());
-   
-   if(!configFile)
-   {
-      throw Exception("Error opening/reading configuration file", __FILE__, __LINE__);
-   }
-
-   string sline;
-   const char * anchor;
-   while(getline(configFile, sline)) 
+   Data filenameOnly;
+   ParseBuffer pb(fileAndPath);
+   const char* anchor = pb.position();
+   while(pb.skipToOneOf("/\\") && !pb.eof())
    {
-      Data line(sline);
-      Data name;
-      Data value;
-      ParseBuffer pb(line);
-
-      pb.skipWhitespace();
-      anchor = pb.position();
-      if(pb.eof() || *anchor == '#') continue;  // if line is a comment or blank then skip it
-
-      // Look for end of name
-      pb.skipToOneOf("= \t");
-      pb.data(name,anchor);
-      if(*pb.position()!='=') 
-      {
-         pb.skipToChar('=');
-      }
-      pb.skipChar('=');
-      pb.skipWhitespace();
+      pb.skipChar();
       anchor = pb.position();
-      if(!pb.eof())
-      {
-         pb.skipToOneOf("\r\n");
-         pb.data(value, anchor);
-      }
-      //cout << "Config file Name='" << name << "' value='" << value << "'" << endl;
-      insertConfigValue(name, value);
    }
+   pb.data(filenameOnly, anchor);
+   return filenameOnly;
 }
 
 EncodeStream& 
diff -Nru resiprocate-1.8.4/rutil/ConfigParse.hxx resiprocate-1.8.5/rutil/ConfigParse.hxx
--- resiprocate-1.8.4/rutil/ConfigParse.hxx	2012-07-05 15:10:53.000000000 +0000
+++ resiprocate-1.8.5/rutil/ConfigParse.hxx	2012-08-08 12:49:27.000000000 +0000
@@ -24,13 +24,15 @@
    };
 
    ConfigParse();
-   ConfigParse(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount = 0);
    virtual ~ConfigParse();
 
-   virtual void printHelpText(int argc, char **argv) = 0;
+   // parses both command line and config file - using config file name from first command line parameter (if present)
+   // skipcount represents the number of command line options to skip before looking for config filename or name value pairs
+   virtual void parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount = 0); 
+   virtual void parseCommandLine(int argc, char** argv, int skipCount = 0);
+   virtual void parseConfigFile(const resip::Data& filename);
 
-   void parseCommandLine(int argc, char** argv);
-   void parseConfigFile(const resip::Data& filename);
+   virtual void printHelpText(int argc, char **argv) = 0;
 
    bool getConfigValue(const resip::Data& name, resip::Data &value);
    resip::Data getConfigData(const resip::Data& name, const resip::Data& defaultValue, bool useDefaultIfEmpty=false);
@@ -55,13 +57,13 @@
    typedef HashMultiMap<resip::Data, resip::Data> ConfigValuesMap;
    ConfigValuesMap mConfigValues;
 
+   resip::Data removePath(const resip::Data& fileAndPath);
+
    // Config filename from command line
    resip::Data mCmdLineConfigFilename;
 
 private:
    friend EncodeStream& operator<<(EncodeStream& strm, const ConfigParse& config);
-
-   int mSkipCount;
 };
 
 EncodeStream& operator<<(EncodeStream& strm, const ConfigParse& config);
diff -Nru resiprocate-1.8.4/rutil/dns/DnsStub.cxx resiprocate-1.8.5/rutil/dns/DnsStub.cxx
--- resiprocate-1.8.4/rutil/dns/DnsStub.cxx	2012-07-05 15:10:49.000000000 +0000
+++ resiprocate-1.8.5/rutil/dns/DnsStub.cxx	2012-08-08 12:49:23.000000000 +0000
@@ -797,6 +797,30 @@
 }
 
 void
+DnsStub::setEnumDomains(const std::map<Data,Data>& domains)
+{
+   SetEnumDomainsCommand* command = new SetEnumDomainsCommand(*this, domains);
+   mCommandFifo.add(command);
+
+   if (mAsyncProcessHandler)
+   {
+      mAsyncProcessHandler->handleProcessNotification();
+   }
+}
+
+const std::map<Data,Data>&
+DnsStub::getEnumDomains() const
+{
+   return mEnumDomains;
+}
+
+void
+DnsStub::doSetEnumDomains(const std::map<Data,Data>& domains)
+{
+   mEnumDomains = domains;
+}
+
+void
 DnsStub::clearDnsCache()
 {
    ClearDnsCacheCommand* command = new ClearDnsCacheCommand(*this);
diff -Nru resiprocate-1.8.4/rutil/dns/DnsStub.hxx resiprocate-1.8.5/rutil/dns/DnsStub.hxx
--- resiprocate-1.8.4/rutil/dns/DnsStub.hxx	2012-07-05 15:10:49.000000000 +0000
+++ resiprocate-1.8.5/rutil/dns/DnsStub.hxx	2012-08-08 12:49:23.000000000 +0000
@@ -149,6 +149,8 @@
       void removeResultTransform();
       void setEnumSuffixes(const std::vector<Data>& suffixes);
       const std::vector<Data>& getEnumSuffixes() const;
+      void setEnumDomains(const std::map<Data,Data>& domains);
+      const std::map<Data,Data>& getEnumDomains() const;
       void clearDnsCache();
       void logDnsCache();
       void getDnsCacheDump(std::pair<unsigned long, unsigned long> key, GetDnsCacheDumpHandler* handler);
@@ -315,6 +317,7 @@
       };
 
       void doSetEnumSuffixes(const std::vector<Data>& suffixes);
+      void doSetEnumDomains(const std::map<Data,Data>& domains);
 
       class SetEnumSuffixesCommand : public Command
       {
@@ -335,6 +338,25 @@
             std::vector<Data> mEnumSuffixes;
       };
 
+      class SetEnumDomainsCommand : public Command
+      {
+         public:
+            SetEnumDomainsCommand(DnsStub& stub,
+                                   const std::map<Data,Data>& domains)
+               : mStub(stub),
+                 mEnumDomains(domains)
+            {}
+            ~SetEnumDomainsCommand() {}
+            void execute()
+            {
+               mStub.doSetEnumDomains(mEnumDomains);
+            }
+
+         private:
+            DnsStub& mStub;
+            std::map<Data,Data> mEnumDomains;
+      };
+
       void doClearDnsCache();
 
       class ClearDnsCacheCommand : public Command
@@ -414,6 +436,7 @@
       std::set<Query*> mQueries;
 
       std::vector<Data> mEnumSuffixes; // where to do enum lookups
+      std::map<Data,Data> mEnumDomains;
 
       static int mDnsTimeout; // in seconds
       static int mDnsTries;
diff -Nru resiprocate-1.8.4/rutil/ParseBuffer.hxx resiprocate-1.8.5/rutil/ParseBuffer.hxx
--- resiprocate-1.8.4/rutil/ParseBuffer.hxx	2012-07-05 15:10:53.000000000 +0000
+++ resiprocate-1.8.5/rutil/ParseBuffer.hxx	2012-08-08 12:49:27.000000000 +0000
@@ -244,8 +244,8 @@
       UInt32 uInt32();
       UInt64 uInt64();
 
-      RESIP_DEPRECATED UInt64 unsignedLongLong(){return uInt64();} 
-      RESIP_DEPRECATED unsigned long unsignedInteger(){return uInt32();}
+      RESIP_DEPRECATED(UInt64 unsignedLongLong()){return uInt64();} 
+      RESIP_DEPRECATED(unsigned long unsignedInteger()){return uInt32();}
 
 #ifndef RESIP_FIXED_POINT		
       float floatVal();
------------------------------------------------------------------------
r9799 | dpocock | 2012-07-05 17:19:33 +0200 (Thu, 05 Jul 2012) | 1 line

release: update release branch for next in series, 1.8.5
------------------------------------------------------------------------
r9803 | sgodin | 2012-07-13 18:00:27 +0200 (Fri, 13 Jul 2012) | 6 lines

-repro config - disable TLS by default
-fix repro readme.txt - had old command line format stuff in it
-changes to repro windows installer:
 -Add repro.config
 -Add shortcut to repro.config on start menu
 -Add working directory to Repro shortcut so that config file is found
------------------------------------------------------------------------
r9832 | dpocock | 2012-08-04 20:27:33 +0200 (Sat, 04 Aug 2012) | 2 lines

Fix some 32/64 issues and an edge case where no ICE attributes are provided

------------------------------------------------------------------------
r9833 | dpocock | 2012-08-04 20:29:37 +0200 (Sat, 04 Aug 2012) | 24 lines

-some build fixes submitted by Xmly

ContactInstanceRecord.hxx
Use ULL suffix instead of UL. change ContactInstanceRecord.hxx:15,
     static const UInt64 NeverExpire = 0xFFFFFFFFFFFFFFFFUL; ->
     static const UInt64 NeverExpire = 0xFFFFFFFFFFFFFFFFULL;

      Reference links,
      http://gcc.gnu.org/onlinedocs/gcc/Long-Long.html


StackThread.hxx
This error happens when compiling StackThread.cxx.  gcc 3.2.2 is used.
In file included from StackThread.cxx:1:
../../resip/stack/StackThread.hxx:28: parse error before `&' token
StackThread.cxx:11: prototype for `
   resip::StackThread::StackThread(resip::SipStack&)' does not match any in
   class `! resip::StackThread'
Fix
     Using RESIP_DEPRECATED before constructor StackThread(SipStack& stack)  gives the compiler a surprise.
    Though there is no such compiling error with latest gcc, suggest fix it for backward compatibility. In stack/StackThread.hxx, change line
     RESIP_DEPRECATED StackThread(SipStack& stack) ->
     StackThread(SipStack& stack) RESIP_DEPRECATED

------------------------------------------------------------------------
r9834 | dpocock | 2012-08-04 20:30:34 +0200 (Sat, 04 Aug 2012) | 1 line

-added missing Config.h include - was not building properly with popt enabled
------------------------------------------------------------------------
r9835 | dpocock | 2012-08-04 20:32:00 +0200 (Sat, 04 Aug 2012) | 1 line

resip: correct assert() for ENUM lookups
------------------------------------------------------------------------
r9836 | dpocock | 2012-08-04 20:34:39 +0200 (Sat, 04 Aug 2012) | 1 line

repro: eliminate code that automatically adds localhost, machine name, etc to the Domains config variable
------------------------------------------------------------------------
r9837 | dpocock | 2012-08-04 20:37:03 +0200 (Sat, 04 Aug 2012) | 2 lines

resip: Make test for E.164 number (for ENUM use) more thorough.  Add logging to Uri ENUM logic

------------------------------------------------------------------------
r9839 | dpocock | 2012-08-05 00:32:19 +0200 (Sun, 05 Aug 2012) | 1 line

b2bua: update README.txt, include sample apps/basicB2BUA
------------------------------------------------------------------------
r9840 | fjoanis | 2012-08-06 06:08:41 +0200 (Mon, 06 Aug 2012) | 1 line

Merged fix from trunk (r9823) to prevent recursive InviteSessionReferExCommand commands
------------------------------------------------------------------------
r9851 | sgodin | 2012-08-06 19:12:25 +0200 (Mon, 06 Aug 2012) | 1 line

-2nd attempt at fix for RESIP_DEPRECATED macro - http://stackoverflow.com/questions/295120/c-mark-as-deprecated
------------------------------------------------------------------------
r9853 | dpocock | 2012-08-06 19:38:34 +0200 (Mon, 06 Aug 2012) | 1 line

resip, repro: backport changes to add the EnumDomains config option
------------------------------------------------------------------------
r9854 | dpocock | 2012-08-06 19:56:20 +0200 (Mon, 06 Aug 2012) | 1 line

resip, repro: backport changes to add the CommonNameMappings feature in repro (mapping CN to permitted SIP user IDs)
------------------------------------------------------------------------
r9855 | dpocock | 2012-08-06 20:08:50 +0200 (Mon, 06 Aug 2012) | 1 line

resip, repro: backport changes to enable any arbitrary peer to connect with mutual TLS without being challenged by DIGEST
------------------------------------------------------------------------
r9857 | dpocock | 2012-08-06 20:54:10 +0200 (Mon, 06 Aug 2012) | 1 line

apps/basicB2BUA: add headers to dist
------------------------------------------------------------------------
r9859 | sgodin | 2012-08-07 19:21:40 +0200 (Tue, 07 Aug 2012) | 1 line

-fix VS2010 build issues with scoping of socket API's
------------------------------------------------------------------------
r9860 | sgodin | 2012-08-07 19:24:40 +0200 (Tue, 07 Aug 2012) | 7 lines

-fixed issue there a virtual function (printHelpText) was being called from the ConfigParse constructor
 = was causing crashes if the user specified --help on the command line
 - removed command line parsing from constructor and created a new parseConfig method - this ensures the class is
   fully constructed before calling the virtual fn
-removed debug log statement that could get very large on a busy system in Proxy.cxx
-cleaned up helpText output on windows so that full doesn't print when arg[0] is used in help text
-added exception handling for command line parsing in reTurnServer
------------------------------------------------------------------------
r9862 | dpocock | 2012-08-07 20:40:36 +0200 (Tue, 07 Aug 2012) | 1 line

apps/sipdial: adapt for new ConfigParse API
------------------------------------------------------------------------
r9864 | dpocock | 2012-08-08 14:22:36 +0200 (Wed, 08 Aug 2012) | 1 line

repro: complete change to new ConfigParse API from r9858
------------------------------------------------------------------------
r9866 | dpocock | 2012-08-08 14:41:56 +0200 (Wed, 08 Aug 2012) | 1 line

release: update release branch for next in series, 1.8.6
------------------------------------------------------------------------

Reply to: