github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/gossip/comm/comm_impl.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package comm
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/tls"
    22  	"errors"
    23  	"fmt"
    24  	"net"
    25  	"reflect"
    26  	"sync"
    27  	"sync/atomic"
    28  	"time"
    29  
    30  	"github.com/hyperledger/fabric/gossip/api"
    31  	"github.com/hyperledger/fabric/gossip/common"
    32  	"github.com/hyperledger/fabric/gossip/identity"
    33  	"github.com/hyperledger/fabric/gossip/util"
    34  	proto "github.com/hyperledger/fabric/protos/gossip"
    35  	"github.com/op/go-logging"
    36  	"github.com/spf13/viper"
    37  	"golang.org/x/net/context"
    38  	"google.golang.org/grpc"
    39  	"google.golang.org/grpc/credentials"
    40  	"google.golang.org/grpc/peer"
    41  )
    42  
    43  const (
    44  	defDialTimeout  = time.Second * time.Duration(3)
    45  	defConnTimeout  = time.Second * time.Duration(2)
    46  	defRecvBuffSize = 20
    47  	defSendBuffSize = 20
    48  )
    49  
    50  // SetDialTimeout sets the dial timeout
    51  func SetDialTimeout(timeout time.Duration) {
    52  	viper.Set("peer.gossip.dialTimeout", timeout)
    53  }
    54  
    55  func (c *commImpl) SetDialOpts(opts ...grpc.DialOption) {
    56  	if len(opts) == 0 {
    57  		c.logger.Warning("Given an empty set of grpc.DialOption, aborting")
    58  		return
    59  	}
    60  	c.opts = opts
    61  }
    62  
    63  // NewCommInstanceWithServer creates a comm instance that creates an underlying gRPC server
    64  func NewCommInstanceWithServer(port int, idMapper identity.Mapper, peerIdentity api.PeerIdentityType,
    65  	secureDialOpts api.PeerSecureDialOpts, dialOpts ...grpc.DialOption) (Comm, error) {
    66  
    67  	var ll net.Listener
    68  	var s *grpc.Server
    69  	var certHash []byte
    70  
    71  	if len(dialOpts) == 0 {
    72  		dialOpts = []grpc.DialOption{grpc.WithTimeout(util.GetDurationOrDefault("peer.gossip.dialTimeout", defDialTimeout))}
    73  	}
    74  
    75  	if port > 0 {
    76  		s, ll, secureDialOpts, certHash = createGRPCLayer(port)
    77  	}
    78  
    79  	commInst := &commImpl{
    80  		selfCertHash:   certHash,
    81  		PKIID:          idMapper.GetPKIidOfCert(peerIdentity),
    82  		idMapper:       idMapper,
    83  		logger:         util.GetLogger(util.LoggingCommModule, fmt.Sprintf("%d", port)),
    84  		peerIdentity:   peerIdentity,
    85  		opts:           dialOpts,
    86  		secureDialOpts: secureDialOpts,
    87  		port:           port,
    88  		lsnr:           ll,
    89  		gSrv:           s,
    90  		msgPublisher:   NewChannelDemultiplexer(),
    91  		lock:           &sync.RWMutex{},
    92  		deadEndpoints:  make(chan common.PKIidType, 100),
    93  		stopping:       int32(0),
    94  		exitChan:       make(chan struct{}, 1),
    95  		subscriptions:  make([]chan proto.ReceivedMessage, 0),
    96  	}
    97  	commInst.connStore = newConnStore(commInst, commInst.logger)
    98  
    99  	if port > 0 {
   100  		commInst.stopWG.Add(1)
   101  		go func() {
   102  			defer commInst.stopWG.Done()
   103  			s.Serve(ll)
   104  		}()
   105  		proto.RegisterGossipServer(s, commInst)
   106  	}
   107  
   108  	return commInst, nil
   109  }
   110  
   111  // NewCommInstance creates a new comm instance that binds itself to the given gRPC server
   112  func NewCommInstance(s *grpc.Server, cert *tls.Certificate, idStore identity.Mapper,
   113  	peerIdentity api.PeerIdentityType, secureDialOpts api.PeerSecureDialOpts,
   114  	dialOpts ...grpc.DialOption) (Comm, error) {
   115  
   116  	dialOpts = append(dialOpts, grpc.WithTimeout(util.GetDurationOrDefault("peer.gossip.dialTimeout", defDialTimeout)))
   117  	commInst, err := NewCommInstanceWithServer(-1, idStore, peerIdentity, secureDialOpts, dialOpts...)
   118  	if err != nil {
   119  		return nil, err
   120  	}
   121  
   122  	if cert != nil {
   123  		inst := commInst.(*commImpl)
   124  		if len(cert.Certificate) == 0 {
   125  			inst.logger.Panic("Certificate supplied but certificate chain is empty")
   126  		} else {
   127  			inst.selfCertHash = certHashFromRawCert(cert.Certificate[0])
   128  		}
   129  	}
   130  
   131  	proto.RegisterGossipServer(s, commInst.(*commImpl))
   132  
   133  	return commInst, nil
   134  }
   135  
   136  type commImpl struct {
   137  	selfCertHash   []byte
   138  	peerIdentity   api.PeerIdentityType
   139  	idMapper       identity.Mapper
   140  	logger         *logging.Logger
   141  	opts           []grpc.DialOption
   142  	secureDialOpts func() []grpc.DialOption
   143  	connStore      *connectionStore
   144  	PKIID          []byte
   145  	deadEndpoints  chan common.PKIidType
   146  	msgPublisher   *ChannelDeMultiplexer
   147  	lock           *sync.RWMutex
   148  	lsnr           net.Listener
   149  	gSrv           *grpc.Server
   150  	exitChan       chan struct{}
   151  	stopWG         sync.WaitGroup
   152  	subscriptions  []chan proto.ReceivedMessage
   153  	port           int
   154  	stopping       int32
   155  }
   156  
   157  func (c *commImpl) createConnection(endpoint string, expectedPKIID common.PKIidType) (*connection, error) {
   158  	var err error
   159  	var cc *grpc.ClientConn
   160  	var stream proto.Gossip_GossipStreamClient
   161  	var pkiID common.PKIidType
   162  	var connInfo *proto.ConnectionInfo
   163  	var dialOpts []grpc.DialOption
   164  
   165  	c.logger.Debug("Entering", endpoint, expectedPKIID)
   166  	defer c.logger.Debug("Exiting")
   167  
   168  	if c.isStopping() {
   169  		return nil, errors.New("Stopping")
   170  	}
   171  	dialOpts = append(dialOpts, c.secureDialOpts()...)
   172  	dialOpts = append(dialOpts, grpc.WithBlock())
   173  	dialOpts = append(dialOpts, c.opts...)
   174  	cc, err = grpc.Dial(endpoint, dialOpts...)
   175  	if err != nil {
   176  		return nil, err
   177  	}
   178  
   179  	cl := proto.NewGossipClient(cc)
   180  
   181  	if _, err = cl.Ping(context.Background(), &proto.Empty{}); err != nil {
   182  		cc.Close()
   183  		return nil, err
   184  	}
   185  
   186  	ctx, cf := context.WithCancel(context.Background())
   187  	if stream, err = cl.GossipStream(ctx); err == nil {
   188  		connInfo, err = c.authenticateRemotePeer(stream)
   189  		if err == nil {
   190  			pkiID = connInfo.ID
   191  			if expectedPKIID != nil && !bytes.Equal(pkiID, expectedPKIID) {
   192  				// PKIID is nil when we don't know the remote PKI id's
   193  				c.logger.Warning("Remote endpoint claims to be a different peer, expected", expectedPKIID, "but got", pkiID)
   194  				cc.Close()
   195  				return nil, errors.New("Authentication failure")
   196  			}
   197  			conn := newConnection(cl, cc, stream, nil)
   198  			conn.pkiID = pkiID
   199  			conn.info = connInfo
   200  			conn.logger = c.logger
   201  			conn.cancel = cf
   202  
   203  			h := func(m *proto.SignedGossipMessage) {
   204  				c.logger.Debug("Got message:", m)
   205  				c.msgPublisher.DeMultiplex(&ReceivedMessageImpl{
   206  					conn:                conn,
   207  					lock:                conn,
   208  					SignedGossipMessage: m,
   209  					connInfo:            connInfo,
   210  				})
   211  			}
   212  			conn.handler = h
   213  			return conn, nil
   214  		}
   215  		c.logger.Warning("Authentication failed:", err)
   216  	}
   217  	cc.Close()
   218  	return nil, err
   219  }
   220  
   221  func (c *commImpl) Send(msg *proto.SignedGossipMessage, peers ...*RemotePeer) {
   222  	if c.isStopping() || len(peers) == 0 {
   223  		return
   224  	}
   225  
   226  	c.logger.Debug("Entering, sending", msg, "to ", len(peers), "peers")
   227  
   228  	for _, peer := range peers {
   229  		go func(peer *RemotePeer, msg *proto.SignedGossipMessage) {
   230  			c.sendToEndpoint(peer, msg)
   231  		}(peer, msg)
   232  	}
   233  }
   234  
   235  func (c *commImpl) sendToEndpoint(peer *RemotePeer, msg *proto.SignedGossipMessage) {
   236  	if c.isStopping() {
   237  		return
   238  	}
   239  	c.logger.Debug("Entering, Sending to", peer.Endpoint, ", msg:", msg)
   240  	defer c.logger.Debug("Exiting")
   241  	var err error
   242  
   243  	conn, err := c.connStore.getConnection(peer)
   244  	if err == nil {
   245  		disConnectOnErr := func(err error) {
   246  			c.logger.Warning(peer, "isn't responsive:", err)
   247  			c.disconnect(peer.PKIID)
   248  		}
   249  		conn.send(msg, disConnectOnErr)
   250  		return
   251  	}
   252  	c.logger.Warning("Failed obtaining connection for", peer, "reason:", err)
   253  	c.disconnect(peer.PKIID)
   254  }
   255  
   256  func (c *commImpl) isStopping() bool {
   257  	return atomic.LoadInt32(&c.stopping) == int32(1)
   258  }
   259  
   260  func (c *commImpl) Probe(remotePeer *RemotePeer) error {
   261  	var dialOpts []grpc.DialOption
   262  	endpoint := remotePeer.Endpoint
   263  	pkiID := remotePeer.PKIID
   264  	if c.isStopping() {
   265  		return errors.New("Stopping")
   266  	}
   267  	c.logger.Debug("Entering, endpoint:", endpoint, "PKIID:", pkiID)
   268  	dialOpts = append(dialOpts, c.secureDialOpts()...)
   269  	dialOpts = append(dialOpts, grpc.WithBlock())
   270  	dialOpts = append(dialOpts, c.opts...)
   271  
   272  	cc, err := grpc.Dial(remotePeer.Endpoint, dialOpts...)
   273  	if err != nil {
   274  		c.logger.Debug("Returning", err)
   275  		return err
   276  	}
   277  	defer cc.Close()
   278  	cl := proto.NewGossipClient(cc)
   279  	_, err = cl.Ping(context.Background(), &proto.Empty{})
   280  	c.logger.Debug("Returning", err)
   281  	return err
   282  }
   283  
   284  func (c *commImpl) Handshake(remotePeer *RemotePeer) (api.PeerIdentityType, error) {
   285  	var dialOpts []grpc.DialOption
   286  	dialOpts = append(dialOpts, c.secureDialOpts()...)
   287  	dialOpts = append(dialOpts, grpc.WithBlock())
   288  	dialOpts = append(dialOpts, c.opts...)
   289  
   290  	cc, err := grpc.Dial(remotePeer.Endpoint, dialOpts...)
   291  	if err != nil {
   292  		return nil, err
   293  	}
   294  	defer cc.Close()
   295  
   296  	cl := proto.NewGossipClient(cc)
   297  	if _, err = cl.Ping(context.Background(), &proto.Empty{}); err != nil {
   298  		return nil, err
   299  	}
   300  
   301  	stream, err := cl.GossipStream(context.Background())
   302  	if err != nil {
   303  		return nil, err
   304  	}
   305  	connInfo, err := c.authenticateRemotePeer(stream)
   306  	if err != nil {
   307  		c.logger.Warning("Authentication failed:", err)
   308  		return nil, err
   309  	}
   310  	if len(remotePeer.PKIID) > 0 && !bytes.Equal(connInfo.ID, remotePeer.PKIID) {
   311  		return nil, errors.New("PKI-ID of remote peer doesn't match expected PKI-ID")
   312  	}
   313  	return connInfo.Identity, nil
   314  }
   315  
   316  func (c *commImpl) Accept(acceptor common.MessageAcceptor) <-chan proto.ReceivedMessage {
   317  	genericChan := c.msgPublisher.AddChannel(acceptor)
   318  	specificChan := make(chan proto.ReceivedMessage, 10)
   319  
   320  	if c.isStopping() {
   321  		c.logger.Warning("Accept() called but comm module is stopping, returning empty channel")
   322  		return specificChan
   323  	}
   324  
   325  	c.lock.Lock()
   326  	c.subscriptions = append(c.subscriptions, specificChan)
   327  	c.lock.Unlock()
   328  
   329  	go func() {
   330  		defer c.logger.Debug("Exiting Accept() loop")
   331  		defer func() {
   332  			recover()
   333  		}()
   334  
   335  		c.stopWG.Add(1)
   336  		defer c.stopWG.Done()
   337  
   338  		for {
   339  			select {
   340  			case msg := <-genericChan:
   341  				specificChan <- msg.(*ReceivedMessageImpl)
   342  			case s := <-c.exitChan:
   343  				c.exitChan <- s
   344  				return
   345  			}
   346  		}
   347  	}()
   348  	return specificChan
   349  }
   350  
   351  func (c *commImpl) PresumedDead() <-chan common.PKIidType {
   352  	return c.deadEndpoints
   353  }
   354  
   355  func (c *commImpl) CloseConn(peer *RemotePeer) {
   356  	c.logger.Debug("Closing connection for", peer)
   357  	c.connStore.closeConn(peer)
   358  }
   359  
   360  func (c *commImpl) emptySubscriptions() {
   361  	c.lock.Lock()
   362  	defer c.lock.Unlock()
   363  	for _, ch := range c.subscriptions {
   364  		close(ch)
   365  	}
   366  }
   367  
   368  func (c *commImpl) Stop() {
   369  	if c.isStopping() {
   370  		return
   371  	}
   372  	atomic.StoreInt32(&c.stopping, int32(1))
   373  	c.logger.Info("Stopping")
   374  	defer c.logger.Info("Stopped")
   375  	if c.gSrv != nil {
   376  		c.gSrv.Stop()
   377  	}
   378  	if c.lsnr != nil {
   379  		c.lsnr.Close()
   380  	}
   381  	c.connStore.shutdown()
   382  	c.logger.Debug("Shut down connection store, connection count:", c.connStore.connNum())
   383  	c.exitChan <- struct{}{}
   384  	c.msgPublisher.Close()
   385  	c.logger.Debug("Shut down publisher")
   386  	c.emptySubscriptions()
   387  	c.logger.Debug("Closed subscriptions, waiting for goroutines to stop...")
   388  	c.stopWG.Wait()
   389  }
   390  
   391  func (c *commImpl) GetPKIid() common.PKIidType {
   392  	return c.PKIID
   393  }
   394  
   395  func extractRemoteAddress(stream stream) string {
   396  	var remoteAddress string
   397  	p, ok := peer.FromContext(stream.Context())
   398  	if ok {
   399  		if address := p.Addr; address != nil {
   400  			remoteAddress = address.String()
   401  		}
   402  	}
   403  	return remoteAddress
   404  }
   405  
   406  func (c *commImpl) authenticateRemotePeer(stream stream) (*proto.ConnectionInfo, error) {
   407  	ctx := stream.Context()
   408  	remoteAddress := extractRemoteAddress(stream)
   409  	remoteCertHash := extractCertificateHashFromContext(ctx)
   410  	var err error
   411  	var cMsg *proto.SignedGossipMessage
   412  	var signer proto.Signer
   413  	useTLS := c.selfCertHash != nil
   414  
   415  	// If TLS is enabled, sign the connection message in order to bind
   416  	// the TLS session to the peer's identity
   417  	if useTLS {
   418  		signer = func(msg []byte) ([]byte, error) {
   419  			return c.idMapper.Sign(msg)
   420  		}
   421  	} else { // If we don't use TLS, we have no unique text to sign,
   422  		//  so don't sign anything
   423  		signer = func(msg []byte) ([]byte, error) {
   424  			return msg, nil
   425  		}
   426  	}
   427  
   428  	// TLS enabled but not detected on other side
   429  	if useTLS && len(remoteCertHash) == 0 {
   430  		c.logger.Warningf("%s didn't send TLS certificate", remoteAddress)
   431  		return nil, errors.New("No TLS certificate")
   432  	}
   433  
   434  	cMsg, err = c.createConnectionMsg(c.PKIID, c.selfCertHash, c.peerIdentity, signer)
   435  	if err != nil {
   436  		return nil, err
   437  	}
   438  
   439  	c.logger.Debug("Sending", cMsg, "to", remoteAddress)
   440  	stream.Send(cMsg.Envelope)
   441  	m, err := readWithTimeout(stream, util.GetDurationOrDefault("peer.gossip.connTimeout", defConnTimeout), remoteAddress)
   442  	if err != nil {
   443  		c.logger.Warningf("Failed reading messge from %s, reason: %v", remoteAddress, err)
   444  		return nil, err
   445  	}
   446  	receivedMsg := m.GetConn()
   447  	if receivedMsg == nil {
   448  		c.logger.Warning("Expected connection message from", remoteAddress, "but got", receivedMsg)
   449  		return nil, errors.New("Wrong type")
   450  	}
   451  
   452  	if receivedMsg.PkiId == nil {
   453  		c.logger.Warning("%s didn't send a pkiID", remoteAddress)
   454  		return nil, errors.New("No PKI-ID")
   455  	}
   456  
   457  	c.logger.Debug("Received", receivedMsg, "from", remoteAddress)
   458  	err = c.idMapper.Put(receivedMsg.PkiId, receivedMsg.Identity)
   459  	if err != nil {
   460  		c.logger.Warning("Identity store rejected", remoteAddress, ":", err)
   461  		return nil, err
   462  	}
   463  
   464  	connInfo := &proto.ConnectionInfo{
   465  		ID:       receivedMsg.PkiId,
   466  		Identity: receivedMsg.Identity,
   467  		Endpoint: remoteAddress,
   468  	}
   469  
   470  	// if TLS is enabled and detected, verify remote peer
   471  	if useTLS {
   472  		// If the remote peer sent its TLS certificate, make sure it actually matches the TLS cert
   473  		// that the peer used.
   474  		if !bytes.Equal(remoteCertHash, receivedMsg.TlsCertHash) {
   475  			return nil, fmt.Errorf("Expected %v in remote hash of TLS cert, but got %v", remoteCertHash, receivedMsg.TlsCertHash)
   476  		}
   477  		verifier := func(peerIdentity []byte, signature, message []byte) error {
   478  			pkiID := c.idMapper.GetPKIidOfCert(api.PeerIdentityType(peerIdentity))
   479  			return c.idMapper.Verify(pkiID, signature, message)
   480  		}
   481  		err = m.Verify(receivedMsg.Identity, verifier)
   482  		if err != nil {
   483  			c.logger.Error("Failed verifying signature from", remoteAddress, ":", err)
   484  			return nil, err
   485  		}
   486  		connInfo.Auth = &proto.AuthInfo{
   487  			Signature:  m.Signature,
   488  			SignedData: m.Payload,
   489  		}
   490  	}
   491  
   492  	c.logger.Debug("Authenticated", remoteAddress)
   493  
   494  	return connInfo, nil
   495  }
   496  
   497  func (c *commImpl) GossipStream(stream proto.Gossip_GossipStreamServer) error {
   498  	if c.isStopping() {
   499  		return errors.New("Shutting down")
   500  	}
   501  	connInfo, err := c.authenticateRemotePeer(stream)
   502  	if err != nil {
   503  		c.logger.Error("Authentication failed:", err)
   504  		return err
   505  	}
   506  	c.logger.Debug("Servicing", extractRemoteAddress(stream))
   507  
   508  	conn := c.connStore.onConnected(stream, connInfo)
   509  
   510  	// if connStore denied the connection, it means we already have a connection to that peer
   511  	// so close this stream
   512  	if conn == nil {
   513  		return nil
   514  	}
   515  
   516  	h := func(m *proto.SignedGossipMessage) {
   517  		c.msgPublisher.DeMultiplex(&ReceivedMessageImpl{
   518  			conn:                conn,
   519  			lock:                conn,
   520  			SignedGossipMessage: m,
   521  			connInfo:            connInfo,
   522  		})
   523  	}
   524  
   525  	conn.handler = h
   526  
   527  	defer func() {
   528  		c.logger.Debug("Client", extractRemoteAddress(stream), " disconnected")
   529  		c.connStore.closeByPKIid(connInfo.ID)
   530  		conn.close()
   531  	}()
   532  
   533  	return conn.serviceConnection()
   534  }
   535  
   536  func (c *commImpl) Ping(context.Context, *proto.Empty) (*proto.Empty, error) {
   537  	return &proto.Empty{}, nil
   538  }
   539  
   540  func (c *commImpl) disconnect(pkiID common.PKIidType) {
   541  	if c.isStopping() {
   542  		return
   543  	}
   544  	c.deadEndpoints <- pkiID
   545  	c.connStore.closeByPKIid(pkiID)
   546  }
   547  
   548  func readWithTimeout(stream interface{}, timeout time.Duration, address string) (*proto.SignedGossipMessage, error) {
   549  	incChan := make(chan *proto.SignedGossipMessage, 1)
   550  	errChan := make(chan error, 1)
   551  	go func() {
   552  		if srvStr, isServerStr := stream.(proto.Gossip_GossipStreamServer); isServerStr {
   553  			if m, err := srvStr.Recv(); err == nil {
   554  				msg, err := m.ToGossipMessage()
   555  				if err != nil {
   556  					errChan <- err
   557  					return
   558  				}
   559  				incChan <- msg
   560  			}
   561  		} else if clStr, isClientStr := stream.(proto.Gossip_GossipStreamClient); isClientStr {
   562  			if m, err := clStr.Recv(); err == nil {
   563  				msg, err := m.ToGossipMessage()
   564  				if err != nil {
   565  					errChan <- err
   566  					return
   567  				}
   568  				incChan <- msg
   569  			}
   570  		} else {
   571  			panic(fmt.Errorf("Stream isn't a GossipStreamServer or a GossipStreamClient, but %v. Aborting", reflect.TypeOf(stream)))
   572  		}
   573  	}()
   574  	select {
   575  	case <-time.NewTicker(timeout).C:
   576  		return nil, fmt.Errorf("Timed out waiting for connection message from %s", address)
   577  	case m := <-incChan:
   578  		return m, nil
   579  	case err := <-errChan:
   580  		return nil, err
   581  	}
   582  }
   583  
   584  func (c *commImpl) createConnectionMsg(pkiID common.PKIidType, certHash []byte, cert api.PeerIdentityType, signer proto.Signer) (*proto.SignedGossipMessage, error) {
   585  	m := &proto.GossipMessage{
   586  		Tag:   proto.GossipMessage_EMPTY,
   587  		Nonce: 0,
   588  		Content: &proto.GossipMessage_Conn{
   589  			Conn: &proto.ConnEstablish{
   590  				TlsCertHash: certHash,
   591  				Identity:    cert,
   592  				PkiId:       pkiID,
   593  			},
   594  		},
   595  	}
   596  	sMsg := &proto.SignedGossipMessage{
   597  		GossipMessage: m,
   598  	}
   599  	_, err := sMsg.Sign(signer)
   600  	return sMsg, err
   601  }
   602  
   603  type stream interface {
   604  	Send(envelope *proto.Envelope) error
   605  	Recv() (*proto.Envelope, error)
   606  	grpc.Stream
   607  }
   608  
   609  func createGRPCLayer(port int) (*grpc.Server, net.Listener, api.PeerSecureDialOpts, []byte) {
   610  	var returnedCertHash []byte
   611  	var s *grpc.Server
   612  	var ll net.Listener
   613  	var err error
   614  	var serverOpts []grpc.ServerOption
   615  	var dialOpts []grpc.DialOption
   616  
   617  	cert := GenerateCertificatesOrPanic()
   618  	returnedCertHash = certHashFromRawCert(cert.Certificate[0])
   619  
   620  	tlsConf := &tls.Config{
   621  		Certificates:       []tls.Certificate{cert},
   622  		ClientAuth:         tls.RequestClientCert,
   623  		InsecureSkipVerify: true,
   624  	}
   625  	serverOpts = append(serverOpts, grpc.Creds(credentials.NewTLS(tlsConf)))
   626  	ta := credentials.NewTLS(&tls.Config{
   627  		Certificates:       []tls.Certificate{cert},
   628  		InsecureSkipVerify: true,
   629  	})
   630  	dialOpts = append(dialOpts, grpc.WithTransportCredentials(ta))
   631  
   632  	listenAddress := fmt.Sprintf("%s:%d", "", port)
   633  	ll, err = net.Listen("tcp", listenAddress)
   634  	if err != nil {
   635  		panic(err)
   636  	}
   637  	secureDialOpts := func() []grpc.DialOption {
   638  		return dialOpts
   639  	}
   640  	s = grpc.NewServer(serverOpts...)
   641  	return s, ll, secureDialOpts, returnedCertHash
   642  }