Module: sip-router
Branch: master
Commit: fac5c2fdcb13526c90b88ae1eaf528e7e104602f
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fac5c2f…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Mon Mar 30 20:55:25 2009 +0200
Merge branch 'ser_core_cvs' of ssh://git.sip-router.org/sip-router
* 'ser_core_cvs' of ssh://git.sip-router.org/sip-router:
dns: more strict record end checking
dns: minor fixes: long lines, unlikely(), end of msg checks
Adding missing reset_static_buffer()
Conflicts:
modules/tm/t_reply.c
---
Module: sip-router
Branch: ser_core_cvs
Commit: ca4ceef32cb4149efc14cdd8c25c8cd2348d653c
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ca4ceef…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Mon Mar 30 13:50:36 2009 +0000
dns: minor fixes: long lines, unlikely(), end of msg checks
- check if the rdlength is valid (points inside the answer),
before skipping over a record
- added unlikely() for error checks
- cosmetic: broken some long lines
---
resolve.c | 70 ++++++++++++++++++++++++++++++++++---------------------------
1 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/resolve.c b/resolve.c
index 740ea87..b007918 100644
--- a/resolve.c
+++ b/resolve.c
@@ -523,22 +523,22 @@ struct rdata* get_record(char* name, int type, int flags)
fullname_rd=0;
size=res_search(name, C_IN, type, buff.buff, sizeof(buff));
- if (size<0) {
+ if (unlikely(size<0)) {
DBG("get_record: lookup(%s, %d) failed\n", name, type);
goto not_found;
}
- else if (size > sizeof(buff)) size=sizeof(buff);
+ else if (unlikely(size > sizeof(buff))) size=sizeof(buff);
head=rd=0;
last=crt=&head;
p=buff.buff+DNS_HDR_SIZE;
end=buff.buff+size;
- if (p>=end) goto error_boundary;
+ if (unlikely(p>=end)) goto error_boundary;
qno=ntohs((unsigned short)buff.hdr.qdcount);
for (r=0; r<qno; r++){
/* skip the name of the question */
- if ((p=dns_skipname(p, end))==0) {
+ if (unlikely((p=dns_skipname(p, end))==0)) {
LOG(L_ERR, "ERROR: get_record: skipname==0\n");
goto error;
}
@@ -547,7 +547,7 @@ struct rdata* get_record(char* name, int type, int flags)
for (;(p<end && (*p)); p++);
p+=1+2+2; /* skip the ending '\0, QCODE and QCLASS */
#endif
- if (p>end) {
+ if (unlikely(p>end)) {
LOG(L_ERR, "ERROR: get_record: p>=end\n");
goto error;
}
@@ -562,20 +562,21 @@ again:
goto error;
}
#else
- if ((skip=dn_expand(buff.buff, end, p, rec_name, MAX_DNS_NAME-1))==-1){
+ if (unlikely((skip=dn_expand(buff.buff, end, p, rec_name,
+ MAX_DNS_NAME-1))==-1)){
LOG(L_ERR, "ERROR: get_record: dn_expand(rec_name) failed\n");
goto error;
}
#endif
p+=skip;
rec_name_len=strlen(rec_name);
- if (rec_name_len>255){
+ if (unlikely(rec_name_len>255)){
LOG(L_ERR, "ERROR: get_record: dn_expand(rec_name): name too"
" long (%d)\n", rec_name_len);
goto error;
}
/* check if enough space is left for type, class, ttl & size */
- if ((p+2+2+4+2)>end) goto error_boundary;
+ if (unlikely((p+2+2+4+2)>end)) goto error_boundary;
/* get type */
memcpy((void*) &rtype, (void*)p, 2);
rtype=ntohs(rtype);
@@ -592,6 +593,7 @@ again:
memcpy((void*)&rdlength, (void*)p, 2);
rdlength=ntohs(rdlength);
p+=2;
+ if (unlikely((p+rdlength)>end)) goto error_boundary;
if ((flags & RES_ONLY_TYPE) && (rtype!=type)){
/* skip */
p+=rdlength;
@@ -599,7 +601,8 @@ again:
}
/* expand the "type" record (rdata)*/
- rd=(struct rdata*) local_malloc(sizeof(struct rdata)+rec_name_len+1-1);
+ rd=(struct rdata*) local_malloc(sizeof(struct rdata)+rec_name_len+
+ 1-1);
if (rd==0){
LOG(L_ERR, "ERROR: get_record: out of memory\n");
goto error;
@@ -615,13 +618,13 @@ again:
if ((search_list_used==1)&&(fullname_rd==0)&&
(rec_name_len>=name_len)&&
(strncasecmp(rec_name, name, name_len)==0)) {
- /* now we have record which's name is the same (up-to the name_len
- * with the searched one
- * if the length is the same - we found full match, no fake cname
- * needed, just clear the flag
- * if the length of the name differs - it has matched using search list
- * remember the rd, so we can create fake CNAME record when all answers
- * are used and no better match found
+ /* now we have record whose name is the same (up-to the
+ * name_len with the searched one):
+ * if the length is the same - we found full match, no fake
+ * cname needed, just clear the flag
+ * if the length of the name differs - it has matched using
+ * search list remember the rd, so we can create fake CNAME
+ * record when all answers are used and no better match found
*/
if (rec_name_len==name_len)
search_list_used=0;
@@ -638,7 +641,7 @@ again:
case T_SRV:
srv_rd= dns_srv_parser(buff.buff, end, p);
rd->rdata=(void*)srv_rd;
- if (srv_rd==0) goto error_parse;
+ if (unlikely(srv_rd==0)) goto error_parse;
/* insert sorted into the list */
for (crt=&head; *crt; crt= &((*crt)->next)){
@@ -652,34 +655,35 @@ again:
goto skip;
}
}
- last=&(rd->next); /*end of for => this will be the last elem*/
+ last=&(rd->next); /*end of for => this will be the last
+ element*/
skip:
/* insert here */
rd->next=*crt;
*crt=rd;
-
break;
case T_A:
rd->rdata=(void*) dns_a_parser(p,end);
- if (rd->rdata==0) goto error_parse;
- *last=rd; /* last points to the last "next" or the list head*/
+ if (unlikely(rd->rdata==0)) goto error_parse;
+ *last=rd; /* last points to the last "next" or the list
+ head*/
last=&(rd->next);
break;
case T_AAAA:
rd->rdata=(void*) dns_aaaa_parser(p,end);
- if (rd->rdata==0) goto error_parse;
+ if (unlikely(rd->rdata==0)) goto error_parse;
*last=rd;
last=&(rd->next);
break;
case T_CNAME:
rd->rdata=(void*) dns_cname_parser(buff.buff, end, p);
- if(rd->rdata==0) goto error_parse;
+ if(unlikely(rd->rdata==0)) goto error_parse;
*last=rd;
last=&(rd->next);
break;
case T_NAPTR:
rd->rdata=(void*) dns_naptr_parser(buff.buff, end, p);
- if(rd->rdata==0) goto error_parse;
+ if(unlikely(rd->rdata==0)) goto error_parse;
*last=rd;
last=&(rd->next);
break;
@@ -697,7 +701,8 @@ again:
flags&=~RES_AR;
answers_no=ntohs((unsigned short)buff.hdr.nscount);
#ifdef RESOLVE_DBG
- DBG("get_record: skipping %d NS (p=%p, end=%p)\n", answers_no, p, end);
+ DBG("get_record: skipping %d NS (p=%p, end=%p)\n", answers_no, p,
+ end);
#endif
for (r=0; (r<answers_no) && (p<end); r++){
/* skip over the ns records */
@@ -706,13 +711,14 @@ again:
goto error;
}
/* check if enough space is left for type, class, ttl & size */
- if ((p+2+2+4+2)>end) goto error_boundary;
+ if (unlikely((p+2+2+4+2)>end)) goto error_boundary;
memcpy((void*)&rdlength, (void*)p+2+2+4, 2);
p+=2+2+4+2+ntohs(rdlength);
}
answers_no=ntohs((unsigned short)buff.hdr.arcount);
#ifdef RESOLVE_DBG
- DBG("get_record: parsing %d ARs (p=%p, end=%p)\n", answers_no, p, end);
+ DBG("get_record: parsing %d ARs (p=%p, end=%p)\n", answers_no, p,
+ end);
#endif
goto again; /* add also the additional records */
}
@@ -723,7 +729,7 @@ again:
*/
if ((search_list_used==1)&&(fullname_rd!=0)) {
rd=(struct rdata*) local_malloc(sizeof(struct rdata)+name_len+1-1);
- if (rd==0){
+ if (unlikely(rd==0)){
LOG(L_ERR, "ERROR: get_record: out of memory\n");
goto error;
}
@@ -735,13 +741,15 @@ again:
rd->name[name_len]=0;
rd->name_len=name_len;
/* alloc sizeof struct + space for the null terminated name */
- rd->rdata=(void*)local_malloc(sizeof(struct cname_rdata)-1+head->name_len+1);
- if(rd->rdata==0){
+ rd->rdata=(void*)local_malloc(sizeof(struct cname_rdata)-1+
+ head->name_len+1);
+ if(unlikely(rd->rdata==0)){
LOG(L_ERR, "ERROR: get_record: out of memory\n");
goto error_rd;
}
((struct cname_rdata*)(rd->rdata))->name_len=fullname_rd->name_len;
- memcpy(((struct cname_rdata*)(rd->rdata))->name, fullname_rd->name, fullname_rd->name_len);
+ memcpy(((struct cname_rdata*)(rd->rdata))->name, fullname_rd->name,
+ fullname_rd->name_len);
((struct cname_rdata*)(rd->rdata))->name[head->name_len]=0;
head=rd;
}
Hi,
attached patch converts the utils module to use the sr msg_send functionality.
Please review if the API is used correct.
In kamailio we use this "while( get_next_su( proxy, to, 0) == 0 );" construct
to loop over all destinations (e.g. for failover), how this is handled in sr?
Thanks,
Henning
Module: sip-router
Branch: janakj/kcore
Commit: cb0dd941f2b0d9a579bb98c6689ecabaf7189a6c
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=cb0dd94…
Author: Jan Janak <jan(a)iptel.org>
Committer: Jan Janak <jan(a)iptel.org>
Date: Sun Mar 29 21:50:15 2009 +0200
Adding the supported parser from kamailio core
---
lib/kcore/parse_supported.c | 143 +++++++++++++++++++++++++++++++++++++++++++
lib/kcore/parse_supported.h | 84 +++++++++++++++++++++++++
2 files changed, 227 insertions(+), 0 deletions(-)
diff --git a/lib/kcore/parse_supported.c b/lib/kcore/parse_supported.c
new file mode 100644
index 0000000..ddecf50
--- /dev/null
+++ b/lib/kcore/parse_supported.c
@@ -0,0 +1,143 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2006 Andreas Granig <agranig(a)linguin.org>
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*!
+ * \file
+ * \brief Supported parser
+ * \ingroup parser
+ */
+
+#include "../mem/mem.h"
+#include "keys.h"
+#include "parse_supported.h"
+
+#define IS_DELIM(c) (*(c) == ' ' || *(c) == '\t' || *(c) == '\r' || *(c) == '\n' || *(c) == ',')
+
+/* from parser/parse_hname2.c: */
+#define LOWER_BYTE(b) ((b) | 0x20)
+#define LOWER_DWORD(d) ((d) | 0x20202020)
+#define READ(val) \
+ (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
+
+
+/*!
+ * Parse Supported HF body.
+ */
+static inline int parse_supported_body(str *body, unsigned int *sup)
+{
+ register char* p;
+ register unsigned int val;
+ int len, pos = 0;
+
+ *sup = 0;
+
+ p = body->s;
+ len = body->len;
+
+ while (pos < len) {
+ /* skip spaces and commas */
+ for (; pos < len && IS_DELIM(p); ++pos, ++p);
+
+ val = LOWER_DWORD(READ(p));
+ switch (val) {
+
+ /* "path" */
+ case _path_:
+ if(pos + 4 <= len && IS_DELIM(p+4)) {
+ *sup |= F_SUPPORTED_PATH;
+ pos += 5; p += 5;
+ }
+ break;
+
+ /* "100rel" */
+ case _100r_:
+ if ( pos+6 <= len
+ && LOWER_BYTE(*(p+4))=='e' && LOWER_BYTE(*(p+5))=='l'
+ && IS_DELIM(p+6)) {
+ *sup |= F_SUPPORTED_100REL;
+ pos += SUPPORTED_100REL_LEN + 1;
+ p += SUPPORTED_100REL_LEN + 1;
+ }
+ break;
+
+ /* "timer" */
+ case _time_:
+ if ( pos+5 <= len && LOWER_BYTE(*(p+4))=='r'
+ && IS_DELIM(p+5) ) {
+ *sup |= F_SUPPORTED_TIMER;
+ pos += SUPPORTED_TIMER_LEN + 1;
+ p += SUPPORTED_TIMER_LEN + 1;
+ }
+ break;
+
+ /* unknown */
+ default:
+ /* skip element */
+ for (; pos < len && !IS_DELIM(p); ++pos, ++p);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*!
+ * Parse all Supported headers
+ */
+int parse_supported( struct sip_msg *msg)
+{
+ unsigned int supported;
+ struct hdr_field *hdr;
+ struct supported_body *sb;
+
+ /* maybe the header is already parsed! */
+ if (msg->supported && msg->supported->parsed)
+ return 0;
+
+ /* parse to the end in order to get all SUPPORTED headers */
+ if (parse_headers(msg,HDR_EOH_F,0)==-1 || !msg->supported)
+ return -1;
+
+ /* bad luck! :-( - we have to parse them */
+ supported = 0;
+ for( hdr=msg->supported ; hdr ; hdr=hdr->sibling) {
+ if (hdr->parsed) {
+ supported |= ((struct supported_body*)hdr->parsed)->supported;
+ continue;
+ }
+
+ sb = (struct supported_body*)pkg_malloc(sizeof(struct supported_body));
+ if (sb == 0) {
+ LM_ERR("out of pkg_memory\n");
+ return -1;
+ }
+
+ parse_supported_body(&(hdr->body), &(sb->supported));
+ sb->supported_all = 0;
+ hdr->parsed = (void*)sb;
+ supported |= sb->supported;
+ }
+
+ ((struct supported_body*)msg->supported->parsed)->supported_all =
+ supported;
+ return 0;
+}
diff --git a/lib/kcore/parse_supported.h b/lib/kcore/parse_supported.h
new file mode 100644
index 0000000..9a177fd
--- /dev/null
+++ b/lib/kcore/parse_supported.h
@@ -0,0 +1,84 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2006 Andreas Granig <agranig(a)linguin.org>
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * History:
+ * -------
+ * 2006-03-02 parse_supported() parses and cumulates all SUPPORTED
+ * headers (bogdan)
+ */
+
+/*!
+ * \file
+ * \brief Supported parser
+ * \ingroup parser
+ */
+
+#ifndef PARSE_SUPPORTED_H
+#define PARSE_SUPPORTED_H
+
+#include "msg_parser.h"
+#include "../mem/mem.h"
+
+
+#define F_SUPPORTED_PATH (1 << 0)
+#define F_SUPPORTED_100REL (1 << 1)
+#define F_SUPPORTED_TIMER (1 << 2)
+
+#define SUPPORTED_PATH_STR "path"
+#define SUPPORTED_PATH_LEN (sizeof(SUPPORTED_PATH_STR)-1)
+
+/* RFC 3262 */
+#define SUPPORTED_100REL_STR "100rel"
+#define SUPPORTED_100REL_LEN (sizeof(SUPPORTED_100REL_STR)-1)
+
+/* RFC 4028 */
+#define SUPPORTED_TIMER_STR "timer"
+#define SUPPORTED_TIMER_LEN (sizeof(SUPPORTED_TIMER_STR)-1)
+
+
+#define get_supported(p_msg) \
+ ((p_msg)->supported ? ((struct supported_body*)(p_msg)->supported->parsed)->supported_all : 0)
+
+
+struct supported_body {
+ unsigned int supported; /* supported mask for the current hdr */
+ unsigned int supported_all; /* suppoted mask for the all "supported" hdr
+ * - it's set only for the first hdr in
+ * sibling list*/
+};
+
+
+/*!
+ * Parse all Supported headers.
+ */
+int parse_supported( struct sip_msg *msg);
+
+
+static inline void free_supported(struct supported_body **sb)
+{
+ if (sb && *sb) {
+ pkg_free(*sb);
+ *sb = 0;
+ }
+}
+
+#endif /* PARSE_SUPPORTED_H */