00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include "vfer_ccontrol.h"
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 void CC_Sent_CtlPack(packet* p, vfer_sock* sock) {
00033         sock->ccontrol.s_inflight++;
00034         sock->ccontrol.s_last_seq = sock->l_seq + 1;
00035         DEBUG_CC(DEBUG_CCTL, "ccontrol.c", "CC_Sent_CtlPack", sock);
00036 } 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 void CC_Recvd_Close(packet* p, vfer_sock* sock) {
00045         ccontrol_t* c;
00046         struct timeval tv;
00047         c = &(sock->ccontrol);
00048         GET_TIME_OF_DAY(&tv);
00049         Tree_Insert(&(c->rev_path_base_delayhist), p->delay, tv);
00050         Tree_Insert(&(c->rev_path_curr_delayhist), p->delay, tv);
00051         
00052         sock->ccontrol.r_last_seq = p->seq + 1;
00053 } 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 inline int CC_Can_Send_Data(size_t data_size, vfer_sock* sock) {
00066         if ((data_size + sock->ccontrol.s_cwnd_sent) > sock->ccontrol.s_cwnd) {
00067                 return 0;
00068         }
00069         return 1;
00070 } 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 inline void CC_Sent_Data(packet* p, frame_link* frame, vfer_sock* sock) {
00080         sock->ccontrol.s_cwnd_sent              += p->u.data.data_len;  
00081         sock->ccontrol.s_last_seq               = sock->l_seq + 1;
00082         
00083         sock->ccontrol.s_last_data_frame        = frame;
00084         sock->ccontrol.s_last_data_offset       = p->u.data.data_offset;
00085         sock->ccontrol.s_inflight++;
00086 
00087 } 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 void CC_Recvd_Data(packet* p, vfer_sock* sock) {
00096         ccontrol_t* c;
00097         struct timeval tv;
00098 
00099         c = &(sock->ccontrol);
00100         GET_TIME_OF_DAY(&tv);
00101         Tree_Insert(&(c->rev_path_base_delayhist), p->delay, tv);
00102         Tree_Insert(&(c->rev_path_curr_delayhist), p->delay, tv);
00103         
00104         if (p->seq >= c->r_last_seq) {
00105                 
00106 
00107                 
00108                 c->r_packets_lost       += (p->seq - c->r_last_seq);
00109                 c->r_last_seq            = p->seq+1;
00110         } else if (p->seq >= c->r_first_seq) {
00111                 
00112 
00113                 DEBUG_PRINT(DEBUG_CCTL, "ccontrol.c", "CC_Recvd_Data", "data packet [%d bytes] that was counted as lost", p->u.data.data_len);
00114                 c->r_packets_lost--;
00115         } else {
00116                 DEBUG_PRINT(DEBUG_CCTL, "ccontrol.c", "CC_Recvd_Data", "data packet from the past");
00117                 return;
00118         }
00119 
00120         c->r_bytes_total += p->u.data.data_len;
00121         c->r_unacked_bytes += p->u.data.data_len;
00122 
00123         
00124 } 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 void CC_Recvd_Ack(packet* p, vfer_sock* sock) {
00135         int packets_acked;
00136         int new_rtt;
00137         uint16_t packets_lost;
00138         uint32_t bytes_acked;
00139         ccontrol_t* c;
00140         struct timeval tv;
00141         double off_target;
00142         int lost;
00143         double scaled_gain;
00144 
00145         c = &(sock->ccontrol);
00146 
00147         
00148         if (!((p->u.ccack.last_seq >= (c->s_first_seq - 1) &&
00149                p->u.ccack.last_seq < c->s_last_seq))) {
00150                 DEBUG_PRINT(DEBUG_CCTL, "ccontrol.c", "CC_Recvd_Ack", "ack acknowledges a packet[s] outside of current window range ; ignoring");
00151                 return;
00152         }
00153 
00154         DEBUG_PACK(DEBUG_CCTL, "ccontrol.c", "CC_Recvd_Ack", p, ":");
00155         GET_TIME_OF_DAY(&tv);
00156         Tree_Insert(&(c->rev_path_base_delayhist), p->delay, tv);
00157         Tree_Insert(&(c->rev_path_curr_delayhist), p->delay, tv);
00158 
00159         c->delay_delta          = p->u.ccack.delay_delta;
00160         c->delay                = p->u.ccack.delay;
00161 
00162         
00163         new_rtt = abs(p->u.ccack.delay - p->delay);
00164         if (new_rtt == 0) new_rtt = 1;
00165         sock->stats.avg_rtt = ((sock->stats.avg_rtt * sock->stats.rtt_measurements) + new_rtt) / (sock->stats.rtt_measurements + 1);
00166         if (sock->stats.max_rtt < new_rtt) sock->stats.max_rtt = new_rtt;
00167         if (sock->stats.min_rtt > new_rtt) sock->stats.min_rtt = new_rtt;
00168         sock->stats.rtt_measurements++;
00169 
00170         
00171         if (c->last_packets_lost < p->u.ccack.packets_lost) {
00172                 packets_lost = p->u.ccack.packets_lost - c->last_packets_lost;
00173         } else {
00174                 packets_lost = 0;
00175         }
00176 
00177         
00178         packets_acked = p->u.ccack.last_seq - c->s_first_seq + 1;
00179         if (packets_acked > c->s_inflight) {
00180                 ERROR_PRINT("ccontrol.c","CC_Recvd_Ack","packets_acked > c->s_inflight !");
00181                 c->s_inflight = 0;
00182         } else {
00183                 c->s_inflight -= packets_acked;
00184 }
00185 
00186         
00187         if ((p->u.ccack.bytes_total - c->last_bytes_total) != 0) {
00188                 bytes_acked = p->u.ccack.bytes_total - c->last_bytes_total;
00189         } else {
00190                 bytes_acked = 0;
00191         }
00192 
00193         off_target = CCONTROL_TARGET - (c->delay_delta);
00194         
00195 
00196         scaled_gain = (MAX_CWND_INCREASE_PACKETS_PER_RTT * c->mtu * c->mtu * off_target * UNACKED_THRESH) / (CCONTROL_TARGET * (double)(c->s_cwnd));
00197 
00198         
00199         
00200         if (scaled_gain < 0 && ((scaled_gain * -1) > c->s_cwnd)) {
00201                 c->s_cwnd = 4 * c->mtu;
00202         } else {
00203                 if (scaled_gain > c->s_maxw ||
00204                     (c->s_maxw - c->s_cwnd) < scaled_gain) {
00205                         c->s_cwnd = c->s_maxw;
00206                 } else {
00207                         c->s_cwnd += scaled_gain;
00208                 }
00209         }
00210 
00211         if (packets_lost != 0) {
00212                 lost = 0;
00213                 if (c->r_last_loss.tv_sec == 0) {
00214                         c->s_cwnd /= 2;
00215                         lost = 1;
00216                         c->r_last_loss = tv;
00217                 }
00218         }
00219 
00220         
00221         if (c->s_cwnd > c->s_maxw) {
00222                 DEBUG_PRINT(DEBUG_CCTL, "ccontrol.c","CC_Recvd_Ack","cwin too large, setting to [%u]", c->s_maxw);
00223                 c->s_cwnd = c->s_maxw;
00224         }
00225 
00226         
00227         if (c->s_cwnd < 4 * c->mtu) {
00228                 c->s_cwnd = 4 * c->mtu;
00229         }
00230 
00231         c->last_bytes_total = p->u.ccack.bytes_total;
00232 
00233         
00234         if (p->seq >= c->r_last_seq) {
00235                 
00236 
00237                 c->r_packets_lost       += (p->seq - c->r_last_seq);
00238                 c->r_last_seq            = p->seq+1;
00239         } else if (p->seq >= c->r_first_seq) {
00240                 
00241 
00242                 DEBUG_PRINT(DEBUG_CCTL, "ccontrol.c", "CC_Recvd_Ack", "received ack previously counted as lost");
00243                 c->r_packets_lost--;
00244         }
00245 
00246         c->s_first_seq          = p->u.ccack.last_seq + 1;
00247         c->last_packets_lost    = p->u.ccack.packets_lost;
00248 
00249         
00250         if((sock->pmtu.probe_state == MTU_FOUND) 
00251                 && (sock->pmtu.search_low != (sock->pmtu.common_mtus + COMMON_MTU_MAX_INDEX)) 
00252                 && (sock->pmtu.next_probe_time <= tv.tv_sec)){
00253                         sock->pmtu.search_high = sock->pmtu.common_mtus + COMMON_MTU_MAX_INDEX;
00254                         sock->pmtu.probe_state = NO_PROBE_SENT;
00255         }
00256         
00257         DEBUG_CC(DEBUG_CCTL, "ccontrol.c", "CC_Recvd_Ack", sock);
00258         
00259         
00260         return;
00261 }