main.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package main
  2. import (
  3. "context"
  4. "encoding/base64"
  5. "fmt"
  6. "net"
  7. "os"
  8. "os/user"
  9. "path/filepath"
  10. "time"
  11. "cryptoscope.co/go/muxrpc"
  12. "cryptoscope.co/go/muxrpc/codec"
  13. "cryptoscope.co/go/secretstream"
  14. "cryptoscope.co/go/secretstream/secrethandshake"
  15. "github.com/cryptix/go/debug"
  16. "github.com/cryptix/go/logging"
  17. humanize "github.com/dustin/go-humanize"
  18. kitlog "github.com/go-kit/kit/log"
  19. "github.com/pkg/errors"
  20. cli "gopkg.in/urfave/cli.v2"
  21. )
  22. var (
  23. sbotAppKey []byte
  24. defaultKeyFile string
  25. packer muxrpc.Packer
  26. rpc muxrpc.Endpoint
  27. localKey *secrethandshake.EdKeyPair
  28. localID string
  29. l net.Listener
  30. log logging.Interface
  31. check = logging.CheckFatal
  32. verboseLogging bool
  33. Revision = "unset"
  34. )
  35. func init() {
  36. var err error
  37. sbotAppKey, err = base64.StdEncoding.DecodeString("1KHLiKZvAvjbY1ziZEHMXawbCEIM6qwjCDm3VYRan/s=")
  38. check(err)
  39. u, err := user.Current()
  40. check(err)
  41. defaultKeyFile = filepath.Join(u.HomeDir, ".ssb", "secret")
  42. }
  43. func main() {
  44. logging.SetupLogging(nil)
  45. log = logging.Logger("gossipgopher")
  46. app := cli.App{
  47. Name: "ssb-gossipgopher",
  48. Usage: "very chatty hermit gopher",
  49. Version: "alpha1",
  50. }
  51. cli.VersionPrinter = func(c *cli.Context) {
  52. // go install -ldflags="-X main.Revision=$(git rev-parse HEAD)"
  53. fmt.Printf("%s ( rev: %s )\n", c.App.Version, Revision)
  54. }
  55. app.Flags = []cli.Flag{
  56. &cli.StringFlag{Name: "addr", Value: ":8008", Usage: "tcp address to listen on"},
  57. &cli.StringFlag{Name: "key,k", Value: defaultKeyFile},
  58. &cli.BoolFlag{Name: "verbose,vv", Usage: "print muxrpc packets"},
  59. }
  60. app.Before = initClient
  61. app.Commands = []*cli.Command{
  62. {
  63. Name: "serve",
  64. Action: serveCmd,
  65. },
  66. }
  67. check(app.Run(os.Args))
  68. ctx := context.Background()
  69. for {
  70. start := time.Now()
  71. conn, err := l.Accept()
  72. if err != nil {
  73. log.Log("error", "accept", "err", err)
  74. continue
  75. }
  76. go func() {
  77. rem := conn.RemoteAddr()
  78. shsAddr, ok := rem.(secretstream.Addr)
  79. if !ok {
  80. conn.Close()
  81. log.Log("err", errors.New("could not cast remote address"))
  82. return
  83. }
  84. id := SSBID(shsAddr.PubKey())
  85. log.Log("event", "connection established",
  86. "id", id,
  87. "addr", shsAddr.Addr.String(),
  88. )
  89. counter := debug.WrapCounter(conn)
  90. p := muxrpc.NewPacker(counter)
  91. if verboseLogging {
  92. p = muxrpc.NewPacker(codec.Wrap(kitlog.With(log, "id", id), counter))
  93. }
  94. handler := sbotHandler{id}
  95. rpc = muxrpc.Handle(p, handler)
  96. go serveRpc(ctx, start, id, rpc, counter)
  97. }()
  98. }
  99. }
  100. func serveRpc(ctx context.Context, start time.Time, id string, rpc muxrpc.Endpoint, counter *debug.Counter) {
  101. err := rpc.(muxrpc.Server).Serve(ctx)
  102. log.Log("event", "connection done",
  103. "id", id,
  104. "err", err,
  105. "took", time.Since(start),
  106. "sent", humanize.Bytes(counter.Cw.Count()),
  107. "rcvd", humanize.Bytes(counter.Cr.Count()),
  108. )
  109. }
  110. func initClient(ctx *cli.Context) error {
  111. verboseLogging = ctx.Bool("verbose")
  112. var err error
  113. localKey, err = secrethandshake.LoadSSBKeyPair(ctx.String("key"))
  114. if err != nil {
  115. return errors.Wrap(err, "failed to load keypair")
  116. }
  117. localID = SSBID(localKey.Public[:])
  118. srv, err := secretstream.NewServer(*localKey, sbotAppKey)
  119. if err != nil {
  120. return errors.Wrap(err, "failed to create server")
  121. }
  122. l, err = srv.Listen("tcp", ctx.String("addr"))
  123. if err != nil {
  124. return err
  125. }
  126. log.Log("msg", "listener created", "addr", l.Addr(), "ssbID", localID)
  127. return nil
  128. }
  129. func SSBID(pubKey []byte) string {
  130. return fmt.Sprintf("@%s.ed25519", base64.StdEncoding.EncodeToString(pubKey))
  131. }
  132. func serveCmd(ctx *cli.Context) error {
  133. /*
  134. client.HandleCall("gossip.ping", func(msg json.RawMessage) interface{} {
  135. //var args []map[string]interface{}
  136. var args []struct {
  137. Timeout int
  138. }
  139. err := json.Unmarshal(msg, &args)
  140. if err != nil {
  141. return errors.Wrap(err, "failed to decode ping arguments")
  142. }
  143. timeout := 1000
  144. if len(args) == 1 {
  145. if t, hasTimeout := args[0]["timeout"]; hasTimeout {
  146. timeout = t.(float64)
  147. }
  148. timeout = args[0].Timeout
  149. }
  150. log.Log("event", "incoming call", "cmd", "ping", "timeout", timeout)
  151. return struct {
  152. Pong string
  153. }{"test"}
  154. })
  155. */
  156. /*
  157. client.HandleSource("blobs.createWants", func(msg json.RawMessage) chan interface{} {
  158. log.Log("event", "incoming call", "cmd", "blob wants", "msg", string(msg))
  159. type blobs struct {
  160. Ref string
  161. }
  162. blobWants := make(chan interface{})
  163. go func() {
  164. for i := 0; i <= 10; i++ {
  165. blobWants <- blobs{
  166. Ref: "123",
  167. }
  168. }
  169. close(blobWants)
  170. log.Log("event", "source done", "cmd", "blob wants")
  171. }()
  172. return blobWants
  173. })
  174. */
  175. return nil
  176. }