performance optimization test
All checks were successful
release-tag / release-image (push) Successful in 1m49s
All checks were successful
release-tag / release-image (push) Successful in 1m49s
This commit is contained in:
105
main.go
105
main.go
@@ -728,7 +728,7 @@ func importCategory(st Store, cat, url string) (int, error) {
|
|||||||
return count, sc.Err()
|
return count, sc.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func startImporter(st Store, cats map[string]string) {
|
func startImporter(st Store, cats map[string]string, srv *server) {
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
@@ -752,6 +752,7 @@ func startImporter(st Store, cats map[string]string) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
srv.rebuildIndex()
|
||||||
atomic.AddUint64(&metrics.importerCycles, 1)
|
atomic.AddUint64(&metrics.importerCycles, 1)
|
||||||
atomic.StoreInt64(&metrics.importerLastSuccess, time.Now().Unix())
|
atomic.StoreInt64(&metrics.importerLastSuccess, time.Now().Unix())
|
||||||
log.Printf("Import cycle finished in %s", time.Since(start))
|
log.Printf("Import cycle finished in %s", time.Since(start))
|
||||||
@@ -764,10 +765,74 @@ func startImporter(st Store, cats map[string]string) {
|
|||||||
// HTTP layer
|
// HTTP layer
|
||||||
// ──────────────────────────────────────────────────────────────────────────────
|
// ──────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
type ipIndex struct {
|
||||||
|
v4Lens []int // vorhandene Präfixlängen (z. B. 8, 16, 24, 32)
|
||||||
|
v6Lens []int
|
||||||
|
v4 map[int]map[string][]string // len -> "a.b.c.d/len" -> []categories
|
||||||
|
v6 map[int]map[string][]string // len -> "xxxx::/len" -> []categories
|
||||||
|
}
|
||||||
|
|
||||||
type server struct {
|
type server struct {
|
||||||
st Store
|
st Store
|
||||||
catalog map[string]string // latest catalog for category list
|
catalog map[string]string // latest catalog for category list
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
idx atomic.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) rebuildIndex() {
|
||||||
|
idx := &ipIndex{v4: map[int]map[string][]string{}, v6: map[int]map[string][]string{}}
|
||||||
|
lens4 := map[int]struct{}{}
|
||||||
|
lens6 := map[int]struct{}{}
|
||||||
|
|
||||||
|
cats := s.cats()
|
||||||
|
for _, c := range cats {
|
||||||
|
pfxs, _ := s.st.ListPrefixes(c)
|
||||||
|
for _, p := range pfxs {
|
||||||
|
m := idx.v6
|
||||||
|
lens := lens6
|
||||||
|
if p.Addr().Is4() {
|
||||||
|
m = idx.v4
|
||||||
|
lens = lens4
|
||||||
|
}
|
||||||
|
l := int(p.Bits())
|
||||||
|
if m[l] == nil {
|
||||||
|
m[l] = map[string][]string{}
|
||||||
|
}
|
||||||
|
k := p.String()
|
||||||
|
m[l][k] = append(m[l][k], c)
|
||||||
|
lens[l] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// manuelle Blacklist mit aufnehmen (als Kategorie "manual-blacklist")
|
||||||
|
if bl, err := s.st.ListBlacklist(); err == nil {
|
||||||
|
for p := range bl {
|
||||||
|
m := idx.v6
|
||||||
|
lens := lens6
|
||||||
|
if p.Addr().Is4() {
|
||||||
|
m = idx.v4
|
||||||
|
lens = lens4
|
||||||
|
}
|
||||||
|
l := int(p.Bits())
|
||||||
|
if m[l] == nil {
|
||||||
|
m[l] = map[string][]string{}
|
||||||
|
}
|
||||||
|
k := p.String()
|
||||||
|
m[l][k] = append(m[l][k], "manual-blacklist")
|
||||||
|
lens[l] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Längen sortiert ablegen (damit Lookup nur vorhandene prüft)
|
||||||
|
for l := range lens4 {
|
||||||
|
idx.v4Lens = append(idx.v4Lens, l)
|
||||||
|
}
|
||||||
|
for l := range lens6 {
|
||||||
|
idx.v6Lens = append(idx.v6Lens, l)
|
||||||
|
}
|
||||||
|
sort.Ints(idx.v4Lens)
|
||||||
|
sort.Ints(idx.v6Lens)
|
||||||
|
|
||||||
|
s.idx.Store(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) cats() []string {
|
func (s *server) cats() []string {
|
||||||
@@ -1310,32 +1375,30 @@ func (s *server) handleBlacklistList(w http.ResponseWriter, r *http.Request) {
|
|||||||
writeJSON(w, map[string]any{"entries": list})
|
writeJSON(w, map[string]any{"entries": list})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) checkIP(ip netip.Addr, cats []string) ([]string, error) {
|
func (s *server) checkIP(ip netip.Addr, _ []string) ([]string, error) {
|
||||||
// 1) Whitelist gewinnt
|
|
||||||
if ok, _ := s.st.IsWhitelisted(ip); ok {
|
if ok, _ := s.st.IsWhitelisted(ip); ok {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2) Manuelle Blacklist
|
idx := s.idx.Load().(*ipIndex)
|
||||||
bl, _ := s.st.ListBlacklist()
|
var lens []int
|
||||||
for pfx := range bl {
|
var m map[int]map[string][]string
|
||||||
if pfx.Contains(ip) {
|
if ip.Is4() {
|
||||||
// "manual-blacklist" als erste Kategorie markieren
|
lens, m = idx.v4Lens, idx.v4
|
||||||
return []string{"manual-blacklist"}, nil
|
} else {
|
||||||
}
|
lens, m = idx.v6Lens, idx.v6
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) Import-Kategorien
|
seen := map[string]struct{}{}
|
||||||
var matches []string
|
var matches []string
|
||||||
for _, c := range cats {
|
for _, l := range lens {
|
||||||
pfxs, err := s.st.ListPrefixes(c)
|
p := netip.PrefixFrom(ip, l).String()
|
||||||
if err != nil {
|
if cats, ok := m[l][p]; ok {
|
||||||
return nil, err
|
for _, c := range cats {
|
||||||
}
|
if _, dup := seen[c]; !dup {
|
||||||
for _, p := range pfxs {
|
seen[c] = struct{}{}
|
||||||
if p.Contains(ip) {
|
matches = append(matches, c)
|
||||||
matches = append(matches, c)
|
}
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1428,7 +1491,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
srv := &server{st: st, catalog: cat}
|
srv := &server{st: st, catalog: cat}
|
||||||
startImporter(st, cat)
|
startImporter(st, cat, srv)
|
||||||
|
|
||||||
// honeypot listeners
|
// honeypot listeners
|
||||||
if enableHoneypot {
|
if enableHoneypot {
|
||||||
|
|||||||
Reference in New Issue
Block a user