parseMessageForName parses a DNS message, checks validity, looks for answers regarding name
( message []byte, name string, questionType dnsmessage.Type )
| 91 | |
| 92 | // parseMessageForName parses a DNS message, checks validity, looks for answers regarding name |
| 93 | func ( d *Resolver ) parseMessageForNameAndType( message []byte, name string, questionType dnsmessage.Type ) ( ip net.IP , err error ) { |
| 94 | msg := dnsmessage.Message{} |
| 95 | if err = msg.Unpack( message ); err != nil { return } |
| 96 | if !msg.Header.Response { err = errors.New( "not a response message" ); return } |
| 97 | if msg.Header.OpCode != 0 { err = errors.New( "not a query response" ); return } |
| 98 | if msg.Header.RCode != dnsmessage.RCodeSuccess { err = errors.New( "bad response code " + msg.Header.RCode.String() ); return } |
| 99 | |
| 100 | valid := false // Check the questions section, it must contain "name" |
| 101 | for _, question := range msg.Questions { if question.Name.String() == name { valid = true; break } } |
| 102 | if !valid { err = errors.New( "questions section does not contain" + name ); return } |
| 103 | |
| 104 | for _, answer := range msg.Answers { |
| 105 | if answer.Header.Name.String() != name { err = errors.New( "answer for an invalid name" ); return } |
| 106 | if answer.Header.Class != dnsmessage.ClassINET { err = errors.New( "invalid answer class" ); return } |
| 107 | if answer.Header.Type != questionType { err = errors.New( "query and answer type mismatch" ); return } |
| 108 | if answer.Header.Type == dnsmessage.TypeA { if aResource, ok := answer.Body.(*dnsmessage.AResource); ok { ip = aResource.A[:] } } |
| 109 | if answer.Header.Type == dnsmessage.TypeAAAA { if aaaaResource, ok := answer.Body.(*dnsmessage.AAAAResource); ok { ip = aaaaResource.AAAA[:] } } |
| 110 | } |
| 111 | return |
| 112 | } |
| 113 | |
| 114 | // postDnsMessage issues a HTTP POST request with appropriate headers. When endpoint contains an address a direct connection, without DNS resolution, will be made |
| 115 | func ( d *Resolver ) postDnsMessage( ctx context.Context, url string, endpoint string, message []byte ) ( responseBody []byte, err error ) { |