PageRenderTime 100ms CodeModel.GetById 34ms RepoModel.GetById 1ms app.codeStats 0ms

/util/data/dname.c

https://github.com/RS-liuyang/rsdns
C | 781 lines | 623 code | 45 blank | 113 comment | 146 complexity | ea3b70752dee8f334d46d00dd6ba7b65 MD5 | raw file
  1. /*
  2. * util/data/dname.h - domain name handling
  3. *
  4. * Copyright (c) 2007, NLnet Labs. All rights reserved.
  5. *
  6. * This software is open source.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. *
  15. * Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * Neither the name of the NLNET LABS nor the names of its contributors may
  20. * be used to endorse or promote products derived from this software without
  21. * specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  24. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  25. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  26. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. /**
  36. * \file
  37. *
  38. * This file contains domain name handling functions.
  39. */
  40. #include "config.h"
  41. #include <ctype.h>
  42. #include "util/data/dname.h"
  43. #include "util/data/msgparse.h"
  44. #include "util/log.h"
  45. #include "util/storage/lookup3.h"
  46. /* determine length of a dname in buffer, no compression pointers allowed */
  47. size_t
  48. query_dname_len(ldns_buffer* query)
  49. {
  50. size_t len = 0;
  51. size_t labellen;
  52. while(1) {
  53. if(ldns_buffer_remaining(query) < 1)
  54. return 0; /* parse error, need label len */
  55. labellen = ldns_buffer_read_u8(query);
  56. if(labellen&0xc0)
  57. return 0; /* no compression allowed in queries */
  58. len += labellen + 1;
  59. if(len > LDNS_MAX_DOMAINLEN)
  60. return 0; /* too long */
  61. if(labellen == 0)
  62. return len;
  63. if(ldns_buffer_remaining(query) < labellen)
  64. return 0; /* parse error, need content */
  65. ldns_buffer_skip(query, (ssize_t)labellen);
  66. }
  67. }
  68. size_t
  69. dname_valid(uint8_t* dname, size_t maxlen)
  70. {
  71. size_t len = 0;
  72. size_t labellen;
  73. labellen = *dname++;
  74. while(labellen) {
  75. if(labellen&0xc0)
  76. return 0; /* no compression ptrs allowed */
  77. len += labellen + 1;
  78. if(len >= LDNS_MAX_DOMAINLEN)
  79. return 0; /* too long */
  80. if(len > maxlen)
  81. return 0; /* does not fit in memory allocation */
  82. dname += labellen;
  83. labellen = *dname++;
  84. }
  85. len += 1;
  86. if(len > maxlen)
  87. return 0; /* does not fit in memory allocation */
  88. return len;
  89. }
  90. /** compare uncompressed, noncanonical, registers are hints for speed */
  91. int
  92. query_dname_compare(register uint8_t* d1, register uint8_t* d2)
  93. {
  94. register uint8_t lab1, lab2;
  95. log_assert(d1 && d2);
  96. lab1 = *d1++;
  97. lab2 = *d2++;
  98. while( lab1 != 0 || lab2 != 0 ) {
  99. /* compare label length */
  100. /* if one dname ends, it has labellength 0 */
  101. if(lab1 != lab2) {
  102. if(lab1 < lab2)
  103. return -1;
  104. return 1;
  105. }
  106. log_assert(lab1 == lab2 && lab1 != 0);
  107. /* compare lowercased labels. */
  108. while(lab1--) {
  109. /* compare bytes first for speed */
  110. if(*d1 != *d2 &&
  111. tolower((int)*d1) != tolower((int)*d2)) {
  112. if(tolower((int)*d1) < tolower((int)*d2))
  113. return -1;
  114. return 1;
  115. }
  116. d1++;
  117. d2++;
  118. }
  119. /* next pair of labels. */
  120. lab1 = *d1++;
  121. lab2 = *d2++;
  122. }
  123. return 0;
  124. }
  125. void
  126. query_dname_tolower(uint8_t* dname)
  127. {
  128. /* the dname is stored uncompressed */
  129. uint8_t labellen;
  130. labellen = *dname;
  131. while(labellen) {
  132. dname++;
  133. while(labellen--) {
  134. *dname = (uint8_t)tolower((int)*dname);
  135. dname++;
  136. }
  137. labellen = *dname;
  138. }
  139. }
  140. void
  141. pkt_dname_tolower(ldns_buffer* pkt, uint8_t* dname)
  142. {
  143. uint8_t lablen;
  144. int count = 0;
  145. if(dname >= ldns_buffer_end(pkt))
  146. return;
  147. lablen = *dname++;
  148. while(lablen) {
  149. if(LABEL_IS_PTR(lablen)) {
  150. if((size_t)PTR_OFFSET(lablen, *dname)
  151. >= ldns_buffer_limit(pkt))
  152. return;
  153. dname = ldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
  154. lablen = *dname++;
  155. if(count++ > MAX_COMPRESS_PTRS)
  156. return;
  157. continue;
  158. }
  159. if(dname+lablen >= ldns_buffer_end(pkt))
  160. return;
  161. while(lablen--) {
  162. *dname = (uint8_t)tolower((int)*dname);
  163. dname++;
  164. }
  165. if(dname >= ldns_buffer_end(pkt))
  166. return;
  167. lablen = *dname++;
  168. }
  169. }
  170. size_t
  171. pkt_dname_len(ldns_buffer* pkt)
  172. {
  173. size_t len = 0;
  174. int ptrcount = 0;
  175. uint8_t labellen;
  176. size_t endpos = 0;
  177. /* read dname and determine length */
  178. /* check compression pointers, loops, out of bounds */
  179. while(1) {
  180. /* read next label */
  181. if(ldns_buffer_remaining(pkt) < 1)
  182. return 0;
  183. labellen = ldns_buffer_read_u8(pkt);
  184. if(LABEL_IS_PTR(labellen)) {
  185. /* compression ptr */
  186. uint16_t ptr;
  187. if(ldns_buffer_remaining(pkt) < 1)
  188. return 0;
  189. ptr = PTR_OFFSET(labellen, ldns_buffer_read_u8(pkt));
  190. if(ptrcount++ > MAX_COMPRESS_PTRS)
  191. return 0; /* loop! */
  192. if(ldns_buffer_limit(pkt) <= ptr)
  193. return 0; /* out of bounds! */
  194. if(!endpos)
  195. endpos = ldns_buffer_position(pkt);
  196. ldns_buffer_set_position(pkt, ptr);
  197. } else {
  198. /* label contents */
  199. if(labellen > 0x3f)
  200. return 0; /* label too long */
  201. len += 1 + labellen;
  202. if(len > LDNS_MAX_DOMAINLEN)
  203. return 0;
  204. if(labellen == 0) {
  205. /* end of dname */
  206. break;
  207. }
  208. if(ldns_buffer_remaining(pkt) < labellen)
  209. return 0;
  210. ldns_buffer_skip(pkt, (ssize_t)labellen);
  211. }
  212. }
  213. if(endpos)
  214. ldns_buffer_set_position(pkt, endpos);
  215. return len;
  216. }
  217. int
  218. dname_pkt_compare(ldns_buffer* pkt, uint8_t* d1, uint8_t* d2)
  219. {
  220. uint8_t len1, len2;
  221. log_assert(pkt && d1 && d2);
  222. len1 = *d1++;
  223. len2 = *d2++;
  224. while( len1 != 0 || len2 != 0 ) {
  225. /* resolve ptrs */
  226. if(LABEL_IS_PTR(len1)) {
  227. d1 = ldns_buffer_at(pkt, PTR_OFFSET(len1, *d1));
  228. len1 = *d1++;
  229. continue;
  230. }
  231. if(LABEL_IS_PTR(len2)) {
  232. d2 = ldns_buffer_at(pkt, PTR_OFFSET(len2, *d2));
  233. len2 = *d2++;
  234. continue;
  235. }
  236. /* check label length */
  237. log_assert(len1 <= LDNS_MAX_LABELLEN);
  238. log_assert(len2 <= LDNS_MAX_LABELLEN);
  239. if(len1 != len2) {
  240. if(len1 < len2) return -1;
  241. return 1;
  242. }
  243. log_assert(len1 == len2 && len1 != 0);
  244. /* compare labels */
  245. while(len1--) {
  246. if(tolower((int)*d1++) != tolower((int)*d2++)) {
  247. if(tolower((int)d1[-1]) < tolower((int)d2[-1]))
  248. return -1;
  249. return 1;
  250. }
  251. }
  252. len1 = *d1++;
  253. len2 = *d2++;
  254. }
  255. return 0;
  256. }
  257. hashvalue_t
  258. dname_query_hash(uint8_t* dname, hashvalue_t h)
  259. {
  260. uint8_t labuf[LDNS_MAX_LABELLEN+1];
  261. uint8_t lablen;
  262. int i;
  263. /* preserve case of query, make hash label by label */
  264. lablen = *dname++;
  265. while(lablen) {
  266. log_assert(lablen <= LDNS_MAX_LABELLEN);
  267. labuf[0] = lablen;
  268. i=0;
  269. while(lablen--)
  270. labuf[++i] = (uint8_t)tolower((int)*dname++);
  271. h = hashlittle(labuf, labuf[0] + 1, h);
  272. lablen = *dname++;
  273. }
  274. return h;
  275. }
  276. hashvalue_t
  277. dname_pkt_hash(ldns_buffer* pkt, uint8_t* dname, hashvalue_t h)
  278. {
  279. uint8_t labuf[LDNS_MAX_LABELLEN+1];
  280. uint8_t lablen;
  281. int i;
  282. /* preserve case of query, make hash label by label */
  283. lablen = *dname++;
  284. while(lablen) {
  285. if(LABEL_IS_PTR(lablen)) {
  286. /* follow pointer */
  287. dname = ldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
  288. lablen = *dname++;
  289. continue;
  290. }
  291. log_assert(lablen <= LDNS_MAX_LABELLEN);
  292. labuf[0] = lablen;
  293. i=0;
  294. while(lablen--)
  295. labuf[++i] = (uint8_t)tolower((int)*dname++);
  296. h = hashlittle(labuf, labuf[0] + 1, h);
  297. lablen = *dname++;
  298. }
  299. return h;
  300. }
  301. void dname_pkt_copy(ldns_buffer* pkt, uint8_t* to, uint8_t* dname)
  302. {
  303. /* copy over the dname and decompress it at the same time */
  304. size_t len = 0;
  305. uint8_t lablen;
  306. lablen = *dname++;
  307. while(lablen) {
  308. if(LABEL_IS_PTR(lablen)) {
  309. /* follow pointer */
  310. dname = ldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
  311. lablen = *dname++;
  312. continue;
  313. }
  314. log_assert(lablen <= LDNS_MAX_LABELLEN);
  315. len += (size_t)lablen+1;
  316. if(len >= LDNS_MAX_DOMAINLEN) {
  317. *to = 0; /* end the result prematurely */
  318. log_err("bad dname in dname_pkt_copy");
  319. return;
  320. }
  321. *to++ = lablen;
  322. memmove(to, dname, lablen);
  323. dname += lablen;
  324. to += lablen;
  325. lablen = *dname++;
  326. }
  327. /* copy last \0 */
  328. *to = 0;
  329. }
  330. void dname_print(FILE* out, ldns_buffer* pkt, uint8_t* dname)
  331. {
  332. uint8_t lablen;
  333. if(!out) out = stdout;
  334. if(!dname) return;
  335. lablen = *dname++;
  336. if(!lablen)
  337. fputc('.', out);
  338. while(lablen) {
  339. if(LABEL_IS_PTR(lablen)) {
  340. /* follow pointer */
  341. if(!pkt) {
  342. fputs("??compressionptr??", out);
  343. return;
  344. }
  345. dname = ldns_buffer_at(pkt, PTR_OFFSET(lablen, *dname));
  346. lablen = *dname++;
  347. continue;
  348. }
  349. if(lablen > LDNS_MAX_LABELLEN) {
  350. fputs("??extendedlabel??", out);
  351. return;
  352. }
  353. while(lablen--)
  354. fputc((int)*dname++, out);
  355. fputc('.', out);
  356. lablen = *dname++;
  357. }
  358. }
  359. int
  360. dname_count_labels(uint8_t* dname)
  361. {
  362. uint8_t lablen;
  363. int labs = 1;
  364. lablen = *dname++;
  365. while(lablen) {
  366. labs++;
  367. dname += lablen;
  368. lablen = *dname++;
  369. }
  370. return labs;
  371. }
  372. int
  373. dname_count_size_labels(uint8_t* dname, size_t* size)
  374. {
  375. uint8_t lablen;
  376. int labs = 1;
  377. size_t sz = 1;
  378. lablen = *dname++;
  379. while(lablen) {
  380. labs++;
  381. sz += lablen+1;
  382. dname += lablen;
  383. lablen = *dname++;
  384. }
  385. *size = sz;
  386. return labs;
  387. }
  388. /**
  389. * Compare labels in memory, lowercase while comparing.
  390. * @param p1: label 1
  391. * @param p2: label 2
  392. * @param len: number of bytes to compare.
  393. * @return: 0, -1, +1 comparison result.
  394. */
  395. static int
  396. memlowercmp(uint8_t* p1, uint8_t* p2, uint8_t len)
  397. {
  398. while(len--) {
  399. if(*p1 != *p2 && tolower((int)*p1) != tolower((int)*p2)) {
  400. if(tolower((int)*p1) < tolower((int)*p2))
  401. return -1;
  402. return 1;
  403. }
  404. p1++;
  405. p2++;
  406. }
  407. return 0;
  408. }
  409. int
  410. dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs)
  411. {
  412. uint8_t len1, len2;
  413. int atlabel = labs1;
  414. int lastmlabs;
  415. int lastdiff = 0;
  416. /* first skip so that we compare same label. */
  417. if(labs1 > labs2) {
  418. while(atlabel > labs2) {
  419. len1 = *d1++;
  420. d1 += len1;
  421. atlabel--;
  422. }
  423. log_assert(atlabel == labs2);
  424. } else if(labs1 < labs2) {
  425. atlabel = labs2;
  426. while(atlabel > labs1) {
  427. len2 = *d2++;
  428. d2 += len2;
  429. atlabel--;
  430. }
  431. log_assert(atlabel == labs1);
  432. }
  433. lastmlabs = atlabel+1;
  434. /* now at same label in d1 and d2, atlabel */
  435. /* www.example.com. */
  436. /* 4 3 2 1 atlabel number */
  437. /* repeat until at root label (which is always the same) */
  438. while(atlabel > 1) {
  439. len1 = *d1++;
  440. len2 = *d2++;
  441. if(len1 != len2) {
  442. log_assert(len1 != 0 && len2 != 0);
  443. if(len1<len2)
  444. lastdiff = -1;
  445. else lastdiff = 1;
  446. lastmlabs = atlabel;
  447. d1 += len1;
  448. d2 += len2;
  449. } else {
  450. /* memlowercmp is inlined here; or just like
  451. * if((c=memlowercmp(d1, d2, len1)) != 0) {
  452. * lastdiff = c;
  453. * lastmlabs = atlabel; } apart from d1++,d2++ */
  454. while(len1) {
  455. if(*d1 != *d2 && tolower((int)*d1)
  456. != tolower((int)*d2)) {
  457. if(tolower((int)*d1) <
  458. tolower((int)*d2)) {
  459. lastdiff = -1;
  460. lastmlabs = atlabel;
  461. d1 += len1;
  462. d2 += len1;
  463. break;
  464. }
  465. lastdiff = 1;
  466. lastmlabs = atlabel;
  467. d1 += len1;
  468. d2 += len1;
  469. break; /* out of memlowercmp */
  470. }
  471. d1++;
  472. d2++;
  473. len1--;
  474. }
  475. }
  476. atlabel--;
  477. }
  478. /* last difference atlabel number, so number of labels matching,
  479. * at the right side, is one less. */
  480. *mlabs = lastmlabs-1;
  481. if(lastdiff == 0) {
  482. /* all labels compared were equal, check if one has more
  483. * labels, so that example.com. > com. */
  484. if(labs1 > labs2)
  485. return 1;
  486. else if(labs1 < labs2)
  487. return -1;
  488. }
  489. return lastdiff;
  490. }
  491. int
  492. dname_buffer_write(ldns_buffer* pkt, uint8_t* dname)
  493. {
  494. uint8_t lablen;
  495. if(ldns_buffer_remaining(pkt) < 1)
  496. return 0;
  497. lablen = *dname++;
  498. ldns_buffer_write_u8(pkt, lablen);
  499. while(lablen) {
  500. if(ldns_buffer_remaining(pkt) < (size_t)lablen+1)
  501. return 0;
  502. ldns_buffer_write(pkt, dname, lablen);
  503. dname += lablen;
  504. lablen = *dname++;
  505. ldns_buffer_write_u8(pkt, lablen);
  506. }
  507. return 1;
  508. }
  509. void dname_str(uint8_t* dname, char* str)
  510. {
  511. size_t len = 0;
  512. uint8_t lablen = 0;
  513. char* s = str;
  514. if(!dname || !*dname) {
  515. *s++ = '.';
  516. *s = 0;
  517. return;
  518. }
  519. lablen = *dname++;
  520. while(lablen) {
  521. if(lablen > LDNS_MAX_LABELLEN) {
  522. *s++ = '#';
  523. *s = 0;
  524. return;
  525. }
  526. len += lablen+1;
  527. if(len >= LDNS_MAX_DOMAINLEN-1) {
  528. *s++ = '&';
  529. *s = 0;
  530. return;
  531. }
  532. while(lablen--) {
  533. if(isalnum((int)*dname)
  534. || *dname == '-' || *dname == '_'
  535. || *dname == '*')
  536. *s++ = *(char*)dname++;
  537. else {
  538. *s++ = '?';
  539. dname++;
  540. }
  541. }
  542. *s++ = '.';
  543. lablen = *dname++;
  544. }
  545. *s = 0;
  546. }
  547. int
  548. dname_strict_subdomain(uint8_t* d1, int labs1, uint8_t* d2, int labs2)
  549. {
  550. int m;
  551. /* check subdomain: d1: www.example.com. and d2: example.com. */
  552. if(labs2 >= labs1)
  553. return 0;
  554. if(dname_lab_cmp(d1, labs1, d2, labs2, &m) > 0) {
  555. /* subdomain if all labels match */
  556. return (m == labs2);
  557. }
  558. return 0;
  559. }
  560. int
  561. dname_strict_subdomain_c(uint8_t* d1, uint8_t* d2)
  562. {
  563. return dname_strict_subdomain(d1, dname_count_labels(d1), d2,
  564. dname_count_labels(d2));
  565. }
  566. int
  567. dname_subdomain_c(uint8_t* d1, uint8_t* d2)
  568. {
  569. int m;
  570. /* check subdomain: d1: www.example.com. and d2: example.com. */
  571. /* or d1: example.com. and d2: example.com. */
  572. int labs1 = dname_count_labels(d1);
  573. int labs2 = dname_count_labels(d2);
  574. if(labs2 > labs1)
  575. return 0;
  576. if(dname_lab_cmp(d1, labs1, d2, labs2, &m) < 0) {
  577. /* must have been example.com , www.example.com - wrong */
  578. /* or otherwise different dnames */
  579. return 0;
  580. }
  581. return (m == labs2);
  582. }
  583. int
  584. dname_is_root(uint8_t* dname)
  585. {
  586. uint8_t len;
  587. log_assert(dname);
  588. len = dname[0];
  589. log_assert(!LABEL_IS_PTR(len));
  590. return (len == 0);
  591. }
  592. void
  593. dname_remove_label(uint8_t** dname, size_t* len)
  594. {
  595. size_t lablen;
  596. log_assert(dname && *dname && len);
  597. lablen = (*dname)[0];
  598. log_assert(!LABEL_IS_PTR(lablen));
  599. log_assert(*len > lablen);
  600. if(lablen == 0)
  601. return; /* do not modify root label */
  602. *len -= lablen+1;
  603. *dname += lablen+1;
  604. }
  605. void
  606. dname_remove_labels(uint8_t** dname, size_t* len, int n)
  607. {
  608. int i;
  609. for(i=0; i<n; i++)
  610. dname_remove_label(dname, len);
  611. }
  612. int
  613. dname_signame_label_count(uint8_t* dname)
  614. {
  615. uint8_t lablen;
  616. int count = 0;
  617. if(!*dname)
  618. return 0;
  619. if(dname[0] == 1 && dname[1] == '*')
  620. dname += 2;
  621. lablen = dname[0];
  622. while(lablen) {
  623. count++;
  624. dname += lablen;
  625. dname += 1;
  626. lablen = dname[0];
  627. }
  628. return count;
  629. }
  630. int
  631. dname_is_wild(uint8_t* dname)
  632. {
  633. return (dname[0] == 1 && dname[1] == '*');
  634. }
  635. /**
  636. * Compare labels in memory, lowercase while comparing.
  637. * Returns canonical order for labels. If all is equal, the
  638. * shortest is first.
  639. *
  640. * @param p1: label 1
  641. * @param len1: length of label 1.
  642. * @param p2: label 2
  643. * @param len2: length of label 2.
  644. * @return: 0, -1, +1 comparison result.
  645. */
  646. static int
  647. memcanoncmp(uint8_t* p1, uint8_t len1, uint8_t* p2, uint8_t len2)
  648. {
  649. uint8_t min = (len1<len2)?len1:len2;
  650. int c = memlowercmp(p1, p2, min);
  651. if(c != 0)
  652. return c;
  653. /* equal, see who is shortest */
  654. if(len1 < len2)
  655. return -1;
  656. if(len1 > len2)
  657. return 1;
  658. return 0;
  659. }
  660. int
  661. dname_canon_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs)
  662. {
  663. /* like dname_lab_cmp, but with different label comparison,
  664. * empty character sorts before \000.
  665. * So ylyly is before z. */
  666. uint8_t len1, len2;
  667. int atlabel = labs1;
  668. int lastmlabs;
  669. int lastdiff = 0;
  670. int c;
  671. /* first skip so that we compare same label. */
  672. if(labs1 > labs2) {
  673. while(atlabel > labs2) {
  674. len1 = *d1++;
  675. d1 += len1;
  676. atlabel--;
  677. }
  678. log_assert(atlabel == labs2);
  679. } else if(labs1 < labs2) {
  680. atlabel = labs2;
  681. while(atlabel > labs1) {
  682. len2 = *d2++;
  683. d2 += len2;
  684. atlabel--;
  685. }
  686. log_assert(atlabel == labs1);
  687. }
  688. lastmlabs = atlabel+1;
  689. /* now at same label in d1 and d2, atlabel */
  690. /* www.example.com. */
  691. /* 4 3 2 1 atlabel number */
  692. /* repeat until at root label (which is always the same) */
  693. while(atlabel > 1) {
  694. len1 = *d1++;
  695. len2 = *d2++;
  696. if((c=memcanoncmp(d1, len1, d2, len2)) != 0) {
  697. if(c<0)
  698. lastdiff = -1;
  699. else lastdiff = 1;
  700. lastmlabs = atlabel;
  701. }
  702. d1 += len1;
  703. d2 += len2;
  704. atlabel--;
  705. }
  706. /* last difference atlabel number, so number of labels matching,
  707. * at the right side, is one less. */
  708. *mlabs = lastmlabs-1;
  709. if(lastdiff == 0) {
  710. /* all labels compared were equal, check if one has more
  711. * labels, so that example.com. > com. */
  712. if(labs1 > labs2)
  713. return 1;
  714. else if(labs1 < labs2)
  715. return -1;
  716. }
  717. return lastdiff;
  718. }
  719. int
  720. dname_canonical_compare(uint8_t* d1, uint8_t* d2)
  721. {
  722. int labs1, labs2, m;
  723. labs1 = dname_count_labels(d1);
  724. labs2 = dname_count_labels(d2);
  725. return dname_canon_lab_cmp(d1, labs1, d2, labs2, &m);
  726. }
  727. uint8_t* dname_get_shared_topdomain(uint8_t* d1, uint8_t* d2)
  728. {
  729. int labs1, labs2, m;
  730. size_t len = LDNS_MAX_DOMAINLEN;
  731. labs1 = dname_count_labels(d1);
  732. labs2 = dname_count_labels(d2);
  733. (void)dname_lab_cmp(d1, labs1, d2, labs2, &m);
  734. dname_remove_labels(&d1, &len, labs1-m);
  735. return d1;
  736. }