4 * BROKEN: Arno: must be rewritten to libevent
6 * Created by Victor Grishchenko on 3/22/09.
7 * Copyright 2009-2012 TECHNISCHE UNIVERSITEIT DELFT. All rights reserved.
15 #include <gtest/gtest.h>
17 using namespace swift;
25 * busy pipe => negative cwnd
28 TEST(Datagram,LedbatTest) {
30 int MAX_REORDERING = 3;
31 tint TARGET = 25*TINT_MSEC;
32 float GAIN = 1.0/TARGET;
35 tint DELAY_BIN = TINT_SEC*30;
36 tint min_delay = TINT_NEVER;
37 tint rtt_avg = TINT_NEVER>>4, dev_avg = TINT_NEVER>>4;
38 tint last_bin_time = 0;
39 tint last_drop_time = 0;
41 deque<tint> history, delay_history;
42 tint min_delay_bins[4] = {TINT_NEVER,TINT_NEVER,
43 TINT_NEVER,TINT_NEVER};
44 tint cur_delays[4] = {TINT_NEVER,TINT_NEVER,
45 TINT_NEVER,TINT_NEVER};
49 evutil_socket_t send_sock = Datagram::Bind(10001); // bind sending socket
50 evutil_socket_t ack_sock = Datagram::Bind(10002); // bind receiving socket
51 struct sockaddr_in send_to, ack_to;
52 send_to.sin_family = AF_INET;
53 send_to.sin_port = htons(10002);
54 send_to.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
55 ack_to.sin_family = AF_INET;
56 ack_to.sin_port = htons(10001);
57 ack_to.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
58 uint8_t* garbage = (uint8_t*) malloc(1024);
59 evutil_socket_t socks[2] = {send_sock,ack_sock};
60 evutil_socket_t sock2read;
61 tint wait_time = 100*TINT_MSEC;
63 while (sock2read = Datagram::Wait(2,socks,wait_time)) {
64 tint now = Datagram::Time();
65 if (sock2read==ack_sock) {
66 Datagram data(ack_sock); // send an acknowledgement
68 int seq = data.Pull32();
69 Datagram ack(ack_sock,ack_to);
73 fprintf(stderr,"short write\n");
74 fprintf(stderr,"%lli rcvd%i\n",now/TINT_SEC,seq);
75 //cc->OnDataRecv(bin64_t(0,seq));
76 // TODO: peer cwnd !!!
79 if (sock2read==send_sock) { // process an acknowledgement
80 Datagram ack(send_sock);
82 int seq = ack.Pull32();
83 tint arrival_time = ack.Pull64();
87 if (seq>=history.size())
91 tint send_time = history[seq];
93 if (seq>MAX_REORDERING*2) { //loss
94 if (last_drop_time<now-rtt_avg) {
98 fprintf(stderr,"got %i. LOSS, cwnd drop: %f\n",seq,cwnd);
99 for(int i=0; i<MAX_REORDERING*2 && history.size(); i++) {
105 tint delay = arrival_time - send_time;
106 if (seq==0 && seq_off==0) { // FIXME
107 rtt_avg = now - send_time;
110 if (send_time/DELAY_BIN != last_bin_time) {
111 last_bin_time = send_time/DELAY_BIN;
112 delay_bin = (delay_bin+1) % 4;
113 min_delay_bins[delay_bin] = TINT_NEVER;
114 min_delay = TINT_NEVER;
116 if (min_delay_bins[i]<min_delay)
117 min_delay = min_delay_bins[i];
119 if (min_delay_bins[delay_bin] > delay)
120 min_delay_bins[delay_bin] = delay;
121 if (delay < min_delay)
123 cur_delays[(seq_off+seq)%4] = delay;
124 tint current_delay = TINT_NEVER;
125 for(int i=0; i<4; i++)
126 if (current_delay > cur_delays[i])
127 current_delay = cur_delays[i]; // FIXME avg
128 tint queueing_delay = current_delay - min_delay;
130 tint off_target = TARGET - queueing_delay;
131 //cerr<<"\t"<<cwnd<<"+="<<GAIN<<"*"<<off_target<<"/"<<cwnd<<endl;
132 cwnd += GAIN * off_target / cwnd;
133 fprintf(stderr,"ackd cwnd%f cur%lli min%lli seq%i off%i\n",
134 cwnd,current_delay,min_delay,seq_off+seq,seq);
136 if (now/TINT_SEC!=last_sec/TINT_SEC) {
137 fprintf(stderr,"%i KB/sec\n",sec_ackd);
139 last_sec = now; // FIXME
144 while (history[0]==0 && history.size()) {
148 if (history.size() && history[0]<now-rtt_avg-5*dev_avg) {
149 if (last_drop_time<now-rtt_avg) {
151 last_drop_time = now;
153 fprintf(stderr,"TIMEOUT LOSS, cwnd drop: %f\n",cwnd);
158 if (history.size()<cwnd) {
159 int sendseq = history.size() + seq_off;
160 Datagram send(send_sock,send_to);
161 send.Push32(sendseq);
162 send.Push(garbage,1024);
163 history.push_back(now);
164 fprintf(stderr,"sent%i\n",sendseq);
165 if (4+1024!=send.Send())
166 fprintf(stderr,"short data write\n");
170 if (history.size()<cwnd)
171 wait_time = rtt_avg/cwnd;
173 wait_time = 100*TINT_MSEC;
177 int main (int argc, char** argv) {
178 printf("Warning: use the script to set up dummynet!\n");
180 swift::LibraryInit();
181 testing::InitGoogleTest(&argc, argv);
182 return RUN_ALL_TESTS();