helper.go 3.0 KB

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