blob: fd57c22e55f23594cc3a4318241d8aa1e86ab652 [file] [log] [blame]
Pierre Ossmanc09e5582015-12-11 20:23:17 +01001/* Copyright 2009-2015 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
Pierre Ossmanc09e5582015-12-11 20:23:17 +010024namespace rfb {
Pierre Ossmana99d14d2015-12-13 15:43:46 +010025 class Congestion {
Pierre Ossmanc09e5582015-12-11 20:23:17 +010026 public:
27 Congestion();
28 ~Congestion();
29
Pierre Ossmana99d14d2015-12-13 15:43:46 +010030 // updatePosition() registers the current stream position and can
31 // and should be called often.
32 void updatePosition(unsigned pos);
33
Pierre Ossmanc09e5582015-12-11 20:23:17 +010034 // sentPing() must be called when a marker is placed on the
Pierre Ossmana99d14d2015-12-13 15:43:46 +010035 // outgoing stream. gotPong() must be called when the response for
36 // such a marker is received.
37 void sentPing();
Pierre Ossmanc09e5582015-12-11 20:23:17 +010038 void gotPong();
39
40 // isCongested() determines if the transport is currently congested
Pierre Ossmana99d14d2015-12-13 15:43:46 +010041 // 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
Pierre Ossman8cf71632016-03-11 09:38:08 +010050 // debugTrace() writes the current congestion window, as well as the
51 // congestion window of the underlying TCP layer, to the specified
52 // file
53 void debugTrace(const char* filename, int fd);
54
Pierre Ossmana99d14d2015-12-13 15:43:46 +010055 protected:
56 unsigned getExtraBuffer();
57 unsigned getInFlight();
58
59 void updateCongestion();
Pierre Ossmanc09e5582015-12-11 20:23:17 +010060
61 private:
Pierre Ossmana99d14d2015-12-13 15:43:46 +010062 unsigned lastPosition;
63 unsigned extraBuffer;
64 struct timeval lastUpdate;
65 struct timeval lastSent;
Pierre Ossmanc09e5582015-12-11 20:23:17 +010066
Pierre Ossmanc09e5582015-12-11 20:23:17 +010067 unsigned baseRTT;
68 unsigned congWindow;
Pierre Ossmanda8904c2015-12-21 07:59:20 +010069 bool inSlowStart;
Pierre Ossmanc09e5582015-12-11 20:23:17 +010070
Pierre Ossmana99d14d2015-12-13 15:43:46 +010071 struct RTTInfo {
72 struct timeval tv;
73 unsigned pos;
74 unsigned extra;
75 bool congested;
76 };
Pierre Ossmanc09e5582015-12-11 20:23:17 +010077
Pierre Ossmanc09e5582015-12-11 20:23:17 +010078 std::list<struct RTTInfo> pings;
Pierre Ossmana99d14d2015-12-13 15:43:46 +010079
80 struct RTTInfo lastPong;
81 struct timeval lastPongArrival;
82
83 int measurements;
84 struct timeval lastAdjustment;
85 unsigned minRTT, minCongestedRTT;
Pierre Ossmanc09e5582015-12-11 20:23:17 +010086 };
87}
88
89#endif