void SQLiteBundleSet::add(const dtn::data::MetaBundle &bundle) throw () { try { // insert bundle id into database SQLiteDatabase::Statement st(_sqldb._database, SQLiteDatabase::_sql_queries[SQLiteDatabase::BUNDLE_SET_ADD]); sqlite3_bind_int64(*st, 1, _set_id); sqlite3_bind_text(*st, 2, bundle.source.getString().c_str(), static_cast<int>(bundle.source.getString().length()), SQLITE_TRANSIENT); sqlite3_bind_int64(*st, 3, bundle.timestamp.get<uint64_t>()); sqlite3_bind_int64(*st, 4, bundle.sequencenumber.get<uint64_t>()); if (bundle.isFragment()) { sqlite3_bind_int64(*st, 5, bundle.fragmentoffset.get<uint64_t>()); sqlite3_bind_int64(*st, 6, bundle.getPayloadLength()); } else { sqlite3_bind_int64(*st, 5, -1); sqlite3_bind_int64(*st, 6, -1); } sqlite3_bind_int64(*st, 7, bundle.expiretime.get<uint64_t>()); st.step(); // update expiretime, if necessary new_expire_time(bundle.expiretime); // add bundle to the bloomfilter bundle.addTo(_bf); } catch (const SQLiteDatabase::SQLiteQueryException&) { // error } }
virtual bool addIfSelected(dtn::storage::BundleResult &result, const dtn::data::MetaBundle &meta) const throw (dtn::storage::BundleSelectorException) { // check Scope Control Block - do not forward bundles with hop limit == 0 if (meta.hopcount == 0) { return false; } // do not forward local bundles if ((meta.destination.getNode() == dtn::core::BundleCore::local) && meta.get(dtn::data::PrimaryBlock::DESTINATION_IS_SINGLETON) ) { return false; } // check Scope Control Block - do not forward non-group bundles with hop limit <= 1 if ((meta.hopcount <= 1) && (meta.get(dtn::data::PrimaryBlock::DESTINATION_IS_SINGLETON))) { return false; } // do not forward bundles addressed to this neighbor, // because this is handled by neighbor routing extension if (_entry.eid == meta.destination.getNode()) { return false; } // request limits from neighbor database try { const RoutingLimitations &limits = _entry.getDataset<RoutingLimitations>(); if (meta.get(dtn::data::PrimaryBlock::DESTINATION_IS_SINGLETON)) { // check if the peer accepts bundles for other nodes if (limits.getLimit(RoutingLimitations::LIMIT_LOCAL_ONLY) > 0) return false; } else { // check if destination permits non-singleton bundles if (limits.getLimit(RoutingLimitations::LIMIT_SINGLETON_ONLY) > 0) return false; } // check if the payload is too large for the neighbor if ((limits.getLimit(RoutingLimitations::LIMIT_FOREIGN_BLOCKSIZE) > 0) && ((size_t)limits.getLimit(RoutingLimitations::LIMIT_FOREIGN_BLOCKSIZE) < meta.getPayloadLength())) return false; } catch (const NeighborDatabase::DatasetNotAvailableException&) { } // if this is a singleton bundle ... if (meta.get(dtn::data::PrimaryBlock::DESTINATION_IS_SINGLETON)) { const dtn::core::Node n(meta.destination.getNode()); // do not forward the bundle if the final destination is available if (_neighbors.find(n) != _neighbors.end()) { return false; } } // do not forward bundles already known by the destination // throws BloomfilterNotAvailableException if no filter is available or it is expired try { if (_entry.has(meta, true)) { return false; } } catch (const dtn::routing::NeighborDatabase::BloomfilterNotAvailableException&) { throw dtn::storage::BundleSelectorException(); } // update filter context dtn::core::FilterContext context = _context; context.setMetaBundle(meta); // check bundle filter for each possible path for (dtn::net::ConnectionManager::protocol_list::const_iterator it = _plist.begin(); it != _plist.end(); ++it) { const dtn::core::Node::Protocol &p = (*it); // update context with current protocol context.setProtocol(p); // execute filtering dtn::core::BundleFilter::ACTION ret = dtn::core::BundleCore::getInstance().evaluate(dtn::core::BundleFilter::ROUTING, context); if (ret == dtn::core::BundleFilter::ACCEPT) { // put the selected bundle with targeted interface into the result-set static_cast<RoutingResult&>(result).put(meta, p); return true; } } return false; };