TT#8275 debian/patches/sipwise: remove unused patches

Change-Id: I65cd77ac6e3520676c10172a65b64b3d7df60ecd
changes/54/10354/1
Victor Seva 9 years ago
parent 262ed002a3
commit 298ee6bc00

@ -1,837 +0,0 @@
From a9d5d28b8b750b06736b78680da66cfbd3d67e69 Mon Sep 17 00:00:00 2001
From: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Fri, 21 Mar 2014 21:59:41 +0100
Subject: [PATCH] textops: functions to convert, append and remove multipart
bodies
---
modules/textops/textops.c | 767 ++++++++++++++++++++++++++++++++++++++++------
1 file changed, 673 insertions(+), 94 deletions(-)
diff --git a/modules/textops/textops.c b/modules/textops/textops.c
index 12bcf88..82c8ee8 100644
--- a/modules/textops/textops.c
+++ b/modules/textops/textops.c
@@ -123,6 +123,14 @@ static int append_time_f(struct sip_msg* msg, char* , char *);
static int append_time_request_f(struct sip_msg* msg, char* , char *);
static int set_body_f(struct sip_msg* msg, char*, char *);
static int set_rpl_body_f(struct sip_msg* msg, char*, char *);
+static int set_multibody_0(struct sip_msg* msg, char*, char *, char *);
+static int set_multibody_1(struct sip_msg* msg, char*, char *, char *);
+static int set_multibody_2(struct sip_msg* msg, char*, char *, char *);
+static int set_multibody_3(struct sip_msg* msg, char*, char *, char *);
+static int append_multibody_2(struct sip_msg* msg, char*, char *);
+static int append_multibody_3(struct sip_msg* msg, char*, char *, char *);
+static int fixup_multibody_f(void** param, int param_no);
+static int remove_multibody_f(struct sip_msg *msg, char *);
static int is_method_f(struct sip_msg* msg, char* , char *);
static int has_body_f(struct sip_msg *msg, char *type, char *str2 );
static int in_list_f(struct sip_msg* _msg, char* _subject, char* _list,
@@ -275,6 +283,27 @@ static cmd_export_t cmds[]={
{"bind_textops", (cmd_function)bind_textops, 0, 0, 0,
0},
+ {"set_body_multipart", (cmd_function)set_multibody_0, 0,
+ 0, 0,
+ REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
+ {"set_body_multipart", (cmd_function)set_multibody_1, 1,
+ fixup_spve_null, 0,
+ REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
+ {"set_body_multipart", (cmd_function)set_multibody_2, 2,
+ fixup_spve_spve, 0,
+ REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
+ {"set_body_multipart", (cmd_function)set_multibody_3, 3,
+ fixup_multibody_f, 0,
+ REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
+ {"append_body_part", (cmd_function)append_multibody_2, 2,
+ fixup_spve_spve, 0,
+ REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
+ {"append_body_part", (cmd_function)append_multibody_3, 3,
+ fixup_multibody_f, 0,
+ REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
+ {"remove_body_part", (cmd_function)remove_multibody_f, 1,
+ fixup_spve_null, 0,
+ REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
{0,0,0,0,0,0}
};
@@ -866,6 +895,23 @@ static inline int find_line_start(char *text, unsigned int text_len,
return 0;
}
+/**
+ * return:
+ * 1: multipart
+ */
+static int check_multipart(struct sip_msg *msg)
+{
+ int mime;
+
+ /* the function search for and parses the Content-Type hdr */
+ mime = parse_content_type_hdr (msg);
+ if(mime<0) {
+ LM_ERR("failed to extract content type hdr\n");
+ return -1;
+ }
+ if(mime!=MIMETYPE(MULTIPART,MIXED)) return 0;
+ return 1;
+}
/* Filters multipart/mixed body by leaving out everything else except
* first body part of given content type. */
@@ -874,10 +920,8 @@ static int filter_body_f(struct sip_msg* msg, char* _content_type,
{
char *start;
unsigned int len;
- str *content_type, body, params, boundary;
- param_hooks_t hooks;
- param_t *p, *list;
- unsigned int mime;
+ str *content_type, body;
+ str boundary = {0,0};
body.s = get_body(msg);
if (body.s == 0) {
@@ -889,106 +933,73 @@ static int filter_body_f(struct sip_msg* msg, char* _content_type,
LM_DBG("message body has zero length\n");
return -1;
}
-
- content_type = (str *)_content_type;
- mime = parse_content_type_hdr(msg);
- if (mime <= 0) {
- LM_ERR("failed to parse Content-Type hdr\n");
- return -1;
- }
- if (mime != ((TYPE_MULTIPART << 16) + SUBTYPE_MIXED)) {
- LM_ERR("content type is not multipart/mixed\n");
- return -1;
- }
-
- params.s = memchr(msg->content_type->body.s, ';',
- msg->content_type->body.len);
- if (params.s == NULL) {
- LM_ERR("Content-Type hdr has no params\n");
- return -1;
- }
- params.len = msg->content_type->body.len -
- (params.s - msg->content_type->body.s);
- if (parse_params(&params, CLASS_ANY, &hooks, &list) < 0) {
- LM_ERR("while parsing Content-Type params\n");
- return -1;
- }
- boundary.s = NULL;
- boundary.len = 0;
- for (p = list; p; p = p->next) {
- if ((p->name.len == 8)
- && (strncasecmp(p->name.s, "boundary", 8) == 0)) {
- boundary.s = pkg_malloc(p->body.len + 2);
- if (boundary.s == NULL) {
- free_params(list);
- LM_ERR("no memory for boundary string\n");
- return -1;
- }
- *(boundary.s) = '-';
- *(boundary.s + 1) = '-';
- memcpy(boundary.s + 2, p->body.s, p->body.len);
- boundary.len = 2 + p->body.len;
- LM_DBG("boundary is <%.*s>\n", boundary.len, boundary.s);
- break;
- }
+ if(check_multipart(msg)!=1) {
+ LM_WARN("body not multipart\n");
+ return -1;
}
- free_params(list);
- if (boundary.s == NULL) {
- LM_ERR("no mandatory param \";boundary\"\n");
- return -1;
+ if(get_boundary(msg, &boundary)!=0) {
+ return -1;
}
-
+ content_type = (str *)_content_type;
start = body.s;
len = body.len;
-
- while (find_line_start("Content-Type: ", 14, &start, &len)) {
- start = start + 14;
- len = len - 14;
- if (len > content_type->len + 2) {
- if (strncasecmp(start, content_type->s, content_type->len)
- == 0) {
- LM_DBG("found content type %.*s\n",
- content_type->len, content_type->s);
- start = start + content_type->len;
- if ((*start != 13) || (*(start + 1) != 10)) {
- LM_ERR("no CRLF found after content type\n");
- goto err;
- }
- start = start + 2;
- len = len - content_type->len - 2;
- while ((len > 0) && ((*start == 13) || (*start == 10))) {
- len = len - 1;
- start = start + 1;
- }
- if (del_lump(msg, body.s - msg->buf, start - body.s, 0)
- == 0) {
- LM_ERR("deleting lump <%.*s> failed\n",
- (int)(start - body.s), body.s);
- goto err;
- }
- if (find_line_start(boundary.s, boundary.len, &start,
- &len)) {
- if (del_lump(msg, start - msg->buf, len, 0) == 0) {
- LM_ERR("deleting lump <%.*s> failed\n",
- len, start);
- goto err;
- } else {
- pkg_free(boundary.s);
- return 1;
+
+ while (find_line_start("Content-Type: ", 14, &start, &len))
+ {
+ start = start + 14;
+ len = len - 14;
+ LM_DBG("line: [%.*s]\n", len, start);
+ if (len > content_type->len + 2) {
+ if (strncasecmp(start, content_type->s, content_type->len)== 0)
+ {
+ LM_DBG("found content type %.*s\n",
+ content_type->len, content_type->s);
+ start = start + content_type->len;
+ if ((*start != 13) || (*(start + 1) != 10))
+ {
+ LM_ERR("no CRLF found after content type\n");
+ goto err;
+ }
+ start = start + 2;
+ len = len - content_type->len - 2;
+ while ((len > 0) && ((*start == 13) || (*start == 10)))
+ {
+ len = len - 1;
+ start = start + 1;
+ }
+ if (del_lump(msg, body.s - msg->buf, start - body.s, 0)== 0)
+ {
+ LM_ERR("deleting lump <%.*s> failed\n",
+ (int)(start - body.s), body.s);
+ goto err;
+ }
+ if (find_line_start(boundary.s, boundary.len, &start,
+ &len))
+ {
+ if (del_lump(msg, start - msg->buf, len, 0) == 0)
+ {
+ LM_ERR("deleting lump <%.*s> failed\n", len, start);
+ goto err;
+ }
+ else
+ {
+ pkg_free(boundary.s);
+ return 1;
+ }
+ }
+ else
+ {
+ LM_ERR("boundary not found after content\n");
+ goto err;
+ }
}
- } else {
- LM_ERR("boundary not found after content\n");
+ } else {
goto err;
- }
}
- } else {
- pkg_free(boundary.s);
- return -1;
- }
}
err:
- pkg_free(boundary.s);
+ if(boundary.s) pkg_free(boundary.s);
return -1;
}
@@ -1444,7 +1455,575 @@ static int set_rpl_body_f(struct sip_msg* msg, char* p1, char* p2)
return 1;
}
+static str* generate_boundary(str txt, str content_type,
+ str content_disposition, str delimiter, unsigned int initial)
+{
+ unsigned int i = 0;
+ str cth = {"Content-Type: ", 14};
+ str cdh = {"Content-Disposition: ", 21};
+ str* n;
+ unsigned int flag = 0;
+ if(txt.len==0||content_type.len==0||delimiter.len==0)
+ {
+ LM_ERR("invalid parameters\n");
+ return NULL;
+ }
+ n = pkg_malloc(sizeof(str));
+ if(n==NULL)
+ {
+ LM_ERR("out of pkg memory\n");
+ return NULL;
+ }
+ n->len = delimiter.len + 2 + CRLF_LEN;
+ if(initial) n->len = 2*n->len;
+ if(strncmp("\r\n\r\n", txt.s+txt.len-4,4)!=0)
+ {
+ n->len = n->len + CRLF_LEN;
+ flag = 1;
+ LM_DBG("adding final CRLF+CRLF\n");
+ }
+ n->len=n->len + cth.len + content_type.len + 2*CRLF_LEN;
+ if(content_disposition.len>0)
+ {
+ n->len = n->len + cdh.len + content_disposition.len + CRLF_LEN;
+ }
+ n->len = n->len + txt.len;
+
+ n->s = pkg_malloc(sizeof(char)*(n->len));
+ if(n->s==0)
+ {
+ LM_ERR("out of pkg memory\n");
+ pkg_free(n);
+ return NULL;
+ }
+ if(initial)
+ {
+ memcpy(n->s, "--", 2); i=2;
+ memcpy(n->s+i, delimiter.s, delimiter.len); i=i+delimiter.len;
+ memcpy(n->s+i, CRLF, CRLF_LEN); i=i+CRLF_LEN;
+ }
+
+ memcpy(n->s+i, cth.s, cth.len); i=i+cth.len;
+ memcpy(n->s+i, content_type.s, content_type.len); i=i+content_type.len;
+ memcpy(n->s+i, CRLF, CRLF_LEN); i=i+CRLF_LEN;
+
+ if(content_disposition.len>0)
+ {
+ memcpy(n->s+i, cdh.s, cdh.len); i=i+cdh.len;
+ memcpy(n->s+i, content_disposition.s, content_disposition.len);
+ i=i+content_disposition.len;
+ memcpy(n->s+i, CRLF, CRLF_LEN); i=i+CRLF_LEN;
+ }
+ memcpy(n->s+i, CRLF, CRLF_LEN); i=i+CRLF_LEN;
+
+ memcpy(n->s+i, txt.s, txt.len); i=i+txt.len;
+ if(flag) { memcpy(n->s+i, CRLF, CRLF_LEN); i=i+CRLF_LEN; }
+
+ memcpy(n->s+i, "--", 2); i=i+2;
+ memcpy(n->s+i, delimiter.s, delimiter.len); i=i+delimiter.len;
+ memcpy(n->s+i, CRLF, CRLF_LEN); i=i+CRLF_LEN;
+
+ if(i!=n->len)
+ {
+ LM_ERR("out of bounds\n");
+ }
+ return n;
+}
+
+int set_multibody_helper(struct sip_msg* msg, char* p1, char* p2, char* p3)
+{
+ struct lump *anchor;
+ char* buf = NULL;
+ int len;
+ char* value_s;
+ int value_len;
+ str body = {0,0};
+ str nb = {0,0};
+ str oc = {0,0};
+ str cd = {0,0};
+ str delimiter = {0,0};
+ str default_delimiter = {"unique-boundary-1", 17};
+ str nc = {0,0};
+ str cth = {"Content-Type: ", 14};
+ str* nbb;
+ unsigned int convert = 0;
+ fparam_t header;
+ header.orig = NULL;
+ header.type = FPARAM_STR;
+ header.v.str.s = "Mime-Version: 1.0\r\n";
+ header.v.str.len = 19;
+
+ if(p3==0)
+ {
+ delimiter.s = default_delimiter.s;
+ delimiter.len = default_delimiter.len;
+ }
+ else
+ {
+ if(fixup_get_svalue(msg, (gparam_p)p3, &delimiter)!=0)
+ {
+ LM_ERR("unable to get p3\n");
+ return -1;
+ }
+ if(delimiter.s==NULL || delimiter.len == 0)
+ {
+ LM_ERR("invalid boundary parameter\n");
+ return -1;
+ }
+ }
+ LM_DBG("delimiter<%d>:[%.*s]\n", delimiter.len, delimiter.len, delimiter.s);
+ if(p1==0 || p2==0)
+ {
+ if(check_multipart(msg)==1) {
+ LM_WARN("body is already multipart. Do nothing\n");
+ return -1;
+ }
+ convert = 1;
+ }
+ else
+ {
+ if(fixup_get_svalue(msg, (gparam_p)p1, &nb)!=0)
+ {
+ LM_ERR("unable to get p1\n");
+ return -1;
+ }
+ if(nb.s==NULL || nb.len == 0)
+ {
+ LM_ERR("invalid body parameter\n");
+ return -1;
+ }
+ if(fixup_get_svalue(msg, (gparam_p)p2, &oc)!=0)
+ {
+ LM_ERR("unable to get p2\n");
+ return -1;
+ }
+ if(oc.s==NULL || oc.len==0)
+ {
+ LM_ERR("invalid content-type parameter\n");
+ return -1;
+ }
+ if(check_multipart(msg)==1) {
+ convert = -1;
+ }
+ }
+
+ body.len = 0;
+ body.s = get_body(msg);
+ if(body.s==0)
+ {
+ LM_ERR("malformed sip message\n");
+ return -1;
+ }
+ body.len = msg->len -(int)(body.s-msg->buf);
+
+ del_nonshm_lump( &(msg->body_lumps) );
+ msg->body_lumps = NULL;
+
+ if(msg->content_length)
+ {
+ if(body.len > 0)
+ {
+ if(body.s+body.len>msg->buf+msg->len)
+ {
+ LM_ERR("invalid content length: %d\n", body.len);
+ return -1;
+ }
+ if(convert==1)
+ {
+ /* need to copy body */
+ nb.s=pkg_malloc(sizeof(char)*body.len);
+ if (nb.s==0)
+ {
+ LM_ERR("out of pkg memory\n");
+ return -1;
+ }
+ memcpy(nb.s, body.s, body.len);
+ nb.len = body.len;
+ if(msg->content_type!=NULL && msg->content_type->body.s!=NULL)
+ {
+ oc.len = msg->content_type->body.len;
+ oc.s=pkg_malloc(sizeof(char)*oc.len);
+ if (oc.s==0)
+ {
+ LM_ERR("out of pkg memory\n");
+ goto error;
+ }
+ memcpy(oc.s, msg->content_type->body.s, oc.len);
+ }
+ }
+ if(del_lump(msg, body.s-msg->buf, body.len, 0) == 0)
+ {
+ LM_ERR("cannot delete existing body");
+ goto error;
+ }
+ }
+ }
+
+ anchor = anchor_lump(msg, msg->unparsed-msg->buf, 0, 0);
+ if(anchor==0)
+ {
+ LM_ERR("failed to get anchor\n");
+ goto error;
+ }
+
+ /* get initial boundary */
+ nbb = generate_boundary(nb, oc, cd, delimiter, 1);
+ if(nbb==NULL)
+ {
+ LM_ERR("couldn't create initial boundary\n");
+ goto error;
+ }
+
+ if(msg->content_length==0)
+ {
+ /* need to add Content-Length */
+ len = nbb->len;
+ value_s=int2str(len, &value_len);
+
+ len=CONTENT_LENGTH_LEN+value_len+CRLF_LEN;
+ buf=pkg_malloc(sizeof(char)*len);
+
+ if (buf==0)
+ {
+ LM_ERR("out of pkg memory\n");
+ goto error;
+ }
+
+ memcpy(buf, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
+ memcpy(buf+CONTENT_LENGTH_LEN, value_s, value_len);
+ memcpy(buf+CONTENT_LENGTH_LEN+value_len, CRLF, CRLF_LEN);
+ if (insert_new_lump_after(anchor, buf, len, 0) == 0)
+ {
+ LM_ERR("failed to insert content-length lump\n");
+ goto error;
+ }
+ buf = NULL;
+ }
+
+ if(convert!=-1)
+ {
+ /* set new content type with delimiter */
+ nc.len = delimiter.len + 27;
+ nc.s = pkg_malloc(sizeof(char)*nc.len);
+ memcpy(nc.s, "multipart/mixed;boundary=\"", 26);
+ memcpy(nc.s+26, delimiter.s, delimiter.len);
+ nc.s[26+delimiter.len] = '"';
+ LM_DBG("content-type<%d>:[%.*s]\n", nc.len, nc.len, nc.s);
+ /* add content-type */
+ if(msg->content_type==NULL || msg->content_type->body.len!=nc.len
+ || strncmp(msg->content_type->body.s, nc.s, nc.len)!=0)
+ {
+ if(msg->content_type!=NULL)
+ if(del_lump(msg, msg->content_type->name.s-msg->buf,
+ msg->content_type->len, 0) == 0)
+ {
+ LM_ERR("failed to delete content type\n");
+ goto error;
+ }
+ value_len = nc.len;
+ len = cth.len + value_len + CRLF_LEN;
+ buf = pkg_malloc(sizeof(char)*len);
+
+ if(buf==0)
+ {
+ LM_ERR("out of pkg memory\n");
+ goto error;
+ }
+ memcpy(buf, cth.s, cth.len);
+ memcpy(buf + cth.len, nc.s, value_len);
+ memcpy(buf + cth.len + value_len, CRLF, CRLF_LEN);
+ if (insert_new_lump_after(anchor, buf, len, 0) == 0)
+ {
+ LM_ERR("failed to insert content-type lump\n");
+ goto error;
+ }
+ buf = NULL;
+ }
+ /* add Mime-Version header */
+ if(add_hf_helper(msg, 0, 0, &header, 0, 0)<0)
+ {
+ LM_ERR("failed to add Mime-Version header\n");
+ goto error;
+ }
+ }
+ anchor = anchor_lump(msg, body.s - msg->buf, 0, 0);
+ if(anchor==0)
+ {
+ LM_ERR("failed to get body anchor\n");
+ goto error;
+ }
+
+ if(insert_new_lump_after(anchor, nbb->s, nbb->len, 0)==0)
+ {
+ LM_ERR("failed to insert body lump\n");
+ goto error;
+ }
+ pkg_free(nbb);
+ if(nc.s!=NULL) pkg_free(nc.s);
+ LM_DBG("set flag FL_BODY_MULTIPART\n");
+ msg->msg_flags |= FL_BODY_MULTIPART;
+ return 1;
+
+error:
+ if(nbb!=NULL) { pkg_free(nbb->s); pkg_free(nbb); }
+ if(nc.s!=NULL) pkg_free(nc.s);
+ if(buf!=NULL) pkg_free(buf);
+ if(convert && nb.s!=NULL) pkg_free(nb.s);
+ if(convert && oc.s!=NULL) pkg_free(oc.s);
+ return -1;
+}
+
+static int set_multibody_0(struct sip_msg* msg, char* p1, char* p2, char* p3)
+{
+ return set_multibody_helper(msg, NULL, NULL, NULL);
+}
+
+static int set_multibody_1(struct sip_msg* msg, char* p1, char* p2, char* p3)
+{
+ return set_multibody_helper(msg, NULL, NULL, p1);
+}
+
+static int set_multibody_2(struct sip_msg* msg, char* p1, char* p2, char* p3)
+{
+ return set_multibody_helper(msg, p1, p2, NULL);
+}
+
+static int set_multibody_3(struct sip_msg* msg, char* p1, char* p2, char *p3)
+{
+ return set_multibody_helper(msg, p1, p2, p3);
+}
+
+int append_multibody_helper(struct sip_msg* msg, char* p1, char* p2, char* p3)
+{
+ struct lump *l;
+ int off;
+ str body = {0,0};
+ str nc = {0,0};
+ str cd = {0,0};
+ str txt = {0,0};
+ str* nbb = NULL;
+ str delimiter = {0,0};
+
+ if(p1==0 || p2==0)
+ {
+ LM_ERR("invalid parameters\n");
+ return -1;
+ }
+
+ if(fixup_get_svalue(msg, (gparam_p)p1, &txt)!=0)
+ {
+ LM_ERR("unable to get p1\n");
+ return -1;
+ }
+ if(txt.s==NULL || txt.len==0)
+ {
+ LM_ERR("invalid body parameter\n");
+ return -1;
+ }
+ if(fixup_get_svalue(msg, (gparam_p)p2, &nc)!=0)
+ {
+ LM_ERR("unable to get p2\n");
+ return -1;
+ }
+ if(nc.s==NULL || nc.len==0)
+ {
+ LM_ERR("invalid content-type parameter\n");
+ return -1;
+ }
+ if(p3!=NULL)
+ {
+ if(fixup_get_svalue(msg, (gparam_p)p3, &cd)!=0)
+ {
+ LM_ERR("unable to get p3\n");
+ return -1;
+ }
+ }
+
+ body.s = get_body(msg);
+ if(body.s==0) {
+ LM_ERR("failed to get the message body\n");
+ return -1;
+ }
+ body.len = msg->len -(int)(body.s-msg->buf);
+ if(body.len==0) {
+ LM_DBG("message body has zero length\n");
+ return -1;
+ }
+
+ off=body.s-msg->buf;
+ if((l=anchor_lump(msg, off+body.len, 0, 0))==0)
+ {
+ LM_ERR("WTF\n");
+ return -1;
+ }
+ /* get boundary */
+ if(get_boundary(msg, &delimiter)!=0) {
+ LM_ERR("Cannot get boundary. Is body multipart?\n");
+ return -1;
+ }
+ nbb = generate_boundary(txt, nc, cd, delimiter, 0);
+ if(nbb==NULL)
+ {
+ LM_ERR("couldn't create initial boundary\n");
+ pkg_free(delimiter.s);
+ return -1;
+ }
+ pkg_free(delimiter.s);
+ if(insert_new_lump_after(l, nbb->s, nbb->len, 0)==0){
+ LM_ERR("could not insert new lump\n");
+ pkg_free(nbb->s); pkg_free(nbb);
+ return -1;
+ }
+ pkg_free(nbb);
+ if(!(msg->msg_flags&FL_BODY_MULTIPART))
+ {
+ LM_DBG("set flag FL_BODY_MULTIPART\n");
+ msg->msg_flags |= FL_BODY_MULTIPART;
+ }
+ return 1;
+}
+
+static int append_multibody_2(struct sip_msg* msg, char* p1, char* p2)
+{
+ return append_multibody_helper(msg, p1, p2, NULL);
+}
+
+static int append_multibody_3(struct sip_msg* msg, char* p1, char* p2, char *p3)
+{
+ return append_multibody_helper(msg, p1, p2, p3);
+}
+
+static int fixup_multibody_f(void** param, int param_no)
+{
+ int ret;
+ fparam_t* fp;
+
+ if(param_no<=3){
+ if((ret=fix_param_types(FPARAM_PVE, param))<0){
+ ERR("Cannot convert function parameter %d to spve \n",
+ param_no);
+ return E_UNSPEC;
+ } else {
+ fp=(fparam_t*)*param;
+ if((ret==0) && (fp->v.pve->spec==0
+ || fp->v.pve->spec->getf==0)){
+ fparam_free_restore(param);
+ return fix_param_types(FPARAM_STR, param);
+ } else if(ret==1)
+ return fix_param_types(FPARAM_STR, param);
+ return ret;
+ }
+ } else {
+ LM_ERR("wrong number of parameters\n");
+ return E_UNSPEC;
+ }
+}
+
+static inline int get_line(char *s, int len)
+{
+ char *ch;
+
+ if ((ch = memchr(s, 13, len))) {
+ if (*(ch + 1) != 10) {
+ LM_ERR("No LF after CR\n");
+ return 0;
+ }
+ return ch - s + 2;
+ } else {
+ LM_ERR("No CRLF found\n");
+ return len;
+ }
+ return 0;
+}
+
+static int remove_multibody_f(struct sip_msg* msg, char* p1)
+{
+ char *start, *end;
+ unsigned int len, t;
+ str content_type, body;
+ str boundary = {0,0};
+
+ if(p1==0)
+ {
+ LM_ERR("invalid parameters\n");
+ return -1;
+ }
+
+ if(fixup_get_svalue(msg, (gparam_p)p1, &content_type)!=0)
+ {
+ LM_ERR("unable to get p1\n");
+ return -1;
+ }
+
+ body.s = get_body(msg);
+ if (body.s == 0) {
+ LM_ERR("failed to get the message body\n");
+ return -1;
+ }
+ body.len = msg->len - (int)(body.s - msg->buf);
+ if (body.len == 0) {
+ LM_DBG("message body has zero length\n");
+ return -1;
+ }
+
+ if(get_boundary(msg, &boundary)!=0) {
+ LM_ERR("Cannot get boundary. Is body multipart?\n");
+ return -1;
+ }
+
+ start = body.s;
+ len = body.len;
+
+ while (find_line_start("Content-Type: ", 14, &start, &len))
+ {
+ end = start + 14;
+ len = len - 14;
+ if (len > (content_type.len + 2)) {
+ if (strncasecmp(end, content_type.s, content_type.len)== 0)
+ {
+ LM_DBG("found content type %.*s\n",
+ content_type.len, content_type.s);
+ end = end + content_type.len;
+ if ((*end != 13) || (*(end + 1) != 10))
+ {
+ LM_ERR("no CRLF found after content type\n");
+ goto err;
+ }
+ end = end + 2;
+ len = len - content_type.len - 2;
+ if (find_line_start(boundary.s, boundary.len, &end,
+ &len))
+ {
+ LM_DBG("found boundary %.*s\n", boundary.len, boundary.s);
+ end = end + boundary.len;
+ len = len - boundary.len;
+ if (!(t = get_line(end, len))) goto err;
+ end += t; len = end-start;
+ if (del_lump(msg, start - msg->buf, len, 0) == 0)
+ {
+ LM_ERR("deleting lump <%.*s> failed\n", len, start);
+ goto err;
+ }
+ pkg_free(boundary.s);
+ if(!(msg->msg_flags&FL_BODY_MULTIPART))
+ {
+ LM_DBG("set flag FL_BODY_MULTIPART\n");
+ msg->msg_flags |= FL_BODY_MULTIPART;
+ }
+ return 1;
+ }
+ LM_ERR("boundary not found after content\n");
+ goto err;
+ }
+ start = end;
+ }
+ else goto err;
+ }
+ err:
+ pkg_free(boundary.s);
+ return -1;
+}
static int append_to_reply_f(struct sip_msg* msg, char* key, char* str0)
{
--
2.0.0.rc0

@ -1,163 +0,0 @@
From 2be579ffa48c1445a5c768b4a9b6a6532ac58363 Mon Sep 17 00:00:00 2001
From: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Sun, 16 Mar 2014 10:04:38 +0100
Subject: [PATCH] textops: add new multipart functions documentation
---
modules/textops/doc/textops_admin.xml | 140 ++++++++++++++++++++++++++++++++++
1 file changed, 140 insertions(+)
diff --git a/modules/textops/doc/textops_admin.xml b/modules/textops/doc/textops_admin.xml
index e76e921..af9057a 100644
--- a/modules/textops/doc/textops_admin.xml
+++ b/modules/textops/doc/textops_admin.xml
@@ -1358,6 +1358,146 @@ if (starts_with("$rU", "+358"))
</example>
</section>
+ <section id="textops.f.set_body_multipart">
+ <title>
+ <function moreinfo="none">set_body_multipart([txt,content_type][,boundary])</function>
+ </title>
+ <para>
+ Set multipart body to a SIP message. If called with no parameters, will convert
+ present body to multipart.
+ </para>
+ <para>Meaning of the parameters is as follows:</para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>txt</emphasis> - text for the body, can include
+ pseudo-variables.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>content_type</emphasis> - value of Content-Type header,
+ can include pseudo-variables.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>boundary</emphasis> - string to use as boundary,
+ can include pseudo-variables. Default: unique-boundary-1
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.
+ </para>
+ <para>
+ The core will take care of the last boundary ending "--". Detecting wich one is
+ the last and fixing the others if needed.
+ </para>
+ <example>
+ <title><function>set_body_multipart</function> usage</title>
+ <programlisting format="linespecific">
+...
+set_body_multipart("test", "text/plain", "delimiter");
+...
+Will produce:
+...
+Content-Type: multipart/mixed;boundary="delimiter"
+Mime-Version: 1.0
+
+--delimiter
+Content-Type: text/plain
+
+text
+
+--delimiter
+...
+</programlisting>
+ </example>
+ </section>
+
+ <section id="textops.f.append_body_part">
+ <title>
+ <function moreinfo="none">append_body_part(txt,content_type[, content_disposition])</function>
+ </title>
+ <para>
+ Append a part on multipart body SIP message. Will use "unique-boundary-1" as boundary.
+ </para>
+ <para>Meaning of the parameters is as follows:</para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>txt</emphasis> - text for the multipart body, can include
+ pseudo-variables.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>content_type</emphasis> - value of Content-Type header,
+ can include pseudo-variables.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>content_disposition</emphasis> - value of Content-Disposition header,
+ can include pseudo-variables.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.
+ </para>
+ <para>
+ The core will take care of the last boundary ending "--". Detecting wich one is
+ the last and fixing the others if needed.
+ </para>
+ <example>
+ <title><function>append_body_part</function> usage</title>
+ <programlisting format="linespecific">
+...
+$var(b) = "7e Od 04 55 75 69 20 4d 61 6b 65 43 61 6c 6c"
+append_body_part("$var(b)", "application/vnd.cirpack.isdn-ext", "signal;handling=required");
+...
+Will append this the body:
+...
+Content-Type: application/vnd.cirpack.isdn-ext
+Content-Disposition: signal;handling=required
+
+7e Od 04 55 75 69 20 4d 61 6b 65 43 61 6c 6c
+
+--unique-boundary-1
+...
+</programlisting>
+ </example>
+ </section>
+
+ <section id="textops.f.remove_body_part">
+ <title>
+ <function moreinfo="none">remove_body_part(content_type)</function>
+ </title>
+ <para>
+ Remove a part on a multipart body SIP message.
+ </para>
+ <para>Meaning of the parameters is as follows:</para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>content_type</emphasis> - value of Content-Type header
+ of the part to be removed. If more than one exists the first
+ occurrence will be removed.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.
+ </para>
+ <para>
+ The core will take care of the last boundary ending "--". Detecting wich one is
+ the last and fixing the others if needed.
+ </para>
+ <example>
+ <title><function>remove_body_part</function> usage</title>
+ <programlisting format="linespecific">
+...
+remove_body_part("application/vnd.cirpack.isdn-ext");
+...
+</programlisting>
+ </example>
+ </section>
+
</section>
<section>
<title>Known Limitations</title>
--
2.0.0.rc0

File diff suppressed because it is too large Load Diff

@ -1,290 +0,0 @@
From d03bed3fae3426b19b064129d4296a707bce1de8 Mon Sep 17 00:00:00 2001
From: Sipwise Development Team <support@sipwise.com>
Date: Wed, 20 May 2015 15:10:55 +0200
Subject: [PATCH] db_postgres-timeout
Gbp-Pq-Topic: sipwise
---
modules/db_postgres/km_dbase.c | 43 +++++++++++++++++++++++++++++++++++++++++
modules/db_postgres/km_pg_con.c | 36 ++++++++++++++++++++++++++++++++--
modules/db_postgres/pg_con.c | 38 +++++++++++++++++++++++++++++++-----
modules/db_postgres/pg_mod.c | 4 ++++
modules/db_postgres/pg_mod.h | 2 ++
5 files changed, 116 insertions(+), 7 deletions(-)
diff --git a/modules/db_postgres/km_dbase.c b/modules/db_postgres/km_dbase.c
index 21c9cea..633959d 100644
--- a/modules/db_postgres/km_dbase.c
+++ b/modules/db_postgres/km_dbase.c
@@ -167,6 +167,10 @@ static int db_postgres_submit_query(const db1_con_t* _con, const str* _s)
int i, retries;
ExecStatusType pqresult;
PGresult *res = NULL;
+ int sock, ret;
+ fd_set fds;
+ time_t max_time;
+ struct timeval wait_time;
if(! _con || !_s || !_s->s)
{
@@ -217,6 +221,44 @@ static int db_postgres_submit_query(const db1_con_t* _con, const str* _s)
/* exec the query */
if (PQsendQuery(CON_CONNECTION(_con), s)) {
+ if (pg_timeout <= 0)
+ goto do_read;
+
+ max_time = time(NULL) + pg_timeout;
+
+ while (1) {
+ sock = PQsocket(CON_CONNECTION(_con));
+ FD_ZERO(&fds);
+ FD_SET(sock, &fds);
+
+ wait_time.tv_usec = 0;
+ wait_time.tv_sec = max_time - time(NULL);
+ if (wait_time.tv_sec <= 0 || wait_time.tv_sec > 0xffffff)
+ goto timeout;
+
+ ret = select(sock + 1, &fds, NULL, NULL, &wait_time);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ LM_WARN("select() error\n");
+ goto reset;
+ }
+ if (!ret) {
+timeout:
+ LM_WARN("timeout waiting for postgres reply\n");
+ goto reset;
+ }
+
+ if (!PQconsumeInput(CON_CONNECTION(_con))) {
+ LM_WARN("error reading data from postgres server: %s\n",
+ PQerrorMessage(CON_CONNECTION(_con)));
+ goto reset;
+ }
+ if (!PQisBusy(CON_CONNECTION(_con)))
+ break;
+ }
+
+do_read:
/* Get the result of the query */
while ((res = PQgetResult(CON_CONNECTION(_con))) != NULL) {
db_postgres_free_query(_con);
@@ -239,6 +281,7 @@ static int db_postgres_submit_query(const db1_con_t* _con, const str* _s)
PQerrorMessage(CON_CONNECTION(_con)));
if(PQstatus(CON_CONNECTION(_con))!=CONNECTION_OK)
{
+reset:
LM_DBG("reseting the connection to postgress server\n");
PQreset(CON_CONNECTION(_con));
}
diff --git a/modules/db_postgres/km_pg_con.c b/modules/db_postgres/km_pg_con.c
index 92acc75..9cac456 100644
--- a/modules/db_postgres/km_pg_con.c
+++ b/modules/db_postgres/km_pg_con.c
@@ -26,12 +26,15 @@
*/
#include "km_pg_con.h"
+#include "pg_mod.h"
#include "../../mem/mem.h"
#include "../../dprint.h"
#include "../../ut.h"
#include "../../tls_hooks_init.h"
#include <string.h>
#include <time.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
/*!
@@ -46,6 +49,9 @@ struct pg_con* db_postgres_new_connection(struct db_id* id)
{
struct pg_con* ptr;
char *ports;
+ int i = 0;
+ const char *keywords[10], *values[10];
+ char to[16];
LM_DBG("db_id = %p\n", id);
@@ -67,6 +73,8 @@ struct pg_con* db_postgres_new_connection(struct db_id* id)
if (id->port) {
ports = int2str(id->port, 0);
+ keywords[i] = "port";
+ values[i++] = ports;
LM_DBG("opening connection: postgres://xxxx:xxxx@%s:%d/%s\n", ZSW(id->host),
id->port, ZSW(id->database));
} else {
@@ -75,11 +83,27 @@ struct pg_con* db_postgres_new_connection(struct db_id* id)
ZSW(id->database));
}
+ keywords[i] = "host";
+ values[i++] = id->host;
+ keywords[i] = "dbname";
+ values[i++] = id->database;
+ keywords[i] = "user";
+ values[i++] = id->username;
+ keywords[i] = "password";
+ values[i++] = id->password;
+ if (pg_timeout > 0) {
+ snprintf(to, sizeof(to)-1, "%d", pg_timeout + 3);
+ keywords[i] = "connect_timeout";
+ values[i++] = to;
+ }
+
+ keywords[i] = values[i] = NULL;
+
/* don't attempt to re-init openssl if done already */
if(tls_loaded()) PQinitSSL(0);
- ptr->con = PQsetdbLogin(id->host, ports, NULL, NULL, id->database, id->username, id->password);
- LM_DBG("PQsetdbLogin(%p)\n", ptr->con);
+ ptr->con = PQconnectdbParams(keywords, values, 1);
+ LM_DBG("PQconnectdbParams(%p)\n", ptr->con);
if( (ptr->con == 0) || (PQstatus(ptr->con) != CONNECTION_OK) )
{
@@ -92,6 +116,14 @@ struct pg_con* db_postgres_new_connection(struct db_id* id)
ptr->timestamp = time(0);
ptr->id = id;
+#if defined(SO_KEEPALIVE) && defined(TCP_KEEPIDLE)
+ if (pg_keepalive) {
+ i = 1;
+ setsockopt(PQsocket(ptr->con), SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i));
+ setsockopt(PQsocket(ptr->con), IPPROTO_TCP, TCP_KEEPIDLE, &pg_keepalive, sizeof(pg_keepalive));
+ }
+#endif
+
return ptr;
err:
diff --git a/modules/db_postgres/pg_con.c b/modules/db_postgres/pg_con.c
index 32b9be7..86c68fa 100644
--- a/modules/db_postgres/pg_con.c
+++ b/modules/db_postgres/pg_con.c
@@ -39,6 +39,7 @@
#include "pg_con.h"
#include "pg_uri.h"
#include "pg_sql.h"
+#include "pg_mod.h"
#include "../../mem/mem.h"
#include "../../dprint.h"
@@ -47,6 +48,7 @@
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
+#include <netinet/tcp.h>
#include <time.h>
@@ -237,7 +239,9 @@ int pg_con_connect(db_con_t* con)
struct pg_con* pcon;
struct pg_uri* puri;
char* port_str;
- int ret;
+ int ret, i = 0;
+ const char *keywords[10], *values[10];
+ char to[16];
pcon = DB_GET_PAYLOAD(con);
puri = DB_GET_PAYLOAD(con->uri);
@@ -251,6 +255,8 @@ int pg_con_connect(db_con_t* con)
if (puri->port > 0) {
port_str = int2str(puri->port, 0);
+ keywords[i] = "port";
+ values[i++] = port_str;
} else {
port_str = NULL;
}
@@ -260,12 +266,26 @@ int pg_con_connect(db_con_t* con)
pcon->con = NULL;
}
- pcon->con = PQsetdbLogin(puri->host, port_str,
- NULL, NULL, puri->database,
- puri->username, puri->password);
+ keywords[i] = "host";
+ values[i++] = puri->host;
+ keywords[i] = "dbname";
+ values[i++] = puri->database;
+ keywords[i] = "user";
+ values[i++] = puri->username;
+ keywords[i] = "password";
+ values[i++] = puri->password;
+ if (pg_timeout > 0) {
+ snprintf(to, sizeof(to)-1, "%d", pg_timeout + 3);
+ keywords[i] = "connect_timeout";
+ values[i++] = to;
+ }
+
+ keywords[i] = values[i] = NULL;
+
+ pcon->con = PQconnectdbParams(keywords, values, 1);
if (pcon->con == NULL) {
- ERR("postgres: PQsetdbLogin ran out of memory\n");
+ ERR("postgres: PQconnectdbParams ran out of memory\n");
goto error;
}
@@ -285,6 +305,14 @@ int pg_con_connect(db_con_t* con)
PQprotocolVersion(pcon->con), 0 );
#endif
+#if defined(SO_KEEPALIVE) && defined(TCP_KEEPIDLE)
+ if (pg_keepalive) {
+ i = 1;
+ setsockopt(PQsocket(pcon->con), SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i));
+ setsockopt(PQsocket(pcon->con), IPPROTO_TCP, TCP_KEEPIDLE, &pg_keepalive, sizeof(pg_keepalive));
+ }
+#endif
+
ret = timestamp_format(pcon->con);
if (ret == 1 || ret == -1) {
/* Assume INT8 representation if detection fails */
diff --git a/modules/db_postgres/pg_mod.c b/modules/db_postgres/pg_mod.c
index 1b2d9f7..14f50a3 100644
--- a/modules/db_postgres/pg_mod.c
+++ b/modules/db_postgres/pg_mod.c
@@ -61,6 +61,8 @@ int pg_retries = 2; /* How many times should the module try re-execute failed c
* 0 disables reconnecting */
int pg_lockset = 4;
+int pg_timeout = 0; /* default = no timeout */
+int pg_keepalive = 0;
/*
* Postgres module interface
@@ -92,6 +94,8 @@ static cmd_export_t cmds[] = {
static param_export_t params[] = {
{"retries", PARAM_INT, &pg_retries },
{"lockset", PARAM_INT, &pg_lockset },
+ {"timeout", PARAM_INT, &pg_timeout },
+ {"tcp_keepalive", PARAM_INT, &pg_keepalive },
{0, 0, 0}
};
diff --git a/modules/db_postgres/pg_mod.h b/modules/db_postgres/pg_mod.h
index 10c0535..194c7df 100644
--- a/modules/db_postgres/pg_mod.h
+++ b/modules/db_postgres/pg_mod.h
@@ -41,6 +41,8 @@
*/
extern int pg_retries;
+extern int pg_timeout;
+extern int pg_keepalive;
/** @} */
--
2.1.4

@ -1,220 +0,0 @@
--- a/modules/nathelper/nathelper.c
+++ b/modules/nathelper/nathelper.c
@@ -344,6 +344,7 @@
static int natping_disable_flag = -1;
static int natping_processes = 1;
static int contact_only = 0;
+static int filter_socket = 0;
static str nortpproxy_str = str_init("a=nortpproxy:yes");
@@ -426,6 +427,7 @@
{"keepalive_timeout", INT_PARAM, &nh_keepalive_timeout },
{"udpping_from_path", INT_PARAM, &udpping_from_path },
{"contact_only", INT_PARAM, &contact_only },
+ {"filter_socket", INT_PARAM, &filter_socket },
{0, 0, 0}
};
@@ -2075,6 +2077,7 @@
char *path_ip_str = NULL;
unsigned int path_ip = 0;
unsigned short path_port = 0;
+ unsigned int options = 0;
if((*natping_state) == 0)
goto done;
@@ -2087,10 +2090,13 @@
goto done;
}
}
+
+ if(contact_only) options |= GAU_OPT_ONLY_CONTACT;
+ if(filter_socket) options |= GAU_OPT_FILTER_SOCKET;
+
rval = ul.get_all_ucontacts_opt(buf, cblen, (ping_nated_only?ul.nat_flag:0),
((unsigned int)(unsigned long)timer_idx)*natping_interval+iteration,
- natping_processes*natping_interval,
- contact_only ? GAU_OPT_ONLY_CONTACT : 0);
+ natping_processes*natping_interval, options);
if (rval<0) {
LM_ERR("failed to fetch contacts\n");
goto done;
@@ -2106,8 +2112,7 @@
}
rval = ul.get_all_ucontacts_opt(buf,cblen,(ping_nated_only?ul.nat_flag:0),
((unsigned int)(unsigned long)timer_idx)*natping_interval+iteration,
- natping_processes*natping_interval,
- contact_only ? GAU_OPT_ONLY_CONTACT : 0);
+ natping_processes*natping_interval, options);
if (rval != 0) {
pkg_free(buf);
goto done;
--- a/modules/usrloc/dlist.c
+++ b/modules/usrloc/dlist.c
@@ -79,6 +79,44 @@
return 1;
}
+int sprint_all_socket_lists(char **buf, int len)
+{
+ struct socket_info *si;
+ struct socket_info** list;
+ struct addr_info* ai;
+ unsigned short proto=PROTO_UDP;
+ unsigned int pos = 0;
+ size_t size = 0;
+ str s_proto = STR_NULL;
+ char *s = *buf;
+
+ list=get_sock_info_list(proto);
+ s_proto.s = get_valid_proto_name(proto);
+ s_proto.len = strlen(s_proto.s);
+
+ for(si=list?*list:0; si; si=si->next){
+ if (si->addr_info_lst)
+ {
+ for (ai=si->addr_info_lst; ai; ai=ai->next)
+ {
+ size = 5 + s_proto.len + ai->address_str.len + si->port_no_str.len;
+ if (pos + size + 1>len) return -1;
+ snprintf(s + pos, len-pos, ",'%s:%s:%s'",
+ s_proto.s, ai->address_str.s, si->port_no_str.s);
+ pos = pos + size;
+ }
+ }else{
+ size = 5 + s_proto.len + si->name.len + si->port_no_str.len;
+ if (pos + size + 1>len) return -1;
+ snprintf(s + pos, len-pos, ",'%s:%s:%s'",
+ s_proto.s, si->name.s, si->port_no_str.s);
+ pos = pos + size;
+ }
+ }
+
+ s[0] = '('; s[pos] = ')'; pos = pos + 1;
+ return pos;
+}
/*!
* \brief Get all contacts from the database, in partitions if wanted
@@ -96,6 +134,8 @@
unsigned int options)
{
static char query_buf[512];
+ static char socket_list[256];
+ static str socket_str;
static str query_str;
struct socket_info *sock;
@@ -115,8 +155,50 @@
int i;
void *cp;
int shortage, needed;
+ char *query_format = NULL;
+ db1_con_t* dbh = NULL;
+ db_func_t* dbf = NULL;
+
+ if (options & GAU_OPT_FILTER_SOCKET)
+ {
+ socket_str.s = socket_list;
+ socket_str.len = sprint_all_socket_lists(&socket_str.s, 256);
+ if(socket_str.len<0) {
+ LM_ERR("error generating socket_list parameter\n");
+ return -1;
+ }
+ query_format = "select %.*s, %.*s, %.*s,"
+ " %.*s, %.*s, %.*s from %s where %.*s > %.*s and"
+#ifdef ORACLE_USRLOC
+ " bitand(%.*s, %d) = %d and mod(id, %u) = %u and %.*s in %.*s";
+#else
+ " %.*s & %d = %d and id %% %u = %u and %.*s in %.*s";
+#endif
+ if(!ul_dbh_ro) {
+ LM_ERR("read-only connection not available. Using db_url\n");
+ dbh = ul_dbh;
+ dbf = &ul_dbf;
+ }
+ else
+ {
+ dbh = ul_dbh_ro;
+ dbf = &ul_dbf_ro;
+ }
+ }
+ else
+ {
+ query_format = "select %.*s, %.*s, %.*s,"
+ " %.*s, %.*s, %.*s from %s where %.*s > %.*s and"
+#ifdef ORACLE_USRLOC
+ " bitand(%.*s, %d) = %d and mod(id, %u) = %u";
+#else
+ " %.*s & %d = %d and id %% %u = %u";
+#endif
+ dbh = ul_dbh;
+ dbf = &ul_dbf;
+ }
- if(ul_dbf.raw_query==NULL) {
+ if(dbf->raw_query==NULL) {
LM_WARN("DB raw query support is required, but not implemented\n");
return -1;
}
@@ -136,13 +218,8 @@
for (dom = root; dom!=NULL ; dom=dom->next) {
/* build query */
- i = snprintf( query_buf, sizeof(query_buf), "select %.*s, %.*s, %.*s,"
- " %.*s, %.*s, %.*s from %s where %.*s > %.*s and"
-#ifdef ORACLE_USRLOC
- " bitand(%.*s, %d) = %d and mod(id, %u) = %u",
-#else
- " %.*s & %d = %d and id %% %u = %u",
-#endif
+ i = snprintf( query_buf, sizeof(query_buf),
+ query_format,
received_col.len, received_col.s,
contact_col.len, contact_col.s,
sock_col.len, sock_col.s,
@@ -153,19 +230,21 @@
expires_col.len, expires_col.s,
now_len, now_s,
cflags_col.len, cflags_col.s,
- flags, flags, part_max, part_idx);
+ flags, flags, part_max, part_idx,
+ sock_col.len, sock_col.s,
+ socket_str.len, socket_str.s);
if ( i>=sizeof(query_buf) ) {
LM_ERR("DB query too long\n");
return -1;
}
query_str.s = query_buf;
query_str.len = i;
- if ( ul_dbf.raw_query( ul_dbh, &query_str, &res)<0 ) {
+ if ( dbf->raw_query( dbh, &query_str, &res)<0 ) {
LM_ERR("raw_query failed\n");
return -1;
}
if( RES_ROW_N(res)==0 ) {
- ul_dbf.free_result(ul_dbh, res);
+ dbf->free_result(dbh, res);
continue;
}
@@ -269,7 +348,7 @@
len -= needed;
} /* row cycle */
- ul_dbf.free_result(ul_dbh, res);
+ dbf->free_result(dbh, res);
} /* domain cycle */
/* len < 0 is possible, if size of the buffer < sizeof(c->c.len) */
--- a/modules/usrloc/usrloc.h
+++ b/modules/usrloc/usrloc.h
@@ -43,6 +43,7 @@
#define DB_READONLY 4
#define GAU_OPT_ONLY_CONTACT (1<<0) /* ignore "received" address and always return contact */
+#define GAU_OPT_FILTER_SOCKET (1<<1) /* filter query by socket field */
/*forward declaration necessary for udomain*/
Loading…
Cancel
Save