util.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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 cmd
  16. import (
  17. "runtime"
  18. "time"
  19. "github.com/ipfs/go-log"
  20. "github.com/libp2p/go-libp2p"
  21. "github.com/mudler/edgevpn/internal"
  22. "github.com/mudler/edgevpn/pkg/blockchain"
  23. "github.com/mudler/edgevpn/pkg/discovery"
  24. "github.com/mudler/edgevpn/pkg/edgevpn"
  25. "github.com/mudler/edgevpn/pkg/logger"
  26. "github.com/peterbourgon/diskv"
  27. "github.com/songgao/water"
  28. "github.com/urfave/cli"
  29. )
  30. var CommonFlags []cli.Flag = []cli.Flag{
  31. &cli.StringFlag{
  32. Name: "config",
  33. Usage: "Specify a path to a edgevpn config file",
  34. EnvVar: "EDGEVPNCONFIG",
  35. },
  36. &cli.StringFlag{
  37. Name: "timeout",
  38. Usage: "Specify a default timeout for connection stream",
  39. EnvVar: "EDGEVPNTIMEOUT",
  40. Value: "15s",
  41. },
  42. &cli.IntFlag{
  43. Name: "mtu",
  44. Usage: "Specify a mtu",
  45. EnvVar: "EDGEVPNMTU",
  46. Value: 1200,
  47. },
  48. &cli.IntFlag{
  49. Name: "channel-buffer-size",
  50. Usage: "Specify a channel buffer size",
  51. EnvVar: "EDGEVPNCHANNELBUFFERSIZE",
  52. Value: 0,
  53. },
  54. &cli.IntFlag{
  55. Name: "discovery-interval",
  56. Usage: "DHT discovery interval time",
  57. EnvVar: "EDGEVPNDHTINTERVAL",
  58. Value: 120,
  59. },
  60. &cli.IntFlag{
  61. Name: "ledger-announce-interval",
  62. Usage: "Ledger announce interval time",
  63. EnvVar: "EDGEVPNLEDGERINTERVAL",
  64. Value: 10,
  65. },
  66. &cli.IntFlag{
  67. Name: "ledger-syncronization-interval",
  68. Usage: "Ledger syncronization interval time",
  69. EnvVar: "EDGEVPNLEDGERSYNCINTERVAL",
  70. Value: 10,
  71. },
  72. &cli.IntFlag{
  73. Name: "nat-ratelimit-global",
  74. Usage: "Rate limit global requests",
  75. EnvVar: "EDGEVPNNATRATELIMITGLOBAL",
  76. Value: 10,
  77. },
  78. &cli.IntFlag{
  79. Name: "nat-ratelimit-peer",
  80. Usage: "Rate limit perr requests",
  81. EnvVar: "EDGEVPNNATRATELIMITPEER",
  82. Value: 10,
  83. },
  84. &cli.IntFlag{
  85. Name: "nat-ratelimit-interval",
  86. Usage: "Rate limit interval",
  87. EnvVar: "EDGEVPNNATRATELIMITINTERVAL",
  88. Value: 60,
  89. },
  90. &cli.BoolTFlag{
  91. Name: "nat-ratelimit",
  92. Usage: "Changes the default rate limiting configured in helping other peers determine their reachability status",
  93. EnvVar: "EDGEVPNNATRATELIMIT",
  94. },
  95. &cli.StringFlag{
  96. Name: "ledger-state",
  97. Usage: "Specify a ledger state directory",
  98. EnvVar: "EDGEVPNLEDGERSTATE",
  99. },
  100. &cli.BoolTFlag{
  101. Name: "mdns",
  102. Usage: "Enable mDNS for peer discovery",
  103. EnvVar: "EDGEVPNMDNS",
  104. },
  105. &cli.BoolTFlag{
  106. Name: "autorelay",
  107. Usage: "Automatically act as a relay if the node can accept inbound connections",
  108. EnvVar: "EDGEVPNAUTORELAY",
  109. },
  110. &cli.IntFlag{
  111. Name: "concurrency",
  112. Usage: "Number of concurrent requests to serve",
  113. Value: runtime.NumCPU(),
  114. },
  115. &cli.BoolTFlag{
  116. Name: "holepunch",
  117. Usage: "Automatically try holepunching when possible",
  118. EnvVar: "EDGEVPNHOLEPUNCH",
  119. },
  120. &cli.BoolTFlag{
  121. Name: "natservice",
  122. Usage: "Tries to determine reachability status of nodes",
  123. EnvVar: "EDGEVPNNATSERVICE",
  124. },
  125. &cli.BoolTFlag{
  126. Name: "natmap",
  127. Usage: "Tries to open a port in the firewall via upnp",
  128. EnvVar: "EDGEVPNNATMAP",
  129. },
  130. &cli.BoolTFlag{
  131. Name: "dht",
  132. Usage: "Enable DHT for peer discovery",
  133. EnvVar: "EDGEVPNDHT",
  134. },
  135. &cli.StringFlag{
  136. Name: "log-level",
  137. Usage: "Specify loglevel",
  138. EnvVar: "EDGEVPNLOGLEVEL",
  139. Value: "info",
  140. },
  141. &cli.StringFlag{
  142. Name: "libp2p-log-level",
  143. Usage: "Specify libp2p loglevel",
  144. EnvVar: "EDGEVPNLIBP2PLOGLEVEL",
  145. Value: "fatal",
  146. },
  147. &cli.StringSliceFlag{
  148. Name: "discovery-bootstrap-peers",
  149. Usage: "List of discovery peers to use",
  150. EnvVar: "EDGEVPNBOOTSTRAPPEERS",
  151. },
  152. &cli.StringFlag{
  153. Name: "token",
  154. Usage: "Specify an edgevpn token in place of a config file",
  155. EnvVar: "EDGEVPNTOKEN",
  156. }}
  157. func displayStart(e *edgevpn.EdgeVPN) {
  158. e.Logger().Info(Copyright)
  159. e.Logger().Infof("Version: %s commit: %s", internal.Version, internal.Commit)
  160. }
  161. func cliToOpts(c *cli.Context) []edgevpn.Option {
  162. config := c.String("config")
  163. address := c.String("address")
  164. router := c.String("router")
  165. iface := c.String("interface")
  166. logLevel := c.String("log-level")
  167. libp2plogLevel := c.String("libp2p-log-level")
  168. dht, mDNS := c.Bool("dht"), c.Bool("mdns")
  169. ledgerState := c.String("ledger-state")
  170. addrsList := discovery.AddrList{}
  171. peers := c.StringSlice("discovery-bootstrap-peers")
  172. lvl, err := log.LevelFromString(logLevel)
  173. if err != nil {
  174. lvl = log.LevelError
  175. }
  176. llger := logger.New(lvl)
  177. libp2plvl, err := log.LevelFromString(libp2plogLevel)
  178. if err != nil {
  179. libp2plvl = log.LevelFatal
  180. }
  181. token := c.String("token")
  182. if config == "" &&
  183. token == "" {
  184. llger.Fatal("EDGEVPNCONFIG or EDGEVPNTOKEN not supplied. At least a config file is required")
  185. }
  186. for _, p := range peers {
  187. if err := addrsList.Set(p); err != nil {
  188. llger.Fatal("Failed reading bootstrap peer list", err.Error())
  189. }
  190. }
  191. opts := []edgevpn.Option{
  192. edgevpn.WithDiscoveryInterval(time.Duration(c.Int("discovery-interval")) * time.Second),
  193. edgevpn.WithLedgerAnnounceTime(time.Duration(c.Int("ledger-announce-interval")) * time.Second),
  194. edgevpn.WithLedgerInterval(time.Duration(c.Int("ledger-syncronization-interval")) * time.Second),
  195. edgevpn.Logger(llger),
  196. edgevpn.WithDiscoveryBootstrapPeers(addrsList),
  197. edgevpn.LibP2PLogLevel(libp2plvl),
  198. edgevpn.WithInterfaceMTU(c.Int("mtu")),
  199. edgevpn.WithPacketMTU(1420),
  200. edgevpn.WithInterfaceAddress(address),
  201. edgevpn.WithRouterAddress(router),
  202. edgevpn.WithInterfaceName(iface),
  203. edgevpn.WithTimeout(c.String("timeout")),
  204. edgevpn.WithInterfaceType(water.TUN),
  205. edgevpn.NetLinkBootstrap(true),
  206. edgevpn.WithChannelBufferSize(c.Int("channel-buffer-size")),
  207. edgevpn.FromBase64(mDNS, dht, token),
  208. edgevpn.FromYaml(mDNS, dht, config),
  209. }
  210. libp2pOpts := []libp2p.Option{libp2p.UserAgent("edgevpn")}
  211. if c.Bool("autorelay") {
  212. libp2pOpts = append(libp2pOpts, libp2p.EnableAutoRelay())
  213. }
  214. if c.Bool("nat-ratelimit") {
  215. libp2pOpts = append(libp2pOpts, libp2p.AutoNATServiceRateLimit(
  216. c.Int("nat-ratelimit-global"),
  217. c.Int("nat-ratelimit-peer"),
  218. time.Duration(c.Int("nat-ratelimit-interval"))*time.Second,
  219. ))
  220. }
  221. if c.Bool("holepunch") {
  222. libp2pOpts = append(libp2pOpts, libp2p.EnableHolePunching())
  223. }
  224. if c.Bool("natservice") {
  225. libp2pOpts = append(libp2pOpts, libp2p.EnableNATService())
  226. }
  227. if c.Bool("natmap") {
  228. libp2pOpts = append(libp2pOpts, libp2p.NATPortMap())
  229. }
  230. opts = append(opts, edgevpn.WithLibp2pOptions(libp2pOpts...))
  231. if ledgerState != "" {
  232. opts = append(opts, edgevpn.WithStore(blockchain.NewDiskStore(diskv.New(diskv.Options{
  233. BasePath: ledgerState,
  234. CacheSizeMax: uint64(50), // 50MB
  235. }))))
  236. } else {
  237. opts = append(opts, edgevpn.WithStore(&blockchain.MemoryStore{}))
  238. }
  239. return opts
  240. }