package utp import ( "bufio" "context" "crypto/tls" "encoding/gob" "net" "github.com/anacrolix/utp" "go-micro.dev/v4/transport" maddr "go-micro.dev/v4/util/addr" mnet "go-micro.dev/v4/util/net" mls "go-micro.dev/v4/util/tls" ) func (u *utpTransport) Dial(addr string, opts ...transport.DialOption) (transport.Client, error) { dopts := transport.DialOptions{ Timeout: transport.DefaultDialTimeout, } for _, opt := range opts { opt(&dopts) } ctx, _ := context.WithTimeout(context.Background(), dopts.Timeout) c, err := utp.DialContext(ctx, addr) if err != nil { return nil, err } if u.opts.Secure || u.opts.TLSConfig != nil { config := u.opts.TLSConfig if config == nil { config = &tls.Config{ InsecureSkipVerify: true, } } c = tls.Client(c, config) } encBuf := bufio.NewWriter(c) return &utpClient{ dialOpts: dopts, conn: c, encBuf: encBuf, enc: gob.NewEncoder(encBuf), dec: gob.NewDecoder(c), timeout: u.opts.Timeout, }, nil } func (u *utpTransport) Listen(addr string, opts ...transport.ListenOption) (transport.Listener, error) { var options transport.ListenOptions for _, o := range opts { o(&options) } var l net.Listener var err error if u.opts.Secure || u.opts.TLSConfig != nil { config := u.opts.TLSConfig fn := func(addr string) (net.Listener, error) { if config == nil { hosts := []string{addr} // check if its a valid host:port if host, _, err := net.SplitHostPort(addr); err == nil { if len(host) == 0 { hosts = maddr.IPs() } else { hosts = []string{host} } } // generate a certificate cert, err := mls.Certificate(hosts...) if err != nil { return nil, err } config = &tls.Config{Certificates: []tls.Certificate{cert}} } l, err := utp.Listen(addr) if err != nil { return nil, err } return tls.NewListener(l, config), nil } l, err = mnet.Listen(addr, fn) } else { l, err = mnet.Listen(addr, utp.Listen) } if err != nil { return nil, err } return &utpListener{ t: u.opts.Timeout, l: l, opts: options, }, nil } func (u *utpTransport) Init(opts ...transport.Option) error { for _, o := range opts { o(&u.opts) } return nil } func (u *utpTransport) Options() transport.Options { return u.opts } func (u *utpTransport) String() string { return "utp" }