Browse Source

modules/lcr: added lcr.load_gws rpc function

Juha Heinanen 8 years ago
parent
commit
b2e8a193d0

+ 22 - 7
src/modules/lcr/README

@@ -86,7 +86,8 @@ Juha Heinanen
               5.1. lcr.reload
               5.2. lcr.dump_gws
               5.3. lcr.dump_rules
-              5.4. lcr.defunct_gw
+              5.4. lcr.load_gws
+              5.5. lcr.defunct_gw
 
         6. Known Limitations
 
@@ -148,7 +149,8 @@ Juha Heinanen
    1.54. lcr.reload RPC example
    1.55. lcr.dump_gws RPC example
    1.56. lcr.dump_rules RPC example
-   1.57. lcr.defunct_gw RPC example
+   1.57. lcr.load_gws RPC example
+   1.58. lcr.defunct_gw RPC example
 
 Chapter 1. Admin Guide
 
@@ -223,7 +225,8 @@ Chapter 1. Admin Guide
         5.1. lcr.reload
         5.2. lcr.dump_gws
         5.3. lcr.dump_rules
-        5.4. lcr.defunct_gw
+        5.4. lcr.load_gws
+        5.5. lcr.defunct_gw
 
    6. Known Limitations
 
@@ -920,7 +923,7 @@ modparam("lcr", "ping_socket", "192.98.102.10:5060")
    look for matching gateways. Caller's URI may be given by caller_uri
    argument. If caller_uri argument is omitted, it defaults to empty
    string. Both uri_user and caller_uri argument may be a string or a
-   pseudo variable containing a sting value.
+   pseudo variable containing a string value.
 
    Returns 1 if at least one matching gateway was found, 2 if no matching
    gateways was found, and -1 on error.
