[asterisk-commits] russell: branch russell/chan_refcount r89501 - in /team/russell/chan_refcount...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Nov 21 13:51:03 CST 2007


Author: russell
Date: Wed Nov 21 13:51:02 2007
New Revision: 89501

URL: http://svn.digium.com/view/asterisk?view=rev&rev=89501
Log:
sync some more with trunk

Modified:
    team/russell/chan_refcount/   (props changed)
    team/russell/chan_refcount/CHANGES
    team/russell/chan_refcount/Makefile
    team/russell/chan_refcount/Makefile.moddir_rules
    team/russell/chan_refcount/Makefile.rules
    team/russell/chan_refcount/channels/chan_sip.c
    team/russell/chan_refcount/include/asterisk/srv.h
    team/russell/chan_refcount/main/channel.c
    team/russell/chan_refcount/main/db.c
    team/russell/chan_refcount/main/srv.c
    team/russell/chan_refcount/res/res_odbc.c

Propchange: team/russell/chan_refcount/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/russell/chan_refcount/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Nov 21 13:51:02 2007
@@ -1,1 +1,1 @@
-/trunk:1-88500
+/trunk:1-88750

Modified: team/russell/chan_refcount/CHANGES
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/CHANGES?view=diff&rev=89501&r1=89500&r2=89501
==============================================================================
--- team/russell/chan_refcount/CHANGES (original)
+++ team/russell/chan_refcount/CHANGES Wed Nov 21 13:51:02 2007
@@ -303,7 +303,7 @@
      channel in conjunction with the existing 'n' option for local channels.
   * Added support for reading the TOUCH_MONITOR_PREFIX channel variable.
      It allows you to configure a prefix for auto-monitor recordings.
-  * Added support for running your dialplan by writing one in lua.  See
+  * Added support for writing and running your dialplan in lua.  See
      configs/extensions.lua.sample for examples of how to do this.
  * Added a new channel driver, chan_unistim.  See doc/unistim.txt and
     configs/unistim.conf.sample for details.  This new channel driver allows

Modified: team/russell/chan_refcount/Makefile
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/Makefile?view=diff&rev=89501&r1=89500&r2=89501
==============================================================================
--- team/russell/chan_refcount/Makefile (original)
+++ team/russell/chan_refcount/Makefile Wed Nov 21 13:51:02 2007
@@ -293,16 +293,21 @@
   HAVEDOT=no
 endif
 
+# $(MAKE) is printed in several places, and we want it to be a
+# fixed size string. Define a variable whose name has also the
+# same size, so we can easily align text.
+ifeq ($(MAKE), gmake)
+	mK="gmake"
+else
+	mK=" make"
+endif
+
 all: _all
 	@echo " +--------- Asterisk Build Complete ---------+"  
 	@echo " + Asterisk has successfully been built, and +"  
 	@echo " + can be installed by running:              +"
 	@echo " +                                           +"
-ifeq ($(MAKE), gmake)
-	@echo " +               $(MAKE) install               +"  
-else
-	@echo " +               $(MAKE) install                +"  
-endif
+	@echo " +               $(mK) install               +"  
 	@echo " +-------------------------------------------+"  
 
 _all: cleantest $(SUBDIRS)
@@ -342,10 +347,14 @@
 main: $(filter-out main,$(MOD_SUBDIRS))
 
 $(MOD_SUBDIRS):
+	@echo "   [enter MOD_SUBDIR $@/]"
 	@ASTCFLAGS="$(MOD_SUBDIR_CFLAGS) $(ASTCFLAGS)" ASTLDFLAGS="$(ASTLDFLAGS)" AST_LIBS="$(AST_LIBS)" $(MAKE) --no-print-directory --no-builtin-rules -C $@ SUBDIR=$@ all
+	@echo "   [exit MOD_SUBDIR $@/]"
 
 $(OTHER_SUBDIRS):
+	@echo "   [enter SUBDIR $@/]"
 	@ASTCFLAGS="$(OTHER_SUBDIR_CFLAGS) $(ASTCFLAGS)" ASTLDFLAGS="$(ASTLDFLAGS)" AUDIO_LIBS="$(AUDIO_LIBS)" $(MAKE) --no-print-directory --no-builtin-rules -C $@ SUBDIR=$@ all
