Exemple #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
			}
		}
		void NativeSession::receive() throw (NativeSessionException)
		{
			Registration &reg = _registration;
			try {
				try {
					const dtn::data::MetaBundle id = reg.receiveMetaBundle();

					if (id.procflags & dtn::data::PrimaryBlock::APPDATA_IS_ADMRECORD) {
						// transform custody signals & status reports into notifies
						fireNotificationAdministrativeRecord(id);

						// announce the delivery of this bundle
						reg.delivered(id);
					} else {
						IBRCOMMON_LOGGER_DEBUG_TAG(NativeSession::TAG, 20) << "fire notification for new bundle " << id.toString() << IBRCOMMON_LOGGER_ENDL;

						// put the bundle into the API queue
						_bundle_queue.push(id);

						// notify the client about the new bundle
						fireNotificationBundle(id);
					}
				} catch (const dtn::storage::NoBundleFoundException&) {
					IBRCOMMON_LOGGER_DEBUG_TAG(NativeSession::TAG, 25) << "no more bundles found - wait until we are notified" << IBRCOMMON_LOGGER_ENDL;
					reg.wait_for_bundle();
				}
			} catch (const ibrcommon::QueueUnblockedException &ex) {
				throw NativeSessionException(std::string("loop aborted - ") + ex.what());
			} catch (const std::exception &ex) {
				throw NativeSessionException(std::string("loop aborted - ") + ex.what());
			}
		}
				virtual bool shouldAdd(const dtn::data::MetaBundle &meta) const throw (dtn::storage::BundleSelectorException)
				{
					// filter fragments if requested
					if (meta.isFragment() && _fragment_filter)
					{
						return false;
					}

					if (_endpoints.find(meta.destination) == _endpoints.end())
					{
						return false;
					}

					// filter own bundles
					if (!_loopback)
					{
						if (_endpoints.find(meta.source) != _endpoints.end())
						{
							return false;
						}
					}

					IBRCOMMON_LOGGER_DEBUG_TAG(Registration::TAG, 30) << "search bundle in the list of delivered bundles: " << meta.toString() << IBRCOMMON_LOGGER_ENDL;

					if (_queue.has(meta))
					{
						return false;
					}

					return true;
				};
		void Registration::delivered(const dtn::data::MetaBundle &m) const
		{
			// raise bundle event
			dtn::core::BundleEvent::raise(m, dtn::core::BUNDLE_DELIVERED);

			if (m.get(dtn::data::PrimaryBlock::DESTINATION_IS_SINGLETON))
			{
				dtn::core::BundlePurgeEvent::raise(m);
			}
		}
		void MemoryBundleSet::add(const dtn::data::MetaBundle &bundle) throw ()
		{
			// insert bundle id to the private list
			pair<bundle_set::iterator,bool> ret = _bundles.insert(bundle);

			BundleSetImpl::ExpiringBundle exb(*ret.first);
			_expire.insert(exb);

			// add bundle to the bloomfilter
			bundle.addTo(_bf);
		}
		void EpidemicRoutingExtension::eventBundleQueued(const dtn::data::EID &peer, const dtn::data::MetaBundle &meta) throw ()
		{
			// ignore the bundle if the scope is limited to local delivery
			if ((meta.hopcount <= 1) && (meta.get(dtn::data::PrimaryBlock::DESTINATION_IS_SINGLETON))) return;

			// new bundles trigger a recheck for all neighbors
			const std::set<dtn::core::Node> nl = dtn::core::BundleCore::getInstance().getConnectionManager().getNeighbors();

			for (std::set<dtn::core::Node>::const_iterator iter = nl.begin(); iter != nl.end(); ++iter)
			{
				const dtn::core::Node &n = (*iter);

				if (n.getEID() != peer)
				{
					// trigger all routing modules to search for bundles to forward
					eventDataChanged(n.getEID());
				}
			}
		}
		/**
		 * Transfer one bundle to another node.
		 * @param destination The EID of the other node.
		 * @param id The ID of the bundle to transfer. This bundle must be stored in the storage.
		 */
		void RoutingExtension::transferTo(const dtn::data::EID &destination, const dtn::data::MetaBundle &meta)
		{
			// acquire the transfer of this bundle, could throw already in transit or no resource left exception
			{
				// lock the list of neighbors
				ibrcommon::MutexLock l((**this).getNeighborDB());

				// get the neighbor entry for the next hop
				NeighborDatabase::NeighborEntry &entry = (**this).getNeighborDB().get(destination, true);

				// acquire the transfer, could throw already in transit or no resource left exception
				entry.acquireTransfer(meta);
			}

			try {
				// create a new bundle transfer object
				dtn::net::BundleTransfer transfer(destination, meta);

				// transfer the bundle to the next hop
				dtn::core::BundleCore::getInstance().getConnectionManager().queue(transfer);

				IBRCOMMON_LOGGER_DEBUG_TAG(RoutingExtension::TAG, 20) << "bundle " << meta.toString() << " queued for " << destination.getString() << IBRCOMMON_LOGGER_ENDL;
			} catch (const dtn::core::P2PDialupException&) {
				// lock the list of neighbors
				ibrcommon::MutexLock l((**this).getNeighborDB());

				// get the neighbor entry for the next hop
				NeighborDatabase::NeighborEntry &entry = (**this).getNeighborDB().get(destination);

				// release the transfer
				entry.releaseTransfer(meta);

				// and abort the query
				throw NeighborDatabase::NeighborNotAvailableException();
			} catch (const ibrcommon::Exception &e) {
				// ignore any other error
			}
		}
		void StatusReportGenerator::createStatusReport(const dtn::data::MetaBundle &b, StatusReportBlock::TYPE type, StatusReportBlock::REASON_CODE reason)
		{
			// create a new bundle
			Bundle bundle;

			// create a new statusreport block
			StatusReportBlock &report = bundle.push_back<StatusReportBlock>();

			bundle.set(dtn::data::PrimaryBlock::APPDATA_IS_ADMRECORD, true);

			// get the flags and set the status flag
			report._status |= type;

			// set the reason code
			report._reasoncode |= reason;

			switch (type)
			{
				case StatusReportBlock::RECEIPT_OF_BUNDLE:
					report._timeof_receipt.set();
				break;

				case StatusReportBlock::CUSTODY_ACCEPTANCE_OF_BUNDLE:
					report._timeof_custodyaccept.set();
				break;

				case StatusReportBlock::FORWARDING_OF_BUNDLE:
					report._timeof_forwarding.set();
				break;

				case StatusReportBlock::DELIVERY_OF_BUNDLE:
					report._timeof_delivery.set();
				break;

				case StatusReportBlock::DELETION_OF_BUNDLE:
					report._timeof_deletion.set();
				break;

				default:

				break;
			}

			// set source and destination
			bundle._source = dtn::core::BundleCore::local;
			bundle.set(dtn::data::PrimaryBlock::DESTINATION_IS_SINGLETON, true);
			bundle._destination = b.reportto;

			// set bundle parameter
			if (b.get(Bundle::FRAGMENT))
			{
				report._fragment_offset = b.offset;
				report._fragment_length = b.appdatalength;
				report._admfield |= 1;
			}

			report._bundle_timestamp = b.timestamp;
			report._bundle_sequence = b.sequencenumber;
			report._source = b.source;

			dtn::core::BundleGeneratedEvent::raise(bundle);
		}
		void Registration::RegistrationQueue::put(const dtn::data::MetaBundle &bundle) throw ()
		{
			try {
				_queue.push(bundle);

				ibrcommon::MutexLock l(_lock);
				_recv_bundles.add(bundle);

				IBRCOMMON_LOGGER_DEBUG_TAG(Registration::TAG, 10) << "[RegistrationQueue] add bundle to list of delivered bundles: " << bundle.toString() << IBRCOMMON_LOGGER_ENDL;
			} catch (const ibrcommon::Exception&) { }
		}
				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;
				};
				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;
					}

					// 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
					if (_entry.has(meta))
					{
						return false;
					}

					// 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;
				};
		virtual bool shouldAdd(const dtn::data::MetaBundle &meta) const throw (dtn::storage::BundleSelectorException)
		{
			// select the bundle if it is in the filter
			return meta.isIn(_filter);
		};