mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2026-01-10 03:01:44 +01:00
main/kamailio: add srv_query function to ipops module
This commit is contained in:
parent
e211cfc6cb
commit
2bf3eba2ae
@ -13,7 +13,7 @@ _gittag=HEAD
|
||||
|
||||
|
||||
pkgver=4.2.3
|
||||
pkgrel=0
|
||||
pkgrel=1
|
||||
[ -z "${_gitcommit}" ] && _suffix="_src" || _suffix="-${_gitcommit}"
|
||||
|
||||
pkgdesc="Open Source SIP Server"
|
||||
@ -225,6 +225,8 @@ done
|
||||
source="http://www.kamailio.org/pub/kamailio/$pkgver/src/kamailio-${pkgver}${_suffix}.tar.gz
|
||||
kamailio-4.2-backslash.patch
|
||||
0001-musl-fixes.patch
|
||||
kamailio-4.2-ipops-srv-query.patch
|
||||
|
||||
kamailio.cfg
|
||||
kamailio.initd
|
||||
"
|
||||
@ -489,15 +491,18 @@ redis() {
|
||||
md5sums="f94eb1db3820dba22bd3fdae464e93b3 kamailio-4.2.3_src.tar.gz
|
||||
bad1ac2d4c95043df271d2ea6d37627a kamailio-4.2-backslash.patch
|
||||
4685288dc54680597b00f956dc95d4d6 0001-musl-fixes.patch
|
||||
5b7ecf5c4ae06420c028e03721cb9e89 kamailio-4.2-ipops-srv-query.patch
|
||||
a3c959ec568c43a905710e7d25cd8c25 kamailio.cfg
|
||||
0e0a271fd3ddb7e87c01c26c7d041d59 kamailio.initd"
|
||||
sha256sums="7dbbca4a515778d3e903380adcc49f727ddc4853238cb905e14c811a5671ed80 kamailio-4.2.3_src.tar.gz
|
||||
d7e59be721ed0ad4621d404493b9a519708d801e9d4914b0164b819fa1abcd13 kamailio-4.2-backslash.patch
|
||||
b98555ff304b51b82c6cf7e01d757b15ea4f05bd2e603c84d4384df6a6be62b6 0001-musl-fixes.patch
|
||||
cfe645fc80eaed8a9e4bd56047f75555b2a9e3edcb3e2b6c6cece1547ab0a574 kamailio-4.2-ipops-srv-query.patch
|
||||
8024266849033a917147827c3579a382f10f3796989bebc6de3d7c80c965fb72 kamailio.cfg
|
||||
a90d3ab09a3ed58892e94710a1f80492a61ffad1ccf7ccb5b851bb8f538d32c4 kamailio.initd"
|
||||
sha512sums="2f42499fe84eefac236fe3d4aa3c7bc424944236f00b95a7071feaa816b3df5764f84076d57b2137908dab7ff06a2440cc7a53a799216befd9511f8718a2eee5 kamailio-4.2.3_src.tar.gz
|
||||
a9bb1e8f9f373264b8351ddae099a36a46ddd46fdec09e468d297ba4f64bb4896e7d6e599da70a424e8a28695ab3f3b4ac940afab534593a6b9d08ae462f001a kamailio-4.2-backslash.patch
|
||||
dea7ef2ccf01357576045ba375d41301e2447b4454324007c7ca1862322835c57045852017192ca5434b32dd1b7a2e9669209b7111889dab335b74f042d0f11f 0001-musl-fixes.patch
|
||||
3a9bb5d05b4628f6146b824b8916db259f1da51415398ba420900311d73986d21cab653079080c0e8c55ef512909f542279ca7da944b5ef14520331584ca958f kamailio-4.2-ipops-srv-query.patch
|
||||
0b666bfa10fd0af97b62749f8691cb3f76d9b40d1abe0a33e810e367bd733d2e8189c89f7f23010ec591116aada6e1a8a403b17449fe775038917617f281ad4d kamailio.cfg
|
||||
5ddaa059cdef10462c904f061f7bb085e62ad7501e2ed41f797d9e68822bce4e0e5ca09c1586c3901c920f8ce563c8c3ede860752c2b9bdb8f09908388ef337f kamailio.initd"
|
||||
|
||||
658
main/kamailio/kamailio-4.2-ipops-srv-query.patch
Normal file
658
main/kamailio/kamailio-4.2-ipops-srv-query.patch
Normal file
@ -0,0 +1,658 @@
|
||||
--- a/modules/ipops/ipops_mod.c
|
||||
+++ b/modules/ipops/ipops_mod.c
|
||||
@@ -21,6 +21,7 @@
|
||||
*
|
||||
* History:
|
||||
* -------
|
||||
+ * 2015-02-04: Added srv_query function (rboisvert)
|
||||
* 2011-07-29: Added a function to detect RFC1918 private IPv4 addresses (ibc)
|
||||
* 2011-04-27: Initial version (ibc)
|
||||
*/
|
||||
@@ -92,10 +93,13 @@
|
||||
static int w_dns_int_match_ip(sip_msg_t*, char*, char*);
|
||||
|
||||
static int w_dns_query(struct sip_msg* msg, char* str1, char* str2);
|
||||
+static int w_srv_query(struct sip_msg* msg, char* str1, char* str2);
|
||||
|
||||
static pv_export_t mod_pvs[] = {
|
||||
{ {"dns", sizeof("dns")-1}, PVT_OTHER, pv_get_dns, 0,
|
||||
pv_parse_dns_name, 0, 0, 0 },
|
||||
+ { {"srvquery", sizeof("srvquery")-1}, PVT_OTHER, pv_get_srv, 0,
|
||||
+ pv_parse_srv_name, 0, 0, 0 },
|
||||
{ {"HN", sizeof("HN")-1}, PVT_OTHER, pv_get_hn, 0,
|
||||
pv_parse_hn_name, 0, 0, 0 },
|
||||
{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
|
||||
@@ -132,6 +136,8 @@
|
||||
ANY_ROUTE },
|
||||
{ "dns_query", (cmd_function)w_dns_query, 2, fixup_spve_spve, 0,
|
||||
ANY_ROUTE },
|
||||
+ { "srv_query", (cmd_function)w_srv_query, 2, fixup_spve_spve, 0,
|
||||
+ ANY_ROUTE },
|
||||
{ "bind_ipops", (cmd_function)bind_ipops, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
@@ -772,4 +778,32 @@
|
||||
}
|
||||
|
||||
return dns_update_pv(&hostname, &name);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ *
|
||||
+ */
|
||||
+static int w_srv_query(struct sip_msg* msg, char* str1, char* str2)
|
||||
+{
|
||||
+ str srvcname;
|
||||
+ str name;
|
||||
+
|
||||
+ if(msg==NULL)
|
||||
+ {
|
||||
+ LM_ERR("received null msg\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if(fixup_get_svalue(msg, (gparam_t*)str1, &srvcname)<0)
|
||||
+ {
|
||||
+ LM_ERR("cannot get the srvcname\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if(fixup_get_svalue(msg, (gparam_t*)str2, &name)<0)
|
||||
+ {
|
||||
+ LM_ERR("cannot get the pvid name\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return srv_update_pv(&srvcname, &name);
|
||||
}
|
||||
--- a/modules/ipops/ipops_pv.c
|
||||
+++ b/modules/ipops/ipops_pv.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "../../dprint.h"
|
||||
+#include "../../rand/fastrand.h"
|
||||
#include "../../hashes.h"
|
||||
#include "../../resolve.h"
|
||||
#include "../../pvar.h"
|
||||
@@ -66,7 +67,6 @@
|
||||
int nidx;
|
||||
} dns_pv_t;
|
||||
|
||||
-
|
||||
static sr_dns_item_t *_sr_dns_list = NULL;
|
||||
|
||||
/**
|
||||
@@ -132,7 +132,6 @@
|
||||
return it;
|
||||
}
|
||||
|
||||
-
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -431,7 +430,6 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
-
|
||||
struct _hn_pv_data {
|
||||
str data;
|
||||
str fullname;
|
||||
@@ -594,4 +592,545 @@
|
||||
return pv_get_null(msg, param, res);;
|
||||
return pv_get_strval(msg, param, res, &_hn_data->hostname);
|
||||
}
|
||||
+}
|
||||
+
|
||||
+/**********
|
||||
+* srvquery PV
|
||||
+**********/
|
||||
+
|
||||
+static char *srvqrylst []
|
||||
+ = {"count", "port", "priority", "target", "weight", NULL};
|
||||
+
|
||||
+#define PV_SRV_MAXSTR 64
|
||||
+#define PV_SRV_MAXRECS 32
|
||||
+
|
||||
+typedef struct _sr_srv_record {
|
||||
+ unsigned short priority;
|
||||
+ unsigned short weight;
|
||||
+ unsigned short port;
|
||||
+ char target [PV_SRV_MAXSTR + 1];
|
||||
+} sr_srv_record_t;
|
||||
+
|
||||
+typedef struct _sr_srv_item {
|
||||
+ str pvid;
|
||||
+ unsigned int hashid;
|
||||
+ int count;
|
||||
+ sr_srv_record_t rr [PV_SRV_MAXRECS];
|
||||
+ struct _sr_srv_item *next;
|
||||
+} sr_srv_item_t;
|
||||
+
|
||||
+typedef struct _srv_pv {
|
||||
+ sr_srv_item_t *item;
|
||||
+ int type;
|
||||
+ int flags;
|
||||
+ pv_spec_t *pidx;
|
||||
+ int nidx;
|
||||
+} srv_pv_t;
|
||||
+
|
||||
+static sr_srv_item_t *_sr_srv_list = NULL;
|
||||
+
|
||||
+/**********
|
||||
+* Add srvquery Item
|
||||
+*
|
||||
+* INPUT:
|
||||
+* Arg (1) = pvid string pointer
|
||||
+* Arg (2) = find flag; <>0=search only
|
||||
+* OUTPUT: srv record pointer; NULL=not found
|
||||
+**********/
|
||||
+
|
||||
+sr_srv_item_t *sr_srv_add_item (str *pvid, int findflg)
|
||||
+
|
||||
+{
|
||||
+sr_srv_item_t *pitem;
|
||||
+unsigned int hashid;
|
||||
+
|
||||
+/**********
|
||||
+* o get hash
|
||||
+* o already exists?
|
||||
+**********/
|
||||
+
|
||||
+hashid = get_hash1_raw (pvid->s, pvid->len);
|
||||
+for (pitem = _sr_srv_list; pitem; pitem = pitem->next) {
|
||||
+ if (pitem->hashid == hashid
|
||||
+ && pitem->pvid.len == pvid->len
|
||||
+ && !strncmp (pitem->pvid.s, pvid->s, pvid->len))
|
||||
+ return pitem;
|
||||
+}
|
||||
+if (findflg)
|
||||
+ return NULL;
|
||||
+
|
||||
+/**********
|
||||
+* o alloc/init item structure
|
||||
+* o link in new item
|
||||
+**********/
|
||||
+
|
||||
+pitem = (sr_srv_item_t *) pkg_malloc (sizeof (sr_srv_item_t));
|
||||
+if (!pitem) {
|
||||
+ LM_ERR ("No more pkg memory!\n");
|
||||
+ return NULL;
|
||||
+}
|
||||
+memset (pitem, 0, sizeof (sr_srv_item_t));
|
||||
+pitem->pvid.s = (char *) pkg_malloc (pvid->len + 1);
|
||||
+if (!pitem->pvid.s) {
|
||||
+ LM_ERR ("No more pkg memory!\n");
|
||||
+ pkg_free (pitem);
|
||||
+ return NULL;
|
||||
+}
|
||||
+memcpy (pitem->pvid.s, pvid->s, pvid->len);
|
||||
+pitem->pvid.len = pvid->len;
|
||||
+pitem->hashid = hashid;
|
||||
+pitem->next = _sr_srv_list;
|
||||
+_sr_srv_list = pitem;
|
||||
+return pitem;
|
||||
+}
|
||||
+
|
||||
+/**********
|
||||
+* Skip Over
|
||||
+*
|
||||
+* INPUT:
|
||||
+* Arg (1) = string pointer
|
||||
+* Arg (2) = starting position
|
||||
+* Arg (3) = whitespace flag
|
||||
+* OUTPUT: position past skipped
|
||||
+**********/
|
||||
+
|
||||
+int skip_over (str *pstr, int pos, int bWS)
|
||||
+
|
||||
+{
|
||||
+char *pchar;
|
||||
+
|
||||
+/**********
|
||||
+* o string exists?
|
||||
+* o skip over
|
||||
+**********/
|
||||
+
|
||||
+if (pos >= pstr->len)
|
||||
+ return pstr->len;
|
||||
+for (pchar = &pstr->s [pos]; pos < pstr->len; pchar++, pos++) {
|
||||
+ if (*pchar == ' ' || *pchar == '\t' || *pchar == '\n' || *pchar == '\r') {
|
||||
+ if (bWS)
|
||||
+ continue;
|
||||
+ }
|
||||
+ if ((*pchar>='A' && *pchar<='Z') || (*pchar>='a' && *pchar<='z')
|
||||
+ || (*pchar>='0' && *pchar<='9')) {
|
||||
+ if (!bWS)
|
||||
+ continue;
|
||||
+ }
|
||||
+ break;
|
||||
+}
|
||||
+return pos;
|
||||
+}
|
||||
+
|
||||
+/**********
|
||||
+* Sort SRV Records by Weight (RFC 2782)
|
||||
+*
|
||||
+* INPUT:
|
||||
+* Arg (1) = pointer to array of SRV records
|
||||
+* Arg (2) = first record in range
|
||||
+* Arg (3) = last record in range
|
||||
+* OUTPUT: position past skipped
|
||||
+**********/
|
||||
+
|
||||
+void sort_weights (struct srv_rdata **plist, int pos1, int pos2)
|
||||
+
|
||||
+{
|
||||
+int idx1, idx2, idx3, lastfound;
|
||||
+struct srv_rdata *wlist [PV_SRV_MAXRECS];
|
||||
+unsigned int rand, sum, sums [PV_SRV_MAXRECS];
|
||||
+
|
||||
+/**********
|
||||
+* place zero weights in the unordered list and then non-zero
|
||||
+**********/
|
||||
+
|
||||
+idx2 = 0;
|
||||
+for (idx1 = pos1; idx1 <= pos2; idx1++) {
|
||||
+ if (!plist [idx1]->weight) {
|
||||
+ wlist [idx2++] = plist [idx1];
|
||||
+ }
|
||||
+}
|
||||
+for (idx1 = pos1; idx1 <= pos2; idx1++) {
|
||||
+ if (plist [idx1]->weight) {
|
||||
+ wlist [idx2++] = plist [idx1];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**********
|
||||
+* generate running sum list
|
||||
+**********/
|
||||
+
|
||||
+sum = 0;
|
||||
+for (idx1 = pos1; idx1 <= pos2; idx1++) {
|
||||
+ sum += wlist [idx1]->weight;
|
||||
+ sums [pos1 - idx1] = sum;
|
||||
+}
|
||||
+
|
||||
+/**********
|
||||
+* resort randomly
|
||||
+**********/
|
||||
+
|
||||
+idx3 = pos1;
|
||||
+lastfound = 0;
|
||||
+for (idx1 = pos2 - pos1; idx1; --idx1) {
|
||||
+ /**********
|
||||
+ * o calculate a random number in range
|
||||
+ * o find first unsorted
|
||||
+ **********/
|
||||
+
|
||||
+ rand = fastrand_max (sum);
|
||||
+ for (idx2 = 0; idx2 < pos2 - pos1; idx2++) {
|
||||
+ if (!wlist [idx2]) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (sums [idx2] >= rand) {
|
||||
+ plist [idx3++] = wlist [idx2];
|
||||
+ wlist [idx2] = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ lastfound = idx2;
|
||||
+ }
|
||||
+ if (idx2 == pos2 - pos1) {
|
||||
+ plist [idx3++] = wlist [lastfound];
|
||||
+ wlist [lastfound] = 0;
|
||||
+ }
|
||||
+}
|
||||
+return;
|
||||
+}
|
||||
+
|
||||
+/**********
|
||||
+* Sort SRV Records by Priority/Weight
|
||||
+*
|
||||
+* INPUT:
|
||||
+* Arg (1) = pointer to array of SRV records
|
||||
+* Arg (2) = record count
|
||||
+* OUTPUT: position past skipped
|
||||
+**********/
|
||||
+
|
||||
+void sort_srv (struct srv_rdata **plist, int rcount)
|
||||
+
|
||||
+{
|
||||
+int idx1, idx2;
|
||||
+struct srv_rdata *pswap;
|
||||
+
|
||||
+/**********
|
||||
+* sort by priority
|
||||
+**********/
|
||||
+
|
||||
+for (idx1 = 1; idx1 < rcount; idx1++) {
|
||||
+ pswap = plist [idx1];
|
||||
+ for (idx2 = idx1;
|
||||
+ idx2 && (plist [idx2 - 1]->priority > pswap->priority); --idx2) {
|
||||
+ plist [idx2] = plist [idx2 - 1];
|
||||
+ }
|
||||
+ plist [idx2] = pswap;
|
||||
+}
|
||||
+
|
||||
+/**********
|
||||
+* check for multiple priority
|
||||
+**********/
|
||||
+
|
||||
+idx2 = 0;
|
||||
+pswap = plist [0];
|
||||
+for (idx1 = 1; idx1 <= rcount; idx1++) {
|
||||
+ if ((idx1 == rcount) || (pswap->priority != plist [idx1]->priority)) {
|
||||
+ /**********
|
||||
+ * o range has more than one element?
|
||||
+ * o restart range
|
||||
+ **********/
|
||||
+
|
||||
+ if (idx1 - idx2 - 1) {
|
||||
+ sort_weights (plist, idx2, idx1 - 1);
|
||||
+ }
|
||||
+ idx2 = idx1;
|
||||
+ pswap = plist [idx2];
|
||||
+ }
|
||||
+}
|
||||
+return;
|
||||
+}
|
||||
+
|
||||
+/**********
|
||||
+* Parse srvquery Name
|
||||
+*
|
||||
+* INPUT:
|
||||
+* Arg (1) = pv spec pointer
|
||||
+* Arg (2) = input string pointer
|
||||
+* OUTPUT: 0=success
|
||||
+**********/
|
||||
+
|
||||
+int pv_parse_srv_name (pv_spec_t *sp, str *in)
|
||||
+
|
||||
+{
|
||||
+char *pstr;
|
||||
+int i, pos, sign;
|
||||
+srv_pv_t *dpv;
|
||||
+str pvi, pvk, pvn;
|
||||
+
|
||||
+/**********
|
||||
+* o alloc/init pvid structure
|
||||
+* o extract pvid name
|
||||
+* o check separator
|
||||
+**********/
|
||||
+
|
||||
+if (!sp || !in || in->len<=0)
|
||||
+ return -1;
|
||||
+dpv = (srv_pv_t *) pkg_malloc (sizeof (srv_pv_t));
|
||||
+if (!dpv) {
|
||||
+ LM_ERR ("No more pkg memory!\n");
|
||||
+ return -1;
|
||||
+}
|
||||
+memset (dpv, 0, sizeof (srv_pv_t));
|
||||
+pos = skip_over (in, 0, 1);
|
||||
+if (pos == in->len)
|
||||
+ goto error;
|
||||
+pvn.s = &in->s [pos];
|
||||
+pvn.len = pos;
|
||||
+pos = skip_over (in, pos, 0);
|
||||
+pvn.len = pos - pvn.len;
|
||||
+if (!pvn.len)
|
||||
+ goto error;
|
||||
+pos = skip_over (in, pos, 1);
|
||||
+if ((pos + 2) > in->len)
|
||||
+ goto error;
|
||||
+if (strncmp (&in->s [pos], "=>", 2))
|
||||
+ goto error;
|
||||
+
|
||||
+/**********
|
||||
+* o extract key name
|
||||
+* o check key name
|
||||
+* o count?
|
||||
+**********/
|
||||
+
|
||||
+pos = skip_over (in, pos + 2, 1);
|
||||
+pvk.s = &in->s [pos];
|
||||
+pvk.len = pos;
|
||||
+pos = skip_over (in, pos, 0);
|
||||
+pvk.len = pos - pvk.len;
|
||||
+if (!pvk.len)
|
||||
+ goto error;
|
||||
+for (i = 0; srvqrylst [i]; i++) {
|
||||
+ if (strlen (srvqrylst [i]) != pvk.len)
|
||||
+ continue;
|
||||
+ if (!strncmp (pvk.s, srvqrylst [i], pvk.len)) {
|
||||
+ dpv->type = i;
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+if (!srvqrylst [i])
|
||||
+ goto error;
|
||||
+if (!i)
|
||||
+ goto noindex;
|
||||
+
|
||||
+/**********
|
||||
+* o check for array
|
||||
+* o extract array index and check
|
||||
+**********/
|
||||
+
|
||||
+pos = skip_over (in, pos, 1);
|
||||
+if ((pos + 3) > in->len)
|
||||
+ goto error;
|
||||
+if (in->s [pos] != '[')
|
||||
+ goto error;
|
||||
+pos = skip_over (in, pos + 1, 1);
|
||||
+if ((pos + 2) > in->len)
|
||||
+ goto error;
|
||||
+pvi.s = &in->s [pos];
|
||||
+pvi.len = pos;
|
||||
+if (in->s [pos] == PV_MARKER) {
|
||||
+ /**********
|
||||
+ * o search from the end back to array close
|
||||
+ * o get PV value
|
||||
+ **********/
|
||||
+
|
||||
+ for (i = in->len - 1; i != pos; --i) {
|
||||
+ if (in->s [i] == ']')
|
||||
+ break;
|
||||
+ }
|
||||
+ if (i == pos)
|
||||
+ goto error;
|
||||
+ pvi.len = i - pvi.len;
|
||||
+ pos = i + 1;
|
||||
+ dpv->pidx = pv_cache_get (&pvi);
|
||||
+ if (!dpv->pidx)
|
||||
+ goto error;
|
||||
+ dpv->flags |= SR_DNS_PVIDX;
|
||||
+} else {
|
||||
+ /**********
|
||||
+ * o get index value
|
||||
+ * o check for reverse index
|
||||
+ * o convert string to number
|
||||
+ **********/
|
||||
+
|
||||
+ pos = skip_over (in, pos, 0);
|
||||
+ pvi.len = pos - pvi.len;
|
||||
+ sign = 1;
|
||||
+ i = 0;
|
||||
+ pstr = pvi.s;
|
||||
+ if (*pstr == '-') {
|
||||
+ sign = -1;
|
||||
+ i++;
|
||||
+ pstr++;
|
||||
+ }
|
||||
+ for (dpv->nidx = 0; i < pvi.len; i++) {
|
||||
+ if (*pstr >= '0' && *pstr <= '9')
|
||||
+ dpv->nidx = (dpv->nidx * 10) + *pstr++ - '0';
|
||||
+ }
|
||||
+ if (i != pvi.len)
|
||||
+ goto error;
|
||||
+ dpv->nidx *= sign;
|
||||
+ pos = skip_over (in, pos, 1);
|
||||
+ if (pos == in->len)
|
||||
+ goto error;
|
||||
+ if (in->s [pos++] != ']')
|
||||
+ goto error;
|
||||
+}
|
||||
+
|
||||
+/**********
|
||||
+* o check for trailing whitespace
|
||||
+* o add data to PV
|
||||
+**********/
|
||||
+
|
||||
+noindex:
|
||||
+if (skip_over (in, pos, 1) != in->len)
|
||||
+ goto error;
|
||||
+LM_DBG ("srvquery (%.*s => %.*s [%.*s])\n",
|
||||
+ pvn.len, pvn.s, pvk.len, pvk.s, pvi.len, pvi.s);
|
||||
+dpv->item = sr_srv_add_item (&pvn, 0);
|
||||
+if (!dpv->item)
|
||||
+ goto error;
|
||||
+sp->pvp.pvn.u.dname = (void *)dpv;
|
||||
+sp->pvp.pvn.type = PV_NAME_OTHER;
|
||||
+return 0;
|
||||
+
|
||||
+error:
|
||||
+LM_ERR ("error at PV srvquery: %.*s@%d\n", in->len, in->s, pos);
|
||||
+pkg_free (dpv);
|
||||
+return -1;
|
||||
+}
|
||||
+
|
||||
+int srv_update_pv (str *srvcname, str *pvid)
|
||||
+
|
||||
+{
|
||||
+int idx1, idx2, rcount;
|
||||
+struct rdata *phead, *psrv;
|
||||
+struct srv_rdata *plist [PV_SRV_MAXRECS];
|
||||
+sr_srv_item_t *pitem;
|
||||
+sr_srv_record_t *prec;
|
||||
+
|
||||
+/**********
|
||||
+* o service name missing?
|
||||
+* o find pvid
|
||||
+**********/
|
||||
+
|
||||
+if (!srvcname->len) {
|
||||
+ LM_DBG ("service name missing: %.*s\n", srvcname->len, srvcname->s);
|
||||
+ return -2;
|
||||
+}
|
||||
+pitem = sr_srv_add_item (pvid, 1);
|
||||
+if (!pitem) {
|
||||
+ LM_DBG ("pvid not found: %.*s\n", pvid->len, pvid->s);
|
||||
+ return -3;
|
||||
+}
|
||||
+
|
||||
+/**********
|
||||
+* o get records
|
||||
+* o sort by priority/weight
|
||||
+* o save to PV
|
||||
+**********/
|
||||
+
|
||||
+LM_DBG ("attempting to query: %.*s\n", srvcname->len, srvcname->s);
|
||||
+phead = get_record (srvcname->s, T_SRV, RES_ONLY_TYPE);
|
||||
+rcount = 0;
|
||||
+for (psrv = phead; psrv; psrv = psrv->next) {
|
||||
+ if (rcount < PV_SRV_MAXRECS) {
|
||||
+ plist [rcount++] = (struct srv_rdata *) psrv->rdata;
|
||||
+ } else {
|
||||
+ LM_WARN ("truncating srv_query list to %d records!", PV_SRV_MAXRECS);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+pitem->count = rcount;
|
||||
+if (rcount)
|
||||
+ sort_srv (plist, rcount);
|
||||
+for (idx1 = 0; idx1 < rcount; idx1++) {
|
||||
+ prec = &pitem->rr [idx1];
|
||||
+ prec->priority = plist [idx1]->priority;
|
||||
+ prec->weight = plist [idx1]->weight;
|
||||
+ prec->port = plist [idx1]->port;
|
||||
+ idx2 = plist [idx1]->name_len;
|
||||
+ if (idx2 > PV_SRV_MAXSTR) {
|
||||
+ LM_WARN ("truncating srv_query target (%.*s)!", idx2, plist [idx1]->name);
|
||||
+ idx2 = PV_SRV_MAXSTR;
|
||||
+ }
|
||||
+ strncpy (prec->target, plist [idx1]->name, idx2);
|
||||
+ prec->target [idx2] = '\0';
|
||||
+}
|
||||
+if (phead)
|
||||
+ free_rdata_list (phead);
|
||||
+LM_DBG ("srvquery PV updated for: %.*s (%d)\n",
|
||||
+ srvcname->len, srvcname->s, rcount);
|
||||
+return 1;
|
||||
+}
|
||||
+
|
||||
+/**********
|
||||
+* Get srvquery Values
|
||||
+*
|
||||
+* INPUT:
|
||||
+* Arg (1) = SIP message pointer
|
||||
+* Arg (2) = parameter pointer
|
||||
+* Arg (3) = PV value pointer
|
||||
+* OUTPUT: 0=success
|
||||
+**********/
|
||||
+
|
||||
+int pv_get_srv (sip_msg_t *pmsg, pv_param_t *param, pv_value_t *res)
|
||||
+
|
||||
+{
|
||||
+pv_value_t val;
|
||||
+srv_pv_t *dpv;
|
||||
+
|
||||
+/**********
|
||||
+* o sipmsg and param exist?
|
||||
+* o PV name exists?
|
||||
+* o count?
|
||||
+**********/
|
||||
+
|
||||
+if(!pmsg || !param)
|
||||
+ return -1;
|
||||
+dpv = (srv_pv_t *) param->pvn.u.dname;
|
||||
+if(!dpv || !dpv->item)
|
||||
+ return -1;
|
||||
+if (!dpv->type)
|
||||
+ return pv_get_sintval (pmsg, param, res, dpv->item->count);
|
||||
+
|
||||
+/**********
|
||||
+* o get index value
|
||||
+* o reverse index?
|
||||
+* o extract data
|
||||
+**********/
|
||||
+
|
||||
+if (!dpv->pidx) {
|
||||
+ val.ri = dpv->nidx;
|
||||
+} else {
|
||||
+ if (pv_get_spec_value (pmsg, dpv->pidx, &val) < 0
|
||||
+ || !(val.flags & PV_VAL_INT)) {
|
||||
+ LM_ERR ("failed to evaluate index variable!\n");
|
||||
+ return pv_get_null (pmsg, param, res);
|
||||
+ }
|
||||
+}
|
||||
+if (val.ri < 0) {
|
||||
+ if ((dpv->item->count + val.ri) < 0)
|
||||
+ return pv_get_null (pmsg, param, res);
|
||||
+ val.ri = dpv->item->count + val.ri;
|
||||
+}
|
||||
+if (val.ri >= dpv->item->count)
|
||||
+ return pv_get_null(pmsg, param, res);
|
||||
+switch (dpv->type) {
|
||||
+ case 1: /* port */
|
||||
+ return pv_get_sintval (pmsg, param, res, dpv->item->rr [val.ri].port);
|
||||
+ case 2: /* priority */
|
||||
+ return pv_get_sintval (pmsg, param, res, dpv->item->rr [val.ri].priority);
|
||||
+ case 3: /* target */
|
||||
+ return pv_get_strzval (pmsg, param, res, dpv->item->rr [val.ri].target);
|
||||
+ case 4: /* weight */
|
||||
+ return pv_get_sintval (pmsg, param, res, dpv->item->rr [val.ri].weight);
|
||||
+}
|
||||
+return pv_get_null (pmsg, param, res);
|
||||
}
|
||||
--- a/modules/ipops/ipops_pv.h
|
||||
+++ b/modules/ipops/ipops_pv.h
|
||||
@@ -39,5 +39,9 @@
|
||||
int pv_get_hn(struct sip_msg *msg, pv_param_t *param,
|
||||
pv_value_t *res);
|
||||
|
||||
+int pv_parse_srv_name(pv_spec_t *, str *);
|
||||
+int pv_get_srv(sip_msg_t *, pv_param_t *, pv_value_t *);
|
||||
+int srv_update_pv(str *, str *);
|
||||
+
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user