go.dedis.ch/onet/v4@v4.0.0-pre1/network/struct.go (about)

     1  package network
     2  
     3  import (
     4  	"bytes"
     5  	"net"
     6  	"strings"
     7  	"sync"
     8  	"time"
     9  
    10  	"go.dedis.ch/kyber/v4"
    11  	"go.dedis.ch/kyber/v4/suites"
    12  	"go.dedis.ch/kyber/v4/util/encoding"
    13  	"go.dedis.ch/kyber/v4/util/key"
    14  	"go.dedis.ch/onet/v4/log"
    15  	"go.dedis.ch/protobuf"
    16  	"golang.org/x/xerrors"
    17  	uuid "gopkg.in/satori/go.uuid.v1"
    18  )
    19  
    20  // MaxRetryConnect defines how many times we should try to connect.
    21  const MaxRetryConnect = 5
    22  
    23  // MaxIdentityExchange is the timeout for an identityExchange.
    24  const MaxIdentityExchange = 5 * time.Second
    25  
    26  // WaitRetry is the timeout on connection-setups.
    27  const WaitRetry = 20 * time.Millisecond
    28  
    29  // ErrClosed is when a connection has been closed.
    30  var ErrClosed = xerrors.New("Connection Closed")
    31  
    32  // ErrEOF is when the connection sends an EOF signal (mostly because it has
    33  // been shut down).
    34  var ErrEOF = xerrors.New("EOF")
    35  
    36  // ErrCanceled means something went wrong in the sending or receiving part.
    37  var ErrCanceled = xerrors.New("Operation Canceled")
    38  
    39  // ErrTimeout is raised if the timeout has been reached.
    40  var ErrTimeout = xerrors.New("Timeout Error")
    41  
    42  // ErrUnknown is an unknown error.
    43  var ErrUnknown = xerrors.New("Unknown Error")
    44  
    45  // Size is a type to reprensent the size that is sent before every packet to
    46  // correctly decode it.
    47  type Size uint32
    48  
    49  // Envelope is a container for any Message received through the network that
    50  // contains the Message itself as well as some metadata such as the type and the
    51  // sender. This is created by the network stack upon reception and is never
    52  // transmitted.
    53  type Envelope struct {
    54  	// The ServerIdentity of the remote peer we are talking to.
    55  	// Basically, this means that when you open a new connection to someone, and
    56  	// or listen to incoming connections, the network library will already
    57  	// make some exchange between the two communicants so each knows the
    58  	// ServerIdentity of the others.
    59  	ServerIdentity *ServerIdentity
    60  	// What kind of msg do we have
    61  	MsgType MessageTypeID
    62  	// A *pointer* to the underlying message
    63  	Msg Message
    64  	// The length of the message in bytes
    65  	Size Size
    66  	// which constructors are used
    67  	Constructors protobuf.Constructors
    68  }
    69  
    70  // ServerIdentity is used to represent a Server in the whole internet.
    71  // It's based on a public key, and there can be one or more addresses to contact it.
    72  type ServerIdentity struct {
    73  	// This is the public key of that ServerIdentity
    74  	Public kyber.Point
    75  	// This is the configuration for the services
    76  	ServiceIdentities []ServiceIdentity
    77  	// The ServerIdentityID corresponding to that public key
    78  	ID ServerIdentityID
    79  	// The address where that Id might be found
    80  	Address Address
    81  	// Description of the server
    82  	Description string
    83  	// This is the private key, may be nil. It is not exported so that it will never
    84  	// be marshalled.
    85  	private kyber.Scalar
    86  	// The URL where the WebSocket interface can be found. (If not set, then default is http, on port+1.)
    87  	// optional
    88  	URL string `protobuf:"opt"`
    89  }
    90  
    91  // ServerIdentityID uniquely identifies an ServerIdentity struct
    92  type ServerIdentityID uuid.UUID
    93  
    94  // ServiceIdentity contains the identity of a service which is its public and
    95  // private keys
    96  type ServiceIdentity struct {
    97  	Name    string
    98  	Suite   string
    99  	Public  kyber.Point
   100  	private kyber.Scalar
   101  }
   102  
   103  // GetPrivate returns the private key of the service identity if available
   104  func (sid *ServiceIdentity) GetPrivate() kyber.Scalar {
   105  	return sid.private
   106  }
   107  
   108  // NewServiceIdentity creates a new identity
   109  func NewServiceIdentity(name string, suite suites.Suite, public kyber.Point, private kyber.Scalar) ServiceIdentity {
   110  	return ServiceIdentity{
   111  		Name:    name,
   112  		Suite:   suite.String(),
   113  		Public:  public,
   114  		private: private,
   115  	}
   116  }
   117  
   118  // NewServiceIdentityFromPair creates a new identity using the provided key pair
   119  func NewServiceIdentityFromPair(name string, suite suites.Suite, kp *key.Pair) ServiceIdentity {
   120  	return NewServiceIdentity(name, suite, kp.Public, kp.Private)
   121  }
   122  
   123  // ServiceIdentities provides definitions to sort the array by service name
   124  type ServiceIdentities []ServiceIdentity
   125  
   126  func (srvids ServiceIdentities) Len() int {
   127  	return len(srvids)
   128  }
   129  
   130  func (srvids ServiceIdentities) Swap(i, j int) {
   131  	srvids[i], srvids[j] = srvids[j], srvids[i]
   132  }
   133  
   134  func (srvids ServiceIdentities) Less(i, j int) bool {
   135  	return strings.Compare(srvids[i].Name, srvids[j].Name) == -1
   136  }
   137  
   138  // String returns a canonical representation of the ServerIdentityID.
   139  func (eId ServerIdentityID) String() string {
   140  	return uuid.UUID(eId).String()
   141  }
   142  
   143  // Equal returns true if both ServerIdentityID are equal or false otherwise.
   144  func (eId ServerIdentityID) Equal(other ServerIdentityID) bool {
   145  	return uuid.Equal(uuid.UUID(eId), uuid.UUID(other))
   146  }
   147  
   148  // IsNil returns true iff the ServerIdentityID is Nil
   149  func (eId ServerIdentityID) IsNil() bool {
   150  	return eId.Equal(ServerIdentityID(uuid.Nil))
   151  }
   152  
   153  func (si *ServerIdentity) String() string {
   154  	return si.Address.String()
   155  }
   156  
   157  // ServerIdentityType can be used to recognise an ServerIdentity-message
   158  var ServerIdentityType = RegisterMessage(ServerIdentity{})
   159  
   160  // ServerIdentityToml is the struct that can be marshalled into a toml file
   161  type ServerIdentityToml struct {
   162  	Public  string
   163  	Address Address
   164  }
   165  
   166  // NewServerIdentity creates a new ServerIdentity based on a public key and with a slice
   167  // of IP-addresses where to find that entity. The Id is based on a
   168  // version5-UUID which can include a URL that is based on it's public key.
   169  func NewServerIdentity(public kyber.Point, address Address) *ServerIdentity {
   170  	si := &ServerIdentity{
   171  		Public:  public,
   172  		Address: address,
   173  	}
   174  	if public != nil {
   175  		url := NamespaceURL + "id/" + public.String()
   176  		si.ID = ServerIdentityID(uuid.NewV5(uuid.NamespaceURL, url))
   177  	}
   178  	return si
   179  }
   180  
   181  // Equal tests on same public key
   182  func (si *ServerIdentity) Equal(e2 *ServerIdentity) bool {
   183  	if si == nil || e2 == nil || si.Public == nil {
   184  		return false
   185  	}
   186  	return si.Public.Equal(e2.Public)
   187  }
   188  
   189  // SetPrivate sets a private key associated with this ServerIdentity.
   190  // It will not be marshalled or output as Toml.
   191  //
   192  // Before calling NewTCPRouter for a TLS server, you must set the private
   193  // key with SetPrivate.
   194  func (si *ServerIdentity) SetPrivate(p kyber.Scalar) {
   195  	si.private = p
   196  }
   197  
   198  // GetPrivate returns the private key set with SetPrivate.
   199  func (si *ServerIdentity) GetPrivate() kyber.Scalar {
   200  	return si.private
   201  }
   202  
   203  // ServicePublic returns the public key of the service or the default
   204  // one if the service has not been registered with a suite
   205  func (si *ServerIdentity) ServicePublic(name string) kyber.Point {
   206  	for _, srvid := range si.ServiceIdentities {
   207  		if srvid.Name == name {
   208  			return srvid.Public
   209  		}
   210  	}
   211  
   212  	return si.Public
   213  }
   214  
   215  // ServicePrivate returns the private key of the service or the default
   216  // one if the service has not been registered with a suite
   217  func (si *ServerIdentity) ServicePrivate(name string) kyber.Scalar {
   218  	for _, srvid := range si.ServiceIdentities {
   219  		if srvid.Name == name {
   220  			return srvid.private
   221  		}
   222  	}
   223  
   224  	return si.private
   225  }
   226  
   227  // HasServiceKeyPair returns true if the public and private keys are
   228  // generated for the given service. The default key pair is ignored.
   229  func (si *ServerIdentity) HasServiceKeyPair(name string) bool {
   230  	for _, srvid := range si.ServiceIdentities {
   231  		if srvid.Name == name && srvid.Public != nil && srvid.private != nil {
   232  			return true
   233  		}
   234  	}
   235  
   236  	return false
   237  }
   238  
   239  // HasServicePublic returns true if the public key is
   240  // generated for the given service. The default public key is ignored.
   241  func (si *ServerIdentity) HasServicePublic(name string) bool {
   242  	for _, srvid := range si.ServiceIdentities {
   243  		if srvid.Name == name && srvid.Public != nil {
   244  			return true
   245  		}
   246  	}
   247  	return false
   248  }
   249  
   250  // Toml converts an ServerIdentity to a Toml-structure
   251  func (si *ServerIdentity) Toml(suite Suite) *ServerIdentityToml {
   252  	var buf bytes.Buffer
   253  	if err := encoding.WriteHexPoint(suite, &buf, si.Public); err != nil {
   254  		log.Error("Error while writing public key:", err)
   255  	}
   256  	return &ServerIdentityToml{
   257  		Address: si.Address,
   258  		Public:  buf.String(),
   259  	}
   260  }
   261  
   262  // ServerIdentity converts an ServerIdentityToml structure back to an ServerIdentity
   263  func (si *ServerIdentityToml) ServerIdentity(suite Suite) *ServerIdentity {
   264  	pub, err := encoding.ReadHexPoint(suite, strings.NewReader(si.Public))
   265  	if err != nil {
   266  		log.Error("Error while reading public key:", err)
   267  	}
   268  	return &ServerIdentity{
   269  		Public:  pub,
   270  		Address: si.Address,
   271  	}
   272  }
   273  
   274  // GlobalBind returns the global-binding address. Given any IP:PORT combination,
   275  // it will return ":PORT".
   276  func GlobalBind(address string) (string, error) {
   277  	_, port, err := net.SplitHostPort(address)
   278  	if err != nil {
   279  		return "", xerrors.Errorf("invalid address: %v", err)
   280  	}
   281  	return ":" + port, nil
   282  }
   283  
   284  // counterSafe is a struct that enables to update two counters Rx & Tx
   285  // atomically that can be have increasing values.
   286  // It's main use is for Conn to update how many bytes they've
   287  // written / read. This struct implements the monitor.CounterIO interface.
   288  type counterSafe struct {
   289  	tx uint64
   290  	rx uint64
   291  	sync.Mutex
   292  }
   293  
   294  // Rx returns the rx counter
   295  func (c *counterSafe) Rx() (out uint64) {
   296  	c.Lock()
   297  	out = c.rx
   298  	c.Unlock()
   299  	return
   300  }
   301  
   302  // Tx returns the tx counter
   303  func (c *counterSafe) Tx() (out uint64) {
   304  	c.Lock()
   305  	out = c.tx
   306  	c.Unlock()
   307  	return
   308  }
   309  
   310  // updateRx adds delta to the rx counter
   311  func (c *counterSafe) updateRx(delta uint64) {
   312  	c.Lock()
   313  	c.rx += delta
   314  	c.Unlock()
   315  }
   316  
   317  // updateTx adds delta to the tx counter
   318  func (c *counterSafe) updateTx(delta uint64) {
   319  	c.Lock()
   320  	c.tx += delta
   321  	c.Unlock()
   322  }