blob: d2935128b89f971bc1784d20faf011cd82ab70d8 [file] [log] [blame]
Pierre Ossmana2b80d62018-03-23 09:30:09 +01001/* Copyright 2009-2018 Pierre Ossman for Cendio AB
Pierre Ossmanc09e5582015-12-11 20:23:17 +01002 *
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 Ossmana2b80d62018-03-23 09:30:09 +010050 // getBandwidth() returns the current bandwidth estimation in bytes
51 // per second.
52 size_t getBandwidth();
53
Pierre Ossman8cf71632016-03-11 09:38:08 +010054 // 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
Pierre Ossmana99d14d2015-12-13 15:43:46 +010059 protected:
60 unsigned getExtraBuffer();
61 unsigned getInFlight();
62
63 void updateCongestion();
Pierre Ossmanc09e5582015-12-11 20:23:17 +010064
65 private:
Pierre Ossmana99d14d2015-12-13 15:43:46 +010066 unsigned lastPosition;
67 unsigned extraBuffer;
68 struct timeval lastUpdate;
69 struct timeval lastSent;
Pierre Ossmanc09e5582015-12-11 20:23:17 +010070
Pierre Ossmanc09e5582015-12-11 20:23:17 +010071 unsigned baseRTT;
72 unsigned congWindow;
Pierre Ossmanda8904c2015-12-21 07:59:20 +010073 bool inSlowStart;
Pierre Ossmanc09e5582015-12-11 20:23:17 +010074
Pierre Ossmana2b80d62018-03-23 09:30:09 +010075 unsigned safeBaseRTT;
76
Pierre Ossmana99d14d2015-12-13 15:43:46 +010077 struct RTTInfo {
78 struct timeval tv;
79 unsigned pos;
80 unsigned extra;
81 bool congested;
82 };
Pierre Ossmanc09e5582015-12-11 20:23:17 +010083
Pierre Ossmanc09e5582015-12-11 20:23:17 +010084 std::list<struct RTTInfo> pings;
Pierre Ossmana99d14d2015-12-13 15:43:46 +010085
86 struct RTTInfo lastPong;
87 struct timeval lastPongArrival;
88
89 int measurements;
90 struct timeval lastAdjustment;
91 unsigned minRTT, minCongestedRTT;
Pierre Ossmanc09e5582015-12-11 20:23:17 +010092 };
93}
94
95#endif