You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pk...@apache.org on 2022/03/17 07:37:24 UTC
[incubator-nuttx] branch master updated: Add dn resolution function
This is an automated email from the ASF dual-hosted git repository.
pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new e211437 Add dn resolution function
e211437 is described below
commit e2114378b9238cfe98d4c10f2f9cf9a2f88b1445
Author: songlinzhang <so...@xiaomi.com>
AuthorDate: Mon Mar 14 15:50:22 2022 +0800
Add dn resolution function
Signed-off-by: songlinzhang <so...@xiaomi.com>
---
include/resolv.h | 8 ++
libs/libc/netdb/Make.defs | 2 +-
libs/libc/netdb/lib_dn.c | 314 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 323 insertions(+), 1 deletion(-)
diff --git a/include/resolv.h b/include/resolv.h
index 5ea6dad..47ca8fb 100644
--- a/include/resolv.h
+++ b/include/resolv.h
@@ -42,6 +42,14 @@ int b64_ntop(FAR const unsigned char *src, size_t srclen,
int b64_pton(FAR const char *src,
FAR unsigned char *target, size_t targsize);
+/* dn resolution */
+
+int dn_comp(FAR const char *src, FAR unsigned char *dst, int space,
+ FAR unsigned char **dnptrs, FAR unsigned char **lastdnptr);
+
+int dn_expand(FAR const unsigned char *base, FAR const unsigned char *end,
+ FAR const unsigned char *src, FAR char *dest, int space);
+
#if defined(__cplusplus)
}
#endif
diff --git a/libs/libc/netdb/Make.defs b/libs/libc/netdb/Make.defs
index dfabc3f..5e71b52 100644
--- a/libs/libc/netdb/Make.defs
+++ b/libs/libc/netdb/Make.defs
@@ -29,7 +29,7 @@ CSRCS += lib_gethostbyaddr.c lib_gethostbyaddrr.c
CSRCS += lib_getservbyname.c lib_getservbynamer.c
CSRCS += lib_getservbyport.c lib_getservbyportr.c
CSRCS += lib_gaistrerror.c lib_freeaddrinfo.c lib_getaddrinfo.c
-CSRCS += lib_getnameinfo.c lib_rexec.c
+CSRCS += lib_getnameinfo.c lib_rexec.c lib_dn.c
# Add host file support
diff --git a/libs/libc/netdb/lib_dn.c b/libs/libc/netdb/lib_dn.c
new file mode 100644
index 0000000..8e53e5d
--- /dev/null
+++ b/libs/libc/netdb/lib_dn.c
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * libs/libc/netdb/lib_dn.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <string.h>
+#include <resolv.h>
+
+/* RFC 1035 message compression */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* label start offsets of a compressed domain name s */
+
+static int getoffs(FAR short *offs, FAR const unsigned char *base,
+ FAR const unsigned char *s)
+{
+ int i = 0;
+
+ for (; ; )
+ {
+ while ((*s & 0xc0) != 0)
+ {
+ if ((*s & 0xc0) != 0xc0)
+ {
+ return 0;
+ }
+
+ s = base + ((s[0] & 0x3f) << 8 | s[1]);
+ }
+
+ if (*s == 0)
+ {
+ return i;
+ }
+
+ if (s - base >= 0x4000)
+ {
+ return 0;
+ }
+
+ offs[i++] = s - base;
+ s += *s + 1;
+ }
+}
+
+/* label lengths of an ascii domain name s */
+
+static int getlens(FAR unsigned char *lens, FAR const char *s, int l)
+{
+ int i = 0;
+ int j = 0;
+ int k = 0;
+
+ for (; ; )
+ {
+ for (; j < l && s[j] != '.'; j++);
+ if (j - k - 1 > 62)
+ {
+ return 0;
+ }
+
+ lens[i++] = j - k;
+ if (j == l)
+ {
+ return i;
+ }
+
+ k = ++j;
+ }
+}
+
+/* longest suffix match of an ascii domain with a compressed domain name dn */
+
+static int match(FAR int *offset, FAR const unsigned char *base,
+ FAR const unsigned char *dn, FAR const char *end,
+ FAR const unsigned char *lens, int nlen)
+{
+ int l;
+ int o;
+ int m = 0;
+ short offs[128];
+ int noff = getoffs(offs, base, dn);
+
+ if (noff == 0)
+ {
+ return 0;
+ }
+
+ for (; ; )
+ {
+ l = lens[--nlen];
+ o = offs[--noff];
+ end -= l;
+ if (l != base[o] || memcmp(base + o + 1, end, l) != 0)
+ {
+ return m;
+ }
+
+ *offset = o;
+ m += l;
+ if (nlen > 0)
+ {
+ m++;
+ }
+
+ if (nlen == 0 || noff == 0)
+ {
+ return m;
+ }
+
+ end--;
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int dn_comp(FAR const char *src, FAR unsigned char *dst, int space,
+ FAR unsigned char **dnptrs, FAR unsigned char **lastdnptr)
+{
+ int i;
+ int j;
+ int n;
+ int m = 0;
+ int offset = 0;
+ int bestlen = 0;
+ int bestoff = 0;
+ unsigned char lens[127];
+ FAR unsigned char **p = dnptrs;
+ FAR const char *end;
+ size_t l = strnlen(src, 255);
+
+ if (l > 0 && src[l - 1] == '.')
+ {
+ l--;
+ }
+
+ if (l > 253 || space <= 0)
+ {
+ return -1;
+ }
+
+ if (l == 0)
+ {
+ *dst = 0;
+ return 1;
+ }
+
+ end = src + l;
+ n = getlens(lens, src, l);
+ if (n == 0)
+ {
+ return -1;
+ }
+
+ if (dnptrs != NULL && *dnptrs != NULL)
+ {
+ for (p = dnptrs + 1 ; *p != NULL; p++)
+ {
+ m = match(&offset, *dnptrs, *p, end, lens, n);
+ if (m > bestlen)
+ {
+ bestlen = m;
+ bestoff = offset;
+ if (m == l)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ /* encode unmatched part */
+
+ if (space < l - bestlen + 2 + (bestlen - 1 < l - 1))
+ {
+ return -1;
+ }
+
+ memcpy(dst + 1, src, l - bestlen);
+ for (i = j = 0; i < l - bestlen; i += lens[j++] + 1)
+ {
+ dst[i] = lens[j];
+ }
+
+ /* add tail */
+
+ if (bestlen > 0)
+ {
+ dst[i++] = 0xc0 | bestoff >> 8;
+ dst[i++] = bestoff;
+ }
+ else
+ {
+ dst[i++] = 0;
+ }
+
+ /* save dst pointer */
+
+ if (i > 2 && lastdnptr != NULL && dnptrs != NULL && *dnptrs != NULL)
+ {
+ while (*p != NULL)
+ {
+ p++;
+ }
+
+ if (p + 1 < lastdnptr)
+ {
+ *p++ = dst;
+ *p = 0;
+ }
+ }
+
+ return i;
+}
+
+int dn_expand(FAR const unsigned char *base, FAR const unsigned char *end,
+ FAR const unsigned char *src, FAR char *dest, int space)
+{
+ FAR const unsigned char *p = src;
+ FAR char *dend;
+ FAR char *dbegin = dest;
+ int len = -1;
+ int i;
+ int j;
+
+ if (p == end || space <= 0)
+ {
+ return -1;
+ }
+
+ dend = dest + (space > 254 ? 254 : space);
+
+ /* detect reference loop using an iteration counter */
+
+ for (i = 0; i < end - base; i += 2)
+ {
+ /* loop invariants: p<end, dest<dend */
+
+ if ((*p & 0xc0) != 0)
+ {
+ if (p + 1 == end)
+ {
+ return -1;
+ }
+
+ j = ((p[0] & 0x3f) << 8) | p[1];
+ if (len < 0)
+ {
+ len = p + 2 - src;
+ }
+
+ if (j >= end - base)
+ {
+ return -1;
+ }
+
+ p = base + j;
+ }
+ else if (*p)
+ {
+ if (dest != dbegin)
+ {
+ *dest++ = '.';
+ }
+
+ j = *p++;
+ if (j >= end - p || j >= dend - dest)
+ {
+ return -1;
+ }
+
+ while (j--)
+ {
+ *dest++ = *p++;
+ }
+ }
+ else
+ {
+ *dest = 0;
+ if (len < 0)
+ {
+ len = p + 1 - src;
+ }
+
+ return len;
+ }
+ }
+
+ return -1;
+}