+	@echo "   [exit SUBDIR $@/]"
 
 defaults.h: makeopts
 	@build_tools/make_defaults_h > $@.tmp
@@ -514,22 +523,14 @@
 	@echo " + configuration files (overwriting any      +"
 	@echo " + existing config files), run:              +"  
 	@echo " +                                           +"
-ifeq ($(MAKE), gmake)
-	@echo " +               $(MAKE) samples               +"
-else
-	@echo " +               $(MAKE) samples                +"
-endif
+	@echo " +               $(mK) samples               +"
 	@echo " +                                           +"
 	@echo " +-----------------  or ---------------------+"
 	@echo " +                                           +"
 	@echo " + You can go ahead and install the asterisk +"
 	@echo " + program documentation now or later run:   +"
 	@echo " +                                           +"
-ifeq ($(MAKE), gmake)
-	@echo " +              $(MAKE) progdocs               +"
-else
-	@echo " +              $(MAKE) progdocs                +"
-endif
+	@echo " +              $(mK) progdocs               +"
 	@echo " +                                           +"
 	@echo " + **Note** This requires that you have      +"
 	@echo " + doxygen installed on your local system    +"
@@ -538,32 +539,42 @@
 
 upgrade: bininstall
 
+# XXX why *.adsi is installed first ?
 adsi:
