Просмотр исходного кода

Merge pull request #24 from 9seconds/ntp

Add support of ntp time verification
tags/0.10
Sergey Arkhipov 7 лет назад
Родитель
Сommit
247ee5b20b
Аккаунт пользователя с таким Email не найден
4 измененных файлов: 93 добавлений и 2 удалений
  1. 18
    1
      Gopkg.lock
  2. 4
    0
      Gopkg.toml
  3. 11
    1
      main.go
  4. 60
    0
      ntp/ntp.go

+ 18
- 1
Gopkg.lock Просмотреть файл

16
   packages = ["."]
16
   packages = ["."]
17
   revision = "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a"
17
   revision = "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a"
18
 
18
 
19
+[[projects]]
20
+  name = "github.com/beevik/ntp"
21
+  packages = ["."]
22
+  revision = "62c80a04de2086884d8296004b6d74ee1846c582"
23
+  version = "v0.2.0"
24
+
19
 [[projects]]
25
 [[projects]]
20
   name = "github.com/davecgh/go-spew"
26
   name = "github.com/davecgh/go-spew"
21
   packages = ["spew"]
27
   packages = ["spew"]
77
   revision = "eeedf312bc6c57391d84767a4cd413f02a917974"
83
   revision = "eeedf312bc6c57391d84767a4cd413f02a917974"
78
   version = "v1.8.0"
84
   version = "v1.8.0"
79
 
85
 
86
+[[projects]]
87
+  branch = "master"
88
+  name = "golang.org/x/net"
89
+  packages = [
90
+    "bpf",
91
+    "internal/iana",
92
+    "internal/socket",
93
+    "ipv4"
94
+  ]
95
+  revision = "d0887baf81f4598189d4e12a37c6da86f0bba4d0"
96
+
80
 [[projects]]
97
 [[projects]]
81
   name = "gopkg.in/alecthomas/kingpin.v2"
98
   name = "gopkg.in/alecthomas/kingpin.v2"
82
   packages = ["."]
99
   packages = ["."]
86
 [solve-meta]
103
 [solve-meta]
87
   analyzer-name = "dep"
104
   analyzer-name = "dep"
88
   analyzer-version = 1
105
   analyzer-version = 1
89
-  inputs-digest = "c4fdd3664f683342ad0c2509f4a8bcfe5b267a6e8cdaf36f70d39536bbf89834"
106
+  inputs-digest = "f828340a30ea13c563829f9a37d0ff62974d4578411c9be02e61125dbdf98692"
90
   solver-name = "gps-cdcl"
107
   solver-name = "gps-cdcl"
91
   solver-version = 1
108
   solver-version = 1

+ 4
- 0
Gopkg.toml Просмотреть файл

48
 [[constraint]]
48
 [[constraint]]
49
   branch = "master"
49
   branch = "master"
50
   name = "github.com/dustin/go-humanize"
50
   name = "github.com/dustin/go-humanize"
51
+
52
+[[constraint]]
53
+  name = "github.com/beevik/ntp"
54
+  version = "0.2.0"

+ 11
- 1
main.go Просмотреть файл

4
 
4
 
5
 import (
5
 import (
6
 	"encoding/json"
6
 	"encoding/json"
7
+	"fmt"
7
 	"io"
8
 	"io"
8
 	"math/rand"
9
 	"math/rand"
9
 	"os"
10
 	"os"
10
 	"syscall"
11
 	"syscall"
11
 	"time"
12
 	"time"
12
 
13
 
14
+	"github.com/juju/errors"
13
 	"go.uber.org/zap"
15
 	"go.uber.org/zap"
14
 	"go.uber.org/zap/zapcore"
16
 	"go.uber.org/zap/zapcore"
15
 	kingpin "gopkg.in/alecthomas/kingpin.v2"
17
 	kingpin "gopkg.in/alecthomas/kingpin.v2"
16
 
18
 
17
 	"github.com/9seconds/mtg/config"
19
 	"github.com/9seconds/mtg/config"
20
+	"github.com/9seconds/mtg/ntp"
18
 	"github.com/9seconds/mtg/proxy"
21
 	"github.com/9seconds/mtg/proxy"
19
 	"github.com/9seconds/mtg/stats"
22
 	"github.com/9seconds/mtg/stats"
20
-	"github.com/juju/errors"
21
 )
23
 )
22
 
24
 
23
 var (
25
 var (
120
 
122
 
121
 	if conf.UseMiddleProxy() {
123
 	if conf.UseMiddleProxy() {
122
 		zap.S().Infow("Use middle proxy connection to Telegram")
124
 		zap.S().Infow("Use middle proxy connection to Telegram")
125
+		if diff, err := ntp.Fetch(); err != nil {
126
+			zap.S().Warnw("Could not fetch time data from NTP")
127
+		} else {
128
+			if diff >= time.Second {
129
+				usage(fmt.Sprintf("You choose to use middle proxy but your clock drift (%s) is bigger than 1 second. Please, sync your time", diff))
130
+			}
131
+			go ntp.AutoUpdate()
132
+		}
123
 	} else {
133
 	} else {
124
 		zap.S().Infow("Use direct connection to Telegram")
134
 		zap.S().Infow("Use direct connection to Telegram")
125
 	}
135
 	}

+ 60
- 0
ntp/ntp.go Просмотреть файл

1
+package ntp
2
+
3
+import (
4
+	"math/rand"
5
+	"time"
6
+
7
+	"github.com/beevik/ntp"
8
+	"github.com/juju/errors"
9
+	"go.uber.org/zap"
10
+)
11
+
12
+const autoUpdatePeriod = time.Minute
13
+
14
+var ntpEndpoints = []string{
15
+	"0.pool.ntp.org",
16
+	"1.pool.ntp.org",
17
+	"2.pool.ntp.org",
18
+	"3.pool.ntp.org",
19
+}
20
+
21
+// Fetch fetches the data on time drift.
22
+func Fetch() (time.Duration, error) {
23
+	url := ntpEndpoints[rand.Intn(len(ntpEndpoints))]
24
+	resp, err := ntp.Query(url)
25
+	if err != nil {
26
+		return 0, errors.Annotatef(err, "Cannot fetch NTP server %s", url)
27
+	}
28
+
29
+	offsetInt := int64(resp.ClockOffset)
30
+	if offsetInt < 0 {
31
+		offsetInt = -offsetInt
32
+	}
33
+	offset := time.Duration(offsetInt)
34
+
35
+	return offset, nil
36
+}
37
+
38
+// AutoUpdate runs periodic check of current time .drift state.
39
+func AutoUpdate() {
40
+	logger := zap.S().Named("ntp")
41
+
42
+	for range time.Tick(autoUpdatePeriod) {
43
+		diff, err := Fetch()
44
+		if err != nil {
45
+			logger.Debugw("Cannot fetch time from NTP", "error", err)
46
+			continue
47
+		}
48
+
49
+		switch {
50
+		case diff < 400*time.Millisecond:
51
+			logger.Debugw("NTP time drift", "value", diff.String())
52
+		case diff < 600*time.Millisecond:
53
+			logger.Infow("NTP time drift", "value", diff.String())
54
+		case diff < 800*time.Millisecond:
55
+			logger.Warnw("NTP time drift", "value", diff.String())
56
+		default:
57
+			logger.Errorw("NTP time drift", "value", diff.String())
58
+		}
59
+	}
60
+}

Загрузка…
Отмена
Сохранить