123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- /*
- Copyright © 2021-2022 Ettore Di Giacinto <[email protected]>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package node
- import (
- "encoding/base64"
- "io/ioutil"
- "time"
- "github.com/ipfs/go-log"
- "github.com/libp2p/go-libp2p"
- "github.com/libp2p/go-libp2p/core/peer"
- "github.com/mudler/edgevpn/pkg/blockchain"
- discovery "github.com/mudler/edgevpn/pkg/discovery"
- "github.com/mudler/edgevpn/pkg/protocol"
- "github.com/mudler/edgevpn/pkg/utils"
- "github.com/pkg/errors"
- "gopkg.in/yaml.v2"
- )
- // WithLibp2pOptions Overrides defaults options
- func WithLibp2pOptions(i ...libp2p.Option) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.Options = i
- return nil
- }
- }
- func WithSealer(i Sealer) Option {
- return func(cfg *Config) error {
- cfg.Sealer = i
- return nil
- }
- }
- func WithLibp2pAdditionalOptions(i ...libp2p.Option) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.AdditionalOptions = append(cfg.AdditionalOptions, i...)
- return nil
- }
- }
- func WithNetworkService(ns ...NetworkService) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.NetworkServices = append(cfg.NetworkServices, ns...)
- return nil
- }
- }
- func WithInterfaceAddress(i string) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.InterfaceAddress = i
- return nil
- }
- }
- func WithBlacklist(i ...string) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.Blacklist = i
- return nil
- }
- }
- func Logger(l log.StandardLogger) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.Logger = l
- return nil
- }
- }
- func WithStore(s blockchain.Store) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.Store = s
- return nil
- }
- }
- // Handlers adds a handler to the list that is called on each received message
- func Handlers(h ...Handler) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.Handlers = append(cfg.Handlers, h...)
- return nil
- }
- }
- // GenericChannelHandlers adds a handler to the list that is called on each received message in the generic channel (not the one allocated for the blockchain)
- func GenericChannelHandlers(h ...Handler) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.GenericChannelHandler = append(cfg.GenericChannelHandler, h...)
- return nil
- }
- }
- // WithStreamHandler adds a handler to the list that is called on each received message
- func WithStreamHandler(id protocol.Protocol, h StreamHandler) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.StreamHandlers[id] = h
- return nil
- }
- }
- // DiscoveryService Adds the service given as argument to the discovery services
- func DiscoveryService(s ...ServiceDiscovery) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.ServiceDiscovery = append(cfg.ServiceDiscovery, s...)
- return nil
- }
- }
- // EnableGenericHub enables an additional generic hub between peers.
- // This can be used to exchange messages between peers that are not related to any
- // blockchain event. For instance, messages could be used for authentication, or for other sort
- // of application.
- var EnableGenericHub = func(cfg *Config) error {
- cfg.GenericHub = true
- return nil
- }
- func ListenAddresses(ss ...string) func(cfg *Config) error {
- return func(cfg *Config) error {
- for _, s := range ss {
- a := &discovery.AddrList{}
- err := a.Set(s)
- if err != nil {
- return err
- }
- cfg.ListenAddresses = append(cfg.ListenAddresses, *a)
- }
- return nil
- }
- }
- func Insecure(b bool) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.Insecure = b
- return nil
- }
- }
- func ExchangeKeys(s string) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.ExchangeKey = s
- return nil
- }
- }
- func RoomName(s string) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.RoomName = s
- return nil
- }
- }
- func SealKeyInterval(i int) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.SealKeyInterval = i
- return nil
- }
- }
- func SealKeyLength(i int) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.SealKeyLength = i
- return nil
- }
- }
- func LibP2PLogLevel(l log.LogLevel) func(cfg *Config) error {
- return func(cfg *Config) error {
- log.SetAllLoggers(l)
- return nil
- }
- }
- func MaxMessageSize(i int) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.MaxMessageSize = i
- return nil
- }
- }
- func WithPeerGater(d Gater) Option {
- return func(cfg *Config) error {
- cfg.PeerGater = d
- return nil
- }
- }
- func WithLedgerAnnounceTime(t time.Duration) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.LedgerAnnounceTime = t
- return nil
- }
- }
- func WithLedgerInterval(t time.Duration) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.LedgerSyncronizationTime = t
- return nil
- }
- }
- func WithDiscoveryInterval(t time.Duration) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.DiscoveryInterval = t
- return nil
- }
- }
- func WithDiscoveryBootstrapPeers(a discovery.AddrList) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.DiscoveryBootstrapPeers = a
- return nil
- }
- }
- func WithPrivKey(b []byte) func(cfg *Config) error {
- return func(cfg *Config) error {
- cfg.PrivateKey = b
- return nil
- }
- }
- func WithStaticPeer(ip string, p peer.ID) func(cfg *Config) error {
- return func(cfg *Config) error {
- if cfg.PeerTable == nil {
- cfg.PeerTable = make(map[string]peer.ID)
- }
- cfg.PeerTable[ip] = p
- return nil
- }
- }
- type OTPConfig struct {
- Interval int `yaml:"interval"`
- Key string `yaml:"key"`
- Length int `yaml:"length"`
- }
- type OTP struct {
- DHT OTPConfig `yaml:"dht"`
- Crypto OTPConfig `yaml:"crypto"`
- }
- type YAMLConnectionConfig struct {
- OTP OTP `yaml:"otp"`
- RoomName string `yaml:"room"`
- Rendezvous string `yaml:"rendezvous"`
- MDNS string `yaml:"mdns"`
- MaxMessageSize int `yaml:"max_message_size"`
- }
- // Base64 returns the base64 string representation of the connection
- func (y YAMLConnectionConfig) Base64() string {
- bytesData, _ := yaml.Marshal(y)
- return base64.StdEncoding.EncodeToString(bytesData)
- }
- // YAML returns the connection config as yaml string
- func (y YAMLConnectionConfig) YAML() string {
- bytesData, _ := yaml.Marshal(y)
- return string(bytesData)
- }
- func (y YAMLConnectionConfig) copy(mdns, dht bool, cfg *Config, d *discovery.DHT, m *discovery.MDNS) {
- if d == nil {
- d = discovery.NewDHT()
- }
- if m == nil {
- m = &discovery.MDNS{}
- }
- d.RefreshDiscoveryTime = cfg.DiscoveryInterval
- d.OTPInterval = y.OTP.DHT.Interval
- d.OTPKey = y.OTP.DHT.Key
- d.KeyLength = y.OTP.DHT.Length
- d.RendezvousString = y.Rendezvous
- d.BootstrapPeers = cfg.DiscoveryBootstrapPeers
- m.DiscoveryServiceTag = y.MDNS
- cfg.ExchangeKey = y.OTP.Crypto.Key
- cfg.RoomName = y.RoomName
- cfg.SealKeyInterval = y.OTP.Crypto.Interval
- // cfg.ServiceDiscovery = []ServiceDiscovery{d, m}
- if mdns {
- cfg.ServiceDiscovery = append(cfg.ServiceDiscovery, m)
- }
- if dht {
- cfg.ServiceDiscovery = append(cfg.ServiceDiscovery, d)
- }
- cfg.SealKeyLength = y.OTP.Crypto.Length
- cfg.MaxMessageSize = y.MaxMessageSize
- }
- const defaultKeyLength = 43
- func GenerateNewConnectionData(i ...int) *YAMLConnectionConfig {
- defaultInterval := 9000
- maxMessSize := 20 << 20 // 20MB
- keyLength := defaultKeyLength
- if len(i) >= 3 {
- keyLength = i[2]
- defaultInterval = i[0]
- maxMessSize = i[1]
- } else if len(i) >= 2 {
- defaultInterval = i[0]
- maxMessSize = i[1]
- } else if len(i) == 1 {
- defaultInterval = i[0]
- }
- return &YAMLConnectionConfig{
- MaxMessageSize: maxMessSize,
- RoomName: utils.RandStringRunes(keyLength),
- Rendezvous: utils.RandStringRunes(keyLength),
- MDNS: utils.RandStringRunes(keyLength),
- OTP: OTP{
- DHT: OTPConfig{
- Key: utils.RandStringRunes(keyLength),
- Interval: defaultInterval,
- Length: defaultKeyLength,
- },
- Crypto: OTPConfig{
- Key: utils.RandStringRunes(keyLength),
- Interval: defaultInterval,
- Length: defaultKeyLength,
- },
- },
- }
- }
- func FromYaml(enablemDNS, enableDHT bool, path string, d *discovery.DHT, m *discovery.MDNS) func(cfg *Config) error {
- return func(cfg *Config) error {
- if len(path) == 0 {
- return nil
- }
- t := YAMLConnectionConfig{}
- data, err := ioutil.ReadFile(path)
- if err != nil {
- return errors.Wrap(err, "reading yaml file")
- }
- if err := yaml.Unmarshal(data, &t); err != nil {
- return errors.Wrap(err, "parsing yaml")
- }
- t.copy(enablemDNS, enableDHT, cfg, d, m)
- return nil
- }
- }
- func FromBase64(enablemDNS, enableDHT bool, bb string, d *discovery.DHT, m *discovery.MDNS) func(cfg *Config) error {
- return func(cfg *Config) error {
- if len(bb) == 0 {
- return nil
- }
- configDec, err := base64.StdEncoding.DecodeString(bb)
- if err != nil {
- return err
- }
- t := YAMLConnectionConfig{}
- if err := yaml.Unmarshal(configDec, &t); err != nil {
- return errors.Wrap(err, "parsing yaml")
- }
- t.copy(enablemDNS, enableDHT, cfg, d, m)
- return nil
- }
- }
|