--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/servlib/prophet/Encounter.h Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2007 Baylor University
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _PROPHET_ENCOUNTER_H_
+#define _PROPHET_ENCOUNTER_H_
+
+#include "Link.h"
+#include "BaseTLV.h"
+#include "HelloTLV.h"
+#include "ProphetTLV.h"
+#include "Oracle.h"
+#include "Table.h"
+#include "Dictionary.h"
+#include "BundleTLVEntryList.h"
+#include "Alarm.h"
+
+namespace prophet
+{
+
+/**
+ * Section 4.4.4, p. 28
+ * The Routing Information Base lists the destinations a node knows of,
+ * and the delivery predictabilities it has associated with them. This
+ * information is needed by the PRoPHET algorithm to make decisions on
+ * routing and forwarding.
+ *
+ * Section 4.4.3, p. 27
+ * The Routing Information Base Dictionary includes the list of addresses
+ * used in making routing decisions. The referents remain constant for
+ * the duration of a session over a link where the instance numbers remain
+ * the same and can be used by both the Routing Information Base messages
+ * and the bundle offer messages.
+ *
+ * Track the state for the Prophet protocol throughout the duration of
+ * this encounter between the local node and this remote.
+ */
+class Encounter : public ExpirationHandler
+{
+public:
+ typedef enum {
+ UNDEFINED_STATE = 0,
+ WAIT_NB, ///< Waiting for Neighbor
+ SYNSENT, ///< Sent SYN, waiting for SYNACK
+ SYNRCVD, ///< Received SYN, sent SYNACK, waiting for ACK
+ ESTAB, ///< Prophet link established with remote
+ WAIT_DICT, ///< Listener mode of bundle-passing phase
+ WAIT_RIB, ///< Listener rcvd RIBD, waiting for RIB
+ OFFER, ///< Listener sent Offer, waiting for Request
+ CREATE_DR, ///< Initiator creates and sends RIBD and RIB
+ SEND_DR, ///< Initiator sent RIBD and RIB, waiting for Offer
+ REQUEST, ///< Initiator sent Request, waiting for Bundles
+ WAIT_INFO ///< All phases now complete, waiting for timer or ACK
+ } state_t;
+
+ static const char* state_to_str(state_t st) {
+ switch(st) {
+#define CASE(_state) case _state: return # _state
+ CASE(WAIT_NB);
+ CASE(SYNSENT);
+ CASE(SYNRCVD);
+ CASE(ESTAB);
+ CASE(WAIT_DICT);
+ CASE(WAIT_RIB);
+ CASE(OFFER);
+ CASE(CREATE_DR);
+ CASE(SEND_DR);
+ CASE(REQUEST);
+ CASE(WAIT_INFO);
+#undef CASE
+ default: return "Unknown State";
+ }
+ }
+ /**
+ * Constructor
+ */
+ Encounter(const Link* nexthop, Oracle* oracle, u_int16_t instance);
+
+ /**
+ * Copy constructor
+ */
+ Encounter(const Encounter& e);
+
+ /**
+ * Destructor
+ */
+ ~Encounter();
+
+ ///@{ Operators
+ bool operator< (const Encounter& e) const
+ {
+ return remote_instance_ < e.remote_instance_;
+ }
+ ///@}
+
+ ///@{ Accessors
+ u_int16_t remote_instance() const { return remote_instance_; }
+ u_int16_t local_instance() const { return local_instance_; }
+ const char* remote_eid() const { return next_hop_->remote_eid(); }
+ const Link* nexthop() const { return next_hop_; }
+ state_t state() const { return state_; }
+ const char* state_str() const { return state_to_str(state_); }
+ bool neighbor_gone() const { return neighbor_gone_; }
+ u_int time_remaining() const { return alarm_->time_remaining(); }
+ ///@}
+
+ /**
+ * Callback to inform this instance that the hello_interval
+ * parameter has changed
+ */
+ void hello_interval_changed();
+
+ /**
+ * Callback for this instance to receive TLVs received from peer
+ * by the host bundling system. Encounter assumes ownership of
+ * memory pointed to by tlv. Return true if message processed
+ * successfully. Return false upon fault (peering session died).
+ */
+ bool receive_tlv(ProphetTLV* tlv);
+
+ /**
+ * Callback for timeout handler, either due to peer failure or
+ * unacceptable delay in messaging
+ */
+ void handle_timeout();
+
+ /**
+ * Callback for tracking which Bundle requests are outstanding
+ */
+ void handle_bundle_received(const Bundle* b);
+
+protected:
+
+ ///@{ TLV event handlers
+ bool dispatch_tlv(BaseTLV* tlv);
+ bool handle_hello_tlv(BaseTLV* hello);
+ bool handle_ribd_tlv(BaseTLV* ribd);
+ bool handle_rib_tlv(BaseTLV* rib);
+ bool handle_offer_tlv(BaseTLV* offer);
+ bool handle_response_tlv(BaseTLV* response);
+ ///@}
+
+ ///@{ Outbound message generators
+ bool send_hello(HelloTLV::hello_hf_t hf,
+ ProphetTLV::header_result_t hr = ProphetTLV::NoSuccessAck,
+ u_int32_t tid = 0);
+ bool send_dictionary_rib(ProphetTLV::header_result_t hr =
+ ProphetTLV::NoSuccessAck,
+ u_int32_t tid = 0);
+ bool send_offer(ProphetTLV::header_result_t hr = ProphetTLV::NoSuccessAck,
+ u_int32_t tid = 0);
+ bool send_response(ProphetTLV::header_result_t hr =
+ ProphetTLV::NoSuccessAck,
+ u_int32_t tid = 0);
+ bool send_tlv(ProphetTLV* tlv);
+ ///@}
+
+ Oracle* const oracle_; ///< collection of Prophet information
+ u_int16_t local_instance_; ///< local's instance for remote
+ u_int16_t remote_instance_; ///< remote's instance for local
+ u_int32_t tid_; ///< transaction id from peer's most recent TLV
+ u_int32_t next_tid_; ///< used to generate TID for outbound TLVs
+ u_int32_t timeout_; ///< most milliseconds expected between TLVs
+ const Link* next_hop_; ///< Link object for this encounter
+ ProphetTLV* tlv_; ///< most recent message received from peer
+ const bool synsender_; ///< whether active or passive during Hello phase
+ state_t state_; ///< which phase of Prophet protocol for this end
+ bool synsent_; ///< whether hello phase has sent SYN or SYNACK
+ bool estab_; ///< whether hello phase has been completed
+ volatile bool neighbor_gone_; ///< whether session has died
+ Dictionary local_ribd_; ///< 16 bit index lookup to translate routes
+ Dictionary remote_ribd_; ///< 16 bit index lookup for remote's routes
+ BundleOfferList remote_offers_; ///< in-memory rep of remote's offer
+ BundleResponseList local_response_; ///< Bundle requests sent to peer
+ Table remote_nodes_; ///< in-memory representation of remote's RIB
+ u_int hello_rate_; ///< simple flow control for Hello messages (ACK, etc)
+ u_int32_t data_sent_; ///< timestamp of last TLV sent
+ u_int32_t data_rcvd_; ///< timestamp of last TLV received
+ Alarm* alarm_; ///< callback registration for timeout handler
+}; // class Encounter
+
+}; // namespace prophet
+
+#endif // _PROPHET_ENCOUNTER_H_