Merge lp:~davewalker/ubuntu/lucid/asterisk/lp605358 into lp:ubuntu/lucid/asterisk

Proposed by Dave Walker
Status: Merged
Merge reported by: Dave Walker
Merged at revision: not available
Proposed branch: lp:~davewalker/ubuntu/lucid/asterisk/lp605358
Merge into: lp:ubuntu/lucid/asterisk
Diff against target: 1432 lines (+1252/-13)
12 files modified
.pc/.quilt_patches (+1/-0)
.pc/.quilt_series (+1/-0)
.pc/applied-patches (+1/-0)
.pc/dnsmgr-A-SRV-handling/include/asterisk/dnsmgr.h (+105/-0)
.pc/dnsmgr-A-SRV-handling/main/acl.c (+541/-0)
.pc/dnsmgr-A-SRV-handling/main/dnsmgr.c (+439/-0)
debian/changelog (+8/-0)
debian/patches/dnsmgr-A-SRV-handling (+132/-0)
debian/patches/series (+1/-0)
include/asterisk/dnsmgr.h (+4/-3)
main/acl.c (+1/-0)
main/dnsmgr.c (+18/-10)
To merge this branch: bzr merge lp:~davewalker/ubuntu/lucid/asterisk/lp605358
Reviewer Review Type Date Requested Status
Ubuntu Stable Release Updates Team Pending
Ubuntu Sponsors Pending
Review via email: mp+29860@code.launchpad.net

Description of the change

asterisk (1:1.6.2.5-0ubuntu1.1) lucid-proposed; urgency=low

  * debian/patches/dnsmgr-A-SRV-handling: Resolve handling of A and
    SRV record changes and problem with multiple A/SRV records returned.
    Patch based on Asterisk project's upstream patch. (LP: #605358)

 -- Dave Walker (Daviey) <email address hidden> Wed, 14 Jul 2010 11:40:55 +0100

SRU:-
 IMPACT: New users or users upgrading to Lucid, who use a provider that has multiple A/SRV records, after a short amount of time will not be able to make outgoing calls.
 FIX: Patch derived from upstream asterisk addresses this issue with better dnsmgr handling
 TEST CASE: Install asterisk, set up a peer using multiple A or SRV records, observe:
   "[Jul 14 12:07:57] WARNING[25721]: chan_sip.c:3581 __sip_xmit: sip_xmit of 0xb9bdb680 (len 536) to X.X.X.X:5060 returned -1: Address family not supported by protocol", and therefore outgoing calls fail.
 Notes: Applied in current upstream trunk and stable, and therefore will be in Maverick in a forthcoming merge.

To post a comment you must log in.
58. By Dave Walker

debian/changelog: Removed .patch extension from new patch

59. By Dave Walker

Added .pc quilt meta files for completness

Revision history for this message
Dave Walker (davewalker) wrote :

