package handler import ( "net" "time" "github.com/bjdgyc/anylink/base" "github.com/bjdgyc/anylink/sessdata" ) func LinkDtls(conn net.Conn, cSess *sessdata.ConnSession) { base.Debug("LinkDtls connect ip:", cSess.IpAddr, "udp-rip:", conn.RemoteAddr()) dSess := cSess.NewDtlsConn() if dSess == nil { // 创建失败,直接关闭链接 _ = conn.Close() return } defer func() { base.Debug("LinkDtls return", cSess.IpAddr) _ = conn.Close() dSess.Close() }() var ( dead = time.Duration(cSess.CstpDpd+5) * time.Second ) go dtlsWrite(conn, dSess, cSess) for { err := conn.SetReadDeadline(time.Now().Add(dead)) if err != nil { base.Error("SetDeadline: ", err) return } hb := getByteFull() hdata := *hb n, err := conn.Read(hdata) if err != nil { base.Error("read hdata: ", err) return } // 限流设置 err = cSess.RateLimit(n, true) if err != nil { base.Error(err) } switch hdata[0] { case 0x07: // KEEPALIVE // do nothing // base.Debug("recv keepalive", cSess.IpAddr) case 0x05: // DISCONNECT base.Debug("DISCONNECT DTLS", cSess.IpAddr) return case 0x03: // DPD-REQ // base.Debug("recv DPD-REQ", cSess.IpAddr) if payloadOutDtls(cSess, dSess, sessdata.LTypeIPData, 0x04, nil) { return } case 0x04: // base.Debug("recv DPD-RESP", cSess.IpAddr) case 0x00: // DATA if payloadIn(cSess, sessdata.LTypeIPData, 0x00, hdata[1:n]) { return } } putByte(hb) } } func dtlsWrite(conn net.Conn, dSess *sessdata.DtlsSession, cSess *sessdata.ConnSession) { defer func() { base.Debug("dtlsWrite return", cSess.IpAddr) _ = conn.Close() dSess.Close() }() var ( // header []byte payload *sessdata.Payload ) for { // dtls优先推送数据 select { case payload = <-cSess.PayloadOutDtls: case <-dSess.CloseChan: return } if payload.LType != sessdata.LTypeIPData { continue } // header = []byte{payload.PType} hb := getByteZero() header := *hb 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(hb) putPayload(payload) // 限流设置 err = cSess.RateLimit(n, false) if err != nil { base.Error(err) } } }