|
@@ -292,13 +292,13 @@ m_tree_t* mt_get_first_tree()
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-is_t* mt_get_tvalue(m_tree_t *pt, str *tomatch)
|
|
|
|
|
|
+is_t* mt_get_tvalue(m_tree_t *pt, str *tomatch, int *len)
|
|
{
|
|
{
|
|
int l;
|
|
int l;
|
|
mt_node_t *itn;
|
|
mt_node_t *itn;
|
|
is_t *tvalue;
|
|
is_t *tvalue;
|
|
|
|
|
|
- if(pt==NULL || tomatch==NULL || tomatch->s==NULL)
|
|
|
|
|
|
+ if(pt==NULL || tomatch==NULL || tomatch->s==NULL || len == NULL)
|
|
{
|
|
{
|
|
LM_ERR("bad parameters\n");
|
|
LM_ERR("bad parameters\n");
|
|
return NULL;
|
|
return NULL;
|
|
@@ -327,6 +327,8 @@ is_t* mt_get_tvalue(m_tree_t *pt, str *tomatch)
|
|
l++;
|
|
l++;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ *len = l;
|
|
|
|
+
|
|
return tvalue;
|
|
return tvalue;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -387,7 +389,7 @@ int mt_match_prefix(struct sip_msg *msg, m_tree_t *it,
|
|
str *tomatch, int mode)
|
|
str *tomatch, int mode)
|
|
{
|
|
{
|
|
int l, len, n;
|
|
int l, len, n;
|
|
- int i, j;
|
|
|
|
|
|
+ int i, j, k = 0;
|
|
mt_node_t *itn;
|
|
mt_node_t *itn;
|
|
is_t *tvalue;
|
|
is_t *tvalue;
|
|
int_str dstid_avp_name;
|
|
int_str dstid_avp_name;
|
|
@@ -413,7 +415,7 @@ int mt_match_prefix(struct sip_msg *msg, m_tree_t *it,
|
|
if ((it->type==MT_TREE_SVAL) || (it->type==MT_TREE_IVAL)) {
|
|
if ((it->type==MT_TREE_SVAL) || (it->type==MT_TREE_IVAL)) {
|
|
if (mode == 2)
|
|
if (mode == 2)
|
|
return mt_add_tvalues(msg, it, tomatch);
|
|
return mt_add_tvalues(msg, it, tomatch);
|
|
- tvalue = mt_get_tvalue(it, tomatch);
|
|
|
|
|
|
+ tvalue = mt_get_tvalue(it, tomatch, &k);
|
|
if (tvalue == NULL) {
|
|
if (tvalue == NULL) {
|
|
LM_DBG("no match for: %.*s\n", tomatch->len, tomatch->s);
|
|
LM_DBG("no match for: %.*s\n", tomatch->len, tomatch->s);
|
|
return -1;
|
|
return -1;
|
|
@@ -873,3 +875,417 @@ int mt_defined_trees(void)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int mt_mi_add_tvalues(struct mi_node *rpl, m_tree_t *pt, str *tomatch)
|
|
|
|
+{
|
|
|
|
+ int l;
|
|
|
|
+ mt_node_t *itn;
|
|
|
|
+ mt_is_t *tvalues;
|
|
|
|
+ struct mi_attr* attr= NULL;
|
|
|
|
+ struct mi_node *node = NULL;
|
|
|
|
+
|
|
|
|
+ if (pt == NULL || tomatch == NULL || tomatch->s == NULL) {
|
|
|
|
+ LM_ERR("bad parameters\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ l = 0;
|
|
|
|
+ itn = pt->head;
|
|
|
|
+
|
|
|
|
+ while (itn != NULL && l < tomatch->len && l < MT_MAX_DEPTH) {
|
|
|
|
+ /* check validity */
|
|
|
|
+ if(_mt_char_table[(unsigned int)tomatch->s[l]]==255) {
|
|
|
|
+ LM_ERR("invalid char at %d in [%.*s]\n",
|
|
|
|
+ l, tomatch->len, tomatch->s);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ tvalues = itn[_mt_char_table[(unsigned int)tomatch->s[l]]].tvalues;
|
|
|
|
+ while (tvalues != NULL) {
|
|
|
|
+ node = add_mi_node_child(rpl, 0, "MT", 2, 0, 0);
|
|
|
|
+ if(node == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ if( add_mi_attr(node, MI_DUP_VALUE, "TNAME", 5,
|
|
|
|
+ pt->tname.s, pt->tname.len) == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ if (add_mi_attr(node, MI_DUP_VALUE, "TPREFIX", 7,
|
|
|
|
+ tomatch->s, l+1) == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ if (pt->type == MT_TREE_IVAL) {
|
|
|
|
+ attr = addf_mi_attr(node, MI_DUP_VALUE, "TVALUE", 6,
|
|
|
|
+ "%d", tvalues->tvalue.n);
|
|
|
|
+ } else { /* pt->type == MT_TREE_SVAL */
|
|
|
|
+ attr = add_mi_attr(node, MI_DUP_VALUE, "TVALUE", 6,
|
|
|
|
+ tvalues->tvalue.s.s, tvalues->tvalue.s.len);
|
|
|
|
+ }
|
|
|
|
+ tvalues = tvalues->next;
|
|
|
|
+ if (attr == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ itn = itn[_mt_char_table[(unsigned int)tomatch->s[l]]].child;
|
|
|
|
+ l++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (node == NULL) return -1;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int mt_mi_match_prefix(struct mi_node *rpl, m_tree_t *it,
|
|
|
|
+ str *tomatch, int mode)
|
|
|
|
+{
|
|
|
|
+ int l, len, n;
|
|
|
|
+ int i, j;
|
|
|
|
+ mt_node_t *itn;
|
|
|
|
+ is_t *tvalue;
|
|
|
|
+ mt_dw_t *dw;
|
|
|
|
+ int tprefix_len = 0;
|
|
|
|
+
|
|
|
|
+ struct mi_node *node;
|
|
|
|
+ struct mi_attr* attr= NULL;
|
|
|
|
+
|
|
|
|
+#define MT_MAX_DST_LIST 64
|
|
|
|
+ unsigned int tmp_list[2*(MT_MAX_DST_LIST+1)];
|
|
|
|
+
|
|
|
|
+ if(it==NULL || tomatch == NULL
|
|
|
|
+ || tomatch->s == NULL)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("bad parameters\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ l = len = 0;
|
|
|
|
+ n = 0;
|
|
|
|
+ if ((it->type==MT_TREE_SVAL) || (it->type==MT_TREE_IVAL)) {
|
|
|
|
+ if (mode == 2)
|
|
|
|
+ return mt_mi_add_tvalues(rpl, it, tomatch);
|
|
|
|
+ tvalue = mt_get_tvalue(it, tomatch, &tprefix_len);
|
|
|
|
+ if (tvalue == NULL) {
|
|
|
|
+ LM_DBG("no match for: %.*s\n", tomatch->len, tomatch->s);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if (tvalue) {
|
|
|
|
+ node = add_mi_node_child(rpl, 0, "MT", 2, 0, 0);
|
|
|
|
+ if(node == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ if( add_mi_attr(node, MI_DUP_VALUE, "TNAME", 5,
|
|
|
|
+ it->tname.s, it->tname.len) == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ if (add_mi_attr(node, MI_DUP_VALUE, "TPREFIX", 7,
|
|
|
|
+ tomatch->s, tprefix_len) == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ if (it->type==MT_TREE_SVAL) {
|
|
|
|
+ attr = add_mi_attr(node, MI_DUP_VALUE, "TVALUE", 6,
|
|
|
|
+ tvalue->s.s, tvalue->s.len);
|
|
|
|
+ } else {
|
|
|
|
+ attr = addf_mi_attr(node, MI_DUP_VALUE, "TVALUE", 6,
|
|
|
|
+ "%d", tvalue->n);
|
|
|
|
+ }
|
|
|
|
+ if (attr == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(it->type!=MT_TREE_DW)
|
|
|
|
+ return -1; /* wrong tree type */
|
|
|
|
+
|
|
|
|
+ itn = it->head;
|
|
|
|
+ memset(tmp_list, 0, sizeof(unsigned int)*2*(MT_MAX_DST_LIST+1));
|
|
|
|
+
|
|
|
|
+ while(itn!=NULL && l < tomatch->len && l < MT_MAX_DEPTH)
|
|
|
|
+ {
|
|
|
|
+ /* check validity */
|
|
|
|
+ if(_mt_char_table[(unsigned int)tomatch->s[l]]==255)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("invalid char at %d in [%.*s]\n",
|
|
|
|
+ l, tomatch->len, tomatch->s);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(itn[_mt_char_table[(unsigned int)tomatch->s[l]]].tvalues!=NULL)
|
|
|
|
+ {
|
|
|
|
+ dw = (mt_dw_t*)itn[_mt_char_table[(unsigned int)tomatch->s[l]]].data;
|
|
|
|
+ while(dw) {
|
|
|
|
+ tmp_list[2*n]=dw->dstid;
|
|
|
|
+ tmp_list[2*n+1]=dw->weight;
|
|
|
|
+ n++;
|
|
|
|
+ if(n==MT_MAX_DST_LIST)
|
|
|
|
+ break;
|
|
|
|
+ dw = dw->next;
|
|
|
|
+ }
|
|
|
|
+ len = l+1;
|
|
|
|
+ }
|
|
|
|
+ if(n==MT_MAX_DST_LIST)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ itn = itn[_mt_char_table[(unsigned int)tomatch->s[l]]].child;
|
|
|
|
+ l++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(n==0)
|
|
|
|
+ return -1; /* no match */
|
|
|
|
+ /* invalidate duplicated dstid, keeping longest match */
|
|
|
|
+ for(i=(n-1); i>0; i--)
|
|
|
|
+ {
|
|
|
|
+ if (tmp_list[2*i]!=0)
|
|
|
|
+ {
|
|
|
|
+ for(j=0; j<i; j++)
|
|
|
|
+ if(tmp_list[2*i]==tmp_list[2*j])
|
|
|
|
+ tmp_list[2*j] = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /* sort the table -- bubble sort -- reverse order */
|
|
|
|
+ for (i = (n - 1); i >= 0; i--)
|
|
|
|
+ {
|
|
|
|
+ for (j = 1; j <= i; j++)
|
|
|
|
+ {
|
|
|
|
+ if (tmp_list[2*(j-1)+1] < tmp_list[2*j+1])
|
|
|
|
+ {
|
|
|
|
+ tmp_list[2*MT_MAX_DST_LIST] = tmp_list[2*(j-1)];
|
|
|
|
+ tmp_list[2*MT_MAX_DST_LIST+1] = tmp_list[2*(j-1)+1];
|
|
|
|
+ tmp_list[2*(j-1)] = tmp_list[2*j];
|
|
|
|
+ tmp_list[2*(j-1)+1] = tmp_list[2*j+1];
|
|
|
|
+ tmp_list[2*j] = tmp_list[2*MT_MAX_DST_LIST];
|
|
|
|
+ tmp_list[2*j+1] = tmp_list[2*MT_MAX_DST_LIST+1];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* add as attributes */
|
|
|
|
+ for(i=0; i<n; i++)
|
|
|
|
+ {
|
|
|
|
+ if(tmp_list[2*i]!=0)
|
|
|
|
+ {
|
|
|
|
+ node = add_mi_node_child(rpl, 0, "MT", 2, 0, 0);
|
|
|
|
+ if(node == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ if( add_mi_attr(node, MI_DUP_VALUE, "TNAME", 5,
|
|
|
|
+ it->tname.s, it->tname.len) == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ if (add_mi_attr(node, MI_DUP_VALUE, "TPREFIX", 7,
|
|
|
|
+ tomatch->s, len) == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+ if(addf_mi_attr(node, MI_DUP_VALUE, "WEIGHT", 6,
|
|
|
|
+ "%d", (int)tmp_list[2*i+1]) == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ if (addf_mi_attr(node, MI_DUP_VALUE, "DSTID", 5,
|
|
|
|
+ "%d", (int)tmp_list[2*i]) == NULL)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int mt_rpc_add_tvalues(rpc_t* rpc, void* ctx, m_tree_t *pt, str *tomatch)
|
|
|
|
+{
|
|
|
|
+ int l;
|
|
|
|
+ mt_node_t *itn;
|
|
|
|
+ mt_is_t *tvalues;
|
|
|
|
+ void *vstruct = NULL;
|
|
|
|
+ str prefix = *tomatch;
|
|
|
|
+
|
|
|
|
+ if (pt == NULL || tomatch == NULL || tomatch->s == NULL) {
|
|
|
|
+ LM_ERR("bad parameters\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ l = 0;
|
|
|
|
+ itn = pt->head;
|
|
|
|
+
|
|
|
|
+ while (itn != NULL && l < tomatch->len && l < MT_MAX_DEPTH) {
|
|
|
|
+ /* check validity */
|
|
|
|
+ if(_mt_char_table[(unsigned int)tomatch->s[l]]==255) {
|
|
|
|
+ LM_ERR("invalid char at %d in [%.*s]\n",
|
|
|
|
+ l, tomatch->len, tomatch->s);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ tvalues = itn[_mt_char_table[(unsigned int)tomatch->s[l]]].tvalues;
|
|
|
|
+ while (tvalues != NULL) {
|
|
|
|
+ prefix.len = l+1;
|
|
|
|
+ if (rpc->add(ctx, "{", &vstruct) < 0) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding struct");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if(rpc->struct_add(vstruct, "S", "PREFIX", &prefix) < 0) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding prefix");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if (pt->type == MT_TREE_IVAL) {
|
|
|
|
+ if(rpc->struct_add(vstruct, "d", "TVALUE", tvalues->tvalue.n) < 0 ) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding tvalue");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ } else { /* pt->type == MT_TREE_SVAL */
|
|
|
|
+ if(rpc->struct_add(vstruct, "S", "TVALUE", &tvalues->tvalue.s) < 0 ) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding tvalue");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ tvalues = tvalues->next;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ itn = itn[_mt_char_table[(unsigned int)tomatch->s[l]]].child;
|
|
|
|
+ l++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (vstruct == NULL) return -1;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int mt_rpc_match_prefix(rpc_t* rpc, void* ctx, m_tree_t *it,
|
|
|
|
+ str *tomatch, int mode)
|
|
|
|
+{
|
|
|
|
+ int l, len, n;
|
|
|
|
+ int i, j;
|
|
|
|
+ mt_node_t *itn;
|
|
|
|
+ is_t *tvalue;
|
|
|
|
+ mt_dw_t *dw;
|
|
|
|
+ int tprefix_len = 0;
|
|
|
|
+ str prefix = *tomatch;
|
|
|
|
+ void *vstruct = NULL;
|
|
|
|
+
|
|
|
|
+#define MT_MAX_DST_LIST 64
|
|
|
|
+ unsigned int tmp_list[2*(MT_MAX_DST_LIST+1)];
|
|
|
|
+
|
|
|
|
+ if(it==NULL || tomatch == NULL
|
|
|
|
+ || tomatch->s == NULL)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("bad parameters\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (rpc->add(ctx, "S", &it->tname) < 0) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding tname");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ l = len = 0;
|
|
|
|
+ n = 0;
|
|
|
|
+ if ((it->type==MT_TREE_SVAL) || (it->type==MT_TREE_IVAL)) {
|
|
|
|
+ if (mode == 2)
|
|
|
|
+ return mt_rpc_add_tvalues(rpc, ctx, it, tomatch);
|
|
|
|
+ tvalue = mt_get_tvalue(it, tomatch, &tprefix_len);
|
|
|
|
+ if (tvalue == NULL) {
|
|
|
|
+ LM_DBG("no match for: %.*s\n", tomatch->len, tomatch->s);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if (tvalue) {
|
|
|
|
+ prefix.len = tprefix_len;
|
|
|
|
+ if (rpc->add(ctx, "{", &vstruct) < 0) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding struct");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if (rpc->struct_add(vstruct, "S", "PREFIX", &prefix) < 0) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding prefix");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if (it->type==MT_TREE_SVAL) {
|
|
|
|
+ if(rpc->struct_add(vstruct, "S", "TVALUE", &tvalue->s) < 0 ) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding tvalue");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if(rpc->struct_add(vstruct, "d", "TVALUE", tvalue->n) < 0 ) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding tvalue");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(it->type!=MT_TREE_DW)
|
|
|
|
+ return -1; /* wrong tree type */
|
|
|
|
+
|
|
|
|
+ itn = it->head;
|
|
|
|
+ memset(tmp_list, 0, sizeof(unsigned int)*2*(MT_MAX_DST_LIST+1));
|
|
|
|
+
|
|
|
|
+ while(itn!=NULL && l < tomatch->len && l < MT_MAX_DEPTH)
|
|
|
|
+ {
|
|
|
|
+ /* check validity */
|
|
|
|
+ if(_mt_char_table[(unsigned int)tomatch->s[l]]==255)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("invalid char at %d in [%.*s]\n",
|
|
|
|
+ l, tomatch->len, tomatch->s);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(itn[_mt_char_table[(unsigned int)tomatch->s[l]]].tvalues!=NULL)
|
|
|
|
+ {
|
|
|
|
+ dw = (mt_dw_t*)itn[_mt_char_table[(unsigned int)tomatch->s[l]]].data;
|
|
|
|
+ while(dw) {
|
|
|
|
+ tmp_list[2*n]=dw->dstid;
|
|
|
|
+ tmp_list[2*n+1]=dw->weight;
|
|
|
|
+ n++;
|
|
|
|
+ if(n==MT_MAX_DST_LIST)
|
|
|
|
+ break;
|
|
|
|
+ dw = dw->next;
|
|
|
|
+ }
|
|
|
|
+ len = l+1;
|
|
|
|
+ }
|
|
|
|
+ if(n==MT_MAX_DST_LIST)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ itn = itn[_mt_char_table[(unsigned int)tomatch->s[l]]].child;
|
|
|
|
+ l++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(n==0)
|
|
|
|
+ return -1; /* no match */
|
|
|
|
+ /* invalidate duplicated dstid, keeping longest match */
|
|
|
|
+ for(i=(n-1); i>0; i--)
|
|
|
|
+ {
|
|
|
|
+ if (tmp_list[2*i]!=0)
|
|
|
|
+ {
|
|
|
|
+ for(j=0; j<i; j++)
|
|
|
|
+ if(tmp_list[2*i]==tmp_list[2*j])
|
|
|
|
+ tmp_list[2*j] = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /* sort the table -- bubble sort -- reverse order */
|
|
|
|
+ for (i = (n - 1); i >= 0; i--)
|
|
|
|
+ {
|
|
|
|
+ for (j = 1; j <= i; j++)
|
|
|
|
+ {
|
|
|
|
+ if (tmp_list[2*(j-1)+1] < tmp_list[2*j+1])
|
|
|
|
+ {
|
|
|
|
+ tmp_list[2*MT_MAX_DST_LIST] = tmp_list[2*(j-1)];
|
|
|
|
+ tmp_list[2*MT_MAX_DST_LIST+1] = tmp_list[2*(j-1)+1];
|
|
|
|
+ tmp_list[2*(j-1)] = tmp_list[2*j];
|
|
|
|
+ tmp_list[2*(j-1)+1] = tmp_list[2*j+1];
|
|
|
|
+ tmp_list[2*j] = tmp_list[2*MT_MAX_DST_LIST];
|
|
|
|
+ tmp_list[2*j+1] = tmp_list[2*MT_MAX_DST_LIST+1];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ prefix.len = len;
|
|
|
|
+
|
|
|
|
+ /* add as attributes */
|
|
|
|
+ for(i=0; i<n; i++)
|
|
|
|
+ {
|
|
|
|
+ if(tmp_list[2*i]!=0)
|
|
|
|
+ {
|
|
|
|
+ if (rpc->add(ctx, "{", &vstruct) < 0) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding struct");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if (rpc->struct_add(vstruct, "S", "PREFIX", &prefix) < 0) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding prefix");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if(rpc->add(vstruct, "dd",
|
|
|
|
+ "WEIGHT", tmp_list[2*i+1],
|
|
|
|
+ "DSTID", tmp_list[2*i]) < 0 ) {
|
|
|
|
+ rpc->fault(ctx, 500, "Internal error adding weight/dstid");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|