@@ -1132,7 +1135,8 @@ if (to_any_gw("192.55.66.2", 1)) {
    5.1. lcr.reload
    5.2. lcr.dump_gws
    5.3. lcr.dump_rules
-   5.4. lcr.defunct_gw
+   5.4. lcr.load_gws
+   5.5. lcr.defunct_gw
 
 5.1. lcr.reload
 
@@ -1164,7 +1168,18 @@ if (to_any_gw("192.55.66.2", 1)) {
    Example 1.56. lcr.dump_rules RPC example
                 $ kamcmd lcr.dump_rules
 
-5.4. lcr.defunct_gw
+5.4. lcr.load_gws
+
+   Loads gateways and prints ids of matching ones in priority order.
+
+   Name: lcr.load_gws
+
+   Parameters: lcr_id uri_user [caller_uri request_uri]
+
+   Example 1.57. lcr.load_gws RPC example
+                $ kamcmd lcr.load_gws 2 s:0447058050
+
+5.5. lcr.defunct_gw
 
    Defuncts gateway loaded into memory for a period of time (seconds)
    without a need to store gateway's defunct value into database and
@@ -1174,7 +1189,7 @@ if (to_any_gw("192.55.66.2", 1)) {
 
    Parameters: lcr_id gw_id period
 
-   Example 1.57. lcr.defunct_gw RPC example
+   Example 1.58. lcr.defunct_gw RPC example
                 $ kamcmd lcr.defunct_gw 1 4 120
 
 6. Known Limitations

+ 18 - 1
src/modules/lcr/doc/lcr_admin.xml

@@ -1183,7 +1183,7 @@ modparam("lcr", "ping_socket", "192.98.102.10:5060")
 		by caller_uri argument. If caller_uri argument is
 		omitted, it defaults to empty string. Both uri_user and
 		caller_uri argument may be a string or a pseudo variable
-		containing a sting value.  
+		containing a string value.  
 		</para>
 		<para>
 		Returns 1 if at least one matching gateway was found, 2
@@ -1553,6 +1553,23 @@ if (to_any_gw("192.55.66.2", 1)) {
 		</example>
 		</section>
 
+		<section>
+		<title><function>lcr.load_gws</function></title>
+		<para>
+			Loads gateways and prints ids of matching ones in priority order.
+		</para>
+		<para>
+		Name: <emphasis>lcr.load_gws</emphasis>
+		</para>
+		<para>Parameters: <emphasis>lcr_id uri_user [caller_uri request_uri]</emphasis></para>
+		<example>
+		<title><function>lcr.load_gws</function> RPC example</title>
+		<programlisting  format="linespecific">
+		$ &sercmd; lcr.load_gws 2 s:0447058050
+		</programlisting>
+		</example>
+		</section>
+
 		<section>
 		<title><function>lcr.defunct_gw</function></title>
 		<para>

+ 107 - 12
src/modules/lcr/lcr_mod.c

@@ -115,18 +115,6 @@ MODULE_VERSION
 #define DEF_LCR_GW_COUNT 128
 #define DEF_FETCH_ROWS 1024
 
-/*
- * Type definitions
- */
-
-struct matched_gw_info {
-    unsigned short gw_index;
-    unsigned short prefix_len;
-    unsigned short priority;
-    unsigned int weight;
-    unsigned short duplicate;
-};
-
 /*
  * Database variables
  */
@@ -1944,6 +1932,113 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws,
 }
 
 
+/*
+ * Loads ids matching GWs in priority order into gw_ids array.
+ * Returns the number of entries in the array.
+ */
+int load_gws_dummy(int lcr_id, str* ruri_user, str* from_uri, str* request_uri,
+		   unsigned int* gw_ids)
+{
+    int i, j;
+    unsigned int gw_index, now, dex;
+    struct rule_info **rules, *rule, *pl;
+    struct gw_info *gws;
+    struct target *t;
+    struct matched_gw_info matched_gws[MAX_NO_OF_GWS + 1];
+
+    if ((lcr_id < 1) || (lcr_id > lcr_count_param)) {
+	LM_ERR("invalid lcr_id parameter value %d\n", lcr_id);
+	return -1;
+    }
+
+    LM_DBG("load_gws_dummy(%u, %.*s, %.*s, %.*s)\n",
+	   lcr_id, ruri_user->len, ruri_user->s, from_uri->len, from_uri->s,
+	   request_uri->len, request_uri->s);
+
+    rules = rule_pt[lcr_id];
+    gws = gw_pt[lcr_id];
+    pl = rules[lcr_rule_hash_size_param];
+    gw_index = 0;
+
+    now = time((time_t *)NULL);
+
+    while (pl) {
+	if (ruri_user->len < pl->prefix_len) {
+	    pl = pl->next;
+	    continue;
+	}
+	rule = rule_hash_table_lookup(rules, pl->prefix_len, ruri_user->s);
+	while (rule) {
+
+	    if ((rule->prefix_len != pl->prefix_len) ||
+		strncmp(rule->prefix, ruri_user->s, pl->prefix_len))
+		goto next;
+	    
+	    if ((rule->from_uri_len != 0) &&
+		(pcre_exec(rule->from_uri_re, NULL, from_uri->s,
+			   from_uri->len, 0, 0, NULL, 0) < 0))
+		goto next;
+
+	    if (rule->request_uri_len != 0) {
+		if (request_uri->len == 0) {
+		    LM_ERR("lcr_rule has non-null request_uri and request_uri param has not been given.\n");
+		    return -1;
+		}
+		if (pcre_exec(rule->request_uri_re, NULL, request_uri->s,
+			      request_uri->len, 0, 0, NULL, 0) < 0)
+		    goto next;
+	    }
+
+	    t = rule->targets;
+	    while (t) {
+		if ((gws[t->gw_index].defunct_until > now) ||
+		    (gws[t->gw_index].state == GW_INACTIVE))
+		    goto skip_gw;
+		matched_gws[gw_index].gw_index = t->gw_index;
+		matched_gws[gw_index].prefix_len = pl->prefix_len;
+		matched_gws[gw_index].priority = t->priority;
+		matched_gws[gw_index].weight = t->weight *
+		    (kam_rand() >> 8);
+		matched_gws[gw_index].duplicate = 0;
+		LM_DBG("added matched_gws[%d]=[%u, %u, %u, %u]\n",
+		       gw_index, t->gw_index, pl->prefix_len,
+		       t->priority, matched_gws[gw_index].weight);
+		gw_index++;
+	    skip_gw:
+		t = t->next;
+	    }
+	    if (rule->stopper == 1) goto done;
+
+	next:
+	    rule = rule->next;
+	}
+	pl = pl->next;
+    }
+
+done:
+    qsort(matched_gws, gw_index, sizeof(struct matched_gw_info), comp_matched);
+
+    for (i = gw_index - 1; i >= 0; i--) {
+	if (matched_gws[i].duplicate == 1) continue;
+	dex = matched_gws[i].gw_index;
+	for (j = i - 1; j >= 0; j--) {
+	    if (matched_gws[j].gw_index == dex) {
+		matched_gws[j].duplicate = 1;
+	    }
+	}
+    }
+
+    j = 0;
+    for (i = gw_index - 1; i >= 0; i--) {
+	if (matched_gws[i].duplicate == 1) continue;
+	gw_ids[j] = gws[matched_gws[i].gw_index].gw_id;
+	j++;
+    }
+	
+    return j;
+}
+
+
 /*
  * Load info of matching GWs into gw_uri_avps
  */

+ 10 - 0
src/modules/lcr/lcr_mod.h

@@ -72,6 +72,14 @@ struct rule_id_info {
     struct rule_id_info *next;
 };
 
+struct matched_gw_info {
+    unsigned short gw_index;
+    unsigned short prefix_len;
+    unsigned short priority;
+    unsigned int weight;
+    unsigned short duplicate;
+};
+
 struct target {
     unsigned short gw_index;
     unsigned short priority;
@@ -127,6 +135,8 @@ extern struct gw_info **gw_pt;
 extern struct rule_info ***rule_pt;
 extern struct rule_id_info **rule_id_hash_table;
 
+extern int load_gws_dummy(int lcr_id, str* ruri_user, str* from_uri,
+			  str* request_uri, unsigned int* gw_ids);
 extern int reload_tables();
 extern int rpc_defunct_gw(unsigned int, unsigned int, unsigned int);
 

+ 40 - 0
src/modules/lcr/lcr_rpc.c

@@ -211,11 +211,51 @@ static void defunct_gw(rpc_t* rpc, void* c)
     return;
 }
 
+static const char* load_gws_doc[2] = {
+    "Load matching gateways and prints their ids in priority order.  Mandatory parameters are lcr_id and uri_user followed by optional parameters caller_uri and request_uri.  Error is reported if an lcr_rule with matching prefix and from_uri has non-null request_uri and request_uri parameter has not been given.",
+    0
+};
+
+
+static void load_gws(rpc_t* rpc, void* c)
+{
+    unsigned int lcr_id, i;
+    int gw_count, ret;
+    str uri_user;
+    str caller_uri;
+    str request_uri;
+    unsigned int gw_ids[MAX_NO_OF_GWS];
+
+    ret =  rpc->scan(c, "dS*SS", &lcr_id, &uri_user, &caller_uri, &request_uri);
+    if (ret == -1) {
+	rpc->fault(c, 400, "parameter error; if using cli, remember to prefix numeric uri_user param value with 's:'");
+	return;
+    }
+
+    if (ret < 4) request_uri.len = 0;
+    if (ret < 3) caller_uri.len = 0;
+
+    gw_count = load_gws_dummy(lcr_id, &uri_user, &caller_uri, &request_uri,
+			      &(gw_ids[0]));
+
+    if (gw_count < 0) {
+	rpc->fault(c, 400, "load_gws excution error (see syslog)");
+	return;
+    }
+    
+    for (i = 0; i < gw_count; i++) {
+	rpc->add(c, "d", gw_ids[i]);
+    }
+	
+    return;
+}
+
 
 rpc_export_t lcr_rpc[] = {
     {"lcr.reload", reload, reload_doc, 0},
     {"lcr.dump_gws", dump_gws, dump_gws_doc, 0},
     {"lcr.dump_rules", dump_rules, dump_rules_doc, 0},
     {"lcr.defunct_gw", defunct_gw, defunct_gw_doc, 0},
+    {"lcr.load_gws", load_gws, load_gws_doc, 0},
     {0, 0, 0, 0}
 };