[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