helper.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package web
  2. import (
  3. v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
  4. "net"
  5. )
  6. // FindDifferenceList 查找两个列表的差异
  7. func (s *AidedWebService) FindDifferenceList(oldList, newList []v1.BackendList) (added, removed []v1.BackendList) {
  8. diff := make(map[v1.BackendList]int)
  9. // 1. 遍历旧列表,为每个元素计数 +1
  10. for _, item := range oldList {
  11. diff[item]++
  12. }
  13. // 2. 遍历新列表,为每个元素计数 -1
  14. for _, item := range newList {
  15. diff[item]--
  16. }
  17. // 3. 遍历 diff map 来找出差异
  18. for item, count := range diff {
  19. if count > 0 {
  20. // 如果 count > 0,说明这个元素在 oldList 中但不在 newList 中
  21. removed = append(removed, item)
  22. } else if count < 0 {
  23. // 如果 count < 0,说明这个元素在 newList 中但不在 oldList 中
  24. added = append(added, item)
  25. }
  26. // 如果 count == 0,说明元素在两个列表中都存在,不做任何操作
  27. }
  28. return added, removed
  29. }
  30. // WashDifferentIp 清洗IP差异 - 并发版本
  31. func (s *AidedWebService) WashDifferentIp(newIpList []string, oldIpList []string) (addedDenyIps []string, removedDenyIps []string) {
  32. // 并发验证并过滤有效IP
  33. oldAllowIps := s.filterValidIpsConcurrently(oldIpList)
  34. newAllowIps := s.filterValidIpsConcurrently(newIpList)
  35. addedDenyIps, removedDenyIps = s.wafformatter.FindIpDifferences(oldAllowIps, newAllowIps)
  36. return addedDenyIps, removedDenyIps
  37. }
  38. // filterValidIpsConcurrently 并发过滤有效IP地址
  39. func (s *AidedWebService) filterValidIpsConcurrently(ipList []string) []string {
  40. if len(ipList) == 0 {
  41. return nil
  42. }
  43. // 小于10个IP时不使用并发,避免overhead
  44. if len(ipList) < 10 {
  45. return s.filterValidIpsSequentially(ipList)
  46. }
  47. type ipResult struct {
  48. ip string
  49. valid bool
  50. index int
  51. }
  52. resultChan := make(chan ipResult, len(ipList))
  53. semaphore := make(chan struct{}, 20) // 限制并发数为20
  54. // 启动goroutine验证IP
  55. for i, ip := range ipList {
  56. go func(ip string, index int) {
  57. semaphore <- struct{}{} // 获取信号量
  58. defer func() { <-semaphore }() // 释放信号量
  59. valid := net.ParseIP(ip) != nil
  60. resultChan <- ipResult{ip: ip, valid: valid, index: index}
  61. }(ip, i)
  62. }
  63. // 收集结果并保持原始顺序
  64. results := make([]ipResult, len(ipList))
  65. for i := 0; i < len(ipList); i++ {
  66. result := <-resultChan
  67. results[result.index] = result
  68. }
  69. close(resultChan)
  70. // 按原始顺序提取有效IP
  71. var validIps []string
  72. for _, result := range results {
  73. if result.valid {
  74. validIps = append(validIps, result.ip)
  75. }
  76. }
  77. return validIps
  78. }
  79. // filterValidIpsSequentially 顺序过滤有效IP地址(用于小数据集)
  80. func (s *AidedWebService) filterValidIpsSequentially(ipList []string) []string {
  81. var validIps []string
  82. for _, ip := range ipList {
  83. if net.ParseIP(ip) != nil {
  84. validIps = append(validIps, ip)
  85. }
  86. }
  87. return validIps
  88. }