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 }