From 0512ce197ab3aebef867c9c71f9647c6ffdf4fbf Mon Sep 17 00:00:00 2001 From: bjdgyc Date: Sat, 29 May 2021 17:31:41 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BC=98=E5=8C=96gc=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/base/app_ver.go | 2 +- server/handler/link_cstp.go | 19 +++++++++----- server/handler/link_dtls.go | 25 +++++++++++++----- server/handler/link_tun.go | 11 +++++--- server/handler/payload.go | 33 +++++++++++------------ server/handler/pool.go | 52 +++++++++++++++++++++++++++++++++++++ 6 files changed, 106 insertions(+), 36 deletions(-) create mode 100644 server/handler/pool.go diff --git a/server/base/app_ver.go b/server/base/app_ver.go index 5494255..52fe698 100644 --- a/server/base/app_ver.go +++ b/server/base/app_ver.go @@ -2,5 +2,5 @@ package base const ( APP_NAME = "AnyLink" - APP_VER = "0.2.1" + APP_VER = "0.3.1" ) diff --git a/server/handler/link_cstp.go b/server/handler/link_cstp.go index 4613de9..431cefb 100644 --- a/server/handler/link_cstp.go +++ b/server/handler/link_cstp.go @@ -33,7 +33,8 @@ func LinkCstp(conn net.Conn, cSess *sessdata.ConnSession) { base.Error("SetDeadline: ", err) return } - hdata := make([]byte, BufferSize) + // hdata := make([]byte, BufferSize) + hdata := getByteFull() n, err = conn.Read(hdata) if err != nil { base.Error("read hdata: ", err) @@ -65,8 +66,9 @@ func LinkCstp(conn net.Conn, cSess *sessdata.ConnSession) { if payloadIn(cSess, sessdata.LTypeIPData, 0x00, hdata[8:8+dataLen]) { return } - } + + putByte(hdata) } } @@ -78,9 +80,9 @@ func cstpWrite(conn net.Conn, cSess *sessdata.ConnSession) { }() var ( - err error - n int - header []byte + err error + n int + // header []byte payload *sessdata.Payload ) @@ -95,7 +97,9 @@ func cstpWrite(conn net.Conn, cSess *sessdata.ConnSession) { continue } - header = []byte{'S', 'T', 'F', 0x01, 0x00, 0x00, payload.PType, 0x00} + h := []byte{'S', 'T', 'F', 0x01, 0x00, 0x00, payload.PType, 0x00} + header := getByteZero() + header = append(header, h...) if payload.PType == 0x00 { // data binary.BigEndian.PutUint16(header[4:6], uint16(len(payload.Data))) header = append(header, payload.Data...) @@ -106,6 +110,9 @@ func cstpWrite(conn net.Conn, cSess *sessdata.ConnSession) { return } + putByte(header) + putPayload(payload) + // 限流设置 err = cSess.RateLimit(n, false) if err != nil { diff --git a/server/handler/link_dtls.go b/server/handler/link_dtls.go index 4883a42..d94daaf 100644 --- a/server/handler/link_dtls.go +++ b/server/handler/link_dtls.go @@ -9,7 +9,7 @@ import ( ) func LinkDtls(conn net.Conn, cSess *sessdata.ConnSession) { - base.Debug("LinkDtls connect", cSess.IpAddr, conn.RemoteAddr()) + base.Debug("LinkDtls connect ip:", cSess.IpAddr, "udp-rip:", conn.RemoteAddr()) dSess := cSess.NewDtlsConn() if dSess == nil { // 创建失败,直接关闭链接 @@ -35,7 +35,9 @@ func LinkDtls(conn net.Conn, cSess *sessdata.ConnSession) { base.Error("SetDeadline: ", err) return } - hdata := make([]byte, BufferSize) + + // hdata := make([]byte, BufferSize) + hdata := getByteFull() n, err := conn.Read(hdata) if err != nil { base.Error("read hdata: ", err) @@ -51,9 +53,9 @@ func LinkDtls(conn net.Conn, cSess *sessdata.ConnSession) { switch hdata[0] { case 0x07: // KEEPALIVE // do nothing - base.Debug("recv keepalive", cSess.IpAddr) + // base.Debug("recv keepalive", cSess.IpAddr) case 0x05: // DISCONNECT - base.Debug("DISCONNECT", cSess.IpAddr) + base.Debug("DISCONNECT DTLS", cSess.IpAddr) return case 0x03: // DPD-REQ // base.Debug("recv DPD-REQ", cSess.IpAddr) @@ -67,6 +69,8 @@ func LinkDtls(conn net.Conn, cSess *sessdata.ConnSession) { return } } + + putByte(hdata) } } @@ -78,7 +82,7 @@ func dtlsWrite(conn net.Conn, dSess *sessdata.DtlsSession, cSess *sessdata.ConnS }() var ( - header []byte + // header []byte payload *sessdata.Payload ) @@ -94,14 +98,21 @@ func dtlsWrite(conn net.Conn, dSess *sessdata.DtlsSession, cSess *sessdata.ConnS continue } - header = []byte{payload.PType} - header = append(header, payload.Data...) + // header = []byte{payload.PType} + header := getByteZero() + header = append(header, payload.PType) + if payload.PType == 0x00 { // data + header = append(header, payload.Data...) + } n, err := conn.Write(header) if err != nil { base.Error("write err", err) return } + putByte(header) + putPayload(payload) + // 限流设置 err = cSess.RateLimit(n, false) if err != nil { diff --git a/server/handler/link_tun.go b/server/handler/link_tun.go index 13b7ee2..0a7c3d8 100644 --- a/server/handler/link_tun.go +++ b/server/handler/link_tun.go @@ -84,6 +84,8 @@ func tunWrite(ifce *water.Interface, cSess *sessdata.ConnSession) { base.Error("tun Write err", err) return } + + putPayload(payload) } } @@ -98,15 +100,15 @@ func tunRead(ifce *water.Interface, cSess *sessdata.ConnSession) { ) for { - data := make([]byte, BufferSize) + // data := make([]byte, BufferSize) + data := getByteFull() n, err = ifce.Read(data) if err != nil { base.Error("tun Read err", n, err) return } - data = data[:n] - + // data = data[:n] // ip_src := waterutil.IPv4Source(data) // ip_dst := waterutil.IPv4Destination(data) // ip_port := waterutil.IPv4DestinationPort(data) @@ -114,9 +116,10 @@ func tunRead(ifce *water.Interface, cSess *sessdata.ConnSession) { // packet := gopacket.NewPacket(data, layers.LayerTypeIPv4, gopacket.Default) // fmt.Println("read:", packet) - if payloadOut(cSess, sessdata.LTypeIPData, 0x00, data) { + if payloadOut(cSess, sessdata.LTypeIPData, 0x00, data[:n]) { return } + putByte(data) } } diff --git a/server/handler/payload.go b/server/handler/payload.go index 3264b23..91dd0cc 100644 --- a/server/handler/payload.go +++ b/server/handler/payload.go @@ -7,13 +7,12 @@ import ( ) func payloadIn(cSess *sessdata.ConnSession, lType sessdata.LType, pType byte, data []byte) bool { - payload := &sessdata.Payload{ - LType: lType, - PType: pType, - Data: data, - } + pl := getPayload() + pl.LType = lType + pl.PType = pType + pl.Data = append(pl.Data, data...) - return payloadInData(cSess, payload) + return payloadInData(cSess, pl) } func payloadInData(cSess *sessdata.ConnSession, payload *sessdata.Payload) bool { @@ -44,16 +43,15 @@ func payloadOut(cSess *sessdata.ConnSession, lType sessdata.LType, pType byte, d } func payloadOutCstp(cSess *sessdata.ConnSession, lType sessdata.LType, pType byte, data []byte) bool { - payload := &sessdata.Payload{ - LType: lType, - PType: pType, - Data: data, - } + pl := getPayload() + pl.LType = lType + pl.PType = pType + pl.Data = append(pl.Data, data...) closed := false select { - case cSess.PayloadOutCstp <- payload: + case cSess.PayloadOutCstp <- pl: case <-cSess.CloseChan: closed = true } @@ -62,14 +60,13 @@ func payloadOutCstp(cSess *sessdata.ConnSession, lType sessdata.LType, pType byt } func payloadOutDtls(cSess *sessdata.ConnSession, dSess *sessdata.DtlsSession, lType sessdata.LType, pType byte, data []byte) bool { - payload := &sessdata.Payload{ - LType: lType, - PType: pType, - Data: data, - } + pl := getPayload() + pl.LType = lType + pl.PType = pType + pl.Data = append(pl.Data, data...) select { - case cSess.PayloadOutDtls <- payload: + case cSess.PayloadOutDtls <- pl: case <-dSess.CloseChan: } diff --git a/server/handler/pool.go b/server/handler/pool.go new file mode 100644 index 0000000..27ddffb --- /dev/null +++ b/server/handler/pool.go @@ -0,0 +1,52 @@ +package handler + +import ( + "sync" + + "github.com/bjdgyc/anylink/sessdata" +) + +var plPool = sync.Pool{ + New: func() interface{} { + pl := sessdata.Payload{ + Data: make([]byte, 0, BufferSize), + } + // fmt.Println("plPool-init", len(pl.Data), cap(pl.Data)) + return &pl + }, +} + +func getPayload() *sessdata.Payload { + pl := plPool.Get().(*sessdata.Payload) + return pl +} + +func putPayload(pl *sessdata.Payload) { + pl.LType = 0 + pl.PType = 0 + pl.Data = pl.Data[:0] + plPool.Put(pl) +} + +var bytePool = sync.Pool{ + New: func() interface{} { + b := make([]byte, 0, BufferSize) + // fmt.Println("bytePool-init") + return b + }, +} + +func getByteZero() []byte { + b := bytePool.Get().([]byte) + return b +} + +func getByteFull() []byte { + b := bytePool.Get().([]byte) + b = b[:BufferSize] + return b +} +func putByte(b []byte) { + b = b[:0] + bytePool.Put(b) +} From b704e089b682d4503472c6b17eb5797b2408cf61 Mon Sep 17 00:00:00 2001 From: bjdgyc Date: Sat, 29 May 2021 18:11:50 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BC=98=E5=8C=96gc=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/base/cfg.go | 1 + server/base/config.go | 5 +++-- server/conf/server.toml | 4 +++- server/handler/dtls.go | 4 ++++ server/handler/link_tunnel.go | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/server/base/cfg.go b/server/base/cfg.go index c30cd2e..4d7f79a 100644 --- a/server/base/cfg.go +++ b/server/base/cfg.go @@ -33,6 +33,7 @@ type ServerConfig struct { // LinkAddr string `json:"link_addr"` ServerAddr string `json:"server_addr"` ServerDTLSAddr string `json:"server_dtls_addr"` + ServerDTLS bool `json:"server_dtls"` AdminAddr string `json:"admin_addr"` ProxyProtocol bool `json:"proxy_protocol"` DbFile string `json:"db_file"` diff --git a/server/base/config.go b/server/base/config.go index 6e412ba..f45d80d 100644 --- a/server/base/config.go +++ b/server/base/config.go @@ -16,8 +16,9 @@ type config struct { } var configs = []config{ - {Typ: cfgStr, Name: "server_addr", Usage: "前台服务监听地址", ValStr: ":443"}, - {Typ: cfgStr, Name: "server_dtls_addr", Usage: "前台DTLS监听地址", ValStr: ":4433"}, + {Typ: cfgStr, Name: "server_addr", Usage: "服务监听地址", ValStr: ":443"}, + {Typ: cfgBool, Name: "server_dtls", Usage: "开启DTLS", ValBool: false}, + {Typ: cfgStr, Name: "server_dtls_addr", Usage: "DTLS监听地址", ValStr: ":4433"}, {Typ: cfgStr, Name: "admin_addr", Usage: "后台服务监听地址", ValStr: ":8800"}, {Typ: cfgBool, Name: "proxy_protocol", Usage: "TCP代理协议", ValBool: false}, {Typ: cfgStr, Name: "db_file", Usage: "数据库地址", ValStr: "./data.db"}, diff --git a/server/conf/server.toml b/server/conf/server.toml index 92e166c..0cd6b76 100644 --- a/server/conf/server.toml +++ b/server/conf/server.toml @@ -25,8 +25,10 @@ admin_pass = "$2a$10$UQ7C.EoPifDeJh6d8.31TeSPQU7hM/NOM2nixmBucJpAuXDQNqNke" jwt_secret = "iLmspvOiz*%ovfcs*wersdf#heR8pNU4XxBm&mW$aPCjSRMbYH#&" -#前台服务监听地址 +#服务监听地址 server_addr = ":443" +#开启 DTLS, 默认关闭 +server_dtls = false server_dtls_addr = ":4433" #后台服务监听地址 admin_addr = ":8800" diff --git a/server/handler/dtls.go b/server/handler/dtls.go index d3cc7c9..d897923 100644 --- a/server/handler/dtls.go +++ b/server/handler/dtls.go @@ -21,6 +21,10 @@ import ( // 最后,感谢 github.com/pion/dtls 对golang生态做出的贡献 func startDtls() { + if !base.Cfg.ServerDTLS { + return + } + certificate, err := selfsign.GenerateSelfSigned() if err != nil { panic(err) diff --git a/server/handler/link_tunnel.go b/server/handler/link_tunnel.go index 6388692..8b73780 100644 --- a/server/handler/link_tunnel.go +++ b/server/handler/link_tunnel.go @@ -70,7 +70,7 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) { } cSess.CstpDpd = cstpDpd - dtlsPort := "" + dtlsPort := "4433" if strings.Contains(base.Cfg.ServerDTLSAddr, ":") { ss := strings.Split(base.Cfg.ServerDTLSAddr, ":") dtlsPort = ss[1] From ab58f21b3bab981744c73d04887144d536339975 Mon Sep 17 00:00:00 2001 From: bjdgyc Date: Mon, 31 May 2021 16:20:36 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BC=98=E5=8C=96gc=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/handler/link_tap.go | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/server/handler/link_tap.go b/server/handler/link_tap.go index 2bec160..fa7d7bc 100644 --- a/server/handler/link_tap.go +++ b/server/handler/link_tap.go @@ -89,6 +89,7 @@ func tapWrite(ifce *water.Interface, cSess *sessdata.ConnSession) { var ( err error payload *sessdata.Payload + frame ethernet.Frame ) for { @@ -98,12 +99,14 @@ func tapWrite(ifce *water.Interface, cSess *sessdata.ConnSession) { return } - var frame ethernet.Frame + // var frame ethernet.Frame + frame = getByteFull() switch payload.LType { default: // log.Println(payload) case sessdata.LTypeEthernet: - frame = payload.Data + copy(frame, payload.Data) + frame = frame[:len(payload.Data)] case sessdata.LTypeIPData: // 需要转换成 Ethernet 数据 data := payload.Data @@ -148,6 +151,9 @@ func tapWrite(ifce *water.Interface, cSess *sessdata.ConnSession) { base.Error("tap Write err", err) return } + + putByte(frame) + putPayload(payload) } } @@ -158,14 +164,16 @@ func tapRead(ifce *water.Interface, cSess *sessdata.ConnSession) { }() var ( - err error - n int - buf []byte + err error + n int + buf []byte + frame ethernet.Frame ) for { - var frame ethernet.Frame - frame.Resize(BufferSize) + // var frame ethernet.Frame + // frame.Resize(BufferSize) + frame = getByteFull() n, err = ifce.Read(frame) if err != nil { base.Error("tap Read err", n, err) @@ -237,5 +245,7 @@ func tapRead(ifce *water.Interface, cSess *sessdata.ConnSession) { } } + + putByte(frame) } } From d6aa586349dd33284bccd9e54f84263c6235830f Mon Sep 17 00:00:00 2001 From: bjdgyc Date: Tue, 1 Jun 2021 17:22:06 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0readme=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 103 +++++++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index cd83c1c..4d4e5dd 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,58 @@ sudo ./anylink --conf="conf/server.toml" [conf/server.toml](server/conf/server.toml) + +## Setting + +网络模式选择,需要配置 `link_mode` 参数,如 `link_mode="tun"`,`link_mode="tap"` 两种参数。 不同的参数需要对服务器做相应的设置。 + +建议优先选择tun模式,因客户端传输的是IP层数据,无须进行数据转换。 tap模式是在用户态做的链路层到IP层的数据互相转换,性能会有所下降。 如果需要在虚拟机内开启tap模式,请确认虚拟机的网卡开启混杂模式。 + +### tun设置 + +1. 开启服务器转发 + + ```shell + # flie: /etc/sysctl.conf + net.ipv4.ip_forward = 1 + + #执行如下命令 + sysctl -w net.ipv4.ip_forward=1 + ``` + +2. 设置nat转发规则 + +```shell +# eth0为服务器内网网卡 +iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j MASQUERADE +``` + +3. 使用AnyConnect客户端连接即可 + +### tap设置 + +1. 创建桥接网卡 + +``` +注意 server.toml 的ip参数,需要与 bridge-init.sh 的配置参数一致 +``` + +2. 修改 bridge-init.sh 内的参数 + +``` +eth="eth0" +eth_ip="192.168.1.4" +eth_netmask="255.255.255.0" +eth_broadcast="192.168.1.255" +eth_gateway="192.168.1.1" +``` + +3. 执行 bridge-init.sh 文件 + +``` +sh bridge-init.sh +``` + ## Systemd 添加 systemd脚本 @@ -155,57 +207,6 @@ systemd 脚本放入: docker build -t anylink . ``` -## Setting - -网络模式选择,需要配置 `link_mode` 参数,如 `link_mode="tun"`,`link_mode="tap"` 两种参数。 不同的参数需要对服务器做相应的设置。 - -建议优先选择tun模式,因客户端传输的是IP层数据,无须进行数据转换。 tap模式是在用户态做的链路层到IP层的数据互相转换,性能会有所下降。 如果需要在虚拟机内开启tap模式,请确认虚拟机的网卡开启混杂模式。 - -### tun设置 - -1. 开启服务器转发 - - ```shell - # flie: /etc/sysctl.conf - net.ipv4.ip_forward = 1 - - #执行如下命令 - sysctl -w net.ipv4.ip_forward=1 - ``` - -2. 设置nat转发规则 - -```shell -# eth0为服务器内网网卡 -iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j MASQUERADE -``` - -3. 使用AnyConnect客户端连接即可 - -### tap设置 - -1. 创建桥接网卡 - -``` -注意 server.toml 的ip参数,需要与 bridge-init.sh 的配置参数一致 -``` - -2. 修改 bridge-init.sh 内的参数 - -``` -eth="eth0" -eth_ip="192.168.1.4" -eth_netmask="255.255.255.0" -eth_broadcast="192.168.1.255" -eth_gateway="192.168.1.1" -``` - -3. 执行 bridge-init.sh 文件 - -``` -sh bridge-init.sh -``` - ## 常见问题 请前往 [问题地址](question.md) 查看具体信息