Commit 76783b20 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 60a44061
......@@ -679,7 +679,7 @@ func openClientByURL(ctx context.Context, u *url.URL, opt *zodb.DriverOptions) (
net := xnet.NetPlain("tcp") // TODO not only "tcp" ?
if ssl {
tlsCfg, err := tlsForSSL(ca, cert, key)
tlsCfg, err := tlsForP2P(ca, cert, key)
if err != nil {
return nil, zodb.InvalidTid, err
}
......
// Copyright (C) 2017-2018 Nexedi SA and Contributors.
// Copyright (C) 2017-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
......@@ -29,7 +29,6 @@ import (
"os"
"lab.nexedi.com/kirr/go123/prog"
"lab.nexedi.com/kirr/go123/xnet"
"lab.nexedi.com/kirr/neo/go/neo"
)
......@@ -48,6 +47,7 @@ Run NEO master node.
func masterMain(argv []string) {
flags := flag.NewFlagSet("", flag.ExitOnError)
flags.Usage = func() { masterUsage(os.Stderr); flags.PrintDefaults() } // XXX prettify
netSetup := netFlags(flags)
cluster := flags.String("cluster", "", "cluster name")
// XXX masters here too?
bind := flags.String("bind", "", "address to serve on")
......@@ -63,11 +63,14 @@ func masterMain(argv []string) {
prog.Exit(2)
}
net := xnet.NetPlain("tcp") // TODO + TLS; not only "tcp" ?
net, err := netSetup()
if err != nil {
prog.Fatal(err)
}
ctx := context.Background()
err := listenAndServe(ctx, net, *bind, func(ctx context.Context, l stdnet.Listener) error {
err = listenAndServe(ctx, net, *bind, func(ctx context.Context, l stdnet.Listener) error {
master := neo.NewMaster(*cluster, net)
return master.Run(ctx, l)
})
......
......@@ -21,8 +21,9 @@ package main
// routines common to several subcommands
import (
"bytes"
"context"
"encoding/binary"
"flag"
stdnet "net"
"net/http"
"io"
......@@ -30,6 +31,7 @@ import (
"github.com/soheilhy/cmux"
"lab.nexedi.com/kirr/go123/xerr"
"lab.nexedi.com/kirr/go123/xnet"
"lab.nexedi.com/kirr/go123/xsync"
"lab.nexedi.com/kirr/neo/go/internal/log"
......@@ -39,6 +41,38 @@ import (
_ "net/http/pprof"
)
// netFlags installs common network fags and returns function to setup network
// and create selected networker.
func netFlags(flags *flag.FlagSet) /*netSetup*/ func() (xnet.Networker, error) {
// XXX also support $NEO_<K> envvars?
fca := flags.String("ca", "", "path to CA certificate")
fcert := flags.String("cert", "", "path to node certificate")
fkey := flags.String("key", "", "path to node private key")
return func() (_ xnet.Networker, err error) {
defer xerr.Contextf(&err, "network setup")
ca := *fca
cert := *fcert
key := *fkey
ssl := (ca != "" || cert != "" || key != "")
if !ssl && !(ca != "" && cert != "" && key != "") {
return nil, fmt.Errorf("incomplete ca/cert/key provided")
}
net := xnet.NetPlain("tcp") // TODO not only "tcp" ?
if ssl {
tlsCfg, err := tlsForP2P(ca, cert, key)
if err != nil {
return nil, err
}
net = xnet.NetTLS(net, tlsCfg)
}
return net, nil
}
}
// neoMatch tells whether incoming stream starts like a NEO protocol handshake word.
func neoMatch(r io.Reader) bool {
var b [4]byte
......@@ -47,8 +81,18 @@ func neoMatch(r io.Reader) bool {
return false
}
version := binary.BigEndian.Uint32(b[:])
return (version < 0xff) // so it looks like 00 00 00 v
switch {
// 00 00 00 v - original handshake for NEO <= 1.12
case bytes.Equal(b[:3], []byte{0,0,0}):
return true
// NEO handshake after switch to MsgPack (= msgpack encoding for [2](b"NEO", version) )
case bytes.Equal(b[:], []byte{0x92, 'N','E','O'}):
return true
default:
return false
}
}
// listenAndServe runs service on laddr.
......@@ -115,7 +159,6 @@ func listenAndServe(ctx context.Context, net xnet.Networker, laddr string, serve
})
err = wg.Wait()
return err
}
// Copyright (C) 2016-2018 Nexedi SA and Contributors.
// Copyright (C) 2016-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
......@@ -31,7 +31,6 @@ import (
"strings"
"lab.nexedi.com/kirr/go123/prog"
"lab.nexedi.com/kirr/go123/xnet"
"lab.nexedi.com/kirr/neo/go/neo"
"lab.nexedi.com/kirr/neo/go/neo/storage"
......@@ -65,6 +64,7 @@ XXX currently storage is read-only.
func storageMain(argv []string) {
flags := flag.NewFlagSet("", flag.ExitOnError)
flags.Usage = func() { storageUsage(os.Stderr); flags.PrintDefaults() } // XXX prettify
netSetup := netFlags(flags)
cluster := flags.String("cluster", "", "the cluster name")
masters := flags.String("masters", "", "list of masters")
bind := flags.String("bind", "", "address to serve on")
......@@ -105,7 +105,10 @@ func storageMain(argv []string) {
prog.Fatal(err)
}
net := xnet.NetPlain("tcp") // TODO + TLS; not only "tcp" ?
net, err := netSetup()
if err != nil {
prog.Fatal(err)
}
err = listenAndServe(ctx, net, *bind, func(ctx context.Context, l stdnet.Listener) error {
stor := neo.NewStorage(*cluster, master, net, back)
......
......@@ -73,9 +73,21 @@ func before2At(before zodb.Tid) (at zodb.Tid) {
}
// tlsForSSL builds tls.Config from ca/cert/key files that should be interoperable with NEO/py.
// tlsForP2P builds tls.Config for peer-to-peer internetworking.
//
// see https://lab.nexedi.com/nexedi/neoppod/blob/v1.12-61-gc1c26894/neo/lib/app.py#L74-90
// When two peers connect, they authenticate each other by verifying that
// peer's certificate is signed by CA, which should be common to all peers.
//
// Arguments provide paths to files:
//
// - ca - path to CA certificate
// - cert - path to node certificate
// - key - path to node private key
//
// Returned TLS config is interoperable with NEO/py - see:
// https://lab.nexedi.com/nexedi/neoppod/blob/v1.12-61-gc1c26894/neo/lib/app.py#L74-90
//
// XXX -> xtls.ConfigForP2P
func tlsForSSL(ca, cert, key string) (_ *tls.Config, err error) {
defer xerr.Contextf(&err, "tls setup")
......@@ -100,7 +112,7 @@ func tlsForSSL(ca, cert, key string) (_ *tls.Config, err error) {
Certificates: []tls.Certificate{crt}, // (cert, key) as loaded
RootCAs: CA, // (ca,) as loaded
// a server also verifies cient (but also see verifyPeerCert below)
// a server also verifies client (but also see verifyPeerCert below)
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: CA,
......
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