-	mkdir -p $(DESTDIR)$(ASTETCDIR)
-	for x in configs/*.adsi; do \
-		if [ ! -f $(DESTDIR)$(ASTETCDIR)/$$x ]; then \
-			$(INSTALL) -m 644 $$x $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x` ; \
+	@echo Installing adsi config files...
+	@mkdir -p $(DESTDIR)$(ASTETCDIR)
+	@for x in configs/*.adsi; do \
+		dst="$(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x`" ; \
+		if [ -f $${dst} ] ; then \
+			echo "Overwriting $$x" ; \
+		else \
+			echo "Installing $$x" ; \
 		fi ; \
+		$(INSTALL) -m 644 $$x $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x` ; \
 	done
 
 samples: adsi
-	mkdir -p $(DESTDIR)$(ASTETCDIR)
-	for x in configs/*.sample; do \
-		if [ -f $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x .sample` ]; then \
+	@echo Installing other config files...
+	@mkdir -p $(DESTDIR)$(ASTETCDIR)
+	@for x in configs/*.sample; do \
+		dst="$(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x .sample`" ;	\
+		if [ -f $${dst} ]; then \
 			if [ "$(OVERWRITE)" = "y" ]; then \
-				if cmp -s $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x .sample` $$x ; then \
+				if cmp -s $${dst} $$x ; then \
 					echo "Config file $$x is unchanged"; \
 					continue; \
 				fi ; \
-				mv -f $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x .sample` $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x .sample`.old ; \
+				mv -f $${dst} $${dst}.old ; \
 			else \
 				echo "Skipping config file $$x"; \
 				continue; \
 			fi ;\
 		fi ; \
-		$(INSTALL) -m 644 $$x $(DESTDIR)$(ASTETCDIR)/`$(BASENAME) $$x .sample` ;\
+		echo "Installing file $$x"; \
+		$(INSTALL) -m 644 $$x $${dst} ;\
 	done
-	if [ "$(OVERWRITE)" = "y" ] || [ ! -f $(DESTDIR)$(ASTCONFPATH) ]; then \
+	@if [ "$(OVERWRITE)" = "y" ] || [ ! -f $(DESTDIR)$(ASTCONFPATH) ]; then \
+		echo "Creating asterisk.conf"; \
 		( \
 		echo "[directories]" ; \
 		echo "astetcdir => $(ASTETCDIR)" ; \
@@ -726,11 +737,7 @@
 	@echo " + directories, and logs, run the following  +"
 	@echo " + command:                                  +"
 	@echo " +                                           +"
-ifeq ($(MAKE), gmake)
-	@echo " +            $(MAKE) uninstall-all            +"  
-else
-	@echo " +            $(MAKE) uninstall-all             +"  
-endif
+	@echo " +            $(mK) uninstall-all            +"  
 	@echo " +-------------------------------------------+"  
 
 uninstall-all: _uninstall

Modified: team/russell/chan_refcount/Makefile.moddir_rules
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/Makefile.moddir_rules?view=diff&rev=89501&r1=89500&r2=89501
==============================================================================
--- team/russell/chan_refcount/Makefile.moddir_rules (original)
+++ team/russell/chan_refcount/Makefile.moddir_rules Wed Nov 21 13:51:02 2007
@@ -10,6 +10,13 @@
 # This program is free software, distributed under the terms of
 # the GNU General Public License
 #
+
+# Makefile rules for building modules.
+
+# In most cases, we set target-specific variables for certain targets
+# (remember that they apply recursively to prerequisites).
+# Also note that we can only set one variable per rule, so we have to
+# repeat the left hand side to set multiple variables.
 
 ifneq ($(findstring MALLOC_DEBUG,$(MENUSELECT_CFLAGS)),)
  ifeq ($(findstring astmm.h,$(ASTCFLAGS)),)
@@ -29,9 +36,14 @@
 
 comma:=,
 
-$(addsuffix .o,$(C_MODS)): ASTCFLAGS+=-DAST_MODULE=\"$*\" $(MENUSELECT_OPTS_$*:%=-D%) $(foreach dep,$(MENUSELECT_DEPENDS_$*),$(value $(dep)_INCLUDE))
-$(addsuffix .oo,$(CC_MODS)): ASTCFLAGS+=-DAST_MODULE=\"$*\" $(MENUSELECT_OPTS_$*:%=-D%) $(foreach dep,$(MENUSELECT_DEPENDS_$*),$(value $(dep)_INCLUDE))
+# Both C++ and C++ sources need their module name in AST_MODULE
+# We also pass whatever _INCLUDE list is generated by menuselect
+# (they are stored in file 'makeopts')
 
+$(addsuffix .oo,$(CC_MODS)) $(addsuffix .o,$(C_MODS)):	\
+	ASTCFLAGS+= -DAST_MODULE=\"$*\" $(MENUSELECT_OPTS_$*:%=-D%) $(foreach dep,$(MENUSELECT_DEPENDS_$*),$(value $(dep)_INCLUDE))
+
+# For loadable modules, pass _LIB and _LDFLAGS from menuselect.
 $(LOADABLE_MODS:%=%.so): ASTCFLAGS+=-fPIC
 $(LOADABLE_MODS:%=%.so): LIBS+=$(foreach dep,$(MENUSELECT_DEPENDS_$*),$(value $(dep)_LIB))
 $(LOADABLE_MODS:%=%.so): ASTLDFLAGS+=$(foreach dep,$(MENUSELECT_DEPENDS_$*),$(value $(dep)_LDFLAGS))

Modified: team/russell/chan_refcount/Makefile.rules
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/Makefile.rules?view=diff&rev=89501&r1=89500&r2=89501
==============================================================================
--- team/russell/chan_refcount/Makefile.rules (original)
+++ team/russell/chan_refcount/Makefile.rules Wed Nov 21 13:51:02 2007
@@ -11,6 +11,7 @@
 # the GNU General Public License
 #
 
+# Rules for various build phases.
 # Each command is preceded by a short comment on what to do.
 # Prefixing one or the other with @\# or @ or nothing makes the desired
 # behaviour. ECHO_PREFIX prefixes the comment, CMD_PREFIX prefixes the command.
@@ -19,52 +20,48 @@
 
 .PHONY: dist-clean
 
+# extra cflags to build dependencies. Recursively expanded.
+MAKE_DEPS= -MMD -MT $@ -MF .$(subst /,_,$@).d -MP
+
 ifeq ($(NOISY_BUILD),)
-   ECHO_PREFIX=@
-   CMD_PREFIX=@
+    ECHO_PREFIX=@
+    CMD_PREFIX=@
 else
-   ECHO_PREFIX=@\# 
-   CMD_PREFIX=
+    ECHO_PREFIX=@\#
+    CMD_PREFIX=
 endif
 
 ifeq ($(findstring DONT_OPTIMIZE,$(MENUSELECT_CFLAGS)),)
-# More GSM codec optimization
-# Uncomment to enable MMXTM optimizations for x86 architecture CPU's
-# which support MMX instructions.  This should be newer pentiums,
-# ppro's, etc, as well as the AMD K6 and K7.  
-#K6OPT=-DK6OPT
+    # More GSM codec optimization
+    # Uncomment to enable MMXTM optimizations for x86 architecture CPU's
+    # which support MMX instructions.  This should be newer pentiums,
+    # ppro's, etc, as well as the AMD K6 and K7.  
+    #K6OPT=-DK6OPT
 
-OPTIMIZE?=-O6
-ASTCFLAGS+=$(OPTIMIZE)
+    OPTIMIZE?=-O6
+    ASTCFLAGS+=$(OPTIMIZE)
 endif
 
+# build rules for various targets
 %.o: %.c
 	$(ECHO_PREFIX) echo "   [CC] $< -> $@"
-	$(CMD_PREFIX) $(CC) -o $@ -c $< $(PTHREAD_CFLAGS) $(ASTCFLAGS) -MMD -MT $@ -MF .$(subst /,_,$@).d -MP
+	$(CMD_PREFIX) $(CC) -o $@ -c $< $(PTHREAD_CFLAGS) $(ASTCFLAGS) $(MAKE_DEPS)
 
 %.o: %.i
-	$(ECHO_PREFIX) echo "   [CC] $< -> $@"
-ifeq ($(AST_DEVMODE),yes)
-	$(CMD_PREFIX) $(CC) -o $@ -c $< $(PTHREAD_CFLAGS) $(ASTCFLAGS) -MMD -MT $@ -MF .$(subst /,_,$@).d -MP
-else
-	$(CMD_PREFIX) $(CC) -o $@ -c $< $(PTHREAD_CFLAGS) $(ASTCFLAGS)
-endif
+	$(ECHO_PREFIX) echo "   [CCi] $< -> $@"
+	$(CMD_PREFIX) $(CC) -o $@ -c $< $(PTHREAD_CFLAGS) $(ASTCFLAGS) $(MAKE_DEPS)
 
 %.i: %.c
-	$(ECHO_PREFIX) echo "   [CC] $< -> $@"
-ifeq ($(AST_DEVMODE),yes)
-	$(CMD_PREFIX) $(CC) -o $@ -E $< $(PTHREAD_CFLAGS) $(ASTCFLAGS) -MMD -MT $@ -MF .$(subst /,_,$@).d -MP
-else
-	$(CMD_PREFIX) $(CC) -o $@ -E $< $(PTHREAD_CFLAGS) $(ASTCFLAGS)
-endif
+	$(ECHO_PREFIX) echo "   [CPP] $< -> $@"
+	$(CMD_PREFIX) $(CC) -o $@ -E $< $(PTHREAD_CFLAGS) $(ASTCFLAGS) $(MAKE_DEPS)
 
 %.o: %.s
 	$(ECHO_PREFIX) echo "   [AS] $< -> $@"
-	$(CMD_PREFIX) $(CC) -o $@ -c $< $(PTHREAD_CFLAGS) $(ASTCFLAGS) -MMD -MT $@ -MF .$(subst /,_,$@).d -MP
+	$(CMD_PREFIX) $(CC) -o $@ -c $< $(PTHREAD_CFLAGS) $(ASTCFLAGS) $(MAKE_DEPS)
 
 %.oo: %.cc
 	$(ECHO_PREFIX) echo "   [CXX] $< -> $@"
-	$(CMD_PREFIX) $(CXX) -o $@ -c $< $(PTHREAD_CFLAGS) $(filter-out -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations,$(ASTCFLAGS)) -MMD -MT $@ -MF .$(subst /,_,$@).d -MP
+	$(CMD_PREFIX) $(CXX) -o $@ -c $< $(PTHREAD_CFLAGS) $(filter-out -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations,$(ASTCFLAGS)) $(MAKE_DEPS)
 
 %.c: %.y
 	$(ECHO_PREFIX) echo "   [BISON] $< -> $@"

Modified: team/russell/chan_refcount/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/channels/chan_sip.c?view=diff&rev=89501&r1=89500&r2=89501
==============================================================================
--- team/russell/chan_refcount/channels/chan_sip.c (original)
+++ team/russell/chan_refcount/channels/chan_sip.c Wed Nov 21 13:51:02 2007
@@ -6091,6 +6091,7 @@
 			sip_peer_hold(p, FALSE);
 		ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
 	} else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) {
+		int already_on_hold = ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD);
 		ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 
 				       S_OR(p->mohsuggest, NULL),
 				       !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
@@ -6114,7 +6115,7 @@
 			ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
 		else
 			ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
-		if (global_notifyhold)
+		if (global_notifyhold && !already_on_hold)
 			sip_peer_hold(p, TRUE);
 	}
 	
@@ -18338,6 +18339,7 @@
 	internip = bindaddr;
 	if (ast_find_ourip(&internip.sin_addr, bindaddr)) {
 		ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
+		ast_config_destroy(cfg);
 		return 0;
 	}
 	ast_mutex_lock(&netlock);
@@ -18349,6 +18351,7 @@
 		sipsock = socket(AF_INET, SOCK_DGRAM, 0);
 		if (sipsock < 0) {
 			ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
+			ast_config_destroy(cfg);
 			return -1;
 		} else {
 			/* Allow SIP clients on the same host to access us: */

