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
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

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