options.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /*
  2. Copyright © 2021-2022 Ettore Di Giacinto <[email protected]>
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package node
  14. import (
  15. "encoding/base64"
  16. "io/ioutil"
  17. "time"
  18. "github.com/ipfs/go-log"
  19. "github.com/libp2p/go-libp2p"
  20. "github.com/libp2p/go-libp2p/core/peer"
  21. "github.com/mudler/edgevpn/pkg/blockchain"
  22. discovery "github.com/mudler/edgevpn/pkg/discovery"
  23. "github.com/mudler/edgevpn/pkg/protocol"
  24. "github.com/mudler/edgevpn/pkg/utils"
  25. "github.com/pkg/errors"
  26. "gopkg.in/yaml.v2"
  27. )
  28. // WithLibp2pOptions Overrides defaults options
  29. func WithLibp2pOptions(i ...libp2p.Option) func(cfg *Config) error {
  30. return func(cfg *Config) error {
  31. cfg.Options = i
  32. return nil
  33. }
  34. }
  35. func WithSealer(i Sealer) Option {
  36. return func(cfg *Config) error {
  37. cfg.Sealer = i
  38. return nil
  39. }
  40. }
  41. func WithLibp2pAdditionalOptions(i ...libp2p.Option) func(cfg *Config) error {
  42. return func(cfg *Config) error {
  43. cfg.AdditionalOptions = append(cfg.AdditionalOptions, i...)
  44. return nil
  45. }
  46. }
  47. func WithNetworkService(ns ...NetworkService) func(cfg *Config) error {
  48. return func(cfg *Config) error {
  49. cfg.NetworkServices = append(cfg.NetworkServices, ns...)
  50. return nil
  51. }
  52. }
  53. func WithInterfaceAddress(i string) func(cfg *Config) error {
  54. return func(cfg *Config) error {
  55. cfg.InterfaceAddress = i
  56. return nil
  57. }
  58. }
  59. func WithBlacklist(i ...string) func(cfg *Config) error {
  60. return func(cfg *Config) error {
  61. cfg.Blacklist = i
  62. return nil
  63. }
  64. }
  65. func Logger(l log.StandardLogger) func(cfg *Config) error {
  66. return func(cfg *Config) error {
  67. cfg.Logger = l
  68. return nil
  69. }
  70. }
  71. func WithStore(s blockchain.Store) func(cfg *Config) error {
  72. return func(cfg *Config) error {
  73. cfg.Store = s
  74. return nil
  75. }
  76. }
  77. // Handlers adds a handler to the list that is called on each received message
  78. func Handlers(h ...Handler) func(cfg *Config) error {
  79. return func(cfg *Config) error {
  80. cfg.Handlers = append(cfg.Handlers, h...)
  81. return nil
  82. }
  83. }
  84. // 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)
  85. func GenericChannelHandlers(h ...Handler) func(cfg *Config) error {
  86. return func(cfg *Config) error {
  87. cfg.GenericChannelHandler = append(cfg.GenericChannelHandler, h...)
  88. return nil
  89. }
  90. }
  91. // WithStreamHandler adds a handler to the list that is called on each received message
  92. func WithStreamHandler(id protocol.Protocol, h StreamHandler) func(cfg *Config) error {
  93. return func(cfg *Config) error {
  94. cfg.StreamHandlers[id] = h
  95. return nil
  96. }
  97. }
  98. // DiscoveryService Adds the service given as argument to the discovery services
  99. func DiscoveryService(s ...ServiceDiscovery) func(cfg *Config) error {
  100. return func(cfg *Config) error {
  101. cfg.ServiceDiscovery = append(cfg.ServiceDiscovery, s...)
  102. return nil
  103. }
  104. }
  105. // EnableGenericHub enables an additional generic hub between peers.
  106. // This can be used to exchange messages between peers that are not related to any
  107. // blockchain event. For instance, messages could be used for authentication, or for other sort
  108. // of application.
  109. var EnableGenericHub = func(cfg *Config) error {
  110. cfg.GenericHub = true
  111. return nil
  112. }
  113. func ListenAddresses(ss ...string) func(cfg *Config) error {
  114. return func(cfg *Config) error {
  115. for _, s := range ss {
  116. a := &discovery.AddrList{}
  117. err := a.Set(s)
  118. if err != nil {
  119. return err
  120. }
  121. cfg.ListenAddresses = append(cfg.ListenAddresses, *a)
  122. }
  123. return nil
  124. }
  125. }
  126. func Insecure(b bool) func(cfg *Config) error {
  127. return func(cfg *Config) error {
  128. cfg.Insecure = b
  129. return nil
  130. }
  131. }
  132. func ExchangeKeys(s string) func(cfg *Config) error {
  133. return func(cfg *Config) error {
  134. cfg.ExchangeKey = s
  135. return nil
  136. }
  137. }
  138. func RoomName(s string) func(cfg *Config) error {
  139. return func(cfg *Config) error {
  140. cfg.RoomName = s
  141. return nil
  142. }
  143. }
  144. func SealKeyInterval(i int) func(cfg *Config) error {
  145. return func(cfg *Config) error {
  146. cfg.SealKeyInterval = i
  147. return nil
  148. }
  149. }
  150. func SealKeyLength(i int) func(cfg *Config) error {
  151. return func(cfg *Config) error {
  152. cfg.SealKeyLength = i
  153. return nil
  154. }
  155. }
  156. func LibP2PLogLevel(l log.LogLevel) func(cfg *Config) error {
  157. return func(cfg *Config) error {
  158. log.SetAllLoggers(l)
  159. return nil
  160. }
  161. }
  162. func MaxMessageSize(i int) func(cfg *Config) error {
  163. return func(cfg *Config) error {
  164. cfg.MaxMessageSize = i
  165. return nil
  166. }
  167. }
  168. func WithPeerGater(d Gater) Option {
  169. return func(cfg *Config) error {
  170. cfg.PeerGater = d
  171. return nil
  172. }
  173. }
  174. func WithLedgerAnnounceTime(t time.Duration) func(cfg *Config) error {
  175. return func(cfg *Config) error {
  176. cfg.LedgerAnnounceTime = t
  177. return nil
  178. }
  179. }
  180. func WithLedgerInterval(t time.Duration) func(cfg *Config) error {
  181. return func(cfg *Config) error {
  182. cfg.LedgerSyncronizationTime = t
  183. return nil
  184. }
  185. }
  186. func WithDiscoveryInterval(t time.Duration) func(cfg *Config) error {
  187. return func(cfg *Config) error {
  188. cfg.DiscoveryInterval = t
  189. return nil
  190. }
  191. }
  192. func WithDiscoveryBootstrapPeers(a discovery.AddrList) func(cfg *Config) error {
  193. return func(cfg *Config) error {
  194. cfg.DiscoveryBootstrapPeers = a
  195. return nil
  196. }
  197. }
  198. func WithPrivKey(b []byte) func(cfg *Config) error {
  199. return func(cfg *Config) error {
  200. cfg.PrivateKey = b
  201. return nil
  202. }
  203. }
  204. func WithStaticPeer(ip string, p peer.ID) func(cfg *Config) error {
  205. return func(cfg *Config) error {
  206. if cfg.PeerTable == nil {
  207. cfg.PeerTable = make(map[string]peer.ID)
  208. }
  209. cfg.PeerTable[ip] = p
  210. return nil
  211. }
  212. }
  213. type OTPConfig struct {
  214. Interval int `yaml:"interval"`
  215. Key string `yaml:"key"`
  216. Length int `yaml:"length"`
  217. }
  218. type OTP struct {
  219. DHT OTPConfig `yaml:"dht"`
  220. Crypto OTPConfig `yaml:"crypto"`
  221. }
  222. type YAMLConnectionConfig struct {
  223. OTP OTP `yaml:"otp"`
  224. RoomName string `yaml:"room"`
  225. Rendezvous string `yaml:"rendezvous"`
  226. MDNS string `yaml:"mdns"`
  227. MaxMessageSize int `yaml:"max_message_size"`
  228. }
  229. // Base64 returns the base64 string representation of the connection
  230. func (y YAMLConnectionConfig) Base64() string {
  231. bytesData, _ := yaml.Marshal(y)
  232. return base64.StdEncoding.EncodeToString(bytesData)
  233. }
  234. // YAML returns the connection config as yaml string
  235. func (y YAMLConnectionConfig) YAML() string {
  236. bytesData, _ := yaml.Marshal(y)
  237. return string(bytesData)
  238. }
  239. func (y YAMLConnectionConfig) copy(mdns, dht bool, cfg *Config, d *discovery.DHT, m *discovery.MDNS) {
  240. if d == nil {
  241. d = discovery.NewDHT()
  242. }
  243. if m == nil {
  244. m = &discovery.MDNS{}
  245. }
  246. d.RefreshDiscoveryTime = cfg.DiscoveryInterval
  247. d.OTPInterval = y.OTP.DHT.Interval
  248. d.OTPKey = y.OTP.DHT.Key
  249. d.KeyLength = y.OTP.DHT.Length
  250. d.RendezvousString = y.Rendezvous
  251. d.BootstrapPeers = cfg.DiscoveryBootstrapPeers
  252. m.DiscoveryServiceTag = y.MDNS
  253. cfg.ExchangeKey = y.OTP.Crypto.Key
  254. cfg.RoomName = y.RoomName
  255. cfg.SealKeyInterval = y.OTP.Crypto.Interval
  256. // cfg.ServiceDiscovery = []ServiceDiscovery{d, m}
  257. if mdns {
  258. cfg.ServiceDiscovery = append(cfg.ServiceDiscovery, m)
  259. }
  260. if dht {
  261. cfg.ServiceDiscovery = append(cfg.ServiceDiscovery, d)
  262. }
  263. cfg.SealKeyLength = y.OTP.Crypto.Length
  264. cfg.MaxMessageSize = y.MaxMessageSize
  265. }
  266. const defaultKeyLength = 43
  267. func GenerateNewConnectionData(i ...int) *YAMLConnectionConfig {
  268. defaultInterval := 9000
  269. maxMessSize := 20 << 20 // 20MB
  270. keyLength := defaultKeyLength
  271. if len(i) >= 3 {
  272. keyLength = i[2]
  273. defaultInterval = i[0]
  274. maxMessSize = i[1]
  275. } else if len(i) >= 2 {
  276. defaultInterval = i[0]
  277. maxMessSize = i[1]
  278. } else if len(i) == 1 {
  279. defaultInterval = i[0]
  280. }
  281. return &YAMLConnectionConfig{
  282. MaxMessageSize: maxMessSize,
  283. RoomName: utils.RandStringRunes(keyLength),
  284. Rendezvous: utils.RandStringRunes(keyLength),
  285. MDNS: utils.RandStringRunes(keyLength),
  286. OTP: OTP{
  287. DHT: OTPConfig{
  288. Key: utils.RandStringRunes(keyLength),
  289. Interval: defaultInterval,
  290. Length: defaultKeyLength,
  291. },
  292. Crypto: OTPConfig{
  293. Key: utils.RandStringRunes(keyLength),
  294. Interval: defaultInterval,
  295. Length: defaultKeyLength,
  296. },
  297. },
  298. }
  299. }
  300. func FromYaml(enablemDNS, enableDHT bool, path string, d *discovery.DHT, m *discovery.MDNS) func(cfg *Config) error {
  301. return func(cfg *Config) error {
  302. if len(path) == 0 {
  303. return nil
  304. }
  305. t := YAMLConnectionConfig{}
  306. data, err := ioutil.ReadFile(path)
  307. if err != nil {
  308. return errors.Wrap(err, "reading yaml file")
  309. }
  310. if err := yaml.Unmarshal(data, &t); err != nil {
  311. return errors.Wrap(err, "parsing yaml")
  312. }
  313. t.copy(enablemDNS, enableDHT, cfg, d, m)
  314. return nil
  315. }
  316. }
  317. func FromBase64(enablemDNS, enableDHT bool, bb string, d *discovery.DHT, m *discovery.MDNS) func(cfg *Config) error {
  318. return func(cfg *Config) error {
  319. if len(bb) == 0 {
  320. return nil
  321. }
  322. configDec, err := base64.StdEncoding.DecodeString(bb)
  323. if err != nil {
  324. return err
  325. }
  326. t := YAMLConnectionConfig{}
  327. if err := yaml.Unmarshal(configDec, &t); err != nil {
  328. return errors.Wrap(err, "parsing yaml")
  329. }
  330. t.copy(enablemDNS, enableDHT, cfg, d, m)
  331. return nil
  332. }
  333. }