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

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 1996 The Regents of the University of California.
  4.  * All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  *  This product includes software developed by the Network Research
  17.  *  Group at Lawrence Berkeley National Laboratory.
  18.  * 4. Neither the name of the University nor of the Laboratory may be used
  19.  *    to endorse or promote products derived from this software without
  20.  *    specific prior written permission.
  21.  * 
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  */
  34. /* 9/96 Pittsburgh Supercomputing Center
  35.  *      UpdateScoreBoard, CheckSndNxt, MarkRetran modified for fack
  36.  */
  37. /*  A quick hack version of the scoreboard  */
  38. #include <stdlib.h>
  39. #include <stdio.h>
  40. #include "scoreboard.h"
  41. #include "tcp.h"
  42. #define ASSERT(x) if (!(x)) {printf ("Assert SB failedn"); exit(1);}
  43. #define ASSERT1(x) if (!(x)) {printf ("Assert1 SB (length)n"); exit(1);}
  44. #define SBNI SBN[i%sbsize_]
  45. // last_ack = TCP last ack
  46. int ScoreBoard::UpdateScoreBoard (int last_ack, hdr_tcp* tcph)
  47. {
  48. int i, sack_index, sack_left, sack_right;
  49. int retran_decr = 0;
  50. changed_ = 0;
  51. //  Advance the left edge of the block.
  52. if (length_ && SBN[first_%sbsize_].seq_no_ <= last_ack) {
  53. for (i=SBN[first_%sbsize_].seq_no_; i<=last_ack; i++) {
  54. //  Advance the ACK
  55. if (SBNI.seq_no_ <= last_ack) {
  56. ASSERT(first_ == i);
  57. first_ = (first_+1);
  58. length_--;
  59. ASSERT1(length_ >= 0);
  60. SBNI.ack_flag_ = 1;
  61. SBNI.sack_flag_ = 1;
  62. if (SBNI.retran_) {
  63. SBNI.retran_ = 0;
  64. SBNI.snd_nxt_ = 0;
  65. retran_decr++;
  66. }
  67. changed_++;
  68. if (length_==0) 
  69. break;
  70. }
  71. }
  72. }
  73. //  If there is no scoreboard, create one.
  74. if (length_ == 0 && tcph->sa_length()) {
  75. i = last_ack+1;
  76. SBNI.seq_no_ = i;
  77. SBNI.ack_flag_ = 0;
  78. SBNI.sack_flag_ = 0;
  79. SBNI.retran_ = 0;
  80. SBNI.snd_nxt_ = 0;
  81. first_ = i;
  82. length_++;
  83. if (length_ >= sbsize_) {
  84. printf ("Error, scoreboard too large (increase sbsize_ for more space)n");
  85. exit(1);
  86. }
  87. changed_++;
  88. }
  89. for (sack_index=0; sack_index < tcph->sa_length(); sack_index++) {
  90. sack_left = tcph->sa_left(sack_index);
  91. sack_right = tcph->sa_right(sack_index);
  92. //  Create new entries off the right side.
  93. if (sack_right > SBN[(first_+length_+sbsize_-1)%sbsize_].seq_no_) {
  94. // Resize the scoreboard if it is going to overrun the length
  95. while((sack_right - last_ack) >= sbsize_ -1 ){
  96. resizeSB(sbsize_*2);
  97. }
  98. //  Create new entries
  99. for (i = SBN[(first_+length_+sbsize_-1)%sbsize_].seq_no_+1; i<sack_right; i++) {
  100. SBNI.seq_no_ = i;
  101. SBNI.ack_flag_ = 0;
  102. SBNI.sack_flag_ = 0;
  103. SBNI.retran_ = 0;
  104. SBNI.snd_nxt_ = 0;
  105. length_++;
  106. if (length_ >= sbsize_) {
  107. fprintf(stderr, "ERROR: Scoreboard got too large!!!n");
  108. fprintf(stderr, " SBN[first (mod) sbsize_]: %i, sack_right: %i length_: %in", SBN[first_%sbsize_].seq_no_,sack_right , length_);
  109. fprintf(stderr, "last_ack: %i SBN[(first_+length_+sbsize_-1) (mod) sbsize_].seq_no_: %i, sbsize_: %in", last_ack, SBN[(first_+length_+sbsize_-1)%sbsize_].seq_no_ , sbsize_);
  110.   exit(1);
  111. }
  112. changed_++;
  113. }
  114. }
  115. for (i=SBN[(first_)%sbsize_].seq_no_; i<sack_right; i++) {
  116. //  Check to see if this segment is now covered by the sack block
  117. if (SBNI.seq_no_ >= sack_left && SBNI.seq_no_ < sack_right) {
  118. if (! SBNI.sack_flag_) {
  119. SBNI.sack_flag_ = 1;
  120. changed_++;
  121. }
  122. if (SBNI.retran_) {
  123. SBNI.retran_ = 0;
  124. retran_decr++;
  125. }
  126. }
  127. }
  128. }
  129. return (retran_decr);
  130. }
  131. int ScoreBoard::CheckSndNxt (hdr_tcp* tcph)
  132. {
  133. int i, sack_index, sack_left, sack_right;
  134. int force_timeout = 0;
  135. for (sack_index=0; sack_index < tcph->sa_length(); sack_index++) {
  136. sack_left = tcph->sa_left(sack_index);
  137. sack_right = tcph->sa_right(sack_index);
  138. for (i=SBN[(first_)%sbsize_].seq_no_; i<sack_right; i++) {
  139. //  Check to see if this segment's snd_nxt_ is now covered by the sack block
  140. if (SBNI.retran_ && SBNI.snd_nxt_ < sack_right) {
  141. // the packet was lost again
  142. SBNI.retran_ = 0;
  143. SBNI.snd_nxt_ = 0;
  144. force_timeout = 1;
  145. }
  146. }
  147. }
  148. return (force_timeout);
  149. }
  150. void ScoreBoard::ClearScoreBoard()
  151. {
  152. length_ = 0;
  153. }
  154. /*
  155.  * GetNextRetran() returns "-1" if there is no packet that is
  156.  *   not acked and not sacked and not retransmitted.
  157.  */
  158. int ScoreBoard::GetNextRetran() // Returns sequence number of next pkt...
  159. {
  160. int i;
  161. if (length_) {
  162. for (i=SBN[(first_)%sbsize_].seq_no_; 
  163.      i<SBN[(first_)%sbsize_].seq_no_+length_; i++) {
  164. if (!SBNI.ack_flag_ && !SBNI.sack_flag_ && !SBNI.retran_) {
  165. return (i);
  166. }
  167. }
  168. }
  169. return (-1);
  170. }
  171. /*
  172.  * GetNextUnacked returns sequence number of next unacked pkt,
  173.  * starting with seqno.
  174.  * Returns -1 if there is no unacked packet in that range.
  175.  */
  176. int ScoreBoard::GetNextUnacked (int seqno)
  177. {
  178. int i;
  179. if (!length_) {
  180. return (-1);
  181. } else if (seqno < SBN[(first_)%sbsize_].seq_no_ ||
  182. seqno >= SBN[(first_)%sbsize_].seq_no_+length_) {
  183. return (-1);
  184. } else {
  185. for (i=seqno; i<SBN[(first_)%sbsize_].seq_no_+length_; i++) {
  186. if (!SBNI.ack_flag_ && !SBNI.sack_flag_) {
  187. return (i);
  188. }
  189. }
  190. }
  191. return (-1);
  192. }
  193. void ScoreBoard::MarkRetran (int retran_seqno, int snd_nxt)
  194. {
  195. SBN[retran_seqno%sbsize_].retran_ = 1;
  196. SBN[retran_seqno%sbsize_].snd_nxt_ = snd_nxt;
  197. }
  198. void ScoreBoard::MarkRetran (int retran_seqno)
  199. {
  200. SBN[retran_seqno%sbsize_].retran_ = 1;
  201. }
  202. void ScoreBoard::resizeSB(int sz)
  203. {
  204. ScoreBoardNode *newSBN = new ScoreBoardNode[sz+1];
  205. if(!newSBN){
  206. fprintf(stderr, "Unable to allocate new ScoreBoardNode[%i]n", sz);
  207. exit(1);
  208. }
  209. for(int i = SBN[first_%sbsize_].seq_no_;
  210.     i<=SBN[(first_)%sbsize_].seq_no_+length_; i++) {
  211. newSBN[i%sz] = SBN[i%sbsize_];
  212. }
  213. delete[] SBN;
  214. SBN = newSBN;
  215. sbsize_ = sz;
  216. }
  217. void ScoreBoard::Dump()
  218. {
  219.        int i;
  220.        printf("SB len: %d  ", length_);
  221.        if (length_) {
  222.                for (i=SBN[(first_)%sbsize_].seq_no_; 
  223.                     i<SBN[(first_)%sbsize_].seq_no_+length_; i++) {
  224.                        printf("seq: %d  [ ", i);
  225.                        if(SBNI.ack_flag_)
  226.                                printf("A");
  227.                        if(SBNI.sack_flag_)
  228.                                printf("S");
  229.                        if(SBNI.retran_)
  230.                                printf("R");
  231.                        printf(" ]");
  232.                }
  233.        }
  234.        printf("n");
  235. }