encode.c
来自「此dns服务器是在mydns基础上改写」· C语言 代码 · 共 199 行
C
199 行
/************************************************************************************************** $Id: encode.c,v 1.36 2006/01/18 20:46:47 bboy Exp $ Copyright (C) 2002-2005 Don Moore <bboy@bboy.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at Your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA**************************************************************************************************/#include "named.h"/* Make this nonzero to enable debugging for this source file */#define DEBUG_ENCODE 1/* Set this to nonzero to disable encoding */#define NO_ENCODING 0/************************************************************************************************** NAME_REMEMBER Adds the specified name + offset to the `Labels' array within the specified task.**************************************************************************************************/inline intname_remember(TASK *t, char *name, unsigned int offset){ if (!name || strlen(name) > 64) /* Don't store labels > 64 bytes in length */ return (0);#if DYNAMIC_NAMES if (!t->Names) { if (!(t->Names = (char **)malloc(1 * sizeof(char *)))) Err(_("out of memory")); } else { if (!(t->Names = realloc(t->Names, (t->numNames + 1) * sizeof(char *)))) Err(_("out of memory")); } if (!(t->Names[t->numNames] = strdup(name))) Err("strdup"); if (!t->Offsets) { if (!(t->Offsets = malloc(sizeof(unsigned int)))) Err(_("out of memory")); } else { if (!(t->Offsets = realloc(t->Offsets, (t->numNames + 1) * sizeof(unsigned int)))) Err(_("out of memory")); }#else if (t->numNames >= MAX_STORED_NAMES - 1) return dnserror(t, DNS_RCODE_SERVFAIL, ERR_RR_NAME_TOO_LONG); strncpy(t->Names[t->numNames], name, sizeof(t->Names[t->numNames]) - 1);#endif#if DEBUG_ENABLED && DEBUG_ENCODE Debug("remembering name \"%s\" at offset %u", name, offset);#endif t->Offsets[t->numNames] = offset; t->numNames++; return (0);}/*--- name_remember() ---------------------------------------------------------------------------*//************************************************************************************************** NAME_FORGET Forget all names in the specified task.**************************************************************************************************/inline voidname_forget(TASK *t){#if DYNAMIC_NAMES register int n; for (n = 0; n < t->numNames; n++) Free(t->Names[n]); Free(t->Names); Free(t->Offsets);#endif t->numNames = 0;}/*--- name_forget() -----------------------------------------------------------------------------*//************************************************************************************************** NAME_FIND Searches the task's remembered names arary for `name'. Returns the offset within the reply if found, or 0 if not found.**************************************************************************************************/unsigned intname_find(TASK *t, char *name){ register unsigned int n; for (n = 0; n < t->numNames; n++) if (!strcasecmp(t->Names[n], name)) {#if DEBUG_ENABLED && DEBUG_ENCODE Debug("found name \"%s\" at offset %u", name, t->Offsets[n]);#endif return (t->Offsets[n]); } return (0);}/*--- name_find() -------------------------------------------------------------------------------*//************************************************************************************************** NAME_ENCODE Encodes `in_name' into `dest'. Returns the length of data in `dest', or -1 on error. If `name' is not NULL, it should be DNS_MAXNAMELEN bytes or bigger.**************************************************************************************************/intname_encode(TASK *t, char *dest, char *name, unsigned int dest_offset, int compression){ char namebuf[DNS_MAXNAMELEN+1]; register char *c, *d, *this_name, *cp; register int len = 0; register unsigned int offset;#if DEBUG_ENABLED && DEBUG_ENCODE Debug("encoding \"%s\" at dest offset %u", name, dest_offset);#endif strncpy(namebuf, name, sizeof(namebuf)-1); /* Label must end in the root zone (with a dot) */ if (LASTCHAR(namebuf) != '.') return dnserror(t, DNS_RCODE_SERVFAIL, ERR_NAME_FORMAT); /* Examine name one label at a time */ for (c = namebuf, d = dest; *c; c++) if (c == namebuf || *c == '.') { if (!c[1]) { len++; if (len > DNS_MAXNAMELEN) return dnserror(t, DNS_RCODE_SERVFAIL, ERR_RR_NAME_TOO_LONG); *d++ = 0; return (len); } this_name = (c == namebuf) ? c : (++c);#if !NO_ENCODING if (compression && !t->no_markers && (offset = name_find(t, this_name))) { /* Found marker for this name - output offset pointer and we're done */ len += SIZE16; if (len > DNS_MAXNAMELEN) return dnserror(t, DNS_RCODE_SERVFAIL, ERR_RR_NAME_TOO_LONG); offset |= 0xC000; DNS_PUT16(d, offset); return (len); } else /* No marker for this name; encode current label and store marker */#endif { register unsigned int nlen; if ((cp = strchr(this_name, '.'))) *cp = '\0'; nlen = strlen(this_name); if (nlen > DNS_MAXLABELLEN) return dnserror(t, DNS_RCODE_SERVFAIL, ERR_RR_LABEL_TOO_LONG); len += nlen + 1; if (len > DNS_MAXNAMELEN) return dnserror(t, DNS_RCODE_SERVFAIL, ERR_RR_NAME_TOO_LONG); *d++ = (unsigned char)nlen; memcpy(d, this_name, nlen); d += nlen; if (cp) *cp = '.'; if (!t->no_markers && (name_remember(t, this_name, dest_offset + (c - namebuf)) < 0)) return (-1); } } return (len);}/*--- name_encode() -----------------------------------------------------------------------------*//* vi:set ts=3: *//* NEED_PO */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?