Home | History | Annotate | Download | only in ninfod
      1 /* $USAGI: ninfod_core.c,v 1.29 2003-07-16 09:49:01 yoshfuji Exp $ */
      2 /*
      3  * Copyright (C) 2002 USAGI/WIDE Project.
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. Neither the name of the project nor the names of its contributors
     15  *    may be used to endorse or promote products derived from this software
     16  *    without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28  * SUCH DAMAGE.
     29  */
     30 /*
     31  * Author:
     32  * 	YOSHIFUJI Hideaki <yoshfuji (at) linux-ipv6.org>
     33  */
     34 
     35 #if HAVE_CONFIG_H
     36 #include "config.h"
     37 #endif
     38 
     39 #if HAVE_SYS_TYPES_H
     40 # include <sys/types.h>
     41 #endif
     42 #if STDC_HEADERS
     43 # include <stdio.h>
     44 # include <stdlib.h>
     45 # include <stddef.h>
     46 #else
     47 # if HAVE_STDLIB_H
     48 #  include <stdlib.h>
     49 # endif
     50 #endif
     51 #if ENABLE_THREADS && HAVE_PTHREAD_H
     52 # include <pthread.h>
     53 #endif
     54 #if HAVE_STRING_H
     55 # if !STDC_HEADERS && HAVE_MEMORY_H
     56 #  include <memory.h>
     57 # endif
     58 # include <string.h>
     59 #endif
     60 #if HAVE_STRINGS_H
     61 # include <strings.h>
     62 #endif
     63 #if HAVE_INTTYPES_H
     64 # include <inttypes.h>
     65 #else
     66 # if HAVE_STDINT_H
     67 #  include <stdint.h>
     68 # endif
     69 #endif
     70 #if HAVE_UNISTD_H
     71 # include <unistd.h>
     72 #endif
     73 
     74 #if TIME_WITH_SYS_TIME
     75 # include <sys/time.h>
     76 # include <time.h>
     77 #else
     78 # if HAVE_SYS_TIME_H
     79 #  include <sys/time.h>
     80 # else
     81 #  include <time.h>
     82 # endif
     83 #endif
     84 
     85 #if HAVE_SYS_UIO_H
     86 #include <sys/uio.h>
     87 #endif
     88 
     89 #if HAVE_NETINET_IN_H
     90 # include <netinet/in.h>
     91 #endif
     92 
     93 #if HAVE_NETINET_ICMP6_H
     94 # include <netinet/icmp6.h>
     95 #endif
     96 #ifndef HAVE_STRUCT_ICMP6_NODEINFO
     97 # include "icmp6_nodeinfo.h"
     98 #endif
     99 
    100 #if HAVE_NETDB_H
    101 # include <netdb.h>
    102 #endif
    103 #include <errno.h>
    104 
    105 #if HAVE_SYSLOG_H
    106 # include <syslog.h>
    107 #endif
    108 
    109 #include "ninfod.h"
    110 
    111 #ifndef offsetof
    112 # define offsetof(aggregate,member)	((size_t)&((aggregate *)0)->member)
    113 #endif
    114 
    115 #define ARRAY_SIZE(a)		(sizeof(a) / sizeof(a[0]))
    116 
    117 /* ---------- */
    118 /* ID */
    119 static char *RCSID __attribute__ ((unused)) = "$USAGI: ninfod_core.c,v 1.29 2003-07-16 09:49:01 yoshfuji Exp $";
    120 
    121 /* Variables */
    122 int initialized = 0;
    123 
    124 #if ENABLE_THREADS && HAVE_LIBPTHREAD
    125 pthread_attr_t pattr;
    126 #endif
    127 
    128 static uint32_t suptypes[(MAX_SUPTYPES+31)>>5];
    129 static size_t suptypes_len;
    130 
    131 /* ---------- */
    132 struct subjinfo {
    133 	uint8_t	code;
    134 	char	*name;
    135 	int	(*checksubj)(CHECKANDFILL_ARGS);
    136 	int	(*init)(INIT_ARGS);
    137 };
    138 
    139 static struct subjinfo subjinfo_table [] = {
    140 	[ICMP6_NI_SUBJ_IPV6] = {
    141 		.code = ICMP6_NI_SUBJ_IPV6,
    142 		.name = "IPv6",
    143 		//.init = init_nodeinfo_ipv6addr,
    144 		.checksubj = pr_nodeinfo_ipv6addr,
    145 	},
    146 	[ICMP6_NI_SUBJ_FQDN] = {
    147 		.code = ICMP6_NI_SUBJ_FQDN,
    148 		.name = "FQDN",
    149 		//.init = init_nodeinfo_nodename,
    150 		.checksubj = pr_nodeinfo_nodename,
    151 	},
    152 	[ICMP6_NI_SUBJ_IPV4] = {
    153 		.code = ICMP6_NI_SUBJ_IPV4,
    154 		.name = "IPv4",
    155 		//.init = init_nodeinfo_ipv4addr,
    156 		.checksubj = pr_nodeinfo_ipv4addr,
    157 	},
    158 };
    159 
    160 static struct subjinfo subjinfo_null = {
    161 	.name = "null",
    162 	.checksubj = pr_nodeinfo_noop,
    163 };
    164 
    165 static __inline__ struct subjinfo *subjinfo_lookup(int code)
    166 {
    167 	if (code >= ARRAY_SIZE(subjinfo_table))
    168 		return NULL;
    169 	if (subjinfo_table[code].name == NULL)
    170 		return NULL;
    171 	return &subjinfo_table[code];
    172 }
    173 
    174 /* ---------- */
    175 #define QTYPEINFO_F_RATELIMIT	0x1
    176 
    177 struct qtypeinfo {
    178 	uint16_t qtype;
    179 	char	*name;
    180 	int	(*getreply)(CHECKANDFILL_ARGS);
    181 	void	(*init)(INIT_ARGS);
    182 	int	flags;
    183 };
    184 
    185 static struct qtypeinfo qtypeinfo_table[] = {
    186 	[NI_QTYPE_NOOP]		= {
    187 		.qtype = NI_QTYPE_NOOP,
    188 		.name = "NOOP",
    189 		.getreply = pr_nodeinfo_noop,
    190 	},
    191 #if ENABLE_SUPTYPES
    192 	[NI_QTYPE_SUPTYPES]	= {
    193 		.qtype = NI_QTYPE_SUPTYPES,
    194 		.name = "SupTypes",
    195 		.getreply = pr_nodeinfo_suptypes,
    196 		.init = init_nodeinfo_suptypes,
    197 	},
    198 #endif
    199 	[NI_QTYPE_DNSNAME]	= {
    200 		.qtype = NI_QTYPE_DNSNAME,
    201 		.name = "DnsName",
    202 		.getreply = pr_nodeinfo_nodename,
    203 		.init = init_nodeinfo_nodename,
    204 	},
    205 	[NI_QTYPE_NODEADDR]	= {
    206 		.qtype = NI_QTYPE_NODEADDR,
    207 		.name = "NodeAddr",
    208 		.getreply = pr_nodeinfo_ipv6addr,
    209 		.init = init_nodeinfo_ipv6addr,
    210 	},
    211 	[NI_QTYPE_IPV4ADDR]	= {
    212 		.qtype = NI_QTYPE_IPV4ADDR,
    213 		.name = "IPv4Addr",
    214 		.getreply = pr_nodeinfo_ipv4addr,
    215 		.init = init_nodeinfo_ipv4addr,
    216 	},
    217 };
    218 
    219 static struct qtypeinfo qtypeinfo_unknown = {
    220 	.name = "unknown",
    221 	.getreply = pr_nodeinfo_unknown,
    222 	.flags = QTYPEINFO_F_RATELIMIT,
    223 };
    224 
    225 static struct qtypeinfo qtypeinfo_refused = {
    226 	.name = "refused",
    227 	.getreply = pr_nodeinfo_refused,
    228 	.flags = QTYPEINFO_F_RATELIMIT,
    229 };
    230 
    231 static __inline__ struct qtypeinfo *qtypeinfo_lookup(int qtype)
    232 {
    233 	if (qtype >= ARRAY_SIZE(qtypeinfo_table))
    234 		return &qtypeinfo_unknown;
    235 	if (qtypeinfo_table[qtype].name == NULL)
    236 		return &qtypeinfo_unknown;
    237 	return &qtypeinfo_table[qtype];
    238 }
    239 
    240 /* ---------- */
    241 /* noop */
    242 int pr_nodeinfo_noop(CHECKANDFILL_ARGS)
    243 {
    244 	DEBUG(LOG_DEBUG, "%s()\n", __func__);
    245 
    246 	if (subjlen) {
    247 		DEBUG(LOG_WARNING,
    248 		      "%s(): invalid subject length(%zu)\n",
    249 		      __func__, subjlen);
    250 		return 1;
    251 	}
    252 
    253 	if (reply) {
    254 		p->reply.ni_type = ICMP6_NI_REPLY;
    255 		p->reply.ni_code = ICMP6_NI_SUCCESS;
    256 		p->reply.ni_cksum = 0;
    257 		p->reply.ni_qtype = htons(NI_QTYPE_NOOP);
    258 		p->reply.ni_flags = flags;
    259 	}
    260 
    261 	if (subj_if)
    262 		*subj_if = 0;
    263 
    264 	return 0;
    265 }
    266 
    267 #if ENABLE_SUPTYPES
    268 /* suptypes */
    269 int pr_nodeinfo_suptypes(CHECKANDFILL_ARGS)
    270 {
    271 	DEBUG(LOG_DEBUG, "%s()\n", __func__);
    272 
    273 	if (subjlen) {
    274 		DEBUG(LOG_WARNING, "%s(): invalid subject length(%zu)\n",
    275 		      __func__, subjlen);
    276 		return 1;
    277 	}
    278 
    279 	if (reply) {
    280 		p->reply.ni_type = ICMP6_NI_REPLY;
    281 		p->reply.ni_code = ICMP6_NI_SUCCESS;
    282 		p->reply.ni_cksum = 0;
    283 		p->reply.ni_qtype = htons(NI_QTYPE_SUPTYPES);
    284 		p->reply.ni_flags = flags&~NI_SUPTYPE_FLAG_COMPRESS;
    285 
    286 		p->replydatalen = suptypes_len<<2;
    287 		p->replydata = ni_malloc(p->replydatalen);
    288 		if (p->replydata == NULL) {
    289 			p->replydatalen = -1;
    290 			return -1;	/*XXX*/
    291 		}
    292 
    293 		memcpy(p->replydata, suptypes, p->replydatalen);
    294 	}
    295 	return 0;
    296 }
    297 
    298 void init_nodeinfo_suptypes(INIT_ARGS)
    299 {
    300 	size_t w, b;
    301 	int i;
    302 
    303 	if (!forced && initialized)
    304 		return;
    305 
    306 	memset(suptypes, 0, sizeof(suptypes));
    307 	suptypes_len = 0;
    308 
    309 	for (i=0; i < ARRAY_SIZE(qtypeinfo_table); i++) {
    310 		unsigned short qtype;
    311 
    312 		if (qtypeinfo_table[i].name == NULL)
    313 			continue;
    314 		qtype = qtypeinfo_table[i].qtype;
    315 		w = qtype>>5;
    316 		b = qtype&0x1f;
    317 		if (w >= ARRAY_SIZE(suptypes)) {
    318 			/* This is programming error. */
    319 			DEBUG(LOG_ERR, "Warning: Too Large Supported Types\n");
    320 			exit(1);
    321 		}
    322 		suptypes[w] |= htonl(1<<b);
    323 
    324 		if (suptypes_len < w)
    325 			suptypes_len = w;
    326 	}
    327 	suptypes_len++;
    328 }
    329 #endif
    330 
    331 /* ---------- */
    332 /* unknown qtype response */
    333 int pr_nodeinfo_unknown(CHECKANDFILL_ARGS)
    334 {
    335 	if (!reply)
    336 		return -1;	/*???*/
    337 
    338 	p->reply.ni_type = ICMP6_NI_REPLY;
    339 	p->reply.ni_code = ICMP6_NI_UNKNOWN;
    340 	p->reply.ni_cksum = 0;
    341 	//p->reply.ni_qtype = 0;
    342 	p->reply.ni_flags = flags;
    343 
    344 	p->replydata = NULL;
    345 	p->replydatalen = 0;
    346 
    347 	return 0;
    348 }
    349 
    350 /* refused response */
    351 int pr_nodeinfo_refused(CHECKANDFILL_ARGS)
    352 {
    353 	if (!reply)
    354 		return -1;	/*???*/
    355 
    356 	p->reply.ni_type = ICMP6_NI_REPLY;
    357 	p->reply.ni_code = ICMP6_NI_REFUSED;
    358 	p->reply.ni_cksum = 0;
    359 	//p->reply.ni_qtype = 0;
    360 	p->reply.ni_flags = flags;
    361 
    362 	p->replydata = NULL;
    363 	p->replydatalen = 0;
    364 
    365 	return 0;
    366 }
    367 
    368 /* ---------- */
    369 /* Policy */
    370 static int ni_policy(struct packetcontext *p)
    371 {
    372 	const struct in6_addr *saddr = &((const struct sockaddr_in6 *)&p->addr)->sin6_addr;
    373 
    374 	/*
    375 	 * >0: reply
    376 	 *  0: refused
    377 	 * <0: discard
    378 	 */
    379 
    380 	/* Default policy is to refuse queries from
    381 	 * non-local addresses; loopback, link-local or
    382 	 * site-local are okay
    383 	 */
    384 	if (!(IN6_IS_ADDR_LINKLOCAL(saddr) ||
    385 	      IN6_IS_ADDR_SITELOCAL(saddr) ||
    386 	      IN6_IS_ADDR_LOOPBACK(saddr)))
    387 		return 0;
    388 	return 1;
    389 }
    390 
    391 /* ---------- */
    392 void init_core(int forced)
    393 {
    394 	int i;
    395 
    396 	DEBUG(LOG_DEBUG, "%s()\n", __func__);
    397 
    398 	if (!initialized || forced) {
    399 		struct timeval tv;
    400 		unsigned int seed = 0;
    401 		pid_t pid;
    402 
    403 		if (gettimeofday(&tv, NULL) < 0) {
    404 			DEBUG(LOG_WARNING, "%s(): failed to gettimeofday()\n", __func__);
    405 		} else {
    406 			seed = (tv.tv_usec & 0xffffffff);
    407 		}
    408 
    409 		pid = getpid();
    410 		seed ^= (((unsigned long)pid) & 0xffffffff);
    411 
    412 		srand(seed);
    413 
    414 #if ENABLE_THREADS && HAVE_LIBPTHREAD
    415 		if (initialized)
    416 			pthread_attr_destroy(&pattr);
    417 
    418 		pthread_attr_init(&pattr);
    419 		pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
    420 #endif
    421 	}
    422 
    423 	for (i=0; i < ARRAY_SIZE(subjinfo_table); i++) {
    424 		if (subjinfo_table[i].name == NULL)
    425 			continue;
    426 		if (subjinfo_table[i].init)
    427 			subjinfo_table[i].init(forced);
    428 	}
    429 
    430 	for (i=0; i < ARRAY_SIZE(qtypeinfo_table); i++) {
    431 		if (qtypeinfo_table[i].name == NULL)
    432 			continue;
    433 		if (qtypeinfo_table[i].init)
    434 			qtypeinfo_table[i].init(forced);
    435 	}
    436 
    437 	initialized = 1;
    438 
    439 	return;
    440 }
    441 
    442 #if ENABLE_THREADS && HAVE_LIBPTHREAD
    443 static void *ni_send_thread(void *data)
    444 {
    445 	int ret;
    446 	DEBUG(LOG_DEBUG, "%s(): thread=%ld\n", __func__, pthread_self());
    447 	ret = ni_send(data);
    448 	DEBUG(LOG_DEBUG, "%s(): thread=%ld => %d\n", __func__, pthread_self(), ret);
    449 	return NULL;
    450 }
    451 #else
    452 static int ni_send_fork(struct packetcontext *p)
    453 {
    454 	pid_t child = fork();
    455 	if (child < 0)
    456 		return -1;
    457 	if (child == 0) {
    458 		pid_t grandchild = fork();
    459 		if (grandchild < 0)
    460 			exit(1);
    461 		if (grandchild == 0) {
    462 			int ret;
    463 			DEBUG(LOG_DEBUG, "%s(): worker=%d\n",
    464 			      __func__, getpid());
    465 			ret = ni_send(p);
    466 			DEBUG(LOG_DEBUG, "%s(): worker=%d => %d\n",
    467 			      __func__, getpid(), ret);
    468 			exit(ret > 0 ? 1 : 0);
    469 		}
    470 		ni_free(p->replydata);
    471 		ni_free(p);
    472 		exit(0);
    473 	} else {
    474 		waitpid(child, NULL, 0);
    475 		ni_free(p->replydata);
    476 		ni_free(p);
    477 	}
    478 	return 0;
    479 }
    480 #endif
    481 
    482 static int ni_ratelimit(void)
    483 {
    484 	static struct timeval last;
    485 	struct timeval tv, sub;
    486 
    487 	if (gettimeofday(&tv, NULL) < 0) {
    488 		DEBUG(LOG_WARNING, "%s(): gettimeofday(): %s\n",
    489 		      __func__, strerror(errno));
    490 		return -1;
    491 	}
    492 
    493 	if (!timerisset(&last)) {
    494 		last = tv;
    495 		return 0;
    496 	}
    497 
    498 	timersub(&tv, &last, &sub);
    499 
    500 	if (sub.tv_sec < 1)
    501 		return 1;
    502 
    503 	last = tv;
    504 	return 0;
    505 }
    506 
    507 int pr_nodeinfo(struct packetcontext *p)
    508 {
    509 	struct icmp6_nodeinfo *query = (struct icmp6_nodeinfo *)p->query;
    510 
    511 	char *subject = (char *)(query + 1);
    512 	size_t subjlen;
    513 	struct subjinfo *subjinfo;
    514 	struct qtypeinfo *qtypeinfo;
    515 	int replyonsubjcheck = 0;
    516 	unsigned int subj_if;
    517 #if ENABLE_DEBUG
    518 	char printbuf[128];
    519 	int i;
    520 	char *cp;
    521 #endif
    522 #if ENABLE_THREADS && HAVE_PTHREAD_H
    523 	pthread_t thread;
    524 #endif
    525 	int rc;
    526 
    527 	/* Step 0: Check destination address
    528 	 *		discard non-linklocal multicast
    529 	 *		discard non-nigroup multicast address(?)
    530 	 */
    531 	if (IN6_IS_ADDR_MULTICAST(&p->pktinfo.ipi6_addr)) {
    532 		if (!IN6_IS_ADDR_MC_LINKLOCAL(&p->pktinfo.ipi6_addr)) {
    533 			DEBUG(LOG_WARNING,
    534 			      "Destination is non-link-local multicast address.\n");
    535 			ni_free(p);
    536 			return -1;
    537 		}
    538 #if 0
    539 		/* Do not discard NI Queries to multicast address
    540 		 * other than its own NI Group Address(es) by default.
    541 		 */
    542 		if (!check_nigroup(&p->pktinfo.ipi6_addr)) {
    543 			DEBUG(LOG_WARNING,
    544 			      "Destination is link-local multicast address other than "
    545 			      "NI Group address.\n");
    546 			ni_free(p);
    547 			return -1;
    548 		}
    549 #endif
    550 	}
    551 
    552 	/* Step 1: Check length */
    553 	if (p->querylen < sizeof(struct icmp6_nodeinfo)) {
    554 		DEBUG(LOG_WARNING, "Query too short\n");
    555 		ni_free(p);
    556 		return -1;
    557 	}
    558 
    559 #if ENABLE_DEBUG
    560 	cp = printbuf;
    561 	for (i = 0; i < sizeof(query->icmp6_ni_nonce); i++) {
    562 		cp += sprintf(cp, " %02x", query->icmp6_ni_nonce[i]);
    563 	}
    564 	DEBUG(LOG_DEBUG, "%s(): qtype=%d, flags=0x%04x, nonce[] = {%s }\n",
    565 	      __func__,
    566 	      ntohs(query->ni_qtype), ntohs(query->ni_flags), printbuf);
    567 #endif
    568 
    569 	subjlen = p->querylen - sizeof(struct icmp6_nodeinfo);
    570 
    571 	/* Step 2: Check Subject Code */
    572 	switch(htons(query->ni_qtype)) {
    573 	case NI_QTYPE_NOOP:
    574 	case NI_QTYPE_SUPTYPES:
    575 		if (query->ni_code != ICMP6_NI_SUBJ_FQDN) {
    576 			DEBUG(LOG_WARNING,
    577 			      "%s(): invalid/unknown code %u\n",
    578 			      __func__, query->ni_code);
    579 			subjlen = 0;
    580 		}
    581 		subjinfo = &subjinfo_null;
    582 		break;
    583 	default:
    584 		subjinfo = subjinfo_lookup(query->ni_code);
    585 		if (!subjinfo) {
    586 			DEBUG(LOG_WARNING,
    587 			      "%s(): unknown code %u\n",
    588 			      __func__, query->ni_code);
    589 			ni_free(p);
    590 			return -1;
    591 		}
    592 	}
    593 
    594 	/* Step 3: Lookup Qtype */
    595 	qtypeinfo = qtypeinfo_lookup(ntohs(query->ni_qtype));
    596 
    597 	/* Step 4: Check Subject
    598 	 *         (And fill reply if it is available now)
    599 	 */
    600 	if (qtypeinfo->getreply == subjinfo->checksubj)
    601 		replyonsubjcheck = 1;
    602 
    603 	if (subjinfo->checksubj(p,
    604 				subject, subjlen,
    605 				query->ni_flags,
    606 				replyonsubjcheck ? NULL : &subj_if,
    607 				replyonsubjcheck)) {
    608 		if (p->replydatalen < 0) {
    609 			DEBUG(LOG_WARNING,
    610 			      "failed to make reply: %s\n",
    611 			      strerror(errno));
    612 		}
    613 		ni_free(p);
    614 		return -1;
    615 	}
    616 
    617 	/* XXX: Step 5: Check the policy */
    618 	rc = ni_policy(p);
    619 	if (rc <= 0) {
    620 		ni_free(p->replydata);
    621 		p->replydata = NULL;
    622 		p->replydatalen = 0;
    623 		if (rc < 0) {
    624 			DEBUG(LOG_WARNING, "Ignored by policy.\n");
    625 			ni_free(p);
    626 			return -1;
    627 		}
    628 		DEBUG(LOG_WARNING, "Refused by policy.\n");
    629 		replyonsubjcheck = 0;
    630 		qtypeinfo = &qtypeinfo_refused;
    631 	}
    632 
    633 	/* Step 6: Fill the reply if not yet done */
    634 	if (!replyonsubjcheck) {
    635 		if (qtypeinfo->getreply(p,
    636 					NULL, 0,
    637 					query->ni_flags,
    638 					&subj_if,
    639 					1)) {
    640 			if (p->replydatalen) {
    641 				DEBUG(LOG_WARNING,
    642 				      "failed to make reply: %s\n",
    643 				      strerror(errno));
    644 			}
    645 			ni_free(p);
    646 			return -1;
    647 		}
    648 	}
    649 
    650 	/* Step 7: Rate Limit */
    651 	if (qtypeinfo->flags&QTYPEINFO_F_RATELIMIT &&
    652 	    ni_ratelimit()) {
    653 		ni_free(p->replydata);
    654 		ni_free(p);
    655 		return -1;
    656 	}
    657 
    658 	/* Step 8: Fill Qtype / Nonce */
    659 	p->reply.ni_qtype = query->ni_qtype;
    660 	memcpy(p->reply.icmp6_ni_nonce, query->icmp6_ni_nonce, sizeof(p->reply.icmp6_ni_nonce));
    661 
    662 	/* Step 9: Source address selection */
    663 	if (IN6_IS_ADDR_MULTICAST(&p->pktinfo.ipi6_addr)) {
    664 		/* if query was sent to multicast address,
    665 		 * use source address selection in kernel.
    666 		 * XXX: anycast?
    667 		 */
    668 		memset(&p->pktinfo.ipi6_addr, 0, sizeof(p->pktinfo.ipi6_addr));
    669 
    670 	 	/* Random Delay between zero and MAX_ANYCAST_DELAY_TIME is
    671 		 * required if query was sent to anycast or multicast address.
    672 		 */
    673 		p->delay = (int) (MAX_ANYCAST_DELAY_TIME*rand()/(RAND_MAX+1.0));
    674 	} else {
    675 		p->delay = 0;
    676 	}
    677 
    678 	/* Step 10: Send the reply
    679 	 * XXX: with possible random delay */
    680 #if ENABLE_THREADS && HAVE_LIBPTHREAD
    681 	/* ni_send_thread() frees p */
    682 	if (pthread_create(&thread, &pattr, ni_send_thread, p)) {
    683 		ni_free(p->replydata);
    684 		ni_free(p);
    685 		return -1;
    686 	}
    687 #else
    688 	/* ni_send_fork() frees p */
    689 	if (ni_send_fork(p)) {
    690 		ni_free(p->replydata);
    691 		ni_free(p);
    692 		return -1;
    693 	}
    694 #endif
    695 
    696 	return 0;
    697 }
    698 
    699