Example #1
0
		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;
				};