mirror of https://github.com/bjdgyc/anylink.git
增加 macvtap 模式支持
This commit is contained in:
parent
5010d2ecbd
commit
903554533b
|
@ -8,8 +8,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LinkModeTUN = "tun"
|
LinkModeTUN = "tun"
|
||||||
LinkModeTAP = "tap"
|
LinkModeTAP = "tap"
|
||||||
|
LinkModeMacvtap = "macvtap"
|
||||||
|
LinkModeIpvtap = "ipvtap"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -48,11 +50,12 @@ type ServerConfig struct {
|
||||||
AdminPass string `json:"admin_pass"`
|
AdminPass string `json:"admin_pass"`
|
||||||
JwtSecret string `json:"jwt_secret"`
|
JwtSecret string `json:"jwt_secret"`
|
||||||
|
|
||||||
LinkMode string `json:"link_mode"` // tun tap
|
LinkMode string `json:"link_mode"` // tun tap macvtap ipvtap
|
||||||
Ipv4CIDR string `json:"ipv4_cidr"` // 192.168.1.0/24
|
Ipv4Master string `json:"ipv4_master"` // eth0
|
||||||
Ipv4Gateway string `json:"ipv4_gateway"`
|
Ipv4CIDR string `json:"ipv4_cidr"` // 192.168.10.0/24
|
||||||
Ipv4Start string `json:"ipv4_start"` // 192.168.1.100
|
Ipv4Gateway string `json:"ipv4_gateway"` // 192.168.10.1
|
||||||
Ipv4End string `json:"ipv4_end"` // 192.168.1.200
|
Ipv4Start string `json:"ipv4_start"` // 192.168.10.100
|
||||||
|
Ipv4End string `json:"ipv4_end"` // 192.168.10.200
|
||||||
IpLease int `json:"ip_lease"`
|
IpLease int `json:"ip_lease"`
|
||||||
|
|
||||||
MaxClient int `json:"max_client"`
|
MaxClient int `json:"max_client"`
|
||||||
|
|
|
@ -26,19 +26,20 @@ var configs = []config{
|
||||||
{Typ: cfgStr, Name: "server_dtls_addr", Usage: "DTLS监听地址", ValStr: ":4433"},
|
{Typ: cfgStr, Name: "server_dtls_addr", Usage: "DTLS监听地址", ValStr: ":4433"},
|
||||||
{Typ: cfgStr, Name: "admin_addr", Usage: "后台服务监听地址", ValStr: ":8800"},
|
{Typ: cfgStr, Name: "admin_addr", Usage: "后台服务监听地址", ValStr: ":8800"},
|
||||||
{Typ: cfgBool, Name: "proxy_protocol", Usage: "TCP代理协议", ValBool: false},
|
{Typ: cfgBool, Name: "proxy_protocol", Usage: "TCP代理协议", ValBool: false},
|
||||||
{Typ: cfgStr, Name: "db_type", Usage: "数据库类型 [sqlite3、mysql、postgres]", ValStr: "sqlite3"},
|
{Typ: cfgStr, Name: "db_type", Usage: "数据库类型 [sqlite3 mysql postgres]", ValStr: "sqlite3"},
|
||||||
{Typ: cfgStr, Name: "db_source", Usage: "数据库source", ValStr: "./conf/anylink.db"},
|
{Typ: cfgStr, Name: "db_source", Usage: "数据库source", ValStr: "./conf/anylink.db"},
|
||||||
{Typ: cfgStr, Name: "cert_file", Usage: "证书文件", ValStr: "./conf/vpn_cert.pem"},
|
{Typ: cfgStr, Name: "cert_file", Usage: "证书文件", ValStr: "./conf/vpn_cert.pem"},
|
||||||
{Typ: cfgStr, Name: "cert_key", Usage: "证书密钥", ValStr: "./conf/vpn_cert.key"},
|
{Typ: cfgStr, Name: "cert_key", Usage: "证书密钥", ValStr: "./conf/vpn_cert.key"},
|
||||||
{Typ: cfgStr, Name: "files_path", Usage: "外部下载文件路径", ValStr: "./conf/files"},
|
{Typ: cfgStr, Name: "files_path", Usage: "外部下载文件路径", ValStr: "./conf/files"},
|
||||||
{Typ: cfgStr, Name: "log_path", Usage: "日志文件路径,默认标准输出", ValStr: ""},
|
{Typ: cfgStr, Name: "log_path", Usage: "日志文件路径,默认标准输出", ValStr: ""},
|
||||||
{Typ: cfgStr, Name: "log_level", Usage: "日志等级 [debug、info、warn、error]", ValStr: "info"},
|
{Typ: cfgStr, Name: "log_level", Usage: "日志等级 [debug info warn error]", ValStr: "info"},
|
||||||
{Typ: cfgBool, Name: "pprof", Usage: "开启pprof", ValBool: false},
|
{Typ: cfgBool, Name: "pprof", Usage: "开启pprof", ValBool: false},
|
||||||
{Typ: cfgStr, Name: "issuer", Usage: "系统名称", ValStr: "XX公司VPN"},
|
{Typ: cfgStr, Name: "issuer", Usage: "系统名称", ValStr: "XX公司VPN"},
|
||||||
{Typ: cfgStr, Name: "admin_user", Usage: "管理用户名", ValStr: "admin"},
|
{Typ: cfgStr, Name: "admin_user", Usage: "管理用户名", ValStr: "admin"},
|
||||||
{Typ: cfgStr, Name: "admin_pass", Usage: "管理用户密码", ValStr: defaultPwd},
|
{Typ: cfgStr, Name: "admin_pass", Usage: "管理用户密码", ValStr: defaultPwd},
|
||||||
{Typ: cfgStr, Name: "jwt_secret", Usage: "JWT密钥", ValStr: defaultJwt},
|
{Typ: cfgStr, Name: "jwt_secret", Usage: "JWT密钥", ValStr: defaultJwt},
|
||||||
{Typ: cfgStr, Name: "link_mode", Usage: "虚拟网络类型", ValStr: "tun"},
|
{Typ: cfgStr, Name: "link_mode", Usage: "虚拟网络类型[tun tap macvtap ipvtap]", ValStr: "tun"},
|
||||||
|
{Typ: cfgStr, Name: "ipv4_master", Usage: "ipv4主网卡名称", ValStr: "eth0"},
|
||||||
{Typ: cfgStr, Name: "ipv4_cidr", Usage: "ip地址网段", ValStr: "192.168.10.0/24"},
|
{Typ: cfgStr, Name: "ipv4_cidr", Usage: "ip地址网段", ValStr: "192.168.10.0/24"},
|
||||||
{Typ: cfgStr, Name: "ipv4_gateway", Usage: "ipv4_gateway", ValStr: "192.168.10.1"},
|
{Typ: cfgStr, Name: "ipv4_gateway", Usage: "ipv4_gateway", ValStr: "192.168.10.1"},
|
||||||
{Typ: cfgStr, Name: "ipv4_start", Usage: "IPV4开始地址", ValStr: "192.168.10.100"},
|
{Typ: cfgStr, Name: "ipv4_start", Usage: "IPV4开始地址", ValStr: "192.168.10.100"},
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
#################################
|
|
||||||
# Set up Ethernet bridge on Linux
|
|
||||||
# Requires: bridge-utils
|
|
||||||
#################################
|
|
||||||
|
|
||||||
#yum install bridge-utils
|
#yum install bridge-utils
|
||||||
|
|
||||||
# Define Bridge Interface
|
# Define Bridge Interface
|
||||||
br="anylink0"
|
br="anylink0"
|
||||||
|
|
||||||
# Define physical ethernet interface to be bridged
|
# 请根据sever服务器信息,更新下面的信息
|
||||||
# with TAP interface(s) above.
|
|
||||||
|
|
||||||
eth="eth0"
|
eth="eth0"
|
||||||
eth_ip="192.168.10.4/24"
|
eth_ip="192.168.10.4/24"
|
||||||
eth_broadcast="192.168.10.255"
|
eth_broadcast="192.168.10.255"
|
||||||
|
@ -24,10 +17,10 @@ brctl addif $br $eth
|
||||||
|
|
||||||
ip addr del $eth_ip dev $eth
|
ip addr del $eth_ip dev $eth
|
||||||
ip addr add 0.0.0.0 dev $eth
|
ip addr add 0.0.0.0 dev $eth
|
||||||
ip link set dev $eth ip promisc on
|
ip link set dev $eth up promisc on
|
||||||
|
|
||||||
mac=`cat /sys/class/net/$eth/address`
|
mac=`cat /sys/class/net/$eth/address`
|
||||||
ip link set up address $mac dev $br
|
ip link set dev $br up address $mac promisc on
|
||||||
ip addr add $eth_ip broadcast $eth_broadcast dev $br
|
ip addr add $eth_ip broadcast $eth_broadcast dev $br
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ proxy_protocol = false
|
||||||
link_mode = "tun"
|
link_mode = "tun"
|
||||||
|
|
||||||
#客户端分配的ip地址池
|
#客户端分配的ip地址池
|
||||||
|
ipv4_master = "eth0"
|
||||||
ipv4_cidr = "192.168.10.0/24"
|
ipv4_cidr = "192.168.10.0/24"
|
||||||
ipv4_gateway = "192.168.10.1"
|
ipv4_gateway = "192.168.10.1"
|
||||||
ipv4_start = "192.168.10.100"
|
ipv4_start = "192.168.10.100"
|
||||||
|
|
|
@ -26,6 +26,7 @@ require (
|
||||||
github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119
|
github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
|
||||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023
|
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023
|
||||||
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da
|
||||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
|
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||||
xorm.io/xorm v1.1.2
|
xorm.io/xorm v1.1.2
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bjdgyc/anylink/base"
|
"github.com/bjdgyc/anylink/base"
|
||||||
|
"github.com/bjdgyc/anylink/pkg/utils"
|
||||||
"github.com/bjdgyc/anylink/sessdata"
|
"github.com/bjdgyc/anylink/sessdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ func LinkCstp(conn net.Conn, bufRW *bufio.ReadWriter, cSess *sessdata.ConnSessio
|
||||||
for {
|
for {
|
||||||
|
|
||||||
// 设置超时限制
|
// 设置超时限制
|
||||||
err = conn.SetReadDeadline(time.Now().Add(dead))
|
err = conn.SetReadDeadline(utils.NowSec().Add(dead))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
base.Error("SetDeadline: ", err)
|
base.Error("SetDeadline: ", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bjdgyc/anylink/base"
|
"github.com/bjdgyc/anylink/base"
|
||||||
|
"github.com/bjdgyc/anylink/pkg/utils"
|
||||||
"github.com/bjdgyc/anylink/sessdata"
|
"github.com/bjdgyc/anylink/sessdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ func LinkDtls(conn net.Conn, cSess *sessdata.ConnSession) {
|
||||||
go dtlsWrite(conn, dSess, cSess)
|
go dtlsWrite(conn, dSess, cSess)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
err = conn.SetReadDeadline(time.Now().Add(dead))
|
err = conn.SetReadDeadline(utils.NowSec().Add(dead))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
base.Error("SetDeadline: ", err)
|
base.Error("SetDeadline: ", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -2,6 +2,7 @@ package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/bjdgyc/anylink/base"
|
"github.com/bjdgyc/anylink/base"
|
||||||
|
@ -17,18 +18,32 @@ import (
|
||||||
const bridgeName = "anylink0"
|
const bridgeName = "anylink0"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
bridgeIp net.IP
|
// 网关mac地址
|
||||||
bridgeHw net.HardwareAddr
|
gatewayHw net.HardwareAddr
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkTap() {
|
type LinkDriver interface {
|
||||||
brFace, err := net.InterfaceByName(bridgeName)
|
io.ReadWriteCloser
|
||||||
|
Name() string
|
||||||
|
}
|
||||||
|
|
||||||
|
func _setGateway() {
|
||||||
|
dstAddr := arpdis.Lookup(sessdata.IpPool.Ipv4Gateway, false)
|
||||||
|
gatewayHw = dstAddr.HardwareAddr
|
||||||
|
// 设置为静态地址映射
|
||||||
|
dstAddr.Type = arpdis.TypeStatic
|
||||||
|
arpdis.Add(dstAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _checkTapIp(ifName string) {
|
||||||
|
iFace, err := net.InterfaceByName(ifName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
base.Fatal("testTap err: ", err)
|
base.Fatal("testTap err: ", err)
|
||||||
}
|
}
|
||||||
bridgeHw = brFace.HardwareAddr
|
|
||||||
|
|
||||||
addrs, err := brFace.Addrs()
|
var ifIp net.IP
|
||||||
|
|
||||||
|
addrs, err := iFace.Addrs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
base.Fatal("testTap err: ", err)
|
base.Fatal("testTap err: ", err)
|
||||||
}
|
}
|
||||||
|
@ -37,17 +52,19 @@ func checkTap() {
|
||||||
if err != nil || ip.To4() == nil {
|
if err != nil || ip.To4() == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
bridgeIp = ip
|
ifIp = ip
|
||||||
}
|
|
||||||
if bridgeIp == nil && bridgeHw == nil {
|
|
||||||
base.Fatal("bridgeIp is err")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sessdata.IpPool.Ipv4IPNet.Contains(bridgeIp) {
|
if !sessdata.IpPool.Ipv4IPNet.Contains(ifIp) {
|
||||||
base.Fatal("bridgeIp or Ip network err")
|
base.Fatal("tapIp or Ip network err")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkTap() {
|
||||||
|
_setGateway()
|
||||||
|
_checkTapIp(bridgeName)
|
||||||
|
}
|
||||||
|
|
||||||
// 创建tap网卡
|
// 创建tap网卡
|
||||||
func LinkTap(cSess *sessdata.ConnSession) error {
|
func LinkTap(cSess *sessdata.ConnSession) error {
|
||||||
cfg := water.Config{
|
cfg := water.Config{
|
||||||
|
@ -60,9 +77,8 @@ func LinkTap(cSess *sessdata.ConnSession) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cSess.TunName = ifce.Name()
|
cSess.SetIfName(ifce.Name())
|
||||||
|
|
||||||
// arp on
|
|
||||||
cmdstr1 := fmt.Sprintf("ip link set dev %s up mtu %d multicast on", ifce.Name(), cSess.Mtu)
|
cmdstr1 := fmt.Sprintf("ip link set dev %s up mtu %d multicast on", ifce.Name(), cSess.Mtu)
|
||||||
cmdstr2 := fmt.Sprintf("ip link set dev %s master %s", ifce.Name(), bridgeName)
|
cmdstr2 := fmt.Sprintf("ip link set dev %s master %s", ifce.Name(), bridgeName)
|
||||||
err = execCmd([]string{cmdstr1, cmdstr2})
|
err = execCmd([]string{cmdstr1, cmdstr2})
|
||||||
|
@ -75,25 +91,31 @@ func LinkTap(cSess *sessdata.ConnSession) error {
|
||||||
cmdstr3 := fmt.Sprintf("sysctl -w net.ipv6.conf.%s.disable_ipv6=1", ifce.Name())
|
cmdstr3 := fmt.Sprintf("sysctl -w net.ipv6.conf.%s.disable_ipv6=1", ifce.Name())
|
||||||
execCmd([]string{cmdstr3})
|
execCmd([]string{cmdstr3})
|
||||||
|
|
||||||
go tapRead(ifce, cSess)
|
go allTapRead(ifce, cSess)
|
||||||
go tapWrite(ifce, cSess)
|
go allTapWrite(ifce, cSess)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func tapWrite(ifce *water.Interface, cSess *sessdata.ConnSession) {
|
// ========================通用代码===========================
|
||||||
|
|
||||||
|
func allTapWrite(ifce LinkDriver, cSess *sessdata.ConnSession) {
|
||||||
defer func() {
|
defer func() {
|
||||||
base.Debug("LinkTap return", cSess.IpAddr)
|
base.Debug("LinkTap return", cSess.IpAddr)
|
||||||
cSess.Close()
|
cSess.Close()
|
||||||
_ = ifce.Close()
|
ifce.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
dstHw net.HardwareAddr
|
||||||
pl *sessdata.Payload
|
pl *sessdata.Payload
|
||||||
frame ethernet.Frame
|
frame = make(ethernet.Frame, BufferSize)
|
||||||
|
ipDst = net.IPv4(1, 2, 3, 4)
|
||||||
)
|
)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
frame.Resize(BufferSize)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case pl = <-cSess.PayloadIn:
|
case pl = <-cSess.PayloadIn:
|
||||||
case <-cSess.CloseChan:
|
case <-cSess.CloseChan:
|
||||||
|
@ -101,45 +123,46 @@ func tapWrite(ifce *water.Interface, cSess *sessdata.ConnSession) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// var frame ethernet.Frame
|
// var frame ethernet.Frame
|
||||||
fb := getByteFull()
|
|
||||||
frame = *fb
|
|
||||||
switch pl.LType {
|
switch pl.LType {
|
||||||
default:
|
default:
|
||||||
// log.Println(payload)
|
// log.Println(payload)
|
||||||
case sessdata.LTypeEthernet:
|
case sessdata.LTypeEthernet:
|
||||||
copy(frame, pl.Data)
|
copy(frame, pl.Data)
|
||||||
frame = frame[:len(pl.Data)]
|
frame = frame[:len(pl.Data)]
|
||||||
|
|
||||||
|
// packet := gopacket.NewPacket(frame, layers.LayerTypeEthernet, gopacket.Default)
|
||||||
|
// fmt.Println("wirteArp:", packet)
|
||||||
case sessdata.LTypeIPData: // 需要转换成 Ethernet 数据
|
case sessdata.LTypeIPData: // 需要转换成 Ethernet 数据
|
||||||
ip_src := waterutil.IPv4Source(pl.Data)
|
ipSrc := waterutil.IPv4Source(pl.Data)
|
||||||
if waterutil.IsIPv6(pl.Data) || !ip_src.Equal(cSess.IpAddr) {
|
if !ipSrc.Equal(cSess.IpAddr) {
|
||||||
// 过滤掉IPv6的数据
|
|
||||||
// 非分配给客户端ip,直接丢弃
|
// 非分配给客户端ip,直接丢弃
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// packet := gopacket.NewPacket(data, layers.LayerTypeIPv4, gopacket.Default)
|
if waterutil.IsIPv6(pl.Data) {
|
||||||
|
// 过滤掉IPv6的数据
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// packet := gopacket.NewPacket(pl.Data, layers.LayerTypeIPv4, gopacket.Default)
|
||||||
// fmt.Println("get:", packet)
|
// fmt.Println("get:", packet)
|
||||||
|
|
||||||
ip_dst := waterutil.IPv4Destination(pl.Data)
|
// 手动设置ipv4地址
|
||||||
// fmt.Println("get:", ip_src, ip_dst)
|
ipDst[12] = pl.Data[16]
|
||||||
|
ipDst[13] = pl.Data[17]
|
||||||
|
ipDst[14] = pl.Data[18]
|
||||||
|
ipDst[15] = pl.Data[19]
|
||||||
|
|
||||||
var dstHw net.HardwareAddr
|
dstHw = gatewayHw
|
||||||
if !sessdata.IpPool.Ipv4IPNet.Contains(ip_dst) || ip_dst.Equal(sessdata.IpPool.Ipv4Gateway) {
|
if sessdata.IpPool.Ipv4IPNet.Contains(ipDst) {
|
||||||
// 不是同一网段,使用网关mac地址
|
dstAddr := arpdis.Lookup(ipDst, true)
|
||||||
dstAddr := arpdis.Lookup(sessdata.IpPool.Ipv4Gateway, false)
|
|
||||||
dstHw = dstAddr.HardwareAddr
|
|
||||||
} else {
|
|
||||||
dstAddr := arpdis.Lookup(ip_dst, true)
|
|
||||||
// fmt.Println("dstAddr", dstAddr)
|
// fmt.Println("dstAddr", dstAddr)
|
||||||
if dstAddr != nil {
|
if dstAddr != nil {
|
||||||
dstHw = dstAddr.HardwareAddr
|
dstHw = dstAddr.HardwareAddr
|
||||||
} else {
|
|
||||||
dstHw = bridgeHw
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// fmt.Println("Gateway", ip_dst, dstAddr.HardwareAddr)
|
|
||||||
|
|
||||||
|
// fmt.Println("Gateway", ipSrc, ipDst, dstHw)
|
||||||
frame.Prepare(dstHw, cSess.MacHw, ethernet.NotTagged, ethernet.IPv4, len(pl.Data))
|
frame.Prepare(dstHw, cSess.MacHw, ethernet.NotTagged, ethernet.IPv4, len(pl.Data))
|
||||||
copy(frame[12+2:], pl.Data)
|
copy(frame[12+2:], pl.Data)
|
||||||
}
|
}
|
||||||
|
@ -152,29 +175,26 @@ func tapWrite(ifce *water.Interface, cSess *sessdata.ConnSession) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
putByte(fb)
|
|
||||||
putPayload(pl)
|
putPayload(pl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func tapRead(ifce *water.Interface, cSess *sessdata.ConnSession) {
|
func allTapRead(ifce LinkDriver, cSess *sessdata.ConnSession) {
|
||||||
defer func() {
|
defer func() {
|
||||||
base.Debug("tapRead return", cSess.IpAddr)
|
base.Debug("tapRead return", cSess.IpAddr)
|
||||||
_ = ifce.Close()
|
ifce.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
n int
|
n int
|
||||||
data []byte
|
data []byte
|
||||||
frame ethernet.Frame
|
frame = make(ethernet.Frame, BufferSize)
|
||||||
)
|
)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// var frame ethernet.Frame
|
frame.Resize(BufferSize)
|
||||||
// frame.Resize(BufferSize)
|
|
||||||
fb := getByteFull()
|
|
||||||
frame = *fb
|
|
||||||
n, err = ifce.Read(frame)
|
n, err = ifce.Read(frame)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
base.Error("tap Read err", n, err)
|
base.Error("tap Read err", n, err)
|
||||||
|
@ -184,8 +204,6 @@ func tapRead(ifce *water.Interface, cSess *sessdata.ConnSession) {
|
||||||
|
|
||||||
switch frame.Ethertype() {
|
switch frame.Ethertype() {
|
||||||
default:
|
default:
|
||||||
// packet := gopacket.NewPacket(frame, layers.LayerTypeEthernet, gopacket.Default)
|
|
||||||
// fmt.Println(packet)
|
|
||||||
continue
|
continue
|
||||||
case ethernet.IPv6:
|
case ethernet.IPv6:
|
||||||
continue
|
continue
|
||||||
|
@ -214,7 +232,7 @@ func tapRead(ifce *water.Interface, cSess *sessdata.ConnSession) {
|
||||||
|
|
||||||
case ethernet.ARP:
|
case ethernet.ARP:
|
||||||
// 暂时仅实现了ARP协议
|
// 暂时仅实现了ARP协议
|
||||||
packet := gopacket.NewPacket(frame, layers.LayerTypeEthernet, gopacket.Default)
|
packet := gopacket.NewPacket(frame, layers.LayerTypeEthernet, gopacket.NoCopy)
|
||||||
layer := packet.Layer(layers.LayerTypeARP)
|
layer := packet.Layer(layers.LayerTypeARP)
|
||||||
arpReq := layer.(*layers.ARP)
|
arpReq := layer.(*layers.ARP)
|
||||||
|
|
||||||
|
@ -223,12 +241,12 @@ func tapRead(ifce *water.Interface, cSess *sessdata.ConnSession) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// fmt.Println("arp", net.IP(arpReq.SourceProtAddress), sess.Ip)
|
// fmt.Println("arp", time.Now(), net.IP(arpReq.SourceProtAddress), cSess.IpAddr)
|
||||||
// fmt.Println(packet)
|
// fmt.Println(packet)
|
||||||
|
|
||||||
// 返回ARP数据
|
// 返回ARP数据
|
||||||
src := &arpdis.Addr{IP: cSess.IpAddr, HardwareAddr: cSess.MacHw}
|
src := &arpdis.Addr{IP: cSess.IpAddr, HardwareAddr: cSess.MacHw}
|
||||||
dst := &arpdis.Addr{IP: arpReq.SourceProtAddress, HardwareAddr: frame.Source()}
|
dst := &arpdis.Addr{IP: arpReq.SourceProtAddress, HardwareAddr: arpReq.SourceHwAddress}
|
||||||
data, err = arpdis.NewARPReply(src, dst)
|
data, err = arpdis.NewARPReply(src, dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
base.Error(err)
|
base.Error(err)
|
||||||
|
@ -237,13 +255,9 @@ func tapRead(ifce *water.Interface, cSess *sessdata.ConnSession) {
|
||||||
|
|
||||||
// 从接受的arp信息添加arp地址
|
// 从接受的arp信息添加arp地址
|
||||||
addr := &arpdis.Addr{
|
addr := &arpdis.Addr{
|
||||||
IP: make([]byte, len(arpReq.SourceProtAddress)),
|
IP: append([]byte{}, dst.IP...),
|
||||||
HardwareAddr: make([]byte, len(frame.Source())),
|
HardwareAddr: append([]byte{}, dst.HardwareAddr...),
|
||||||
}
|
}
|
||||||
// addr.IP = arpReq.SourceProtAddress
|
|
||||||
// addr.HardwareAddr = frame.Source()
|
|
||||||
copy(addr.IP, arpReq.SourceProtAddress)
|
|
||||||
copy(addr.HardwareAddr, frame.Source())
|
|
||||||
arpdis.Add(addr)
|
arpdis.Add(addr)
|
||||||
|
|
||||||
pl := getPayload()
|
pl := getPayload()
|
||||||
|
@ -259,7 +273,5 @@ func tapRead(ifce *water.Interface, cSess *sessdata.ConnSession) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
putByte(fb)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,7 @@ func LinkTun(cSess *sessdata.ConnSession) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// log.Printf("Interface Name: %s\n", ifce.Name())
|
// log.Printf("Interface Name: %s\n", ifce.Name())
|
||||||
cSess.SetTunName(ifce.Name())
|
cSess.SetIfName(ifce.Name())
|
||||||
// cSess.TunName = ifce.Name()
|
|
||||||
|
|
||||||
cmdstr1 := fmt.Sprintf("ip link set dev %s up mtu %d multicast off", ifce.Name(), cSess.Mtu)
|
cmdstr1 := fmt.Sprintf("ip link set dev %s up mtu %d multicast off", ifce.Name(), cSess.Mtu)
|
||||||
cmdstr2 := fmt.Sprintf("ip addr add dev %s local %s peer %s/32",
|
cmdstr2 := fmt.Sprintf("ip addr add dev %s local %s peer %s/32",
|
||||||
|
|
|
@ -160,9 +160,12 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) {
|
||||||
err = LinkTun(cSess)
|
err = LinkTun(cSess)
|
||||||
case base.LinkModeTAP:
|
case base.LinkModeTAP:
|
||||||
err = LinkTap(cSess)
|
err = LinkTap(cSess)
|
||||||
|
case base.LinkModeMacvtap:
|
||||||
|
err = LinkMacvtap(cSess)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
conn.Close()
|
||||||
|
base.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/bjdgyc/anylink/base"
|
||||||
|
"github.com/bjdgyc/anylink/pkg/utils"
|
||||||
|
"github.com/bjdgyc/anylink/sessdata"
|
||||||
|
)
|
||||||
|
|
||||||
|
// link vtap
|
||||||
|
const vTapPrefix = "lvtap"
|
||||||
|
|
||||||
|
type Vtap struct {
|
||||||
|
*os.File
|
||||||
|
ifName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vtap) Close() error {
|
||||||
|
v.File.Close()
|
||||||
|
cmdstr := fmt.Sprintf("ip link del %s", v.ifName)
|
||||||
|
return execCmd([]string{cmdstr})
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkMacvtap() {
|
||||||
|
_setGateway()
|
||||||
|
_checkTapIp(base.Cfg.Ipv4Master)
|
||||||
|
|
||||||
|
ifName := "anylinkMacvtap"
|
||||||
|
// 加载 macvtap
|
||||||
|
cmdstr0 := fmt.Sprintf("modprobe -i macvtap")
|
||||||
|
// 开启主网卡混杂模式
|
||||||
|
cmdstr1 := fmt.Sprintf("ip link set dev %s promisc on", base.Cfg.Ipv4Master)
|
||||||
|
// 测试 macvtap 功能
|
||||||
|
cmdstr2 := fmt.Sprintf("ip link add link %s name %s type macvtap mode bridge", base.Cfg.Ipv4Master, ifName)
|
||||||
|
cmdstr3 := fmt.Sprintf("ip link del %s", ifName)
|
||||||
|
err := execCmd([]string{cmdstr0, cmdstr1, cmdstr2, cmdstr3})
|
||||||
|
if err != nil {
|
||||||
|
base.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建 Macvtap 网卡
|
||||||
|
func LinkMacvtap(cSess *sessdata.ConnSession) error {
|
||||||
|
capL := sessdata.IpPool.IpLongMax - sessdata.IpPool.IpLongMin
|
||||||
|
ipN := utils.Ip2long(cSess.IpAddr) % capL
|
||||||
|
ifName := fmt.Sprintf("%s%d", vTapPrefix, ipN)
|
||||||
|
|
||||||
|
cSess.SetIfName(ifName)
|
||||||
|
|
||||||
|
cmdstr1 := fmt.Sprintf("ip link add link %s name %s type macvtap mode bridge", base.Cfg.Ipv4Master, ifName)
|
||||||
|
cmdstr2 := fmt.Sprintf("ip link set dev %s up mtu %d address %s", ifName, cSess.Mtu, cSess.MacHw)
|
||||||
|
err := execCmd([]string{cmdstr1, cmdstr2})
|
||||||
|
if err != nil {
|
||||||
|
base.Error(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmdstr3 := fmt.Sprintf("sysctl -w net.ipv6.conf.%s.disable_ipv6=1", ifName)
|
||||||
|
execCmd([]string{cmdstr3})
|
||||||
|
|
||||||
|
return createVtap(cSess, ifName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkIpvtap() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建 Ipvtap 网卡
|
||||||
|
func LinkIpvtap(cSess *sessdata.ConnSession) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ifReq struct {
|
||||||
|
Name [0x10]byte
|
||||||
|
Flags uint16
|
||||||
|
pad [0x28 - 0x10 - 2]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func createVtap(cSess *sessdata.ConnSession, ifName string) error {
|
||||||
|
// 初始化 ifName
|
||||||
|
inf, err := net.InterfaceByName(ifName)
|
||||||
|
if err != nil {
|
||||||
|
base.Error(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tName := fmt.Sprintf("/dev/tap%d", inf.Index)
|
||||||
|
|
||||||
|
var fdInt int
|
||||||
|
|
||||||
|
fdInt, err = syscall.Open(tName, os.O_RDWR|syscall.O_NONBLOCK, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var flags uint16 = syscall.IFF_TAP | syscall.IFF_NO_PI
|
||||||
|
var req ifReq
|
||||||
|
req.Flags = flags
|
||||||
|
|
||||||
|
_, _, errno := syscall.Syscall(
|
||||||
|
syscall.SYS_IOCTL,
|
||||||
|
uintptr(fdInt),
|
||||||
|
uintptr(syscall.TUNSETIFF),
|
||||||
|
uintptr(unsafe.Pointer(&req)),
|
||||||
|
)
|
||||||
|
if errno != 0 {
|
||||||
|
return os.NewSyscallError("ioctl", errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
file := os.NewFile(uintptr(fdInt), tName)
|
||||||
|
ifce := &Vtap{file, ifName}
|
||||||
|
|
||||||
|
go allTapRead(ifce, cSess)
|
||||||
|
go allTapWrite(ifce, cSess)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 销毁未关闭的vtap
|
||||||
|
func destroyVtap() {
|
||||||
|
its, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
base.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, v := range its {
|
||||||
|
if strings.HasPrefix(v.Name, vTapPrefix) {
|
||||||
|
// 删除原来的网卡
|
||||||
|
cmdstr := fmt.Sprintf("ip link del %s", v.Name)
|
||||||
|
execCmd([]string{cmdstr})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,10 +11,17 @@ func Start() {
|
||||||
dbdata.Start()
|
dbdata.Start()
|
||||||
sessdata.Start()
|
sessdata.Start()
|
||||||
|
|
||||||
checkTun()
|
switch base.Cfg.LinkMode {
|
||||||
if base.Cfg.LinkMode == base.LinkModeTAP {
|
case base.LinkModeTUN:
|
||||||
|
checkTun()
|
||||||
|
case base.LinkModeTAP:
|
||||||
checkTap()
|
checkTap()
|
||||||
|
case base.LinkModeMacvtap:
|
||||||
|
checkMacvtap()
|
||||||
|
default:
|
||||||
|
base.Fatal("LinkMode is err")
|
||||||
}
|
}
|
||||||
|
|
||||||
go admin.StartAdmin()
|
go admin.StartAdmin()
|
||||||
go startTls()
|
go startTls()
|
||||||
go startDtls()
|
go startDtls()
|
||||||
|
@ -22,4 +29,5 @@ func Start() {
|
||||||
|
|
||||||
func Stop() {
|
func Stop() {
|
||||||
_ = dbdata.Stop()
|
_ = dbdata.Stop()
|
||||||
|
destroyVtap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/bjdgyc/anylink/admin"
|
"github.com/bjdgyc/anylink/admin"
|
||||||
|
|
||||||
"github.com/bjdgyc/anylink/base"
|
"github.com/bjdgyc/anylink/base"
|
||||||
"github.com/bjdgyc/anylink/handler"
|
"github.com/bjdgyc/anylink/handler"
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/bjdgyc/anylink/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -16,7 +18,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
table = make(map[string]*Addr)
|
table = make(map[string]*Addr, 128)
|
||||||
tableMu sync.RWMutex
|
tableMu sync.RWMutex
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,25 +42,25 @@ func Lookup(ip net.IP, onlyTable bool) *Addr {
|
||||||
|
|
||||||
// Add adds a IP-MAC map to a runtime ARP table.
|
// Add adds a IP-MAC map to a runtime ARP table.
|
||||||
func tableLookup(ip net.IP) *Addr {
|
func tableLookup(ip net.IP) *Addr {
|
||||||
tableMu.Lock()
|
tableMu.RLock()
|
||||||
addr := table[ip.To4().String()]
|
addr := table[ip.To4().String()]
|
||||||
tableMu.Unlock()
|
tableMu.RUnlock()
|
||||||
if addr == nil {
|
if addr == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断老化过期时间
|
// 判断老化过期时间
|
||||||
tsub := time.Since(addr.disTime)
|
tSub := utils.NowSec().Sub(addr.disTime)
|
||||||
switch addr.Type {
|
switch addr.Type {
|
||||||
|
case TypeStatic:
|
||||||
case TypeNormal:
|
case TypeNormal:
|
||||||
if tsub > StaleTimeNormal {
|
if tSub > StaleTimeNormal {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case TypeUnreachable:
|
case TypeUnreachable:
|
||||||
if tsub > StaleTimeUnreachable {
|
if tSub > StaleTimeUnreachable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case TypeStatic:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return addr
|
return addr
|
||||||
|
@ -70,7 +72,7 @@ func Add(addr *Addr) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if addr.disTime.IsZero() {
|
if addr.disTime.IsZero() {
|
||||||
addr.disTime = time.Now()
|
addr.disTime = utils.NowSec()
|
||||||
}
|
}
|
||||||
ip := addr.IP.To4().String()
|
ip := addr.IP.To4().String()
|
||||||
tableMu.Lock()
|
tableMu.Lock()
|
||||||
|
|
|
@ -19,7 +19,8 @@ func doLookup(ip net.IP) *Addr {
|
||||||
err := doPing(ip.String())
|
err := doPing(ip.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// log.Println(err)
|
// log.Println(err)
|
||||||
addr := &Addr{IP: ip, Type: TypeUnreachable}
|
addr := &Addr{IP: net.IPv4(1, 2, 3, 4), Type: TypeUnreachable}
|
||||||
|
copy(addr.IP, ip)
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +51,9 @@ func doArpShow(ip net.IP) *Addr {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Addr{IP: ip, HardwareAddr: mac}
|
addr := &Addr{IP: net.IPv4(1, 2, 3, 4), HardwareAddr: mac}
|
||||||
|
copy(addr.IP, ip)
|
||||||
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// IP address HW type Flags HW address Mask Device
|
// IP address HW type Flags HW address Mask Device
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Long2ip(i uint32) net.IP {
|
||||||
|
ip := make([]byte, 4)
|
||||||
|
binary.BigEndian.PutUint32(ip, i)
|
||||||
|
return ip
|
||||||
|
}
|
||||||
|
|
||||||
|
func Ip2long(ip net.IP) uint32 {
|
||||||
|
ip = ip.To4()
|
||||||
|
return binary.BigEndian.Uint32(ip)
|
||||||
|
}
|
|
@ -1,13 +1,13 @@
|
||||||
package sessdata
|
package sessdata
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bjdgyc/anylink/base"
|
"github.com/bjdgyc/anylink/base"
|
||||||
"github.com/bjdgyc/anylink/dbdata"
|
"github.com/bjdgyc/anylink/dbdata"
|
||||||
|
"github.com/bjdgyc/anylink/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -43,19 +43,8 @@ func initIpPool() {
|
||||||
// max := min | uint32(math.Pow(2, float64(32-one))-1)
|
// max := min | uint32(math.Pow(2, float64(32-one))-1)
|
||||||
|
|
||||||
// ip地址池
|
// ip地址池
|
||||||
IpPool.IpLongMin = ip2long(net.ParseIP(base.Cfg.Ipv4Start))
|
IpPool.IpLongMin = utils.Ip2long(net.ParseIP(base.Cfg.Ipv4Start))
|
||||||
IpPool.IpLongMax = ip2long(net.ParseIP(base.Cfg.Ipv4End))
|
IpPool.IpLongMax = utils.Ip2long(net.ParseIP(base.Cfg.Ipv4End))
|
||||||
}
|
|
||||||
|
|
||||||
func long2ip(i uint32) net.IP {
|
|
||||||
ip := make([]byte, 4)
|
|
||||||
binary.BigEndian.PutUint32(ip, i)
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
|
|
||||||
func ip2long(ip net.IP) uint32 {
|
|
||||||
ip = ip.To4()
|
|
||||||
return binary.BigEndian.Uint32(ip)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcquireIp 获取动态ip
|
// AcquireIp 获取动态ip
|
||||||
|
@ -90,7 +79,7 @@ func AcquireIp(username, macAddr string) net.IP {
|
||||||
farIp := &dbdata.IpMap{LastLogin: tNow}
|
farIp := &dbdata.IpMap{LastLogin: tNow}
|
||||||
// 全局遍历超过租期ip
|
// 全局遍历超过租期ip
|
||||||
for i := IpPool.IpLongMin; i <= IpPool.IpLongMax; i++ {
|
for i := IpPool.IpLongMin; i <= IpPool.IpLongMax; i++ {
|
||||||
ip := long2ip(i)
|
ip := utils.Long2ip(i)
|
||||||
ipStr := ip.String()
|
ipStr := ip.String()
|
||||||
|
|
||||||
// 跳过活跃连接
|
// 跳过活跃连接
|
||||||
|
|
|
@ -54,13 +54,13 @@ func OnlineSess() []Online {
|
||||||
Group: v.Group,
|
Group: v.Group,
|
||||||
MacAddr: v.MacAddr,
|
MacAddr: v.MacAddr,
|
||||||
RemoteAddr: v.CSess.RemoteAddr,
|
RemoteAddr: v.CSess.RemoteAddr,
|
||||||
TunName: v.CSess.TunName,
|
TunName: v.CSess.IfName,
|
||||||
Mtu: v.CSess.Mtu,
|
Mtu: v.CSess.Mtu,
|
||||||
Client: v.CSess.Client,
|
Client: v.CSess.Client,
|
||||||
BandwidthUp: utils.HumanByte(atomic.LoadUint32(&v.CSess.BandwidthUpPeriod)) + "/s",
|
BandwidthUp: utils.HumanByte(atomic.LoadUint32(&v.CSess.BandwidthUpPeriod)) + "/s",
|
||||||
BandwidthDown: utils.HumanByte(atomic.LoadUint32(&v.CSess.BandwidthDownPeriod)) + "/s",
|
BandwidthDown: utils.HumanByte(atomic.LoadUint32(&v.CSess.BandwidthDownPeriod)) + "/s",
|
||||||
BandwidthUpAll: utils.HumanByte(atomic.LoadUint32(&v.CSess.BandwidthUpAll)),
|
BandwidthUpAll: utils.HumanByte(atomic.LoadUint64(&v.CSess.BandwidthUpAll)),
|
||||||
BandwidthDownAll: utils.HumanByte(atomic.LoadUint32(&v.CSess.BandwidthDownAll)),
|
BandwidthDownAll: utils.HumanByte(atomic.LoadUint64(&v.CSess.BandwidthDownAll)),
|
||||||
LastLogin: v.LastLogin,
|
LastLogin: v.LastLogin,
|
||||||
}
|
}
|
||||||
datas = append(datas, val)
|
datas = append(datas, val)
|
||||||
|
|
|
@ -32,7 +32,7 @@ type ConnSession struct {
|
||||||
MacHw net.HardwareAddr // 客户端mac地址,从Session取出
|
MacHw net.HardwareAddr // 客户端mac地址,从Session取出
|
||||||
RemoteAddr string
|
RemoteAddr string
|
||||||
Mtu int
|
Mtu int
|
||||||
TunName string
|
IfName string
|
||||||
Client string // 客户端 mobile pc
|
Client string // 客户端 mobile pc
|
||||||
CstpDpd int
|
CstpDpd int
|
||||||
Group *dbdata.Group
|
Group *dbdata.Group
|
||||||
|
@ -41,8 +41,8 @@ type ConnSession struct {
|
||||||
BandwidthDown uint32 // 使用下行带宽 Byte
|
BandwidthDown uint32 // 使用下行带宽 Byte
|
||||||
BandwidthUpPeriod uint32 // 前一周期的总量
|
BandwidthUpPeriod uint32 // 前一周期的总量
|
||||||
BandwidthDownPeriod uint32
|
BandwidthDownPeriod uint32
|
||||||
BandwidthUpAll uint32 // 使用上行带宽总量
|
BandwidthUpAll uint64 // 使用上行带宽总量
|
||||||
BandwidthDownAll uint32 // 使用下行带宽总量
|
BandwidthDownAll uint64 // 使用下行带宽总量
|
||||||
closeOnce sync.Once
|
closeOnce sync.Once
|
||||||
CloseChan chan struct{}
|
CloseChan chan struct{}
|
||||||
PayloadIn chan *Payload
|
PayloadIn chan *Payload
|
||||||
|
@ -111,9 +111,9 @@ func checkSession() {
|
||||||
|
|
||||||
func GenToken() string {
|
func GenToken() string {
|
||||||
// 生成32位的 token
|
// 生成32位的 token
|
||||||
btoken := make([]byte, 32)
|
bToken := make([]byte, 32)
|
||||||
rand.Read(btoken)
|
rand.Read(bToken)
|
||||||
return fmt.Sprintf("%x", btoken)
|
return fmt.Sprintf("%x", bToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSession(token string) *Session {
|
func NewSession(token string) *Session {
|
||||||
|
@ -285,8 +285,8 @@ func (cs *ConnSession) ratePeriod() {
|
||||||
atomic.SwapUint32(&cs.BandwidthUpPeriod, rtUp/BandwidthPeriodSec)
|
atomic.SwapUint32(&cs.BandwidthUpPeriod, rtUp/BandwidthPeriodSec)
|
||||||
atomic.SwapUint32(&cs.BandwidthDownPeriod, rtDown/BandwidthPeriodSec)
|
atomic.SwapUint32(&cs.BandwidthDownPeriod, rtDown/BandwidthPeriodSec)
|
||||||
// 累加所有流量
|
// 累加所有流量
|
||||||
atomic.AddUint32(&cs.BandwidthUpAll, rtUp)
|
atomic.AddUint64(&cs.BandwidthUpAll, uint64(rtUp))
|
||||||
atomic.AddUint32(&cs.BandwidthDownAll, rtDown)
|
atomic.AddUint64(&cs.BandwidthDownAll, uint64(rtDown))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,10 +305,10 @@ func (cs *ConnSession) SetMtu(mtu string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ConnSession) SetTunName(name string) {
|
func (cs *ConnSession) SetIfName(name string) {
|
||||||
cs.Sess.mux.Lock()
|
cs.Sess.mux.Lock()
|
||||||
defer cs.Sess.mux.Unlock()
|
defer cs.Sess.mux.Unlock()
|
||||||
cs.TunName = name
|
cs.IfName = name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ConnSession) RateLimit(byt int, isUp bool) error {
|
func (cs *ConnSession) RateLimit(byt int, isUp bool) error {
|
||||||
|
|
Loading…
Reference in New Issue