Official cwtch.im peer and server implementations. https://cwtch.im
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server.go 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package server
  2. import (
  3. "cwtch.im/cwtch/server/fetch"
  4. "cwtch.im/cwtch/server/listen"
  5. "cwtch.im/cwtch/server/metrics"
  6. "cwtch.im/cwtch/server/send"
  7. "cwtch.im/cwtch/server/storage"
  8. "git.openprivacy.ca/openprivacy/libricochet-go/application"
  9. "git.openprivacy.ca/openprivacy/libricochet-go/channels"
  10. "git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
  11. "git.openprivacy.ca/openprivacy/libricochet-go/utils"
  12. "git.openprivacy.ca/openprivacy/libricochet-go/log"
  13. "os"
  14. "strconv"
  15. "time"
  16. )
  17. // Server encapsulates a complete, compliant Cwtch server.
  18. type Server struct {
  19. app *application.RicochetApplication
  20. config Config
  21. metricsPack metrics.Monitors
  22. closed bool
  23. }
  24. // Run starts a server with the given privateKey
  25. // TODO: surface errors
  26. // TODO: handle HUP/KILL signals to exit and close Tor gracefully
  27. // TODO: handle user input to exit
  28. func (s *Server) Run(acn connectivity.ACN, serverConfig Config) {
  29. s.closed = false
  30. s.config = serverConfig
  31. cwtchserver := new(application.RicochetApplication)
  32. s.metricsPack.Start(cwtchserver, serverConfig.ConfigDir, s.config.ServerReporting.LogMetricsToFile)
  33. af := application.InstanceFactory{}
  34. af.Init()
  35. ms := new(storage.MessageStore)
  36. err := ms.Init(serverConfig.ConfigDir, s.config.MaxBufferLines, s.metricsPack.MessageCounter)
  37. if err != nil {
  38. log.Errorln(err)
  39. acn.Close()
  40. os.Exit(1)
  41. }
  42. af.AddHandler("im.cwtch.server.listen", func(rai *application.Instance) func() channels.Handler {
  43. return func() channels.Handler {
  44. cslc := new(listen.CwtchServerListenChannel)
  45. return cslc
  46. }
  47. })
  48. af.AddHandler("im.cwtch.server.fetch", func(rai *application.Instance) func() channels.Handler {
  49. si := new(Instance)
  50. si.Init(rai, cwtchserver, ms)
  51. return func() channels.Handler {
  52. cssc := new(fetch.CwtchServerFetchChannel)
  53. cssc.Handler = si
  54. return cssc
  55. }
  56. })
  57. af.AddHandler("im.cwtch.server.send", func(rai *application.Instance) func() channels.Handler {
  58. si := new(Instance)
  59. si.Init(rai, cwtchserver, ms)
  60. return func() channels.Handler {
  61. cssc := new(send.CwtchServerSendChannel)
  62. cssc.Handler = si
  63. return cssc
  64. }
  65. })
  66. addressIdentity := utils.GetTorV3Hostname(s.config.PublicKey)
  67. cwtchserver.Init(acn, "cwtch server for "+addressIdentity, s.config.Identity(), af, new(application.AcceptAllContactManager))
  68. port := strconv.Itoa(application.RicochetPort)
  69. log.Infof("cwtch server running on cwtch:%s\n", addressIdentity+".onion:"+port)
  70. s.app = cwtchserver
  71. for true {
  72. listenService, err := acn.Listen(s.config.PrivateKey, application.RicochetPort)
  73. if err != nil {
  74. log.Errorf("Listen() error setting up onion service: %v\n", err)
  75. } else {
  76. s.app.Run(listenService)
  77. }
  78. if s.closed {
  79. return
  80. }
  81. time.Sleep(5 * time.Second)
  82. }
  83. }
  84. // Shutdown kills the app closing all connections and freeing all goroutines
  85. func (s *Server) Shutdown() {
  86. s.closed = true
  87. s.app.Shutdown()
  88. s.metricsPack.Stop()
  89. }