123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- // Copyright © 2021 Ettore Di Giacinto <[email protected]>
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation; either version 2 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License along
- // with this program; if not, see <http://www.gnu.org/licenses/>.
- package node
- import (
- "encoding/base64"
- "io/ioutil"
- "time"
- "github.com/ipfs/go-log"
- "github.com/libp2p/go-libp2p"
- dht "github.com/libp2p/go-libp2p-kad-dht"
- "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"
- "github.com/xlzd/gotp"
- "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
- }
- }
- // 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
- }
- }
- 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
- }
- }
- 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, opts ...dht.Option) {
- d := discovery.NewDHT(opts...)
- 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 := &discovery.MDNS{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 = 32
- func GenerateNewConnectionData(i ...int) *YAMLConnectionConfig {
- defaultInterval := 9000
- maxMessSize := 20 << 20 // 20MB
- if len(i) >= 2 {
- defaultInterval = i[0]
- maxMessSize = i[1]
- } else if len(i) == 1 {
- defaultInterval = i[0]
- }
- return &YAMLConnectionConfig{
- MaxMessageSize: maxMessSize,
- RoomName: gotp.RandomSecret(defaultKeyLength),
- Rendezvous: utils.RandStringRunes(defaultKeyLength),
- MDNS: utils.RandStringRunes(defaultKeyLength),
- OTP: OTP{
- DHT: OTPConfig{
- Key: gotp.RandomSecret(defaultKeyLength),
- Interval: defaultInterval,
- Length: defaultKeyLength,
- },
- Crypto: OTPConfig{
- Key: gotp.RandomSecret(defaultKeyLength),
- Interval: defaultInterval,
- Length: defaultKeyLength,
- },
- },
- }
- }
- func FromYaml(enablemDNS, enableDHT bool, path string, d ...dht.Option) 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...)
- return nil
- }
- }
- func FromBase64(enablemDNS, enableDHT bool, bb string, d ...dht.Option) 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...)
- return nil
- }
- }
|