minor build fix for zonekeeperless builds
[distributedratelimiting.git] / drl / config.c
index 1c56ce8..86d1ec4 100644 (file)
@@ -79,10 +79,13 @@ int get_eligible_leaves(drl_instance_t *instance) {
 
         return ENOMEM;
     }
+    memset(leaves, 0, count * sizeof(leaf_t));
 
     for (i = 0; i < count; ++i) {
         leaves[i].xid = atoi(names[i]->d_name);
         leaves[i].parent = NULL;
+        leaves[i].drop_prob = 0.0;
+        leaves[i].delay = 0;
         
         free(names[i]);
 
@@ -103,12 +106,26 @@ static int parse_common(xmlDocPtr doc, xmlNodePtr ident, ident_config *common) {
     xmlChar *limit;
     xmlChar *commfabric;
     xmlChar *branch;
+    xmlChar *membership;
+    xmlChar *failure_behavior;
     xmlChar *accounting;
     xmlChar *ewma;
-    xmlChar *intervals;
+    xmlChar *mainloop_intervals;
+    xmlChar *communication_intervals;
+    xmlChar *independent;
+    xmlChar *htb_node;
+    xmlChar *htb_parent;
     xmlNodePtr fields = ident->children;
     ident_peer *current = NULL;
 
+    /* The struct has been memsetted to 0, this is just to be safe. */
+#ifdef BUILD_ZOOKEEPER
+    common->zk_host = NULL;
+#endif
+    common->peers = NULL;
+    common->members = NULL;
+    common->next = NULL;
+
     /* Make sure no required fields are missing. */
     id = xmlGetProp(ident, (const xmlChar *) "id");
     if (id == NULL) {
@@ -145,7 +162,7 @@ static int parse_common(xmlDocPtr doc, xmlNodePtr ident, ident_config *common) {
         xmlFree(commfabric);
     }
 
-    /* Only care about branching factor if we're using gossip. */
+    /* Only care about branching factor and failure detector if we're using gossip. */
     if (common->commfabric == COMM_GOSSIP) {
         branch = xmlGetProp(ident, (const xmlChar *) "branch");
         if (branch == NULL) {
@@ -155,6 +172,46 @@ static int parse_common(xmlDocPtr doc, xmlNodePtr ident, ident_config *common) {
             common->branch = atoi((const char *) branch);
             xmlFree(branch);
         }
+
+        membership = xmlGetProp(ident, (const xmlChar *) "membership");
+        if (membership == NULL) {
+            printlog(LOG_CRITICAL, "Ident missing membership protocol selection.\n");
+            return EINVAL;
+        } else {
+            if (!xmlStrcmp(membership, (const xmlChar *) "SWIM")) {
+                common->membership = SWIM;
+            } else if (!xmlStrcmp(membership, (const xmlChar *) "ZOOKEEPER")) {
+#ifdef BUILD_ZOOKEEPER
+                common->membership = ZOOKEEPER;
+#else
+                printlog(LOG_CRITICAL, "Zookeeper requested, but support not compiled into DRL at configure time.\n");
+                xmlFree(membership);
+                return EINVAL;
+#endif
+            } else {
+                printlog(LOG_CRITICAL, "Unknown/invalid gossip group membership protocol.\n");
+                xmlFree(membership);
+                return EINVAL;
+            }
+            xmlFree(membership);
+        }
+
+        failure_behavior = xmlGetProp(ident, (const xmlChar *) "failure_behavior");
+        if (failure_behavior == NULL) {
+            printlog(LOG_CRITICAL, "Ident missing failure handling behavior.\n");
+            return EINVAL;
+        } else {
+            if (!xmlStrcmp(failure_behavior, (const xmlChar *) "PANIC")) {
+                common->failure_behavior = PANIC;
+            } else if (!xmlStrcmp(failure_behavior, (const xmlChar *) "QUORUM")) {
+                common->failure_behavior = QUORUM;
+            } else {
+                printlog(LOG_CRITICAL, "Unknown/invalid gossip failure behavior policy.\n");
+                xmlFree(failure_behavior);
+                return EINVAL;
+            }
+            xmlFree(failure_behavior);
+        }
     }
 
     accounting = xmlGetProp(ident, (const xmlChar *) "accounting");
@@ -168,6 +225,8 @@ static int parse_common(xmlDocPtr doc, xmlNodePtr ident, ident_config *common) {
             common->accounting = ACT_SAMPLEHOLD;
         } else if (!xmlStrcmp(accounting, (const xmlChar *) "SIMPLE")) {
             common->accounting = ACT_SIMPLE;
+        } else if (!xmlStrcmp(accounting, (const xmlChar *) "MULTIPLEINTERVAL")) {
+            common->accounting = ACT_MULTIPLE;
         } else {
             printlog(LOG_CRITICAL, "Unknown/invalid accounting table.\n");
             xmlFree(accounting);
@@ -185,13 +244,45 @@ static int parse_common(xmlDocPtr doc, xmlNodePtr ident, ident_config *common) {
         xmlFree(ewma);
     }
 
-    intervals = xmlGetProp(ident, (const xmlChar *) "intervals");
-    if (intervals == NULL) {
-        printlog(LOG_CRITICAL, "Ident missing interval count.\n");
-        return EINVAL;
+    mainloop_intervals = xmlGetProp(ident, (const xmlChar *) "loop_intervals");
+    if (mainloop_intervals == NULL) {
+        printlog(LOG_WARN, "Ident id: %d missing loop_intervals, assuming 1.\n", common->id);
+        common->mainloop_intervals = 1;
     } else {
-        common->intervals = atoi((const char *) intervals);
-        xmlFree(intervals);
+        common->mainloop_intervals = atoi((const char *) mainloop_intervals);
+        xmlFree(mainloop_intervals);
+    }
+
+    communication_intervals = xmlGetProp(ident, (const xmlChar *) "comm_intervals");
+    if (communication_intervals == NULL) {
+        printlog(LOG_WARN, "Ident id: %d missing comm_intervals, assuming 1.\n", common->id);
+        common->communication_intervals = 1;
+    } else {
+        common->communication_intervals = atoi((const char *) communication_intervals);
+        xmlFree(communication_intervals);
+    }
+
+    independent = xmlGetProp(ident, (const xmlChar *) "independent");
+    if (independent == NULL) {
+        common->independent = 0;
+    } else {
+        common->independent = atoi((const char *) independent);
+        xmlFree(independent);
+    }
+
+    htb_node = xmlGetProp(ident, (const xmlChar *) "htb_node");
+    htb_parent = xmlGetProp(ident, (const xmlChar *) "htb_parent");
+    if (htb_node == NULL) {
+        common->htb_node = -1;
+    } else {
+        sscanf((const char *)htb_node, "%x", &common->htb_node);
+        xmlFree(htb_node);
+    }
+    if (htb_parent == NULL) {
+        common->htb_parent = -1;
+    } else {
+        sscanf((const char *)htb_parent, "%x", &common->htb_parent);
+        xmlFree(htb_parent);
     }
 
     while (fields != NULL) {
@@ -219,6 +310,16 @@ static int parse_common(xmlDocPtr doc, xmlNodePtr ident, ident_config *common) {
                 current->next = NULL;
             }
             xmlFree(ip);
+        } else if ((!xmlStrcmp(fields->name, (const xmlChar *) "zkhost"))) {
+            xmlChar *host = xmlNodeListGetString(doc, fields->children, 1);
+
+#ifdef BUILD_ZOOKEEPER
+            common->zk_host = strdup((const char *) host);
+            if (common->zk_host == NULL) {
+                return ENOMEM;
+            }
+#endif
+            xmlFree(host);
         }
         fields = fields->next;
     }
@@ -228,6 +329,12 @@ static int parse_common(xmlDocPtr doc, xmlNodePtr ident, ident_config *common) {
         return EINVAL;
     }
 
+#ifdef BUILD_ZOOKEEPER
+    if (common->membership == ZOOKEEPER && common->zk_host == NULL) {
+        printlog(LOG_CRITICAL, "Group membership protocol ZOOKEEPER requires a zkhost field.\n");
+        return EINVAL;
+    }
+#endif
     /* No errors. */
     return 0;
 }