github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/dns/dohjson.go (about)

     1  package dns
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"io"
     7  	"net"
     8  	"net/http"
     9  )
    10  
    11  /*
    12  {
    13    "Status": 0,
    14    "TC": false,
    15    "RD": true,
    16    "RA": true,
    17    "AD": false,
    18    "CD": false,
    19    "Question": [
    20      {
    21        "name": "google.com.",
    22        "type": 1
    23      }
    24    ],
    25    "Answer": [
    26      {
    27        "name": "google.com.",
    28        "type": 1,
    29        "TTL": 252,
    30        "Expires": "Fri, 14 Feb 2020 09:53:44 UTC",
    31        "data": "172.217.31.238"
    32      }
    33    ],
    34    "edns_client_subnet": "110.166.218.0/0"
    35  }
    36  
    37  {
    38    "Status": 0,
    39    "TC": false,
    40    "RD": true,
    41    "RA": true,
    42    "AD": false,
    43    "CD": false,
    44    "Question": [
    45      {
    46        "name": "baidu.com.",
    47        "type": 1
    48      }
    49    ],
    50    "Answer": [
    51      {
    52        "name": "baidu.com.",
    53        "type": 1,
    54        "TTL": 518,
    55        "Expires": "Fri, 14 Feb 2020 09:59:03 UTC",
    56        "data": "39.156.69.79"
    57      },
    58      {
    59        "name": "baidu.com.",
    60        "type": 1,
    61        "TTL": 518,
    62        "Expires": "Fri, 14 Feb 2020 09:59:03 UTC",
    63        "data": "220.181.38.148"
    64      }
    65    ],
    66    "edns_client_subnet": "110.166.218.0/0"
    67  }
    68  */
    69  
    70  type DOHJson struct {
    71  	Status           int        `json:"status"`
    72  	TC               bool       `json:"TC"`
    73  	RD               bool       `json:"RD"`
    74  	RA               bool       `json:"RA"`
    75  	AD               bool       `json:"AD"`
    76  	CD               bool       `json:"CD"`
    77  	Question         []Question `json:"Question"`
    78  	Answer           []Answer   `json:"Answer"`
    79  	EdnsClientSubnet string     `json:"edns_client_subnet"`
    80  }
    81  type Question struct {
    82  	Name string `json:"name"`
    83  	Type int    `json:"type"`
    84  }
    85  type Answer struct {
    86  	Name    string `json:"name"`
    87  	Type    int    `json:"type"`
    88  	TTL     int    `json:"TTL"`
    89  	Expires string `json:"Expires"`
    90  	Data    string `json:"data"`
    91  }
    92  
    93  func DOHJsonAPI(DNSServer, domain string, proxy func(ctx context.Context, network, addr string) (net.Conn, error)) (DNS []net.IP, err error) {
    94  	doh := &DOHJson{}
    95  	var res *http.Response
    96  	if proxy != nil {
    97  		tr := http.Transport{
    98  			DialContext: proxy,
    99  		}
   100  		newClient := &http.Client{Transport: &tr}
   101  		res, err = newClient.Get(DNSServer + "?ct=application/dns-json&name=" + domain + "&type=A")
   102  	} else {
   103  		res, err = http.Get(DNSServer + "?ct=application/dns-json&name=" + domain + "&type=A")
   104  	}
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  	body, err := io.ReadAll(res.Body)
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  	err = json.Unmarshal(body, doh)
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  	if doh.Status != 0 {
   117  		return nil, err
   118  	}
   119  	for _, x := range doh.Answer {
   120  		if net.ParseIP(x.Data) != nil {
   121  			DNS = append(DNS, net.ParseIP(x.Data))
   122  		}
   123  	}
   124  	return DNS, nil
   125  }