Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
discosrv
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Ind.ie Projects
discosrv
Commits
a1c5f247
Commit
a1c5f247
authored
Apr 03, 2014
by
Jakob Borg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
discosrv: Source based rate limiting
parent
86de8c15
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
44 additions
and
1 deletion
+44
-1
main.go
main.go
+44
-1
No files found.
main.go
View file @
a1c5f247
...
...
@@ -11,6 +11,8 @@ import (
"time"
"github.com/calmh/syncthing/discover"
"github.com/golang/groupcache/lru"
"github.com/juju/ratelimit"
)
type
Node
struct
{
...
...
@@ -28,7 +30,9 @@ var (
lock
sync
.
Mutex
queries
=
0
answered
=
0
limited
=
0
debug
=
false
limiter
=
lru
.
New
(
1024
)
)
func
main
()
{
...
...
@@ -57,9 +61,16 @@ func main() {
for
{
buf
=
buf
[
:
cap
(
buf
)]
n
,
addr
,
err
:=
conn
.
ReadFromUDP
(
buf
)
if
limit
(
addr
)
{
// Rate limit in effect for source
continue
}
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
if
n
<
4
{
log
.
Printf
(
"Received short packet (%d bytes)"
,
n
)
continue
...
...
@@ -84,6 +95,36 @@ func main() {
}
}
func
limit
(
addr
*
net
.
UDPAddr
)
bool
{
key
:=
addr
.
IP
.
String
()
lock
.
Lock
()
defer
lock
.
Unlock
()
bkt
,
ok
:=
limiter
.
Get
(
key
)
if
ok
{
bkt
:=
bkt
.
(
*
ratelimit
.
Bucket
)
if
bkt
.
TakeAvailable
(
1
)
!=
1
{
// Rate limit exceeded; ignore packet
if
debug
{
log
.
Printf
(
"Rate limit exceeded for"
,
key
)
}
limited
++
return
true
}
else
if
debug
{
log
.
Printf
(
"Rate limit OK for"
,
key
)
}
}
else
{
if
debug
{
log
.
Printf
(
"New limiter for"
,
key
)
}
// One packet per ten seconds average rate, burst ten packets
limiter
.
Add
(
key
,
ratelimit
.
NewBucket
(
10
*
time
.
Second
,
10
))
}
return
false
}
func
handleAnnounceV1
(
addr
*
net
.
UDPAddr
,
buf
[]
byte
)
{
var
pkt
discover
.
AnnounceV1
err
:=
pkt
.
UnmarshalXDR
(
buf
)
...
...
@@ -246,9 +287,11 @@ func logStats() {
deleted
++
}
}
log
.
Printf
(
"Expired %d nodes; %d nodes in registry; %d queries (%d answered)"
,
deleted
,
len
(
nodes
),
queries
,
answered
)
log
.
Printf
(
"Expired %d nodes; %d nodes in registry; %d queries (%d answered); %d entries in limiter cache"
,
deleted
,
len
(
nodes
),
queries
,
answered
,
limiter
.
Len
())
log
.
Printf
(
"Limited %d queries; %d entries in limiter cache"
,
limited
,
limiter
.
Len
())
queries
=
0
answered
=
0
limited
=
0
lock
.
Unlock
()
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment