main.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "io"
  6. "log"
  7. "net"
  8. "net/http"
  9. "os"
  10. "os/signal"
  11. "sort"
  12. "strconv"
  13. "strings"
  14. "syscall"
  15. "github.com/weaveworks/mesh"
  16. )
  17. func main() {
  18. peers := &stringset{}
  19. var (
  20. httpListen = flag.String("http", ":8080", "HTTP listen address")
  21. meshListen = flag.String("mesh", net.JoinHostPort("0.0.0.0", strconv.Itoa(mesh.Port)), "mesh listen address")
  22. hwaddr = flag.String("hwaddr", mustHardwareAddr(), "MAC address, i.e. mesh peer ID")
  23. nickname = flag.String("nickname", mustHostname(), "peer nickname")
  24. password = flag.String("password", "", "password (optional)")
  25. channel = flag.String("channel", "default", "gossip channel name")
  26. )
  27. flag.Var(peers, "peer", "initial peer (may be repeated)")
  28. flag.Parse()
  29. logger := log.New(os.Stderr, *nickname+"> ", log.LstdFlags)
  30. host, portStr, err := net.SplitHostPort(*meshListen)
  31. if err != nil {
  32. logger.Fatalf("mesh address: %s: %v", *meshListen, err)
  33. }
  34. port, err := strconv.Atoi(portStr)
  35. if err != nil {
  36. logger.Fatalf("mesh address: %s: %v", *meshListen, err)
  37. }
  38. name, err := mesh.PeerNameFromString(*hwaddr)
  39. if err != nil {
  40. logger.Fatalf("%s: %v", *hwaddr, err)
  41. }
  42. router, err := mesh.NewRouter(mesh.Config{
  43. Host: host,
  44. Port: port,
  45. ProtocolMinVersion: mesh.ProtocolMinVersion,
  46. Password: []byte(*password),
  47. ConnLimit: 64,
  48. PeerDiscovery: true,
  49. TrustedSubnets: []*net.IPNet{},
  50. }, name, *nickname, mesh.NullOverlay{}, log.New(io.Discard, "", 0))
  51. if err != nil {
  52. logger.Fatalf("Could not create router: %v", err)
  53. }
  54. peer := newPeer(name, logger)
  55. gossip, err := router.NewGossip(*channel, peer)
  56. if err != nil {
  57. logger.Fatalf("Could not create gossip: %v", err)
  58. }
  59. peer.register(gossip)
  60. func() {
  61. logger.Printf("mesh router starting (%s)", *meshListen)
  62. router.Start()
  63. }()
  64. defer func() {
  65. logger.Printf("mesh router stopping")
  66. router.Stop()
  67. }()
  68. router.ConnectionMaker.InitiateConnections(peers.slice(), true)
  69. errs := make(chan error)
  70. go func() {
  71. c := make(chan os.Signal)
  72. signal.Notify(c, syscall.SIGINT)
  73. errs <- fmt.Errorf("%s", <-c)
  74. }()
  75. go func() {
  76. logger.Printf("HTTP server starting (%s)", *httpListen)
  77. http.HandleFunc("/", handle(peer))
  78. errs <- http.ListenAndServe(*httpListen, nil)
  79. }()
  80. logger.Print(<-errs)
  81. }
  82. type counter interface {
  83. get() int
  84. incr() int
  85. }
  86. func handle(c counter) http.HandlerFunc {
  87. return func(w http.ResponseWriter, r *http.Request) {
  88. switch r.Method {
  89. case "GET":
  90. fmt.Fprintf(w, "get => %d\n", c.get())
  91. case "POST":
  92. fmt.Fprintf(w, "incr => %d\n", c.incr())
  93. }
  94. }
  95. }
  96. type stringset map[string]struct{}
  97. func (ss stringset) Set(value string) error {
  98. ss[value] = struct{}{}
  99. return nil
  100. }
  101. func (ss stringset) String() string {
  102. return strings.Join(ss.slice(), ",")
  103. }
  104. func (ss stringset) slice() []string {
  105. slice := make([]string, 0, len(ss))
  106. for k := range ss {
  107. slice = append(slice, k)
  108. }
  109. sort.Strings(slice)
  110. return slice
  111. }
  112. func mustHardwareAddr() string {
  113. ifaces, err := net.Interfaces()
  114. if err != nil {
  115. panic(err)
  116. }
  117. for _, iface := range ifaces {
  118. if s := iface.HardwareAddr.String(); s != "" {
  119. return s
  120. }
  121. }
  122. panic("no valid network interfaces")
  123. }
  124. func mustHostname() string {
  125. hostname, err := os.Hostname()
  126. if err != nil {
  127. panic(err)
  128. }
  129. return hostname
  130. }