github.com/ergo-services/ergo@v1.999.224/node/types.go (about) 1 package node 2 3 import ( 4 "context" 5 "crypto/cipher" 6 "crypto/tls" 7 "net" 8 "time" 9 10 "github.com/ergo-services/ergo/etf" 11 "github.com/ergo-services/ergo/gen" 12 "github.com/ergo-services/ergo/lib" 13 ) 14 15 const ( 16 // node options 17 defaultListenBegin uint16 = 15000 18 defaultListenEnd uint16 = 65000 19 defaultKeepAlivePeriod time.Duration = 15 20 defaultProxyPathLimit int = 32 21 22 DefaultProcessMailboxSize int = 100 23 DefaultProcessDirectboxSize int = 10 24 25 EnvKeyVersion gen.EnvKey = "ergo:Version" 26 EnvKeyNode gen.EnvKey = "ergo:Node" 27 EnvKeyRemoteSpawn gen.EnvKey = "ergo:RemoteSpawn" 28 29 DefaultProtoRecvQueueLength int = 100 30 DefaultProtoSendQueueLength int = 100 31 DefaultProtoFragmentationUnit int = 65000 32 33 DefaultCompressionLevel int = -1 34 DefaultCompressionThreshold int = 1024 35 36 DefaultProxyMaxHop int = 8 37 38 EventNetwork gen.Event = "network" 39 ) 40 41 type Node interface { 42 gen.Core 43 // Name returns node name 44 Name() string 45 // IsAlive returns true if node is still alive 46 IsAlive() bool 47 // Uptime returns node uptime in seconds 48 Uptime() int64 49 // Version return node version 50 Version() Version 51 // ListEnv returns a map of configured Node environment variables. 52 ListEnv() map[gen.EnvKey]interface{} 53 // SetEnv set node environment variable with given name. Use nil value to remove variable with given name. Ignores names with "ergo:" as a prefix. 54 SetEnv(name gen.EnvKey, value interface{}) 55 // Env returns value associated with given environment name. 56 Env(name gen.EnvKey) interface{} 57 58 // Spawn spawns a new process 59 Spawn(name string, opts gen.ProcessOptions, object gen.ProcessBehavior, args ...etf.Term) (gen.Process, error) 60 61 // RegisterName 62 RegisterName(name string, pid etf.Pid) error 63 // UnregisterName 64 UnregisterName(name string) error 65 66 LoadedApplications() []gen.ApplicationInfo 67 WhichApplications() []gen.ApplicationInfo 68 ApplicationInfo(name string) (gen.ApplicationInfo, error) 69 ApplicationLoad(app gen.ApplicationBehavior, args ...etf.Term) (string, error) 70 ApplicationUnload(appName string) error 71 ApplicationStart(appName string, args ...etf.Term) (gen.Process, error) 72 ApplicationStartPermanent(appName string, args ...etf.Term) (gen.Process, error) 73 ApplicationStartTransient(appName string, args ...etf.Term) (gen.Process, error) 74 ApplicationStop(appName string) error 75 76 ProvideRemoteSpawn(name string, object gen.ProcessBehavior) error 77 RevokeRemoteSpawn(name string) error 78 79 // AddStaticRoute adds static route for the given name 80 AddStaticRoute(node string, host string, port uint16, options RouteOptions) error 81 // AddStaticRoutePort adds static route for the given node name which makes node skip resolving port process 82 AddStaticRoutePort(node string, port uint16, options RouteOptions) error 83 // AddStaticRouteOptions adds static route options for the given node name which does regular port resolving but applies static options 84 AddStaticRouteOptions(node string, options RouteOptions) error 85 // Remove static route removes static route with given name 86 RemoveStaticRoute(name string) bool 87 // StaticRoutes returns list of routes added using AddStaticRoute 88 StaticRoutes() []Route 89 // StaticRoute returns Route for the given name. Returns false if it doesn't exist. 90 StaticRoute(name string) (Route, bool) 91 92 AddProxyRoute(proxy ProxyRoute) error 93 RemoveProxyRoute(name string) bool 94 // ProxyRoutes returns list of proxy routes added using AddProxyRoute 95 ProxyRoutes() []ProxyRoute 96 // ProxyRoute returns proxy route added using AddProxyRoute 97 ProxyRoute(name string) (ProxyRoute, bool) 98 99 // Resolve 100 Resolve(node string) (Route, error) 101 // ResolveProxy resolves proxy route. Checks for the proxy route added using AddProxyRoute. 102 // If it wasn't found makes request to the registrar. 103 ResolveProxy(node string) (ProxyRoute, error) 104 105 // Returns Registrar interface 106 Registrar() Registrar 107 108 // Connect sets up a connection to node 109 Connect(node string) error 110 // Disconnect close connection to the node 111 Disconnect(node string) error 112 // Nodes returns the list of connected nodes 113 Nodes() []string 114 // NodesIndirect returns the list of nodes connected via proxies 115 NodesIndirect() []string 116 // NetworkStats returns network statistics of the connection with the node. Returns error 117 // ErrUnknown if connection with given node is not established. 118 NetworkStats(name string) (NetworkStats, error) 119 120 Links(process etf.Pid) []etf.Pid 121 Monitors(process etf.Pid) []etf.Pid 122 MonitorsByName(process etf.Pid) []gen.ProcessID 123 MonitoredBy(process etf.Pid) []etf.Pid 124 125 Stats() NodeStats 126 127 Stop() 128 Wait() 129 WaitWithTimeout(d time.Duration) error 130 } 131 132 // Version 133 type Version struct { 134 Release string 135 Prefix string 136 OTP int 137 } 138 139 // CoreRouter routes messages from/to remote node 140 type CoreRouter interface { 141 142 // 143 // implemented by core 144 // 145 146 // RouteSend routes message by Pid 147 RouteSend(from etf.Pid, to etf.Pid, message etf.Term) error 148 // RouteSendReg routes message by registered process name (gen.ProcessID) 149 RouteSendReg(from etf.Pid, to gen.ProcessID, message etf.Term) error 150 // RouteSendAlias routes message by process alias 151 RouteSendAlias(from etf.Pid, to etf.Alias, message etf.Term) error 152 153 RouteSpawnRequest(node string, behaviorName string, request gen.RemoteSpawnRequest, args ...etf.Term) error 154 RouteSpawnReply(to etf.Pid, ref etf.Ref, result etf.Term) error 155 156 // 157 // implemented by monitor 158 // 159 160 // RouteLink makes linking of the given two processes 161 RouteLink(pidA etf.Pid, pidB etf.Pid) error 162 // RouteUnlink makes unlinking of the given two processes 163 RouteUnlink(pidA etf.Pid, pidB etf.Pid) error 164 // RouteExit routes MessageExit to the linked process 165 RouteExit(to etf.Pid, terminated etf.Pid, reason string) error 166 // RouteMonitorReg makes monitor to the given registered process name (gen.ProcessID) 167 RouteMonitorReg(by etf.Pid, process gen.ProcessID, ref etf.Ref) error 168 // RouteMonitor makes monitor to the given Pid 169 RouteMonitor(by etf.Pid, process etf.Pid, ref etf.Ref) error 170 RouteDemonitor(by etf.Pid, ref etf.Ref) error 171 RouteMonitorExitReg(terminated gen.ProcessID, reason string, ref etf.Ref) error 172 RouteMonitorExit(terminated etf.Pid, reason string, ref etf.Ref) error 173 // RouteNodeDown 174 RouteNodeDown(name string, disconnect *ProxyDisconnect) 175 176 // 177 // implemented by network 178 // 179 180 // RouteProxyConnectRequest 181 RouteProxyConnectRequest(from ConnectionInterface, request ProxyConnectRequest) error 182 // RouteProxyConnectReply 183 RouteProxyConnectReply(from ConnectionInterface, reply ProxyConnectReply) error 184 // RouteProxyConnectCancel 185 RouteProxyConnectCancel(from ConnectionInterface, cancel ProxyConnectCancel) error 186 // RouteProxyDisconnect 187 RouteProxyDisconnect(from ConnectionInterface, disconnect ProxyDisconnect) error 188 // RouteProxy returns ErrProxySessionEndpoint if this node is the endpoint of the 189 // proxy session. In this case, the packet must be handled on this node with 190 // provided ProxySession parameters. 191 RouteProxy(from ConnectionInterface, sessionID string, packet *lib.Buffer) error 192 } 193 194 // Options defines bootstrapping options for the node 195 type Options struct { 196 // Applications application list that must be started 197 Applications []gen.ApplicationBehavior 198 199 // Env node environment 200 Env map[gen.EnvKey]interface{} 201 202 // Creation. Default value: uint32(time.Now().Unix()) 203 Creation uint32 204 205 // Listeners node can have multiple listening interface at once. If this list is empty 206 // the default listener will be using. Only the first listener will be registered on 207 // the Registrar 208 Listeners []Listener 209 210 // Flags defines option flags of this node for the outgoing connection 211 Flags Flags 212 213 // TLS settings 214 TLS *tls.Config 215 216 // StaticRoutesOnly disables resolving service (default is EPMD client) and 217 // makes resolving localy only for nodes added using gen.AddStaticRoute 218 StaticRoutesOnly bool 219 220 // Registrar defines a registrar service (default is EPMD service, client and server) 221 Registrar Registrar 222 223 // Compression defines default compression options for the spawning processes. 224 Compression Compression 225 226 // Handshake defines a handshake handler. By default is using 227 // DIST handshake created with dist.CreateHandshake(...) 228 Handshake HandshakeInterface 229 230 // Proto defines a proto handler. By default is using 231 // DIST proto created with dist.CreateProto(...) 232 Proto ProtoInterface 233 234 // Cloud enable Ergo Cloud support 235 Cloud Cloud 236 237 // Proxy options 238 Proxy Proxy 239 240 // System options for the system application 241 System System 242 } 243 244 type Listener struct { 245 // Cookie cookie for the incoming connection to this listener. Leave it empty in 246 // case of using the node's cookie. 247 Cookie string 248 // Hostname defines an interface for the listener. Default: takes from the node name. 249 Hostname string 250 // Listen defines a listening port number for accepting incoming connections. 251 Listen uint16 252 // ListenBegin and ListenEnd define a range of the port numbers where 253 // the node looking for available free port number for the listening. 254 // Default values 15000 and 65000 accordingly 255 ListenBegin uint16 256 ListenEnd uint16 257 // Handshake if its nil the default TLS (Options.TLS) will be using 258 TLS *tls.Config 259 // Handshake if its nil the default Handshake (Options.Handshake) will be using 260 Handshake HandshakeInterface 261 // Proto if its nil the default Proto (Options.Proto) will be using 262 Proto ProtoInterface 263 // Flags defines option flags of this node for the incoming connection 264 // on this port. If its disabled the default Flags (Options.Flags) will be using 265 Flags Flags 266 } 267 268 type Cloud struct { 269 Enable bool 270 Cluster string 271 Cookie string 272 Flags CloudFlags 273 Timeout time.Duration 274 } 275 276 type Proxy struct { 277 // Transit allows to use this node as a proxy 278 Transit bool 279 // Accept incoming proxy connections 280 Accept bool 281 // Cookie sets cookie for incoming connections 282 Cookie string 283 // Flags sets options for incoming connections 284 Flags ProxyFlags 285 // Routes sets options for outgoing connections 286 Routes map[string]ProxyRoute 287 } 288 289 type System struct { 290 DisableAnonMetrics bool 291 } 292 293 type Compression struct { 294 // Enable enables compression for all outgoing messages having size 295 // greater than the defined threshold. 296 Enable bool 297 // Level defines compression level. Value must be in range 1..9 or -1 for the default level 298 Level int 299 // Threshold defines the minimal message size for the compression. 300 // Messages less of this threshold will not be compressed. 301 Threshold int 302 } 303 304 // Connection 305 type Connection struct { 306 ConnectionInterface 307 } 308 309 // ConnectionInterface 310 type ConnectionInterface interface { 311 Send(from gen.Process, to etf.Pid, message etf.Term) error 312 SendReg(from gen.Process, to gen.ProcessID, message etf.Term) error 313 SendAlias(from gen.Process, to etf.Alias, message etf.Term) error 314 315 Link(local etf.Pid, remote etf.Pid) error 316 Unlink(local etf.Pid, remote etf.Pid) error 317 LinkExit(to etf.Pid, terminated etf.Pid, reason string) error 318 319 Monitor(local etf.Pid, remote etf.Pid, ref etf.Ref) error 320 Demonitor(local etf.Pid, remote etf.Pid, ref etf.Ref) error 321 MonitorExit(to etf.Pid, terminated etf.Pid, reason string, ref etf.Ref) error 322 323 MonitorReg(local etf.Pid, remote gen.ProcessID, ref etf.Ref) error 324 DemonitorReg(local etf.Pid, remote gen.ProcessID, ref etf.Ref) error 325 MonitorExitReg(to etf.Pid, terminated gen.ProcessID, reason string, ref etf.Ref) error 326 327 SpawnRequest(nodeName string, behaviorName string, request gen.RemoteSpawnRequest, args ...etf.Term) error 328 SpawnReply(to etf.Pid, ref etf.Ref, spawned etf.Pid) error 329 SpawnReplyError(to etf.Pid, ref etf.Ref, err error) error 330 331 ProxyConnectRequest(connect ProxyConnectRequest) error 332 ProxyConnectReply(reply ProxyConnectReply) error 333 ProxyConnectCancel(cancel ProxyConnectCancel) error 334 ProxyDisconnect(disconnect ProxyDisconnect) error 335 ProxyRegisterSession(session ProxySession) error 336 ProxyUnregisterSession(id string) error 337 ProxyPacket(packet *lib.Buffer) error 338 339 Creation() uint32 340 Stats() NetworkStats 341 } 342 343 // Handshake template struct for the custom Handshake implementation 344 type Handshake struct { 345 HandshakeInterface 346 } 347 348 // Handshake defines handshake interface 349 type HandshakeInterface interface { 350 // Mandatory: 351 352 // Init initialize handshake. 353 Init(nodename string, creation uint32, flags Flags) error 354 355 // Optional: 356 357 // Start initiates handshake process. Argument tls means the connection is wrapped by TLS 358 // Returns the name of connected peer, Flags and Creation wrapped into HandshakeDetails struct 359 Start(remote net.Addr, conn lib.NetReadWriter, tls bool, cookie string) (HandshakeDetails, error) 360 // Accept accepts handshake process initiated by another side of this connection. 361 // Returns the name of connected peer, Flags and Creation wrapped into HandshakeDetails struct 362 Accept(remote net.Addr, conn lib.NetReadWriter, tls bool, cookie string) (HandshakeDetails, error) 363 // Version handshake version. Must be implemented if this handshake is going to be used 364 // for the accepting connections (this method is used in registration on the Resolver) 365 Version() HandshakeVersion 366 } 367 368 // HandshakeDetails 369 type HandshakeDetails struct { 370 // Name node name 371 Name string 372 // Flags node flags 373 Flags Flags 374 // Creation 375 Creation uint32 376 // Version 377 Version int 378 // NumHandlers defines the number of readers/writers per connection. Default value is provided by ProtoOptions 379 NumHandlers int 380 // AtomMapping 381 AtomMapping *etf.AtomMapping 382 // ProxyTransit allows to restrict proxy connection requests for this connection 383 ProxyTransit ProxyTransit 384 // Buffer keeps data received along with the handshake 385 Buffer *lib.Buffer 386 // Custom allows passing the custom data to the ProtoInterface.Start 387 Custom HandshakeCustomDetails 388 } 389 390 type HandshakeCustomDetails interface{} 391 392 type HandshakeVersion int 393 394 // Proto template struct for the custom Proto implementation 395 type Proto struct { 396 ProtoInterface 397 } 398 399 // Proto defines proto interface for the custom Proto implementation 400 type ProtoInterface interface { 401 // Init initialize connection handler 402 Init(ctx context.Context, conn lib.NetReadWriter, nodename string, details HandshakeDetails) (ConnectionInterface, error) 403 // Serve connection 404 Serve(connection ConnectionInterface, router CoreRouter) 405 // Terminate invoked once Serve callback is finished 406 Terminate(connection ConnectionInterface) 407 } 408 409 // ProtoOptions 410 type ProtoOptions struct { 411 // NumHandlers defines the number of readers/writers per connection. Default is the number of CPU 412 NumHandlers int 413 // MaxMessageSize limit the message size. Default 0 (no limit) 414 MaxMessageSize int 415 // SendQueueLength defines queue size of handler for the outgoing messages. Default 100. 416 SendQueueLength int 417 // RecvQueueLength defines queue size of handler for the incoming messages. Default 100. 418 RecvQueueLength int 419 // FragmentationUnit defines unit size for the fragmentation feature. Default 65000 420 FragmentationUnit int 421 // Custom brings a custom set of options to the ProtoInterface.Serve handler 422 Custom CustomProtoOptions 423 } 424 425 // CustomProtoOptions a custom set of proto options 426 type CustomProtoOptions interface{} 427 428 // Flags 429 type Flags struct { 430 // Enable enable flags customization 431 Enable bool 432 // EnableHeaderAtomCache enables header atom cache feature 433 EnableHeaderAtomCache bool 434 // EnableBigCreation 435 EnableBigCreation bool 436 // EnableBigPidRef accepts a larger amount of data in pids and references 437 EnableBigPidRef bool 438 // EnableFragmentation enables fragmentation feature for the sending data 439 EnableFragmentation bool 440 // EnableAlias accepts process aliases 441 EnableAlias bool 442 // EnableRemoteSpawn accepts remote spawn request 443 EnableRemoteSpawn bool 444 // Compression compression support 445 EnableCompression bool 446 // Proxy enables support for incoming proxy connection 447 EnableProxy bool 448 } 449 450 // Registrar defines registrar interface 451 type Registrar interface { 452 Register(ctx context.Context, nodename string, options RegisterOptions) error 453 RegisterProxy(nodename string, maxhop int, flags ProxyFlags) error 454 UnregisterProxy(peername string) error 455 Resolve(peername string) (Route, error) 456 ResolveProxy(peername string) (ProxyRoute, error) 457 Config() (RegistrarConfig, error) 458 ConfigItem(name string) (etf.Term, error) 459 SetConfigUpdateCallback(func(name string, value etf.Term) error) error 460 } 461 462 type RegistrarConfig struct { 463 Version int 464 Config etf.Term 465 } 466 467 // RegisterOptions defines resolving options 468 type RegisterOptions struct { 469 Port uint16 470 Creation uint32 471 NodeVersion Version 472 HandshakeVersion HandshakeVersion 473 EnableTLS bool 474 EnableProxy bool 475 EnableCompression bool 476 Proxy string 477 } 478 479 // Route 480 type Route struct { 481 Node string 482 Host string 483 Port uint16 484 Options RouteOptions 485 } 486 487 // RouteOptions 488 type RouteOptions struct { 489 Cookie string 490 TLS *tls.Config 491 IsErgo bool 492 Handshake HandshakeInterface 493 Proto ProtoInterface 494 } 495 496 // ProxyRoute 497 type ProxyRoute struct { 498 // Name can be either nodename (example@domain) or domain (@domain) 499 Name string 500 Proxy string 501 Cookie string 502 Flags ProxyFlags 503 MaxHop int // DefaultProxyMaxHop == 8 504 } 505 506 // CloudFlags 507 type CloudFlags struct { 508 Enable bool 509 EnableIntrospection bool 510 EnableMetrics bool 511 EnableRemoteSpawn bool 512 } 513 514 // ProxyFlags 515 type ProxyFlags struct { 516 Enable bool 517 EnableLink bool 518 EnableMonitor bool 519 EnableRemoteSpawn bool 520 EnableEncryption bool 521 } 522 523 // ProxyTransit 524 type ProxyTransit struct { 525 AllowTo []string 526 } 527 528 // ProxyConnectRequest 529 type ProxyConnectRequest struct { 530 ID etf.Ref 531 To string // To node 532 Digest []byte // md5(md5(md5(md5(Node)+Cookie)+To)+PublicKey) 533 PublicKey []byte 534 Flags ProxyFlags 535 Creation uint32 536 Hop int 537 Path []string 538 } 539 540 // ProxyConnectReply 541 type ProxyConnectReply struct { 542 ID etf.Ref 543 To string 544 Digest []byte // md5(md5(md5(md5(Node)+Cookie)+To)+symmetric key) 545 Cipher []byte // encrypted symmetric key using PublicKey from the ProxyConnectRequest 546 Flags ProxyFlags 547 Creation uint32 548 SessionID string // proxy session ID 549 Path []string 550 } 551 552 // ProxyConnectCancel 553 type ProxyConnectCancel struct { 554 ID etf.Ref 555 From string 556 Reason string 557 Path []string 558 } 559 560 // ProxyDisconnect 561 type ProxyDisconnect struct { 562 Node string 563 Proxy string 564 SessionID string 565 Reason string 566 } 567 568 // Proxy session 569 type ProxySession struct { 570 ID string 571 NodeFlags ProxyFlags 572 PeerFlags ProxyFlags 573 Creation uint32 574 PeerName string 575 Block cipher.Block // made from symmetric key 576 } 577 578 type NetworkStats struct { 579 NodeName string 580 BytesIn uint64 581 BytesOut uint64 582 TransitBytesIn uint64 583 TransitBytesOut uint64 584 MessagesIn uint64 585 MessagesOut uint64 586 } 587 588 type NodeStats struct { 589 TotalProcesses uint64 590 TotalReferences uint64 591 RunningProcesses uint64 592 RegisteredNames uint64 593 RegisteredAliases uint64 594 595 MonitorsByPid uint64 596 MonitorsByName uint64 597 MonitorsNodes uint64 598 Links uint64 599 600 LoadedApplications uint64 601 RunningApplications uint64 602 603 NetworkConnections uint64 604 ProxyConnections uint64 605 TransitConnections uint64 606 } 607 608 type MessageEventNetwork struct { 609 PeerName string 610 Online bool 611 Proxy bool 612 }