Modified: team/russell/chan_refcount/include/asterisk/srv.h
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/include/asterisk/srv.h?view=diff&rev=89501&r1=89500&r2=89501
==============================================================================
--- team/russell/chan_refcount/include/asterisk/srv.h (original)
+++ team/russell/chan_refcount/include/asterisk/srv.h Wed Nov 21 13:51:02 2007
@@ -26,9 +26,10 @@
 /*!
   \file srv.h
   \brief Support for DNS SRV records, used in to locate SIP services.
-  \note Note: The Asterisk DNS SRV record support is broken, it only
-	supports the first DNS SRV record and will give no load 
-	balancing or failover support.
+  \note Note: This SRV record support is very minimal; it will only
+        return the first (lowest priority) answer that is received, and
+	has no provisions for the 'weight' elements of the records or
+	retrying if the first returned result fails.
 */
 
 /*! Lookup entry in SRV records Returns 1 if found, 0 if not found, -1 on hangup 

Modified: team/russell/chan_refcount/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/main/channel.c?view=diff&rev=89501&r1=89500&r2=89501
==============================================================================
--- team/russell/chan_refcount/main/channel.c (original)
+++ team/russell/chan_refcount/main/channel.c Wed Nov 21 13:51:02 2007
@@ -3559,16 +3559,38 @@
 	original->tech_pvt = clone->tech_pvt;
 	clone->tech_pvt = t_pvt;
 
-	/* Swap the readq's */
-	cur = AST_LIST_FIRST(&original->readq);
-	AST_LIST_HEAD_SET_NOLOCK(&original->readq, AST_LIST_FIRST(&clone->readq));
-	AST_LIST_HEAD_SET_NOLOCK(&clone->readq, cur);
-
 	/* Swap the alertpipes */
 	for (i = 0; i < 2; i++) {
 		x = original->alertpipe[i];
 		original->alertpipe[i] = clone->alertpipe[i];
 		clone->alertpipe[i] = x;
+	}
+
+	/* 
+	 * Swap the readq's.  The end result should be this:
+	 *
+	 *  1) All frames should be on the new (original) channel.
+	 *  2) Any frames that were already on the new channel before this
+	 *     masquerade need to be at the end of the readq, after all of the
+	 *     frames on the old (clone) channel.
+	 *  3) The alertpipe needs to get poked for every frame that was already
+	 *     on the new channel, since we are now using the alert pipe from the
+	 *     old (clone) channel.
+	 */
+	{
+		AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
+		AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
+
+		AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
+		AST_LIST_APPEND_LIST(&original->readq, &clone->readq, frame_list);
+
+		while ((cur = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
+			AST_LIST_INSERT_TAIL(&original->readq, cur, frame_list);
+			if (original->alertpipe[1] > -1) {
+				int poke = 0;
+				write(original->alertpipe[1], &poke, sizeof(poke));
+			}
+		}
 	}
 
 	/* Swap the raw formats */
@@ -3579,26 +3601,7 @@
 	original->rawwriteformat = clone->rawwriteformat;
 	clone->rawwriteformat = x;
 
-	/* Save any pending frames on both sides.  Start by counting
-	 * how many we're going to need... */
-	x = 0;
-	if (original->alertpipe[1] > -1) {
-		AST_LIST_TRAVERSE(&clone->readq, cur, frame_list)
-			x++;
-	}
-
-	/* If we had any, prepend them to the ones already in the queue, and 
-	 * load up the alertpipe */
-	if (AST_LIST_FIRST(&clone->readq)) {
-		AST_LIST_INSERT_TAIL(&clone->readq, AST_LIST_FIRST(&original->readq), frame_list);
-		AST_LIST_HEAD_SET_NOLOCK(&original->readq, AST_LIST_FIRST(&clone->readq));
-		AST_LIST_HEAD_SET_NOLOCK(&clone->readq, NULL);
-		for (i = 0; i < x; i++)
-			write(original->alertpipe[1], &x, sizeof(x));
-	}
-	
 	clone->_softhangup = AST_SOFTHANGUP_DEV;
-
 
 	/* And of course, so does our current state.  Note we need not
 	   call ast_setstate since the event manager doesn't really consider
@@ -3645,8 +3648,7 @@
 
 	/* Move data stores over */
 	if (AST_LIST_FIRST(&clone->datastores))
-                AST_LIST_INSERT_TAIL(&original->datastores, AST_LIST_FIRST(&clone->datastores), entry);
-	AST_LIST_HEAD_INIT_NOLOCK(&clone->datastores);
+		AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry);
 
 	clone_variables(original, clone);
 	/* Presense of ADSI capable CPE follows clone */

