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

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package network
  2. import (
  3. "net/http"
  4. "time"
  5. doh "github.com/babolivier/go-doh-client"
  6. "github.com/dgraph-io/ristretto"
  7. )
  8. const (
  9. dnsResolverSize = 1024 * 1024 // 1mb
  10. dnsResolverKeepTime = 10 * time.Minute
  11. )
  12. type dnsResolver struct {
  13. resolver doh.Resolver
  14. cache *ristretto.Cache
  15. }
  16. func (d dnsResolver) LookupA(hostname string) []string {
  17. key := "\x00." + hostname
  18. if value, ok := d.cache.Get(key); ok {
  19. return value.([]string)
  20. }
  21. var ips []string
  22. if recs, _, err := d.resolver.LookupA(hostname); err == nil {
  23. for _, v := range recs {
  24. ips = append(ips, v.IP4)
  25. }
  26. d.cache.SetWithTTL(key, ips, 0, dnsResolverKeepTime)
  27. }
  28. return ips
  29. }
  30. func (d dnsResolver) LookupAAAA(hostname string) []string {
  31. key := "\x01." + hostname
  32. if value, ok := d.cache.Get(key); ok {
  33. return value.([]string)
  34. }
  35. var ips []string
  36. if recs, _, err := d.resolver.LookupAAAA(hostname); err == nil {
  37. for _, v := range recs {
  38. ips = append(ips, v.IP6)
  39. }
  40. d.cache.SetWithTTL(key, ips, 0, dnsResolverKeepTime)
  41. }
  42. return ips
  43. }
  44. func newDNSResolver(hostname string, httpClient *http.Client) dnsResolver {
  45. cache, err := ristretto.NewCache(&ristretto.Config{
  46. NumCounters: 10 * dnsResolverSize, // nolint: gomnd // taken from official doc as a best practice value
  47. MaxCost: dnsResolverSize,
  48. BufferItems: 64, // nolint: gomnd // taken from official doc as a best practice value
  49. Cost: func(value interface{}) int64 {
  50. var cost int64
  51. for _, v := range value.([]string) {
  52. cost += int64(len([]byte(v)))
  53. }
  54. return cost
  55. },
  56. })
  57. if err != nil {
  58. panic(err)
  59. }
  60. return dnsResolver{
  61. resolver: doh.Resolver{
  62. Host: hostname,
  63. Class: doh.IN,
  64. HTTPClient: httpClient,
  65. },
  66. cache: cache,
  67. }
  68. }