tbf.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:4k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) Xerox Corporation 1997. All rights reserved.
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License as published by the
  7.  * Free Software Foundation; either version 2 of the License, or (at your
  8.  * option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18.  *
  19.  * Linking this file statically or dynamically with other modules is making
  20.  * a combined work based on this file.  Thus, the terms and conditions of
  21.  * the GNU General Public License cover the whole combination.
  22.  *
  23.  * In addition, as a special exception, the copyright holders of this file
  24.  * give you permission to combine this file with free software programs or
  25.  * libraries that are released under the GNU LGPL and with code included in
  26.  * the standard release of ns-2 under the Apache 2.0 license or under
  27.  * otherwise-compatible licenses with advertising requirements (or modified
  28.  * versions of such code, with unchanged license).  You may copy and
  29.  * distribute such a system following the terms of the GNU GPL for this
  30.  * file and the licenses of the other code concerned, provided that you
  31.  * include the source code of that other code when and as the GNU GPL
  32.  * requires distribution of source code.
  33.  *
  34.  * Note that people who make modified versions of this file are not
  35.  * obligated to grant this special exception for their modified versions;
  36.  * it is their choice whether to do so.  The GNU General Public License
  37.  * gives permission to release a modified version without this exception;
  38.  * this exception also makes it possible to release a modified version
  39.  * which carries forward this exception.
  40.  */
  41. /* Token Bucket filter which has  3 parameters :
  42.    a. Token Generation rate
  43.    b. Token bucket depth
  44.    c. Max. Queue Length (a finite length would allow this to be used as  policer as packets are dropped after queue gets full)
  45.    */
  46. #include "connector.h" 
  47. #include "packet.h"
  48. #include "queue.h"
  49. #include "tbf.h"
  50. TBF::TBF() :tokens_(0),tbf_timer_(this), init_(1)
  51. {
  52. q_=new PacketQueue();
  53. bind_bw("rate_",&rate_);
  54. bind("bucket_",&bucket_);
  55. bind("qlen_",&qlen_);
  56. }
  57. TBF::~TBF()
  58. {
  59. if (q_->length() != 0) {
  60. //Clear all pending timers
  61. tbf_timer_.cancel();
  62. //Free up the packetqueue
  63. for (Packet *p=q_->head();p!=0;p=p->next_) 
  64. Packet::free(p);
  65. }
  66. delete q_;
  67. }
  68. void TBF::recv(Packet *p, Handler *)
  69. {
  70. //start with a full bucket
  71. if (init_) {
  72. tokens_=bucket_;
  73. lastupdatetime_ = Scheduler::instance().clock();
  74. init_=0;
  75. }
  76. hdr_cmn *ch=hdr_cmn::access(p);
  77. //enque packets appropriately if a non-zero q already exists
  78. if (q_->length() !=0) {
  79. if (q_->length() < qlen_) {
  80. q_->enque(p);
  81. return;
  82. }
  83. drop(p);
  84. return;
  85. }
  86. double tok;
  87. tok = getupdatedtokens();
  88. int pktsize = ch->size()<<3;
  89. if (tokens_ >=pktsize) {
  90. target_->recv(p);
  91. tokens_-=pktsize;
  92. }
  93. else {
  94. if (qlen_!=0) {
  95. q_->enque(p);
  96. tbf_timer_.resched((pktsize-tokens_)/rate_);
  97. }
  98. else {
  99. drop(p);
  100. }
  101. }
  102. }
  103. double TBF::getupdatedtokens(void)
  104. {
  105. double now=Scheduler::instance().clock();
  106. tokens_ += (now-lastupdatetime_)*rate_;
  107. if (tokens_ > bucket_)
  108. tokens_=bucket_;
  109. lastupdatetime_ = Scheduler::instance().clock();
  110. return tokens_;
  111. }
  112. void TBF::timeout(int)
  113. {
  114. if (q_->length() == 0) {
  115. fprintf (stderr,"ERROR in tbfn");
  116. abort();
  117. }
  118. Packet *p=q_->deque();
  119. double tok;
  120. tok = getupdatedtokens();
  121. hdr_cmn *ch=hdr_cmn::access(p);
  122. int pktsize = ch->size()<<3;
  123. //We simply send the packet here without checking if we have enough tokens
  124. //because the timer is supposed to fire at the right time
  125. target_->recv(p);
  126. tokens_-=pktsize;
  127. if (q_->length() !=0 ) {
  128. p=q_->head();
  129. hdr_cmn *ch=hdr_cmn::access(p);
  130. pktsize = ch->size()<<3;
  131. tbf_timer_.resched((pktsize-tokens_)/rate_);
  132. }
  133. }
  134. void TBF_Timer::expire(Event* /*e*/)
  135. {
  136. tbf_->timeout(0);
  137. }
  138. static class TBFClass : public TclClass {
  139. public:
  140. TBFClass() : TclClass ("TBF") {}
  141. TclObject* create(int,const char*const*) {
  142. return (new TBF());
  143. }
  144. }class_tbf;