Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
Tor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Benjamin J. Thompson
Tor
Commits
e476ffc2
Commit
e476ffc2
authored
14 years ago
by
Nick Mathewson
Browse files
Options
Downloads
Plain Diff
Merge branch 'bug1789'
parents
fb34c66e
9cba61eb
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
changes/bug1789
+16
-0
16 additions, 0 deletions
changes/bug1789
src/or/config.c
+3
-0
3 additions, 0 deletions
src/or/config.c
src/or/hibernate.c
+87
-16
87 additions, 16 deletions
src/or/hibernate.c
src/or/or.h
+3
-0
3 additions, 0 deletions
src/or/or.h
with
109 additions
and
16 deletions
changes/bug1789
0 → 100644
+
16
−
0
View file @
e476ffc2
o Minor features:
- Be more generous with how much bandwidth we'd use up (with
accounting enabled) before entering "soft hibernation".
Previously, we'd hibernate once we'd used up 95% of our
allotment. Now, we use up 95% of our allotment, AND make sure
that we have no more than 500MB (or 3 hours of expected traffic,
whichever is lower) remaining before we enter soft hibernation.
o Minor bugfixes:
- For bandwidth accounting, calculate our expected bandwidth rate
based on the time during which we were active and not in
soft-hibernation during the last interval. Previously, we were
also considering the time spent in soft-hibernation. If this
was a long time, we would wind up underestimating our bandwidth
by a lot, and skewing our wakeup time towards the start of the
accounting interval. Fixes bug 1789. Bugfix on 0.0.9pre5.
This diff is collapsed.
Click to expand it.
src/or/config.c
+
3
−
0
View file @
e476ffc2
...
@@ -428,6 +428,9 @@ static config_var_t _state_vars[] = {
...
@@ -428,6 +428,9 @@ static config_var_t _state_vars[] = {
V
(
AccountingExpectedUsage
,
MEMUNIT
,
NULL
),
V
(
AccountingExpectedUsage
,
MEMUNIT
,
NULL
),
V
(
AccountingIntervalStart
,
ISOTIME
,
NULL
),
V
(
AccountingIntervalStart
,
ISOTIME
,
NULL
),
V
(
AccountingSecondsActive
,
INTERVAL
,
NULL
),
V
(
AccountingSecondsActive
,
INTERVAL
,
NULL
),
V
(
AccountingSecondsToReachSoftLimit
,
INTERVAL
,
NULL
),
V
(
AccountingSoftLimitHitAt
,
ISOTIME
,
NULL
),
V
(
AccountingBytesAtSoftLimit
,
MEMUNIT
,
NULL
),
VAR
(
"EntryGuard"
,
LINELIST_S
,
EntryGuards
,
NULL
),
VAR
(
"EntryGuard"
,
LINELIST_S
,
EntryGuards
,
NULL
),
VAR
(
"EntryGuardDownSince"
,
LINELIST_S
,
EntryGuards
,
NULL
),
VAR
(
"EntryGuardDownSince"
,
LINELIST_S
,
EntryGuards
,
NULL
),
...
...
This diff is collapsed.
Click to expand it.
src/or/hibernate.c
+
87
−
16
View file @
e476ffc2
...
@@ -95,6 +95,13 @@ static uint64_t n_bytes_read_in_interval = 0;
...
@@ -95,6 +95,13 @@ static uint64_t n_bytes_read_in_interval = 0;
static
uint64_t
n_bytes_written_in_interval
=
0
;
static
uint64_t
n_bytes_written_in_interval
=
0
;
/** How many seconds have we been running this interval? */
/** How many seconds have we been running this interval? */
static
uint32_t
n_seconds_active_in_interval
=
0
;
static
uint32_t
n_seconds_active_in_interval
=
0
;
/** How many seconds were we active in this interval before we hit our soft
* limit? */
static
int
n_seconds_to_hit_soft_limit
=
0
;
/** When in this interval was the soft limit hit. */
static
time_t
soft_limit_hit_at
=
0
;
/** How many bytes had we read/written when we hit the soft limit? */
static
uint64_t
n_bytes_at_soft_limit
=
0
;
/** When did this accounting interval start? */
/** When did this accounting interval start? */
static
time_t
interval_start_time
=
0
;
static
time_t
interval_start_time
=
0
;
/** When will this accounting interval end? */
/** When will this accounting interval end? */
...
@@ -374,23 +381,42 @@ configure_accounting(time_t now)
...
@@ -374,23 +381,42 @@ configure_accounting(time_t now)
static
void
static
void
update_expected_bandwidth
(
void
)
update_expected_bandwidth
(
void
)
{
{
uint64_t
used
,
expected
;
uint64_t
expected
;
uint64_t
max_configured
=
(
get_options
()
->
BandwidthRate
*
60
);
or_options_t
*
options
=
get_options
();
uint64_t
max_configured
=
(
options
->
RelayBandwidthRate
>
0
?
if
(
n_seconds_active_in_interval
<
1800
)
{
options
->
RelayBandwidthRate
:
options
->
BandwidthRate
)
*
60
;
#define MIN_TIME_FOR_MEASUREMENT (1800)
if
(
soft_limit_hit_at
>
interval_start_time
&&
n_bytes_at_soft_limit
&&
(
soft_limit_hit_at
-
interval_start_time
)
>
MIN_TIME_FOR_MEASUREMENT
)
{
/* If we hit our soft limit last time, only count the bytes up to that
* time. This is a better predictor of our actual bandwidth than
* considering the entirety of the last interval, since we likely started
* using bytes very slowly once we hit our soft limit. */
expected
=
n_bytes_at_soft_limit
/
(
soft_limit_hit_at
-
interval_start_time
);
expected
/=
60
;
}
else
if
(
n_seconds_active_in_interval
>=
MIN_TIME_FOR_MEASUREMENT
)
{
/* Otherwise, we either measured enough time in the last interval but
* never hit our soft limit, or we're using a state file from a Tor that
* doesn't know to store soft-limit info. Just take rate at which
* we were reading/writing in the last interval as our expected rate.
*/
uint64_t
used
=
MAX
(
n_bytes_written_in_interval
,
n_bytes_read_in_interval
);
expected
=
used
/
(
n_seconds_active_in_interval
/
60
);
}
else
{
/* If we haven't gotten enough data last interval, set 'expected'
/* If we haven't gotten enough data last interval, set 'expected'
* to 0. This will set our wakeup to the start of the interval.
* to 0. This will set our wakeup to the start of the interval.
* Next interval, we'll choose our starting time based on how much
* Next interval, we'll choose our starting time based on how much
* we sent this interval.
* we sent this interval.
*/
*/
expected
=
0
;
expected
=
0
;
}
else
{
used
=
n_bytes_written_in_interval
<
n_bytes_read_in_interval
?
n_bytes_read_in_interval
:
n_bytes_written_in_interval
;
expected
=
used
/
(
n_seconds_active_in_interval
/
60
);
if
(
expected
>
max_configured
)
expected
=
max_configured
;
}
}
if
(
expected
>
max_configured
)
expected
=
max_configured
;
expected_bandwidth_usage
=
expected
;
expected_bandwidth_usage
=
expected
;
}
}
...
@@ -408,6 +434,9 @@ reset_accounting(time_t now)
...
@@ -408,6 +434,9 @@ reset_accounting(time_t now)
n_bytes_read_in_interval
=
0
;
n_bytes_read_in_interval
=
0
;
n_bytes_written_in_interval
=
0
;
n_bytes_written_in_interval
=
0
;
n_seconds_active_in_interval
=
0
;
n_seconds_active_in_interval
=
0
;
n_bytes_at_soft_limit
=
0
;
soft_limit_hit_at
=
0
;
n_seconds_to_hit_soft_limit
=
0
;
}
}
/** Return true iff we should save our bandwidth usage to disk. */
/** Return true iff we should save our bandwidth usage to disk. */
...
@@ -568,6 +597,10 @@ accounting_record_bandwidth_usage(time_t now, or_state_t *state)
...
@@ -568,6 +597,10 @@ accounting_record_bandwidth_usage(time_t now, or_state_t *state)
state
->
AccountingSecondsActive
=
n_seconds_active_in_interval
;
state
->
AccountingSecondsActive
=
n_seconds_active_in_interval
;
state
->
AccountingExpectedUsage
=
expected_bandwidth_usage
;
state
->
AccountingExpectedUsage
=
expected_bandwidth_usage
;
state
->
AccountingSecondsToReachSoftLimit
=
n_seconds_to_hit_soft_limit
;
state
->
AccountingSoftLimitHitAt
=
soft_limit_hit_at
;
state
->
AccountingBytesAtSoftLimit
=
n_bytes_at_soft_limit
;
or_state_mark_dirty
(
state
,
or_state_mark_dirty
(
state
,
now
+
(
get_options
()
->
AvoidDiskWrites
?
7200
:
60
));
now
+
(
get_options
()
->
AvoidDiskWrites
?
7200
:
60
));
...
@@ -591,10 +624,6 @@ read_bandwidth_usage(void)
...
@@ -591,10 +624,6 @@ read_bandwidth_usage(void)
if
(
!
state
)
if
(
!
state
)
return
-
1
;
return
-
1
;
/* Okay; it looks like the state file is more up-to-date than the
* bw_accounting file, or the bw_accounting file is nonexistent,
* or the bw_accounting file is corrupt.
*/
log_info
(
LD_ACCT
,
"Reading bandwidth accounting data from state file"
);
log_info
(
LD_ACCT
,
"Reading bandwidth accounting data from state file"
);
n_bytes_read_in_interval
=
state
->
AccountingBytesReadInInterval
;
n_bytes_read_in_interval
=
state
->
AccountingBytesReadInInterval
;
n_bytes_written_in_interval
=
state
->
AccountingBytesWrittenInInterval
;
n_bytes_written_in_interval
=
state
->
AccountingBytesWrittenInInterval
;
...
@@ -602,6 +631,21 @@ read_bandwidth_usage(void)
...
@@ -602,6 +631,21 @@ read_bandwidth_usage(void)
interval_start_time
=
state
->
AccountingIntervalStart
;
interval_start_time
=
state
->
AccountingIntervalStart
;
expected_bandwidth_usage
=
state
->
AccountingExpectedUsage
;
expected_bandwidth_usage
=
state
->
AccountingExpectedUsage
;
/* Older versions of Tor (before 0.2.2.17-alpha or so) didn't generate these
* fields. If you switch back and forth, you might get an
* AccountingSoftLimitHitAt value from long before the most recent
* interval_start_time. If that's so, then ignore the softlimit-related
* values. */
if
(
state
->
AccountingSoftLimitHitAt
>
interval_start_time
)
{
soft_limit_hit_at
=
state
->
AccountingSoftLimitHitAt
;
n_bytes_at_soft_limit
=
state
->
AccountingBytesAtSoftLimit
;
n_seconds_to_hit_soft_limit
=
state
->
AccountingSecondsToReachSoftLimit
;
}
else
{
soft_limit_hit_at
=
0
;
n_bytes_at_soft_limit
=
0
;
n_seconds_to_hit_soft_limit
=
0
;
}
{
{
char
tbuf1
[
ISO_TIME_LEN
+
1
];
char
tbuf1
[
ISO_TIME_LEN
+
1
];
char
tbuf2
[
ISO_TIME_LEN
+
1
];
char
tbuf2
[
ISO_TIME_LEN
+
1
];
...
@@ -641,8 +685,27 @@ hibernate_hard_limit_reached(void)
...
@@ -641,8 +685,27 @@ hibernate_hard_limit_reached(void)
static
int
static
int
hibernate_soft_limit_reached
(
void
)
hibernate_soft_limit_reached
(
void
)
{
{
uint64_t
soft_limit
=
DBL_TO_U64
(
U64_TO_DBL
(
get_options
()
->
AccountingMax
)
const
uint64_t
acct_max
=
get_options
()
->
AccountingMax
;
*
.
95
);
#define SOFT_LIM_PCT (.95)
#define SOFT_LIM_BYTES (500*1024*1024)
#define SOFT_LIM_MINUTES (3*60)
/* The 'soft limit' is a fair bit more complicated now than once it was.
* We want to stop accepting connections when ALL of the following are true:
* - We expect to use up the remaining bytes in under 3 hours
* - We have used up 95% of our bytes.
* - We have less than 500MB of bytes left.
*/
uint64_t
soft_limit
=
DBL_TO_U64
(
U64_TO_DBL
(
acct_max
)
*
SOFT_LIM_PCT
);
if
(
acct_max
>
SOFT_LIM_BYTES
&&
acct_max
-
SOFT_LIM_BYTES
>
soft_limit
)
{
soft_limit
=
acct_max
-
SOFT_LIM_BYTES
;
}
if
(
expected_bandwidth_usage
)
{
const
uint64_t
expected_usage
=
expected_bandwidth_usage
*
SOFT_LIM_MINUTES
;
if
(
acct_max
>
expected_usage
&&
acct_max
-
expected_usage
>
soft_limit
)
soft_limit
=
acct_max
-
expected_usage
;
}
if
(
!
soft_limit
)
if
(
!
soft_limit
)
return
0
;
return
0
;
return
n_bytes_read_in_interval
>=
soft_limit
return
n_bytes_read_in_interval
>=
soft_limit
...
@@ -667,6 +730,14 @@ hibernate_begin(hibernate_state_t new_state, time_t now)
...
@@ -667,6 +730,14 @@ hibernate_begin(hibernate_state_t new_state, time_t now)
exit
(
0
);
exit
(
0
);
}
}
if
(
new_state
==
HIBERNATE_STATE_LOWBANDWIDTH
&&
hibernate_state
==
HIBERNATE_STATE_LIVE
)
{
soft_limit_hit_at
=
now
;
n_seconds_to_hit_soft_limit
=
n_seconds_active_in_interval
;
n_bytes_at_soft_limit
=
MAX
(
n_bytes_read_in_interval
,
n_bytes_written_in_interval
);
}
/* close listeners. leave control listener(s). */
/* close listeners. leave control listener(s). */
while
((
conn
=
connection_get_by_type
(
CONN_TYPE_OR_LISTENER
))
||
while
((
conn
=
connection_get_by_type
(
CONN_TYPE_OR_LISTENER
))
||
(
conn
=
connection_get_by_type
(
CONN_TYPE_AP_LISTENER
))
||
(
conn
=
connection_get_by_type
(
CONN_TYPE_AP_LISTENER
))
||
...
...
This diff is collapsed.
Click to expand it.
src/or/or.h
+
3
−
0
View file @
e476ffc2
...
@@ -2831,6 +2831,9 @@ typedef struct {
...
@@ -2831,6 +2831,9 @@ typedef struct {
uint64_t
AccountingBytesReadInInterval
;
uint64_t
AccountingBytesReadInInterval
;
uint64_t
AccountingBytesWrittenInInterval
;
uint64_t
AccountingBytesWrittenInInterval
;
int
AccountingSecondsActive
;
int
AccountingSecondsActive
;
int
AccountingSecondsToReachSoftLimit
;
time_t
AccountingSoftLimitHitAt
;
uint64_t
AccountingBytesAtSoftLimit
;
uint64_t
AccountingExpectedUsage
;
uint64_t
AccountingExpectedUsage
;
/** A list of Entry Guard-related configuration lines. */
/** A list of Entry Guard-related configuration lines. */
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment