IDSLoadbalancerCfg::IDSLoadbalancerCfg(XMLElement* elem) : CfgHelper<IDSLoadbalancer, IDSLoadbalancerCfg>(elem, "IDSLoadbalancer"), selector(NULL), updateInterval(0) { if (!elem) return; XMLNode::XMLSet<XMLElement*> set = elem->getElementChildren(); for (XMLNode::XMLSet<XMLElement*>::iterator it = set.begin(); it != set.end(); it++) { XMLElement* e = *it; if (e->matches("updateinterval")) { updateInterval = getInt("updateinterval", 0, e); } else if (e->matches("PacketSelector")) { XMLAttribute *a = e->getAttribute("type"); if (!a) THROWEXCEPTION("no PacketSelector specified"); string _selector = a->getValue(); if (_selector == "HashPacketSelector") { if (!selector) { selector = new HashPacketSelector(); } else THROWEXCEPTION("IDSLoadBalancerCfg: multiple packet selectors specified! This is not allowed."); } else if (_selector == "IpPacketSelector") { msg(MSG_DEBUG, "IpPacketSelector"); XMLNode::XMLSet<XMLElement*> set = e->getElementChildren(); for (XMLNode::XMLSet<XMLElement*>::iterator it = set.begin(); it != set.end(); it++) { XMLElement* e = *it; if (e->matches("DestinationIp")){ XMLAttribute *a = e->getAttribute("queueno"); if (!a) THROWEXCEPTION("No queue number specified"); int queueno = 0; std::string tmp = a->getValue(); try { queueno = boost::lexical_cast<int>(tmp); }catch (boost::bad_lexical_cast &){ THROWEXCEPTION("bad value for queue number: %s", tmp.c_str()); } std::string ip = e->getFirstText(); dst[parseIp(ip)] = queueno; }else if (e->matches("SourceIp")){ XMLElement* e = *it; XMLAttribute *a = e->getAttribute("queueno"); if (!a) THROWEXCEPTION("No queue number specified"); int queueno = 0; std::string tmp = a->getValue(); try { queueno = boost::lexical_cast<int>(tmp); }catch (boost::bad_lexical_cast &){ THROWEXCEPTION("bad value for queue number: %s", tmp.c_str()); } std::string ip = e->getFirstText(); src[parseIp(ip)] = queueno; } } if (!selector) { selector = new IpPacketSelector(); if (src.empty() && dst.empty()) THROWEXCEPTION("IDSLoadBalancerCfg: packet selector IpPacketSelector was defined, but no source or destination IPs!"); } else THROWEXCEPTION("IDSLoadBalancerCfg: multiple packet selectors specified! This is not allowed."); } else if (_selector == "PriorityPacketSelector") { float startprio = getDouble("startPriority", 1.0, e); uint32_t minmontime = getInt("minimumMonitoringTime", 10000, e); uint32_t maxspeed = getInt("maxSpeed", 0, e); list<PriorityNetConfig> config; list<WeightModifierConfig> weightmods; XMLNode::XMLSet<XMLElement*> set = e->getElementChildren(); for (XMLNode::XMLSet<XMLElement*>::iterator it = set.begin(); it != set.end(); it++) { XMLElement* e = *it; if (e->matches("networks")) { XMLNode::XMLSet<XMLElement*> netset = e->getElementChildren(); for (XMLNode::XMLSet<XMLElement*>::iterator nit = netset.begin(); nit != netset.end(); nit++) { XMLElement* e = *nit; if (e->matches("network")) { XMLAttribute* a = e->getAttribute("address"); if (!a) THROWEXCEPTION("IDSLoadBalancerCfg: no attribute 'address' in configuration element 'network'!"); string cidr = a->getFirstText(); size_t pos = cidr.find("/"); string ip = cidr.substr(0, pos); string sbits = cidr.substr(pos+1); int maskbits = atoi(sbits.c_str()); if (maskbits<0 || maskbits>32) THROWEXCEPTION("IDSLoadBalancerCfg: attribute 'address' has invalid number of mask bits in configuration (%s)!", sbits.c_str()); in_addr_t ipaddr = inet_addr(ip.c_str()); if (ipaddr==(in_addr_t)-1) THROWEXCEPTION("IDSLoadBalancerCfg: attribute 'address' has invalid ip subnet in configuration (%s)!", ip.c_str()); a = e->getAttribute("weight"); if (!a) THROWEXCEPTION("IDSLoadBalancerCfg: no attribute 'weight' in configuration element 'network'!"); char* res; float weight = strtof(a->getFirstText().c_str(), &res); if (weight<=0 || res==a->getFirstText().c_str()) THROWEXCEPTION("IDSLoadBalancerCfg: attribute 'weight' in configuration element 'network' contains invalid value (%s)!", a->getFirstText().c_str()); config.push_back(PriorityNetConfig(ntohl((uint32_t)ipaddr), ((1<<(32-maskbits))-1)^0xFFFFFFFF, maskbits, weight)); } } } if (e->matches("weightModifiers")) { XMLNode::XMLSet<XMLElement*> netset = e->getElementChildren(); for (XMLNode::XMLSet<XMLElement*>::iterator nit = netset.begin(); nit != netset.end(); nit++) { XMLElement* e = *nit; if (e->matches("traffic")) { XMLAttribute* a = e->getAttribute("quantile"); if (!a) THROWEXCEPTION("IDSLoadBalancerCfg: no attribute 'quantile' in configuration element 'traffic'!"); char* res; float quantile = strtof(a->getFirstText().c_str(), &res); if (quantile<=0 || quantile>1 || res==a->getFirstText().c_str()) THROWEXCEPTION("IDSLoadBalancerCfg: attribute 'quantile' is not in expected range (0<x<=1): %s", a->getFirstText().c_str()); a = e->getAttribute("weightModifier"); if (!a) THROWEXCEPTION("IDSLoadBalancerCfg: no attribute 'weightModifier' in configuration element 'traffic'!"); float weightmod = strtof(a->getFirstText().c_str(), &res); if (weightmod<=0 || res==a->getFirstText().c_str()) THROWEXCEPTION("IDSLoadBalancerCfg: attribute 'weightModifier' is not in expected range (0<x): %s", a->getFirstText().c_str()); weightmods.push_back(WeightModifierConfig(quantile, weightmod)); } } } } if (!selector) { struct timeval tv; tv.tv_sec = minmontime/1000; tv.tv_usec = (minmontime%1000)*1000; // sort the network configuration by decreasing maskbits config.sort(compareDecrMask); selector = new PriorityPacketSelector(config, startprio, tv, maxspeed, weightmods); } else THROWEXCEPTION("IDSLoadBalancerCfg: multiple packet selectors specified! This is not allowed."); } else { THROWEXCEPTION("Invalid selector: %s", _selector.c_str()); } } } if (!selector) THROWEXCEPTION("IDSLoadBalancerCfg: No packet selector specified, this is compulsory"); }