diff --git a/server/base/cfg.go b/server/base/cfg.go index 4c7f840..3df1113 100644 --- a/server/base/cfg.go +++ b/server/base/cfg.go @@ -72,6 +72,8 @@ type ServerConfig struct { SessionTimeout int `json:"session_timeout"` // in seconds // AuthTimeout int `json:"auth_timeout"` // in seconds AuditInterval int `json:"audit_interval"` // in seconds + + ShowSQL bool `json:"show_sql"` // bool } func initServerCfg() { diff --git a/server/base/config.go b/server/base/config.go index 7195611..50f9e28 100644 --- a/server/base/config.go +++ b/server/base/config.go @@ -59,6 +59,8 @@ var configs = []config{ {Typ: cfgInt, Name: "session_timeout", Usage: "session过期时间(秒)", ValInt: 3600}, // {Typ: cfgInt, Name: "auth_timeout", Usage: "auth_timeout", ValInt: 0}, {Typ: cfgInt, Name: "audit_interval", Usage: "审计去重间隔(秒),-1关闭", ValInt: -1}, + + {Typ: cfgBool, Name: "show_sql", Usage: "显示sql语句,用于调试", ValBool: false}, } var envs = map[string]string{} diff --git a/server/conf/server-sample.toml b/server/conf/server-sample.toml index 81f30af..785e901 100644 --- a/server/conf/server-sample.toml +++ b/server/conf/server-sample.toml @@ -73,6 +73,7 @@ session_timeout = 3600 auth_timeout = 0 audit_interval = -1 +show_sql = false diff --git a/server/dbdata/db.go b/server/dbdata/db.go index c52d209..771820c 100644 --- a/server/dbdata/db.go +++ b/server/dbdata/db.go @@ -19,11 +19,14 @@ func GetXdb() *xorm.Engine { func initDb() { var err error xdb, err = xorm.NewEngine(base.Cfg.DbType, base.Cfg.DbSource) - // xdb.ShowSQL(true) if err != nil { base.Fatal(err) } + if base.Cfg.ShowSQL { + xdb.ShowSQL(true) + } + // 初始化数据库 err = xdb.Sync2(&User{}, &Setting{}, &Group{}, &IpMap{}, &AccessAudit{}, &Policy{}, &StatsNetwork{}, &StatsCpu{}, &StatsMem{}, &StatsOnline{}) if err != nil { diff --git a/server/dbdata/tables.go b/server/dbdata/tables.go index 9249643..e0da7e0 100644 --- a/server/dbdata/tables.go +++ b/server/dbdata/tables.go @@ -47,7 +47,7 @@ type IpMap struct { Keep bool `json:"keep" xorm:"Bool"` // 保留 ip-mac 绑定 KeepTime time.Time `json:"keep_time" xorm:"DateTime"` Note string `json:"note" xorm:"varchar(255)"` // 备注 - LastLogin time.Time `json:"last_login" xorm:"DateTime updated"` + LastLogin time.Time `json:"last_login" xorm:"DateTime"` UpdatedAt time.Time `json:"updated_at" xorm:"DateTime updated"` } diff --git a/server/sessdata/ip_pool.go b/server/sessdata/ip_pool.go index 7fdf207..57ea969 100644 --- a/server/sessdata/ip_pool.go +++ b/server/sessdata/ip_pool.go @@ -13,6 +13,8 @@ import ( var ( IpPool = &ipPoolConfig{} ipActive = map[string]bool{} + // ipKeep and ipLease ipAddr => type + ipLease = map[string]bool{} ) type ipPoolConfig struct { @@ -45,6 +47,33 @@ func initIpPool() { // ip地址池 IpPool.IpLongMin = utils.Ip2long(net.ParseIP(base.Cfg.Ipv4Start)) IpPool.IpLongMax = utils.Ip2long(net.ParseIP(base.Cfg.Ipv4End)) + + // 获取IpLease数据 + go cronIpLease() +} + +func cronIpLease() { + getIpLease() + tick := time.NewTicker(time.Minute * 30) + for range tick.C { + getIpLease() + } +} + +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("last_login>?", sNow).Find(&keepIpMaps) + if err != nil { + base.Error(err) + } + // fmt.Println(keepIpMaps) + IpPool.mux.Lock() + for _, v := range keepIpMaps { + ipLease[v.IpAddr] = true + } + IpPool.mux.Unlock() } // AcquireIp 获取动态ip @@ -54,30 +83,28 @@ func AcquireIp(username, macAddr string) net.IP { tNow := time.Now() - // 判断已经分配过 + // 判断是否已经分配过 mi := &dbdata.IpMap{} err := dbdata.One("mac_addr", macAddr, mi) + // 存在ip记录 if err == nil { ipStr := mi.IpAddr ip := net.ParseIP(ipStr) // 跳过活跃连接 - _, ok := ipActive[ipStr] + // _, ok := ipActive[ipStr] // 检测原有ip是否在新的ip池内 - if IpPool.Ipv4IPNet.Contains(ip) && !ok { + if IpPool.Ipv4IPNet.Contains(ip) { mi.Username = username mi.LastLogin = tNow // 回写db数据 - _ = dbdata.Add(mi) + _ = dbdata.Set(mi) ipActive[ipStr] = true return ip } - _ = dbdata.Del(mi) - } - farIp := &dbdata.IpMap{LastLogin: tNow} - // 全局遍历超过租期ip + // 全局遍历超过租期和未保留的ip for i := IpPool.IpLongMin; i <= IpPool.IpLongMax; i++ { ip := utils.Long2ip(i) ipStr := ip.String() @@ -86,55 +113,32 @@ func AcquireIp(username, macAddr string) net.IP { if _, ok := ipActive[ipStr]; ok { continue } - - v := &dbdata.IpMap{} - err = dbdata.One("ip_addr", ipStr, v) - if err != nil { - if dbdata.CheckErrNotFound(err) { - // 该ip没有被使用 - mi = &dbdata.IpMap{IpAddr: ipStr, MacAddr: macAddr, Username: username, LastLogin: tNow} - _ = dbdata.Add(mi) - ipActive[ipStr] = true - return ip - } - base.Error(err) - return nil - } - - // 跳过ip保留 - if v.Keep { + // 跳过ip租期内数据 + if _, ok := ipLease[ipStr]; ok { continue } - // 已经超过租期 - if tNow.Sub(v.LastLogin) > time.Duration(base.Cfg.IpLease)*time.Second { - _ = dbdata.Del(v) + v := &dbdata.IpMap{} + err = dbdata.One("ip_addr", ipStr, v) + if err == nil { + // 存在记录直接跳过 + continue + } + + if dbdata.CheckErrNotFound(err) { + // 该ip没有被使用 mi = &dbdata.IpMap{IpAddr: ipStr, MacAddr: macAddr, Username: username, LastLogin: tNow} - // 重写db数据 _ = dbdata.Add(mi) ipActive[ipStr] = true return ip } - - // 其他情况判断最早登陆 - if v.LastLogin.Before(farIp.LastLogin) { - farIp = v - } - } - - // 全都在线,没有数据可用 - if farIp.Id == 0 { + // 查询报错 + base.Error(err) return nil } - // 使用最早登陆的mac ip - ipStr := farIp.IpAddr - ip := net.ParseIP(ipStr) - mi = &dbdata.IpMap{IpAddr: ipStr, MacAddr: macAddr, Username: username, LastLogin: tNow} - // 回写db数据 - _ = dbdata.Add(mi) - ipActive[ipStr] = true - return ip + base.Error("no ip available, please del ip_map table row") + return nil } // 回收ip @@ -143,10 +147,11 @@ func ReleaseIp(ip net.IP, macAddr string) { defer IpPool.mux.Unlock() delete(ipActive, ip.String()) + mi := &dbdata.IpMap{} err := dbdata.One("ip_addr", ip.String(), mi) if err == nil { mi.LastLogin = time.Now() - _ = dbdata.Add(mi) + _ = dbdata.Set(mi) } }