Skip to content

Commit 8f6271a

Browse files
committed
Draft of accounting rate limit
1 parent a4ed29c commit 8f6271a

File tree

2 files changed

+96
-2
lines changed

2 files changed

+96
-2
lines changed

go/cmd/pfacct/pfacct.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ type PfAcct struct {
5050
SwitchInfoCache *cache.Cache
5151
NodeSessionCache *cache.Cache
5252
AcctSessionCache *cache.Cache
53+
RateLimit *cache.Cache
54+
MacNas *cache.Cache
5355
StatsdAddress string
5456
StatsdOption statsd.Option
5557
StatsdClient *statsd.Client
@@ -90,6 +92,8 @@ func NewPfAcct() *PfAcct {
9092
pfAcct.SwitchInfoCache = cache.New(5*time.Minute, 10*time.Minute)
9193
pfAcct.NodeSessionCache = cache.New(cache.NoExpiration, cache.NoExpiration)
9294
pfAcct.AcctSessionCache = cache.New(5*time.Minute, 10*time.Minute)
95+
pfAcct.RateLimit = cache.New(5*time.Minute, 10*time.Minute)
96+
pfAcct.MacNas = cache.New(5*time.Minute, 10*time.Minute)
9397
pfAcct.LoggerCtx = ctx
9498
pfAcct.RadiusStatements.Setup(pfAcct.Db)
9599

go/cmd/pfacct/radius.go

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,99 @@ func (h *PfAcct) sendRadiusAccountingCall(r *radius.Request) {
333333
logWarn(ctx, fmt.Sprintf("Empty NAS-IP-Address, using the source IP address of the packet (%s)", attr["NAS-IP-Address"]))
334334
}
335335

336-
if err := h.AAAClient.Notify(ctx, "radius_accounting", attr); err != nil {
337-
logError(ctx, err.Error())
336+
status := rfc2866.AcctStatusType_Get(r.Packet)
337+
338+
if h.rateLimit(attr, status) {
339+
if err := h.AAAClient.Notify(ctx, "radius_accounting", attr); err != nil {
340+
logError(ctx, err.Error())
341+
}
342+
}
343+
}
344+
345+
func (h *PfAcct) rateLimit(attr map[string]interface{}, status rfc2866.AcctStatusType) bool {
346+
347+
NasIp, NasIPExists := attr["NAS-IP-Address"]
348+
CalledStationId, CalledStationIdExists := attr["Called-Station-Id"]
349+
CallingStationId, CallingStationIdExists := attr["Calling-Station-Id"]
350+
FramedIPAddress, FramedIPAddressExists := attr["Framed-IP-Addres"]
351+
var key string
352+
var keyStart string
353+
var macLocValue string
354+
var macAddress mac.Mac
355+
// No CallingStationId
356+
if !CallingStationIdExists {
357+
return false
358+
} else {
359+
macAddress, _ = mac.NewFromString(CallingStationId.(string))
360+
}
361+
362+
macOldLocation, macOldLocationExists := h.MacNas.Get(macAddress.String())
363+
364+
// Generate the keys
365+
if CalledStationIdExists {
366+
key = rfc2866.AcctStatusType_Strings[status] + "-" + CalledStationId.(string) + "-" + CallingStationId.(string)
367+
keyStart = "Start" + "-" + CalledStationId.(string) + "-" + CallingStationId.(string)
368+
macLocValue = CalledStationId.(string)
369+
// h.MacNas.Set(macAddress.String(), CalledStationId, 5*time.Minute)
370+
371+
} else if NasIPExists {
372+
key = rfc2866.AcctStatusType_Strings[status] + "-" + NasIp.(string) + "-" + CallingStationId.(string)
373+
keyStart = "Start" + "-" + NasIp.(string) + "-" + CallingStationId.(string)
374+
macLocValue = NasIp.(string)
375+
// h.MacNas.Set(macAddress.String(), CalledStationId, 5*time.Minute)
376+
} else {
377+
return true
378+
}
379+
380+
if rfc2866.AcctStatusType_Strings[status] == "Start" {
381+
ip, exists := h.RateLimit.Get(key)
382+
if !exists {
383+
h.RateLimit.Set(key, FramedIPAddress, 5*time.Minute)
384+
// Purge old Start entry
385+
if macOldLocationExists && macOldLocation != macLocValue {
386+
// Replace the location
387+
h.MacNas.Set(macAddress.String(), macLocValue, 5*time.Minute)
388+
h.RateLimit.Delete("Start" + macOldLocation.(string) + CallingStationId.(string))
389+
}
390+
return true
391+
} else {
392+
if FramedIPAddressExists && FramedIPAddress != ip.(string) {
393+
h.RateLimit.Set(key, FramedIPAddress, 5*time.Minute)
394+
h.MacNas.Set(macAddress.String(), macLocValue, 5*time.Minute)
395+
return true
396+
} else {
397+
return false
398+
}
399+
}
400+
}
401+
if rfc2866.AcctStatusType_Strings[status] == "Interim-Update" {
402+
// Verify that we already got a start
403+
ip, exists := h.RateLimit.Get(keyStart)
404+
if exists {
405+
if FramedIPAddressExists && FramedIPAddress != ip.(string) {
406+
h.RateLimit.Set(key, FramedIPAddress, 5*time.Minute)
407+
h.MacNas.Set(macAddress.String(), macLocValue, 5*time.Minute)
408+
return true
409+
} else {
410+
return false
411+
}
412+
}
413+
}
414+
if rfc2866.AcctStatusType_Strings[status] == "Stop" {
415+
// Verify that we already got a start
416+
ip, exists := h.RateLimit.Get(keyStart)
417+
if exists {
418+
if FramedIPAddressExists && FramedIPAddress != ip.(string) {
419+
h.RateLimit.Set(key, FramedIPAddress, 5*time.Minute)
420+
h.MacNas.Set(macAddress.String(), macLocValue, 5*time.Minute)
421+
return true
422+
} else {
423+
return false
424+
}
425+
}
426+
338427
}
428+
return false
339429
}
340430

341431
func (h *PfAcct) radiusListen(w *sync.WaitGroup) *radius.PacketServer {

0 commit comments

Comments
 (0)