forked from gnolang/gno
-
Notifications
You must be signed in to change notification settings - Fork 0
/
throttle.go
60 lines (53 loc) · 1.13 KB
/
throttle.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package main
import (
"net"
"time"
"github.com/gnolang/gno/tm2/pkg/service"
)
type SubnetThrottler struct {
service.BaseService
ticker *time.Ticker
subnets3 [2 << (8 * 3)]uint8
// subnets2 [2 << (8 * 2)]uint8
// subnets1 [2 << (8 * 1)]uint8
}
func NewSubnetThrottler() *SubnetThrottler {
st := &SubnetThrottler{}
// st.ticker = time.NewTicker(time.Second)
st.ticker = time.NewTicker(time.Minute)
st.BaseService = *service.NewBaseService(nil, "SubnetThrottler", st)
return st
}
func (st *SubnetThrottler) OnStart() error {
st.BaseService.OnStart()
go st.routineTimer()
return nil
}
func (st *SubnetThrottler) routineTimer() {
for {
select {
case <-st.Quit():
return
case <-st.ticker.C:
// run something every time interval.
for i := range st.subnets3 {
st.subnets3[i] /= 2
}
}
}
}
func (st *SubnetThrottler) Request(ip net.IP) (allowed bool, reason string) {
ip = ip.To4()
if len(ip) != 4 {
return false, "invalid ip format"
}
bucket3 := int(ip[0])*256*256 +
int(ip[1])*256 +
int(ip[2])
v := st.subnets3[bucket3]
if v > 5 {
return false, ">5"
}
st.subnets3[bucket3] += 1
return true, ""
}