Commit d55d441e authored by Kirill Smelkov's avatar Kirill Smelkov

go/neo/neonet += Join

The utility to create Networker suitable for interoperating with nodes
in a NEO cluster, be it TCP, TLS/TCP, TLS/lonet, etc. See added comments
for details.
parent 377f230a
...@@ -59,6 +59,14 @@ ...@@ -59,6 +59,14 @@
// connection. A response can be sent back via Request.Reply. Then once // connection. A response can be sent back via Request.Reply. Then once
// Request.Close is called the connection object that was accepted is // Request.Close is called the connection object that was accepted is
// immediately put back into pool for later reuse. // immediately put back into pool for later reuse.
//
//
// Joining network
//
// Besides plain TCP, NEO clusters are frequently configured to use TLS in
// peer-to-peer mode and/or network virtualisation. A networker suitable for
// interoperating with nodes in such a cluster can be created via Join. See
// Join and Config for details.
package neonet package neonet
// XXX neonet compatibility with NEO/py depends on the following small NEO/py patch: // XXX neonet compatibility with NEO/py depends on the following small NEO/py patch:
......
// Copyright (C) 2018-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Free Software licenses or any of the Open Source
// Initiative approved licenses and Convey the resulting work. Corresponding
// source of such a combination shall include the source code for all other
// software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
package neonet
// joining raw underlying network.
import (
"context"
"fmt"
"strings"
"lab.nexedi.com/kirr/go123/xerr"
"lab.nexedi.com/kirr/go123/xnet"
"lab.nexedi.com/kirr/go123/xnet/lonet"
"lab.nexedi.com/kirr/go123/xstrings"
"lab.nexedi.com/kirr/neo/go/neo/internal/xtls"
)
// Config specifies network configuration for Join.
//
// Empty config means to use plain TCP networking for inter-node exchange.
type Config struct {
// CA/Cert/Key, if non-empty, tells to use TLS in peer-to-peer mode
// with CA certificate and public/private node keys taken from specified files.
CA, Cert, Key string
// LoNode, if non-empty, tells to use lonet as underlying network.
// Network and hostname should be specified as "<net>/<host>".
LoNode string
}
// Join returns network access-point suitable for interoperating with nodes in
// a NEO cluster according to config.
func Join(ctx context.Context, cfg Config) (net xnet.Networker, err error) {
optv := []string{}
ssl := (cfg.CA != "" || cfg.Cert != "" || cfg.Key != "")
if ssl {
optv = append(optv, "ssl")
}
if cfg.LoNode != "" {
optv = append(optv, fmt.Sprintf("lonode=%q", cfg.LoNode))
}
defer xerr.Contextf(&err, "neonet join [%s]", strings.Join(optv, " "))
if ssl && !(cfg.CA != "" && cfg.Cert != "" && cfg.Key != "") {
return nil, fmt.Errorf("incomplete ca/cert/key provided")
}
defer func() {
if err != nil && net != nil {
net.Close() // ignore err
}
}()
if cfg.LoNode == "" {
net = xnet.NetPlain("tcp") // TODO not only "tcp" ?
} else {
netname, hostname, err := xstrings.HeadTail(cfg.LoNode, "/")
if err != nil {
return nil, fmt.Errorf("invalid lonode")
}
network, err := lonet.Join(ctx, netname)
if err != nil {
return nil, err
}
host, err := network.NewHost(ctx, hostname)
if err != nil {
network.Close() // ignore err
return nil, err
}
network.AutoClose() // host.Close will close network
net = host
}
if ssl {
tlsCfg, err := xtls.ConfigForP2P(cfg.CA, cfg.Cert, cfg.Key)
if err != nil {
return nil, err
}
net = xnet.NetTLS(net, tlsCfg)
}
return net, nil
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment