4 /* RFC 1035 message compression */
6 /* label start offsets of a compressed domain name s */
7 static int getoffs(short *offs
, const unsigned char *base
, const unsigned char *s
)
12 if ((*s
& 0xc0) != 0xc0) return 0;
13 s
= base
+ ((s
[0]&0x3f)<<8 | s
[1]);
16 if (s
-base
>= 0x4000) return 0;
22 /* label lengths of an ascii domain name s */
23 static int getlens(unsigned char *lens
, const char *s
, int l
)
27 for (; j
<l
&& s
[j
]!='.'; j
++);
28 if (j
-k
-1u > 62) return 0;
35 /* longest suffix match of an ascii domain with a compressed domain name dn */
36 static int match(int *offset
, const unsigned char *base
, const unsigned char *dn
,
37 const char *end
, const unsigned char *lens
, int nlen
)
41 int noff
= getoffs(offs
, base
, dn
);
47 if (l
!= base
[o
] || memcmp(base
+o
+1, end
, l
))
52 if (!nlen
|| !noff
) return m
;
57 int dn_comp(const char *src
, unsigned char *dst
, int space
, unsigned char **dnptrs
, unsigned char **lastdnptr
)
59 int i
, j
, n
, m
=0, offset
, bestlen
=0, bestoff
;
60 unsigned char lens
[127];
63 size_t l
= strnlen(src
, 255);
64 if (l
&& src
[l
-1] == '.') l
--;
65 if (l
>253 || space
<=0) return -1;
71 n
= getlens(lens
, src
, l
);
75 if (p
&& *p
) for (p
++; *p
; p
++) {
76 m
= match(&offset
, *dnptrs
, *p
, end
, lens
, n
);
85 /* encode unmatched part */
86 if (space
< l
-bestlen
+2+(bestlen
-1 < l
-1)) return -1;
87 memcpy(dst
+1, src
, l
-bestlen
);
88 for (i
=j
=0; i
<l
-bestlen
; i
+=lens
[j
++]+1)
93 dst
[i
++] = 0xc0 | bestoff
>>8;
98 /* save dst pointer */
99 if (i
>2 && lastdnptr
&& dnptrs
&& *dnptrs
) {
101 if (p
+1 < lastdnptr
) {