options.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. // Copyright © 2021 Ettore Di Giacinto <[email protected]>
  2. //
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License along
  14. // with this program; if not, see <http://www.gnu.org/licenses/>.
  15. package node
  16. import (
  17. "encoding/base64"
  18. "io/ioutil"
  19. "time"
  20. "github.com/ipfs/go-log"
  21. "github.com/libp2p/go-libp2p"
  22. "github.com/mudler/edgevpn/pkg/blockchain"
  23. discovery "github.com/mudler/edgevpn/pkg/discovery"
  24. "github.com/mudler/edgevpn/pkg/protocol"
  25. "github.com/mudler/edgevpn/pkg/utils"
  26. "github.com/pkg/errors"
  27. "github.com/xlzd/gotp"
  28. "gopkg.in/yaml.v2"
  29. )
  30. // WithLibp2pOptions Overrides defaults options
  31. func WithLibp2pOptions(i ...libp2p.Option) func(cfg *Config) error {
  32. return func(cfg *Config) error {
  33. cfg.Options = i
  34. return nil
  35. }
  36. }
  37. func WithLibp2pAdditionalOptions(i ...libp2p.Option) func(cfg *Config) error {
  38. return func(cfg *Config) error {
  39. cfg.AdditionalOptions = append(cfg.Options, i...)
  40. return nil
  41. }
  42. }
  43. func WithNetworkService(ns ...NetworkService) func(cfg *Config) error {
  44. return func(cfg *Config) error {
  45. cfg.NetworkServices = append(cfg.NetworkServices, ns...)
  46. return nil
  47. }
  48. }
  49. func WithInterfaceAddress(i string) func(cfg *Config) error {
  50. return func(cfg *Config) error {
  51. cfg.InterfaceAddress = i
  52. return nil
  53. }
  54. }
  55. func Logger(l log.StandardLogger) func(cfg *Config) error {
  56. return func(cfg *Config) error {
  57. cfg.Logger = l
  58. return nil
  59. }
  60. }
  61. func WithStore(s blockchain.Store) func(cfg *Config) error {
  62. return func(cfg *Config) error {
  63. cfg.Store = s
  64. return nil
  65. }
  66. }
  67. // Handlers adds a handler to the list that is called on each received message
  68. func Handlers(h ...Handler) func(cfg *Config) error {
  69. return func(cfg *Config) error {
  70. cfg.Handlers = append(cfg.Handlers, h...)
  71. return nil
  72. }
  73. }
  74. // WithStreamHandler adds a handler to the list that is called on each received message
  75. func WithStreamHandler(id protocol.Protocol, h StreamHandler) func(cfg *Config) error {
  76. return func(cfg *Config) error {
  77. cfg.StreamHandlers[id] = h
  78. return nil
  79. }
  80. }
  81. // DiscoveryService Adds the service given as argument to the discovery services
  82. func DiscoveryService(s ...ServiceDiscovery) func(cfg *Config) error {
  83. return func(cfg *Config) error {
  84. cfg.ServiceDiscovery = append(cfg.ServiceDiscovery, s...)
  85. return nil
  86. }
  87. }
  88. func ListenAddresses(ss ...string) func(cfg *Config) error {
  89. return func(cfg *Config) error {
  90. for _, s := range ss {
  91. a := &discovery.AddrList{}
  92. err := a.Set(s)
  93. if err != nil {
  94. return err
  95. }
  96. cfg.ListenAddresses = append(cfg.ListenAddresses, *a)
  97. }
  98. return nil
  99. }
  100. }
  101. func Insecure(b bool) func(cfg *Config) error {
  102. return func(cfg *Config) error {
  103. cfg.Insecure = b
  104. return nil
  105. }
  106. }
  107. func ExchangeKeys(s string) func(cfg *Config) error {
  108. return func(cfg *Config) error {
  109. cfg.ExchangeKey = s
  110. return nil
  111. }
  112. }
  113. func RoomName(s string) func(cfg *Config) error {
  114. return func(cfg *Config) error {
  115. cfg.RoomName = s
  116. return nil
  117. }
  118. }
  119. func SealKeyInterval(i int) func(cfg *Config) error {
  120. return func(cfg *Config) error {
  121. cfg.SealKeyInterval = i
  122. return nil
  123. }
  124. }
  125. func SealKeyLength(i int) func(cfg *Config) error {
  126. return func(cfg *Config) error {
  127. cfg.SealKeyLength = i
  128. return nil
  129. }
  130. }
  131. func LibP2PLogLevel(l log.LogLevel) func(cfg *Config) error {
  132. return func(cfg *Config) error {
  133. log.SetAllLoggers(l)
  134. return nil
  135. }
  136. }
  137. func MaxMessageSize(i int) func(cfg *Config) error {
  138. return func(cfg *Config) error {
  139. cfg.MaxMessageSize = i
  140. return nil
  141. }
  142. }
  143. func WithLedgerAnnounceTime(t time.Duration) func(cfg *Config) error {
  144. return func(cfg *Config) error {
  145. cfg.LedgerAnnounceTime = t
  146. return nil
  147. }
  148. }
  149. func WithLedgerInterval(t time.Duration) func(cfg *Config) error {
  150. return func(cfg *Config) error {
  151. cfg.LedgerSyncronizationTime = t
  152. return nil
  153. }
  154. }
  155. func WithDiscoveryInterval(t time.Duration) func(cfg *Config) error {
  156. return func(cfg *Config) error {
  157. cfg.DiscoveryInterval = t
  158. return nil
  159. }
  160. }
  161. func WithDiscoveryBootstrapPeers(a discovery.AddrList) func(cfg *Config) error {
  162. return func(cfg *Config) error {
  163. cfg.DiscoveryBootstrapPeers = a
  164. return nil
  165. }
  166. }
  167. type OTPConfig struct {
  168. Interval int `yaml:"interval"`
  169. Key string `yaml:"key"`
  170. Length int `yaml:"length"`
  171. }
  172. type OTP struct {
  173. DHT OTPConfig `yaml:"dht"`
  174. Crypto OTPConfig `yaml:"crypto"`
  175. }
  176. type YAMLConnectionConfig struct {
  177. OTP OTP `yaml:"otp"`
  178. RoomName string `yaml:"room"`
  179. Rendezvous string `yaml:"rendezvous"`
  180. MDNS string `yaml:"mdns"`
  181. MaxMessageSize int `yaml:"max_message_size"`
  182. }
  183. // Base64 returns the base64 string representation of the connection
  184. func (y YAMLConnectionConfig) Base64() string {
  185. bytesData, _ := yaml.Marshal(y)
  186. return base64.StdEncoding.EncodeToString(bytesData)
  187. }
  188. // YAML returns the connection config as yaml string
  189. func (y YAMLConnectionConfig) YAML() string {
  190. bytesData, _ := yaml.Marshal(y)
  191. return string(bytesData)
  192. }
  193. func (y YAMLConnectionConfig) copy(mdns, dht bool, cfg *Config) {
  194. d := &discovery.DHT{
  195. RefreshDiscoveryTime: cfg.DiscoveryInterval,
  196. OTPInterval: y.OTP.DHT.Interval,
  197. OTPKey: y.OTP.DHT.Key,
  198. KeyLength: y.OTP.DHT.Length,
  199. RendezvousString: y.Rendezvous,
  200. BootstrapPeers: cfg.DiscoveryBootstrapPeers,
  201. }
  202. m := &discovery.MDNS{DiscoveryServiceTag: y.MDNS}
  203. cfg.ExchangeKey = y.OTP.Crypto.Key
  204. cfg.RoomName = y.RoomName
  205. cfg.SealKeyInterval = y.OTP.Crypto.Interval
  206. // cfg.ServiceDiscovery = []ServiceDiscovery{d, m}
  207. if mdns {
  208. cfg.ServiceDiscovery = append(cfg.ServiceDiscovery, m)
  209. }
  210. if dht {
  211. cfg.ServiceDiscovery = append(cfg.ServiceDiscovery, d)
  212. }
  213. cfg.SealKeyLength = y.OTP.Crypto.Length
  214. cfg.MaxMessageSize = y.MaxMessageSize
  215. }
  216. func GenerateNewConnectionData() *YAMLConnectionConfig {
  217. return &YAMLConnectionConfig{
  218. MaxMessageSize: 20 << 20, // 20MB
  219. RoomName: utils.RandStringRunes(23),
  220. Rendezvous: utils.RandStringRunes(23),
  221. MDNS: utils.RandStringRunes(23),
  222. OTP: OTP{
  223. DHT: OTPConfig{
  224. Key: gotp.RandomSecret(16),
  225. Interval: 9000,
  226. Length: 12,
  227. },
  228. Crypto: OTPConfig{
  229. Key: gotp.RandomSecret(16),
  230. Interval: 9000,
  231. Length: 12,
  232. },
  233. },
  234. }
  235. }
  236. func FromYaml(enablemDNS, enableDHT bool, path string) func(cfg *Config) error {
  237. return func(cfg *Config) error {
  238. if len(path) == 0 {
  239. return nil
  240. }
  241. t := YAMLConnectionConfig{}
  242. data, err := ioutil.ReadFile(path)
  243. if err != nil {
  244. return errors.Wrap(err, "reading yaml file")
  245. }
  246. if err := yaml.Unmarshal(data, &t); err != nil {
  247. return errors.Wrap(err, "parsing yaml")
  248. }
  249. t.copy(enablemDNS, enableDHT, cfg)
  250. return nil
  251. }
  252. }
  253. func FromBase64(enablemDNS, enableDHT bool, bb string) func(cfg *Config) error {
  254. return func(cfg *Config) error {
  255. if len(bb) == 0 {
  256. return nil
  257. }
  258. configDec, err := base64.StdEncoding.DecodeString(bb)
  259. if err != nil {
  260. return err
  261. }
  262. t := YAMLConnectionConfig{}
  263. if err := yaml.Unmarshal(configDec, &t); err != nil {
  264. return errors.Wrap(err, "parsing yaml")
  265. }
  266. t.copy(enablemDNS, enableDHT, cfg)
  267. return nil
  268. }
  269. }