dns.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. package sniff
  2. import (
  3. "context"
  4. "encoding/binary"
  5. "io"
  6. "os"
  7. "time"
  8. "github.com/sagernet/sing-box/adapter"
  9. C "github.com/sagernet/sing-box/constant"
  10. "github.com/sagernet/sing/common"
  11. "github.com/sagernet/sing/common/buf"
  12. "github.com/sagernet/sing/common/task"
  13. mDNS "github.com/miekg/dns"
  14. )
  15. func StreamDomainNameQuery(readCtx context.Context, reader io.Reader) (*adapter.InboundContext, error) {
  16. var length uint16
  17. err := binary.Read(reader, binary.BigEndian, &length)
  18. if err != nil {
  19. return nil, err
  20. }
  21. if length == 0 {
  22. return nil, os.ErrInvalid
  23. }
  24. _buffer := buf.StackNewSize(int(length))
  25. defer common.KeepAlive(_buffer)
  26. buffer := common.Dup(_buffer)
  27. defer buffer.Release()
  28. readCtx, cancel := context.WithTimeout(readCtx, time.Millisecond*100)
  29. var readTask task.Group
  30. readTask.Append0(func(ctx context.Context) error {
  31. return common.Error(buffer.ReadFullFrom(reader, buffer.FreeLen()))
  32. })
  33. err = readTask.Run(readCtx)
  34. cancel()
  35. if err != nil {
  36. return nil, err
  37. }
  38. return DomainNameQuery(readCtx, buffer.Bytes())
  39. }
  40. func DomainNameQuery(ctx context.Context, packet []byte) (*adapter.InboundContext, error) {
  41. var msg mDNS.Msg
  42. err := msg.Unpack(packet)
  43. if err != nil {
  44. return nil, err
  45. }
  46. return &adapter.InboundContext{Protocol: C.ProtocolDNS}, nil
  47. }