ip_pool.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package sessdata
  2. import (
  3. "encoding/binary"
  4. "net"
  5. "sync"
  6. "time"
  7. "github.com/bjdgyc/anylink/base"
  8. "github.com/bjdgyc/anylink/dbdata"
  9. )
  10. var (
  11. IpPool = &ipPoolConfig{}
  12. ipActive = map[string]bool{}
  13. )
  14. type ipPoolConfig struct {
  15. mux sync.Mutex
  16. // 计算动态ip
  17. Ipv4Gateway net.IP
  18. Ipv4Mask net.IP
  19. Ipv4IPNet *net.IPNet
  20. IpLongMin uint32
  21. IpLongMax uint32
  22. }
  23. func initIpPool() {
  24. // 地址处理
  25. _, ipNet, err := net.ParseCIDR(base.Cfg.Ipv4CIDR)
  26. if err != nil {
  27. panic(err)
  28. }
  29. IpPool.Ipv4IPNet = ipNet
  30. IpPool.Ipv4Mask = net.IP(ipNet.Mask)
  31. IpPool.Ipv4Gateway = net.ParseIP(base.Cfg.Ipv4Gateway)
  32. // 网络地址零值
  33. // zero := binary.BigEndian.Uint32(ip.Mask(mask))
  34. // 广播地址
  35. // one, _ := ipNet.Mask.Size()
  36. // max := min | uint32(math.Pow(2, float64(32-one))-1)
  37. // ip地址池
  38. IpPool.IpLongMin = ip2long(net.ParseIP(base.Cfg.Ipv4Start))
  39. IpPool.IpLongMax = ip2long(net.ParseIP(base.Cfg.Ipv4End))
  40. }
  41. func long2ip(i uint32) net.IP {
  42. ip := make([]byte, 4)
  43. binary.BigEndian.PutUint32(ip, i)
  44. return ip
  45. }
  46. func ip2long(ip net.IP) uint32 {
  47. ip = ip.To4()
  48. return binary.BigEndian.Uint32(ip)
  49. }
  50. // AcquireIp 获取动态ip
  51. func AcquireIp(username, macAddr string) net.IP {
  52. IpPool.mux.Lock()
  53. defer IpPool.mux.Unlock()
  54. tNow := time.Now()
  55. // 判断已经分配过
  56. mi := &dbdata.IpMap{}
  57. err := dbdata.One("MacAddr", macAddr, mi)
  58. if err == nil {
  59. ip := mi.IpAddr
  60. ipStr := ip.String()
  61. // 跳过活跃连接
  62. _, ok := ipActive[ipStr]
  63. // 检测原有ip是否在新的ip池内
  64. if IpPool.Ipv4IPNet.Contains(ip) && !ok {
  65. mi.Username = username
  66. mi.LastLogin = tNow
  67. // 回写db数据
  68. _ = dbdata.Save(mi)
  69. ipActive[ipStr] = true
  70. return ip
  71. }
  72. _ = dbdata.Del(mi)
  73. }
  74. farIp := &dbdata.IpMap{LastLogin: tNow}
  75. // 全局遍历超过租期ip
  76. for i := IpPool.IpLongMin; i <= IpPool.IpLongMax; i++ {
  77. ip := long2ip(i)
  78. ipStr := ip.String()
  79. // 跳过活跃连接
  80. if _, ok := ipActive[ipStr]; ok {
  81. continue
  82. }
  83. v := &dbdata.IpMap{}
  84. err = dbdata.One("IpAddr", ip, v)
  85. if err != nil {
  86. if dbdata.CheckErrNotFound(err) {
  87. // 该ip没有被使用
  88. mi = &dbdata.IpMap{IpAddr: ip, MacAddr: macAddr, Username: username, LastLogin: tNow}
  89. _ = dbdata.Save(mi)
  90. ipActive[ipStr] = true
  91. return ip
  92. }
  93. base.Error(err)
  94. return nil
  95. }
  96. // 跳过ip保留
  97. if v.Keep {
  98. continue
  99. }
  100. // 已经超过租期
  101. if tNow.Sub(v.LastLogin) > time.Duration(base.Cfg.IpLease)*time.Second {
  102. _ = dbdata.Del(v)
  103. mi = &dbdata.IpMap{IpAddr: ip, MacAddr: macAddr, Username: username, LastLogin: tNow}
  104. // 重写db数据
  105. _ = dbdata.Save(mi)
  106. ipActive[ipStr] = true
  107. return ip
  108. }
  109. // 其他情况判断最早登陆
  110. if v.LastLogin.Before(farIp.LastLogin) {
  111. farIp = v
  112. }
  113. }
  114. // 全都在线,没有数据可用
  115. if farIp.Id == 0 {
  116. return nil
  117. }
  118. // 使用最早登陆的mac ip
  119. ip := farIp.IpAddr
  120. ipStr := ip.String()
  121. mi = &dbdata.IpMap{IpAddr: ip, MacAddr: macAddr, Username: username, LastLogin: tNow}
  122. // 回写db数据
  123. _ = dbdata.Save(mi)
  124. ipActive[ipStr] = true
  125. return ip
  126. }
  127. // 回收ip
  128. func ReleaseIp(ip net.IP, macAddr string) {
  129. IpPool.mux.Lock()
  130. defer IpPool.mux.Unlock()
  131. delete(ipActive, ip.String())
  132. mi := &dbdata.IpMap{}
  133. err := dbdata.One("IpAddr", ip, mi)
  134. if err == nil {
  135. mi.LastLogin = time.Now()
  136. _ = dbdata.Save(mi)
  137. }
  138. }