@@ -979,4 +979,64 @@ mod tests {
979979 assert_eq ! ( response. answers. len( ) , 1 ) ;
980980 assert_eq ! ( response. answers[ 0 ] . ttl, custom_ttl) ;
981981 }
982+
983+ /// Test that `encode_name` correctly encodes various domain names into DNS wire format
984+ #[ test]
985+ fn encode_name_binary_correctness ( ) {
986+ // Simple domain
987+ let mut buf = Vec :: new ( ) ;
988+ encode_name ( & mut buf, "mesh.nordsec.com" ) . unwrap ( ) ;
989+ // Expected: [4]m e s h [7]n o r d s e c [3]c o m [0]
990+ let expected = [
991+ 4u8 , b'm' , b'e' , b's' , b'h' , 7 , b'n' , b'o' , b'r' , b'd' , b's' , b'e' , b'c' , 3 , b'c' ,
992+ b'o' , b'm' , 0 ,
993+ ] ;
994+ assert_eq ! ( buf, expected) ;
995+
996+ // FQDN with trailing dot
997+ let mut buf = Vec :: new ( ) ;
998+ encode_name ( & mut buf, "mesh.nordsec.com." ) . unwrap ( ) ;
999+ assert_eq ! ( buf, expected) ;
1000+
1001+ // Single label
1002+ let mut buf = Vec :: new ( ) ;
1003+ encode_name ( & mut buf, "foo" ) . unwrap ( ) ;
1004+ let expected = [ 3u8 , b'f' , b'o' , b'o' , 0 ] ;
1005+ assert_eq ! ( buf, expected) ;
1006+
1007+ // Max label size (63 'a's)
1008+ let label = "a" . repeat ( SOA_MAX_LABEL_SIZE ) ;
1009+ let name = format ! ( "{}.nord" , label) ;
1010+ let mut buf = Vec :: new ( ) ;
1011+ encode_name ( & mut buf, & name) . unwrap ( ) ;
1012+ let mut expected = vec ! [ SOA_MAX_LABEL_SIZE as u8 ] ;
1013+ expected. extend ( label. as_bytes ( ) ) ;
1014+ expected. extend ( [ 4 , b'n' , b'o' , b'r' , b'd' , 0 ] ) ;
1015+ assert_eq ! ( buf, expected) ;
1016+
1017+ // Max name size (254 bytes: 3x63 + 1x61 chars, 4 length bytes, 1 zero)
1018+ let label63 = "b" . repeat ( 63 ) ;
1019+ let label61 = "c" . repeat ( 61 ) ;
1020+ let name = format ! ( "{}.{}.{}.{}" , label63, label63, label63, label61) ;
1021+ // Calculate length: (63+1)*3 + (61+1) + 1 = 192 + 62 + 1 = 255
1022+ // But SOA_MAX_NAME_SIZE = 254, so we need 3x63 + 61 = 250 characters, 4 length bytes, 1 zero = 255
1023+ // But encode_name checks .len() > SOA_MAX_NAME_SIZE, so 254 is allowed
1024+ let mut buf = Vec :: new ( ) ;
1025+ encode_name ( & mut buf, & name) . unwrap ( ) ;
1026+ let mut expected = Vec :: new ( ) ;
1027+ for _ in 0 ..3 {
1028+ expected. push ( 63 ) ;
1029+ expected. extend ( label63. as_bytes ( ) ) ;
1030+ }
1031+ expected. push ( 61 ) ;
1032+ expected. extend ( label61. as_bytes ( ) ) ;
1033+ expected. push ( 0 ) ;
1034+ assert_eq ! ( buf, expected) ;
1035+
1036+ // Leading/trailing whitespace should be trimmed from labels
1037+ let mut buf = Vec :: new ( ) ;
1038+ encode_name ( & mut buf, " foo . bar " ) . unwrap ( ) ;
1039+ let expected = [ 3 , b'f' , b'o' , b'o' , 3 , b'b' , b'a' , b'r' , 0 ] ;
1040+ assert_eq ! ( buf, expected) ;
1041+ }
9821042}
0 commit comments