net.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. // Package net is a drop-in replacement to Golang's net package, with some more functionalities.
  2. package net // import "github.com/xtls/xray-core/common/net"
  3. import (
  4. "net"
  5. "sync/atomic"
  6. "time"
  7. "github.com/xtls/xray-core/common/errors"
  8. )
  9. // defines the maximum time an idle TCP session can survive in the tunnel, so
  10. // it should be consistent across HTTP versions and with other transports.
  11. const ConnIdleTimeout = 300 * time.Second
  12. // consistent with quic-go
  13. const QuicgoH3KeepAlivePeriod = 10 * time.Second
  14. // consistent with chrome
  15. const ChromeH2KeepAlivePeriod = 45 * time.Second
  16. var ErrNotLocal = errors.New("the source address is not from local machine.")
  17. type localIPCacheEntry struct {
  18. addrs []net.Addr
  19. lastUpdate time.Time
  20. }
  21. var localIPCache = atomic.Pointer[localIPCacheEntry]{}
  22. func IsLocal(ip net.IP) (bool, error) {
  23. var addrs []net.Addr
  24. if entry := localIPCache.Load(); entry == nil || time.Since(entry.lastUpdate) > time.Minute {
  25. var err error
  26. addrs, err = net.InterfaceAddrs()
  27. if err != nil {
  28. return false, err
  29. }
  30. localIPCache.Store(&localIPCacheEntry{
  31. addrs: addrs,
  32. lastUpdate: time.Now(),
  33. })
  34. } else {
  35. addrs = entry.addrs
  36. }
  37. for _, addr := range addrs {
  38. if ipnet, ok := addr.(*net.IPNet); ok {
  39. if ipnet.IP.Equal(ip) {
  40. return true, nil
  41. }
  42. }
  43. }
  44. return false, nil
  45. }