a20a7db793
It provides an abstraction around the rpc details so that one can use dprc or gprc with the same code. It subsumes using the protobuf package directly for client interfaces as well as the pkg/transport package to perform dials. Change-Id: I8f5688bd71be8b0c766f13029128a77e5d46320b
76 lines
1.8 KiB
Go
76 lines
1.8 KiB
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
// +build drpc
|
|
|
|
package rpc
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
|
|
"storj.io/drpc/drpcconn"
|
|
)
|
|
|
|
const drpcHeader = "DRPC!!!1"
|
|
|
|
// dial performs the dialing to the drpc endpoint with tls.
|
|
func (d Dialer) dial(ctx context.Context, address string, tlsConfig *tls.Config) (_ *Conn, err error) {
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
// set up an error to expire when the context is canceled
|
|
errCh := make(chan error, 2)
|
|
go func() {
|
|
<-ctx.Done()
|
|
errCh <- ctx.Err()
|
|
}()
|
|
|
|
// open the tcp socket to the address
|
|
rawConn, err := d.dialContext(ctx, address)
|
|
if err != nil {
|
|
return nil, Error.Wrap(err)
|
|
}
|
|
|
|
// write the header bytes before the tls handshake
|
|
if _, err := rawConn.Write([]byte(drpcHeader)); err != nil {
|
|
_ = rawConn.Close()
|
|
return nil, Error.Wrap(err)
|
|
}
|
|
|
|
// perform the handshake racing with the context closing
|
|
conn := tls.Client(rawConn, tlsConfig)
|
|
go func() { errCh <- conn.Handshake() }()
|
|
|
|
// see which wins and close the raw conn if there was any error. we can't
|
|
// close the tls connection concurrently with handshakes or it sometimes
|
|
// will panic. cool, huh?
|
|
if err := <-errCh; err != nil {
|
|
_ = rawConn.Close()
|
|
return nil, Error.Wrap(err)
|
|
}
|
|
|
|
return &Conn{
|
|
raw: drpcconn.New(conn),
|
|
state: conn.ConnectionState(),
|
|
}, nil
|
|
}
|
|
|
|
// dialInsecure performs dialing to the drpc endpoint with no tls.
|
|
func (d Dialer) dialInsecure(ctx context.Context, address string) (_ *Conn, err error) {
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
// open the tcp socket to the address
|
|
conn, err := d.dialContext(ctx, address)
|
|
if err != nil {
|
|
return nil, Error.Wrap(err)
|
|
}
|
|
|
|
// write the header bytes before the tls handshake
|
|
if _, err := conn.Write([]byte(drpcHeader)); err != nil {
|
|
_ = conn.Close()
|
|
return nil, Error.Wrap(err)
|
|
}
|
|
|
|
return &Conn{raw: drpcconn.New(conn)}, nil
|
|
}
|