Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > 29c369053a983cc5d8c880dc6e0a2237 > files > 276

libdtn-devel-2.6.0-2mdv2009.1.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>DTN Reference Implementation: Encounter.cc Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css">
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.5.8 -->
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="namespaces.html"><span>Namespaces</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
  <div class="tabs">
    <ul>
      <li><a href="files.html"><span>File&nbsp;List</span></a></li>
      <li><a href="globals.html"><span>File&nbsp;Members</span></a></li>
    </ul>
  </div>
<h1>Encounter.cc</h1><a href="Encounter_8cc.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
<a name="l00002"></a>00002 <span class="comment"> *    Copyright 2007 Baylor University</span>
<a name="l00003"></a>00003 <span class="comment"> * </span>
<a name="l00004"></a>00004 <span class="comment"> *    Licensed under the Apache License, Version 2.0 (the "License");</span>
<a name="l00005"></a>00005 <span class="comment"> *    you may not use this file except in compliance with the License.</span>
<a name="l00006"></a>00006 <span class="comment"> *    You may obtain a copy of the License at</span>
<a name="l00007"></a>00007 <span class="comment"> * </span>
<a name="l00008"></a>00008 <span class="comment"> *        http://www.apache.org/licenses/LICENSE-2.0</span>
<a name="l00009"></a>00009 <span class="comment"> * </span>
<a name="l00010"></a>00010 <span class="comment"> *    Unless required by applicable law or agreed to in writing, software</span>
<a name="l00011"></a>00011 <span class="comment"> *    distributed under the License is distributed on an "AS IS" BASIS,</span>
<a name="l00012"></a>00012 <span class="comment"> *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
<a name="l00013"></a>00013 <span class="comment"> *    See the License for the specific language governing permissions and</span>
<a name="l00014"></a>00014 <span class="comment"> *    limitations under the License.</span>
<a name="l00015"></a>00015 <span class="comment"> */</span>
<a name="l00016"></a>00016 
<a name="l00017"></a>00017 <span class="preprocessor">#include "<a class="code" href="BundleCore_8h.html">BundleCore.h</a>"</span>
<a name="l00018"></a>00018 <span class="preprocessor">#include "<a class="code" href="HelloTLV_8h.html">HelloTLV.h</a>"</span>
<a name="l00019"></a>00019 <span class="preprocessor">#include "<a class="code" href="RIBDTLV_8h.html">RIBDTLV.h</a>"</span>
<a name="l00020"></a>00020 <span class="preprocessor">#include "<a class="code" href="RIBTLV_8h.html">RIBTLV.h</a>"</span>
<a name="l00021"></a>00021 <span class="preprocessor">#include "<a class="code" href="OfferTLV_8h.html">OfferTLV.h</a>"</span>
<a name="l00022"></a>00022 <span class="preprocessor">#include "<a class="code" href="ResponseTLV_8h.html">ResponseTLV.h</a>"</span>
<a name="l00023"></a>00023 <span class="preprocessor">#include "<a class="code" href="TLVCreator_8h.html">TLVCreator.h</a>"</span>
<a name="l00024"></a>00024 <span class="preprocessor">#include "<a class="code" href="Encounter_8h.html">Encounter.h</a>"</span>
<a name="l00025"></a>00025 
<a name="l00026"></a>00026 <span class="preprocessor">#define NEXT_TID (++next_tid_ == 0) ? ++next_tid_ : next_tid_</span>
<a name="l00027"></a>00027 <span class="preprocessor"></span>
<a name="l00028"></a>00028 <span class="preprocessor">#define PROPHET_TLV(_tlv, _result, _tid) do { \</span>
<a name="l00029"></a>00029 <span class="preprocessor">    _tlv = new ProphetTLV(                    \</span>
<a name="l00030"></a>00030 <span class="preprocessor">            oracle_-&gt;core()-&gt;prophet_id(),    \</span>
<a name="l00031"></a>00031 <span class="preprocessor">            oracle_-&gt;core()-&gt;prophet_id(next_hop_), \</span>
<a name="l00032"></a>00032 <span class="preprocessor">            _result,                          \</span>
<a name="l00033"></a>00033 <span class="preprocessor">            local_instance_,                  \</span>
<a name="l00034"></a>00034 <span class="preprocessor">            remote_instance_,                 \</span>
<a name="l00035"></a>00035 <span class="preprocessor">            (_tid == 0) ? NEXT_TID : _tid); \</span>
<a name="l00036"></a>00036 <span class="preprocessor">    } while (0)</span>
<a name="l00037"></a>00037 <span class="preprocessor"></span>
<a name="l00038"></a>00038 <span class="preprocessor">#define SEND_ACK(_tid) send_hello(HelloTLV::ACK, \</span>
<a name="l00039"></a>00039 <span class="preprocessor">                                  ProphetTLV::NoSuccessAck,_tid)</span>
<a name="l00040"></a>00040 <span class="preprocessor"></span><span class="preprocessor">#define SEND_SYN(_tid) send_hello(HelloTLV::SYN, \</span>
<a name="l00041"></a>00041 <span class="preprocessor">                                  ProphetTLV::NoSuccessAck,_tid)</span>
<a name="l00042"></a>00042 <span class="preprocessor"></span><span class="preprocessor">#define SEND_SYNACK(_tid) send_hello(HelloTLV::SYNACK, \</span>
<a name="l00043"></a>00043 <span class="preprocessor">                                     ProphetTLV::NoSuccessAck,_tid)</span>
<a name="l00044"></a>00044 <span class="preprocessor"></span><span class="preprocessor">#define SEND_RSTACK(_tid) send_hello(HelloTLV::RSTACK,\</span>
<a name="l00045"></a>00045 <span class="preprocessor">                                     ProphetTLV::Failure,_tid)</span>
<a name="l00046"></a>00046 <span class="preprocessor"></span>
<a name="l00047"></a>00047 <span class="preprocessor">#define LOG(_level, _args...) oracle_-&gt;core()-&gt;print_log( \</span>
<a name="l00048"></a>00048 <span class="preprocessor">        name_.c_str(), BundleCore::_level,  _args )</span>
<a name="l00049"></a>00049 <span class="preprocessor"></span>
<a name="l00050"></a>00050 <span class="preprocessor">#define SET_STATE(_new) do { LOG(LOG_DEBUG, "state_ %s -&gt; %s %s:%d", \</span>
<a name="l00051"></a>00051 <span class="preprocessor">        state_to_str(state_), state_to_str(_new), __FILE__, __LINE__); \</span>
<a name="l00052"></a>00052 <span class="preprocessor">        state_ = _new; \</span>
<a name="l00053"></a>00053 <span class="preprocessor">    } while (0)</span>
<a name="l00054"></a>00054 <span class="preprocessor"></span>
<a name="l00055"></a>00055 <span class="preprocessor">#define UPDATE_PEER_VERIFIER(_sender_instance) do {     \</span>
<a name="l00056"></a>00056 <span class="preprocessor">        remote_instance_ = _sender_instance;            \</span>
<a name="l00057"></a>00057 <span class="preprocessor">        LOG(LOG_DEBUG, "update peer verifier %d",       \</span>
<a name="l00058"></a>00058 <span class="preprocessor">                       (_sender_instance)); } while (0) \</span>
<a name="l00059"></a>00059 <span class="preprocessor"></span>
<a name="l00060"></a>00060 <span class="preprocessor"></span><span class="preprocessor">#define ASSIGN_ROLES(_s,_r) do { \</span>
<a name="l00061"></a>00061 <span class="preprocessor">        if (synsender_) { \</span>
<a name="l00062"></a>00062 <span class="preprocessor">            _s = oracle_-&gt;core()-&gt;local_eid(); \</span>
<a name="l00063"></a>00063 <span class="preprocessor">            _r = next_hop_-&gt;remote_eid(); } \</span>
<a name="l00064"></a>00064 <span class="preprocessor">        else { \</span>
<a name="l00065"></a>00065 <span class="preprocessor">            _s = next_hop_-&gt;remote_eid(); \</span>
<a name="l00066"></a>00066 <span class="preprocessor">            _r = oracle_-&gt;core()-&gt;local_eid(); }\</span>
<a name="l00067"></a>00067 <span class="preprocessor">    } while (0) </span>
<a name="l00068"></a>00068 <span class="preprocessor"></span>
<a name="l00069"></a>00069 
<a name="l00070"></a>00070 <span class="keyword">namespace </span>prophet
<a name="l00071"></a>00071 {
<a name="l00072"></a>00072 
<a name="l00073"></a>00073 <a class="code" href="classprophet_1_1Encounter.html#9afbbeba17132b7bc958afa01d8de7a9" title="Constructor.">Encounter::Encounter</a>(<span class="keyword">const</span> Link* nexthop,
<a name="l00074"></a>00074                      Oracle* oracle,
<a name="l00075"></a>00075                      u_int16_t instance)
<a name="l00076"></a>00076     : ExpirationHandler(),
<a name="l00077"></a>00077       oracle_(oracle),
<a name="l00078"></a>00078       local_instance_(instance),
<a name="l00079"></a>00079       remote_instance_(0),
<a name="l00080"></a>00080       tid_(0),
<a name="l00081"></a>00081       next_tid_(0),
<a name="l00082"></a>00082       timeout_(oracle_-&gt;params()-&gt;hello_interval() * 100),
<a name="l00083"></a>00083       next_hop_(nexthop),
<a name="l00084"></a>00084       tlv_(NULL),
<a name="l00085"></a>00085       synsender_(oracle_-&gt;core()-&gt;local_eid().compare(
<a name="l00086"></a>00086                   next_hop_-&gt;remote_eid()) &lt; 0),
<a name="l00087"></a>00087       state_(WAIT_NB),
<a name="l00088"></a>00088       synsent_(false),
<a name="l00089"></a>00089       estab_(false),
<a name="l00090"></a>00090       neighbor_gone_(false),
<a name="l00091"></a>00091       remote_nodes_(oracle_-&gt;core(),<span class="stringliteral">"remote"</span>,false),
<a name="l00092"></a>00092       hello_rate_(0),
<a name="l00093"></a>00093       data_sent_(time(0)),
<a name="l00094"></a>00094       data_rcvd_(time(0)),
<a name="l00095"></a>00095       alarm_(NULL)
<a name="l00096"></a>00096 {
<a name="l00097"></a>00097     std::string name(<span class="stringliteral">"encounter-"</span>);
<a name="l00098"></a>00098     <span class="keywordtype">char</span> buff[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
<a name="l00099"></a>00099     <span class="keywordtype">size_t</span> <a class="code" href="num2sdnv_8c.html#fed088663f8704004425cdae2120b9b3">len</a> = snprintf(buff,10,<span class="stringliteral">"%d"</span>,instance);
<a name="l00100"></a>00100     name.append(buff,len);
<a name="l00101"></a>00101     ExpirationHandler::set_name(name.c_str());
<a name="l00102"></a>00102 
<a name="l00103"></a>00103     <span class="keywordflow">if</span> (synsender_)
<a name="l00104"></a>00104         <span class="keywordflow">if</span> (send_hello(HelloTLV::SYN))
<a name="l00105"></a>00105             SET_STATE(SYNSENT);
<a name="l00106"></a>00106 
<a name="l00107"></a>00107     <span class="comment">// set up reminder for timeout_ milliseconds</span>
<a name="l00108"></a>00108     alarm_ = oracle_-&gt;core()-&gt;create_alarm(<span class="keyword">this</span>,timeout_);
<a name="l00109"></a>00109     <span class="keywordflow">if</span> (alarm_ == NULL) neighbor_gone_ = <span class="keyword">true</span>;
<a name="l00110"></a>00110 
<a name="l00111"></a>00111     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"constructor(%s,%u)"</span>,nexthop-&gt;remote_eid(),instance);
<a name="l00112"></a>00112 
<a name="l00113"></a>00113 }
<a name="l00114"></a>00114 
<a name="l00115"></a>00115 Encounter::Encounter(<span class="keyword">const</span> Encounter&amp; e)
<a name="l00116"></a>00116     : ExpirationHandler(e),
<a name="l00117"></a>00117       oracle_(e.oracle_),
<a name="l00118"></a>00118       local_instance_(e.local_instance_),
<a name="l00119"></a>00119       remote_instance_(e.remote_instance_),
<a name="l00120"></a>00120       tid_(e.tid_),
<a name="l00121"></a>00121       timeout_(e.timeout_),
<a name="l00122"></a>00122       next_hop_(e.next_hop_),
<a name="l00123"></a>00123       tlv_(e.tlv_),
<a name="l00124"></a>00124       synsender_(e.synsender_),
<a name="l00125"></a>00125       state_(e.state_),
<a name="l00126"></a>00126       synsent_(e.synsent_),
<a name="l00127"></a>00127       estab_(e.estab_),
<a name="l00128"></a>00128       neighbor_gone_(e.neighbor_gone_),
<a name="l00129"></a>00129       local_ribd_(e.local_ribd_),
<a name="l00130"></a>00130       remote_ribd_(e.remote_ribd_),
<a name="l00131"></a>00131       remote_offers_(e.remote_offers_),
<a name="l00132"></a>00132       local_response_(e.local_response_),
<a name="l00133"></a>00133       remote_nodes_(e.remote_nodes_),
<a name="l00134"></a>00134       hello_rate_(e.hello_rate_),
<a name="l00135"></a>00135       data_sent_(e.data_sent_),
<a name="l00136"></a>00136       data_rcvd_(e.data_rcvd_),
<a name="l00137"></a>00137       alarm_(NULL)
<a name="l00138"></a>00138 {
<a name="l00139"></a>00139     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"copy constructor(%u)"</span>,local_instance_);
<a name="l00140"></a>00140     alarm_ = oracle_-&gt;core()-&gt;create_alarm(<span class="keyword">this</span>,e.alarm_-&gt;time_remaining());
<a name="l00141"></a>00141     <span class="keywordflow">if</span> (alarm_ == NULL) neighbor_gone_ = <span class="keyword">true</span>;
<a name="l00142"></a>00142 }
<a name="l00143"></a>00143 
<a name="l00144"></a>00144 Encounter::~Encounter()
<a name="l00145"></a>00145 {
<a name="l00146"></a>00146     <span class="keywordflow">if</span> (alarm_ != NULL &amp;&amp; alarm_-&gt;pending())
<a name="l00147"></a>00147         alarm_-&gt;cancel();
<a name="l00148"></a>00148 }
<a name="l00149"></a>00149 
<a name="l00150"></a>00150 <span class="keywordtype">void</span>
<a name="l00151"></a>00151 Encounter::hello_interval_changed()
<a name="l00152"></a>00152 {
<a name="l00153"></a>00153     <span class="keywordflow">if</span> (neighbor_gone_) <span class="keywordflow">return</span>;
<a name="l00154"></a>00154 
<a name="l00155"></a>00155     <span class="comment">// nothing to do if it's the same value</span>
<a name="l00156"></a>00156     u_int timeout = oracle_-&gt;params()-&gt;hello_interval() * 100;
<a name="l00157"></a>00157     <span class="keywordflow">if</span> (timeout == timeout_) <span class="keywordflow">return</span>;
<a name="l00158"></a>00158 
<a name="l00159"></a>00159     <span class="comment">// nothing to do for alarm_ unless it is pending</span>
<a name="l00160"></a>00160     <span class="keywordflow">if</span> (alarm_-&gt;pending()) 
<a name="l00161"></a>00161     {
<a name="l00162"></a>00162         <span class="keywordflow">if</span> (alarm_-&gt;time_remaining() == 0)
<a name="l00163"></a>00163             <span class="comment">// no change, let timeout handler catch it</span>
<a name="l00164"></a>00164             <span class="keywordflow">goto</span> set_timeout;
<a name="l00165"></a>00165 
<a name="l00166"></a>00166         <span class="comment">// grab the difference from old to new</span>
<a name="l00167"></a>00167         u_int diff;
<a name="l00168"></a>00168         u_int new_alarm;
<a name="l00169"></a>00169         <span class="keywordflow">if</span> (timeout_ &gt; timeout) 
<a name="l00170"></a>00170         {
<a name="l00171"></a>00171             <span class="comment">// new timeout is shorter than old</span>
<a name="l00172"></a>00172             diff = timeout_ - timeout;
<a name="l00173"></a>00173             new_alarm = alarm_-&gt;time_remaining() &lt; diff ? 
<a name="l00174"></a>00174                         0 : alarm_-&gt;time_remaining() - diff;
<a name="l00175"></a>00175         }
<a name="l00176"></a>00176         <span class="keywordflow">else</span>
<a name="l00177"></a>00177         {
<a name="l00178"></a>00178             <span class="comment">// new timeout is longer than old</span>
<a name="l00179"></a>00179             diff = timeout - timeout_;
<a name="l00180"></a>00180             new_alarm = alarm_-&gt;time_remaining() + diff;
<a name="l00181"></a>00181         }
<a name="l00182"></a>00182 
<a name="l00183"></a>00183         <span class="comment">// take the old timeout value off the schedule</span>
<a name="l00184"></a>00184         alarm_-&gt;cancel();
<a name="l00185"></a>00185 
<a name="l00186"></a>00186         <span class="comment">// write new timeout value to alarm</span>
<a name="l00187"></a>00187         alarm_ = oracle_-&gt;core()-&gt;create_alarm(<span class="keyword">this</span>,new_alarm);
<a name="l00188"></a>00188 
<a name="l00189"></a>00189         <span class="comment">// give up on error</span>
<a name="l00190"></a>00190         <span class="keywordflow">if</span> (alarm_ == NULL) neighbor_gone_ = <span class="keyword">true</span>;
<a name="l00191"></a>00191     }
<a name="l00192"></a>00192 
<a name="l00193"></a>00193 set_timeout:
<a name="l00194"></a>00194     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"hello_interval changed (%u -&gt; %u)"</span>, timeout_,timeout);
<a name="l00195"></a>00195 
<a name="l00196"></a>00196     <span class="comment">// store the new timeout</span>
<a name="l00197"></a>00197     timeout_ = timeout;
<a name="l00198"></a>00198 }
<a name="l00199"></a>00199 
<a name="l00200"></a>00200 <span class="keywordtype">bool</span>
<a name="l00201"></a>00201 Encounter::receive_tlv(ProphetTLV* tlv)
<a name="l00202"></a>00202 {
<a name="l00203"></a>00203     <span class="keywordflow">if</span> (neighbor_gone_) <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00204"></a>00204 
<a name="l00205"></a>00205     <span class="keywordflow">if</span> (tlv == NULL)
<a name="l00206"></a>00206         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00207"></a>00207 
<a name="l00208"></a>00208     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"receive_tlv"</span>);
<a name="l00209"></a>00209 
<a name="l00210"></a>00210     <span class="comment">// update member pointer</span>
<a name="l00211"></a>00211     tlv_ = tlv;
<a name="l00212"></a>00212 
<a name="l00213"></a>00213     <span class="comment">// update timestamp</span>
<a name="l00214"></a>00214     data_rcvd_ = time(0);
<a name="l00215"></a>00215 
<a name="l00216"></a>00216     <span class="comment">// disarm</span>
<a name="l00217"></a>00217     <span class="keywordflow">if</span> (alarm_-&gt;pending())
<a name="l00218"></a>00218         alarm_-&gt;cancel();
<a name="l00219"></a>00219 
<a name="l00220"></a>00220     <span class="comment">// capture transaction id</span>
<a name="l00221"></a>00221     tid_ = tlv_-&gt;transaction_id();
<a name="l00222"></a>00222 
<a name="l00223"></a>00223     BaseTLV* bt = NULL; 
<a name="l00224"></a>00224     <span class="keywordtype">bool</span> ok = <span class="keyword">true</span>;
<a name="l00225"></a>00225     <span class="comment">// distribute the individual TLVs to the correct handler</span>
<a name="l00226"></a>00226     <span class="keywordflow">while</span> ( (bt = tlv_-&gt;get_tlv()) != NULL &amp;&amp; ok )
<a name="l00227"></a>00227     {
<a name="l00228"></a>00228         ok = dispatch_tlv(bt);
<a name="l00229"></a>00229         <span class="keyword">delete</span> bt;
<a name="l00230"></a>00230     }
<a name="l00231"></a>00231 
<a name="l00232"></a>00232     <span class="comment">// clean up memory</span>
<a name="l00233"></a>00233     <span class="keyword">delete</span> tlv_;
<a name="l00234"></a>00234     tlv_ = NULL;
<a name="l00235"></a>00235 
<a name="l00236"></a>00236     <span class="keywordflow">if</span> (ok)
<a name="l00237"></a>00237     {
<a name="l00238"></a>00238         <span class="comment">// clean up old alarm: host implementation cleans up cancelled</span>
<a name="l00239"></a>00239         <span class="comment">// alarms, else we clean up our own spent alarms</span>
<a name="l00240"></a>00240         <span class="keywordflow">if</span> (alarm_-&gt;pending())
<a name="l00241"></a>00241             alarm_-&gt;cancel();
<a name="l00242"></a>00242         <span class="keywordflow">else</span>
<a name="l00243"></a>00243             <span class="keyword">delete</span> alarm_;
<a name="l00244"></a>00244         <span class="comment">// reschedule the timeout handler</span>
<a name="l00245"></a>00245         alarm_ = oracle_-&gt;core()-&gt;create_alarm(<span class="keyword">this</span>,timeout_,<span class="keyword">true</span>);
<a name="l00246"></a>00246 
<a name="l00247"></a>00247         <span class="comment">// give up on error</span>
<a name="l00248"></a>00248         <span class="keywordflow">if</span> (alarm_ == NULL) neighbor_gone_ = <span class="keyword">true</span>;
<a name="l00249"></a>00249     } 
<a name="l00250"></a>00250     <span class="keywordflow">else</span>
<a name="l00251"></a>00251         <span class="comment">// fail out on error</span>
<a name="l00252"></a>00252         neighbor_gone_ = <span class="keyword">true</span>;
<a name="l00253"></a>00253 
<a name="l00254"></a>00254     <span class="keywordflow">return</span> ok;
<a name="l00255"></a>00255 }
<a name="l00256"></a>00256 
<a name="l00257"></a>00257 <span class="keywordtype">bool</span>
<a name="l00258"></a>00258 Encounter::dispatch_tlv(BaseTLV* tlv)
<a name="l00259"></a>00259 {
<a name="l00260"></a>00260     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"dispatch_tlv"</span>);
<a name="l00261"></a>00261 
<a name="l00262"></a>00262     <span class="keywordtype">bool</span> ok = <span class="keyword">false</span>;
<a name="l00263"></a>00263     <span class="keywordtype">bool</span> pre_dispatch = estab_;
<a name="l00264"></a>00264 
<a name="l00265"></a>00265     <span class="keywordflow">switch</span> (tlv-&gt;typecode())
<a name="l00266"></a>00266     {
<a name="l00267"></a>00267         <span class="keywordflow">case</span> BaseTLV::HELLO_TLV:
<a name="l00268"></a>00268             ok = handle_hello_tlv(tlv);
<a name="l00269"></a>00269             <span class="keywordflow">if</span> (ok &amp;&amp; !pre_dispatch &amp;&amp; estab_)
<a name="l00270"></a>00270             {
<a name="l00271"></a>00271                 <span class="comment">// Hello procedure just completed ... move from ESTAB to </span>
<a name="l00272"></a>00272                 <span class="comment">// either CREATE_DR (synsender_) or WAIT_DICT (!synsender_)</span>
<a name="l00273"></a>00273                 <span class="keywordflow">if</span> (synsender_)
<a name="l00274"></a>00274                 {
<a name="l00275"></a>00275                     SET_STATE(CREATE_DR);
<a name="l00276"></a>00276                     <span class="keywordtype">bool</span> ok = send_dictionary_rib();
<a name="l00277"></a>00277                     <span class="keywordflow">if</span> (ok) SET_STATE(SEND_DR);
<a name="l00278"></a>00278                     <span class="keywordflow">return</span> ok;
<a name="l00279"></a>00279                 }
<a name="l00280"></a>00280                 <span class="keywordflow">else</span>
<a name="l00281"></a>00281                     SET_STATE(WAIT_DICT);
<a name="l00282"></a>00282             }
<a name="l00283"></a>00283             <span class="keywordflow">return</span> ok;
<a name="l00284"></a>00284         <span class="keywordflow">case</span> BaseTLV::RIBD_TLV:
<a name="l00285"></a>00285             <span class="keywordflow">if</span> (! estab_) <span class="keywordflow">break</span>;
<a name="l00286"></a>00286             <span class="keywordflow">return</span> handle_ribd_tlv(tlv);
<a name="l00287"></a>00287         <span class="keywordflow">case</span> BaseTLV::RIB_TLV:
<a name="l00288"></a>00288             <span class="keywordflow">if</span> (! estab_) <span class="keywordflow">break</span>;
<a name="l00289"></a>00289             <span class="keywordflow">return</span> handle_rib_tlv(tlv);
<a name="l00290"></a>00290         <span class="keywordflow">case</span> BaseTLV::OFFER_TLV:
<a name="l00291"></a>00291             <span class="keywordflow">if</span> (! estab_) <span class="keywordflow">break</span>;
<a name="l00292"></a>00292             ok = handle_offer_tlv(tlv);
<a name="l00293"></a>00293             <span class="keywordflow">if</span> (ok &amp;&amp; synsender_ &amp;&amp; state_ == WAIT_INFO)
<a name="l00294"></a>00294             {
<a name="l00295"></a>00295                 <span class="comment">// finished Initiator phase, now switch to Listener</span>
<a name="l00296"></a>00296                 SET_STATE(WAIT_DICT);
<a name="l00297"></a>00297             }
<a name="l00298"></a>00298             <span class="keywordflow">return</span> ok;
<a name="l00299"></a>00299         <span class="keywordflow">case</span> BaseTLV::RESPONSE_TLV:
<a name="l00300"></a>00300             <span class="keywordflow">if</span> (! estab_) <span class="keywordflow">break</span>;
<a name="l00301"></a>00301             ok = handle_response_tlv(tlv);
<a name="l00302"></a>00302             <span class="keywordflow">if</span> (ok &amp;&amp; !synsender_ &amp;&amp; state_ == WAIT_INFO)
<a name="l00303"></a>00303             {
<a name="l00304"></a>00304                 <span class="comment">// finished Listener phase, now switch to Initiator</span>
<a name="l00305"></a>00305                 SET_STATE(CREATE_DR);
<a name="l00306"></a>00306                 ok = send_dictionary_rib();
<a name="l00307"></a>00307                 <span class="keywordflow">if</span> (ok) SET_STATE(SEND_DR);
<a name="l00308"></a>00308             }
<a name="l00309"></a>00309             <span class="keywordflow">return</span> ok;
<a name="l00310"></a>00310         <span class="keywordflow">case</span> BaseTLV::ERROR_TLV:
<a name="l00311"></a>00311         <span class="keywordflow">case</span> BaseTLV::UNKNOWN_TLV:
<a name="l00312"></a>00312         <span class="keywordflow">default</span>:
<a name="l00313"></a>00313             <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00314"></a>00314     }
<a name="l00315"></a>00315 
<a name="l00316"></a>00316     <span class="comment">// not reached unless !estab &amp;&amp; tlv-&gt;typecode() != HELLO_TLV</span>
<a name="l00317"></a>00317 
<a name="l00318"></a>00318     hello_rate_ = 2;
<a name="l00319"></a>00319     <span class="keywordflow">if</span> (state_ == SYNSENT)
<a name="l00320"></a>00320         <span class="keywordflow">return</span> SEND_SYN(NEXT_TID);
<a name="l00321"></a>00321     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (state_ == SYNRCVD)
<a name="l00322"></a>00322         <span class="keywordflow">return</span> SEND_SYNACK(tid_);
<a name="l00323"></a>00323 
<a name="l00324"></a>00324     <span class="comment">// unless ERROR or UNKNOWN, do not fail out of this peering session</span>
<a name="l00325"></a>00325     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00326"></a>00326 }
<a name="l00327"></a>00327 
<a name="l00328"></a>00328 <span class="keywordtype">void</span>
<a name="l00329"></a>00329 Encounter::handle_bundle_received(<span class="keyword">const</span> Bundle* b)
<a name="l00330"></a>00330 {
<a name="l00331"></a>00331     <span class="keywordflow">if</span> (state_ != REQUEST) <span class="keywordflow">return</span>;
<a name="l00332"></a>00332     <span class="keywordflow">if</span> (b == NULL) <span class="keywordflow">return</span>;
<a name="l00333"></a>00333 
<a name="l00334"></a>00334     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"handle_bundle_received: "</span>
<a name="l00335"></a>00335             <span class="stringliteral">"%s %u:%u"</span>,b-&gt;destination_id().c_str(),
<a name="l00336"></a>00336             b-&gt;creation_ts(), b-&gt;sequence_num());
<a name="l00337"></a>00337 
<a name="l00338"></a>00338     <span class="comment">// reduce dest id to node id</span>
<a name="l00339"></a>00339     std::string eid = oracle_-&gt;core()-&gt;get_route(b-&gt;destination_id());
<a name="l00340"></a>00340 
<a name="l00341"></a>00341     <span class="comment">// translate node id to sid</span>
<a name="l00342"></a>00342     u_int sid = local_ribd_.find(eid);
<a name="l00343"></a>00343 
<a name="l00344"></a>00344     <span class="comment">// check for dictionary error</span>
<a name="l00345"></a>00345     <span class="keywordflow">if</span> (sid == Dictionary::INVALID_SID) <span class="keywordflow">return</span>;
<a name="l00346"></a>00346 
<a name="l00347"></a>00347     <span class="comment">// reduce list of responses by this one</span>
<a name="l00348"></a>00348     local_response_.remove_entry(
<a name="l00349"></a>00349             b-&gt;creation_ts(),
<a name="l00350"></a>00350             b-&gt;sequence_num(),
<a name="l00351"></a>00351             sid);
<a name="l00352"></a>00352 
<a name="l00353"></a>00353     <span class="comment">// clean up previous alarm: host implementation cleans up cancelled</span>
<a name="l00354"></a>00354     <span class="comment">// alarms, else we clean up our own spent alarms</span>
<a name="l00355"></a>00355     <span class="keywordflow">if</span> (alarm_-&gt;pending())
<a name="l00356"></a>00356         alarm_-&gt;cancel();
<a name="l00357"></a>00357     <span class="keywordflow">else</span>
<a name="l00358"></a>00358         <span class="keyword">delete</span> alarm_;
<a name="l00359"></a>00359 
<a name="l00360"></a>00360     <span class="comment">// set up reminder for timeout_ milliseconds</span>
<a name="l00361"></a>00361     alarm_ = oracle_-&gt;core()-&gt;create_alarm(<span class="keyword">this</span>,timeout_,<span class="keyword">true</span>);
<a name="l00362"></a>00362 
<a name="l00363"></a>00363     <span class="comment">// give up on error</span>
<a name="l00364"></a>00364     <span class="keywordflow">if</span> (alarm_ == NULL) neighbor_gone_ = <span class="keyword">true</span>;
<a name="l00365"></a>00365 }
<a name="l00366"></a>00366 
<a name="l00367"></a>00367 <span class="keywordtype">void</span>
<a name="l00368"></a>00368 Encounter::handle_timeout()
<a name="l00369"></a>00369 {
<a name="l00370"></a>00370     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"handle_timeout"</span>);
<a name="l00371"></a>00371 
<a name="l00372"></a>00372     <span class="keywordflow">if</span> (neighbor_gone_) <span class="keywordflow">return</span>;
<a name="l00373"></a>00373 
<a name="l00374"></a>00374     <span class="keywordtype">bool</span> ok = <span class="keyword">false</span>;
<a name="l00375"></a>00375     <span class="keywordflow">switch</span> (state_)
<a name="l00376"></a>00376     {
<a name="l00377"></a>00377         <span class="keywordflow">case</span> WAIT_NB:
<a name="l00378"></a>00378             ok = <span class="keyword">true</span>;
<a name="l00379"></a>00379             SET_STATE(WAIT_NB);
<a name="l00380"></a>00380             <span class="keywordflow">break</span>;
<a name="l00381"></a>00381         <span class="keywordflow">case</span> SYNSENT:
<a name="l00382"></a>00382             ok = SEND_SYN(NEXT_TID);
<a name="l00383"></a>00383             SET_STATE(SYNSENT);
<a name="l00384"></a>00384             <span class="keywordflow">break</span>;
<a name="l00385"></a>00385         <span class="keywordflow">case</span> SYNRCVD:
<a name="l00386"></a>00386             ok = SEND_SYNACK(tid_);
<a name="l00387"></a>00387             SET_STATE(SYNRCVD);
<a name="l00388"></a>00388             <span class="keywordflow">break</span>;
<a name="l00389"></a>00389         <span class="keywordflow">case</span> ESTAB:
<a name="l00390"></a>00390             <span class="comment">// should not be reached</span>
<a name="l00391"></a>00391             ok = <span class="keyword">false</span>;
<a name="l00392"></a>00392             <span class="keywordflow">break</span>;
<a name="l00393"></a>00393         <span class="keywordflow">case</span> WAIT_DICT:
<a name="l00394"></a>00394             ok = SEND_ACK(tid_);
<a name="l00395"></a>00395             SET_STATE(WAIT_DICT);
<a name="l00396"></a>00396             <span class="keywordflow">break</span>;
<a name="l00397"></a>00397         <span class="keywordflow">case</span> WAIT_RIB:
<a name="l00398"></a>00398             ok = SEND_ACK(tid_);
<a name="l00399"></a>00399             SET_STATE(WAIT_DICT);
<a name="l00400"></a>00400             <span class="keywordflow">break</span>;
<a name="l00401"></a>00401         <span class="keywordflow">case</span> OFFER:
<a name="l00402"></a>00402             ok = send_offer();
<a name="l00403"></a>00403             SET_STATE(OFFER);
<a name="l00404"></a>00404             <span class="keywordflow">break</span>;
<a name="l00405"></a>00405         <span class="keywordflow">case</span> SEND_DR:
<a name="l00406"></a>00406             ok = send_dictionary_rib();
<a name="l00407"></a>00407             <span class="keywordflow">if</span> (ok) SET_STATE(SEND_DR);
<a name="l00408"></a>00408             <span class="keywordflow">break</span>;
<a name="l00409"></a>00409         <span class="keywordflow">case</span> REQUEST:
<a name="l00410"></a>00410             ok = send_response();
<a name="l00411"></a>00411             <span class="keywordflow">break</span>;
<a name="l00412"></a>00412         <span class="keywordflow">case</span> WAIT_INFO:
<a name="l00413"></a>00413             <span class="comment">// if time_diff(now,data_sent) &gt; hello_dead/2 </span>
<a name="l00414"></a>00414             <span class="comment">// start InfoExch again</span>
<a name="l00415"></a>00415             <span class="keywordflow">if</span> (time(0) - data_rcvd_ &gt;
<a name="l00416"></a>00416                 (oracle_-&gt;params()-&gt;hello_dead() *
<a name="l00417"></a>00417                  oracle_-&gt;params()-&gt;hello_interval() / 20))
<a name="l00418"></a>00418             {
<a name="l00419"></a>00419                 <span class="keywordflow">if</span> (synsender_)
<a name="l00420"></a>00420                 {
<a name="l00421"></a>00421                     SET_STATE(CREATE_DR);
<a name="l00422"></a>00422                     ok = send_dictionary_rib();
<a name="l00423"></a>00423                     <span class="keywordflow">if</span> (ok) SET_STATE(SEND_DR);
<a name="l00424"></a>00424                 }
<a name="l00425"></a>00425                 <span class="keywordflow">else</span>
<a name="l00426"></a>00426                 {
<a name="l00427"></a>00427                     SET_STATE(WAIT_DICT);
<a name="l00428"></a>00428                     ok = <span class="keyword">true</span>;
<a name="l00429"></a>00429                 }
<a name="l00430"></a>00430             }
<a name="l00431"></a>00431             <span class="keywordflow">else</span>
<a name="l00432"></a>00432                 ok = <span class="keyword">true</span>;
<a name="l00433"></a>00433             <span class="keywordflow">break</span>;
<a name="l00434"></a>00434         <span class="keywordflow">default</span>:
<a name="l00435"></a>00435             <span class="keywordflow">break</span>;
<a name="l00436"></a>00436     }
<a name="l00437"></a>00437     <span class="comment">// if error sending message, or if silence exceeds max, then</span>
<a name="l00438"></a>00438     <span class="comment">// signal session death and fail out</span>
<a name="l00439"></a>00439     <span class="keywordflow">if</span> (!ok ||
<a name="l00440"></a>00440         (time(0) - data_rcvd_) &gt;
<a name="l00441"></a>00441         (oracle_-&gt;params()-&gt;hello_dead() *
<a name="l00442"></a>00442                             <span class="comment">/* convert 100's of ms to seconds */</span>
<a name="l00443"></a>00443          oracle_-&gt;params()-&gt;hello_interval() / 10))
<a name="l00444"></a>00444     {
<a name="l00445"></a>00445         neighbor_gone_ = <span class="keyword">true</span>;
<a name="l00446"></a>00446         <span class="keywordflow">return</span>;
<a name="l00447"></a>00447     }
<a name="l00448"></a>00448 
<a name="l00449"></a>00449     <span class="comment">// clean up previous alarm: host implementation cleans up cancelled</span>
<a name="l00450"></a>00450     <span class="comment">// alarms, else we clean up our own spent alarms</span>
<a name="l00451"></a>00451     <span class="keywordflow">if</span> (alarm_-&gt;pending())
<a name="l00452"></a>00452         alarm_-&gt;cancel();
<a name="l00453"></a>00453     <span class="keywordflow">else</span>
<a name="l00454"></a>00454         <span class="keyword">delete</span> alarm_;
<a name="l00455"></a>00455 
<a name="l00456"></a>00456     <span class="comment">// set up reminder for timeout_ milliseconds</span>
<a name="l00457"></a>00457     alarm_ = oracle_-&gt;core()-&gt;create_alarm(<span class="keyword">this</span>,timeout_,<span class="keyword">true</span>);
<a name="l00458"></a>00458 
<a name="l00459"></a>00459     <span class="comment">// give up on error</span>
<a name="l00460"></a>00460     <span class="keywordflow">if</span> (alarm_ == NULL) neighbor_gone_ = <span class="keyword">true</span>;
<a name="l00461"></a>00461 }
<a name="l00462"></a>00462 
<a name="l00463"></a>00463 <span class="keywordtype">bool</span>
<a name="l00464"></a>00464 Encounter::handle_hello_tlv(BaseTLV* tlv)
<a name="l00465"></a>00465 {
<a name="l00466"></a>00466     <span class="keywordflow">if</span> (tlv_ == NULL) <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00467"></a>00467     HelloTLV* hello = <span class="keyword">static_cast&lt;</span>HelloTLV*<span class="keyword">&gt;</span>(tlv);
<a name="l00468"></a>00468     <span class="keywordflow">if</span> (hello == NULL || hello-&gt;typecode() != BaseTLV::HELLO_TLV)
<a name="l00469"></a>00469         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00470"></a>00470 
<a name="l00471"></a>00471     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"handle_hello_tlv(%s,%u) from %s"</span>,
<a name="l00472"></a>00472             hello-&gt;hf_str(),hello-&gt;timer(),hello-&gt;sender().c_str());
<a name="l00473"></a>00473 
<a name="l00474"></a>00474     <span class="comment">// build out truth table as laid out in Section 5.2</span>
<a name="l00475"></a>00475     <span class="keywordtype">bool</span> hello_a = (remote_instance_ == tlv_-&gt;sender_instance());
<a name="l00476"></a>00476     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"hello_a %s remote_instance_ %u tlv %u"</span>,
<a name="l00477"></a>00477             hello_a ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>, remote_instance_,
<a name="l00478"></a>00478             tlv_-&gt;sender_instance());
<a name="l00479"></a>00479     <span class="keywordtype">bool</span> hello_b = hello_a &amp;&amp;
<a name="l00480"></a>00480         (oracle_-&gt;core()-&gt;prophet_id(next_hop_) == tlv_-&gt;source());
<a name="l00481"></a>00481     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"hello_b %s next_hop_ %s tlv %s"</span>,
<a name="l00482"></a>00482             hello_b ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>, 
<a name="l00483"></a>00483             oracle_-&gt;core()-&gt;prophet_id(next_hop_).c_str(),
<a name="l00484"></a>00484             tlv_-&gt;source().c_str());
<a name="l00485"></a>00485     <span class="keywordtype">bool</span> hello_c = (local_instance_ == tlv_-&gt;receiver_instance());
<a name="l00486"></a>00486     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"hello_c %s local_instance_ %u tlv %u"</span>,
<a name="l00487"></a>00487             hello_c ? <span class="stringliteral">"true"</span> : <span class="stringliteral">"false"</span>,
<a name="l00488"></a>00488             local_instance_, tlv_-&gt;receiver_instance());
<a name="l00489"></a>00489 
<a name="l00490"></a>00490     <span class="comment">// negotiate a common timeout by choosing minimum</span>
<a name="l00491"></a>00491     u_int timeout = std::min((u_int)oracle_-&gt;params()-&gt;hello_interval(),
<a name="l00492"></a>00492                              (u_int)hello-&gt;timer(), std::less&lt;u_int&gt;());
<a name="l00493"></a>00493 
<a name="l00494"></a>00494     <span class="keywordflow">if</span> (!estab_ &amp;&amp; (timeout * 100) != timeout_)
<a name="l00495"></a>00495     {
<a name="l00496"></a>00496         <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"timeout_ %u -&gt; %u (line %d)"</span>,
<a name="l00497"></a>00497                 timeout_, timeout, __LINE__);
<a name="l00498"></a>00498         <span class="comment">// convert to milliseconds</span>
<a name="l00499"></a>00499         timeout_ = timeout * 100;
<a name="l00500"></a>00500     }
<a name="l00501"></a>00501 
<a name="l00502"></a>00502     <span class="keywordtype">bool</span> ok = <span class="keyword">true</span>;
<a name="l00503"></a>00503     <span class="keywordflow">switch</span> (hello-&gt;hf())
<a name="l00504"></a>00504     {
<a name="l00505"></a>00505     <span class="keywordflow">case</span> HelloTLV::SYN:
<a name="l00506"></a>00506         <span class="keywordflow">if</span> (estab_)
<a name="l00507"></a>00507         {
<a name="l00508"></a>00508             <span class="comment">// note 2, 5.2.1</span>
<a name="l00509"></a>00509             hello_rate_ = 2;
<a name="l00510"></a>00510             ok = SEND_ACK(tid_);
<a name="l00511"></a>00511         }
<a name="l00512"></a>00512         <span class="keywordflow">else</span>
<a name="l00513"></a>00513         <span class="keywordflow">if</span> (state_ == SYNSENT ||
<a name="l00514"></a>00514             state_ == SYNRCVD ||
<a name="l00515"></a>00515             state_ == WAIT_NB)
<a name="l00516"></a>00516         {
<a name="l00517"></a>00517             UPDATE_PEER_VERIFIER(tlv_-&gt;sender_instance());
<a name="l00518"></a>00518             <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"handle_hello_tlv(SYN): state_ %s remote_instance_ %u"</span>,
<a name="l00519"></a>00519                     state_to_str(state_),remote_instance_);
<a name="l00520"></a>00520             ok = SEND_SYNACK(tid_);
<a name="l00521"></a>00521             SET_STATE(SYNRCVD);
<a name="l00522"></a>00522         }
<a name="l00523"></a>00523         <span class="keywordflow">break</span>;
<a name="l00524"></a>00524     <span class="keywordflow">case</span> HelloTLV::SYNACK:
<a name="l00525"></a>00525         <span class="keywordflow">if</span> (estab_)
<a name="l00526"></a>00526         {
<a name="l00527"></a>00527             <span class="comment">// note 2, 5.2.1</span>
<a name="l00528"></a>00528             hello_rate_ = 2;
<a name="l00529"></a>00529             ok = SEND_ACK(tid_);
<a name="l00530"></a>00530         }
<a name="l00531"></a>00531         <span class="keywordflow">else</span>
<a name="l00532"></a>00532         <span class="keywordflow">if</span> (state_ == SYNSENT)
<a name="l00533"></a>00533         {
<a name="l00534"></a>00534             <span class="keywordflow">if</span> ( hello_c)
<a name="l00535"></a>00535             {
<a name="l00536"></a>00536                 hello_rate_ = 0;
<a name="l00537"></a>00537                 UPDATE_PEER_VERIFIER(tlv_-&gt;sender_instance());
<a name="l00538"></a>00538                 <span class="keywordflow">if</span> (ok = SEND_ACK(tid_))
<a name="l00539"></a>00539                 {
<a name="l00540"></a>00540                     SET_STATE(ESTAB);
<a name="l00541"></a>00541                     estab_ = <span class="keyword">true</span>;
<a name="l00542"></a>00542                 }
<a name="l00543"></a>00543             }
<a name="l00544"></a>00544             <span class="keywordflow">else</span>
<a name="l00545"></a>00545             {
<a name="l00546"></a>00546                 ok = SEND_RSTACK(tid_);
<a name="l00547"></a>00547                 SET_STATE(SYNSENT);
<a name="l00548"></a>00548             }
<a name="l00549"></a>00549         }
<a name="l00550"></a>00550         <span class="keywordflow">else</span>
<a name="l00551"></a>00551         <span class="keywordflow">if</span> (state_ == SYNRCVD)
<a name="l00552"></a>00552         {
<a name="l00553"></a>00553             <span class="keywordflow">if</span> (hello_c)
<a name="l00554"></a>00554             {
<a name="l00555"></a>00555                 hello_rate_ = 0;
<a name="l00556"></a>00556                 UPDATE_PEER_VERIFIER(tlv_-&gt;sender_instance());
<a name="l00557"></a>00557                 <span class="keywordflow">if</span> (ok = SEND_ACK(tid_))
<a name="l00558"></a>00558                 {
<a name="l00559"></a>00559                     SET_STATE(ESTAB);
<a name="l00560"></a>00560                     estab_ = <span class="keyword">true</span>;
<a name="l00561"></a>00561                 }
<a name="l00562"></a>00562             }
<a name="l00563"></a>00563             <span class="keywordflow">else</span>
<a name="l00564"></a>00564             {
<a name="l00565"></a>00565                 ok = SEND_RSTACK(tid_);
<a name="l00566"></a>00566                 SET_STATE(SYNRCVD);
<a name="l00567"></a>00567             }
<a name="l00568"></a>00568         }
<a name="l00569"></a>00569         <span class="keywordflow">break</span>;
<a name="l00570"></a>00570     <span class="keywordflow">case</span> HelloTLV::ACK:
<a name="l00571"></a>00571         <span class="keywordflow">if</span> (estab_ &amp;&amp; !(hello_b &amp;&amp; hello_c))
<a name="l00572"></a>00572         {
<a name="l00573"></a>00573             ok = SEND_RSTACK(tid_);
<a name="l00574"></a>00574             <span class="keywordflow">break</span>;
<a name="l00575"></a>00575         }
<a name="l00576"></a>00576         <span class="keywordflow">if</span> (state_ == SYNSENT)
<a name="l00577"></a>00577         {
<a name="l00578"></a>00578             ok = SEND_RSTACK(tid_);
<a name="l00579"></a>00579             SET_STATE(SYNSENT);
<a name="l00580"></a>00580         }
<a name="l00581"></a>00581         <span class="keywordflow">else</span>
<a name="l00582"></a>00582         <span class="keywordflow">if</span> (state_ == SYNRCVD)
<a name="l00583"></a>00583         {
<a name="l00584"></a>00584             <span class="keywordflow">if</span> (hello_b &amp;&amp; hello_c)
<a name="l00585"></a>00585             {
<a name="l00586"></a>00586                 SET_STATE(ESTAB);
<a name="l00587"></a>00587                 estab_ = <span class="keyword">true</span>;
<a name="l00588"></a>00588             }
<a name="l00589"></a>00589             <span class="keywordflow">else</span>
<a name="l00590"></a>00590             {
<a name="l00591"></a>00591                 <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"handle_hello_tlv(ACK): state_ SYNRCVD "</span>
<a name="l00592"></a>00592                         <span class="stringliteral">"remote_instance_ %u tlv instance %u"</span>,
<a name="l00593"></a>00593                         remote_instance_,tlv_-&gt;sender_instance());
<a name="l00594"></a>00594                 ok = SEND_RSTACK(tid_);
<a name="l00595"></a>00595                 SET_STATE(SYNRCVD);
<a name="l00596"></a>00596             }
<a name="l00597"></a>00597         }
<a name="l00598"></a>00598         <span class="keywordflow">else</span>
<a name="l00599"></a>00599         <span class="keywordflow">if</span> (state_ == WAIT_RIB || state_ == OFFER)
<a name="l00600"></a>00600         {
<a name="l00601"></a>00601             SET_STATE(WAIT_DICT);
<a name="l00602"></a>00602         }
<a name="l00603"></a>00603         <span class="keywordflow">else</span>
<a name="l00604"></a>00604         <span class="keywordflow">if</span> (state_ == REQUEST)
<a name="l00605"></a>00605         {
<a name="l00606"></a>00606             SET_STATE(CREATE_DR);
<a name="l00607"></a>00607             ok = send_dictionary_rib();
<a name="l00608"></a>00608             <span class="keywordflow">if</span> (ok) SET_STATE(SEND_DR);
<a name="l00609"></a>00609         }
<a name="l00610"></a>00610         <span class="keywordflow">else</span>
<a name="l00611"></a>00611         <span class="keywordflow">if</span> (state_ == WAIT_INFO)
<a name="l00612"></a>00612         {
<a name="l00613"></a>00613             <span class="comment">// remote says "What up?" so we wake up and move on</span>
<a name="l00614"></a>00614             <span class="keywordflow">if</span> (time(0) - data_sent_ &gt; oracle_-&gt;params()-&gt;hello_interval())
<a name="l00615"></a>00615             {
<a name="l00616"></a>00616                 <span class="keywordflow">if</span> (synsender_)
<a name="l00617"></a>00617                 {
<a name="l00618"></a>00618                     SET_STATE(CREATE_DR);
<a name="l00619"></a>00619                     <span class="keywordtype">bool</span> ok = send_dictionary_rib();
<a name="l00620"></a>00620                     <span class="keywordflow">if</span> (ok) SET_STATE(SEND_DR);
<a name="l00621"></a>00621                     <span class="keywordflow">return</span> ok;
<a name="l00622"></a>00622                 }
<a name="l00623"></a>00623                 <span class="keywordflow">else</span>
<a name="l00624"></a>00624                 {
<a name="l00625"></a>00625                     SET_STATE(WAIT_DICT);
<a name="l00626"></a>00626                 }
<a name="l00627"></a>00627             }
<a name="l00628"></a>00628         }
<a name="l00629"></a>00629         <span class="keywordflow">break</span>;
<a name="l00630"></a>00630     <span class="keywordflow">case</span> HelloTLV::RSTACK:
<a name="l00631"></a>00631         <span class="keywordflow">if</span> (hello_a &amp;&amp; hello_c &amp;&amp; !synsent_)
<a name="l00632"></a>00632         {
<a name="l00633"></a>00633             <span class="comment">// signal end of session</span>
<a name="l00634"></a>00634             <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00635"></a>00635         }
<a name="l00636"></a>00636         <span class="keywordflow">break</span>;
<a name="l00637"></a>00637     <span class="keywordflow">case</span> HelloTLV::HF_UNKNOWN:
<a name="l00638"></a>00638     <span class="keywordflow">default</span>:
<a name="l00639"></a>00639         <span class="keywordflow">break</span>;
<a name="l00640"></a>00640     }
<a name="l00641"></a>00641 
<a name="l00642"></a>00642     <span class="keywordflow">return</span> ok;
<a name="l00643"></a>00643 }
<a name="l00644"></a>00644 
<a name="l00645"></a>00645 <span class="keywordtype">bool</span>
<a name="l00646"></a>00646 Encounter::handle_ribd_tlv(BaseTLV* tlv)
<a name="l00647"></a>00647 {
<a name="l00648"></a>00648     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"handle_ribd_tlv"</span>);
<a name="l00649"></a>00649 
<a name="l00650"></a>00650     RIBDTLV* ribd = <span class="keyword">static_cast&lt;</span>RIBDTLV*<span class="keyword">&gt;</span>(tlv);
<a name="l00651"></a>00651     <span class="keywordflow">if</span> (ribd == NULL)
<a name="l00652"></a>00652         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00653"></a>00653 
<a name="l00654"></a>00654     <span class="comment">// figure out which one of us is sender and which is receiver</span>
<a name="l00655"></a>00655     std::string sender, receiver;
<a name="l00656"></a>00656     ASSIGN_ROLES(sender,receiver);
<a name="l00657"></a>00657 
<a name="l00658"></a>00658     <span class="keywordflow">switch</span> (state_)
<a name="l00659"></a>00659     {
<a name="l00660"></a>00660     <span class="keywordflow">case</span> WAIT_INFO:
<a name="l00661"></a>00661         <span class="comment">// remote says "What up?" so we wake up and move on</span>
<a name="l00662"></a>00662         <span class="keywordflow">if</span> (time(0) - data_sent_ &gt; oracle_-&gt;params()-&gt;hello_interval())
<a name="l00663"></a>00663         {
<a name="l00664"></a>00664             <span class="keywordflow">if</span> (synsender_)
<a name="l00665"></a>00665                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00666"></a>00666             <span class="keywordflow">else</span>
<a name="l00667"></a>00667                 SET_STATE(WAIT_DICT);
<a name="l00668"></a>00668         }
<a name="l00669"></a>00669     <span class="keywordflow">case</span> WAIT_DICT:
<a name="l00670"></a>00670     <span class="keywordflow">case</span> WAIT_RIB:
<a name="l00671"></a>00671         remote_ribd_ = ribd-&gt;ribd(sender,receiver);
<a name="l00672"></a>00672         remote_ribd_.dump(oracle_-&gt;core(),__FILE__,__LINE__);
<a name="l00673"></a>00673         SET_STATE(WAIT_RIB);
<a name="l00674"></a>00674         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00675"></a>00675     <span class="keywordflow">case</span> OFFER:
<a name="l00676"></a>00676         SET_STATE(OFFER);
<a name="l00677"></a>00677         <span class="keywordflow">return</span> send_offer();
<a name="l00678"></a>00678     <span class="keywordflow">default</span>:
<a name="l00679"></a>00679         <span class="keywordflow">break</span>;
<a name="l00680"></a>00680     }
<a name="l00681"></a>00681     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00682"></a>00682 }
<a name="l00683"></a>00683 
<a name="l00684"></a>00684 <span class="keywordtype">bool</span>
<a name="l00685"></a>00685 Encounter::handle_rib_tlv(BaseTLV* tlv)
<a name="l00686"></a>00686 {
<a name="l00687"></a>00687     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"handle_rib_tlv"</span>);
<a name="l00688"></a>00688 
<a name="l00689"></a>00689     RIBTLV* rib = <span class="keyword">static_cast&lt;</span>RIBTLV*<span class="keyword">&gt;</span>(tlv);
<a name="l00690"></a>00690     <span class="keywordflow">if</span> (rib == NULL)
<a name="l00691"></a>00691         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00692"></a>00692 
<a name="l00693"></a>00693     remote_ribd_.dump(oracle_-&gt;core(),__FILE__,__LINE__);
<a name="l00694"></a>00694     Table* nodes = oracle_-&gt;nodes();
<a name="l00695"></a>00695     <span class="keywordflow">if</span> (state_ == WAIT_RIB)
<a name="l00696"></a>00696     {
<a name="l00697"></a>00697         <span class="comment">// update p for remote peer</span>
<a name="l00698"></a>00698         nodes-&gt;update_route(next_hop_-&gt;remote_eid(),
<a name="l00699"></a>00699                             rib-&gt;relay(),
<a name="l00700"></a>00700                             rib-&gt;custody(),
<a name="l00701"></a>00701                             rib-&gt;internet());
<a name="l00702"></a>00702         <span class="comment">// then update p for each RIB entry</span>
<a name="l00703"></a>00703         nodes-&gt;update_transitive(next_hop_-&gt;remote_eid(),
<a name="l00704"></a>00704                                  rib-&gt;nodes(),
<a name="l00705"></a>00705                                  remote_ribd_);
<a name="l00706"></a>00706         <span class="comment">// keep a local copy of remote's RIB</span>
<a name="l00707"></a>00707         remote_nodes_.assign(rib-&gt;nodes(),
<a name="l00708"></a>00708                              remote_ribd_);
<a name="l00709"></a>00709         SET_STATE(OFFER);
<a name="l00710"></a>00710         <span class="keywordflow">return</span> send_offer();
<a name="l00711"></a>00711     } 
<a name="l00712"></a>00712     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00713"></a>00713 }
<a name="l00714"></a>00714 
<a name="l00715"></a>00715 <span class="keywordtype">bool</span>
<a name="l00716"></a>00716 Encounter::handle_offer_tlv(BaseTLV* tlv)
<a name="l00717"></a>00717 {
<a name="l00718"></a>00718     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"handle_offer_tlv"</span>);
<a name="l00719"></a>00719 
<a name="l00720"></a>00720     OfferTLV* offer = <span class="keyword">static_cast&lt;</span>OfferTLV*<span class="keyword">&gt;</span>(tlv);
<a name="l00721"></a>00721     <span class="keywordflow">if</span> (offer == NULL)
<a name="l00722"></a>00722     {
<a name="l00723"></a>00723         <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"failed to downcast tlv"</span>);
<a name="l00724"></a>00724         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00725"></a>00725     }
<a name="l00726"></a>00726 
<a name="l00727"></a>00727     <span class="keywordflow">if</span> (state_ == SEND_DR || state_ == REQUEST)
<a name="l00728"></a>00728     {
<a name="l00729"></a>00729         remote_offers_ = offer-&gt;list();
<a name="l00730"></a>00730         <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"received %zu offers"</span>,remote_offers_.size()); 
<a name="l00731"></a>00731         SET_STATE(REQUEST);
<a name="l00732"></a>00732         <span class="keywordflow">return</span> send_response();
<a name="l00733"></a>00733     }
<a name="l00734"></a>00734     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (state_ == WAIT_INFO)
<a name="l00735"></a>00735     {
<a name="l00736"></a>00736         <span class="comment">// ignore</span>
<a name="l00737"></a>00737         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00738"></a>00738     }
<a name="l00739"></a>00739     <span class="keywordflow">else</span>
<a name="l00740"></a>00740     {
<a name="l00741"></a>00741         <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_ERR,<span class="stringliteral">"received offer tlv when state_ == %s"</span>,state_str());
<a name="l00742"></a>00742     }
<a name="l00743"></a>00743 
<a name="l00744"></a>00744     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00745"></a>00745 }
<a name="l00746"></a>00746 
<a name="l00747"></a>00747 <span class="keywordtype">bool</span>
<a name="l00748"></a>00748 Encounter::handle_response_tlv(BaseTLV* tlv)
<a name="l00749"></a>00749 {
<a name="l00750"></a>00750     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"handle_response_tlv"</span>);
<a name="l00751"></a>00751 
<a name="l00752"></a>00752     ResponseTLV* response = <span class="keyword">static_cast&lt;</span>ResponseTLV*<span class="keyword">&gt;</span>(tlv);
<a name="l00753"></a>00753     <span class="keywordflow">if</span> (response == NULL)
<a name="l00754"></a>00754         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00755"></a>00755 
<a name="l00756"></a>00756     <span class="keywordflow">switch</span> (state_)
<a name="l00757"></a>00757     {
<a name="l00758"></a>00758     <span class="keywordflow">case</span> WAIT_RIB:
<a name="l00759"></a>00759         SET_STATE(WAIT_DICT);
<a name="l00760"></a>00760         <span class="keywordflow">return</span> SEND_ACK(tid_);
<a name="l00761"></a>00761     <span class="keywordflow">case</span> OFFER:
<a name="l00762"></a>00762         <span class="comment">// empty request signals state change</span>
<a name="l00763"></a>00763         <span class="keywordflow">if</span> (response-&gt;list().empty())
<a name="l00764"></a>00764         {
<a name="l00765"></a>00765             <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"received empty request"</span>);
<a name="l00766"></a>00766             SET_STATE(WAIT_INFO);
<a name="l00767"></a>00767             <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00768"></a>00768         }
<a name="l00769"></a>00769         <span class="keywordflow">else</span>
<a name="l00770"></a>00770         {
<a name="l00771"></a>00771             <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"received %zu requests"</span>,response-&gt;list().size());
<a name="l00772"></a>00772             <span class="comment">// enumerate bundle list from repository</span>
<a name="l00773"></a>00773             BundleList bundles = oracle_-&gt;core()-&gt;bundles();
<a name="l00774"></a>00774             <span class="comment">// dump the dictionary </span>
<a name="l00775"></a>00775             remote_ribd_.dump(oracle_-&gt;core(),__FILE__,__LINE__);
<a name="l00776"></a>00776 
<a name="l00777"></a>00777             <span class="comment">// walk the list of requests</span>
<a name="l00778"></a>00778             <span class="keywordflow">for</span>(BundleResponseList::const_iterator i =
<a name="l00779"></a>00779                     response-&gt;list().begin();
<a name="l00780"></a>00780                 i != response-&gt;list().end();
<a name="l00781"></a>00781                 i++)
<a name="l00782"></a>00782             {
<a name="l00783"></a>00783                 <span class="comment">// look up the requested bundle</span>
<a name="l00784"></a>00784                 std::string eid = remote_ribd_.find((*i)-&gt;sid());
<a name="l00785"></a>00785                 <span class="keyword">const</span> Bundle* b = oracle_-&gt;core()-&gt;find(bundles,
<a name="l00786"></a>00786                         eid,(*i)-&gt;creation_ts(),(*i)-&gt;seqno());
<a name="l00787"></a>00787 
<a name="l00788"></a>00788                 <span class="comment">// ignore failure (after logging)</span>
<a name="l00789"></a>00789                 <span class="keywordflow">if</span> (b == NULL) 
<a name="l00790"></a>00790                 {
<a name="l00791"></a>00791                     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_ERR,<span class="stringliteral">"failed to locate bundle for request "</span>
<a name="l00792"></a>00792                         <span class="stringliteral">"%u -&gt; %s, %u, %u"</span>, (*i)-&gt;sid(),
<a name="l00793"></a>00793                         remote_ribd_.find((*i)-&gt;sid()).c_str(),
<a name="l00794"></a>00794                         (*i)-&gt;creation_ts(),(*i)-&gt;seqno());
<a name="l00795"></a>00795                     <span class="keywordflow">continue</span>;
<a name="l00796"></a>00796                 }
<a name="l00797"></a>00797 
<a name="l00798"></a>00798                 <span class="comment">// skip if send fails, try again next timeout</span>
<a name="l00799"></a>00799                 <span class="keywordflow">if</span> (!oracle_-&gt;core()-&gt;send_bundle(b,next_hop_))
<a name="l00800"></a>00800                 {
<a name="l00801"></a>00801                     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_ERR,<span class="stringliteral">"failed to send bundle for request "</span>
<a name="l00802"></a>00802                         <span class="stringliteral">"%s, %u, %u"</span>, remote_ribd_.find((*i)-&gt;sid()).c_str(),
<a name="l00803"></a>00803                         (*i)-&gt;creation_ts(),(*i)-&gt;seqno());
<a name="l00804"></a>00804                     <span class="keywordflow">continue</span>;
<a name="l00805"></a>00805                 }
<a name="l00806"></a>00806 
<a name="l00807"></a>00807                 <span class="comment">// update timestamp on outbound data</span>
<a name="l00808"></a>00808                 data_sent_ = time(0);
<a name="l00809"></a>00809 
<a name="l00810"></a>00810             }
<a name="l00811"></a>00811             SET_STATE(OFFER);
<a name="l00812"></a>00812             <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00813"></a>00813         }
<a name="l00814"></a>00814     <span class="keywordflow">default</span>:
<a name="l00815"></a>00815         <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_ERR,<span class="stringliteral">"received response when state_ == %s"</span>,
<a name="l00816"></a>00816                 state_to_str(state_));
<a name="l00817"></a>00817         <span class="keywordflow">break</span>;
<a name="l00818"></a>00818     }
<a name="l00819"></a>00819 
<a name="l00820"></a>00820     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00821"></a>00821 }
<a name="l00822"></a>00822 
<a name="l00823"></a>00823 <span class="keywordtype">bool</span>
<a name="l00824"></a>00824 Encounter::send_hello(HelloTLV::hello_hf_t hf,
<a name="l00825"></a>00825                       ProphetTLV::header_result_t hr,
<a name="l00826"></a>00826                       u_int32_t tid)
<a name="l00827"></a>00827 {
<a name="l00828"></a>00828     <span class="comment">// Impose a simple flow control; hello_rate_ is set by the constructor</span>
<a name="l00829"></a>00829     <span class="comment">// and by handle_hello_tlv</span>
<a name="l00830"></a>00830     <span class="keywordflow">if</span> ((state_ != WAIT_NB) &amp;&amp;
<a name="l00831"></a>00831             (hello_rate_ &gt; 0) &amp;&amp;
<a name="l00832"></a>00832             (hf != HelloTLV::RSTACK) &amp;&amp;
<a name="l00833"></a>00833             (time(0) - data_sent_ &lt; timeout_ / hello_rate_) )
<a name="l00834"></a>00834         <span class="keywordflow">return</span> <span class="keyword">true</span>; <span class="comment">// don't kill the Encounter, but neither do we</span>
<a name="l00835"></a>00835                      <span class="comment">// send this Hello message</span>
<a name="l00836"></a>00836 
<a name="l00837"></a>00837     <span class="comment">// Create Hello TLV with hello function hf</span>
<a name="l00838"></a>00838     HelloTLV* ht = <span class="keyword">new</span> HelloTLV(hf,
<a name="l00839"></a>00839                                 oracle_-&gt;params()-&gt;hello_interval(),
<a name="l00840"></a>00840                                 oracle_-&gt;core()-&gt;local_eid());
<a name="l00841"></a>00841 
<a name="l00842"></a>00842     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"send_hello(%s,%u)"</span>,
<a name="l00843"></a>00843             ht-&gt;hf_str(),ht-&gt;timer());
<a name="l00844"></a>00844 
<a name="l00845"></a>00845     <span class="comment">// Create outbound TLV</span>
<a name="l00846"></a>00846     ProphetTLV* tlv = NULL;
<a name="l00847"></a>00847     PROPHET_TLV(tlv,hr,tid);
<a name="l00848"></a>00848     <span class="keywordflow">if</span> (tlv == NULL)
<a name="l00849"></a>00849     {
<a name="l00850"></a>00850         <span class="keyword">delete</span> ht;
<a name="l00851"></a>00851         <span class="keyword">delete</span> tlv;
<a name="l00852"></a>00852         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00853"></a>00853     }
<a name="l00854"></a>00854 
<a name="l00855"></a>00855     <span class="comment">// Attach the Hello TLV</span>
<a name="l00856"></a>00856     <span class="keywordflow">if</span> (!tlv-&gt;add_tlv(ht))
<a name="l00857"></a>00857     {
<a name="l00858"></a>00858         <span class="keyword">delete</span> ht;
<a name="l00859"></a>00859         <span class="keyword">delete</span> tlv;
<a name="l00860"></a>00860         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00861"></a>00861     }
<a name="l00862"></a>00862 
<a name="l00863"></a>00863     <span class="comment">// Submit TLV as a bundle to the host bundle core</span>
<a name="l00864"></a>00864     <span class="keywordtype">bool</span> ok = send_tlv(tlv);
<a name="l00865"></a>00865 
<a name="l00866"></a>00866     <span class="comment">// set flag on SYN sent </span>
<a name="l00867"></a>00867     <span class="keywordflow">if</span> (ok &amp;&amp; (hf == HelloTLV::SYN || hf == HelloTLV::SYNACK))
<a name="l00868"></a>00868         synsent_ = <span class="keyword">true</span>;
<a name="l00869"></a>00869 
<a name="l00870"></a>00870     <span class="keywordflow">return</span> ok;
<a name="l00871"></a>00871 }
<a name="l00872"></a>00872 
<a name="l00873"></a>00873 <span class="keywordtype">bool</span>
<a name="l00874"></a>00874 Encounter::send_dictionary_rib(ProphetTLV::header_result_t hr,
<a name="l00875"></a>00875                                u_int32_t tid)
<a name="l00876"></a>00876 {
<a name="l00877"></a>00877     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"send_dictionary_rib"</span>);
<a name="l00878"></a>00878 
<a name="l00879"></a>00879     <span class="keywordflow">if</span> (state_ != CREATE_DR &amp;&amp; state_ != SEND_DR)
<a name="l00880"></a>00880         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00881"></a>00881 
<a name="l00882"></a>00882     <span class="comment">// figure out which one of us is sender and which is receiver</span>
<a name="l00883"></a>00883     std::string sender, receiver;
<a name="l00884"></a>00884     ASSIGN_ROLES(sender,receiver);
<a name="l00885"></a>00885 
<a name="l00886"></a>00886     <span class="comment">// Create the dictionary TLV</span>
<a name="l00887"></a>00887     RIBDTLV* ribdtlv = TLVCreator::ribd(oracle_-&gt;core(),
<a name="l00888"></a>00888                                         oracle_-&gt;nodes(),
<a name="l00889"></a>00889                                         sender, receiver);
<a name="l00890"></a>00890 
<a name="l00891"></a>00891     <span class="keywordflow">if</span> (ribdtlv == NULL) <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00892"></a>00892 
<a name="l00893"></a>00893     <span class="comment">// hold on to that dictionary, for creating RIB and Offer</span>
<a name="l00894"></a>00894     local_ribd_ = ribdtlv-&gt;ribd(sender,receiver);
<a name="l00895"></a>00895     local_ribd_.dump(oracle_-&gt;core(),__FILE__,__LINE__);
<a name="l00896"></a>00896 
<a name="l00897"></a>00897     <span class="comment">// Create outbound TLV</span>
<a name="l00898"></a>00898     ProphetTLV* tlv = NULL;
<a name="l00899"></a>00899     PROPHET_TLV(tlv,hr,tid);
<a name="l00900"></a>00900     <span class="keywordflow">if</span> (tlv == NULL)
<a name="l00901"></a>00901     {
<a name="l00902"></a>00902         <span class="keyword">delete</span> ribdtlv;
<a name="l00903"></a>00903         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00904"></a>00904     }
<a name="l00905"></a>00905 
<a name="l00906"></a>00906     <span class="comment">// Attach the RIBD TLV</span>
<a name="l00907"></a>00907     <span class="keywordflow">if</span> (!tlv-&gt;add_tlv(ribdtlv))
<a name="l00908"></a>00908     {
<a name="l00909"></a>00909         <span class="keyword">delete</span> ribdtlv;
<a name="l00910"></a>00910         <span class="keyword">delete</span> tlv;
<a name="l00911"></a>00911         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00912"></a>00912     }
<a name="l00913"></a>00913 
<a name="l00914"></a>00914     RIBTLV* rib = TLVCreator::rib(oracle_,
<a name="l00915"></a>00915                                   local_ribd_,
<a name="l00916"></a>00916                                   oracle_-&gt;params()-&gt;relay_node(),
<a name="l00917"></a>00917                                   oracle_-&gt;core()-&gt;custody_accepted(),
<a name="l00918"></a>00918                                   oracle_-&gt;params()-&gt;internet_gw());
<a name="l00919"></a>00919 
<a name="l00920"></a>00920     <span class="keywordflow">if</span> (rib == NULL)
<a name="l00921"></a>00921     {
<a name="l00922"></a>00922         <span class="keyword">delete</span> tlv;
<a name="l00923"></a>00923         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00924"></a>00924     }
<a name="l00925"></a>00925 
<a name="l00926"></a>00926     <span class="comment">// Attach the RIB TLV</span>
<a name="l00927"></a>00927     <span class="keywordflow">if</span> (!tlv-&gt;add_tlv(rib))
<a name="l00928"></a>00928     {
<a name="l00929"></a>00929         <span class="keyword">delete</span> rib;
<a name="l00930"></a>00930         <span class="keyword">delete</span> tlv;
<a name="l00931"></a>00931         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00932"></a>00932     }
<a name="l00933"></a>00933 
<a name="l00934"></a>00934     <span class="comment">// Submit TLV as a bundle to the host bundle core</span>
<a name="l00935"></a>00935     <span class="keywordflow">return</span> send_tlv(tlv);
<a name="l00936"></a>00936 }
<a name="l00937"></a>00937 
<a name="l00938"></a>00938 <span class="keywordtype">bool</span>
<a name="l00939"></a>00939 Encounter::send_offer(ProphetTLV::header_result_t hr,
<a name="l00940"></a>00940                       u_int32_t tid)
<a name="l00941"></a>00941 {
<a name="l00942"></a>00942     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"send_offer"</span>);
<a name="l00943"></a>00943     remote_ribd_.dump(oracle_-&gt;core(),__FILE__,__LINE__);
<a name="l00944"></a>00944 
<a name="l00945"></a>00945     <span class="comment">// remote nodes is filled in by handle_rib_tlv</span>
<a name="l00946"></a>00946     OfferTLV* offer = TLVCreator::offer(oracle_,
<a name="l00947"></a>00947                                         next_hop_,
<a name="l00948"></a>00948                                         remote_ribd_,
<a name="l00949"></a>00949                                         remote_nodes_);
<a name="l00950"></a>00950 
<a name="l00951"></a>00951     <span class="keywordflow">if</span> (offer == NULL) <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00952"></a>00952 
<a name="l00953"></a>00953     <span class="comment">// Create outbound TLV</span>
<a name="l00954"></a>00954     ProphetTLV* tlv = NULL;
<a name="l00955"></a>00955     PROPHET_TLV(tlv,hr,tid);
<a name="l00956"></a>00956     <span class="keywordflow">if</span> (tlv == NULL)
<a name="l00957"></a>00957     {
<a name="l00958"></a>00958         <span class="keyword">delete</span> offer;
<a name="l00959"></a>00959         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00960"></a>00960     }
<a name="l00961"></a>00961 
<a name="l00962"></a>00962     <span class="comment">// Attach the RIBD TLV</span>
<a name="l00963"></a>00963     <span class="keywordflow">if</span> (!tlv-&gt;add_tlv(offer))
<a name="l00964"></a>00964     {
<a name="l00965"></a>00965         <span class="keyword">delete</span> offer;
<a name="l00966"></a>00966         <span class="keyword">delete</span> tlv;
<a name="l00967"></a>00967         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00968"></a>00968     }
<a name="l00969"></a>00969 
<a name="l00970"></a>00970     <span class="comment">// Submit TLV as a bundle to the host bundle core</span>
<a name="l00971"></a>00971     <span class="keywordflow">return</span> send_tlv(tlv);
<a name="l00972"></a>00972 }
<a name="l00973"></a>00973 
<a name="l00974"></a>00974 <span class="keywordtype">bool</span>
<a name="l00975"></a>00975 Encounter::send_response(ProphetTLV::header_result_t hr,
<a name="l00976"></a>00976                          u_int32_t tid)
<a name="l00977"></a>00977 {
<a name="l00978"></a>00978     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"send_response"</span>);
<a name="l00979"></a>00979     local_ribd_.dump(oracle_-&gt;core(),__FILE__,__LINE__);
<a name="l00980"></a>00980 
<a name="l00981"></a>00981     ResponseTLV* response = TLVCreator::response(oracle_,
<a name="l00982"></a>00982                                                  remote_offers_,
<a name="l00983"></a>00983                                                  local_response_,
<a name="l00984"></a>00984                                                  local_ribd_);
<a name="l00985"></a>00985 
<a name="l00986"></a>00986     <span class="keywordflow">if</span> (response == NULL) <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00987"></a>00987 
<a name="l00988"></a>00988     <span class="comment">// Create outbound TLV</span>
<a name="l00989"></a>00989     ProphetTLV* tlv = NULL;
<a name="l00990"></a>00990     PROPHET_TLV(tlv,hr,tid);
<a name="l00991"></a>00991     <span class="keywordflow">if</span> (tlv == NULL) 
<a name="l00992"></a>00992     {
<a name="l00993"></a>00993         <span class="keyword">delete</span> response;
<a name="l00994"></a>00994         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00995"></a>00995     }
<a name="l00996"></a>00996 
<a name="l00997"></a>00997     <span class="comment">// Attach the RIBD TLV</span>
<a name="l00998"></a>00998     <span class="keywordflow">if</span> (!tlv-&gt;add_tlv(response)) 
<a name="l00999"></a>00999     {
<a name="l01000"></a>01000         <span class="keyword">delete</span> response;
<a name="l01001"></a>01001         <span class="keyword">delete</span> tlv;
<a name="l01002"></a>01002         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01003"></a>01003     }
<a name="l01004"></a>01004 
<a name="l01005"></a>01005     <span class="comment">// empty response means state change</span>
<a name="l01006"></a>01006     <span class="keywordtype">bool</span> wait_info = local_response_.empty();
<a name="l01007"></a>01007 
<a name="l01008"></a>01008     <span class="comment">// Submit TLV as a bundle to the host bundle core</span>
<a name="l01009"></a>01009     <span class="keywordtype">bool</span> ok = send_tlv(tlv);
<a name="l01010"></a>01010 
<a name="l01011"></a>01011     <span class="keywordflow">if</span> (wait_info &amp;&amp; ok)
<a name="l01012"></a>01012         SET_STATE(WAIT_INFO);
<a name="l01013"></a>01013 
<a name="l01014"></a>01014     <span class="keywordflow">return</span> ok;
<a name="l01015"></a>01015 }
<a name="l01016"></a>01016 
<a name="l01017"></a>01017 <span class="keywordtype">bool</span>
<a name="l01018"></a>01018 Encounter::send_tlv(ProphetTLV* tlv)
<a name="l01019"></a>01019 {
<a name="l01020"></a>01020     <span class="comment">// weed out the oddball</span>
<a name="l01021"></a>01021     <span class="keywordflow">if</span> (tlv == NULL) <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01022"></a>01022 
<a name="l01023"></a>01023     <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_DEBUG,<span class="stringliteral">"send_tlv(%u) with %zu TLVs"</span>,tid_,tlv-&gt;size());
<a name="l01024"></a>01024 
<a name="l01025"></a>01025     <span class="comment">// create a new facade bundle with src and dst</span>
<a name="l01026"></a>01026     <span class="comment">// expire after HELLO_DEAD interval seconds</span>
<a name="l01027"></a>01027     <span class="comment">// (convert from 100's of ms)</span>
<a name="l01028"></a>01028     Bundle* b = oracle_-&gt;core()-&gt;create_bundle(
<a name="l01029"></a>01029                        tlv-&gt;source(),tlv-&gt;destination(),
<a name="l01030"></a>01030                        oracle_-&gt;params()-&gt;hello_dead() *
<a name="l01031"></a>01031                        oracle_-&gt;params()-&gt;hello_interval() / 10);
<a name="l01032"></a>01032 
<a name="l01033"></a>01033     <span class="comment">// create a buffer to move data between Prophet and bundle host, with</span>
<a name="l01034"></a>01034     <span class="comment">// some slush factor</span>
<a name="l01035"></a>01035     u_char* <a class="code" href="num2sdnv_8c.html#a81cdcc7ff6987bc85c073253e32715f">buf</a> = <span class="keyword">new</span> u_char[tlv-&gt;length() + 512];
<a name="l01036"></a>01036 
<a name="l01037"></a>01037     <span class="keywordtype">size_t</span> len = tlv-&gt;serialize(buf,tlv-&gt;length() + 512);
<a name="l01038"></a>01038     <span class="keywordtype">bool</span> ok = oracle_-&gt;core()-&gt;write_bundle(b,buf,len);
<a name="l01039"></a>01039 
<a name="l01040"></a>01040     <span class="comment">// clean up memory</span>
<a name="l01041"></a>01041     <span class="keyword">delete</span> [] buf;
<a name="l01042"></a>01042     <span class="keyword">delete</span> tlv;
<a name="l01043"></a>01043 
<a name="l01044"></a>01044     <span class="keywordflow">if</span> (ok)
<a name="l01045"></a>01045     {
<a name="l01046"></a>01046         ok = oracle_-&gt;core()-&gt;send_bundle(b, next_hop_);
<a name="l01047"></a>01047         <span class="keywordflow">if</span> (ok)
<a name="l01048"></a>01048         {
<a name="l01049"></a>01049             <span class="comment">// update timestamp</span>
<a name="l01050"></a>01050             data_sent_ = time(0);
<a name="l01051"></a>01051         }
<a name="l01052"></a>01052         <span class="keywordflow">else</span>
<a name="l01053"></a>01053             <a class="code" href="BundleOffer_8cc.html#259e390b81bb640af4691776b15a9116">LOG</a>(LOG_ERR,<span class="stringliteral">"failed to send TLV"</span>);
<a name="l01054"></a>01054     }
<a name="l01055"></a>01055 
<a name="l01056"></a>01056     <span class="keywordflow">return</span> ok;
<a name="l01057"></a>01057 }
<a name="l01058"></a>01058 
<a name="l01059"></a>01059 }; <span class="comment">// namespace prophet</span>
</pre></div></div>
<hr size="1"><address style="text-align: right;"><small>Generated on Fri Jan 30 09:26:56 2009 for DTN Reference Implementation by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.8 </small></address>
</body>
</html>