mirror of
				https://github.com/bjdgyc/anylink.git
				synced 2025-10-31 16:43:28 +08:00 
			
		
		
		
	优化ip获取流程
This commit is contained in:
		| @@ -60,6 +60,7 @@ type IpMap struct { | ||||
| 	Id        int       `json:"id" xorm:"pk autoincr not null"` | ||||
| 	IpAddr    string    `json:"ip_addr" xorm:"varchar(32) not null unique"` | ||||
| 	MacAddr   string    `json:"mac_addr" xorm:"varchar(32) not null unique"` | ||||
| 	UniqueMac bool      `json:"unique_mac" xorm:"Bool index"` | ||||
| 	Username  string    `json:"username" xorm:"varchar(60)"` | ||||
| 	Keep      bool      `json:"keep" xorm:"Bool"` // 保留 ip-mac 绑定 | ||||
| 	KeepTime  time.Time `json:"keep_time" xorm:"DateTime"` | ||||
|   | ||||
| @@ -18,6 +18,10 @@ import ( | ||||
| var profileHash = "" | ||||
|  | ||||
| func LinkAuth(w http.ResponseWriter, r *http.Request) { | ||||
| 	// TODO 调试信息输出 | ||||
| 	//hd, _ := httputil.DumpRequest(r, true) | ||||
| 	//base.Debug("DumpRequest: ", string(hd)) | ||||
|  | ||||
| 	// 判断anyconnect客户端 | ||||
| 	userAgent := strings.ToLower(r.UserAgent()) | ||||
| 	xAggregateAuth := r.Header.Get("X-Aggregate-Auth") | ||||
| @@ -106,6 +110,7 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) { | ||||
| 	sess.PlatformVersion = ua.PlatformVersion | ||||
| 	sess.RemoteAddr = r.RemoteAddr | ||||
| 	// 获取客户端mac地址 | ||||
| 	sess.UniqueMac = true | ||||
| 	macHw, err := net.ParseMAC(sess.MacAddr) | ||||
| 	if err != nil { | ||||
| 		var sum [16]byte | ||||
| @@ -113,6 +118,7 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) { | ||||
| 			sum = md5.Sum([]byte(sess.UniqueIdGlobal)) | ||||
| 		} else { | ||||
| 			sum = md5.Sum([]byte(sess.Token)) | ||||
| 			sess.UniqueMac = false | ||||
| 		} | ||||
| 		macHw = sum[0:5] // 5个byte | ||||
| 		macHw = append([]byte{0x02}, macHw...) | ||||
|   | ||||
| @@ -34,9 +34,8 @@ func HttpAddHeader(w http.ResponseWriter, key string, value string) { | ||||
|  | ||||
| func LinkTunnel(w http.ResponseWriter, r *http.Request) { | ||||
| 	// TODO 调试信息输出 | ||||
| 	// hd, _ := httputil.DumpRequest(r, true) | ||||
| 	// fmt.Println("DumpRequest: ", string(hd)) | ||||
| 	// fmt.Println("LinkTunnel", r.RemoteAddr) | ||||
| 	//hd, _ := httputil.DumpRequest(r, true) | ||||
| 	//base.Debug("DumpRequest: ", string(hd)) | ||||
|  | ||||
| 	// 判断session-token的值 | ||||
| 	cookie, err := r.Cookie("webvpn") | ||||
|   | ||||
| @@ -66,7 +66,7 @@ func startTls() { | ||||
| 	if base.Cfg.ProxyProtocol { | ||||
| 		ln = &proxyproto.Listener{ | ||||
| 			Listener:          ln, | ||||
| 			ReadHeaderTimeout: 20 * time.Second, | ||||
| 			ReadHeaderTimeout: 40 * time.Second, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -64,7 +64,8 @@ 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) | ||||
| 	err := xdb.Cols("ip_addr").Where("keep=?", true). | ||||
| 		Or("unique_mac=? and last_login>?", true, sNow).Find(&keepIpMaps) | ||||
| 	if err != nil { | ||||
| 		base.Error(err) | ||||
| 	} | ||||
| @@ -78,33 +79,71 @@ func getIpLease() { | ||||
| } | ||||
|  | ||||
| // AcquireIp 获取动态ip | ||||
| func AcquireIp(username, macAddr string) net.IP { | ||||
| func AcquireIp(username, macAddr string, uniqueMac bool) net.IP { | ||||
| 	ipPoolMux.Lock() | ||||
| 	defer ipPoolMux.Unlock() | ||||
|  | ||||
| 	tNow := time.Now() | ||||
| 	var ( | ||||
| 		err  error | ||||
| 		tNow = time.Now() | ||||
| 		sNow = time.Now().Add(-1 * time.Duration(base.Cfg.IpLease) * time.Second) | ||||
| 	) | ||||
|  | ||||
| 	// 判断是否已经分配过 | ||||
| 	mi := &dbdata.IpMap{} | ||||
| 	err := dbdata.One("mac_addr", macAddr, mi) | ||||
| 	// 存在ip记录 | ||||
| 	if err == nil { | ||||
| 		ipStr := mi.IpAddr | ||||
| 		ip := net.ParseIP(ipStr) | ||||
| 		// 跳过活跃连接 | ||||
| 		_, ok := ipActive[ipStr] | ||||
| 		// 检测原有ip是否在新的ip池内 | ||||
| 		if IpPool.Ipv4IPNet.Contains(ip) && !ok && | ||||
| 			utils.Ip2long(ip) >= IpPool.IpLongMin && | ||||
| 			utils.Ip2long(ip) <= IpPool.IpLongMax { | ||||
| 			mi.Username = username | ||||
| 			mi.LastLogin = tNow | ||||
| 			// 回写db数据 | ||||
| 			_ = dbdata.Set(mi) | ||||
| 			ipActive[ipStr] = true | ||||
| 			return ip | ||||
| 	if uniqueMac { | ||||
| 		// 判断是否已经分配过 | ||||
| 		mi := &dbdata.IpMap{} | ||||
| 		err = dbdata.One("mac_addr", macAddr, mi) | ||||
| 		// 存在ip记录 | ||||
| 		if err == nil { | ||||
| 			ipStr := mi.IpAddr | ||||
| 			ip := net.ParseIP(ipStr) | ||||
| 			// 跳过活跃连接 | ||||
| 			_, ok := ipActive[ipStr] | ||||
| 			// 检测原有ip是否在新的ip池内 | ||||
| 			if IpPool.Ipv4IPNet.Contains(ip) && !ok && | ||||
| 				utils.Ip2long(ip) >= IpPool.IpLongMin && | ||||
| 				utils.Ip2long(ip) <= IpPool.IpLongMax { | ||||
| 				mi.Username = username | ||||
| 				mi.LastLogin = tNow | ||||
| 				mi.UniqueMac = uniqueMac | ||||
| 				// 回写db数据 | ||||
| 				_ = dbdata.Set(mi) | ||||
| 				ipActive[ipStr] = true | ||||
| 				return ip | ||||
| 			} | ||||
| 			_ = dbdata.Del(mi) | ||||
| 		} | ||||
| 	} else { | ||||
| 		ipMaps := []dbdata.IpMap{} | ||||
| 		err = dbdata.FindWhere(&ipMaps, 50, 1, "username=? and unique_mac=?", username, false) | ||||
| 		if err == nil { | ||||
| 			//遍历mac记录 | ||||
| 			for _, mi := range ipMaps { | ||||
| 				ipStr := mi.IpAddr | ||||
| 				ip := net.ParseIP(ipStr) | ||||
|  | ||||
| 				// 跳过活跃连接 | ||||
| 				if _, ok := ipActive[ipStr]; ok { | ||||
| 					continue | ||||
| 				} | ||||
| 				// 跳过ip租期内数据 | ||||
| 				if _, ok := ipLease[ipStr]; ok { | ||||
| 					continue | ||||
| 				} | ||||
|  | ||||
| 				if IpPool.Ipv4IPNet.Contains(ip) && | ||||
| 					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 | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		_ = dbdata.Del(mi) | ||||
| 	} | ||||
|  | ||||
| 	// 全局遍历超过租期和未保留的ip | ||||
| @@ -121,16 +160,22 @@ func AcquireIp(username, macAddr string) net.IP { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		v := &dbdata.IpMap{} | ||||
| 		err = dbdata.One("ip_addr", ipStr, v) | ||||
| 		if err == nil { | ||||
| 			// 存在记录直接跳过 | ||||
| 			continue | ||||
| 		mi := &dbdata.IpMap{} | ||||
| 		err = dbdata.One("ip_addr", ipStr, mi) | ||||
| 		if err == nil && mi.LastLogin.Before(sNow) { | ||||
| 			// 存在记录,说明已经超过租期,可以直接使用 | ||||
| 			mi.LastLogin = tNow | ||||
| 			mi.MacAddr = macAddr | ||||
| 			mi.UniqueMac = uniqueMac | ||||
| 			// 回写db数据 | ||||
| 			_ = dbdata.Set(mi) | ||||
| 			ipActive[ipStr] = true | ||||
| 			return ip | ||||
| 		} | ||||
|  | ||||
| 		if dbdata.CheckErrNotFound(err) { | ||||
| 			// 该ip没有被使用 | ||||
| 			mi = &dbdata.IpMap{IpAddr: ipStr, MacAddr: macAddr, Username: username, LastLogin: tNow} | ||||
| 			mi := &dbdata.IpMap{IpAddr: ipStr, MacAddr: macAddr, UniqueMac: uniqueMac, Username: username, LastLogin: tNow} | ||||
| 			_ = dbdata.Add(mi) | ||||
| 			ipActive[ipStr] = true | ||||
| 			return ip | ||||
|   | ||||
| @@ -14,6 +14,7 @@ type Online struct { | ||||
| 	Username         string    `json:"username"` | ||||
| 	Group            string    `json:"group"` | ||||
| 	MacAddr          string    `json:"mac_addr"` | ||||
| 	UniqueMac        bool      `json:"unique_mac"` | ||||
| 	Ip               net.IP    `json:"ip"` | ||||
| 	RemoteAddr       string    `json:"remote_addr"` | ||||
| 	TunName          string    `json:"tun_name"` | ||||
| @@ -52,6 +53,7 @@ func OnlineSess() []Online { | ||||
| 				Username:         v.Username, | ||||
| 				Group:            v.Group, | ||||
| 				MacAddr:          v.MacAddr, | ||||
| 				UniqueMac:        v.UniqueMac, | ||||
| 				RemoteAddr:       v.CSess.RemoteAddr, | ||||
| 				TunName:          v.CSess.IfName, | ||||
| 				Mtu:              v.CSess.Mtu, | ||||
|   | ||||
| @@ -71,6 +71,7 @@ type Session struct { | ||||
| 	MacAddr         string // 客户端mac地址 | ||||
| 	UniqueIdGlobal  string // 客户端唯一标示 | ||||
| 	MacHw           net.HardwareAddr | ||||
| 	UniqueMac       bool   // 客户端获取到真实设备mac | ||||
| 	Username        string // 用户名 | ||||
| 	Group           string | ||||
| 	AuthStep        string | ||||
| @@ -178,6 +179,7 @@ func (s *Session) NewConn() *ConnSession { | ||||
| 	macAddr := s.MacAddr | ||||
| 	macHw := s.MacHw | ||||
| 	username := s.Username | ||||
| 	uniqueMac := s.UniqueMac | ||||
| 	s.mux.RUnlock() | ||||
| 	if active { | ||||
| 		s.CSess.Close() | ||||
| @@ -187,7 +189,7 @@ func (s *Session) NewConn() *ConnSession { | ||||
| 	if !limit { | ||||
| 		return nil | ||||
| 	} | ||||
| 	ip := AcquireIp(username, macAddr) | ||||
| 	ip := AcquireIp(username, macAddr, uniqueMac) | ||||
| 	if ip == nil { | ||||
| 		LimitClient(username, true) | ||||
| 		return nil | ||||
|   | ||||
| @@ -35,6 +35,14 @@ | ||||
|             label="MAC地址"> | ||||
|         </el-table-column> | ||||
|  | ||||
|         <el-table-column | ||||
|             prop="unique_mac" | ||||
|             label="唯一MAC"> | ||||
|             <template slot-scope="scope"> | ||||
|                 <el-tag v-if="scope.row.unique_mac" type="success">是</el-tag> | ||||
|             </template> | ||||
|         </el-table-column> | ||||
|  | ||||
|         <el-table-column | ||||
|             prop="username" | ||||
|             label="用户名"> | ||||
|   | ||||
| @@ -27,6 +27,15 @@ | ||||
|             prop="mac_addr" | ||||
|             label="MAC地址"> | ||||
|         </el-table-column> | ||||
|          | ||||
|         <el-table-column | ||||
|             prop="unique_mac" | ||||
|             label="唯一MAC"> | ||||
|             <template slot-scope="scope"> | ||||
|                 <el-tag v-if="scope.row.unique_mac" type="success">是</el-tag> | ||||
|             </template> | ||||
|         </el-table-column> | ||||
|  | ||||
|         <el-table-column | ||||
|             prop="ip" | ||||
|             label="IP地址" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user