Browse Source

config.json parsing

Ian Goldberg 1 year ago
parent
commit
10f7a028d5
3 changed files with 131 additions and 13 deletions
  1. 95 0
      App/config.cpp
  2. 31 0
      App/config.hpp
  3. 5 13
      App/teems.cpp

+ 95 - 0
App/config.cpp

@@ -0,0 +1,95 @@
+#include <iostream>
+#include "config.hpp"
+
+// The next line suppresses a deprecation warning within boost
+#define BOOST_BIND_GLOBAL_PLACEHOLDERS
+#include "boost/property_tree/ptree.hpp"
+#include "boost/property_tree/json_parser.hpp"
+
+Config g_config;
+
+// Split a hostport string like "127.0.0.1:12000" at the rightmost colon
+// into a host part "127.0.0.1" and a port part "12000".
+static bool split_host_port(std::string &host, std::string &port,
+    const std::string &hostport)
+{
+    size_t colon = hostport.find_last_of(':');
+    if (colon == std::string::npos) {
+        std::cerr << "Cannot parse \"" << hostport << "\" as host:port\n";
+        return false;
+    }
+    host = hostport.substr(0, colon);
+    port = hostport.substr(colon+1);
+    return true;
+}
+
+bool config_parse(const std::string configstr, const std::string &myname)
+{
+    bool found_my_node = false;
+    bool found_params = false;
+    bool ret = true;
+
+    std::istringstream configstream(configstr);
+    boost::property_tree::ptree conftree;
+
+    read_json(configstream, conftree);
+
+    for (auto & entry : conftree) {
+        if (!entry.first.compare("params")) {
+            for (auto & pentry : entry.second) {
+                if (!pentry.first.compare("msgsize")) {
+                    g_config.msgsize = pentry.second.get_value<uint16_t>();
+                } else {
+                    std::cerr << "Unknown field in params: " <<
+                        pentry.first << "\n";
+                    ret = false;
+                }
+            }
+            found_params = true;
+        } else if (!entry.first.compare("nodes")) {
+            for (auto & node : entry.second) {
+                NodeConfig nc;
+                nc.weight = 1;  // default
+                for (auto & nentry : node.second) {
+                    if (!nentry.first.compare("name")) {
+                        nc.name = nentry.second.get_value<std::string>();
+                        if (!myname.compare(nc.name)) {
+                            g_config.mynodenum = g_config.nodes.size();
+                            found_my_node = true;
+                        }
+                    } else if (!nentry.first.compare("pubkey")) {
+                        nc.pubkey = nentry.second.get_value<std::string>();
+                    } else if (!nentry.first.compare("weight")) {
+                        nc.weight = nentry.second.get_value<std::uint8_t>();
+                    } else if (!nentry.first.compare("listen")) {
+                        ret &= split_host_port(nc.listenhost, nc.listenport,
+                            nentry.second.get_value<std::string>());
+                    } else if (!nentry.first.compare("clisten")) {
+                        ret &= split_host_port(nc.clistenhost, nc.clistenport,
+                            nentry.second.get_value<std::string>());
+                    } else {
+                        std::cerr << "Unknown field in host config: " <<
+                            nentry.first << "\n";
+                        ret = false;
+                    }
+                }
+                g_config.nodes.push_back(std::move(nc));
+            }
+        } else {
+            std::cerr << "Unknown key in config: " <<
+                entry.first << "\n";
+            ret = false;
+        }
+    }
+
+    if (!found_params) {
+        std::cerr << "Could not find params in config\n";
+        ret = false;
+    }
+    if (!found_my_node) {
+        std::cerr << "Could not find my own node entry in config\n";
+        ret = false;
+    }
+
+    return ret;
+}

+ 31 - 0
App/config.hpp

@@ -0,0 +1,31 @@
+#ifndef __CONFIG_HPP__
+#define __CONFIG_HPP__
+
+#include <string>
+#include <vector>
+#include <cstdint>
+
+// The per-node config
+struct NodeConfig {
+    std::string name;
+    std::string pubkey;  // a 128-character hex string
+    std::string listenhost, listenport;
+    std::string clistenhost, clistenport;
+    uint8_t weight;
+};
+
+// The global config
+struct Config {
+    // global params
+    uint16_t msgsize;
+    // config for each node
+    std::vector<NodeConfig> nodes;
+    // Which node is this one?
+    size_t mynodenum;
+};
+
+extern Config g_config;
+
+bool config_parse(const std::string configstr, const std::string &myname);
+
+#endif

+ 5 - 13
App/teems.cpp

@@ -6,11 +6,7 @@
 #include "sgx_tcrypto.h"
 #include "sgx_tseal.h"
 #include "Untrusted.hpp"
-
-// The next line suppresses a deprecation warning within boost
-#define BOOST_BIND_GLOBAL_PLACEHOLDERS
-#include "boost/property_tree/ptree.hpp"
-#include "boost/property_tree/json_parser.hpp"
+#include "config.hpp"
 
 static bool hexdump(FILE *outf, const char *label, void *p, size_t len)
 {
@@ -181,7 +177,7 @@ int main(int argc, char **argv)
     }
 
     const char *sealedprivkeyfile = argv[1];
-    const char *myname = argv[2];
+    std::string myname(argv[2]);
 
     // Read the config.json from the first line of stdin.  We have to do
     // this before outputting anything to avoid potential deadlock with
@@ -201,13 +197,9 @@ int main(int argc, char **argv)
     }
     fclose(sprivf);
 
-    using boost::property_tree::ptree;
-
-    ptree conf;
-
-    std::istringstream configstream(config);
-
-    read_json(configstream, conf);
+    if (!config_parse(config, myname)) {
+        exit(1);
+    }
 
     sgx_destroy_enclave(global_eid);