1 /* Copyright 2009-2018 Pierre Ossman for Cendio AB
2  *
3  * This is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This software is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this software; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
16  * USA.
17  */
18 
19 #ifndef __RFB_CONGESTION_H__
20 #define __RFB_CONGESTION_H__
21 
22 #include <list>
23 
24 namespace rfb {
25   class Congestion {
26   public:
27     Congestion();
28     ~Congestion();
29 
30     // updatePosition() registers the current stream position and can
31     // and should be called often.
32     void updatePosition(unsigned pos);
33 
34     // sentPing() must be called when a marker is placed on the
35     // outgoing stream. gotPong() must be called when the response for
36     // such a marker is received.
37     void sentPing();
38     void gotPong();
39 
40     // isCongested() determines if the transport is currently congested
41     // or if more data can be sent.
42     bool isCongested();
43 
44     // getUncongestedETA() returns the number of milliseconds until the
45     // transport is no longer congested. Returns 0 if there is no
46     // congestion, and -1 if it is unknown when the transport will no
47     // longer be congested.
48     int getUncongestedETA();
49 
50     // getBandwidth() returns the current bandwidth estimation in bytes
51     // per second.
52     size_t getBandwidth();
53 
54     // debugTrace() writes the current congestion window, as well as the
55     // congestion window of the underlying TCP layer, to the specified
56     // file
57     void debugTrace(const char* filename, int fd);
58 
59   protected:
60     unsigned getExtraBuffer();
61     unsigned getInFlight();
62 
63     void updateCongestion();
64 
65   private:
66     unsigned lastPosition;
67     unsigned extraBuffer;
68     struct timeval lastUpdate;
69     struct timeval lastSent;
70 
71     unsigned baseRTT;
72     unsigned congWindow;
73     bool inSlowStart;
74 
75     unsigned safeBaseRTT;
76 
77     struct RTTInfo {
78       struct timeval tv;
79       unsigned pos;
80       unsigned extra;
81       bool congested;
82     };
83 
84     std::list<struct RTTInfo> pings;
85 
86     struct RTTInfo lastPong;
87     struct timeval lastPongArrival;
88 
89     int measurements;
90     struct timeval lastAdjustment;
91     unsigned minRTT, minCongestedRTT;
92   };
93 }
94 
95 #endif
96