Module: sip-router
Branch: master
Commit: 5a8977107c9c3f49dedf6de748cef421d755aa8b
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=5a89771…
Author: Jan Janak <jan(a)iptel.org>
Committer: Jan Janak <jan(a)iptel.org>
Date: Tue Mar 24 20:30:31 2009 +0100
New element of sip_msg structure with pointer to parsed body
This patch adds a new variable (called body) to the sip_msg structure
which can be used to store a pointer to parsed message body. This is
useful for modules that need to parse the SIP message body and would
like to store the result somewhere in the sip_msg structure so that
the body does not get parsed repeatedly.
The pointer is of type msg_body which is a generic structure that
represents parsed body of any type (SDP documents, XML documents, etc.).
This structure contains only two elements, the first element is enum
msg_body_type which designates the type of the parsed body document.
The second element is a pointer to a free function that is called by
the sr core to free all memory associated with the parsed body
structure.
Body parsers do not use the generic structure directly, instead they
are supposed to cast it to some other data structure. The target
structure must, however, retain the first two elements (the type and
the free function pointer) in the same order as the generic structure.
Body parsers provide the value of 'type' and 'free' elements.
The new structure in this commit only supports one body document type
per SIP message. As a possible future extension we could modify the
structure so that multiple such structures can be arranged into a
tree-like structure and then we will have support for multi-part body
documents.
---
parser/msg_parser.c | 1 +
parser/msg_parser.h | 22 ++++++++++++++++++++++
2 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/parser/msg_parser.c b/parser/msg_parser.c
index 74f91f5..bc73fb7 100644
--- a/parser/msg_parser.c
+++ b/parser/msg_parser.c
@@ -694,6 +694,7 @@ void free_sip_msg(struct sip_msg* msg)
if (msg->new_uri.s) { pkg_free(msg->new_uri.s); msg->new_uri.len=0; }
if (msg->dst_uri.s) { pkg_free(msg->dst_uri.s); msg->dst_uri.len=0; }
if (msg->headers) free_hdr_field_lst(msg->headers);
+ if (msg->body && msg->body->free) msg->body->free(&msg->body);
if (msg->add_rm) free_lump_list(msg->add_rm);
if (msg->body_lumps) free_lump_list(msg->body_lumps);
if (msg->reply_lump) free_reply_lump(msg->reply_lump);
diff --git a/parser/msg_parser.h b/parser/msg_parser.h
index af85f21..74754f7 100644
--- a/parser/msg_parser.h
+++ b/parser/msg_parser.h
@@ -200,6 +200,26 @@ struct sip_uri {
#endif
};
+struct msg_body;
+
+typedef void (*free_msg_body_f)(struct msg_body** ptr);
+
+typedef enum msg_body_type {
+ MSG_BODY_UNKNOWN = 0,
+ MSG_BODY_SDP
+} msg_body_type_t;
+
+/* This structure represents a generic SIP message body, regardless of the
+ * body type. Body parsers are supposed to cast this structure to some other
+ * body-type specific structure, but the body type specific structure must
+ * retain msg_body_type variable and a pointer to the free function as the
+ * first two variables within the structure.
+ */
+typedef struct msg_body {
+ msg_body_type_t type;
+ free_msg_body_f free;
+} msg_body_t;
+
typedef struct sip_msg {
unsigned int id; /* message id, unique/process*/
@@ -259,6 +279,8 @@ typedef struct sip_msg {
struct hdr_field* ppi;
struct hdr_field* path;
+ struct msg_body* body;
+
char* eoh; /* pointer to the end of header (if found) or null */
char* unparsed; /* here we stopped parsing*/
Module: sip-router
Branch: master
Commit: d6ac6a12e171fe5cff766ef187a0a0be945de758
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d6ac6a1…
Author: Jan Janak <jan(a)iptel.org>
Committer: Jan Janak <jan(a)iptel.org>
Date: Tue Mar 24 20:36:57 2009 +0100
Update the SDP parser for the sip-router core.
This patch makes the SDP parser work with the sip-router core. The
sr core sip_msg structure does not contain the pointer to sdp_info_t,
instead it contains an element called body which points to a generic
structure msg_body_t.
To make the SDP parser work with the sr core we need to cast msg_body_t
to sdp_info_t and add 'type' and 'free' elements at the beginning of
the sdp_info structure.
Function new_sdp then stores the type of the document being parsed in
msg->body->type and a pointer to free_sdp function in msg->body->free.
Furthemore, testing just if (msg->body != 0) is not enough anymore,
because the variable could also contain a pointer to a different body
document type. So we need to change all such tests to something like:
if ((msg->body != 0) && (msg->body->type == MSG_BODY_SDP))
---
parser/sdp/sdp.c | 38 ++++++++++++++++++++++++--------------
parser/sdp/sdp.h | 2 ++
2 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/parser/sdp/sdp.c b/parser/sdp/sdp.c
index ec43cf3..4a6697f 100644
--- a/parser/sdp/sdp.c
+++ b/parser/sdp/sdp.c
@@ -51,8 +51,9 @@ static inline int new_sdp(struct sip_msg* _m)
return -1;
}
memset( sdp, 0, sizeof(sdp_info_t));
-
- _m->sdp = sdp;
+ sdp->type = MSG_BODY_SDP;
+ sdp->free = (free_msg_body_f)free_sdp;
+ _m->body = (msg_body_t*)sdp;
return 0;
}
@@ -279,8 +280,9 @@ sdp_session_cell_t* get_sdp_session_sdp(struct sdp_info* sdp, int session_num)
sdp_session_cell_t* get_sdp_session(struct sip_msg* _m, int session_num)
{
- if (_m->sdp == NULL) return NULL;
- return get_sdp_session_sdp(_m->sdp, session_num);
+ if (_m->body == NULL) return NULL;
+ if (_m->body->type != MSG_BODY_SDP) return NULL;
+ return get_sdp_session_sdp((sdp_info_t*)_m->body, session_num);
}
@@ -311,15 +313,18 @@ sdp_stream_cell_t* get_sdp_stream_sdp(struct sdp_info* sdp, int session_num, int
sdp_stream_cell_t* get_sdp_stream(struct sip_msg* _m, int session_num, int stream_num)
{
+ sdp_info_t* sdp;
sdp_session_cell_t *session;
sdp_stream_cell_t *stream;
- return get_sdp_stream_sdp(_m->sdp, session_num, stream_num);
+ return get_sdp_stream_sdp((sdp_info_t*)_m->body, session_num, stream_num);
- if (_m->sdp == NULL) return NULL;
- if (session_num > _m->sdp->sessions_num) return NULL;
+ sdp = (sdp_info_t*)_m->body;
+ if (sdp == NULL) return NULL;
+ if (sdp->type != MSG_BODY_SDP) return NULL;
+ if (session_num > sdp->sessions_num) return NULL;
- session = _m->sdp->sessions;
+ session = sdp->sessions;
while (session) {
if (session->session_num == session_num) {
stream = session->streams;
@@ -666,7 +671,7 @@ int parse_sdp(struct sip_msg* _m)
str body, mp_delimiter;
int mime;
- if (_m->sdp) {
+ if (_m->body) {
return 0; /* Already parsed */
}
@@ -696,10 +701,10 @@ int parse_sdp(struct sip_msg* _m)
LM_ERR("Can't create sdp\n");
return -1;
}
- res = parse_sdp_session(&body, 0, NULL, _m->sdp);
+ res = parse_sdp_session(&body, 0, NULL, (sdp_info_t*)_m->body);
if (res != 0) {
LM_DBG("free_sdp\n");
- free_sdp((sdp_info_t**)(void*)&(_m->sdp));
+ free_sdp((sdp_info_t**)&_m->body);
}
return res;
break;
@@ -719,9 +724,9 @@ int parse_sdp(struct sip_msg* _m)
LM_ERR("Can't create sdp\n");
return -1;
}
- res = parse_mixed_content(&body, mp_delimiter, _m->sdp);
+ res = parse_mixed_content(&body, mp_delimiter, (sdp_info_t*)_m->body);
if (res != 0) {
- free_sdp((sdp_info_t**)(void*)&(_m->sdp));
+ free_sdp((sdp_info_t**)&_m->body);
}
return res;
} else {
@@ -1151,7 +1156,8 @@ error:
sdp_info_t * clone_sdp_info(struct sip_msg* _m)
{
- sdp_info_t *clone_sdp_info, *sdp_info=_m->sdp;
+ sdp_info_t *clone_sdp_info, *sdp_info=(sdp_info_t*)_m->body
+;
sdp_session_cell_t *clone_session, *prev_clone_session, *session;
int i, len;
@@ -1159,6 +1165,10 @@ sdp_info_t * clone_sdp_info(struct sip_msg* _m)
LM_ERR("no sdp to clone\n");
return NULL;
}
+ if (sdp_info->type != MSG_BODY_SDP) {
+ LM_ERR("Unsupported body type\n");
+ return NULL;
+ }
if (sdp_info->sessions_num == 0) {
LM_ERR("no sessions to clone\n");
return NULL;
diff --git a/parser/sdp/sdp.h b/parser/sdp/sdp.h
index 3f6c775..9c9b9c7 100644
--- a/parser/sdp/sdp.h
+++ b/parser/sdp/sdp.h
@@ -86,6 +86,8 @@ typedef struct sdp_session_cell {
* Here we hold the head of the parsed sdp structure
*/
typedef struct sdp_info {
+ msg_body_type_t type;
+ free_msg_body_f free;
int sessions_num; /**< number of SDP sessions */
struct sdp_session_cell *sessions;
} sdp_info_t;
Hi, Kamailio uses the following syntax for =~ operator:
if ( $rU =~ "^2[0-9]{2}$" ) {
Reading the SR commits, it seems that SR will support regular
expressions in 'switch' stament:
switch ($rU) {
case 200: # INTEGER
[...]
case "alice": # STRING
[...]
case /2[0-9]{2}/: # REGULAR EXPRESSION
[...]
}
If the above is correct, it requires two different syntax for a
regular expression:
a) =~ "^2[0-9]{2}$"
b) case /2[0-9]{2}/:
Wouldn't make sense to have an unique syntax for regular expressions?
IMHO the best one is:
/2[0-9]{2}/
so =~ would use:
if ( $rU =~ /^2[0-9]{2}$/ ) {
Opinions? Regards.
--
Iñaki Baz Castillo
<ibc(a)aliax.net>
Hello,
working to integrate the PV module I reached the AVPs and after a short
analyze I wonder (and ask you) whether you should drop the naming scheme
we have in Kamailio (integer id and string name) and stick to string
names all the time. ser seems to use mostly that although looks like
support for ID is still there, but I cannot see how they can be used
with the naming scheme in config (e.g., is it possible to have $f.i:34
in config to refer to avp with id 34?).
The benefits I see:
- complexity in dealing with integer id or string name
- avp name aliases removed
Note that even for string-named AVPs there is an integer id computed and
used in comparisons to speed up.
Jan in an email some time ago mentioned that no performance penalty
could be observed. I pasted most of the content of Jan's email about ser
avps at:
http://sip-router.org/wiki/devel/avps-ser
Looking at the code where there are lot of IF name is string or integer,
I wonder if really worth the complexity. Today we have lot of other
variables for quick and shared-memory operations ($var(...), $shv(...),
$sht(...), $dbr(...) and latest $mct(...)), avps not being anymore used
for everywhere.
Drawback is the naming scheme backward compatibility. We can treat
"i:20" simply as string or throw error at startup (I prefer the second
because is cleaner in long time).
Opinions?
Cheers,
Daniel
--
Daniel-Constantin Mierla
http://www.asipto.com