summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-03-02 14:51:03 +0000
committerBenny Prijono <bennylp@teluu.com>2007-03-02 14:51:03 +0000
commitfdf444b5c4ec258181715864b53e4d383efaea25 (patch)
tree611a7def20a623b5acb5984f9dffe626490959a9
parente4a0cf0e1d20888824896efaa3b0d58116a0adfc (diff)
Fixed ticket #156: Not enough memory to parse DNS packets in resolver (thanks Frank Wiersma)
git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/pjproject-0.5-stable@1033 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjlib-util/include/pjlib-util/config.h9
-rw-r--r--pjlib-util/include/pjlib-util/dns.h19
-rw-r--r--pjlib-util/src/pjlib-util/dns.c17
-rw-r--r--pjlib-util/src/pjlib-util/dns_dump.c5
-rw-r--r--pjlib-util/src/pjlib-util/resolver.c16
-rw-r--r--pjsip/src/pjsip/sip_resolve.c20
6 files changed, 53 insertions, 33 deletions
diff --git a/pjlib-util/include/pjlib-util/config.h b/pjlib-util/include/pjlib-util/config.h
index 7abba3c1..5d363b00 100644
--- a/pjlib-util/include/pjlib-util/config.h
+++ b/pjlib-util/include/pjlib-util/config.h
@@ -169,6 +169,15 @@
#endif
+/**
+ * Size of temporary pool buffer for parsing DNS packets in resolver.
+ *
+ * default: 4000
+ */
+#ifndef PJ_DNS_RESOLVER_TMP_BUF_SIZE
+# define PJ_DNS_RESOLVER_TMP_BUF_SIZE 4000
+#endif
+
/* **************************************************************************
* SCANNER CONFIGURATION
diff --git a/pjlib-util/include/pjlib-util/dns.h b/pjlib-util/include/pjlib-util/dns.h
index cebc20f8..4505eb3d 100644
--- a/pjlib-util/include/pjlib-util/dns.h
+++ b/pjlib-util/include/pjlib-util/dns.h
@@ -25,7 +25,7 @@
* @brief Low level DNS message parsing and packetization.
*/
#include <pjlib-util/types.h>
-
+#include <pj/sock.h>
PJ_BEGIN_DECL
@@ -258,7 +258,7 @@ typedef struct pj_dns_parsed_rr
/** A Resource Data (PJ_DNS_TYPE_A, 1) */
struct a {
- pj_str_t ip_addr;/**< IP host address string. */
+ pj_in_addr ip_addr;/**< IP host address string. */
} a;
} rdata;
@@ -282,6 +282,19 @@ typedef struct pj_dns_parsed_packet
/**
+ * Option flags to be specified when calling #pj_dns_packet_dup() function.
+ * These flags can be combined with bitwise OR operation.
+ */
+enum pj_dns_dup_options
+{
+ PJ_DNS_NO_QD = 1, /**< Do not duplicate the query section. */
+ PJ_DNS_NO_ANS = 2, /**< Do not duplicate the answer section. */
+ PJ_DNS_NO_NS = 4, /**< Do not duplicate the NS section. */
+ PJ_DNS_NO_AR = 8 /**< Do not duplicate the additional rec section */
+};
+
+
+/**
* Create DNS query packet to resolve the specified names. This function
* can be used to build any types of DNS query, such as A record or DNS SRV
* record.
@@ -331,10 +344,12 @@ PJ_DECL(pj_status_t) pj_dns_parse_packet(pj_pool_t *pool,
*
* @param pool The pool to allocate memory for the duplicated packet.
* @param p The DNS packet to be cloned.
+ * @param options Option flags, from pj_dns_dup_options.
* @param p_dst Pointer to store the cloned DNS packet.
*/
PJ_DECL(void) pj_dns_packet_dup(pj_pool_t *pool,
const pj_dns_parsed_packet*p,
+ unsigned options,
pj_dns_parsed_packet **p_dst);
diff --git a/pjlib-util/src/pjlib-util/dns.c b/pjlib-util/src/pjlib-util/dns.c
index 71bad5b6..a3c3217b 100644
--- a/pjlib-util/src/pjlib-util/dns.c
+++ b/pjlib-util/src/pjlib-util/dns.c
@@ -340,11 +340,7 @@ static pj_status_t parse_rr(pj_dns_parsed_rr *rr, pj_pool_t *pool,
/* Parse some well known records */
if (rr->type == PJ_DNS_TYPE_A) {
- pj_in_addr ip_addr;
-
- pj_memcpy(&ip_addr, p, 4);
- pj_strdup2(pool, &rr->rdata.a.ip_addr, pj_inet_ntoa(ip_addr));
-
+ pj_memcpy(&rr->rdata.a.ip_addr, p, 4);
p += 4;
} else if (rr->type == PJ_DNS_TYPE_CNAME ||
@@ -587,7 +583,7 @@ static void copy_rr(pj_pool_t *pool, pj_dns_parsed_rr *dst,
apply_name_table(nametable_count, nametable, &src->rdata.srv.target,
pool, &dst->rdata.srv.target);
} else if (src->type == PJ_DNS_TYPE_A) {
- pj_strdup(pool, &dst->rdata.a.ip_addr, &src->rdata.a.ip_addr);
+ dst->rdata.a.ip_addr.s_addr = src->rdata.a.ip_addr.s_addr;
} else if (src->type == PJ_DNS_TYPE_CNAME) {
pj_strdup(pool, &dst->rdata.cname.name, &src->rdata.cname.name);
} else if (src->type == PJ_DNS_TYPE_NS) {
@@ -602,6 +598,7 @@ static void copy_rr(pj_pool_t *pool, pj_dns_parsed_rr *dst,
*/
PJ_DEF(void) pj_dns_packet_dup(pj_pool_t *pool,
const pj_dns_parsed_packet*p,
+ unsigned options,
pj_dns_parsed_packet **p_dst)
{
pj_dns_parsed_packet *dst;
@@ -630,7 +627,7 @@ PJ_DEF(void) pj_dns_packet_dup(pj_pool_t *pool,
/* Copy query section */
- if (p->hdr.qdcount) {
+ if (p->hdr.qdcount && (options & PJ_DNS_NO_QD)==0) {
dst->q = pj_pool_alloc(pool, p->hdr.qdcount *
sizeof(pj_dns_parsed_query));
for (i=0; i<p->hdr.qdcount; ++i) {
@@ -641,7 +638,7 @@ PJ_DEF(void) pj_dns_packet_dup(pj_pool_t *pool,
}
/* Copy answer section */
- if (p->hdr.anscount) {
+ if (p->hdr.anscount && (options & PJ_DNS_NO_ANS)==0) {
dst->ans = pj_pool_alloc(pool, p->hdr.anscount *
sizeof(pj_dns_parsed_rr));
for (i=0; i<p->hdr.anscount; ++i) {
@@ -652,7 +649,7 @@ PJ_DEF(void) pj_dns_packet_dup(pj_pool_t *pool,
}
/* Copy NS section */
- if (p->hdr.nscount) {
+ if (p->hdr.nscount && (options & PJ_DNS_NO_NS)==0) {
dst->ns = pj_pool_alloc(pool, p->hdr.nscount *
sizeof(pj_dns_parsed_rr));
for (i=0; i<p->hdr.nscount; ++i) {
@@ -663,7 +660,7 @@ PJ_DEF(void) pj_dns_packet_dup(pj_pool_t *pool,
}
/* Copy additional info section */
- if (p->hdr.arcount) {
+ if (p->hdr.arcount && (options & PJ_DNS_NO_AR)==0) {
dst->arr = pj_pool_alloc(pool, p->hdr.arcount *
sizeof(pj_dns_parsed_rr));
for (i=0; i<p->hdr.arcount; ++i) {
diff --git a/pjlib-util/src/pjlib-util/dns_dump.c b/pjlib-util/src/pjlib-util/dns_dump.c
index 2a3e803d..d493323a 100644
--- a/pjlib-util/src/pjlib-util/dns_dump.c
+++ b/pjlib-util/src/pjlib-util/dns_dump.c
@@ -115,9 +115,8 @@ static void dump_answer(unsigned index, const pj_dns_parsed_rr *rr)
(int)rr->rdata.cname.name.slen,
rr->rdata.cname.name.ptr));
} else if (rr->type == PJ_DNS_TYPE_A) {
- PJ_LOG(3,(THIS_FILE, " IP address: %.*s",
- (int)rr->rdata.a.ip_addr.slen,
- rr->rdata.a.ip_addr.ptr));
+ PJ_LOG(3,(THIS_FILE, " IP address: %s",
+ pj_inet_ntoa(rr->rdata.a.ip_addr)));
}
}
diff --git a/pjlib-util/src/pjlib-util/resolver.c b/pjlib-util/src/pjlib-util/resolver.c
index 24304482..d4a950e2 100644
--- a/pjlib-util/src/pjlib-util/resolver.c
+++ b/pjlib-util/src/pjlib-util/resolver.c
@@ -51,6 +51,7 @@
#define RES_BUF_SZ PJ_DNS_RESOLVER_RES_BUF_SIZE
#define UDPSZ PJ_DNS_RESOLVER_MAX_UDP_SIZE
+#define TMP_SZ PJ_DNS_RESOLVER_TMP_BUF_SIZE
/* Nameserver state */
@@ -161,7 +162,7 @@ struct pj_dns_resolver
pj_timer_heap_t *timer; /**< Timer instance. */
pj_bool_t own_ioqueue; /**< Do we own ioqueue? */
pj_ioqueue_t *ioqueue; /**< Ioqueue instance. */
- char tmp_pool[1500];/**< Temporary pool buffer. */
+ char tmp_pool[TMP_SZ];/**< Temporary pool buffer. */
/* Socket */
pj_sock_t udp_sock; /**< UDP socket. */
@@ -993,11 +994,16 @@ static void update_res_cache(pj_dns_resolver *resolver,
}
}
- /* Duplicate the packet */
+ /* Duplicate the packet.
+ * We don't need to keep the query, NS, and AR sections from the packet,
+ * so exclude from duplication.
+ */
res_pool = pj_pool_create_on_buf("respool", cache->buf, sizeof(cache->buf));
PJ_TRY {
cache->pkt = NULL;
- pj_dns_packet_dup(res_pool, pkt, &cache->pkt);
+ pj_dns_packet_dup(res_pool, pkt,
+ PJ_DNS_NO_QD | PJ_DNS_NO_NS | PJ_DNS_NO_AR,
+ &cache->pkt);
}
PJ_CATCH_ANY {
PJ_LOG(1,(THIS_FILE,
@@ -1223,10 +1229,6 @@ static void on_read_complete(pj_ioqueue_key_t *key,
}
}
- /* We don't need NS and query section in the packet, so trim them. */
- dns_pkt->hdr.qdcount = 0;
- dns_pkt->hdr.nscount = 0;
-
/* Save/update response cache. */
update_res_cache(resolver, &q->key, status, PJ_TRUE, dns_pkt);
diff --git a/pjsip/src/pjsip/sip_resolve.c b/pjsip/src/pjsip/sip_resolve.c
index ec6835a8..8faa57d4 100644
--- a/pjsip/src/pjsip/sip_resolve.c
+++ b/pjsip/src/pjsip/sip_resolve.c
@@ -535,7 +535,7 @@ static void build_server_entries(struct query *query,
for (j=0; j<query->srv_cnt; ++j) {
if (pj_stricmp(&rr->name, &query->srv[j].target_name)==0) {
unsigned cnt = query->srv[j].addr_cnt;
- query->srv[j].addr[cnt] = pj_inet_addr(&rr->rdata.a.ip_addr);
+ query->srv[j].addr[cnt].s_addr = rr->rdata.a.ip_addr.s_addr;
++query->srv[j].addr_cnt;
++query->host_resolved;
break;
@@ -777,29 +777,27 @@ static void dns_callback(void *user_data,
} else {
unsigned j;
- query->srv[i].addr[query->srv[i].addr_cnt++] =
- pj_inet_addr(&pkt->ans[0].rdata.a.ip_addr);
+ query->srv[i].addr[query->srv[i].addr_cnt++].s_addr =
+ pkt->ans[0].rdata.a.ip_addr.s_addr;
PJ_LOG(5,(query->objname,
- "DNS A for %.*s: %.*s",
+ "DNS A for %.*s: %s",
(int)query->srv[i].target_name.slen,
query->srv[i].target_name.ptr,
- (int)pkt->ans[0].rdata.a.ip_addr.slen,
- pkt->ans[0].rdata.a.ip_addr.ptr));
+ pj_inet_ntoa(pkt->ans[0].rdata.a.ip_addr)));
/* Check for multiple IP addresses */
for (j=1; j<pkt->hdr.anscount &&
query->srv[i].addr_cnt < ADDR_MAX_COUNT; ++j)
{
- query->srv[i].addr[query->srv[i].addr_cnt++] =
- pj_inet_addr(&pkt->ans[j].rdata.a.ip_addr);
+ query->srv[i].addr[query->srv[i].addr_cnt++].s_addr =
+ pkt->ans[j].rdata.a.ip_addr.s_addr;
PJ_LOG(5,(query->objname,
- "Additional DNS A for %.*s: %.*s",
+ "Additional DNS A for %.*s: %s",
(int)query->srv[i].target_name.slen,
query->srv[i].target_name.ptr,
- (int)pkt->ans[j].rdata.a.ip_addr.slen,
- pkt->ans[j].rdata.a.ip_addr.ptr));
+ pj_inet_ntoa(pkt->ans[j].rdata.a.ip_addr)));
}
}