package handler import ( "context" "crypto/tls" "encoding/hex" "fmt" "net" "time" "github.com/bjdgyc/anylink/base" "github.com/bjdgyc/anylink/sessdata" "github.com/pion/dtls/v2" "github.com/pion/dtls/v2/pkg/crypto/selfsign" "github.com/pion/logging" ) // 因本项目对 github.com/pion/dtls 的代码,进行了大量的修改 // 且短时间内无法合并到上游项目 // 所以本项目暂时copy了一份代码 // 最后,感谢 github.com/pion/dtls 对golang生态做出的贡献 func startDtls() { if !base.Cfg.ServerDTLS { return } certificate, err := selfsign.GenerateSelfSigned() if err != nil { panic(err) } logf := logging.NewDefaultLoggerFactory() logf.Writer = base.GetBaseLw() // logf.DefaultLogLevel = logging.LogLevelTrace logf.DefaultLogLevel = logging.LogLevelInfo config := &dtls.Config{ Certificates: []tls.Certificate{certificate}, InsecureSkipVerify: true, ExtendedMasterSecret: dtls.DisableExtendedMasterSecret, CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, LoggerFactory: logf, MTU: BufferSize, CiscoCompat: func(sessid []byte) ([]byte, error) { masterSecret := sessdata.Dtls2MasterSecret(hex.EncodeToString(sessid)) if masterSecret == "" { return nil, fmt.Errorf("masterSecret is err") } return hex.DecodeString(masterSecret) }, ConnectContextMaker: func() (context.Context, func()) { return context.WithTimeout(context.Background(), 5*time.Second) }, } addr, err := net.ResolveUDPAddr("udp", base.Cfg.ServerDTLSAddr) if err != nil { panic(err) } ln, err := dtls.Listen("udp", addr, config) if err != nil { panic(err) } base.Info("listen DTLS server", addr) for { conn, err := ln.Accept() if err != nil { base.Error("DTLS Accept error", err) continue } go func() { // time.Sleep(1 * time.Second) cc := conn.(*dtls.Conn) sessid := hex.EncodeToString(cc.ConnectionState().SessionID) sess := sessdata.Dtls2Sess(sessid) LinkDtls(conn, sess.CSess) }() } }