dockerfiles/anylink/server/handler/link_dtls.go

167 lines
3.5 KiB
Go
Raw Normal View History

2021-06-08 20:45:26 +08:00
package handler
import (
"net"
"time"
"github.com/bjdgyc/anylink/base"
2023-04-26 22:17:10 +08:00
"github.com/bjdgyc/anylink/dbdata"
2021-08-26 23:09:52 +08:00
"github.com/bjdgyc/anylink/pkg/utils"
2021-06-08 20:45:26 +08:00
"github.com/bjdgyc/anylink/sessdata"
)
func LinkDtls(conn net.Conn, cSess *sessdata.ConnSession) {
2022-11-10 15:53:48 +08:00
base.Debug("LinkDtls connect ip:", cSess.IpAddr, "user:", cSess.Username, "udp-rip:", conn.RemoteAddr())
2021-06-08 20:45:26 +08:00
dSess := cSess.NewDtlsConn()
if dSess == nil {
// 创建失败,直接关闭链接
_ = conn.Close()
return
}
defer func() {
2023-04-26 22:17:10 +08:00
base.Debug("LinkDtls return", cSess.Username, cSess.IpAddr)
2021-06-08 20:45:26 +08:00
_ = conn.Close()
dSess.Close()
}()
var (
2021-08-02 20:41:35 +08:00
err error
n int
2021-06-08 20:45:26 +08:00
dead = time.Duration(cSess.CstpDpd+5) * time.Second
)
go dtlsWrite(conn, dSess, cSess)
for {
2021-08-26 23:09:52 +08:00
err = conn.SetReadDeadline(utils.NowSec().Add(dead))
2021-06-08 20:45:26 +08:00
if err != nil {
2023-04-26 22:17:10 +08:00
base.Error("SetDeadline: ", cSess.Username, err)
2021-06-08 20:45:26 +08:00
return
}
2021-08-02 20:41:35 +08:00
pl := getPayload()
n, err = conn.Read(pl.Data)
2021-06-08 20:45:26 +08:00
if err != nil {
2023-04-26 22:17:10 +08:00
base.Error("read hdata: ", cSess.Username, err)
2021-06-08 20:45:26 +08:00
return
}
// 限流设置
err = cSess.RateLimit(n, true)
if err != nil {
base.Error(err)
}
2021-08-02 20:41:35 +08:00
switch pl.Data[0] {
2021-06-08 20:45:26 +08:00
case 0x07: // KEEPALIVE
// do nothing
// base.Debug("recv keepalive", cSess.IpAddr)
case 0x05: // DISCONNECT
2023-04-26 22:17:10 +08:00
cSess.UserLogoutCode = dbdata.UserLogoutClient
base.Debug("DISCONNECT DTLS", cSess.Username, cSess.IpAddr)
2021-06-08 20:45:26 +08:00
return
case 0x03: // DPD-REQ
// base.Debug("recv DPD-REQ", cSess.IpAddr)
2021-08-02 20:41:35 +08:00
pl.PType = 0x04
if payloadOutDtls(cSess, dSess, pl) {
2021-06-08 20:45:26 +08:00
return
}
case 0x04:
2023-04-26 22:17:10 +08:00
// base.Debug("recv DPD-RESP", cSess.IpAddr)
case 0x08: // decompress
if cSess.DtlsPickCmp == nil {
continue
}
dst := getByteFull()
nn, err := cSess.DtlsPickCmp.Uncompress(pl.Data[1:], *dst)
if err != nil {
putByte(dst)
base.Error("dtls decompress error", err, n)
continue
}
pl.Data = append(pl.Data[:1], (*dst)[:nn]...)
putByte(dst)
n = nn + 1
fallthrough
2021-06-08 20:45:26 +08:00
case 0x00: // DATA
2021-08-02 20:41:35 +08:00
// 去除数据头
// copy(pl.Data, pl.Data[1:n])
// 更新切片长度
// pl.Data = pl.Data[:n-1]
pl.Data = append(pl.Data[:0], pl.Data[1:n]...)
if payloadIn(cSess, pl) {
2021-06-08 20:45:26 +08:00
return
}
}
}
}
func dtlsWrite(conn net.Conn, dSess *sessdata.DtlsSession, cSess *sessdata.ConnSession) {
defer func() {
2023-04-26 22:17:10 +08:00
base.Debug("dtlsWrite return", cSess.Username, cSess.IpAddr)
2021-06-08 20:45:26 +08:00
_ = conn.Close()
dSess.Close()
}()
var (
2021-08-02 20:41:35 +08:00
pl *sessdata.Payload
2021-06-08 20:45:26 +08:00
)
for {
// dtls优先推送数据
select {
2021-08-02 20:41:35 +08:00
case pl = <-cSess.PayloadOutDtls:
2021-06-08 20:45:26 +08:00
case <-dSess.CloseChan:
return
}
2021-08-02 20:41:35 +08:00
if pl.LType != sessdata.LTypeIPData {
2021-06-08 20:45:26 +08:00
continue
}
// header = []byte{payload.PType}
2021-08-02 20:41:35 +08:00
if pl.PType == 0x00 { // data
2023-04-26 22:17:10 +08:00
isCompress := false
if cSess.DtlsPickCmp != nil && len(pl.Data) > base.Cfg.NoCompressLimit {
dst := getByteFull()
size, err := cSess.DtlsPickCmp.Compress(pl.Data, (*dst)[1:])
if err == nil && size < len(pl.Data) {
(*dst)[0] = 0x08
pl.Data = append(pl.Data[:0], (*dst)[:size+1]...)
isCompress = true
}
putByte(dst)
}
// 未压缩
if !isCompress {
// 获取数据长度
l := len(pl.Data)
// 先扩容 +1
pl.Data = pl.Data[:l+1]
// 数据后移
copy(pl.Data[1:], pl.Data)
// 添加头信息
pl.Data[0] = pl.PType
}
2021-08-02 20:41:35 +08:00
} else {
// 设置头类型
pl.Data = append(pl.Data[:0], pl.PType)
2021-06-08 20:45:26 +08:00
}
2021-08-02 20:41:35 +08:00
n, err := conn.Write(pl.Data)
2021-06-08 20:45:26 +08:00
if err != nil {
2023-04-26 22:17:10 +08:00
base.Error("write err", cSess.Username, err)
2021-06-08 20:45:26 +08:00
return
}
2021-08-02 20:41:35 +08:00
putPayload(pl)
2021-06-08 20:45:26 +08:00
// 限流设置
err = cSess.RateLimit(n, false)
if err != nil {
base.Error(err)
}
}
}