Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

srm-ssm.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 //
00003 // Copyright (c) 1997 by the University of Southern California
00004 // All rights reserved.
00005 //
00006 // Permission to use, copy, modify, and distribute this software and its
00007 // documentation in source and binary forms for non-commercial purposes
00008 // and without fee is hereby granted, provided that the above copyright
00009 // notice appear in all copies and that both the copyright notice and
00010 // this permission notice appear in supporting documentation. and that
00011 // any documentation, advertising materials, and other materials related
00012 // to such distribution and use acknowledge that the software was
00013 // developed by the University of Southern California, Information
00014 // Sciences Institute.  The name of the University may not be used to
00015 // endorse or promote products derived from this software without
00016 // specific prior written permission.
00017 //
00018 // THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about
00019 // the suitability of this software for any purpose.  THIS SOFTWARE IS
00020 // PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
00021 // INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00022 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00023 //
00024 // Other copyrights might apply to parts of this software and are so
00025 // noted when applicable.
00026 //
00027 // The code implements scalable session message. See
00028 // http://catarina.usc.edu/estrin/papers/infocom98/ssession.ps
00029 
00030 
00031 #ifndef lint
00032 static const char rcsid[] =
00033     "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/mcast/srm-ssm.cc,v 1.10 2000/09/01 03:04:07 haoboy Exp $ (USC/ISI)";
00034 #endif
00035 
00036 #include <stdlib.h>
00037 #include <assert.h>
00038 
00039 #include <stdio.h>
00040 
00041 #include "config.h"
00042 #include "tclcl.h"
00043 #include "agent.h"
00044 #include "packet.h"
00045 #include "ip.h"
00046 #include "srm.h"
00047 #include "srm-ssm.h"
00048 #include "trace.h"
00049 
00050 int hdr_srm_ext::offset_;
00051 static class SRMEXTHeaderClass : public PacketHeaderClass {
00052 public:
00053         SRMEXTHeaderClass() : PacketHeaderClass("PacketHeader/SRMEXT",
00054                                                 sizeof(hdr_srm_ext)) {
00055                 bind_offset(&hdr_srm_ext::offset_);
00056         }
00057 } class_srmexthdr;
00058 
00059 static class SSMSRMAgentClass : public TclClass {
00060 public:
00061   SSMSRMAgentClass() : TclClass("Agent/SRM/SSM") {}
00062   TclObject* create(int, const char*const*) {
00063     return (new SSMSRMAgent());
00064   }
00065 } class_srm_ssm_agent;
00066 
00067 
00068 SSMSRMAgent::SSMSRMAgent() 
00069   : SRMAgent(), glb_sessCtr_(-1), loc_sessCtr_(-1), rep_sessCtr_(-1)
00070 {
00071   bind("group_scope_",&groupScope_);
00072   bind("local_scope_",&localScope_);
00073   bind("scope_flag_",&scopeFlag_);
00074   bind("rep_id_", &repid_);
00075 }
00076 
00077 int SSMSRMAgent::command(int argc, const char*const* argv)
00078 {
00079   Tcl& tcl = Tcl::instance();
00080 
00081   if (strcmp(argv[1], "send") == 0) {
00082     if (strcmp(argv[2], "session") == 0) {
00083       send_sess();
00084       return TCL_OK;
00085     }
00086     if (strcmp(argv[2], "request") == 0) {
00087       int round = atoi(argv[3]);
00088       int sender = atoi(argv[4]);
00089       int msgid  = atoi(argv[5]);
00090       send_ctrl(SRM_RQST, round, sender, msgid, 0);
00091       return TCL_OK;
00092     }
00093     if (strcmp(argv[2], "repair") == 0) {
00094       int round = atoi(argv[3]);
00095       int sender = atoi(argv[4]);
00096       int msgid  = atoi(argv[5]);
00097       send_ctrl(SRM_REPR, round, sender, msgid, packetSize_);
00098       return TCL_OK;
00099     }
00100     tcl.resultf("%s: invalid send request %s", name_, argv[2]);
00101     return TCL_ERROR;
00102     /*
00103       #if 0
00104       fprintf(stdout,"%s: send request %s passed to srm_agent", 
00105       name_, argv[2]);
00106       #endif
00107       return SRMAgent::command(argc, argv);
00108       */
00109   }
00110 
00111   if (argc == 2) {
00112     if (strcmp(argv[1], "start") == 0) {
00113       sip_->sender_ = addr();
00114       sip_->distance_ = 0.0;
00115       /* sip_->repid_ = addr_;
00116          sip_->scopeFlag_ = SRM_GLOBAL;
00117          repid_ = addr_;
00118          scopeFlag_ = SRM_GLOBAL;
00119          */               
00120       groupScope_ = 32;
00121       senderFlag_ = 0;
00122       printf("%s is %d and rep-status %d\n", name_, addr(), scopeFlag_);
00123       return TCL_OK;
00124     }
00125     if (strcmp(argv[1], "ch-rep") == 0) {
00126       if(scopeFlag_ == SRM_GLOBAL) {
00127         sip_->repid_ = repid_ = addr();
00128         sip_->scopeFlag_ = SRM_GLOBAL;
00129       } else {
00130         sip_->repid_ = repid_;
00131         sip_->scopeFlag_ = SRM_LOCAL;
00132       }    
00133       return TCL_OK;
00134     }
00135     if (strcmp(argv[1], "distances?") == 0) {
00136       if (sip_->sender_ < 0) { // i.e. this agent is not
00137         tcl.result("");  //      yet active.
00138         return TCL_OK;
00139       }
00140       for (SRMinfo* sp = sip_; sp; sp = sp->next_) {
00141         if((sp->distanceFlag_ == REP_DISTANCE) || 
00142            (sp->distanceFlag_ == SELF_DISTANCE)) {
00143           
00144           tcl.resultf("%s %d %f", tcl.result(),
00145                       sp->sender_, sp->distance_);
00146         } else { /* Return reps distance */
00147           SRMinfo* rsp = get_state(sp->repid_);
00148           tcl.resultf("%s %d %f", tcl.result(),
00149                       sp->sender_, rsp->distance_);
00150         }
00151       }
00152       return TCL_OK;
00153     }
00154     
00155   }
00156   if (argc == 3) {
00157     if (strcmp(argv[1], "distance?") == 0) {
00158       int sender = atoi(argv[2]);
00159       SRMinfo* sp = get_state(sender);
00160       if((sp->distanceFlag_ == REP_DISTANCE) || 
00161          (sp->distanceFlag_ == SELF_DISTANCE)) {
00162         tcl.resultf("%f", sp->distance_);
00163       } else { /* Return reps distance */
00164         SRMinfo* rsp = get_state(sp->repid_);
00165         tcl.resultf("%f", rsp->distance_);
00166       }
00167       return TCL_OK;
00168     }
00169   }
00170   return SRMAgent::command(argc, argv);
00171 }
00172 
00173 void SSMSRMAgent::recv(Packet* p, Handler* h)
00174 {
00175   hdr_ip*  ih = hdr_ip::access(p);
00176   hdr_srm* sh = hdr_srm::access(p);
00177   hdr_srm_ext* seh = hdr_srm_ext::access(p);
00178         
00179   if (ih->daddr() == 0) {
00180     // Packet from local agent.  Add srm headers, set dst, and fwd
00181     sh->type() = SRM_DATA;
00182     sh->sender() = addr();
00183     sh->seqnum() = ++dataCtr_;
00184     seh->repid() = repid_;
00185     ih->dst() = dst_;
00186     ih->src() = here_;
00187     target_->recv(p, h);
00188   } else {
00189 
00190 #if 0
00191     static char *foo[] = {"NONE", "DATA", "SESS", "RQST", "REPR"};
00192     fprintf(stdout, "%7.4f %s %d  recvd SRM_%s <%d, %d> from %d\n",
00193             Scheduler::instance().clock(), name_, addr_, foo[sh->type()],
00194             sh->sender(), sh->seqnum(), ih->src());
00195     fflush(stdout);
00196 #endif
00197                 
00198     switch (sh->type()) {
00199     case SRM_DATA:
00200       recv_data(sh->sender(), sh->seqnum(), seh->repid(), p->accessdata());
00201       Packet::free(p);
00202       break;
00203     case SRM_RQST:
00204       recv_rqst(ih->saddr(), sh->round(), sh->sender(), sh->seqnum(),
00205                 seh->repid());  
00206       Packet::free(p);
00207       break;
00208     case SRM_REPR:
00209       recv_repr(sh->round(), sh->sender(), sh->seqnum(), p->accessdata());
00210       Packet::free(p);
00211       break;
00212     case SRM_SESS:
00213       // This seqnum() is the session sequence number,
00214       // not the data packet sequence numbers seen before.
00215       // Send the whole pkt for ttl etc..
00216       recv_sess(sh->seqnum(), (int*) p->accessdata(), p);
00217       break;
00218     }
00219   }
00220 }
00221 
00222 
00223 void SSMSRMAgent::recv_data(int sender, int id, int repid, u_char* data)
00224 {
00225   SRMinfo* sp = get_state(sender);
00226   /* Just store the repid and call srmagent recv_data */
00227   sp->repid_ = repid;
00228   SRMAgent::recv_data(sender,id,data);
00229 }
00230 
00231 void SSMSRMAgent::send_ctrl(int type, int round, int sender, int msgid, int size)
00232 {
00233   Packet* p = Agent::allocpkt();
00234   hdr_srm* sh = hdr_srm::access(p);
00235   hdr_srm_ext* seh = hdr_srm_ext::access(p);
00236   sh->type() = type;
00237   sh->sender() = sender;
00238   sh->seqnum() = msgid; 
00239   sh->round() = round;
00240   seh->repid() = repid_;  /* For ctrl messages this is your own repid */
00241 
00242   hdr_cmn* ch = hdr_cmn::access(p);
00243   ch->size() = sizeof(hdr_srm) + size;
00244   target_->recv(p, (Handler*)NULL);
00245 }
00246 
00247 void SSMSRMAgent::recv_rqst(int requestor, int round, int sender, 
00248                             int msgid, int repid)
00249 {
00250   //Tcl& tcl = Tcl::instance();
00251   SRMinfo* rsp = get_state(requestor);
00252   rsp->repid_ = repid;
00253   SRMAgent::recv_rqst(requestor,round, sender,msgid);
00254 }
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 void SSMSRMAgent::send_sess() 
00263 {
00264   if (scopeFlag_ == SRM_GLOBAL) {
00265     send_glb_sess();
00266     send_rep_sess();
00267   } else {
00268     send_loc_sess();
00269   }
00270 //   timeout_info();
00271 }
00272 
00273 #define SESSINFO_SIZE   5
00274 #define SESS_CONST      2
00275 
00276 void SSMSRMAgent::send_glb_sess()
00277 {
00278         int size = (SESS_CONST + groupSize_ * SESSINFO_SIZE) * sizeof(int);  
00279         /* Currently do extra allocation, later change */
00280         int     num_entries;
00281         Packet* p = Agent::allocpkt(size);
00282         hdr_srm* sh = hdr_srm::access(p);
00283         hdr_srm_ext* seh = hdr_srm_ext::access(p);
00284 
00285 #if 0
00286         printf("sending global session message\n");
00287 #endif
00288         sh->type() = SRM_SESS;
00289         sh->sender() = addr();
00290         sh->seqnum() = ++glb_sessCtr_;
00291         seh->repid() = repid_;
00292 
00293         int* data = (int*) p->accessdata();
00294         *data++ = groupSize_;
00295         *data++ = SRM_GLOBAL;
00296         num_entries = 0;
00297         for (SRMinfo* sp = sip_; sp; sp = sp->next_) {
00298           /* Global Session Message has information about Senders/reps */
00299            if ((sp->senderFlag_ || 
00300                 (sp->scopeFlag_ == SRM_GLOBAL) ||
00301                 (sp->sender_ == addr()))
00302                && (is_active(sp))) {      
00303                 *data++ = sp->sender_;
00304                 *data++ = sp->ldata_;
00305                 *data++ = sp->recvTime_;
00306                 *data++ = sp->sendTime_;
00307                 *data++ = sp->repid_;
00308                 num_entries++;
00309               }
00310         }
00311         data = (int*) p->accessdata();
00312         data[0] = num_entries;
00313         data[1] = SRM_GLOBAL;
00314         size = (SESS_CONST + num_entries * SESSINFO_SIZE) * sizeof(int);
00315         data[5] = (int) (Scheduler::instance().clock()*1000);
00316 
00317         hdr_cmn* ch = hdr_cmn::access(p);
00318         ch->size() += size+ sizeof(hdr_srm); /* Add size of srm_hdr_ext */
00319         hdr_ip*  ih = hdr_ip::access(p);
00320         ih->ttl() = groupScope_;
00321         // Currently put this to distinguish various session messages
00322         ih->flowid() = SRM_GLOBAL;
00323         seh->ottl() = groupScope_;
00324         target_->recv(p, (Handler*)NULL);
00325 }
00326 
00327 
00328 void SSMSRMAgent::send_loc_sess()
00329 {
00330         int size = (SESS_CONST + groupSize_ * SESSINFO_SIZE) * sizeof(int);  
00331         /* Currently do extra allocation, later change */
00332         int     num_entries;
00333         Packet* p = Agent::allocpkt(size);
00334         hdr_srm* sh = hdr_srm::access(p);
00335         hdr_srm_ext* seh = hdr_srm_ext::access(p);
00336         sh->type() = SRM_SESS;
00337         sh->sender() = addr();
00338         sh->seqnum() = ++loc_sessCtr_;
00339         seh->repid() = repid_;
00340 #if 0
00341         printf("sending local session message\n");
00342 #endif
00343         int* data = (int*) p->accessdata();
00344         //int* tmp_data = (int*) p->accessdata();
00345         *data++ = groupSize_;
00346         *data++ = SRM_LOCAL;
00347         num_entries = 0;
00348         for (SRMinfo* sp = sip_; sp; sp = sp->next_) {
00349           /* Local Session Message has information 
00350              about Senders/other locals */
00351           if ((sp->senderFlag_ || 
00352                (sp->scopeFlag_ == SRM_LOCAL) ||
00353                (sp->distanceFlag_ = SELF_DISTANCE) || 
00354                /* For the reps that I am hearing from */
00355                (sp->sender_ == addr()) ||   
00356                // just in case, I have not set the flags properly, 
00357                // one entry has to be there
00358                (repid_ == sp->sender_)) 
00359               && (is_active(sp))) {      
00360             *data++ = sp->sender_;
00361             *data++ = sp->ldata_;
00362             *data++ = sp->recvTime_;
00363             *data++ = sp->sendTime_;
00364             *data++ = sp->repid_;
00365             num_entries++;
00366           }
00367         }
00368         data = (int*) p->accessdata();
00369         data[0] = num_entries;
00370         data[1] = SRM_LOCAL;
00371         size = (SESS_CONST + num_entries * SESSINFO_SIZE) * sizeof(int);
00372         data[5] = (int) (Scheduler::instance().clock()*1000);
00373 
00374         hdr_cmn* ch = hdr_cmn::access(p);
00375         ch->size() += size+ sizeof(hdr_srm);
00376         hdr_ip*  ih = hdr_ip::access(p);
00377         ih->ttl() = localScope_;
00378         // Currently put this to distinguish various session messages
00379         ih->flowid() = SRM_LOCAL;
00380         seh->ottl() = localScope_;
00381         target_->recv(p, (Handler*)NULL);
00382 }
00383 
00384 
00385 void SSMSRMAgent::send_rep_sess()
00386 {
00387         int size = (SESS_CONST + groupSize_ * SESSINFO_SIZE) * sizeof(int);  
00388         /* Currently do extra allocation, later change */
00389         int     num_entries, num_local_members;
00390         Packet* p = Agent::allocpkt(size);
00391         hdr_srm* sh = hdr_srm::access(p);
00392         hdr_srm_ext* seh = hdr_srm_ext::access(p);
00393         sh->type() = SRM_SESS;
00394         sh->sender() = addr();
00395         sh->seqnum() = ++rep_sessCtr_;
00396         seh->repid() = repid_;
00397 #if 0
00398         printf("sending rep_info session message\n");
00399 #endif
00400         int* data = (int*) p->accessdata();
00401         *data++ = groupSize_;
00402         *data++ = SRM_RINFO;
00403         num_entries = 0;
00404         num_local_members = 0;
00405         for (SRMinfo* sp = sip_; sp; sp = sp->next_) {
00406           if (sp->activeFlag_ == ACTIVE) {
00407           /* Rep info has distance to others reps and 
00408              timestamps for everyone */
00409                 *data++ = sp->sender_;
00410                 *data++ = sp->ldata_;
00411                 if (sp->scopeFlag_ == SRM_GLOBAL) {
00412                   *data++ = (int) (sp->distance_*1000);
00413                   data++;
00414                 } else { 
00415                   // Put a check here for only people I have heard from.??
00416                   *data++ = sp->recvTime_;
00417                   *data++ = sp->sendTime_;
00418                   num_local_members++;
00419                 }
00420                 *data++ = sp->repid_;
00421                 num_entries++;
00422               }
00423         }
00424         if (num_local_members <= 0) {
00425           Packet::free(p);
00426           return;
00427         }
00428         data = (int*) p->accessdata();
00429         data[0] = num_entries;
00430         data[1] = SRM_RINFO;
00431         size = (SESS_CONST + num_entries * SESSINFO_SIZE) * sizeof(int);  
00432         data[5] = (int) (Scheduler::instance().clock()*1000);
00433 
00434         hdr_cmn* ch = hdr_cmn::access(p);
00435         ch->size() += size+ sizeof(hdr_srm);
00436         hdr_ip*  ih = hdr_ip::access(p);
00437         ih->ttl() = localScope_;
00438         // Currently put this to distinguish various session messages
00439         ih->flowid() = SRM_RINFO;
00440         seh->ottl() = localScope_;
00441         target_->recv(p, (Handler*)NULL);
00442 }
00443 
00444 
00445 #define GET_SESSION_INFO                        \
00446         sender = *data++;                       \
00447         dataCnt = *data++;                      \
00448         rtime = *data++;                        \
00449         stime = *data++;                         \
00450         repid = *data++;                        \
00451         // printf("s:%d, d:%d, rt:%d, st:%d, rep:%d\n",sender,
00452         // dataCnt,rtime,stime,repid)
00453 
00454 
00455 
00456 void SSMSRMAgent::recv_sess(int sessCtr, int* data, Packet* p)
00457 {
00458   int type = data[1];
00459 
00460   switch (type) {
00461   case SRM_GLOBAL :
00462     recv_glb_sess(sessCtr,data,p);
00463     break;
00464   case SRM_LOCAL :
00465     recv_loc_sess(sessCtr,data,p);
00466     break;
00467   case SRM_RINFO :    
00468     if (scopeFlag_ == SRM_GLOBAL) return;
00469     recv_rep_sess(sessCtr,data,p);
00470     break;
00471   }
00472   Packet::free(p);
00473 }
00474 
00475 void SSMSRMAgent::recv_glb_sess(int sessCtr, int* data, Packet* p)
00476 {
00477   Tcl& tcl = Tcl::instance();
00478   SRMinfo* sp;
00479   int ttl;
00480 
00481   hdr_ip*  ih = hdr_ip::access(p);
00482   hdr_srm_ext* seh = hdr_srm_ext::access(p);
00483   ttl = seh->ottl() - ih->ttl();
00484         
00485   int sender, dataCnt, rtime, stime,repid;
00486   int now, sentAt, sentBy;
00487   int cnt = *data++;
00488   //int type = *data++;
00489   int i;
00490 
00491   // data = data + SESS_CONST;  
00492   /* As as included type of session message also */
00493   /* The first block contains the sender's own state */
00494   GET_SESSION_INFO;
00495   if (sender == addr())                 
00496     // sender's own session message
00497     return;
00498   if (seh->repid() != repid) {
00499     fprintf(stdout,"%f Recvd a glb-sess with diff header(%d) != inside(%d)\n",
00500             Scheduler::instance().clock(),seh->repid(),repid);
00501     /* abort(); */
00502     return;
00503   }
00504   if (sender != repid) {
00505     fprintf(stdout,"%f Recvd a glb-sess with repid(%d) != address(%d)\n",
00506             Scheduler::instance().clock(),repid,sender);
00507     /* abort(); */
00508     return;
00509   }
00510    
00511   sp = get_state(sender);
00512   if (sp->lglbsess_ > sessCtr)          // older session message recd.
00513     return;
00514 #if 0
00515   fprintf(stdout,"%s recv-gsess from %d\n",name_,sender);
00516 #endif 
00517   tcl.evalf("%s recv-gsess %d %d", name_, sender, ttl);
00518   
00519   if (sp->scopeFlag_ != SRM_GLOBAL) {
00520     sp->scopeFlag_ = SRM_GLOBAL;
00521   }
00522   sp->repid_ = repid;
00523   
00524   now = (int) (Scheduler::instance().clock() * 1000);
00525   sentBy = sender;                      // to later compute rtt
00526   sentAt = stime;
00527         
00528   sp->lglbsess_ = sessCtr;
00529   sp->recvTime_ = now;
00530   sp->sendTime_ = stime;
00531   for (i = sp->ldata_ + 1; i <= dataCnt; i++)
00532     if (! sp->ifReceived(i))
00533       tcl.evalf("%s request %d %d", name_, sender, i, sp->repid_);
00534   if (sp->ldata_ < dataCnt)
00535     sp->ldata_ = dataCnt;
00536   
00537   for (i = 1; i < cnt; i++) {
00538     GET_SESSION_INFO;
00539     if (sender == addr() && now) {
00540       int rtt = (now - sentAt) + (rtime - stime);
00541       sp = get_state(sentBy);
00542       sp->distance_ = (double) rtt / 2 / 1000;
00543       sp->distanceFlag_ = SELF_DISTANCE;
00544 #if 0
00545       fprintf(stderr,
00546               "%7.4f %s compute distance to %d: %f\n",
00547               Scheduler::instance().clock(), name_,
00548               sentBy, sp->distance_);
00549 #endif
00550       continue;
00551     }
00552     sp = get_state(sender);
00553     for (int j = sp->ldata_ + 1; j <= dataCnt; j++)
00554       if (! sp->ifReceived(j))
00555         tcl.evalf("%s request %d %d", name_, sender, j, sp->repid_);
00556     if (sp->ldata_ < dataCnt)
00557       sp->ldata_ = dataCnt;
00558   }             
00559 }
00560 
00561 
00562 void SSMSRMAgent::recv_loc_sess(int sessCtr, int* data, Packet* p)
00563 {
00564   Tcl& tcl = Tcl::instance();
00565   SRMinfo* sp;
00566   int ttl;
00567 
00568   hdr_ip*  ih = hdr_ip::access(p);
00569   hdr_srm_ext* seh = hdr_srm_ext::access(p);
00570   ttl = seh->ottl() - ih->ttl();
00571   
00572   int sender, dataCnt, rtime, stime,repid;
00573   int now, sentAt, sentBy;
00574   int cnt = *data++;
00575   /*int type = * */data++;
00576   int i;
00577 
00578   // data = data + SESS_CONST;  
00579   /* As as included type of session message also */
00580 
00581   /* The first block contains the sender's own state */
00582   GET_SESSION_INFO;
00583   if (sender == addr())                 // sender's own session message
00584     return;
00585   
00586   sp = get_state(sender);
00587   if (sp->llocsess_ > sessCtr)          // older session message recd.
00588     return;
00589   if (sp->scopeFlag_ != SRM_LOCAL) {
00590     sp->scopeFlag_ = SRM_LOCAL;
00591     // Also put a check if this is my child
00592   }
00593   sp->repid_ = repid;
00594 
00595 #if 0
00596   fprintf(stdout,"%s recv-lsess from %d\n",name_,sender);
00597 #endif 
00598   tcl.evalf("%s recv-lsess %d %d %d", name_, sender, repid, ttl);
00599   
00600   now = (int) (Scheduler::instance().clock() * 1000);
00601   sentBy = sender;                      // to later compute rtt
00602   sentAt = stime;
00603         
00604   sp->llocsess_ = sessCtr;
00605   sp->recvTime_ = now;
00606   sp->sendTime_ = stime;
00607   for (i = sp->ldata_ + 1; i <= dataCnt; i++)
00608     if (! sp->ifReceived(i))
00609       tcl.evalf("%s request %d %d", name_, sender, i, sp->repid_);
00610   if (sp->ldata_ < dataCnt)
00611     sp->ldata_ = dataCnt;
00612   
00613   for (i = 1; i < cnt; i++) {
00614     GET_SESSION_INFO;
00615     if (sender == addr() && now) {
00616       int rtt = (now - sentAt) + (rtime - stime);
00617       sp = get_state(sentBy);
00618       sp->distance_ = (double) rtt / 2 / 1000;
00619       sp->distanceFlag_ = SELF_DISTANCE;
00620 #if 0
00621       fprintf(stderr,
00622               "%7.4f %s compute distance to %d: %f\n",
00623               Scheduler::instance().clock(), name_,
00624               sentBy, sp->distance_);
00625 #endif
00626       continue;
00627     }
00628     sp = get_state(sender);
00629     for (int j = sp->ldata_ + 1; j <= dataCnt; j++)
00630       if (! sp->ifReceived(j))
00631         tcl.evalf("%s request %d %d", name_, sender, j, sp->repid_);
00632     if (sp->ldata_ < dataCnt)
00633       sp->ldata_ = dataCnt;
00634   }             
00635 }
00636 
00637 
00638 // For the global members the repid == addr
00639 
00640 
00641 void SSMSRMAgent::recv_rep_sess(int sessCtr, int* data, Packet*)
00642 {
00643   Tcl& tcl = Tcl::instance();
00644   SRMinfo* sp;
00645   
00646   int sender, dataCnt, rtime, stime,repid;
00647   int now, sentAt, sentBy;
00648   int cnt = *data++;
00649   /*int type = **/data++;
00650   int i;
00651 
00652   //data = data + SESS_CONST;  
00653   /* As as included type of session message also */
00654 
00655   /* The first block contains the sender's own state */
00656   GET_SESSION_INFO;
00657   if (sender == addr())                 // sender's own session message
00658     return;
00659   if (sender != repid_)                 // not from my rep
00660     return;
00661   if (sender != repid) {
00662     fprintf(stdout,"Recvd a rep-sess with repid(%d) != address(%d)\n",
00663             repid,sender);
00664     abort();
00665   }
00666   sp = get_state(sender);
00667   if (sp->lrepsess_ > sessCtr)          // older session message recd.
00668     return;
00669   if (sp->scopeFlag_ != SRM_GLOBAL)      // Should I change the repid also??
00670     sp->scopeFlag_ = SRM_GLOBAL;
00671   
00672   now = (int) (Scheduler::instance().clock() * 1000);
00673   sentBy = sender;                      // to later compute rtt
00674   sentAt = stime;
00675         
00676   sp->lrepsess_ = sessCtr;
00677   sp->recvTime_ = now;
00678   sp->sendTime_ = stime;
00679   for (i = sp->ldata_ + 1; i <= dataCnt; i++)
00680     if (! sp->ifReceived(i))
00681       tcl.evalf("%s request %d %d", name_, sender, i, sp->repid_);
00682   if (sp->ldata_ < dataCnt)
00683     sp->ldata_ = dataCnt;
00684         
00685   for (i = 1; i < cnt; i++) {
00686     GET_SESSION_INFO;
00687     if (sender == addr() && now) {
00688       int rtt = (now - sentAt) + (rtime - stime);
00689       sp = get_state(sentBy);
00690       sp->distance_ = (double) rtt / 2 / 1000;
00691       sp->distanceFlag_ = SELF_DISTANCE;
00692 #if 0
00693       fprintf(stderr,
00694               "%7.4f %s compute distance to %d: %f\n",
00695               Scheduler::instance().clock(), name_,
00696               sentBy, sp->distance_);
00697 #endif
00698       continue;
00699     }
00700     if ((sender == repid) && (sender != sentBy)) {
00701       sp = get_state(sender);
00702       if (!(is_active(sp) && (sp->distanceFlag_ == SELF_DISTANCE))) {
00703         sp->distance_ = (double) rtime/1000;   
00704         /* As for global members this is distance */
00705         sp->distanceFlag_ = REP_DISTANCE;
00706         /* ?? What if I am hearing from this guy already */
00707       }
00708     }
00709     sp = get_state(sender);
00710     for (int j = sp->ldata_ + 1; j <= dataCnt; j++)
00711       if (! sp->ifReceived(j))
00712         tcl.evalf("%s request %d %d", name_, sender, j, sp->repid_);
00713     if (sp->ldata_ < dataCnt)
00714       sp->ldata_ = dataCnt;
00715   }             
00716 }
00717 
00718 
00719 
00720 #define sessionDelay   1000
00721 
00722 
00723 void SSMSRMAgent::timeout_info()
00724 {
00725   int now;
00726   now = (int) (Scheduler::instance().clock() * 1000);
00727   for (SRMinfo* sp = sip_->next_; sp; sp = sp->next_) {
00728     if ((now - sp->recvTime_) >= 3*sessionDelay) {
00729       sp->activeFlag_ = INACTIVE;
00730       groupSize_--;
00731     }
00732 
00733   }
00734 }
00735 
00736 int SSMSRMAgent::is_active(SRMinfo *sp)
00737 {
00738   int now;
00739   now = (int) (Scheduler::instance().clock() * 1000);
00740   if ((sp->sender_ != addr()) && ((now - sp->recvTime_) >= 3*sessionDelay)) {
00741     return 0;
00742   } else {
00743     return 1;
00744   }
00745 }

Generated on Tue Apr 20 12:14:33 2004 for NS2.26SourcesOriginal by doxygen 1.3.3