rawmsg.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package dns
  2. // These raw* functions do not use reflection, they directly set the values
  3. // in the buffer. There are faster than their reflection counterparts.
  4. // RawSetId sets the message id in buf.
  5. func rawSetId(msg []byte, i uint16) bool {
  6. if len(msg) < 2 {
  7. return false
  8. }
  9. msg[0], msg[1] = packUint16(i)
  10. return true
  11. }
  12. // rawSetQuestionLen sets the length of the question section.
  13. func rawSetQuestionLen(msg []byte, i uint16) bool {
  14. if len(msg) < 6 {
  15. return false
  16. }
  17. msg[4], msg[5] = packUint16(i)
  18. return true
  19. }
  20. // rawSetAnswerLen sets the length of the answer section.
  21. func rawSetAnswerLen(msg []byte, i uint16) bool {
  22. if len(msg) < 8 {
  23. return false
  24. }
  25. msg[6], msg[7] = packUint16(i)
  26. return true
  27. }
  28. // rawSetsNsLen sets the length of the authority section.
  29. func rawSetNsLen(msg []byte, i uint16) bool {
  30. if len(msg) < 10 {
  31. return false
  32. }
  33. msg[8], msg[9] = packUint16(i)
  34. return true
  35. }
  36. // rawSetExtraLen sets the length of the additional section.
  37. func rawSetExtraLen(msg []byte, i uint16) bool {
  38. if len(msg) < 12 {
  39. return false
  40. }
  41. msg[10], msg[11] = packUint16(i)
  42. return true
  43. }
  44. // rawSetRdlength sets the rdlength in the header of
  45. // the RR. The offset 'off' must be positioned at the
  46. // start of the header of the RR, 'end' must be the
  47. // end of the RR.
  48. func rawSetRdlength(msg []byte, off, end int) bool {
  49. l := len(msg)
  50. Loop:
  51. for {
  52. if off+1 > l {
  53. return false
  54. }
  55. c := int(msg[off])
  56. off++
  57. switch c & 0xC0 {
  58. case 0x00:
  59. if c == 0x00 {
  60. // End of the domainname
  61. break Loop
  62. }
  63. if off+c > l {
  64. return false
  65. }
  66. off += c
  67. case 0xC0:
  68. // pointer, next byte included, ends domainname
  69. off++
  70. break Loop
  71. }
  72. }
  73. // The domainname has been seen, we at the start of the fixed part in the header.
  74. // Type is 2 bytes, class is 2 bytes, ttl 4 and then 2 bytes for the length.
  75. off += 2 + 2 + 4
  76. if off+2 > l {
  77. return false
  78. }
  79. //off+1 is the end of the header, 'end' is the end of the rr
  80. //so 'end' - 'off+2' is the length of the rdata
  81. rdatalen := end - (off + 2)
  82. if rdatalen > 0xFFFF {
  83. return false
  84. }
  85. msg[off], msg[off+1] = packUint16(uint16(rdatalen))
  86. return true
  87. }