Add dn resolution function
Signed-off-by: songlinzhang <songlinzhang@xiaomi.com>
This commit is contained in:
parent
2cbad5d92e
commit
e2114378b9
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
314
libs/libc/netdb/lib_dn.c
Normal file
314
libs/libc/netdb/lib_dn.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user