~ubuntu-branches/ubuntu/hardy/openvpn/hardy-proposed

« back to all changes in this revision

Viewing changes to shaper.h

  • Committer: Bazaar Package Importer
  • Author(s): Alberto Gonzalez Iniesta
  • Date: 2004-06-10 15:59:39 UTC
  • Revision ID: james.westby@ubuntu.com-20040610155939-dcmtiuvcoqnwek62
Tags: upstream-1.6.0
ImportĀ upstreamĀ versionĀ 1.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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
 
6
 *             packet compression.
 
7
 *
 
8
 *  Copyright (C) 2002-2004 James Yonan <jim@yonan.net>
 
9
 *
 
10
 *  This program is free software; you can redistribute it and/or modify
 
11
 *  it under the terms of the GNU General Public License as published by
 
12
 *  the Free Software Foundation; either version 2 of the License, or
 
13
 *  (at your option) any later version.
 
14
 *
 
15
 *  This program is distributed in the hope that it will be useful,
 
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 *  GNU General Public License for more details.
 
19
 *
 
20
 *  You should have received a copy of the GNU General Public License
 
21
 *  along with this program (see the file COPYING included with this
 
22
 *  distribution); if not, write to the Free Software Foundation, Inc.,
 
23
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
24
 */
 
25
 
 
26
#ifndef SHAPER_H
 
27
#define SHAPER_H
 
28
 
 
29
#define SHAPER_DEBUG 0
 
30
 
 
31
#ifdef HAVE_GETTIMEOFDAY
 
32
 
 
33
#include "basic.h"
 
34
#include "integer.h"
 
35
#include "misc.h"
 
36
#include "error.h"
 
37
 
 
38
/*
 
39
 * A simple traffic shaper for
 
40
 * the output direction.
 
41
 */
 
42
 
 
43
#define SHAPER_MIN 100          /* bytes per second */
 
44
#define SHAPER_MAX 100000000
 
45
 
 
46
#define SHAPER_MAX_TIMEOUT 10          /* seconds */
 
47
 
 
48
struct shaper 
 
49
{
 
50
  int bytes_per_second;
 
51
  struct timeval wakeup;
 
52
};
 
53
 
 
54
void shaper_msg (struct shaper *s);
 
55
 
 
56
/*
 
57
 * inline functions
 
58
 */
 
59
 
 
60
static inline void
 
61
shaper_reset (struct shaper *s, int bytes_per_second)
 
62
{
 
63
  s->bytes_per_second = bytes_per_second ? constrain_int (bytes_per_second, SHAPER_MIN, SHAPER_MAX) : 0;
 
64
}
 
65
 
 
66
static inline void
 
67
shaper_reset_wakeup (struct shaper *s)
 
68
{
 
69
  CLEAR (s->wakeup);
 
70
}
 
71
 
 
72
static inline void
 
73
shaper_init (struct shaper *s, int bytes_per_second)
 
74
{
 
75
  shaper_reset (s, bytes_per_second);
 
76
  shaper_reset_wakeup (s);
 
77
}
 
78
 
 
79
static inline int
 
80
shaper_current_bandwidth (struct shaper *s)
 
81
{
 
82
  return s->bytes_per_second;
 
83
}
 
84
 
 
85
/*
 
86
 * Returns traffic shaping delay in microseconds relative to current
 
87
 * time, or 0 if no delay.
 
88
 */
 
89
static inline int
 
90
shaper_delay (struct shaper* s)
 
91
{
 
92
  struct timeval tv;
 
93
  int delay = 0;
 
94
 
 
95
  if (tv_defined (&s->wakeup))
 
96
    {
 
97
      ASSERT (!gettimeofday (&tv, NULL));
 
98
      delay = tv_subtract (&s->wakeup, &tv, SHAPER_MAX_TIMEOUT);
 
99
#if SHAPER_DEBUG
 
100
      msg (D_SHAPER_DEBUG, "SHAPER shaper_delay delay=%d", delay);
 
101
#endif
 
102
    }
 
103
 
 
104
  return delay > 0 ? delay : 0;
 
105
}
 
106
 
 
107
/*
 
108
 * We want to wake up in delay microseconds.  If timeval is 0 (undefined) or larger
 
109
 * than delay, set timeval to delay.
 
110
 */
 
111
static inline void
 
112
shaper_soonest_event (struct timeval *tv, int delay)
 
113
{
 
114
  if (!tv->tv_usec && delay < 1000000)
 
115
    {
 
116
      tv->tv_usec = delay;
 
117
      tv->tv_sec = 0;
 
118
    }
 
119
  else
 
120
    {
 
121
      const int sec = delay / 1000000;
 
122
      const int usec = delay % 1000000;
 
123
 
 
124
      if ((!tv->tv_sec && !tv->tv_usec) || (sec < tv->tv_sec))
 
125
        {
 
126
          tv->tv_sec = sec;
 
127
          tv->tv_usec = usec;
 
128
        }
 
129
      else if (sec == tv->tv_sec)
 
130
        {
 
131
          if (usec < tv->tv_usec)
 
132
            {
 
133
              tv->tv_usec = usec;
 
134
            }
 
135
        }
 
136
    }
 
137
#if SHAPER_DEBUG
 
138
  msg (D_SHAPER_DEBUG, "SHAPER shaper_soonest_event sec=%d usec=%d",
 
139
       (int)tv->tv_sec, (int)tv->tv_usec);
 
140
#endif
 
141
}
 
142
 
 
143
/*
 
144
 * We are about to send a datagram of nbytes bytes.
 
145
 *
 
146
 * Compute when we can send another datagram,
 
147
 * based on target throughput (s->bytes_per_second).
 
148
 */
 
149
static inline void
 
150
shaper_wrote_bytes (struct shaper* s, int nbytes)
 
151
{
 
152
  /* delay in microseconds */
 
153
  const int delay = s->bytes_per_second
 
154
    ? min_int (((1000000 / s->bytes_per_second) * max_int (nbytes, 200)), (SHAPER_MAX_TIMEOUT*1000000))
 
155
    : 0;
 
156
  
 
157
  if (delay)
 
158
    {
 
159
      ASSERT (!gettimeofday (&s->wakeup, NULL));
 
160
      s->wakeup.tv_usec += delay;
 
161
      while (s->wakeup.tv_usec >= 1000000)
 
162
        {
 
163
          ++s->wakeup.tv_sec;
 
164
          s->wakeup.tv_usec -= 1000000;
 
165
        }
 
166
#if SHAPER_DEBUG
 
167
      msg (D_SHAPER_DEBUG, "SHAPER shaper_wrote_bytes bytes=%d delay=%d sec=%d usec=%d",
 
168
           nbytes, delay, (int)s->wakeup.tv_sec, (int)s->wakeup.tv_usec);
 
169
#endif
 
170
    }
 
171
}
 
172
 
 
173
/*
 
174
 * Increase/Decrease bandwidth by a percentage.
 
175
 *
 
176
 * Return true if bandwidth changed.
 
177
 */
 
178
static inline bool
 
179
shaper_change_pct (struct shaper *s, int pct)
 
180
{
 
181
  const int orig_bandwidth = s->bytes_per_second;
 
182
  const int new_bandwidth = orig_bandwidth + (orig_bandwidth * pct / 100);
 
183
  ASSERT (s->bytes_per_second);
 
184
  shaper_reset (s, new_bandwidth);
 
185
  return s->bytes_per_second != orig_bandwidth;
 
186
}
 
187
 
 
188
#endif /* HAVE_GETTIMEOFDAY */
 
189
 
 
190
#endif