diff --git a/server/sessdata/ip_pool.go b/server/sessdata/ip_pool.go index e1971a5..8d49496 100644 --- a/server/sessdata/ip_pool.go +++ b/server/sessdata/ip_pool.go @@ -13,11 +13,9 @@ import ( var ( IpPool = &ipPoolConfig{} ipActive = map[string]bool{} - // ipKeep and ipLease ipAddr => type - // ipLease = map[string]bool{} + // ipKeep and ipLease ipAddr => macAddr + // ipKeep = map[string]string{} ipPoolMux sync.Mutex - // 记录循环点 - loopCurIp uint32 ) type ipPoolConfig struct { @@ -73,17 +71,16 @@ func initIpPool() { // func getIpLease() { // xdb := dbdata.GetXdb() // keepIpMaps := []dbdata.IpMap{} -// sNow := time.Now().Add(-1 * time.Duration(base.Cfg.IpLease) * time.Second) -// err := xdb.Cols("ip_addr").Where("keep=?", true). -// Or("unique_mac=? and last_login>?", true, sNow).Find(&keepIpMaps) +// // sNow := time.Now().Add(-1 * time.Duration(base.Cfg.IpLease) * time.Second) +// err := xdb.Cols("ip_addr", "mac_addr").Where("keep=?", true).Find(&keepIpMaps) // if err != nil { // base.Error(err) // } -// // fmt.Println(keepIpMaps) +// log.Println(keepIpMaps) // ipPoolMux.Lock() -// ipLease = map[string]bool{} +// ipKeep = map[string]string{} // for _, v := range keepIpMaps { -// ipLease[v.IpAddr] = true +// ipKeep[v.IpAddr] = v.MacAddr // } // ipPoolMux.Unlock() // } @@ -95,6 +92,7 @@ func AcquireIp(username, macAddr string, uniqueMac bool) (newIp net.IP) { defer func() { ipPoolMux.Unlock() base.Trace("AcquireIp end:", username, macAddr, uniqueMac, newIp) + base.Info("AcquireIp ip:", username, macAddr, uniqueMac, newIp) }() var ( @@ -102,6 +100,7 @@ func AcquireIp(username, macAddr string, uniqueMac bool) (newIp net.IP) { tNow = time.Now() ) + // 获取到客户端 macAddr 的情况 if uniqueMac { // 判断是否已经分配过 mi := &dbdata.IpMap{} @@ -124,8 +123,9 @@ func AcquireIp(username, macAddr string, uniqueMac bool) (newIp net.IP) { _, ok := ipActive[ipStr] // 检测原有ip是否在新的ip池内 // IpPool.Ipv4IPNet.Contains(ip) && - if !ok && - utils.Ip2long(ip) >= IpPool.IpLongMin && + // ip符合规范 + // 检测原有ip是否在新的ip池内 + if !ok && utils.Ip2long(ip) >= IpPool.IpLongMin && utils.Ip2long(ip) <= IpPool.IpLongMax { mi.Username = username mi.LastLogin = tNow @@ -135,61 +135,84 @@ func AcquireIp(username, macAddr string, uniqueMac bool) (newIp net.IP) { ipActive[ipStr] = true return ip } - // 删除当前macAddr - mi = &dbdata.IpMap{MacAddr: macAddr} - _ = dbdata.Del(mi) - } else { - // 没有获取到mac的情况 - ipMaps := []dbdata.IpMap{} - err = dbdata.FindWhere(&ipMaps, 50, 1, "username=? and unique_mac=?", username, false) - if err != nil { - // 没有查询到数据 - if dbdata.CheckErrNotFound(err) { - return loopIp(username, macAddr, uniqueMac) - } - // 查询报错 - base.Error(err) + // ip保留 + if mi.Keep { + base.Error(username, macAddr, ipStr, "保留ip不匹配CIDR") return nil } - // 遍历mac记录 - for _, mi := range ipMaps { - ipStr := mi.IpAddr - ip := net.ParseIP(ipStr) + // 删除当前macAddr + mi = &dbdata.IpMap{MacAddr: macAddr} + _ = dbdata.Del(mi) + return loopIp(username, macAddr, uniqueMac) + } - // 跳过活跃连接 - if _, ok := ipActive[ipStr]; ok { - continue - } - // 跳过保留ip - if mi.Keep { - continue - } - // 没有mac的 不需要验证租期 - // mi.LastLogin.Before(leaseTime) && - if utils.Ip2long(ip) >= IpPool.IpLongMin && - utils.Ip2long(ip) <= IpPool.IpLongMax { - mi.LastLogin = tNow - mi.MacAddr = macAddr - mi.UniqueMac = uniqueMac - // 回写db数据 - _ = dbdata.Set(mi) - ipActive[ipStr] = true - return ip - } + // 没有获取到mac的情况 + ipMaps := []dbdata.IpMap{} + err = dbdata.FindWhere(&ipMaps, 50, 1, "username=?", username) + if err != nil { + // 没有查询到数据 + if dbdata.CheckErrNotFound(err) { + return loopIp(username, macAddr, uniqueMac) + } + // 查询报错 + base.Error(err) + return nil + } + + // 遍历mac记录 + for _, mi := range ipMaps { + ipStr := mi.IpAddr + ip := net.ParseIP(ipStr) + + // 跳过活跃连接 + if _, ok := ipActive[ipStr]; ok { + continue + } + // 跳过保留ip + if mi.Keep { + continue + } + if mi.UniqueMac { + continue + } + + // 没有mac的 不需要验证租期 + // mi.LastLogin.Before(leaseTime) && + if utils.Ip2long(ip) >= IpPool.IpLongMin && + utils.Ip2long(ip) <= IpPool.IpLongMax { + mi.Username = username + mi.LastLogin = tNow + mi.MacAddr = macAddr + mi.UniqueMac = uniqueMac + // 回写db数据 + _ = dbdata.Set(mi) + ipActive[ipStr] = true + return ip } } return loopIp(username, macAddr, uniqueMac) } +var ( + // 记录循环点 + loopCurIp uint32 + loopFarIp = &dbdata.IpMap{LastLogin: time.Now()} + loopFarI = uint32(0) +) + func loopIp(username, macAddr string, uniqueMac bool) net.IP { var ( i uint32 ip net.IP ) + // 重新赋值 + loopFarIp = &dbdata.IpMap{LastLogin: time.Now()} + loopFarI = uint32(0) + i, ip = loopLong(loopCurIp, IpPool.IpLongMax, username, macAddr, uniqueMac) if ip != nil { loopCurIp = i @@ -202,6 +225,22 @@ func loopIp(username, macAddr string, uniqueMac bool) net.IP { return ip } + // ip分配完,从头开始 + loopCurIp = IpPool.IpLongMin + + if loopFarIp.Id > 0 { + // 使用最早登陆的 ip + ipStr := loopFarIp.IpAddr + ip = net.ParseIP(ipStr) + mi := &dbdata.IpMap{IpAddr: ipStr, MacAddr: macAddr, UniqueMac: uniqueMac, Username: username, LastLogin: time.Now()} + // 回写db数据 + _ = dbdata.Set(mi) + ipActive[ipStr] = true + + return ip + } + + // 全都在线,没有数据可用 base.Warn("no ip available, please see ip_map table row", username, macAddr) return nil } @@ -247,6 +286,7 @@ func loopLong(start, end uint32, username, macAddr string, uniqueMac bool) (uint // 判断租期 if mi.LastLogin.Before(leaseTime) { // 存在记录,说明已经超过租期,可以直接使用 + mi.Username = username mi.LastLogin = tNow mi.MacAddr = macAddr mi.UniqueMac = uniqueMac @@ -255,6 +295,11 @@ func loopLong(start, end uint32, username, macAddr string, uniqueMac bool) (uint ipActive[ipStr] = true return i, ip } + // 其他情况判断最早登陆 + if mi.LastLogin.Before(loopFarIp.LastLogin) { + loopFarIp = mi + loopFarI = i + } } return 0, nil diff --git a/web/src/pages/user/IpMap.vue b/web/src/pages/user/IpMap.vue index 5b4755a..78d49e6 100644 --- a/web/src/pages/user/IpMap.vue +++ b/web/src/pages/user/IpMap.vue @@ -48,6 +48,7 @@ label="唯一MAC">