ping.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package netmgrd
  2. import (
  3. "context"
  4. "net"
  5. "net/http"
  6. "os/exec"
  7. "strings"
  8. "time"
  9. )
  10. const (
  11. ///////////////////////////////////////
  12. // 白名单联网检测地址
  13. TEST_URL1 = "www.aliyun.com"
  14. TEST_URL2 = "http://8.136.98.49"
  15. TEST_HOST = "223.5.5.5" // 阿里云DNS主机
  16. ///////////////////////////////////////
  17. TEST_TIMEOUT = 5 * time.Second
  18. )
  19. func test1() bool {
  20. ctx, cancel := context.WithTimeout(context.Background(), TEST_TIMEOUT)
  21. defer cancel()
  22. addrs, err := net.DefaultResolver.LookupHost(ctx, TEST_URL1)
  23. return err == nil && len(addrs) > 0
  24. }
  25. func test2() bool {
  26. ctx, cancel := context.WithTimeout(context.Background(), TEST_TIMEOUT)
  27. defer cancel()
  28. cmd := exec.CommandContext(ctx, "ping", "-c", "3", "-W", "3", TEST_HOST)
  29. out, err := cmd.CombinedOutput()
  30. if err != nil {
  31. return false
  32. }
  33. return strings.Contains(strings.ToLower(string(out)), "ttl=")
  34. }
  35. func tcpReachable(addr string, timeout time.Duration) bool {
  36. conn, err := net.DialTimeout("tcp", addr, timeout)
  37. if err != nil {
  38. return false
  39. }
  40. conn.Close()
  41. return true
  42. }
  43. func test3() bool {
  44. return tcpReachable(TEST_HOST+":53", TEST_TIMEOUT)
  45. }
  46. func test4() (bool, time.Time) { // HTTP访问测试(不跟随重定向)
  47. client := http.Client{
  48. Timeout: TEST_TIMEOUT,
  49. CheckRedirect: func(req *http.Request, via []*http.Request) error {
  50. return http.ErrUseLastResponse
  51. },
  52. }
  53. resp, err := client.Head(TEST_URL2)
  54. if err != nil {
  55. return false, time.Time{}
  56. }
  57. defer resp.Body.Close()
  58. date := resp.Header.Get("Date")
  59. if date == "" {
  60. return true, time.Time{}
  61. }
  62. t, err := time.Parse(http.TimeFormat, date)
  63. if err != nil {
  64. return true, time.Time{}
  65. }
  66. return true, t
  67. }
  68. func CheckNetwork() (dnsOK, pingOK, tcpOK, httpOK bool, httpTime time.Time) {
  69. bOK1 := test1()
  70. bOK3 := test3() || tcpReachable(TEST_HOST+":80", TEST_TIMEOUT) ||
  71. tcpReachable("8.136.98.49:80", TEST_TIMEOUT) || tcpReachable("8.136.98.49:61883", TEST_TIMEOUT)
  72. bOK4, httpDate := test4()
  73. bOK2 := bOK3 || bOK4 || test2()
  74. return bOK1, bOK2, bOK3, bOK4, httpDate
  75. }