summaryrefslogtreecommitdiff
path: root/src/lbdatafactory.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lbdatafactory.cc')
-rw-r--r--src/lbdatafactory.cc334
1 files changed, 334 insertions, 0 deletions
diff --git a/src/lbdatafactory.cc b/src/lbdatafactory.cc
new file mode 100644
index 0000000..0220416
--- /dev/null
+++ b/src/lbdatafactory.cc
@@ -0,0 +1,334 @@
+/*
+ * Module: lbdatafactory.cc
+ *
+ * **** License ****
+ * Version: VPL 1.0
+ *
+ * The contents of this file are subject to the Vyatta Public License
+ * Version 1.0 ("License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.vyatta.com/vpl
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * This code was originally developed by Vyatta, Inc.
+ * Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc.
+ * All Rights Reserved.
+ *
+ * Author: Michael Larson
+ * Date: 2007
+ * Description:
+ *
+ * **** End License ****
+ *
+ */
+#include <syslog.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string>
+#include <algorithm>
+#include <vector>
+#include <iostream>
+#include "rl_str_proc.hh"
+#include "lbdata.hh"
+#include "lbdatafactory.hh"
+
+using namespace std;
+
+
+LBDataFactory::LBDataFactory()
+{
+}
+
+LBDataFactory::~LBDataFactory()
+{
+
+}
+
+bool
+LBDataFactory::load(const string &conf_file)
+{
+ //open file
+ FILE *fp = fopen(conf_file.c_str(), "r");
+ if (fp == NULL) {
+ cerr << "Error opening configuration file: " << conf_file << endl;
+ syslog(LOG_ERR, "wan_lb: configuration file not found: %s", conf_file.c_str());
+ return false;
+ }
+
+ //read line by line and populate vect
+ char str[1025];
+ int depth(0);
+ vector<string> path(10);
+ while (fgets(str, 1024, fp) != 0) {
+ string line(str);
+
+ int pos = line.find("#");
+ line = line.substr(0,pos);
+
+ string key,value;
+
+ StrProc tokens(line, " ");
+ for (int i = 0; i < tokens.size(); ++i) {
+ string symbol = tokens.get(i);
+
+ if (symbol != "{" && symbol != "}") {
+ if (key.empty()) {
+ key = symbol;
+ }
+ else if (value.empty()) {
+ value = symbol;
+ }
+ path[depth] = key;
+ }
+ else if (symbol == "{") {
+ ++depth;
+ }
+ else if (symbol == "}") {
+ --depth;
+ }
+ }
+ if (tokens.size() != 0) {
+ process(path,depth,key,value);
+ }
+ if (depth > 9 || depth < 0) {
+ cerr << "configuration error: malformed configuration file: brackets" << endl;
+ syslog(LOG_ERR, "wan_lb: malformed configuration file: brackets");
+ return false;
+ }
+ }
+
+ fclose(fp);
+ if (depth != 0) {
+ cerr << "configuration error: mismatched brackets in configuration file" << endl;
+ syslog(LOG_ERR, "wan_lb: configuration error due to mismatched brackets");
+ return false;
+ }
+
+#ifdef DEBUG
+ _lb_data.dump();
+#endif
+ return true;
+}
+
+
+void
+LBDataFactory::process(const vector<string> &path, int depth, const string &key, const string &value)
+{
+ string l_key, l_value;
+ std::transform(key.begin(), key.end(), std::back_inserter(l_key),
+ static_cast < int(*)(int) > (std::tolower));
+ std::transform(value.begin(), value.end(), std::back_inserter(l_value),
+ static_cast < int(*)(int) > (std::tolower));
+ if (path[0] == "health") {
+ if (l_key == "interface") {
+ process_health(l_key,l_value);
+ }
+ else {
+ process_health_interface(l_key,l_value);
+ }
+ }
+ else if (path[0] == "rule") {
+ if (depth > 0 && path[1] == "source") {
+ process_rule_source(l_key,l_value);
+ }
+ else if (depth > 0 && path[1] == "destination") {
+ process_rule_destination(l_key,l_value);
+ }
+ else if (depth > 1 && path[1] == "interface") {
+ process_rule_interface(l_key,l_value);
+ }
+ else if (depth > 0 && path[1] == "protocol") {
+ process_rule_protocol(l_key,l_value);
+ }
+ else {
+ process_rule(l_key,l_value);
+ }
+ }
+}
+
+
+void
+LBDataFactory::process_health(const string &key, const string &value)
+{
+ if (value.empty() == false) {
+ LBData::InterfaceHealthIter iter = _lb_data._iface_health_coll.find(key);
+ if (iter == _lb_data._iface_health_coll.end()) {
+ _lb_data._iface_health_coll.insert(pair<string,LBHealth>(value,LBHealth()));
+ }
+ _health_iter = _lb_data._iface_health_coll.find(value);
+ }
+}
+
+
+void
+LBDataFactory::process_health_interface(const string &key, const string &value)
+{
+ if (key == "target") {
+ _health_iter->second._ping_target = value;
+ }
+ else if (key == "success-ct") {
+ int num = strtoul(value.c_str(), NULL, 10);
+ if (num > 0) {
+ _health_iter->second._success_ct = num;
+ }
+ else {
+ cerr << "illegal success-ct specified: " << value << endl;
+ syslog(LOG_ERR, "wan_lb: illegal success-ct specified in configuration file: %s", value.c_str());
+ }
+ }
+ else if (key == "failure-ct") {
+ int num = strtoul(value.c_str(), NULL, 10);
+ if (num > 0) {
+ _health_iter->second._failure_ct = num;
+ }
+ else {
+ cerr << "illegal failure-ct specified: " << value << endl;
+ syslog(LOG_ERR, "wan_lb: illegal failure-ct specified in configuration file: %s", value.c_str());
+ }
+ }
+ else if (key == "ping-resp") {
+ int num = strtoul(value.c_str(), NULL, 10);
+ if (num > 0) {
+ _health_iter->second._ping_resp_time = num;
+ }
+ else {
+ cerr << "illegal ping-resp specified: " << value << endl;
+ syslog(LOG_ERR, "wan_lb: illegal ping-resp specified in configuration file: %s", value.c_str());
+ }
+ }
+ else if (key == "health") {
+ //nothing
+ }
+ else {
+ cout << "LBDataFactory::process_health(): " << "don't understand this symbol: " << key << endl;
+ //nothing
+ }
+
+}
+
+void
+LBDataFactory::process_rule(const string &key, const string &value)
+{
+ if (key.empty()) {
+ return;
+ }
+#ifdef DEBUG
+ cout << "LBDataFactor::process_rule(): " << key << ", " << value << endl;
+#endif
+ int num = strtoul(value.c_str(), NULL, 10);
+ if (num > 0) {
+ _lb_data._lb_rule_coll.insert(pair<int,LBRule>(num,LBRule()));
+ }
+ else {
+ cerr << "Rule number: illegal value" << endl;
+ syslog(LOG_ERR, "wan_lb: illegal rule number: %s", value.c_str());
+ return;
+ }
+ _rule_iter = _lb_data._lb_rule_coll.find(num);
+}
+
+void
+LBDataFactory::process_rule_protocol(const string &key, const string &value)
+{
+ if (key == "protocol") {
+ if (strcasecmp(value.c_str(),"ALL") == 0) {
+ _rule_iter->second._proto = "all";
+ }
+ else if (strcasecmp(value.c_str(),"ICMP") == 0) {
+ _rule_iter->second._proto = "icmp";
+ }
+ else if (strcasecmp(value.c_str(), "UDP") == 0) {
+ _rule_iter->second._proto = "udp";
+ }
+ else if (strcasecmp(value.c_str(),"TCP") == 0) {
+ _rule_iter->second._proto = "tcp";
+ }
+ else {
+ cerr << "protocol not recognized: " << key << ", " << value << endl;
+ syslog(LOG_ERR, "wan_lb: illegal protocol specified: %s", value.c_str());
+ }
+ }
+}
+
+void
+LBDataFactory::process_rule_source(const string &key, const string &value)
+{
+ if (key == "address") {
+ if (inet_addr(value.c_str()) == (unsigned)-1) {
+ cerr << "malformed ip address: " << key << ", " << value << endl;
+ syslog(LOG_ERR, "wan_lb, malformed ip address in configuration: %s,%s", key.c_str(),value.c_str());
+ return;
+ }
+ _rule_iter->second._s_addr = value;
+ }
+ else if (key == "network") {
+ _rule_iter->second._s_net = value;
+ }
+ else if (key == "port-name") {
+ _rule_iter->second._s_port_num = value;
+ }
+ else if (key == "port-number") {
+ _rule_iter->second._s_port_name = value;
+ }
+}
+
+void
+LBDataFactory::process_rule_destination(const string &key, const string &value)
+{
+ if (key == "address") {
+ if (inet_addr(value.c_str()) == (unsigned)-1) {
+ cerr << "malformed ip address: " << key << ", " << value << endl;
+ syslog(LOG_ERR, "wan_lb, malformed ip address in configuration: %s,%s", key.c_str(),value.c_str());
+ return;
+ }
+ _rule_iter->second._d_addr = value;
+ }
+ else if (key == "network") {
+ _rule_iter->second._d_net = value;
+ }
+ else if (key == "port-name") {
+ _rule_iter->second._d_port_num = value;
+ }
+ else if (key == "port-number") {
+ _rule_iter->second._d_port_name = value;
+ }
+}
+
+void
+LBDataFactory::process_rule_interface(const string &key, const string &value)
+{
+#ifdef DEBUG
+ cout << "LBDataFactory::process_rule_interface(): " << key << ", " << value << endl;
+#endif
+ if (key == "interface") {
+ _rule_iter->second._iface_dist_coll.insert(pair<string,int>(value,0));
+ _rule_iface_iter = _rule_iter->second._iface_dist_coll.find(value);
+ }
+ else if (key == "weight") {
+ int num = strtoul(value.c_str(), NULL, 10);
+ if (num > 0) {
+ _rule_iface_iter->second = num;
+ }
+ else {
+ cerr << "illegal interface weight specified: " << value << endl;
+ syslog(LOG_ERR, "wan_lb: illegal interface weight specified in configuration file: %s", value.c_str());
+ }
+ }
+ else {
+ cerr << "LBDataFactory::process_rule(): " << "don't understand this symbol: " << key << endl;
+ }
+}
+
+
+
+LBData
+LBDataFactory::get()
+{
+ return _lb_data;
+}
+