00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef ns_srm_h
00034 #define ns_srm_h
00035
00036 #include <math.h>
00037 #include <tcl.h>
00038
00039 #include "config.h"
00040
00041 #include "srm-state.h"
00042 #include "srm-headers.h"
00043
00044 class SRMAgent : public Agent {
00045 protected:
00046 int dataCtr_;
00047 int sessCtr_;
00048 int packetSize_;
00049 SRMinfo* sip_;
00050 Tcl_HashTable* siphash_;
00051 int groupSize_;
00052 int seqno_;
00053 int app_fid_;
00054 packet_t app_type_;
00055
00056 virtual void start() {
00057 int new_entry = 0;
00058
00059 sip_->sender_ = addr();
00060 sip_->distance_ = 0.0;
00061 sip_->next_ = NULL;
00062
00063 siphash_ = new Tcl_HashTable;
00064 Tcl_InitHashTable(siphash_, TCL_ONE_WORD_KEYS);
00065 Tcl_HashEntry* he = Tcl_CreateHashEntry(siphash_,
00066 (char*) addr(),
00067 &new_entry);
00068 Tcl_SetHashValue(he, (ClientData*)sip_);
00069 groupSize_++;
00070 }
00071 SRMinfo* get_state(int sender) {
00072 assert(siphash_);
00073
00074 int new_entry = 0;
00075 Tcl_HashEntry* he = Tcl_CreateHashEntry(siphash_,
00076 (char*) sender,
00077 &new_entry);
00078 if (new_entry) {
00079 groupSize_++;
00080 SRMinfo* tmp = new SRMinfo(sender);
00081 tmp->next_ = sip_->next_;
00082 sip_->next_ = tmp;
00083 Tcl_SetHashValue(he, (ClientData*)tmp);
00084 }
00085 return (SRMinfo*)Tcl_GetHashValue(he);
00086 }
00087 virtual void cleanup () {
00088 Tcl_DeleteHashTable(siphash_);
00089 }
00090
00091 virtual void addExtendedHeaders(Packet*) {}
00092 virtual void parseExtendedHeaders(Packet*) {}
00093 virtual int request(SRMinfo* sp, int hi) {
00094 int miss = 0;
00095 if (sp->ldata_ >= hi)
00096 return miss;
00097
00098 int maxsize = ((int)log10(hi + 1) + 2) * (hi - sp->ldata_);
00099
00100
00101
00102
00103 char* msgids = new char[maxsize + 1];
00104 *msgids = '\0';
00105 for (int i = sp->ldata_ + 1; i <= hi; i++)
00106 if (! sp->ifReceived(i)) {
00107 (void) sprintf(msgids, "%s %d", msgids, i);
00108 miss++;
00109 }
00110 assert(miss);
00111 Tcl::instance().evalf("%s request %d %s", name_,
00112 sp->sender_, msgids);
00113 delete[] msgids;
00114 return miss;
00115 }
00116
00117 virtual void recv_data(int sender, int msgid, u_char* data);
00118 virtual void recv_repr(int round, int sender, int msgid, u_char* data);
00119 virtual void recv_rqst(int requestr, int round, int sender, int msgid);
00120 virtual void recv_sess(Packet*, int sessCtr, int* data);
00121
00122 virtual void send_ctrl(int typ, int rnd, int sndr, int msgid, int sz);
00123 virtual void send_sess();
00124 public:
00125 SRMAgent();
00126 virtual ~SRMAgent();
00127 virtual int command(int argc, const char*const* argv);
00128 virtual void recv(Packet* p, Handler* h);
00129 virtual void sendmsg(int nbytes, const char *flags = 0);
00130 virtual void send(int nbytes) { sendmsg(nbytes); }
00131 };
00132
00133 class ASRMAgent : public SRMAgent {
00134 double pdistance_;
00135 int requestor_;
00136 public:
00137 ASRMAgent() {
00138 bind("pdistance_", &pdistance_);
00139 bind("requestor_", &requestor_);
00140 }
00141 protected:
00142 virtual void addExtendedHeaders(Packet* p) {
00143 SRMinfo* sp;
00144 hdr_srm* sh = hdr_srm::access(p);
00145 hdr_asrm* seh = hdr_asrm::access(p);
00146 switch (sh->type()) {
00147 case SRM_RQST:
00148 sp = get_state(sh->sender());
00149 seh->distance() = sp->distance_;
00150 break;
00151 case SRM_REPR:
00152 sp = get_state(requestor_);
00153 seh->distance() = sp->distance_;
00154 break;
00155 case SRM_DATA:
00156 case SRM_SESS:
00157 seh->distance() = 0.;
00158 break;
00159 default:
00160 assert(0);
00161
00162 }
00163 SRMAgent::addExtendedHeaders(p);
00164 }
00165 virtual void parseExtendedHeaders(Packet* p) {
00166 SRMAgent::parseExtendedHeaders(p);
00167 hdr_asrm* seh = hdr_asrm::access(p);
00168 pdistance_ = seh->distance();
00169 }
00170 };
00171
00172 #endif