uint64_t RoutingTable::networkEnvironmentFingerprint(const std::vector<std::string> &ignoreInterfaces) const { uint64_t fp = 0; std::vector<Entry> rtab(get()); for(std::vector<Entry>::const_iterator re(rtab.begin());re!=rtab.end();++re) { bool skip = false; for(std::vector<std::string>::const_iterator ii(ignoreInterfaces.begin());ii!=ignoreInterfaces.end();++ii) { if (*ii == re->device) { skip = true; break; } } if (skip) continue; ++fp; if (re->destination.isV4()) { fp = Utils::sdbmHash(re->destination.rawIpData(),4,fp); fp = Utils::sdbmHash((uint16_t)re->destination.netmaskBits(),fp); } else if (re->destination.isV6()) { fp = Utils::sdbmHash(re->destination.rawIpData(),16,fp); fp = Utils::sdbmHash((uint16_t)re->destination.netmaskBits(),fp); } if (re->gateway.isV4()) { fp = Utils::sdbmHash(re->gateway.rawIpData(),4,fp); fp = Utils::sdbmHash((uint16_t)re->gateway.netmaskBits(),fp); } else if (re->gateway.isV6()) { fp = Utils::sdbmHash(re->gateway.rawIpData(),16,fp); fp = Utils::sdbmHash((uint16_t)re->gateway.netmaskBits(),fp); } fp = Utils::sdbmHash(re->device,fp); fp = Utils::sdbmHash((uint32_t)re->metric,fp); } return fp; }
int main(){ rid *nr = create_rid_f(create_rid("test.cfg")); rid *rr = rtab(nr); /* rid *nr = create_rid("a(b(c,d.d1),e.f)"); rid *pr = rstr(nr); */ print_rid(rr); }
std::string Json::serialize(const Variant &data, bool &success, const std::string& tab) { std::string str; success = true; if( data.isNull() ) // invalid or null? { return "null"; } switch( data.type() ) { case Variant::List: case Variant::NStringArray: // variant is a list? { StringArray values; const VariantList rlist = data.toList(); std::string serializedValue; serializedValue.reserve( 512 ); for( auto item : rlist ) { serializedValue = serialize( item, "" ); if( serializedValue.empty() ) { success = false; break; } values.push_back( serializedValue ); } str = "[ " + join( values, ", " ) + " ]"; } break; case Variant::Map: // variant is a map? { VariantMap vmap = data.toMap(); if( vmap.empty() ) { str = "{}"; } else { str = "{ \n"; StringArray pairs; std::string serializedValue; serializedValue.reserve( 512 ); for( auto item : vmap ) { serializedValue = serialize( item.second, tab + " "); if( serializedValue.empty()) { //success = false; pairs.push_back( tab + sanitizeString( item.first ) + std::string( " : \"nonSerializableValue\"" ) ); continue; } pairs.push_back( tab + sanitizeString( item.first ) + " : " + serializedValue ); } str += join(pairs, ",\n"); std::string rtab( tab ); rtab.resize( std::max<int>( 0, tab.size() - 2 ) ); str += std::string( "\n" ) + rtab + "}"; } } break; case Variant::String: case Variant::NByteArray: // a string or a byte array? { str = sanitizeString( data.toString() ); } break; case Variant::Double: case Variant::Float: // double? { // TODO: cheap hack - almost locale independent double formatting str = utils::format( 0xff, "\"%f\"", data.toDouble() ); str = utils::replace(str, ",", "."); if( str.find(".") == std::string::npos && str.find("e") == std::string::npos ) { str += ".0"; } } break; case Variant::NTilePos: { const TilePos& pos = data.toTilePos(); str = utils::format( 0xff, "[ %d, %d ]", pos.i(), pos.j() ); } break; case Variant::NSize: { const Size& size = data.toSize(); str = utils::format( 0xff, "[ %d, %d ]", size.width(), size.height() ); } break; case Variant::NPoint: { const Point& pos = data.toPoint(); str = utils::format( 0xff, "[ %d, %d ]", pos.x(), pos.y() ); } break; case Variant::NPointF: { PointF pos = data.toPointF(); // TODO: cheap hack - almost locale independent double formatting std::string posX = utils::replace(utils::format( 0xff, "%f", pos.x()), ",", "."); std::string posY = utils::replace(utils::format( 0xff, "%f", pos.y()), ",", "."); str = utils::format( 0xff, "[ \"%s\", \"%s\" ]", posX.c_str(), posY.c_str() ); } break; case Variant::Bool: // boolean value? { str = data.toBool() ? "true" : "false"; } break; case Variant::ULongLong: // large unsigned number? { str = utils::format( 0xff, "%u", data.toULongLong() ); } break; case Variant::Int: // simple int? { str = utils::format( 0xff, "%d", data.toInt() ); } break; case Variant::UInt: { str = utils::format( 0xff, "%d", data.toInt() ); } break; default: if ( data.canConvert( Variant::LongLong ) ) // any signed number? { str = utils::format( 0xff, "%d", data.toLongLong() ); } else if (data.canConvert( Variant::Long )) { str = utils::format( 0xff, "%d", data.toLongLong() ); } else if (data.canConvert( Variant::String ) ) // can value be converted to string? { // this will catch Date, DateTime, Url, ... str = sanitizeString( data.toString() ); } else { success = false; } break; } return success ? str : std::string(); }
std::string Json::serialize(const Variant &data, bool &success, const std::string& tab) { std::string str; success = true; if( !data.isValid() ) // invalid or null? { str = "null"; } else if( (data.type() == Variant::List) || (data.type() == Variant::NStringArray) ) // variant is a list? { StringArray values; const VariantList rlist = data.toList(); for( VariantList::const_iterator it = rlist.begin(); it != rlist.end(); it++) { std::string serializedValue = serialize( *it, "" ); if( serializedValue.empty() ) { success = false; break; } values.push_back( serializedValue ); } str = "[ " + join( values, ", " ) + " ]"; } // else if(data.type() == Variant::Hash) // variant is a hash? // { // const VariantHash vhash = data.toHash(); // QHashIterator<std::string, Variant> it( vhash ); // str = "{ "; // QList<QByteArray> pairs; // // while(it.hasNext()) // { // it.next(); // QByteArray serializedValue = serialize(it.value(), ""); // // if(serializedValue.isNull()) // { // success = false; // break; // } // // pairs << tab.toAscii() + sanitizeString(it.key()).toUtf8() + " : " + serializedValue; // } // // str += join(pairs, ", "); // str += " }"; // } else if(data.type() == Variant::Map) // variant is a map? { VariantMap vmap = data.toMap(); str = "{ \n"; StringArray pairs; for( VariantMap::iterator it = vmap.begin(); it != vmap.end(); it++ ) { std::string serializedValue = serialize( it->second, tab + " "); if( serializedValue.empty()) { //success = false; pairs.push_back( tab + sanitizeString( it->first ) + std::string( " : \"nonSerializableValue\"" ) ); continue; } pairs.push_back( tab + sanitizeString( it->first ) + " : " + serializedValue ); } str += join(pairs, ",\n"); std::string rtab( tab ); rtab.resize( std::max<int>( 0, tab.size() - 2 ) ); str += std::string( "\n" ) + rtab + "}"; } else if((data.type() == Variant::String) || (data.type() == Variant::NByteArray)) // a string or a byte array? { str = sanitizeString( data.toString() ); } else if(data.type() == Variant::Double || data.type() == Variant::Float) // double? { str = StringHelper::format( 0xff, "\"%f\"", data.toDouble() ); if( str.find(".") == std::string::npos && str.find("e") == std::string::npos ) { str += ".0"; } } else if( data.type() == Variant::NTilePos) { TilePos pos = data.toTilePos(); str = StringHelper::format( 0xff, "[ %d, %d ]", pos.getI(), pos.getJ() ); } else if( data.type() == Variant::NSize) { Size size = data.toSize(); str = StringHelper::format( 0xff, "[ %d, %d ]", size.getWidth(), size.getHeight() ); } else if( data.type() == Variant::NPoint) { Point pos = data.toPoint(); str = StringHelper::format( 0xff, "[ %d, %d ]", pos.getX(), pos.getY() ); } else if( data.type() == Variant::NPointF) { PointF pos = data.toPointF(); str = StringHelper::format( 0xff, "[ \"%f\", \"%f\" ]", pos.getX(), pos.getY() ); } else if (data.type() == Variant::Bool) // boolean value? { str = data.toBool() ? "true" : "false"; } else if (data.type() == Variant::ULongLong) // large unsigned number? { str = StringHelper::format( 0xff, "%u", data.toULongLong() ); } else if ( data.canConvert( Variant::LongLong ) ) // any signed number? { str = StringHelper::format( 0xff, "%d", data.toLongLong() ); } else if (data.canConvert( Variant::Long )) { str = StringHelper::format( 0xff, "%d", data.toLongLong() ); } else if (data.canConvert( Variant::String ) ) // can value be converted to string? { // this will catch Date, DateTime, Url, ... str = sanitizeString( data.toString() ); } else { success = false; } if (success) { return str; } else { return std::string(); } }
RoutingTable::Entry LinuxRoutingTable::set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric) { char metstr[128]; if ((!gateway)&&((!device)||(!device[0]))) return RoutingTable::Entry(); Utils::snprintf(metstr,sizeof(metstr),"%d",metric); if (metric < 0) { long pid = (long)vfork(); if (pid == 0) { if (gateway) { if ((device)&&(device[0])) { ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","del",destination.toString().c_str(),"via",gateway.toIpString().c_str(),"dev",device,(const char *)0); } else { ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","del",destination.toString().c_str(),"via",gateway.toIpString().c_str(),(const char *)0); } } else { ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","del",destination.toString().c_str(),"dev",device,(const char *)0); } ::_exit(-1); } else if (pid > 0) { int exitcode = -1; ::waitpid(pid,&exitcode,0); } } else { long pid = (long)vfork(); if (pid == 0) { if (gateway) { if ((device)&&(device[0])) { ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","replace",destination.toString().c_str(),"metric",metstr,"via",gateway.toIpString().c_str(),"dev",device,(const char *)0); } else { ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","replace",destination.toString().c_str(),"metric",metstr,"via",gateway.toIpString().c_str(),(const char *)0); } } else { ::execl(ZT_LINUX_IP_COMMAND,ZT_LINUX_IP_COMMAND,"route","replace",destination.toString().c_str(),"metric",metstr,"dev",device,(const char *)0); } ::_exit(-1); } else if (pid > 0) { int exitcode = -1; ::waitpid(pid,&exitcode,0); } } std::vector<RoutingTable::Entry> rtab(get(true,true)); std::vector<RoutingTable::Entry>::iterator bestEntry(rtab.end()); for(std::vector<RoutingTable::Entry>::iterator e(rtab.begin());e!=rtab.end();++e) { if ((e->destination == destination)&&(e->gateway.ipsEqual(gateway))) { if ((device)&&(device[0])) { if (!strcmp(device,e->device)) { if (metric == e->metric) bestEntry = e; } } if (bestEntry == rtab.end()) bestEntry = e; } } if (bestEntry != rtab.end()) return *bestEntry; return RoutingTable::Entry(); }