dns.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package dns
  2. import (
  3. "context"
  4. "encoding/binary"
  5. "github.com/miekg/dns"
  6. "github.com/xtls/xray-core/common"
  7. "github.com/xtls/xray-core/common/dice"
  8. )
  9. type DNS struct {
  10. header []byte
  11. }
  12. func (d DNS) Size() int32 {
  13. return int32(len(d.header))
  14. }
  15. // Serialize implements PacketHeader.
  16. func (d DNS) Serialize(b []byte) {
  17. copy(b, d.header)
  18. binary.BigEndian.PutUint16(b[0:], dice.RollUint16()) // random transaction ID
  19. }
  20. // NewDNS returns a new DNS instance based on given config.
  21. func NewDNS(ctx context.Context, config interface{}) (interface{}, error) {
  22. var header []byte
  23. header = binary.BigEndian.AppendUint16(header, 0x0000) // Transaction ID
  24. header = binary.BigEndian.AppendUint16(header, 0x0100) // Flags: Standard query
  25. header = binary.BigEndian.AppendUint16(header, 0x0001) // Questions
  26. header = binary.BigEndian.AppendUint16(header, 0x0000) // Answer RRs
  27. header = binary.BigEndian.AppendUint16(header, 0x0000) // Authority RRs
  28. header = binary.BigEndian.AppendUint16(header, 0x0000) // Additional RRs
  29. buf := make([]byte, 0x100)
  30. off1, err := dns.PackDomainName(dns.Fqdn(config.(*Config).Domain), buf, 0, nil, false)
  31. if err != nil {
  32. return nil, err
  33. }
  34. header = append(header, buf[:off1]...)
  35. header = binary.BigEndian.AppendUint16(header, 0x0001) // Type: A
  36. header = binary.BigEndian.AppendUint16(header, 0x0001) // Class: IN
  37. return DNS{
  38. header: header,
  39. }, nil
  40. }
  41. func init() {
  42. common.Must(common.RegisterConfig((*Config)(nil), NewDNS))
  43. }