|
@@ -8,6 +8,7 @@ import (
|
8
|
8
|
"fmt"
|
9
|
9
|
"net"
|
10
|
10
|
"sort"
|
|
11
|
+ "sync"
|
11
|
12
|
"time"
|
12
|
13
|
|
13
|
14
|
"strings"
|
|
@@ -79,6 +80,7 @@ type dLineNet struct {
|
79
|
80
|
|
80
|
81
|
// DLineManager manages and dlines.
|
81
|
82
|
type DLineManager struct {
|
|
83
|
+ sync.RWMutex
|
82
|
84
|
// addresses that are dlined
|
83
|
85
|
addresses map[string]*dLineAddr
|
84
|
86
|
// networks that are dlined
|
|
@@ -97,6 +99,9 @@ func NewDLineManager() *DLineManager {
|
97
|
99
|
func (dm *DLineManager) AllBans() map[string]IPBanInfo {
|
98
|
100
|
allb := make(map[string]IPBanInfo)
|
99
|
101
|
|
|
102
|
+ dm.RLock()
|
|
103
|
+ defer dm.RUnlock()
|
|
104
|
+
|
100
|
105
|
for name, info := range dm.addresses {
|
101
|
106
|
allb[name] = info.Info
|
102
|
107
|
}
|
|
@@ -118,13 +123,17 @@ func (dm *DLineManager) AddNetwork(network net.IPNet, length *IPRestrictTime, re
|
118
|
123
|
OperReason: operReason,
|
119
|
124
|
},
|
120
|
125
|
}
|
|
126
|
+ dm.Lock()
|
121
|
127
|
dm.networks[netString] = &dln
|
|
128
|
+ dm.Unlock()
|
122
|
129
|
}
|
123
|
130
|
|
124
|
131
|
// RemoveNetwork removes a network from the blocked list.
|
125
|
132
|
func (dm *DLineManager) RemoveNetwork(network net.IPNet) {
|
126
|
133
|
netString := network.String()
|
|
134
|
+ dm.Lock()
|
127
|
135
|
delete(dm.networks, netString)
|
|
136
|
+ dm.Unlock()
|
128
|
137
|
}
|
129
|
138
|
|
130
|
139
|
// AddIP adds an IP address to the blocked list.
|
|
@@ -138,21 +147,27 @@ func (dm *DLineManager) AddIP(addr net.IP, length *IPRestrictTime, reason string
|
138
|
147
|
OperReason: operReason,
|
139
|
148
|
},
|
140
|
149
|
}
|
|
150
|
+ dm.Lock()
|
141
|
151
|
dm.addresses[addrString] = &dla
|
|
152
|
+ dm.Unlock()
|
142
|
153
|
}
|
143
|
154
|
|
144
|
155
|
// RemoveIP removes an IP from the blocked list.
|
145
|
156
|
func (dm *DLineManager) RemoveIP(addr net.IP) {
|
146
|
157
|
addrString := addr.String()
|
|
158
|
+ dm.Lock()
|
147
|
159
|
delete(dm.addresses, addrString)
|
|
160
|
+ dm.Unlock()
|
148
|
161
|
}
|
149
|
162
|
|
150
|
163
|
// CheckIP returns whether or not an IP address was banned, and how long it is banned for.
|
151
|
164
|
func (dm *DLineManager) CheckIP(addr net.IP) (isBanned bool, info *IPBanInfo) {
|
152
|
165
|
// check IP addr
|
153
|
166
|
addrString := addr.String()
|
154
|
|
-
|
|
167
|
+ dm.RLock()
|
155
|
168
|
addrInfo := dm.addresses[addrString]
|
|
169
|
+ dm.RUnlock()
|
|
170
|
+
|
156
|
171
|
if addrInfo != nil {
|
157
|
172
|
if addrInfo.Info.Time != nil {
|
158
|
173
|
if addrInfo.Info.Time.IsExpired() {
|
|
@@ -167,30 +182,32 @@ func (dm *DLineManager) CheckIP(addr net.IP) (isBanned bool, info *IPBanInfo) {
|
167
|
182
|
}
|
168
|
183
|
|
169
|
184
|
// check networks
|
170
|
|
- var netsToRemove []net.IPNet
|
171
|
|
-
|
172
|
|
- for _, netInfo := range dm.networks {
|
173
|
|
- if !netInfo.Network.Contains(addr) {
|
174
|
|
- continue
|
|
185
|
+ doCleanup := false
|
|
186
|
+ defer func() {
|
|
187
|
+ if doCleanup {
|
|
188
|
+ go func() {
|
|
189
|
+ dm.Lock()
|
|
190
|
+ defer dm.Unlock()
|
|
191
|
+ for key, netInfo := range dm.networks {
|
|
192
|
+ if netInfo.Info.Time.IsExpired() {
|
|
193
|
+ delete(dm.networks, key)
|
|
194
|
+ }
|
|
195
|
+ }
|
|
196
|
+ }()
|
175
|
197
|
}
|
|
198
|
+ }()
|
176
|
199
|
|
177
|
|
- if netInfo.Info.Time != nil {
|
178
|
|
- if netInfo.Info.Time.IsExpired() {
|
179
|
|
- // ban on network has expired, remove it from our blocked list
|
180
|
|
- netsToRemove = append(netsToRemove, netInfo.Network)
|
181
|
|
- } else {
|
182
|
|
- return true, &addrInfo.Info
|
183
|
|
- }
|
184
|
|
- } else {
|
185
|
|
- return true, &addrInfo.Info
|
186
|
|
- }
|
187
|
|
- }
|
|
200
|
+ dm.RLock()
|
|
201
|
+ defer dm.RUnlock()
|
188
|
202
|
|
189
|
|
- // remove expired networks
|
190
|
|
- for _, expiredNet := range netsToRemove {
|
191
|
|
- dm.RemoveNetwork(expiredNet)
|
|
203
|
+ for _, netInfo := range dm.networks {
|
|
204
|
+ if netInfo.Info.Time != nil && netInfo.Info.Time.IsExpired() {
|
|
205
|
+ // expired ban, ignore and clean up later
|
|
206
|
+ doCleanup = true
|
|
207
|
+ } else if netInfo.Network.Contains(addr) {
|
|
208
|
+ return true, &netInfo.Info
|
|
209
|
+ }
|
192
|
210
|
}
|
193
|
|
-
|
194
|
211
|
// no matches!
|
195
|
212
|
return false, nil
|
196
|
213
|
}
|