Modified: team/russell/chan_refcount/main/db.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/main/db.c?view=diff&rev=89501&r1=89500&r2=89501
==============================================================================
--- team/russell/chan_refcount/main/db.c (original)
+++ team/russell/chan_refcount/main/db.c Wed Nov 21 13:51:02 2007
@@ -53,10 +53,6 @@
 #include "asterisk/manager.h"
 #include "db1-ast/include/db.h"
 
-#ifdef __CYGWIN__
-#define dbopen __dbopen
-#endif
-
 static DB *astdb;
 AST_MUTEX_DEFINE_STATIC(dblock);
 

Modified: team/russell/chan_refcount/main/srv.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/main/srv.c?view=diff&rev=89501&r1=89500&r2=89501
==============================================================================
--- team/russell/chan_refcount/main/srv.c (original)
+++ team/russell/chan_refcount/main/srv.c Wed Nov 21 13:51:02 2007
@@ -52,90 +52,196 @@
 #include "asterisk/dns.h"
 #include "asterisk/options.h"
 #include "asterisk/utils.h"
+#include "asterisk/linkedlists.h"
 
 #ifdef __APPLE__
 #undef T_SRV
 #define T_SRV 33
 #endif
 
-struct srv {
+struct srv_entry {
 	unsigned short priority;
 	unsigned short weight;
-	unsigned short portnum;
-} __attribute__ ((__packed__));
-
-static int parse_srv(char *host, int hostlen, int *portno, unsigned char *answer, int len, unsigned char *msg)
-{
+	unsigned short port;
+	unsigned int weight_sum;
+	AST_LIST_ENTRY(srv_entry) list;
+	char host[1];
+};
+
+struct srv_context {
+	unsigned int have_weights:1;
+	AST_LIST_HEAD_NOLOCK(srv_entries, srv_entry) entries;
+};
+
+static int parse_srv(unsigned char *answer, int len, unsigned char *msg, struct srv_entry **result)
+{
+	struct srv {
+		unsigned short priority;
+		unsigned short weight;
+		unsigned short port;
+	} __attribute__ ((__packed__)) *srv = (struct srv *) answer;
+
 	int res = 0;
-	struct srv *srv = (struct srv *)answer;
 	char repl[256] = "";
-
-	if (len < sizeof(struct srv)) {
-		printf("Length too short\n");
-		return -1;
-	}
-	answer += sizeof(struct srv);
-	len -= sizeof(struct srv);
-
-	if ((res = dn_expand(msg, answer + len, answer, repl, sizeof(repl) - 1)) < 0) {
+	struct srv_entry *entry;
+
+	if (len < sizeof(*srv))
+		return -1;
+
+	answer += sizeof(*srv);
+	len -= sizeof(*srv);
+
+	if ((res = dn_expand(msg, answer + len, answer, repl, sizeof(repl) - 1)) <= 0) {
 		ast_log(LOG_WARNING, "Failed to expand hostname\n");
 		return -1;
 	}
-	if (res && strcmp(repl, ".")) {
-		ast_verb(3, "parse_srv: SRV mapped to host %s, port %d\n", repl, ntohs(srv->portnum));
-		if (host) {
-			ast_copy_string(host, repl, hostlen);
-			host[hostlen-1] = '\0';
+
+	/* the magic value "." for the target domain means that this service
+	   is *NOT* available at the domain we searched */
+	if (!strcmp(repl, "."))
+		return -1;
+
+	if (!(entry = ast_calloc(1, sizeof(*entry) + strlen(repl))))
+		return -1;
+	
+	entry->priority = ntohs(srv->priority);
+	entry->weight = ntohs(srv->weight);
+	entry->port = ntohs(srv->port);
+	strcpy(entry->host, repl);
+
+	*result = entry;
+	
+	return 0;
+}
+
+static int srv_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
+{
+	struct srv_context *c = (struct srv_context *) context;
+	struct srv_entry *entry = NULL;
+	struct srv_entry *current;
+
+	if (parse_srv(answer, len, fullanswer, &entry))
+		return -1;
+
+	if (entry->weight)
+		c->have_weights = 1;
+
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&c->entries, current, list) {
+		/* insert this entry just before the first existing
+		   entry with a higher priority */
+		if (current->priority <= entry->priority)
+			continue;
+
+		AST_LIST_INSERT_BEFORE_CURRENT(&c->entries, entry, list);
+		entry = NULL;
+		break;
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+
+	/* if we didn't find a place to insert the entry before an existing
+	   entry, then just add it to the end */
+	if (entry)
+		AST_LIST_INSERT_TAIL(&c->entries, entry, list);
+
+	return 0;
+}
+
+/* Do the bizarre SRV record weight-handling algorithm
+   involving sorting and random number generation...
+
+   See RFC 2782 if you want know why this code does this
+*/
+static void process_weights(struct srv_context *context)
+{
+	struct srv_entry *current;
+	struct srv_entries newlist = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
+
+	while (AST_LIST_FIRST(&context->entries)) {
+		unsigned int random_weight;
+		unsigned int weight_sum;
+		unsigned short cur_priority = AST_LIST_FIRST(&context->entries)->priority;
+		struct srv_entries temp_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
+		weight_sum = 0;
+
+		AST_LIST_TRAVERSE_SAFE_BEGIN(&context->entries, current, list) {
+			if (current->priority != cur_priority)
+				break;
+
+			AST_LIST_REMOVE_CURRENT(&context->entries, list);
+			AST_LIST_INSERT_TAIL(&temp_list, current, list);
 		}
-		if (portno)
-			*portno = ntohs(srv->portnum);
-		return 0;
-	}
-	return -1;
-}
-
-struct srv_context {
-	char *host;
-	int hostlen;
-	int *port;
-};
-
-static int srv_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
-{
-	struct srv_context *c = (struct srv_context *)context;
-
-	if (parse_srv(c->host, c->hostlen, c->port, answer, len, fullanswer)) {
-		ast_log(LOG_WARNING, "Failed to parse srv\n");
-		return -1;
-	}
-
-	if (!ast_strlen_zero(c->host))
-		return 1;
-
-	return 0;
+		AST_LIST_TRAVERSE_SAFE_END;
+
+		while (AST_LIST_FIRST(&temp_list)) {
+			weight_sum = 0;
+			AST_LIST_TRAVERSE(&temp_list, current, list)
+				current->weight_sum = weight_sum += current->weight;
+
+			/* if all the remaining entries have weight == 0,
+			   then just append them to the result list and quit */
+			if (weight_sum == 0) {
+				AST_LIST_APPEND_LIST(&newlist, &temp_list, list);
+				break;
+			}
+
+			random_weight = 1 + (unsigned int) ((float) weight_sum * (ast_random() / ((float) RAND_MAX + 1.0)));
+
+			AST_LIST_TRAVERSE_SAFE_BEGIN(&temp_list, current, list) {
+				if (current->weight < random_weight)
+					continue;
+
+				AST_LIST_REMOVE_CURRENT(&temp_list, list);
+				AST_LIST_INSERT_TAIL(&newlist, current, list);
+			}
+			AST_LIST_TRAVERSE_SAFE_END;
+		}
+
+	}
+
+	/* now that the new list has been ordered,
+	   put it in place */
+
+	AST_LIST_APPEND_LIST(&context->entries, &newlist, list);
 }
 
 int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service)
 {
-	struct srv_context context;
+	struct srv_context context = { .entries = AST_LIST_HEAD_NOLOCK_INIT_VALUE };
+	struct srv_entry *current;
 	int ret;
 
-	context.host = host;
-	context.hostlen = hostlen;
-	context.port = port;
-
 	if (chan && ast_autoservice_start(chan) < 0)
 		return -1;
 
 	ret = ast_search_dns(&context, service, C_IN, T_SRV, srv_callback);
+
+	if (context.have_weights)
+		process_weights(&context);
 
 	if (chan)
 		ret |= ast_autoservice_stop(chan);
 
-	if (ret <= 0) {
+	/* TODO: there could be a "." entry in the returned list of
+	   answers... if so, this requires special handling */
+
+	/* the list of entries will be sorted in the proper selection order
+	   already, so we just need the first one (if any) */
+
+	if ((ret > 0) && (current = AST_LIST_REMOVE_HEAD(&context.entries, list))) {
+		ast_copy_string(host, current->host, hostlen);
+		*port = current->port;
+		ast_free(current);
+		if (option_verbose > 3) {
+			ast_verbose(VERBOSE_PREFIX_3 "ast_get_srv: SRV lookup for '%s' mapped to host %s, port %d\n",
+				    service, host, *port);
+		}
+	} else {
 		host[0] = '\0';
 		*port = -1;
-		return ret;
-	}
+	}
+
+	while ((current = AST_LIST_REMOVE_HEAD(&context.entries, list)))
+		ast_free(current);
+
 	return ret;
 }

Modified: team/russell/chan_refcount/res/res_odbc.c
URL: http://svn.digium.com/view/asterisk/team/russell/chan_refcount/res/res_odbc.c?view=diff&rev=89501&r1=89500&r2=89501
==============================================================================
--- team/russell/chan_refcount/res/res_odbc.c (original)
+++ team/russell/chan_refcount/res/res_odbc.c Wed Nov 21 13:51:02 2007
@@ -379,7 +379,7 @@
 				ast_cli(a->fd, "  Pooled: Yes\n  Limit:  %d\n  Connections in use: %d\n", class->limit, class->count);
 
 				AST_LIST_TRAVERSE(&(class->odbc_obj), current, list) {
-					ast_cli(a->fd, "    - Connection %d: %s\n", ++count, current->up && ast_odbc_sanity_check(current) ? "Connected" : "Disconnected");
+					ast_cli(a->fd, "    - Connection %d: %s\n", ++count, current->used ? "in use" : current->up && ast_odbc_sanity_check(current) ? "connected" : "disconnected");
 				}
 			} else {
 				/* Should only ever be one of these */




More information about the asterisk-commits mailing list