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 }