transport_https.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package dns
  2. import (
  3. "bytes"
  4. "context"
  5. "net"
  6. "net/http"
  7. "net/netip"
  8. "os"
  9. "github.com/sagernet/sing-box/adapter"
  10. C "github.com/sagernet/sing-box/constant"
  11. "github.com/sagernet/sing/common"
  12. "github.com/sagernet/sing/common/buf"
  13. M "github.com/sagernet/sing/common/metadata"
  14. N "github.com/sagernet/sing/common/network"
  15. "golang.org/x/net/dns/dnsmessage"
  16. )
  17. const dnsMimeType = "application/dns-message"
  18. var _ adapter.DNSTransport = (*HTTPSTransport)(nil)
  19. type HTTPSTransport struct {
  20. destination string
  21. transport *http.Transport
  22. }
  23. func NewHTTPSTransport(dialer N.Dialer, destination string) *HTTPSTransport {
  24. return &HTTPSTransport{
  25. destination: destination,
  26. transport: &http.Transport{
  27. ForceAttemptHTTP2: true,
  28. DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
  29. return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
  30. },
  31. },
  32. }
  33. }
  34. func (t *HTTPSTransport) Start() error {
  35. return nil
  36. }
  37. func (t *HTTPSTransport) Close() error {
  38. t.transport.CloseIdleConnections()
  39. return nil
  40. }
  41. func (t *HTTPSTransport) Raw() bool {
  42. return true
  43. }
  44. func (t *HTTPSTransport) Exchange(ctx context.Context, message *dnsmessage.Message) (*dnsmessage.Message, error) {
  45. message.ID = 0
  46. _buffer := buf.StackNewSize(1024)
  47. defer common.KeepAlive(_buffer)
  48. buffer := common.Dup(_buffer)
  49. defer buffer.Release()
  50. rawMessage, err := message.AppendPack(buffer.Index(0))
  51. if err != nil {
  52. return nil, err
  53. }
  54. buffer.Truncate(len(rawMessage))
  55. request, err := http.NewRequestWithContext(ctx, http.MethodPost, t.destination, bytes.NewReader(buffer.Bytes()))
  56. if err != nil {
  57. return nil, err
  58. }
  59. request.Header.Set("content-type", dnsMimeType)
  60. request.Header.Set("accept", dnsMimeType)
  61. client := &http.Client{Transport: t.transport}
  62. response, err := client.Do(request)
  63. if err != nil {
  64. return nil, err
  65. }
  66. defer response.Body.Close()
  67. buffer.FullReset()
  68. _, err = buffer.ReadAllFrom(response.Body)
  69. if err != nil {
  70. return nil, err
  71. }
  72. var responseMessage dnsmessage.Message
  73. err = responseMessage.Unpack(buffer.Bytes())
  74. if err != nil {
  75. return nil, err
  76. }
  77. return &responseMessage, nil
  78. }
  79. func (t *HTTPSTransport) Lookup(ctx context.Context, domain string, strategy C.DomainStrategy) ([]netip.Addr, error) {
  80. return nil, os.ErrInvalid
  81. }