Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
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.

dns_resolver.go 1.7KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package network
  2. import (
  3. "net/http"
  4. "sync"
  5. "time"
  6. doh "github.com/babolivier/go-doh-client"
  7. )
  8. const dnsResolverKeepTime = 10 * time.Minute
  9. type dnsResolverCacheEntry struct {
  10. ips []string
  11. createdAt time.Time
  12. }
  13. func (c dnsResolverCacheEntry) Ok() bool {
  14. return time.Since(c.createdAt) < dnsResolverKeepTime
  15. }
  16. type dnsResolver struct {
  17. resolver doh.Resolver
  18. cache map[string]dnsResolverCacheEntry
  19. cacheMutex sync.RWMutex
  20. }
  21. func (d *dnsResolver) LookupA(hostname string) []string {
  22. key := "\x00" + hostname
  23. d.cacheMutex.RLock()
  24. entry, ok := d.cache[key]
  25. d.cacheMutex.RUnlock()
  26. if ok && entry.Ok() {
  27. return entry.ips
  28. }
  29. var ips []string
  30. if recs, _, err := d.resolver.LookupA(hostname); err == nil {
  31. for _, v := range recs {
  32. ips = append(ips, v.IP4)
  33. }
  34. d.cacheMutex.Lock()
  35. d.cache[key] = dnsResolverCacheEntry{
  36. ips: ips,
  37. createdAt: time.Now(),
  38. }
  39. d.cacheMutex.Unlock()
  40. }
  41. return ips
  42. }
  43. func (d *dnsResolver) LookupAAAA(hostname string) []string {
  44. key := "\x01" + hostname
  45. d.cacheMutex.RLock()
  46. entry, ok := d.cache[key]
  47. d.cacheMutex.RUnlock()
  48. if ok && entry.Ok() {
  49. return entry.ips
  50. }
  51. var ips []string
  52. if recs, _, err := d.resolver.LookupAAAA(hostname); err == nil {
  53. for _, v := range recs {
  54. ips = append(ips, v.IP6)
  55. }
  56. d.cacheMutex.Lock()
  57. d.cache[key] = dnsResolverCacheEntry{
  58. ips: ips,
  59. createdAt: time.Now(),
  60. }
  61. d.cacheMutex.Unlock()
  62. }
  63. return ips
  64. }
  65. func newDNSResolver(hostname string, httpClient *http.Client) *dnsResolver {
  66. return &dnsResolver{
  67. resolver: doh.Resolver{
  68. Host: hostname,
  69. Class: doh.IN,
  70. HTTPClient: httpClient,
  71. },
  72. cache: map[string]dnsResolverCacheEntry{},
  73. }
  74. }