main.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright (C) 2014-2015 Jakob Borg and Contributors (see the CONTRIBUTORS file).
  2. package main
  3. import (
  4. "crypto/tls"
  5. "database/sql"
  6. "flag"
  7. "fmt"
  8. "log"
  9. "os"
  10. "runtime"
  11. "strconv"
  12. "time"
  13. "github.com/syncthing/syncthing/lib/protocol"
  14. "github.com/thejerf/suture"
  15. )
  16. const (
  17. minNegCache = 60 // seconds
  18. maxNegCache = 3600 // seconds
  19. maxDeviceAge = 7 * 86400 // one week, in seconds
  20. )
  21. var (
  22. Version string
  23. BuildStamp string
  24. BuildUser string
  25. BuildHost string
  26. BuildDate time.Time
  27. LongVersion string
  28. )
  29. func init() {
  30. stamp, _ := strconv.Atoi(BuildStamp)
  31. BuildDate = time.Unix(int64(stamp), 0)
  32. date := BuildDate.UTC().Format("2006-01-02 15:04:05 MST")
  33. LongVersion = fmt.Sprintf(`stdiscosrv %s (%s %s-%s) %s@%s %s`, Version, runtime.Version(), runtime.GOOS, runtime.GOARCH, BuildUser, BuildHost, date)
  34. }
  35. var (
  36. lruSize = 10240
  37. limitAvg = 5
  38. limitBurst = 20
  39. globalStats stats
  40. statsFile string
  41. backend = "ql"
  42. dsn = getEnvDefault("STDISCOSRV_DB_DSN", "memory://stdiscosrv")
  43. certFile = "cert.pem"
  44. keyFile = "key.pem"
  45. debug = false
  46. useHTTP = false
  47. )
  48. func main() {
  49. const (
  50. cleanIntv = 1 * time.Hour
  51. statsIntv = 5 * time.Minute
  52. )
  53. var listen string
  54. log.SetOutput(os.Stdout)
  55. log.SetFlags(0)
  56. flag.StringVar(&listen, "listen", ":8443", "Listen address")
  57. flag.IntVar(&lruSize, "limit-cache", lruSize, "Limiter cache entries")
  58. flag.IntVar(&limitAvg, "limit-avg", limitAvg, "Allowed average package rate, per 10 s")
  59. flag.IntVar(&limitBurst, "limit-burst", limitBurst, "Allowed burst size, packets")
  60. flag.StringVar(&statsFile, "stats-file", statsFile, "File to write periodic operation stats to")
  61. flag.StringVar(&backend, "db-backend", backend, "Database backend to use")
  62. flag.StringVar(&dsn, "db-dsn", dsn, "Database DSN")
  63. flag.StringVar(&certFile, "cert", certFile, "Certificate file")
  64. flag.StringVar(&keyFile, "key", keyFile, "Key file")
  65. flag.BoolVar(&debug, "debug", debug, "Debug")
  66. flag.BoolVar(&useHTTP, "http", useHTTP, "Listen on HTTP (behind an HTTPS proxy)")
  67. flag.Parse()
  68. log.Println(LongVersion)
  69. var cert tls.Certificate
  70. var err error
  71. if !useHTTP {
  72. cert, err = tls.LoadX509KeyPair(certFile, keyFile)
  73. if err != nil {
  74. log.Fatalln("Failed to load X509 key pair:", err)
  75. }
  76. devID := protocol.NewDeviceID(cert.Certificate[0])
  77. log.Println("Server device ID is", devID)
  78. }
  79. db, err := sql.Open(backend, dsn)
  80. if err != nil {
  81. log.Fatalln("sql.Open:", err)
  82. }
  83. prep, err := setup(backend, db)
  84. if err != nil {
  85. log.Fatalln("Setup:", err)
  86. }
  87. main := suture.NewSimple("main")
  88. main.Add(&querysrv{
  89. addr: listen,
  90. cert: cert,
  91. db: db,
  92. prep: prep,
  93. })
  94. main.Add(&cleansrv{
  95. intv: cleanIntv,
  96. db: db,
  97. prep: prep,
  98. })
  99. main.Add(&statssrv{
  100. intv: statsIntv,
  101. file: statsFile,
  102. db: db,
  103. })
  104. globalStats.Reset()
  105. main.Serve()
  106. }
  107. func getEnvDefault(key, def string) string {
  108. if val := os.Getenv(key); val != "" {
  109. return val
  110. }
  111. return def
  112. }
  113. func next(intv time.Duration) time.Duration {
  114. t0 := time.Now()
  115. t1 := t0.Add(intv).Truncate(intv)
  116. return t1.Sub(t0)
  117. }