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 #include <assert.h>
00033 #include <math.h>
00034 #include <stdio.h>
00035 #include <signal.h>
00036 #include <float.h>
00037
00038 #include "object.h"
00039 #include "agent.h"
00040 #include "packet.h"
00041 #include "ip.h"
00042 #include "classifier.h"
00043 #include "connector.h"
00044 #include "delay.h"
00045 #include "queue.h"
00046 #include "scheduler.h"
00047 #include "random.h"
00048
00049 #include "hdr_qs.h"
00050 #include "qsagent.h"
00051 #include <fstream>
00052
00053 static class QSAgentClass : public TclClass {
00054 public:
00055 QSAgentClass() : TclClass("Agent/QSAgent") {}
00056 TclObject* create(int, const char*const*) {
00057 return (new QSAgent);
00058 }
00059 } class_QSAgent;
00060
00061 QSAgent::QSAgent():Agent(PT_TCP), old_classifier_(NULL), qs_enabled_(1),
00062 qs_timer_(this)
00063 {
00064
00065 prev_int_aggr_ = 0;
00066 aggr_approval_ = 0;
00067
00068 bind("qs_enabled_", &qs_enabled_);
00069 bind("old_classifier_", &old_classifier_);
00070 bind("state_delay_", &state_delay_);
00071 bind("alloc_rate_", &alloc_rate_);
00072 bind("max_rate_", &max_rate_);
00073 bind("mss_", &mss_);
00074
00075 qs_timer_.resched(state_delay_);
00076
00077 }
00078
00079 QSAgent::~QSAgent()
00080 {
00081 }
00082
00083 int QSAgent::command(int argc, const char*const* argv)
00084 {
00085 return (Agent::command(argc,argv));
00086 }
00087
00088 void QSAgent::recv(Packet* packet, Handler*)
00089 {
00090 int app_rate;
00091 double avail_bw, util;
00092 Classifier * pkt_target;
00093 Tcl& tcl = Tcl::instance();
00094 char qname[64], lname[64];
00095
00096 hdr_qs *qsh = hdr_qs::access(packet);
00097 hdr_ip *iph = hdr_ip::access(packet);
00098
00099 if (old_classifier_)
00100 pkt_target = (Classifier *)TclObject::lookup(old_classifier_->name());
00101
00102 if (qs_enabled_) {
00103
00104
00105
00106 if (qsh->flag() == QS_REQUEST && qsh->rate() > 0 && iph->daddr() != addr()) {
00107 sprintf (qname, "[Simulator instance] get-queue %d %d", addr(), iph->daddr());
00108 tcl.evalc (qname);
00109 Queue * queue = (Queue *) TclObject::lookup(tcl.result());
00110
00111 sprintf (lname, "[Simulator instance] get-link %d %d", addr(), iph->daddr());
00112 tcl.evalc (lname);
00113 LinkDelay * link = (LinkDelay *) TclObject::lookup(tcl.result());
00114
00115 if (link != NULL && queue != NULL) {
00116 util = queue->utilization();
00117 avail_bw = link->bandwidth() / 8 * (1 - util) / mss_;
00118 avail_bw -= (prev_int_aggr_ + aggr_approval_);
00119 avail_bw *= alloc_rate_;
00120 printf("%d: requested = %d, available = %f\n", addr(), qsh->rate(), avail_bw);
00121 app_rate = (avail_bw < (double)qsh->rate()) ? (int) avail_bw : qsh->rate();
00122 app_rate = (app_rate < max_rate_) ? app_rate : max_rate_;
00123 if (app_rate > 0) {
00124 aggr_approval_ += app_rate;
00125 qsh->ttl() -= 1;
00126 qsh->rate() = app_rate;
00127 }
00128 else {
00129 qsh->rate() = 0;
00130 qsh->flag() = QS_DISABLE;
00131 }
00132 }
00133 }
00134 }
00135
00136 #if 0
00137 if (qs_enabled_) {
00138
00139
00140
00141 if (qsh->flag() == QS_REQUEST && qsh->rate() > 0 && iph->daddr() != addr()) {
00142 Connector * head = (Connector *) pkt_target->find(packet);
00143 if (head) {
00144
00145 Connector * enqT = (Connector *) head->target();
00146 if (enqT) {
00147
00148 Queue * queue = (Queue *) enqT->target();
00149 if (queue) {
00150
00151 Connector * deqT = (Connector *) queue->target();
00152 if (deqT) {
00153
00154 LinkDelay * link = (LinkDelay *) deqT->target();
00155 if (link) {
00156 util = queue->utilization();
00157 avail_bw = link->bandwidth() / 8 * (1 - util) / mss_;
00158 avail_bw -= (prev_int_aggr_ + aggr_approval_);
00159 avail_bw *= alloc_rate_;
00160 printf("%d: requested = %d, available = %f\n", addr(), qsh->rate(), avail_bw);
00161 app_rate = (avail_bw < (double)qsh->rate()) ? (int) avail_bw : qsh->rate();
00162 app_rate = (app_rate < max_rate_) ? app_rate : max_rate_;
00163 if (app_rate > 0) {
00164 aggr_approval_ += app_rate;
00165 qsh->ttl() -= 1;
00166 qsh->rate() = app_rate;
00167 }
00168 else {
00169 qsh->rate() = 0;
00170 qsh->flag() = QS_DISABLE;
00171 }
00172 }
00173 }
00174 }
00175 }
00176 }
00177 }
00178 }
00179 #endif
00180
00181 if (pkt_target)
00182 pkt_target->recv(packet, 0);
00183 else {
00184 printf("%d, don't know what to do with the packet\n", addr());
00185 Packet::free(packet);
00186 }
00187
00188 return;
00189
00190 }
00191
00192 void QSTimer::expire(Event *e) {
00193
00194 qs_handle_->prev_int_aggr_ = qs_handle_->aggr_approval_;
00195 qs_handle_->aggr_approval_ = 0;
00196
00197 this->resched(qs_handle_->state_delay_);
00198
00199 }