]>
git.ipfire.org Git - thirdparty/openvpn.git/blob - src/openvpn/shaper.h
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
8 * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 /*#define SHAPER_DEBUG*/
36 * A simple traffic shaper for
37 * the output direction.
40 #define SHAPER_MIN 100 /* bytes per second */
41 #define SHAPER_MAX 100000000
43 #define SHAPER_MAX_TIMEOUT 10 /* seconds */
50 struct timeval wakeup
;
59 void shaper_msg(struct shaper
*s
);
61 void shaper_reset_wakeup(struct shaper
*s
);
64 * We want to wake up in delay microseconds. If timeval is larger
65 * than delay, set timeval to delay.
67 bool shaper_soonest_event(struct timeval
*tv
, int delay
);
74 shaper_reset(struct shaper
*s
, int bytes_per_second
)
76 s
->bytes_per_second
= constrain_int(bytes_per_second
, SHAPER_MIN
, SHAPER_MAX
);
79 s
->factor
= 1000000.0 / (double)s
->bytes_per_second
;
81 s
->factor
= 1000000 / s
->bytes_per_second
;
86 shaper_init(struct shaper
*s
, int bytes_per_second
)
88 shaper_reset(s
, bytes_per_second
);
89 shaper_reset_wakeup(s
);
93 shaper_current_bandwidth(struct shaper
*s
)
95 return s
->bytes_per_second
;
99 * Returns traffic shaping delay in microseconds relative to current
100 * time, or 0 if no delay.
103 shaper_delay(struct shaper
*s
)
108 if (tv_defined(&s
->wakeup
))
110 ASSERT(!openvpn_gettimeofday(&tv
, NULL
));
111 delay
= tv_subtract(&s
->wakeup
, &tv
, SHAPER_MAX_TIMEOUT
);
113 dmsg(D_SHAPER_DEBUG
, "SHAPER shaper_delay delay=%d", delay
);
117 return delay
> 0 ? delay
: 0;
122 * We are about to send a datagram of nbytes bytes.
124 * Compute when we can send another datagram,
125 * based on target throughput (s->bytes_per_second).
128 shaper_wrote_bytes(struct shaper
*s
, int nbytes
)
132 /* compute delay in microseconds */
135 tv
.tv_usec
= min_int((int)((double)max_int(nbytes
, 100) * s
->factor
), (SHAPER_MAX_TIMEOUT
*1000000));
137 tv
.tv_usec
= s
->bytes_per_second
138 ? min_int(max_int(nbytes
, 100) * s
->factor
, (SHAPER_MAX_TIMEOUT
*1000000))
144 ASSERT(!openvpn_gettimeofday(&s
->wakeup
, NULL
));
145 tv_add(&s
->wakeup
, &tv
);
148 dmsg(D_SHAPER_DEBUG
, "SHAPER shaper_wrote_bytes bytes=%d delay=%ld sec=%" PRIi64
" usec=%ld",
151 (int64_t)s
->wakeup
.tv_sec
,
152 (long)s
->wakeup
.tv_usec
);
159 * Increase/Decrease bandwidth by a percentage.
161 * Return true if bandwidth changed.
164 shaper_change_pct(struct shaper
*s
, int pct
)
166 const int orig_bandwidth
= s
->bytes_per_second
;
167 const int new_bandwidth
= orig_bandwidth
+ (orig_bandwidth
* pct
/ 100);
168 ASSERT(s
->bytes_per_second
);
169 shaper_reset(s
, new_bandwidth
);
170 return s
->bytes_per_second
!= orig_bandwidth
;
174 #endif /* ifndef SHAPER_H */