Recently, our DNS server has received some abnormal domain name requests. From the access log, we can see that many domain names are returned with the format error code, but the domain name in the access log looks normal, why is the ERROR code of format error returned?
After a series of troubleshooting, the direct cause is found.
The problem is that the request domain name of some DNS message packets we receive contains a character with a value greater than 127. The following is the hexadecimal data of one of the label of the illegal domain name:
0x09, 0x74, 0x61, 0x6f, 0x62, 0xe1, 0x6f, 0x63, 0x64, 0x6e.
It can be seen that there is a 0xe1 in the middle, and its value is 225, which is a non-printable character on the terminal. The domain name that contains such a character will be considered invalid, so a FORMATERROR is returned. Why can't this character be seen in the access log? Let's take a look at the experiment:
# Include <stdio. h> int main () {unsigned char s [] = {0x74, 0x61, 0x6f, 0x62, 0xe1, 0x6f, 0x63, 0x64, 0x6e, '\ 0'}; printf ("% s \ n", s); return 0 ;}
What will the above code print? Theoretically, it prints "taob? Ocdn ", where "? "It is the 0xe1 output on the terminal, but its output is:
Taobn
It can be seen that at the time of output, 0xe1 and the subsequent three characters are not output to the terminal. So what we see in the access log is a legal domain name ....
Here is a detailed discussion of this issue.
For non-printable ASCII codes, if they are output to the terminal, their behavior is related to the character encoding of the terminal. Therefore, the safest way is to perform special processing on non-printable ASCII codes, because if you output them to the terminal, you may not see the actual content.
C outputs more than 127 accios