Merged, uploaded etc - marking as such.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.pc/.quilt_patches'
2--- .pc/.quilt_patches 1970-01-01 00:00:00 +0000
3+++ .pc/.quilt_patches 2010-07-16 10:16:00 +0000
4@@ -0,0 +1,1 @@
5+debian/patches
6
7=== added file '.pc/.quilt_series'
8--- .pc/.quilt_series 1970-01-01 00:00:00 +0000
9+++ .pc/.quilt_series 2010-07-16 10:16:00 +0000
10@@ -0,0 +1,1 @@
11+series
12
13=== added file '.pc/allow-tilde-destdir/.timestamp'
14=== modified file '.pc/applied-patches'
15--- .pc/applied-patches 2010-03-02 10:00:03 +0000
16+++ .pc/applied-patches 2010-07-16 10:16:00 +0000
17@@ -11,3 +11,4 @@
18 dahdi_ptmp_nt
19 dahdi_pri_debug_spannums
20 sound_files
21+dnsmgr-A-SRV-handling
22
23=== added file '.pc/astgenkey-security/.timestamp'
24=== added file '.pc/dahdi-fxsks-hookstate/.timestamp'
25=== added file '.pc/dahdi_pri_debug_spannums/.timestamp'
26=== added file '.pc/dahdi_ptmp_nt/.timestamp'
27=== added directory '.pc/dnsmgr-A-SRV-handling'
28=== added file '.pc/dnsmgr-A-SRV-handling/.timestamp'
29=== added directory '.pc/dnsmgr-A-SRV-handling/include'
30=== added directory '.pc/dnsmgr-A-SRV-handling/include/asterisk'
31=== added file '.pc/dnsmgr-A-SRV-handling/include/asterisk/dnsmgr.h'
32--- .pc/dnsmgr-A-SRV-handling/include/asterisk/dnsmgr.h 1970-01-01 00:00:00 +0000
33+++ .pc/dnsmgr-A-SRV-handling/include/asterisk/dnsmgr.h 2010-07-16 10:16:00 +0000
34@@ -0,0 +1,105 @@
35+/*
36+ * Asterisk -- An open source telephony toolkit.
37+ *
38+ * Copyright (C) 1999 - 2005, Digium, Inc.
39+ *
40+ * Kevin P. Fleming <kpfleming@digium.com>
41+ *
42+ * See http://www.asterisk.org for more information about
43+ * the Asterisk project. Please do not directly contact
44+ * any of the maintainers of this project for assistance;
45+ * the project provides a web site, mailing lists and IRC
46+ * channels for your use.
47+ *
48+ * This program is free software, distributed under the terms of
49+ * the GNU General Public License Version 2. See the LICENSE file
50+ * at the top of the source tree.
51+ */
52+
53+/*! \file
54+ * \brief Background DNS update manager
55+ */
56+
57+#ifndef _ASTERISK_DNSMGR_H
58+#define _ASTERISK_DNSMGR_H
59+
60+#if defined(__cplusplus) || defined(c_plusplus)
61+extern "C" {
62+#endif
63+
64+#include "asterisk/network.h"
65+#include "asterisk/srv.h"
66+
67+/*!
68+ * \brief A DNS manager entry
69+ *
70+ * This is an opaque type.
71+ */
72+struct ast_dnsmgr_entry;
73+
74+/*!
75+ * \brief Allocate a new DNS manager entry
76+ *
77+ * \param name the hostname
78+ * \param result where the DNS manager should store the IP address as it refreshes it.
79+ * it.
80+ *
81+ * This function allocates a new DNS manager entry object, and fills it with the
82+ * provided hostname and IP address. This function does not force an initial lookup
83+ * of the IP address. So, generally, this should be used when the initial address
84+ * is already known.
85+ *
86+ * \return a DNS manager entry
87+ * \version 1.6.1 result changed from struct in_addr to struct sockaddr_in to store port number
88+ */
89+struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct sockaddr_in *result, const char *service);
90+
91+/*!
92+ * \brief Free a DNS manager entry
93+ *
94+ * \param entry the DNS manager entry to free
95+ *
96+ * \return nothing
97+ */
98+void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry);
99+
100+/*!
101+ * \brief Allocate and initialize a DNS manager entry
102+ *
103+ * \param name the hostname
104+ * \param result where to store the IP address as the DNS manager refreshes it
105+ * \param dnsmgr Where to store the allocate DNS manager entry
106+ *
107+ * This function allocates a new DNS manager entry object, and fills it with
108+ * the provided hostname and IP address. This function _does_ force an initial
109+ * lookup, so it may block for some period of time.
110+ *
111+ * \retval 0 success
112+ * \retval non-zero failure
113+ * \version 1.6.1 result changed from struct in_addr to struct aockaddr_in to store port number
114+ */
115+int ast_dnsmgr_lookup(const char *name, struct sockaddr_in *result, struct ast_dnsmgr_entry **dnsmgr, const char *service);
116+
117+/*!
118+ * \brief Force a refresh of a dnsmgr entry
119+ *
120+ * \retval non-zero if the result is different than the previous result
121+ * \retval zero if the result is the same as the previous result
122+ */
123+int ast_dnsmgr_refresh(struct ast_dnsmgr_entry *entry);
124+
125+/*!
126+ * \brief Check is see if a dnsmgr entry has changed
127+ *
128+ * \retval non-zero if the dnsmgr entry has changed since the last call to
129+ * this function
130+ * \retval zero if the dnsmgr entry has not changed since the last call to
131+ * this function
132+ */
133+int ast_dnsmgr_changed(struct ast_dnsmgr_entry *entry);
134+
135+#if defined(__cplusplus) || defined(c_plusplus)
136+}
137+#endif /* c_plusplus */
138+
139+#endif /* ASTERISK_DNSMGR_H */
140
141=== added directory '.pc/dnsmgr-A-SRV-handling/main'
142=== added file '.pc/dnsmgr-A-SRV-handling/main/acl.c'
143--- .pc/dnsmgr-A-SRV-handling/main/acl.c 1970-01-01 00:00:00 +0000
144+++ .pc/dnsmgr-A-SRV-handling/main/acl.c 2010-07-16 10:16:00 +0000
145@@ -0,0 +1,541 @@
146+/*
147+ * Asterisk -- An open source telephony toolkit.
148+ *
149+ * Copyright (C) 1999 - 2006, Digium, Inc.
150+ *
151+ * Mark Spencer <markster@digium.com>
152+ *
153+ * See http://www.asterisk.org for more information about
154+ * the Asterisk project. Please do not directly contact
155+ * any of the maintainers of this project for assistance;
156+ * the project provides a web site, mailing lists and IRC
157+ * channels for your use.
158+ *
159+ * This program is free software, distributed under the terms of
160+ * the GNU General Public License Version 2. See the LICENSE file
161+ * at the top of the source tree.
162+ */
163+
164+/*! \file
165+ *
166+ * \brief Various sorts of access control
167+ *
168+ * \author Mark Spencer <markster@digium.com>
169+ */
170+
171+#include "asterisk.h"
172+
173+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 248849 $")
174+
175+#include "asterisk/network.h"
176+
177+#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__Darwin__)
178+#include <fcntl.h>
179+#include <net/route.h>
180+#endif
181+
182+#if defined(SOLARIS)
183+#include <sys/sockio.h>
184+#include <net/if.h>
185+#elif defined(HAVE_GETIFADDRS)
186+#include <ifaddrs.h>
187+#endif
188+
189+#include "asterisk/acl.h"
190+#include "asterisk/channel.h"
191+#include "asterisk/utils.h"
192+#include "asterisk/lock.h"
193+#include "asterisk/srv.h"
194+
195+#if (!defined(SOLARIS) && !defined(HAVE_GETIFADDRS))
196+static int get_local_address(struct in_addr *ourip)
197+{
198+ return -1;
199+}
200+#else
201+static void score_address(const struct sockaddr_in *sin, struct in_addr *best_addr, int *best_score)
202+{
203+ const char *address;
204+ int score;
205+
206+ address = ast_inet_ntoa(sin->sin_addr);
207+
208+ /* RFC 1700 alias for the local network */
209+ if (address[0] == '0') {
210+ score = -25;
211+ /* RFC 1700 localnet */
212+ } else if (strncmp(address, "127", 3) == 0) {
213+ score = -20;
214+ /* RFC 1918 non-public address space */
215+ } else if (strncmp(address, "10.", 3) == 0) {
216+ score = -5;
217+ /* RFC 1918 non-public address space */
218+ } else if (strncmp(address, "172", 3) == 0) {
219+ /* 172.16.0.0 - 172.19.255.255, but not 172.160.0.0 - 172.169.255.255 */
220+ if (address[4] == '1' && address[5] >= '6' && address[6] == '.') {
221+ score = -5;
222+ /* 172.20.0.0 - 172.29.255.255, but not 172.200.0.0 - 172.255.255.255 nor 172.2.0.0 - 172.2.255.255 */
223+ } else if (address[4] == '2' && address[6] == '.') {
224+ score = -5;
225+ /* 172.30.0.0 - 172.31.255.255 */
226+ } else if (address[4] == '3' && address[5] <= '1') {
227+ score = -5;
228+ /* All other 172 addresses are public */
229+ } else {
230+ score = 0;
231+ }
232+ /* RFC 2544 Benchmark test range (198.18.0.0 - 198.19.255.255, but not 198.180.0.0 - 198.199.255.255) */
233+ } else if (strncmp(address, "198.1", 5) == 0 && address[5] >= '8' && address[6] == '.') {
234+ score = -10;
235+ /* RFC 1918 non-public address space */
236+ } else if (strncmp(address, "192.168", 7) == 0) {
237+ score = -5;
238+ /* RFC 3330 Zeroconf network */
239+ } else if (strncmp(address, "169.254", 7) == 0) {
240+ /*!\note Better score than a test network, but not quite as good as RFC 1918
241+ * address space. The reason is that some Linux distributions automatically
242+ * configure a Zeroconf address before trying DHCP, so we want to prefer a
243+ * DHCP lease to a Zeroconf address.
244+ */
245+ score = -10;
246+ /* RFC 3330 Test network */
247+ } else if (strncmp(address, "192.0.2.", 8) == 0) {
248+ score = -15;
249+ /* Every other address should be publically routable */
250+ } else {
251+ score = 0;
252+ }
253+
254+ if (score > *best_score) {
255+ *best_score = score;
256+ memcpy(best_addr, &sin->sin_addr, sizeof(*best_addr));
257+ }
258+}
259+
260+static int get_local_address(struct in_addr *ourip)
261+{
262+ int s, res = -1;
263+#ifdef SOLARIS
264+ struct lifreq *ifr = NULL;
265+ struct lifnum ifn;
266+ struct lifconf ifc;
267+ struct sockaddr_in *sa;
268+ char *buf = NULL;
269+ int bufsz, x;
270+#endif /* SOLARIS */
271+#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
272+ struct ifaddrs *ifap, *ifaphead;
273+ int rtnerr;
274+ const struct sockaddr_in *sin;
275+#endif /* BSD_OR_LINUX */
276+ struct in_addr best_addr;
277+ int best_score = -100;
278+ memset(&best_addr, 0, sizeof(best_addr));
279+
280+#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
281+ rtnerr = getifaddrs(&ifaphead);
282+ if (rtnerr) {
283+ perror(NULL);
284+ return -1;
285+ }
286+#endif /* BSD_OR_LINUX */
287+
288+ s = socket(AF_INET, SOCK_STREAM, 0);
289+
290+ if (s > 0) {
291+#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
292+ for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {
293+
294+ if (ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_INET) {
295+ sin = (const struct sockaddr_in *) ifap->ifa_addr;
296+ score_address(sin, &best_addr, &best_score);
297+ res = 0;
298+
299+ if (best_score == 0) {
300+ break;
301+ }
302+ }
303+ }
304+#endif /* BSD_OR_LINUX */
305+
306+ /* There is no reason whatsoever that this shouldn't work on Linux or BSD also. */
307+#ifdef SOLARIS
308+ /* Get a count of interfaces on the machine */
309+ ifn.lifn_family = AF_INET;
310+ ifn.lifn_flags = 0;
311+ ifn.lifn_count = 0;
312+ if (ioctl(s, SIOCGLIFNUM, &ifn) < 0) {
313+ close(s);
314+ return -1;
315+ }
316+
317+ bufsz = ifn.lifn_count * sizeof(struct lifreq);
318+ if (!(buf = malloc(bufsz))) {
319+ close(s);
320+ return -1;
321+ }
322+ memset(buf, 0, bufsz);
323+
324+ /* Get a list of interfaces on the machine */
325+ ifc.lifc_len = bufsz;
326+ ifc.lifc_buf = buf;
327+ ifc.lifc_family = AF_INET;
328+ ifc.lifc_flags = 0;
329+ if (ioctl(s, SIOCGLIFCONF, &ifc) < 0) {
330+ close(s);
331+ free(buf);
332+ return -1;
333+ }
334+
335+ for (ifr = ifc.lifc_req, x = 0; x < ifn.lifn_count; ifr++, x++) {
336+ sa = (struct sockaddr_in *)&(ifr->lifr_addr);
337+ score_address(sa, &best_addr, &best_score);
338+ res = 0;
339+
340+ if (best_score == 0) {
341+ break;
342+ }
343+ }
344+
345+ free(buf);
346+#endif /* SOLARIS */
347+
348+ close(s);
349+ }
350+#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(__Darwin__)
351+ freeifaddrs(ifaphead);
352+#endif /* BSD_OR_LINUX */
353+
354+ if (res == 0 && ourip) {
355+ memcpy(ourip, &best_addr, sizeof(*ourip));
356+ }
357+ return res;
358+}
359+#endif /* HAVE_GETIFADDRS */
360+
361+/* Free HA structure */
362+void ast_free_ha(struct ast_ha *ha)
363+{
364+ struct ast_ha *hal;
365+ while (ha) {
366+ hal = ha;
367+ ha = ha->next;
368+ ast_free(hal);
369+ }
370+}
371+
372+/* Copy HA structure */
373+void ast_copy_ha(const struct ast_ha *from, struct ast_ha *to)
374+{
375+ memcpy(&to->netaddr, &from->netaddr, sizeof(from->netaddr));
376+ memcpy(&to->netmask, &from->netmask, sizeof(from->netmask));
377+ to->sense = from->sense;
378+}
379+
380+/* Create duplicate of ha structure */
381+static struct ast_ha *ast_duplicate_ha(struct ast_ha *original)
382+{
383+ struct ast_ha *new_ha;
384+
385+ if ((new_ha = ast_malloc(sizeof(*new_ha)))) {
386+ /* Copy from original to new object */
387+ ast_copy_ha(original, new_ha);
388+ }
389+
390+ return new_ha;
391+}
392+
393+/* Create duplicate HA link list */
394+/* Used in chan_sip2 templates */
395+struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original)
396+{
397+ struct ast_ha *start = original;
398+ struct ast_ha *ret = NULL;
399+ struct ast_ha *current, *prev = NULL;
400+
401+ while (start) {
402+ current = ast_duplicate_ha(start); /* Create copy of this object */
403+ if (prev) {
404+ prev->next = current; /* Link previous to this object */
405+ }
406+
407+ if (!ret) {
408+ ret = current; /* Save starting point */
409+ }
410+
411+ start = start->next; /* Go to next object */
412+ prev = current; /* Save pointer to this object */
413+ }
414+ return ret; /* Return start of list */
415+}
416+
417+struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
418+{
419+ struct ast_ha *ha;
420+ char *nm;
421+ struct ast_ha *prev = NULL;
422+ struct ast_ha *ret;
423+ int x;
424+ char *tmp = ast_strdupa(stuff);
425+
426+ ret = path;
427+ while (path) {
428+ prev = path;
429+ path = path->next;
430+ }
431+
432+ if (!(ha = ast_malloc(sizeof(*ha)))) {
433+ return ret;
434+ }
435+
436+ if (!(nm = strchr(tmp, '/'))) {
437+ /* assume /32. Yes, htonl does not do anything for this particular mask
438+ but we better use it to show we remember about byte order */
439+ ha->netmask.s_addr = htonl(0xFFFFFFFF);
440+ } else {
441+ *nm = '\0';
442+ nm++;
443+
444+ if (!strchr(nm, '.')) {
445+ if ((sscanf(nm, "%30d", &x) == 1) && (x >= 0) && (x <= 32)) {
446+ if (x == 0) {
447+ /* This is special-cased to prevent unpredictable
448+ * behavior of shifting left 32 bits
449+ */
450+ ha->netmask.s_addr = 0;
451+ } else {
452+ ha->netmask.s_addr = htonl(0xFFFFFFFF << (32 - x));
453+ }
454+ } else {
455+ ast_log(LOG_WARNING, "Invalid CIDR in %s\n", stuff);
456+ ast_free(ha);
457+ if (error) {
458+ *error = 1;
459+ }
460+ return ret;
461+ }
462+ } else if (!inet_aton(nm, &ha->netmask)) {
463+ ast_log(LOG_WARNING, "Invalid mask in %s\n", stuff);
464+ ast_free(ha);
465+ if (error) {
466+ *error = 1;
467+ }
468+ return ret;
469+ }
470+ }
471+
472+ if (!inet_aton(tmp, &ha->netaddr)) {
473+ ast_log(LOG_WARNING, "Invalid IP address in %s\n", stuff);
474+ ast_free(ha);
475+ if (error) {
476+ *error = 1;
477+ }
478+ return ret;
479+ }
480+
481+ ha->netaddr.s_addr &= ha->netmask.s_addr;
482+
483+ ha->sense = strncasecmp(sense, "p", 1) ? AST_SENSE_DENY : AST_SENSE_ALLOW;
484+
485+ ha->next = NULL;
486+ if (prev) {
487+ prev->next = ha;
488+ } else {
489+ ret = ha;
490+ }
491+
492+ ast_debug(1, "%s/%s sense %d appended to acl for peer\n", ast_strdupa(ast_inet_ntoa(ha->netaddr)), ast_strdupa(ast_inet_ntoa(ha->netmask)), ha->sense);
493+
494+ return ret;
495+}
496+
497+int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin)
498+{
499+ /* Start optimistic */
500+ int res = AST_SENSE_ALLOW;
501+ while (ha) {
502+#if 0 /* debugging code */
503+ char iabuf[INET_ADDRSTRLEN];
504+ char iabuf2[INET_ADDRSTRLEN];
505+ /* DEBUG */
506+ ast_copy_string(iabuf, ast_inet_ntoa(sin->sin_addr), sizeof(iabuf));
507+ ast_copy_string(iabuf2, ast_inet_ntoa(ha->netaddr), sizeof(iabuf2));
508+ ast_debug(1, "##### Testing %s with %s\n", iabuf, iabuf2);
509+#endif
510+ /* For each rule, if this address and the netmask = the net address
511+ apply the current rule */
512+ if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == ha->netaddr.s_addr) {
513+ res = ha->sense;
514+ }
515+ ha = ha->next;
516+ }
517+ return res;
518+}
519+
520+int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service)
521+{
522+ struct hostent *hp;
523+ struct ast_hostent ahp;
524+ char srv[256];
525+ char host[256];
526+ int tportno = ntohs(sin->sin_port);
527+ if (service) {
528+ snprintf(srv, sizeof(srv), "%s.%s", service, value);
529+ if (ast_get_srv(NULL, host, sizeof(host), &tportno, srv) > 0) {
530+ sin->sin_port = htons(tportno);
531+ value = host;
532+ }
533+ }
534+ if ((hp = ast_gethostbyname(value, &ahp))) {
535+ memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
536+ } else {
537+ ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
538+ return -1;
539+ }
540+ return 0;
541+}
542+
543+struct dscp_codepoint {
544+ char *name;
545+ unsigned int space;
546+};
547+
548+/* IANA registered DSCP codepoints */
549+
550+static const struct dscp_codepoint dscp_pool1[] = {
551+ { "CS0", 0x00 },
552+ { "CS1", 0x08 },
553+ { "CS2", 0x10 },
554+ { "CS3", 0x18 },
555+ { "CS4", 0x20 },
556+ { "CS5", 0x28 },
557+ { "CS6", 0x30 },
558+ { "CS7", 0x38 },
559+ { "AF11", 0x0A },
560+ { "AF12", 0x0C },
561+ { "AF13", 0x0E },
562+ { "AF21", 0x12 },
563+ { "AF22", 0x14 },
564+ { "AF23", 0x16 },
565+ { "AF31", 0x1A },
566+ { "AF32", 0x1C },
567+ { "AF33", 0x1E },
568+ { "AF41", 0x22 },
569+ { "AF42", 0x24 },
570+ { "AF43", 0x26 },
571+ { "EF", 0x2E },
572+};
573+
574+int ast_str2cos(const char *value, unsigned int *cos)
575+{
576+ int fval;
577+
578+ if (sscanf(value, "%30d", &fval) == 1) {
579+ if (fval < 8) {
580+ *cos = fval;
581+ return 0;
582+ }
583+ }
584+
585+ return -1;
586+}
587+
588+int ast_str2tos(const char *value, unsigned int *tos)
589+{
590+ int fval;
591+ unsigned int x;
592+
593+ if (sscanf(value, "%30i", &fval) == 1) {
594+ *tos = fval & 0xFF;
595+ return 0;
596+ }
597+
598+ for (x = 0; x < ARRAY_LEN(dscp_pool1); x++) {
599+ if (!strcasecmp(value, dscp_pool1[x].name)) {
600+ *tos = dscp_pool1[x].space << 2;
601+ return 0;
602+ }
603+ }
604+
605+ return -1;
606+}
607+
608+const char *ast_tos2str(unsigned int tos)
609+{
610+ unsigned int x;
611+
612+ for (x = 0; x < ARRAY_LEN(dscp_pool1); x++) {
613+ if (dscp_pool1[x].space == (tos >> 2)) {
614+ return dscp_pool1[x].name;
615+ }
616+ }
617+
618+ return "unknown";
619+}
620+
621+int ast_get_ip(struct sockaddr_in *sin, const char *value)
622+{
623+ return ast_get_ip_or_srv(sin, value, NULL);
624+}
625+
626+int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
627+{
628+ int s;
629+ struct sockaddr_in sin;
630+ socklen_t slen;
631+
632+ if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
633+ ast_log(LOG_ERROR, "Cannot create socket\n");
634+ return -1;
635+ }
636+ sin.sin_family = AF_INET;
637+ sin.sin_port = htons(5060);
638+ sin.sin_addr = *them;
639+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin))) {
640+ ast_log(LOG_WARNING, "Cannot connect\n");
641+ close(s);
642+ return -1;
643+ }
644+ slen = sizeof(sin);
645+ if (getsockname(s, (struct sockaddr *)&sin, &slen)) {
646+ ast_log(LOG_WARNING, "Cannot get socket name\n");
647+ close(s);
648+ return -1;
649+ }
650+ close(s);
651+ ast_debug(3, "Found IP address for this socket\n");
652+ *us = sin.sin_addr;
653+ return 0;
654+}
655+
656+int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr)
657+{
658+ char ourhost[MAXHOSTNAMELEN] = "";
659+ struct ast_hostent ahp;
660+ struct hostent *hp;
661+ struct in_addr saddr;
662+
663+ /* just use the bind address if it is nonzero */
664+ if (ntohl(bindaddr.sin_addr.s_addr)) {
665+ memcpy(ourip, &bindaddr.sin_addr, sizeof(*ourip));
666+ ast_debug(3, "Attached to given IP address\n");
667+ return 0;
668+ }
669+ /* try to use our hostname */
670+ if (gethostname(ourhost, sizeof(ourhost) - 1)) {
671+ ast_log(LOG_WARNING, "Unable to get hostname\n");
672+ } else {
673+ if ((hp = ast_gethostbyname(ourhost, &ahp))) {
674+ memcpy(ourip, hp->h_addr, sizeof(*ourip));
675+ ast_debug(3, "Found one IP address based on local hostname %s.\n", ourhost);
676+ return 0;
677+ }
678+ }
679+ ast_debug(3, "Trying to check A.ROOT-SERVERS.NET and get our IP address for that connection\n");
680+ /* A.ROOT-SERVERS.NET. */
681+ if (inet_aton("198.41.0.4", &saddr) && !ast_ouraddrfor(&saddr, ourip)) {
682+ return 0;
683+ }
684+ return get_local_address(ourip);
685+}
686+
687
688=== added file '.pc/dnsmgr-A-SRV-handling/main/dnsmgr.c'
689--- .pc/dnsmgr-A-SRV-handling/main/dnsmgr.c 1970-01-01 00:00:00 +0000
690+++ .pc/dnsmgr-A-SRV-handling/main/dnsmgr.c 2010-07-16 10:16:00 +0000
691@@ -0,0 +1,439 @@
692+/*
693+ * Asterisk -- An open source telephony toolkit.
694+ *
695+ * Copyright (C) 2005-2006, Kevin P. Fleming
696+ *
697+ * Kevin P. Fleming <kpfleming@digium.com>
698+ *
699+ * See http://www.asterisk.org for more information about
700+ * the Asterisk project. Please do not directly contact
701+ * any of the maintainers of this project for assistance;
702+ * the project provides a web site, mailing lists and IRC
703+ * channels for your use.
704+ *
705+ * This program is free software, distributed under the terms of
706+ * the GNU General Public License Version 2. See the LICENSE file
707+ * at the top of the source tree.
708+ */
709+
710+/*! \file
711+ *
712+ * \brief Background DNS update manager
713+ *
714+ * \author Kevin P. Fleming <kpfleming@digium.com>
715+ *
716+ * \bug There is a minor race condition. In the event that an IP address
717+ * of a dnsmgr managed host changes, there is the potential for the consumer
718+ * of that address to access the in_addr data at the same time that the dnsmgr
719+ * thread is in the middle of updating it to the new address.
720+ */
721+
722+#include "asterisk.h"
723+
724+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 211580 $")
725+
726+#include "asterisk/_private.h"
727+#include <regex.h>
728+#include <signal.h>
729+
730+#include "asterisk/dnsmgr.h"
731+#include "asterisk/linkedlists.h"
732+#include "asterisk/utils.h"
733+#include "asterisk/config.h"
734+#include "asterisk/sched.h"
735+#include "asterisk/cli.h"
736+#include "asterisk/manager.h"
737+#include "asterisk/acl.h"
738+
739+static struct sched_context *sched;
740+static int refresh_sched = -1;
741+static pthread_t refresh_thread = AST_PTHREADT_NULL;
742+
743+struct ast_dnsmgr_entry {
744+ /*! where we will store the resulting IP address and port number */
745+ struct sockaddr_in *result;
746+ /*! the last result, used to check if address/port has changed */
747+ struct sockaddr_in last;
748+ /*! SRV record to lookup, if provided. Composed of service, protocol, and domain name: _Service._Proto.Name */
749+ char *service;
750+ /*! Set to 1 if the entry changes */
751+ unsigned int changed:1;
752+ ast_mutex_t lock;
753+ AST_RWLIST_ENTRY(ast_dnsmgr_entry) list;
754+ /*! just 1 here, but we use calloc to allocate the correct size */
755+ char name[1];
756+};
757+
758+static AST_RWLIST_HEAD_STATIC(entry_list, ast_dnsmgr_entry);
759+
760+AST_MUTEX_DEFINE_STATIC(refresh_lock);
761+
762+#define REFRESH_DEFAULT 300
763+
764+static int enabled;
765+static int refresh_interval;
766+
767+struct refresh_info {
768+ struct entry_list *entries;
769+ int verbose;
770+ unsigned int regex_present:1;
771+ regex_t filter;
772+};
773+
774+static struct refresh_info master_refresh_info = {
775+ .entries = &entry_list,
776+ .verbose = 0,
777+};
778+
779+struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct sockaddr_in *result, const char *service)
780+{
781+ struct ast_dnsmgr_entry *entry;
782+ int total_size = sizeof(*entry) + strlen(name) + (service ? strlen(service) + 1 : 0);
783+
784+ if (!result || ast_strlen_zero(name) || !(entry = ast_calloc(1, total_size)))
785+ return NULL;
786+
787+ entry->result = result;
788+ ast_mutex_init(&entry->lock);
789+ strcpy(entry->name, name);
790+ memcpy(&entry->last, result, sizeof(entry->last));
791+ if (service) {
792+ entry->service = ((char *) entry) + sizeof(*entry) + strlen(name);
793+ strcpy(entry->service, service);
794+ }
795+
796+ AST_RWLIST_WRLOCK(&entry_list);
797+ AST_RWLIST_INSERT_HEAD(&entry_list, entry, list);
798+ AST_RWLIST_UNLOCK(&entry_list);
799+
800+ return entry;
801+}
802+
803+void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
804+{
805+ if (!entry)
806+ return;
807+
808+ AST_RWLIST_WRLOCK(&entry_list);
809+ AST_RWLIST_REMOVE(&entry_list, entry, list);
810+ AST_RWLIST_UNLOCK(&entry_list);
811+ ast_verb(4, "removing dns manager for '%s'\n", entry->name);
812+
813+ ast_mutex_destroy(&entry->lock);
814+ ast_free(entry);
815+}
816+
817+int ast_dnsmgr_lookup(const char *name, struct sockaddr_in *result, struct ast_dnsmgr_entry **dnsmgr, const char *service)
818+{
819+ if (ast_strlen_zero(name) || !result || !dnsmgr)
820+ return -1;
821+
822+ if (*dnsmgr && !strcasecmp((*dnsmgr)->name, name))
823+ return 0;
824+
825+ /* if it's actually an IP address and not a name,
826+ there's no need for a managed lookup */
827+ if (inet_aton(name, &result->sin_addr))
828+ return 0;
829+
830+ ast_verb(4, "doing dnsmgr_lookup for '%s'\n", name);
831+
832+ /* do a lookup now but add a manager so it will automagically get updated in the background */
833+ ast_get_ip_or_srv(result, name, service);
834+
835+ /* if dnsmgr is not enable don't bother adding an entry */
836+ if (!enabled)
837+ return 0;
838+
839+ ast_verb(3, "adding dns manager for '%s'\n", name);
840+ *dnsmgr = ast_dnsmgr_get(name, result, service);
841+ return !*dnsmgr;
842+}
843+
844+/*
845+ * Refresh a dnsmgr entry
846+ */
847+static int dnsmgr_refresh(struct ast_dnsmgr_entry *entry, int verbose)
848+{
849+ char iabuf[INET_ADDRSTRLEN];
850+ char iabuf2[INET_ADDRSTRLEN];
851+ struct sockaddr_in tmp;
852+ int changed = 0;
853+
854+ ast_mutex_lock(&entry->lock);
855+ if (verbose)
856+ ast_verb(3, "refreshing '%s'\n", entry->name);
857+
858+ tmp.sin_port = entry->last.sin_port;
859+
860+ if (!ast_get_ip_or_srv(&tmp, entry->name, entry->service) && inaddrcmp(&tmp, &entry->last)) {
861+ ast_copy_string(iabuf, ast_inet_ntoa(entry->last.sin_addr), sizeof(iabuf));
862+ ast_copy_string(iabuf2, ast_inet_ntoa(tmp.sin_addr), sizeof(iabuf2));
863+ ast_log(LOG_NOTICE, "dnssrv: host '%s' changed from %s:%d to %s:%d\n",
864+ entry->name, iabuf, ntohs(entry->last.sin_port), iabuf2, ntohs(tmp.sin_port));
865+ *entry->result = tmp;
866+ entry->last = tmp;
867+ changed = entry->changed = 1;
868+ }
869+
870+ ast_mutex_unlock(&entry->lock);
871+ return changed;
872+}
873+
874+int ast_dnsmgr_refresh(struct ast_dnsmgr_entry *entry)
875+{
876+ return dnsmgr_refresh(entry, 0);
877+}
878+
879+/*
880+ * Check if dnsmgr entry has changed from since last call to this function
881+ */
882+int ast_dnsmgr_changed(struct ast_dnsmgr_entry *entry)
883+{
884+ int changed;
885+
886+ ast_mutex_lock(&entry->lock);
887+
888+ changed = entry->changed;
889+ entry->changed = 0;
890+
891+ ast_mutex_unlock(&entry->lock);
892+
893+ return changed;
894+}
895+
896+static void *do_refresh(void *data)
897+{
898+ for (;;) {
899+ pthread_testcancel();
900+ usleep((ast_sched_wait(sched)*1000));
901+ pthread_testcancel();
902+ ast_sched_runq(sched);
903+ }
904+ return NULL;
905+}
906+
907+static int refresh_list(const void *data)
908+{
909+ struct refresh_info *info = (struct refresh_info *)data;
910+ struct ast_dnsmgr_entry *entry;
911+
912+ /* if a refresh or reload is already in progress, exit now */
913+ if (ast_mutex_trylock(&refresh_lock)) {
914+ if (info->verbose)
915+ ast_log(LOG_WARNING, "DNS Manager refresh already in progress.\n");
916+ return -1;
917+ }
918+
919+ ast_verb(3, "Refreshing DNS lookups.\n");
920+ AST_RWLIST_RDLOCK(info->entries);
921+ AST_RWLIST_TRAVERSE(info->entries, entry, list) {
922+ if (info->regex_present && regexec(&info->filter, entry->name, 0, NULL, 0))
923+ continue;
924+
925+ dnsmgr_refresh(entry, info->verbose);
926+ }
927+ AST_RWLIST_UNLOCK(info->entries);
928+
929+ ast_mutex_unlock(&refresh_lock);
930+
931+ /* automatically reschedule based on the interval */
932+ return refresh_interval * 1000;
933+}
934+
935+void dnsmgr_start_refresh(void)
936+{
937+ if (refresh_sched > -1) {
938+ AST_SCHED_DEL(sched, refresh_sched);
939+ refresh_sched = ast_sched_add_variable(sched, 100, refresh_list, &master_refresh_info, 1);
940+ }
941+}
942+
943+static int do_reload(int loading);
944+
945+static char *handle_cli_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
946+{
947+ switch (cmd) {
948+ case CLI_INIT:
949+ e->command = "dnsmgr reload";
950+ e->usage =
951+ "Usage: dnsmgr reload\n"
952+ " Reloads the DNS manager configuration.\n";
953+ return NULL;
954+ case CLI_GENERATE:
955+ return NULL;
956+ }
957+ if (a->argc > 2)
958+ return CLI_SHOWUSAGE;
959+
960+ do_reload(0);
961+ return CLI_SUCCESS;
962+}
963+
964+static char *handle_cli_refresh(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
965+{
966+ struct refresh_info info = {
967+ .entries = &entry_list,
968+ .verbose = 1,
969+ };
970+ switch (cmd) {
971+ case CLI_INIT:
972+ e->command = "dnsmgr refresh";
973+ e->usage =
974+ "Usage: dnsmgr refresh [pattern]\n"
975+ " Peforms an immediate refresh of the managed DNS entries.\n"
976+ " Optional regular expression pattern is used to filter the entries to refresh.\n";
977+ return NULL;
978+ case CLI_GENERATE:
979+ return NULL;
980+ }
981+
982+ if (!enabled) {
983+ ast_cli(a->fd, "DNS Manager is disabled.\n");
984+ return 0;
985+ }
986+
987+ if (a->argc > 3) {
988+ return CLI_SHOWUSAGE;
989+ }
990+
991+ if (a->argc == 3) {
992+ if (regcomp(&info.filter, a->argv[2], REG_EXTENDED | REG_NOSUB)) {
993+ return CLI_SHOWUSAGE;
994+ } else {
995+ info.regex_present = 1;
996+ }
997+ }
998+
999+ refresh_list(&info);
1000+
1001+ if (info.regex_present) {
1002+ regfree(&info.filter);
1003+ }
1004+
1005+ return CLI_SUCCESS;
1006+}
1007+
1008+static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1009+{
1010+ int count = 0;
1011+ struct ast_dnsmgr_entry *entry;
1012+ switch (cmd) {
1013+ case CLI_INIT:
1014+ e->command = "dnsmgr status";
1015+ e->usage =
1016+ "Usage: dnsmgr status\n"
1017+ " Displays the DNS manager status.\n";
1018+ return NULL;
1019+ case CLI_GENERATE:
1020+ return NULL;
1021+ }
1022+
1023+ if (a->argc > 2)
1024+ return CLI_SHOWUSAGE;
1025+
1026+ ast_cli(a->fd, "DNS Manager: %s\n", enabled ? "enabled" : "disabled");
1027+ ast_cli(a->fd, "Refresh Interval: %d seconds\n", refresh_interval);
1028+ AST_RWLIST_RDLOCK(&entry_list);
1029+ AST_RWLIST_TRAVERSE(&entry_list, entry, list)
1030+ count++;
1031+ AST_RWLIST_UNLOCK(&entry_list);
1032+ ast_cli(a->fd, "Number of entries: %d\n", count);
1033+
1034+ return CLI_SUCCESS;
1035+}
1036+
1037+static struct ast_cli_entry cli_reload = AST_CLI_DEFINE(handle_cli_reload, "Reloads the DNS manager configuration");
1038+static struct ast_cli_entry cli_refresh = AST_CLI_DEFINE(handle_cli_refresh, "Performs an immediate refresh");
1039+static struct ast_cli_entry cli_status = AST_CLI_DEFINE(handle_cli_status, "Display the DNS manager status");
1040+
1041+int dnsmgr_init(void)
1042+{
1043+ if (!(sched = sched_context_create())) {
1044+ ast_log(LOG_ERROR, "Unable to create schedule context.\n");
1045+ return -1;
1046+ }
1047+ ast_cli_register(&cli_reload);
1048+ ast_cli_register(&cli_status);
1049+ ast_cli_register(&cli_refresh);
1050+ return do_reload(1);
1051+}
1052+
1053+int dnsmgr_reload(void)
1054+{
1055+ return do_reload(0);
1056+}
1057+
1058+static int do_reload(int loading)
1059+{
1060+ struct ast_config *config;
1061+ struct ast_flags config_flags = { loading ? 0 : CONFIG_FLAG_FILEUNCHANGED };
1062+ const char *interval_value;
1063+ const char *enabled_value;
1064+ int interval;
1065+ int was_enabled;
1066+ int res = -1;
1067+
1068+ config = ast_config_load2("dnsmgr.conf", "dnsmgr", config_flags);
1069+ if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEUNCHANGED || config == CONFIG_STATUS_FILEINVALID) {
1070+ return 0;
1071+ }
1072+
1073+ /* ensure that no refresh cycles run while the reload is in progress */
1074+ ast_mutex_lock(&refresh_lock);
1075+
1076+ /* reset defaults in preparation for reading config file */
1077+ refresh_interval = REFRESH_DEFAULT;
1078+ was_enabled = enabled;
1079+ enabled = 0;
1080+
1081+ AST_SCHED_DEL(sched, refresh_sched);
1082+
1083+ if (config) {
1084+ if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
1085+ enabled = ast_true(enabled_value);
1086+ }
1087+ if ((interval_value = ast_variable_retrieve(config, "general", "refreshinterval"))) {
1088+ if (sscanf(interval_value, "%30d", &interval) < 1)
1089+ ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", interval_value);
1090+ else if (interval < 0)
1091+ ast_log(LOG_WARNING, "Invalid refresh interval '%d' specified, using default\n", interval);
1092+ else
1093+ refresh_interval = interval;
1094+ }
1095+ ast_config_destroy(config);
1096+ }
1097+
1098+ if (enabled && refresh_interval)
1099+ ast_log(LOG_NOTICE, "Managed DNS entries will be refreshed every %d seconds.\n", refresh_interval);
1100+
1101+ /* if this reload enabled the manager, create the background thread
1102+ if it does not exist */
1103+ if (enabled) {
1104+ if (!was_enabled && (refresh_thread == AST_PTHREADT_NULL)) {
1105+ if (ast_pthread_create_background(&refresh_thread, NULL, do_refresh, NULL) < 0) {
1106+ ast_log(LOG_ERROR, "Unable to start refresh thread.\n");
1107+ }
1108+ }
1109+ /* make a background refresh happen right away */
1110+ refresh_sched = ast_sched_add_variable(sched, 100, refresh_list, &master_refresh_info, 1);
1111+ res = 0;
1112+ }
1113+ /* if this reload disabled the manager and there is a background thread,
1114+ kill it */
1115+ else if (!enabled && was_enabled && (refresh_thread != AST_PTHREADT_NULL)) {
1116+ /* wake up the thread so it will exit */
1117+ pthread_cancel(refresh_thread);
1118+ pthread_kill(refresh_thread, SIGURG);
1119+ pthread_join(refresh_thread, NULL);
1120+ refresh_thread = AST_PTHREADT_NULL;
1121+ res = 0;
1122+ }
1123+ else
1124+ res = 0;
1125+
1126+ ast_mutex_unlock(&refresh_lock);
1127+ manager_event(EVENT_FLAG_SYSTEM, "Reload", "Module: DNSmgr\r\nStatus: %s\r/nMessage: DNSmgr reload Requested\r\n", enabled ? "Enabled" : "Disabled");
1128+
1129+ return res;
1130+}
1131
1132=== added file '.pc/h323-fix-makefile/.timestamp'
1133=== added file '.pc/h323-no-deps-on-asterisk/.timestamp'
1134=== added file '.pc/h323-workaround-openh323-segfault/.timestamp'
1135=== added file '.pc/hack-multiple-app-voicemail/.timestamp'
1136=== added file '.pc/make-clean-fixes/.timestamp'
1137=== added file '.pc/safe_asterisk-config/.timestamp'
1138=== added file '.pc/safe_asterisk-nobg/.timestamp'
1139=== added file '.pc/sound_files/.timestamp'
1140=== modified file 'debian/changelog'
1141--- debian/changelog 2010-04-13 16:27:27 +0000
1142+++ debian/changelog 2010-07-16 10:16:00 +0000
1143@@ -1,3 +1,11 @@
1144+asterisk (1:1.6.2.5-0ubuntu1.1) lucid-proposed; urgency=low
1145+
1146+ * debian/patches/dnsmgr-A-SRV-handling: Resolve handling of A and SRV
1147+ record changes and problem with multiple A/SRV records returned.
1148+ Patch based on Asterisk project's upstream patch. (LP: #605358)
1149+
1150+ -- Dave Walker (Daviey) <DaveWalker@ubuntu.com> Wed, 14 Jul 2010 11:40:55 +0100
1151+
1152 asterisk (1:1.6.2.5-0ubuntu1) lucid; urgency=low
1153
1154 * New upstream bugfix release (1.6.2.5)
1155
1156=== added file 'debian/patches/dnsmgr-A-SRV-handling'
1157--- debian/patches/dnsmgr-A-SRV-handling 1970-01-01 00:00:00 +0000
1158+++ debian/patches/dnsmgr-A-SRV-handling 2010-07-16 10:16:00 +0000
1159@@ -0,0 +1,132 @@
1160+Description: Resolve handling of A and SRV record changes and problem with multiple A/SRV records returned.
1161+Origin: upstream, https://issues.asterisk.org/file_download.php?file_id=25360&type=bug
1162+Bug: https://issues.asterisk.org/view.php?id=15827
1163+Bug-Ubuntu: https://launchpad.net/bugs/605358
1164+Last-Update: 2010-07-14
1165+--- a/include/asterisk/dnsmgr.h
1166++++ b/include/asterisk/dnsmgr.h
1167+@@ -42,12 +42,12 @@
1168+ *
1169+ * \param name the hostname
1170+ * \param result where the DNS manager should store the IP address as it refreshes it.
1171+- * it.
1172++ * \param service SRV prefix (optional, set to NULL to disable SRV)
1173+ *
1174+ * This function allocates a new DNS manager entry object, and fills it with the
1175+ * provided hostname and IP address. This function does not force an initial lookup
1176+- * of the IP address. So, generally, this should be used when the initial address
1177+- * is already known.
1178++ * of the IP address. So, this should be used when the initial address
1179++ * is already known and stored in result.
1180+ *
1181+ * \return a DNS manager entry
1182+ * \version 1.6.1 result changed from struct in_addr to struct sockaddr_in to store port number
1183+@@ -69,6 +69,7 @@
1184+ * \param name the hostname
1185+ * \param result where to store the IP address as the DNS manager refreshes it
1186+ * \param dnsmgr Where to store the allocate DNS manager entry
1187++ * \param service SRV prefix (optional, set to NULL to disable SRV)
1188+ *
1189+ * This function allocates a new DNS manager entry object, and fills it with
1190+ * the provided hostname and IP address. This function _does_ force an initial
1191+--- a/main/acl.c
1192++++ b/main/acl.c
1193+@@ -387,6 +387,7 @@
1194+ }
1195+ }
1196+ if ((hp = ast_gethostbyname(value, &ahp))) {
1197++ sin->sin_family = hp->h_addrtype;
1198+ memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
1199+ } else {
1200+ ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
1201+--- a/main/dnsmgr.c
1202++++ b/main/dnsmgr.c
1203+@@ -52,8 +52,6 @@
1204+ struct ast_dnsmgr_entry {
1205+ /*! where we will store the resulting IP address and port number */
1206+ struct sockaddr_in *result;
1207+- /*! the last result, used to check if address/port has changed */
1208+- struct sockaddr_in last;
1209+ /*! SRV record to lookup, if provided. Composed of service, protocol, and domain name: _Service._Proto.Name */
1210+ char *service;
1211+ /*! Set to 1 if the entry changes */
1212+@@ -85,6 +83,9 @@
1213+ .verbose = 0,
1214+ };
1215+
1216++/*
1217++ * Allocate a new DNS manager entry
1218++ */
1219+ struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct sockaddr_in *result, const char *service)
1220+ {
1221+ struct ast_dnsmgr_entry *entry;
1222+@@ -96,7 +97,6 @@
1223+ entry->result = result;
1224+ ast_mutex_init(&entry->lock);
1225+ strcpy(entry->name, name);
1226+- memcpy(&entry->last, result, sizeof(entry->last));
1227+ if (service) {
1228+ entry->service = ((char *) entry) + sizeof(*entry) + strlen(name);
1229+ strcpy(entry->service, service);
1230+@@ -109,6 +109,9 @@
1231+ return entry;
1232+ }
1233+
1234++/*
1235++ * Free a DNS manager entry
1236++ */
1237+ void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
1238+ {
1239+ if (!entry)
1240+@@ -123,6 +126,9 @@
1241+ ast_free(entry);
1242+ }
1243+
1244++/*
1245++ * Allocate a new DNS manager entry and perform the initial lookup before returning
1246++ */
1247+ int ast_dnsmgr_lookup(const char *name, struct sockaddr_in *result, struct ast_dnsmgr_entry **dnsmgr, const char *service)
1248+ {
1249+ if (ast_strlen_zero(name) || !result || !dnsmgr)
1250+@@ -133,8 +139,10 @@
1251+
1252+ /* if it's actually an IP address and not a name,
1253+ there's no need for a managed lookup */
1254+- if (inet_aton(name, &result->sin_addr))
1255++ if (inet_aton(name, &result->sin_addr)) {
1256++ result->sin_family = AF_INET;
1257+ return 0;
1258++ }
1259+
1260+ ast_verb(4, "doing dnsmgr_lookup for '%s'\n", name);
1261+
1262+@@ -151,7 +159,7 @@
1263+ }
1264+
1265+ /*
1266+- * Refresh a dnsmgr entry
1267++ * Force a refresh of a dnsmgr entry
1268+ */
1269+ static int dnsmgr_refresh(struct ast_dnsmgr_entry *entry, int verbose)
1270+ {
1271+@@ -164,15 +172,15 @@
1272+ if (verbose)
1273+ ast_verb(3, "refreshing '%s'\n", entry->name);
1274+
1275+- tmp.sin_port = entry->last.sin_port;
1276++ memset(&tmp, 0, sizeof(tmp));
1277++ tmp.sin_port = entry->result->sin_port;
1278+
1279+- if (!ast_get_ip_or_srv(&tmp, entry->name, entry->service) && inaddrcmp(&tmp, &entry->last)) {
1280+- ast_copy_string(iabuf, ast_inet_ntoa(entry->last.sin_addr), sizeof(iabuf));
1281++ if (!ast_get_ip_or_srv(&tmp, entry->name, entry->service) && inaddrcmp(&tmp, entry->result)) {
1282++ ast_copy_string(iabuf, ast_inet_ntoa(entry->result->sin_addr), sizeof(iabuf));
1283+ ast_copy_string(iabuf2, ast_inet_ntoa(tmp.sin_addr), sizeof(iabuf2));
1284+ ast_log(LOG_NOTICE, "dnssrv: host '%s' changed from %s:%d to %s:%d\n",
1285+- entry->name, iabuf, ntohs(entry->last.sin_port), iabuf2, ntohs(tmp.sin_port));
1286++ entry->name, iabuf, ntohs(entry->result->sin_port), iabuf2, ntohs(tmp.sin_port));
1287+ *entry->result = tmp;
1288+- entry->last = tmp;
1289+ changed = entry->changed = 1;
1290+ }
1291+
1292
1293=== modified file 'debian/patches/series'
1294--- debian/patches/series 2010-02-16 14:08:54 +0000
1295+++ debian/patches/series 2010-07-16 10:16:00 +0000
1296@@ -17,3 +17,4 @@
1297 dahdi_ptmp_nt
1298 dahdi_pri_debug_spannums
1299 sound_files
1300+dnsmgr-A-SRV-handling
1301
1302=== modified file 'include/asterisk/dnsmgr.h'
1303--- include/asterisk/dnsmgr.h 2009-03-29 22:21:47 +0000
1304+++ include/asterisk/dnsmgr.h 2010-07-16 10:16:00 +0000
1305@@ -42,12 +42,12 @@
1306 *
1307 * \param name the hostname
1308 * \param result where the DNS manager should store the IP address as it refreshes it.
1309- * it.
1310+ * \param service SRV prefix (optional, set to NULL to disable SRV)
1311 *
1312 * This function allocates a new DNS manager entry object, and fills it with the
1313 * provided hostname and IP address. This function does not force an initial lookup
1314- * of the IP address. So, generally, this should be used when the initial address
1315- * is already known.
1316+ * of the IP address. So, this should be used when the initial address
1317+ * is already known and stored in result.
1318 *
1319 * \return a DNS manager entry
1320 * \version 1.6.1 result changed from struct in_addr to struct sockaddr_in to store port number
1321@@ -69,6 +69,7 @@
1322 * \param name the hostname
1323 * \param result where to store the IP address as the DNS manager refreshes it
1324 * \param dnsmgr Where to store the allocate DNS manager entry
1325+ * \param service SRV prefix (optional, set to NULL to disable SRV)
1326 *
1327 * This function allocates a new DNS manager entry object, and fills it with
1328 * the provided hostname and IP address. This function _does_ force an initial
1329
1330=== modified file 'main/acl.c'
1331--- main/acl.c 2010-04-13 16:27:27 +0000
1332+++ main/acl.c 2010-07-16 10:16:00 +0000
1333@@ -387,6 +387,7 @@
1334 }
1335 }
1336 if ((hp = ast_gethostbyname(value, &ahp))) {
1337+ sin->sin_family = hp->h_addrtype;
1338 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
1339 } else {
1340 ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
1341
1342=== modified file 'main/dnsmgr.c'
1343--- main/dnsmgr.c 2010-02-16 14:08:54 +0000
1344+++ main/dnsmgr.c 2010-07-16 10:16:00 +0000
1345@@ -52,8 +52,6 @@
1346 struct ast_dnsmgr_entry {
1347 /*! where we will store the resulting IP address and port number */
1348 struct sockaddr_in *result;
1349- /*! the last result, used to check if address/port has changed */
1350- struct sockaddr_in last;
1351 /*! SRV record to lookup, if provided. Composed of service, protocol, and domain name: _Service._Proto.Name */
1352 char *service;
1353 /*! Set to 1 if the entry changes */
1354@@ -85,6 +83,9 @@
1355 .verbose = 0,
1356 };
1357
1358+/*
1359+ * Allocate a new DNS manager entry
1360+ */
1361 struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct sockaddr_in *result, const char *service)
1362 {
1363 struct ast_dnsmgr_entry *entry;
1364@@ -96,7 +97,6 @@
1365 entry->result = result;
1366 ast_mutex_init(&entry->lock);
1367 strcpy(entry->name, name);
1368- memcpy(&entry->last, result, sizeof(entry->last));
1369 if (service) {
1370 entry->service = ((char *) entry) + sizeof(*entry) + strlen(name);
1371 strcpy(entry->service, service);
1372@@ -109,6 +109,9 @@
1373 return entry;
1374 }
1375
1376+/*
1377+ * Free a DNS manager entry
1378+ */
1379 void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
1380 {
1381 if (!entry)
1382@@ -123,6 +126,9 @@
1383 ast_free(entry);
1384 }
1385
1386+/*
1387+ * Allocate a new DNS manager entry and perform the initial lookup before returning
1388+ */
1389 int ast_dnsmgr_lookup(const char *name, struct sockaddr_in *result, struct ast_dnsmgr_entry **dnsmgr, const char *service)
1390 {
1391 if (ast_strlen_zero(name) || !result || !dnsmgr)
1392@@ -133,8 +139,10 @@
1393
1394 /* if it's actually an IP address and not a name,
1395 there's no need for a managed lookup */
1396- if (inet_aton(name, &result->sin_addr))
1397+ if (inet_aton(name, &result->sin_addr)) {
1398+ result->sin_family = AF_INET;
1399 return 0;
1400+ }
1401
1402 ast_verb(4, "doing dnsmgr_lookup for '%s'\n", name);
1403
1404@@ -151,7 +159,7 @@
1405 }
1406
1407 /*
1408- * Refresh a dnsmgr entry
1409+ * Force a refresh of a dnsmgr entry
1410 */
1411 static int dnsmgr_refresh(struct ast_dnsmgr_entry *entry, int verbose)
1412 {
1413@@ -164,15 +172,15 @@
1414 if (verbose)
1415 ast_verb(3, "refreshing '%s'\n", entry->name);
1416
1417- tmp.sin_port = entry->last.sin_port;
1418+ memset(&tmp, 0, sizeof(tmp));
1419+ tmp.sin_port = entry->result->sin_port;
1420
1421- if (!ast_get_ip_or_srv(&tmp, entry->name, entry->service) && inaddrcmp(&tmp, &entry->last)) {
1422- ast_copy_string(iabuf, ast_inet_ntoa(entry->last.sin_addr), sizeof(iabuf));
1423+ if (!ast_get_ip_or_srv(&tmp, entry->name, entry->service) && inaddrcmp(&tmp, entry->result)) {
1424+ ast_copy_string(iabuf, ast_inet_ntoa(entry->result->sin_addr), sizeof(iabuf));
1425 ast_copy_string(iabuf2, ast_inet_ntoa(tmp.sin_addr), sizeof(iabuf2));
1426 ast_log(LOG_NOTICE, "dnssrv: host '%s' changed from %s:%d to %s:%d\n",
1427- entry->name, iabuf, ntohs(entry->last.sin_port), iabuf2, ntohs(tmp.sin_port));
1428+ entry->name, iabuf, ntohs(entry->result->sin_port), iabuf2, ntohs(tmp.sin_port));
1429 *entry->result = tmp;
1430- entry->last = tmp;
1431 changed = entry->changed = 1;
1432 }
1433

Subscribers

People subscribed via source and target branches

to all changes: