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

     1  package dns
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"net/http"
     8  
     9  	"github.com/Asutorufa/yuhaiin/pkg/net/nat"
    10  	"github.com/Asutorufa/yuhaiin/pkg/net/netapi"
    11  	"github.com/Asutorufa/yuhaiin/pkg/protos/config/dns"
    12  	"github.com/Asutorufa/yuhaiin/pkg/utils/pool"
    13  	"github.com/Asutorufa/yuhaiin/pkg/utils/relay"
    14  	"github.com/quic-go/quic-go/http3"
    15  )
    16  
    17  func init() {
    18  	Register(dns.Type_doh3, NewDoH3)
    19  }
    20  
    21  func NewDoH3(config Config) (netapi.Resolver, error) {
    22  	tr := &http3.RoundTripper{}
    23  
    24  	req, err := getRequest(config.Host)
    25  	if err != nil {
    26  		return nil, fmt.Errorf("get request failed: %w", err)
    27  	}
    28  
    29  	return NewClient(config, func(ctx context.Context, b []byte) (*pool.Bytes, error) {
    30  		resp, err := tr.RoundTrip(req.Clone(ctx, b))
    31  		if err != nil {
    32  			return nil, fmt.Errorf("doh post failed: %w", err)
    33  		}
    34  
    35  		defer resp.Body.Close()
    36  		if resp.StatusCode != http.StatusOK {
    37  			_, _ = relay.Copy(io.Discard, resp.Body) // from v2fly
    38  			return nil, fmt.Errorf("doh post return code: %d", resp.StatusCode)
    39  		}
    40  
    41  		buf := pool.GetBytesBuffer(nat.MaxSegmentSize)
    42  
    43  		_, err = buf.ReadFull(resp.Body)
    44  		if err != nil {
    45  			buf.Free()
    46  			return nil, fmt.Errorf("doh3 post failed: %w", err)
    47  		}
    48  
    49  		return buf, nil
    50  	}), nil
    51  }