/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
 *
 * Licensed 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.
 */

#if __APPLE__
// In Mac OS X 10.5 and later trying to use the daemon function gives a “‘daemon’ is deprecated”
// error, which prevents compilation because we build with "-Werror".
// Since this is supposed to be portable cross-platform code, we don't care that daemon is
// deprecated on Mac OS X 10.5, so we use this preprocessor trick to eliminate the error message.
#define daemon yes_we_know_that_daemon_is_deprecated_in_os_x_10_5_thankyou
#endif

#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <syslog.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <time.h>
#include <errno.h>

#if __APPLE__
#undef daemon
extern int daemon(int, int);
#endif

// Solaris doesn't have daemon(), so we define it here
#ifdef NOT_HAVE_DAEMON
#include "../mDNSPosix/mDNSUNP.h"		// For daemon()
#endif // NOT_HAVE_DAEMON

#include "dnsextd.h"
#include "../mDNSShared/uds_daemon.h"
#include "../mDNSShared/dnssd_ipc.h"
#include "../mDNSCore/uDNS.h"
#include "../mDNSShared/DebugServices.h"

// Compatibility workaround
#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#endif

//
// Constants
//
mDNSexport const char ProgramName[] = "dnsextd";

#define LOOPBACK					"127.0.0.1"
#if !defined(LISTENQ)
#	define LISTENQ					128					// tcp connection backlog
#endif
#define RECV_BUFLEN					9000                
#define LEASETABLE_INIT_NBUCKETS	256					// initial hashtable size (doubles as table fills)
#define EXPIRATION_INTERVAL			300					// check for expired records every 5 minutes
#define SRV_TTL						7200				// TTL For _dns-update SRV records
#define CONFIG_FILE					"/etc/dnsextd.conf"
#define TCP_SOCKET_FLAGS   			kTCPSocketFlags_UseTLS

// LLQ Lease bounds (seconds)
#define LLQ_MIN_LEASE (15 * 60)
#define LLQ_MAX_LEASE (120 * 60)
#define LLQ_LEASE_FUDGE 60

// LLQ SOA poll interval (microseconds)
#define LLQ_MONITOR_ERR_INTERVAL (60 * 1000000)
#define LLQ_MONITOR_INTERVAL 250000
#ifdef SIGINFO
#define INFO_SIGNAL SIGINFO
#else
#define INFO_SIGNAL SIGUSR1
#endif

#define SAME_INADDR(x,y) (*((mDNSu32 *)&x) == *((mDNSu32 *)&y))

//
// Data Structures
// Structs/fields that must be locked for thread safety are explicitly commented
//

// args passed to UDP request handler thread as void*

typedef struct
	{
    PktMsg pkt;
    struct sockaddr_in cliaddr;
    DaemonInfo *d;
	int sd;
	} UDPContext;

// args passed to TCP request handler thread as void*
typedef struct
	{
	PktMsg	pkt;
    struct sockaddr_in cliaddr;
    TCPSocket *sock;           // socket connected to client
    DaemonInfo *d;
	} TCPContext;

// args passed to UpdateAnswerList thread as void*
typedef struct
	{
    DaemonInfo *d;
    AnswerListElem *a;
	} UpdateAnswerListArgs;

//
// Global Variables
//

// booleans to determine runtime output
// read-only after initialization (no mutex protection)
static mDNSBool foreground = 0;
static mDNSBool verbose = 0;

// globals set via signal handler (accessed exclusively by main select loop and signal handler)
static mDNSBool terminate = 0;
static mDNSBool dumptable = 0;
static mDNSBool hangup    = 0;

// global for config file location
static char *   cfgfile   = NULL;

//
// Logging Routines
// Log messages are delivered to syslog unless -f option specified
//

// common message logging subroutine
mDNSlocal void PrintLog(const char *buffer)
	{
	if (foreground)
		{
		fprintf(stderr,"%s\n", buffer);
		fflush(stderr);
		}
	else				
		{
		openlog("dnsextd", LOG_CONS, LOG_DAEMON);
		syslog(LOG_ERR, "%s", buffer);
		closelog();
		}
	}

// Verbose Logging (conditional on -v option)
mDNSlocal void VLog(const char *format, ...)
	{
   	char buffer[512];
	va_list ptr;

	if (!verbose) return;
	va_start(ptr,format);
	buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
	va_end(ptr);
 	PrintLog(buffer);
	}

// Unconditional Logging
mDNSlocal void Log(const char *format, ...)
	{
   	char buffer[512];
	va_list ptr;

	va_start(ptr,format);
	buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
	va_end(ptr);
 	PrintLog(buffer);
	}

// Error Logging
// prints message "dnsextd <function>: <operation> - <error message>"
// must be compiled w/ -D_REENTRANT for thread-safe errno usage
mDNSlocal void LogErr(const char *fn, const char *operation)
	{
	char buf[512], errbuf[256];
	strerror_r(errno, errbuf, sizeof(errbuf));
	snprintf(buf, sizeof(buf), "%s: %s - %s", fn, operation, errbuf);
	PrintLog(buf);
	}

//
// Networking Utility Routines
//

// Convert DNS Message Header from Network to Host byte order
mDNSlocal void HdrNToH(PktMsg *pkt)
	{
	// Read the integer parts which are in IETF byte-order (MSB first, LSB second)
	mDNSu8 *ptr = (mDNSu8 *)&pkt->msg.h.numQuestions;
	pkt->msg.h.numQuestions   = (mDNSu16)((mDNSu16)ptr[0] <<  8 | ptr[1]);
	pkt->msg.h.numAnswers     = (mDNSu16)((mDNSu16)ptr[2] <<  8 | ptr[3]);
	pkt->msg.h.numAuthorities = (mDNSu16)((mDNSu16)ptr[4] <<  8 | ptr[5]);
	pkt->msg.h.numAdditionals = (mDNSu16)((mDNSu16)ptr[6] <<  8 | ptr[7]);
	}

// Convert DNS Message Header from Host to Network byte order
mDNSlocal void HdrHToN(PktMsg *pkt)
	{
	mDNSu16 numQuestions   = pkt->msg.h.numQuestions;
	mDNSu16 numAnswers     = pkt->msg.h.numAnswers;
	mDNSu16 numAuthorities = pkt->msg.h.numAuthorities;
	mDNSu16 numAdditionals = pkt->msg.h.numAdditionals;
	mDNSu8 *ptr = (mDNSu8 *)&pkt->msg.h.numQuestions;

	// Put all the integer values in IETF byte-order (MSB first, LSB second)
	*ptr++ = (mDNSu8)(numQuestions   >> 8);
	*ptr++ = (mDNSu8)(numQuestions   &  0xFF);
	*ptr++ = (mDNSu8)(numAnswers     >> 8);
	*ptr++ = (mDNSu8)(numAnswers     &  0xFF);
	*ptr++ = (mDNSu8)(numAuthorities >> 8);
	*ptr++ = (mDNSu8)(numAuthorities &  0xFF);
	*ptr++ = (mDNSu8)(numAdditionals >> 8);
	*ptr++ = (mDNSu8)(numAdditionals &  0xFF);
	}


// Add socket to event loop

mDNSlocal mStatus AddSourceToEventLoop( DaemonInfo * self, TCPSocket *sock, EventCallback callback, void *context )
	{
	EventSource	* newSource;
	mStatus			err = mStatus_NoError;
	
	if ( self->eventSources.LinkOffset == 0 )
		{
		InitLinkedList( &self->eventSources, offsetof( EventSource, next));
		}

	newSource = ( EventSource*) malloc( sizeof *newSource );
	if ( newSource == NULL )
		{
		err = mStatus_NoMemoryErr;
		goto exit;
		}

	newSource->callback = callback;
	newSource->context = context;
	newSource->sock = sock;
	newSource->fd = mDNSPlatformTCPGetFD( sock );

	AddToTail( &self->eventSources, newSource );

exit:

	return err;
	}


// Remove socket from event loop

mDNSlocal mStatus RemoveSourceFromEventLoop( DaemonInfo * self, TCPSocket *sock )
	{
	EventSource	*	source;
	mStatus			err;
	
	for ( source = ( EventSource* ) self->eventSources.Head; source; source = source->next )
		{
		if ( source->sock == sock )
			{
			RemoveFromList( &self->eventSources, source );

			free( source );
			err = mStatus_NoError;
			goto exit;
			}
		}

	err = mStatus_NoSuchNameErr;

exit:

	return err;
	}

// create a socket connected to nameserver
// caller terminates connection via close()
mDNSlocal TCPSocket *ConnectToServer(DaemonInfo *d)
	{
	int ntries = 0, retry = 0;

	while (1)
		{
		mDNSIPPort port = zeroIPPort;
		int fd;

		TCPSocket *sock = mDNSPlatformTCPSocket( NULL, 0, &port );
		if ( !sock ) { LogErr("ConnectToServer", "socket");  return NULL; }
		fd = mDNSPlatformTCPGetFD( sock );
		if (!connect( fd, (struct sockaddr *)&d->ns_addr, sizeof(d->ns_addr))) return sock;
		mDNSPlatformTCPCloseConnection( sock );
		if (++ntries < 10)
			{
			LogErr("ConnectToServer", "connect");
			Log("ConnectToServer - retrying connection");
			if (!retry) retry = 500000 + random() % 500000;
			usleep(retry);
			retry *= 2;
			}
		else { Log("ConnectToServer - %d failed attempts.  Aborting.", ntries); return NULL; }
		}
	}

// send an entire block of data over a connected socket
mDNSlocal int MySend(TCPSocket *sock, const void *msg, int len)
	{
	int selectval, n, nsent = 0;
	fd_set wset;
	struct timeval timeout = { 3, 0 };  // until we remove all calls from main thread, keep timeout short

	while (nsent < len)
		{
		int fd;

		FD_ZERO(&wset);

		fd = mDNSPlatformTCPGetFD( sock );

		FD_SET( fd, &wset );
		selectval = select( fd+1, NULL, &wset, NULL, &timeout);
		if (selectval < 0) { LogErr("MySend", "select");  return -1; }
		if (!selectval || !FD_ISSET(fd, &wset)) { Log("MySend - timeout"); return -1; }

		n = mDNSPlatformWriteTCP( sock, ( char* ) msg + nsent, len - nsent);

		if (n < 0) { LogErr("MySend", "send");  return -1; }
		nsent += n;
		}
	return 0;
	}

// Transmit a DNS message, prefixed by its length, over TCP, blocking if necessary
mDNSlocal int SendPacket(TCPSocket *sock, PktMsg *pkt)
	{
	// send the lenth, in network byte order
	mDNSu16 len = htons((mDNSu16)pkt->len);
	if (MySend(sock, &len, sizeof(len)) < 0) return -1;

	// send the message
	VLog("SendPacket Q:%d A:%d A:%d A:%d ",
		ntohs(pkt->msg.h.numQuestions),
		ntohs(pkt->msg.h.numAnswers),
		ntohs(pkt->msg.h.numAuthorities),
		ntohs(pkt->msg.h.numAdditionals));
	return MySend(sock, &pkt->msg, pkt->len);
	}

// Receive len bytes, waiting until we have all of them.
// Returns number of bytes read (which should always be the number asked for).
static int my_recv(TCPSocket *sock, void *const buf, const int len, mDNSBool * closed)
    {
    // Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions;
    // use an explicit while() loop instead.
    // Also, don't try to do '+=' arithmetic on the original "void *" pointer --
    // arithmetic on "void *" pointers is compiler-dependent.

	fd_set rset;
	struct timeval timeout = { 3, 0 };  // until we remove all calls from main thread, keep timeout short	
    int selectval, remaining = len;
    char *ptr = (char *)buf;
	ssize_t num_read;

	while (remaining)
    	{
		int fd;

		fd = mDNSPlatformTCPGetFD( sock );

		FD_ZERO(&rset);
		FD_SET(fd, &rset);
		selectval = select(fd+1, &rset, NULL, NULL, &timeout);
		if (selectval < 0) { LogErr("my_recv", "select");  return -1; }
		if (!selectval || !FD_ISSET(fd, &rset))
			{
			Log("my_recv - timeout");
			return -1;
			}

		num_read = mDNSPlatformReadTCP( sock, ptr, remaining, closed );

    	if (((num_read == 0) && *closed) || (num_read < 0) || (num_read > remaining)) return -1;
		if (num_read == 0) return 0;
    	ptr       += num_read;
    	remaining -= num_read;
    	}
    return(len);
    }

// Return a DNS Message read off of a TCP socket, or NULL on failure
// If storage is non-null, result is placed in that buffer.  Otherwise,
// returned value is allocated with Malloc, and contains sufficient extra
// storage for a Lease OPT RR

mDNSlocal PktMsg*
RecvPacket
	(
	TCPSocket *	sock,
	PktMsg		*	storage,
	mDNSBool	*	closed
	)
	{
	int				nread;
	int 			allocsize;
	mDNSu16			msglen = 0;
	PktMsg		*	pkt = NULL;
	unsigned int	srclen;
	int				fd;
	mStatus			err = 0;

	fd = mDNSPlatformTCPGetFD( sock );
	
	nread = my_recv( sock, &msglen, sizeof( msglen ), closed );
	
	require_action_quiet( nread != -1, exit, err = mStatus_UnknownErr );
	require_action_quiet( nread > 0, exit, err = mStatus_NoError );

	msglen = ntohs( msglen );
	require_action_quiet( nread == sizeof( msglen ), exit, err = mStatus_UnknownErr; Log( "Could not read length field of message") );

	if ( storage )
		{
		require_action_quiet( msglen <= sizeof( storage->msg ), exit, err = mStatus_UnknownErr; Log( "RecvPacket: provided buffer too small." ) );
		pkt = storage;
		}
	else
		{
		// buffer extra space to add an OPT RR

		if ( msglen > sizeof(DNSMessage))
			{
			allocsize = sizeof(PktMsg) - sizeof(DNSMessage) + msglen;
			}
		else
			{
			allocsize = sizeof(PktMsg);
			}

		pkt = malloc(allocsize);
		require_action_quiet( pkt, exit, err = mStatus_NoMemoryErr; LogErr( "RecvPacket", "malloc" ) );
		mDNSPlatformMemZero( pkt, sizeof( *pkt ) );
		}
	
	pkt->len = msglen;
	srclen = sizeof(pkt->src);

	if ( getpeername( fd, ( struct sockaddr* ) &pkt->src, &srclen ) || ( srclen != sizeof( pkt->src ) ) )
		{
		LogErr("RecvPacket", "getpeername");
		mDNSPlatformMemZero(&pkt->src, sizeof(pkt->src));
		}

	nread = my_recv(sock, &pkt->msg, msglen, closed );
	require_action_quiet( nread >= 0, exit, err = mStatus_UnknownErr ; LogErr( "RecvPacket", "recv" ) );
	require_action_quiet( nread == msglen, exit, err = mStatus_UnknownErr ; Log( "Could not read entire message" ) );
	require_action_quiet( pkt->len >= sizeof( DNSMessageHeader ), exit, err = mStatus_UnknownErr ; Log( "RecvPacket: Message too short (%d bytes)", pkt->len ) );

exit:

	if ( err && pkt )
		{
		if ( pkt != storage )
			{
			free(pkt);
			}

		pkt = NULL;
		}

	return pkt;
	}


mDNSlocal DNSZone*
FindZone
	(
	DaemonInfo	*	self,
	domainname	*	name
	)
	{
	DNSZone * zone;

	for ( zone = self->zones; zone; zone = zone->next )
		{
		if ( SameDomainName( &zone->name, name ) )
			{
				break;
			}
		}

		return zone;
	}


mDNSlocal mDNSBool
ZoneHandlesName
	(
	const domainname * zname,
	const domainname * dname
	)
	{
	mDNSu16	i = DomainNameLength( zname );
	mDNSu16	j = DomainNameLength( dname );

	if ( ( i == ( MAX_DOMAIN_NAME + 1 ) ) || ( j == ( MAX_DOMAIN_NAME + 1 ) ) || ( i > j )  || ( memcmp( zname->c, dname->c + ( j - i ), i ) != 0 ) )
		{
		return mDNSfalse;
		}

	return mDNStrue;
	}


mDNSlocal mDNSBool IsQuery( PktMsg * pkt )
	{
	return ( pkt->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask ) == (mDNSu8) ( kDNSFlag0_QR_Query | kDNSFlag0_OP_StdQuery );
	}


mDNSlocal mDNSBool IsUpdate( PktMsg * pkt )
	{
	return ( pkt->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask ) == (mDNSu8) ( kDNSFlag0_OP_Update );
	}


mDNSlocal mDNSBool IsNotify(PktMsg *pkt)
	{
	return ( pkt->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask ) == ( mDNSu8) ( kDNSFlag0_OP_Notify );
	}


mDNSlocal mDNSBool IsLLQRequest(PktMsg *pkt)
	{
	const mDNSu8 *ptr = NULL, *end = (mDNSu8 *)&pkt->msg + pkt->len;
	LargeCacheRecord lcr;
	int i;
	mDNSBool result = mDNSfalse;
	
	HdrNToH(pkt);
	if ((mDNSu8)(pkt->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask) != (mDNSu8)(kDNSFlag0_QR_Query | kDNSFlag0_OP_StdQuery)) goto end;

	if (!pkt->msg.h.numAdditionals) goto end;
	ptr = LocateAdditionals(&pkt->msg, end);
	if (!ptr) goto end;

	// find last Additional info.
	for (i = 0; i < pkt->msg.h.numAdditionals; i++)
		{
		ptr = GetLargeResourceRecord(NULL, &pkt->msg, ptr, end, 0, kDNSRecordTypePacketAdd, &lcr);
		if (!ptr) { Log("Unable to read additional record"); goto end; }
		}

	if ( lcr.r.resrec.rrtype == kDNSType_OPT && lcr.r.resrec.rdlength >= DNSOpt_LLQData_Space && lcr.r.resrec.rdata->u.opt[0].opt == kDNSOpt_LLQ )
		{
		result = mDNStrue;
		}

	end:
	HdrHToN(pkt);
	return result;
	}

// !!!KRS implement properly
mDNSlocal mDNSBool IsLLQAck(PktMsg *pkt)
	{
	if ((pkt->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask ) == (mDNSu8) ( kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery ) &&
		pkt->msg.h.numQuestions && !pkt->msg.h.numAnswers && !pkt->msg.h.numAuthorities) return mDNStrue;
	return mDNSfalse;
	}


mDNSlocal mDNSBool
IsPublicSRV
	(
	DaemonInfo	*	self,
	DNSQuestion	*	q
	)
	{
	DNameListElem	*	elem;
	mDNSBool			ret		= mDNSfalse;
	int					i		= ( int ) DomainNameLength( &q->qname ) - 1;

	for ( elem = self->public_names; elem; elem = elem->next )
		{
		int	j = ( int ) DomainNameLength( &elem->name ) - 1;

		if ( i > j )
			{
			for ( ; i >= 0; i--, j-- )
				{
				if ( q->qname.c[ i ] != elem->name.c[ j ] )
					{
					ret = mDNStrue;
					goto exit;
					}
				}
			}
		}

exit:

	return ret;
	}


mDNSlocal void
SetZone
	(
	DaemonInfo	* self,
	PktMsg		* pkt
	)
	{
	domainname			zname;
	mDNSu8				QR_OP;
	const mDNSu8	*	ptr = pkt->msg.data;
	mDNSBool			exception = mDNSfalse;

	// Initialize

	pkt->zone			= NULL;
	pkt->isZonePublic	= mDNStrue;
	zname.c[0]			= '\0';

	// Figure out what type of packet this is

	QR_OP = ( mDNSu8 ) ( pkt->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask );

	if ( IsQuery( pkt ) )
		{
		DNSQuestion question;

		// It's a query

		ptr = getQuestion( &pkt->msg, ptr, ( ( mDNSu8* ) &pkt->msg ) + pkt->len, NULL, &question );

		AppendDomainName( &zname, &question.qname );

		exception = ( ( question.qtype == kDNSType_SOA ) || ( question.qtype == kDNSType_NS ) || ( ( question.qtype == kDNSType_SRV ) && IsPublicSRV( self, &question ) ) );
		}
	else if ( IsUpdate( pkt ) )
		{
		DNSQuestion question;

		// It's an update.  The format of the zone section is the same as the format for the question section
		// according to RFC 2136, so we'll just treat this as a question so we can get at the zone.

		ptr = getQuestion( &pkt->msg, ptr, ( ( mDNSu8* ) &pkt->msg ) + pkt->len, NULL, &question );

		AppendDomainName( &zname, &question.qname );

		exception = mDNSfalse;
		}

	if ( zname.c[0] != '\0' )
		{
		// Find the right zone

		for ( pkt->zone = self->zones; pkt->zone; pkt->zone = pkt->zone->next )
			{
			if ( ZoneHandlesName( &pkt->zone->name, &zname ) )
				{
				VLog( "found correct zone %##s for query", pkt->zone->name.c );

				pkt->isZonePublic = ( ( pkt->zone->type == kDNSZonePublic ) || exception );

				VLog( "zone %##s is %s", pkt->zone->name.c, ( pkt->isZonePublic ) ? "public" : "private" );

				break;
				}
			}
		}
	}


mDNSlocal int
UDPServerTransaction(const DaemonInfo *d, const PktMsg *request, PktMsg *reply, mDNSBool *trunc)
	{
	fd_set			rset;
	struct timeval	timeout = { 3, 0 };  // until we remove all calls from main thread, keep timeout short
	int				sd;
	int				res;
	mStatus			err = mStatus_NoError;

	// Initialize

	*trunc = mDNSfalse;

	// Create a socket

 	sd = socket( AF_INET, SOCK_DGRAM, 0 );
	require_action( sd >= 0, exit, err = mStatus_UnknownErr; LogErr( "UDPServerTransaction", "socket" ) );

	// Send the packet to the nameserver

	VLog("UDPServerTransaction Q:%d A:%d A:%d A:%d ",
		ntohs(request->msg.h.numQuestions),
		ntohs(request->msg.h.numAnswers),
		ntohs(request->msg.h.numAuthorities),
		ntohs(request->msg.h.numAdditionals));
	res = sendto( sd, (char *)&request->msg, request->len, 0, ( struct sockaddr* ) &d->ns_addr, sizeof( d->ns_addr ) );
	require_action( res == (int) request->len, exit, err = mStatus_UnknownErr; LogErr( "UDPServerTransaction", "sendto" ) );

	// Wait for reply

	FD_ZERO( &rset );
	FD_SET( sd, &rset );
	res = select( sd + 1, &rset, NULL, NULL, &timeout );
	require_action( res >= 0, exit, err = mStatus_UnknownErr; LogErr( "UDPServerTransaction", "select" ) );
	require_action( ( res > 0 ) && FD_ISSET( sd, &rset ), exit, err = mStatus_UnknownErr; Log( "UDPServerTransaction - timeout" ) );

	// Receive reply

	reply->len = recvfrom( sd, &reply->msg, sizeof(reply->msg), 0, NULL, NULL );
	require_action( ( ( int ) reply->len ) >= 0, exit, err = mStatus_UnknownErr; LogErr( "UDPServerTransaction", "recvfrom" ) );
	require_action( reply->len >= sizeof( DNSMessageHeader ), exit, err = mStatus_UnknownErr; Log( "UDPServerTransaction - Message too short (%d bytes)", reply->len ) );

	// Check for truncation bit

	if ( reply->msg.h.flags.b[0] & kDNSFlag0_TC )
		{
		*trunc = mDNStrue;
		}

exit:

	if ( sd >= 0 )
		{
		close( sd );
		}

	return err;
	}

//
// Dynamic Update Utility Routines
//

// check if a request and server response complete a successful dynamic update
mDNSlocal mDNSBool SuccessfulUpdateTransaction(PktMsg *request, PktMsg *reply)
	{
	char buf[32];
	char *vlogmsg = NULL;
	
	// check messages
	if (!request || !reply) { vlogmsg = "NULL message"; goto failure; }
	if (request->len < sizeof(DNSMessageHeader) || reply->len < sizeof(DNSMessageHeader)) { vlogmsg = "Malformatted message"; goto failure; }

	// check request operation
	if ((request->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask) != (request->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask))
		{ vlogmsg = "Request opcode not an update"; goto failure; }

	// check result
	if ((reply->msg.h.flags.b[1] & kDNSFlag1_RC_Mask)) { vlogmsg = "Reply contains non-zero rcode";  goto failure; }
	if ((reply->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask) != (kDNSFlag0_OP_Update | kDNSFlag0_QR_Response))
		{ vlogmsg = "Reply opcode not an update response"; goto failure; }

	VLog("Successful update from %s", inet_ntop(AF_INET, &request->src.sin_addr, buf, 32));
	return mDNStrue;

	failure:
	VLog("Request %s: %s", inet_ntop(AF_INET, &request->src.sin_addr, buf, 32), vlogmsg);
	return mDNSfalse;
	}

// Allocate an appropriately sized CacheRecord and copy data from original.
// Name pointer in CacheRecord object is set to point to the name specified
//
mDNSlocal CacheRecord *CopyCacheRecord(const CacheRecord *orig, domainname *name)
	{
	CacheRecord *cr;
	size_t size = sizeof(*cr);
	if (orig->resrec.rdlength > InlineCacheRDSize) size += orig->resrec.rdlength - InlineCacheRDSize;
	cr = malloc(size);
	if (!cr) { LogErr("CopyCacheRecord", "malloc"); return NULL; }
	memcpy(cr, orig, size);
	cr->resrec.rdata = (RData*)&cr->smallrdatastorage;
	cr->resrec.name = name;
	
	return cr;
	}


//
// Lease Hashtable Utility Routines
//

// double hash table size
// caller must lock table prior to invocation
mDNSlocal void RehashTable(DaemonInfo *d)
	{
	RRTableElem *ptr, *tmp, **new;
	int i, bucket, newnbuckets = d->nbuckets * 2;

	VLog("Rehashing lease table (new size %d buckets)", newnbuckets);
	new = malloc(sizeof(RRTableElem *) * newnbuckets);
	if (!new) { LogErr("RehashTable", "malloc");  return; }
	mDNSPlatformMemZero(new, newnbuckets * sizeof(RRTableElem *));

	for (i = 0; i < d->nbuckets; i++)
		{
		ptr = d->table[i];
		while (ptr)
			{
			bucket = ptr->rr.resrec.namehash % newnbuckets;
			tmp = ptr;
			ptr = ptr->next;
			tmp->next = new[bucket];
			new[bucket] = tmp;
			}
		}
	d->nbuckets = newnbuckets;
	free(d->table);
	d->table = new;
	}

// print entire contents of hashtable, invoked via SIGINFO
mDNSlocal void PrintLeaseTable(DaemonInfo *d)
	{
	int i;
	RRTableElem *ptr;
	char rrbuf[MaxMsg], addrbuf[16];
	struct timeval now;
	int hr, min, sec;

	if (gettimeofday(&now, NULL)) { LogErr("PrintTable", "gettimeofday"); return; }
	if (pthread_mutex_lock(&d->tablelock)) { LogErr("PrintTable", "pthread_mutex_lock"); return; }
	
	Log("Dumping Lease Table Contents (table contains %d resource records)", d->nelems);
	for (i = 0; i < d->nbuckets; i++)
		{
		for (ptr = d->table[i]; ptr; ptr = ptr->next)
			{
			hr = ((ptr->expire - now.tv_sec) / 60) / 60;
			min = ((ptr->expire - now.tv_sec) / 60) % 60;
			sec = (ptr->expire - now.tv_sec) % 60;
			Log("Update from %s, Expires in %d:%d:%d\n\t%s", inet_ntop(AF_INET, &ptr->cli.sin_addr, addrbuf, 16), hr, min, sec,
				GetRRDisplayString_rdb(&ptr->rr.resrec, &ptr->rr.resrec.rdata->u, rrbuf));
			}
		}
	pthread_mutex_unlock(&d->tablelock);
	}

//
// Startup SRV Registration Routines 
// Register _dns-update._udp/_tcp.<zone> SRV records indicating the port on which
// the daemon accepts requests  
//

// delete all RRS of a given name/type
mDNSlocal mDNSu8 *putRRSetDeletion(DNSMessage *msg, mDNSu8 *ptr, mDNSu8 *limit,  ResourceRecord *rr)
	{
	ptr = putDomainNameAsLabels(msg, ptr, limit, rr->name);
	if (!ptr || ptr + 10 >= limit) return NULL;  // out of space
	ptr[0] = (mDNSu8)(rr->rrtype  >> 8);
	ptr[1] = (mDNSu8)(rr->rrtype  &  0xFF);
	ptr[2] = (mDNSu8)((mDNSu16)kDNSQClass_ANY >> 8);
	ptr[3] = (mDNSu8)((mDNSu16)kDNSQClass_ANY &  0xFF);
	mDNSPlatformMemZero(ptr+4, sizeof(rr->rroriginalttl) + sizeof(rr->rdlength)); // zero ttl/rdata
	msg->h.mDNS_numUpdates++;
	return ptr + 10;
	}

mDNSlocal mDNSu8 *PutUpdateSRV(DaemonInfo *d, DNSZone * zone, PktMsg *pkt, mDNSu8 *ptr, char *regtype, mDNSIPPort port, mDNSBool registration)
	{
	AuthRecord rr;
	char hostname[1024], buf[MaxMsg];
	mDNSu8 *end = (mDNSu8 *)&pkt->msg + sizeof(DNSMessage);
	
	( void ) d;

	mDNS_SetupResourceRecord(&rr, NULL, 0, kDNSType_SRV, SRV_TTL, kDNSRecordTypeUnique, AuthRecordAny, NULL, NULL);
	rr.resrec.rrclass = kDNSClass_IN;
	rr.resrec.rdata->u.srv.priority = 0;
	rr.resrec.rdata->u.srv.weight   = 0;
	rr.resrec.rdata->u.srv.port     = port;
	if (gethostname(hostname, 1024) < 0 || !MakeDomainNameFromDNSNameString(&rr.resrec.rdata->u.srv.target, hostname))
		rr.resrec.rdata->u.srv.target.c[0] = '\0';
	
	MakeDomainNameFromDNSNameString(&rr.namestorage, regtype);
	AppendDomainName(&rr.namestorage, &zone->name);
	VLog("%s  %s", registration ? "Registering SRV record" : "Deleting existing RRSet",
		 GetRRDisplayString_rdb(&rr.resrec, &rr.resrec.rdata->u, buf));
	if (registration) ptr = PutResourceRecord(&pkt->msg, ptr, &pkt->msg.h.mDNS_numUpdates, &rr.resrec);
	else              ptr = putRRSetDeletion(&pkt->msg, ptr, end, &rr.resrec);
	return ptr;
	}


// perform dynamic update.
// specify deletion by passing false for the register parameter, otherwise register the records.
mDNSlocal int UpdateSRV(DaemonInfo *d, mDNSBool registration)
	{
	TCPSocket *sock = NULL;
	DNSZone * zone;
	int err = mStatus_NoError;

	sock = ConnectToServer( d );
	require_action( sock, exit, err = mStatus_UnknownErr; Log( "UpdateSRV: ConnectToServer failed" ) );

	for ( zone = d->zones; zone; zone = zone->next )
		{
		PktMsg pkt;
		mDNSu8 *ptr = pkt.msg.data;
		mDNSu8 *end = (mDNSu8 *)&pkt.msg + sizeof(DNSMessage);
		PktMsg *reply = NULL;
		mDNSBool closed;
		mDNSBool ok;

		// Initialize message
		InitializeDNSMessage(&pkt.msg.h, zeroID, UpdateReqFlags);
		pkt.src.sin_addr.s_addr = zerov4Addr.NotAnInteger; // address field set solely for verbose logging in subroutines
		pkt.src.sin_family = AF_INET;

		// format message body
		ptr = putZone(&pkt.msg, ptr, end, &zone->name, mDNSOpaque16fromIntVal(kDNSClass_IN));
		require_action( ptr, exit, err = mStatus_UnknownErr; Log("UpdateSRV: Error constructing lease expiration update" ) );
	
	   if ( zone->type == kDNSZonePrivate )
            {
            ptr = PutUpdateSRV(d, zone, &pkt, ptr, "_dns-update-tls._tcp.", d->private_port, registration);
            require_action( ptr, exit, err = mStatus_UnknownErr; Log("UpdateSRV: Error constructing lease expiration update" ) );
            ptr = PutUpdateSRV(d, zone, &pkt, ptr, "_dns-query-tls._tcp.", d->private_port, registration);
            require_action( ptr, exit, err = mStatus_UnknownErr; Log("UpdateSRV: Error constructing lease expiration update" ) );
            ptr = PutUpdateSRV(d, zone, &pkt, ptr, "_dns-llq-tls._tcp.", d->private_port, registration);
            require_action( ptr, exit, err = mStatus_UnknownErr; Log("UpdateSRV: Error constructing lease expiration update" ) );
            
			if ( !registration )
				{
				ptr = PutUpdateSRV(d, zone, &pkt, ptr, "_dns-update._udp.", d->llq_port, registration);
				require_action( ptr, exit, err = mStatus_UnknownErr; Log("UpdateSRV: Error constructing lease expiration update" ) );
				ptr = PutUpdateSRV(d, zone, &pkt, ptr, "_dns-llq._udp.", d->llq_port, registration);
				require_action( ptr, exit, err = mStatus_UnknownErr; Log("UpdateSRV: Error constructing lease expiration update" ) );
				}
			}
        else
            {
			if ( !registration )
				{
				ptr = PutUpdateSRV(d, zone, &pkt, ptr, "_dns-update-tls.", d->private_port, registration);
				require_action( ptr, exit, err = mStatus_UnknownErr; Log("UpdateSRV: Error constructing lease expiration update" ) );
				ptr = PutUpdateSRV(d, zone, &pkt, ptr, "_dns-query-tls.", d->private_port, registration);
				require_action( ptr, exit, err = mStatus_UnknownErr; Log("UpdateSRV: Error constructing lease expiration update" ) );
				ptr = PutUpdateSRV(d, zone, &pkt, ptr, "_dns-llq-tls.", d->private_port, registration);
				require_action( ptr, exit, err = mStatus_UnknownErr; Log("UpdateSRV: Error constructing lease expiration update" ) );
				}

			ptr = PutUpdateSRV(d, zone, &pkt, ptr, "_dns-update._udp.", d->llq_port, registration);
            require_action( ptr, exit, err = mStatus_UnknownErr; Log("UpdateSRV: Error constructing lease expiration update" ) );
            ptr = PutUpdateSRV(d, zone, &pkt, ptr, "_dns-llq._udp.", d->llq_port, registration);
            require_action( ptr, exit, err = mStatus_UnknownErr; Log("UpdateSRV: Error constructing lease expiration update" ) );
			}

		HdrHToN(&pkt);

		if ( zone->updateKeys )
			{
			DNSDigest_SignMessage( &pkt.msg, &ptr, zone->updateKeys, 0 );
			require_action( ptr, exit, Log("UpdateSRV: Error constructing lease expiration update" ) );
			}

		pkt.len = ptr - (mDNSu8 *)&pkt.msg;
	
		// send message, receive reply

		err = SendPacket( sock, &pkt );
		require_action( !err, exit, Log( "UpdateSRV: SendPacket failed" ) );

		reply = RecvPacket( sock, NULL, &closed );
		require_action( reply, exit, err = mStatus_UnknownErr; Log( "UpdateSRV: RecvPacket returned NULL" ) );

		ok = SuccessfulUpdateTransaction( &pkt, reply );

		if ( !ok )
			{
			Log("SRV record registration failed with rcode %d", reply->msg.h.flags.b[1] & kDNSFlag1_RC_Mask);
			}

		free( reply );
		}
	
exit:

	if ( sock )
		{
		mDNSPlatformTCPCloseConnection( sock );
		}

	return err;
	}

// wrapper routines/macros
#define ClearUpdateSRV(d) UpdateSRV(d, 0)

// clear any existing records prior to registration
mDNSlocal int SetUpdateSRV(DaemonInfo *d)
	{
	int err;

	err = ClearUpdateSRV(d);         // clear any existing record
	if (!err) err = UpdateSRV(d, 1);
	return err;
	}

//
// Argument Parsing and Configuration
//

mDNSlocal void PrintUsage(void)
	{
	fprintf(stderr, "Usage: dnsextd [-f <config file>] [-vhd] ...\n"
			"Use \"dnsextd -h\" for help\n");
	}

mDNSlocal void PrintHelp(void)
	{
	fprintf(stderr, "\n\n");
	PrintUsage();

	fprintf(stderr,
			"dnsextd is a daemon that implements DNS extensions supporting Dynamic DNS Update Leases\n"
            "and Long Lived Queries, used in Wide-Area DNS Service Discovery, on behalf of name servers\n"
			"that do not natively support these extensions.  (See dns-sd.org for more info on DNS Service\n"
			"Discovery, Update Leases, and Long Lived Queries.)\n\n"

            "dnsextd requires one argument,the zone, which is the domain for which Update Leases\n"
            "and Long Lived Queries are to be administered.  dnsextd communicates directly with the\n"
			"primary master server for this zone.\n\n"

			"The options are as follows:\n\n"

			"-f    Specify configuration file. The default is /etc/dnsextd.conf.\n\n"

			"-d    Run daemon in foreground.\n\n"

			"-h    Print help.\n\n"

			"-v    Verbose output.\n\n"
		);
	}


// Note: ProcessArgs called before process is daemonized, and therefore must open no descriptors
// returns 0 (success) if program is to continue execution
// output control arguments (-f, -v) do not affect this routine
mDNSlocal int ProcessArgs(int argc, char *argv[], DaemonInfo *d)
	{
	DNSZone	*	zone;
	int			opt;
	int			err = 0;
	
	cfgfile = strdup( CONFIG_FILE );
	require_action( cfgfile, arg_error, err = mStatus_NoMemoryErr );

    // defaults, may be overriden by command option

	// setup our sockaddr

	mDNSPlatformMemZero( &d->addr, sizeof( d->addr ) );
	d->addr.sin_addr.s_addr	= zerov4Addr.NotAnInteger;
	d->addr.sin_port		= UnicastDNSPort.NotAnInteger;
	d->addr.sin_family		= AF_INET;
#ifndef NOT_HAVE_SA_LEN
	d->addr.sin_len			= sizeof( d->addr );
#endif

	// setup nameserver's sockaddr

	mDNSPlatformMemZero(&d->ns_addr, sizeof(d->ns_addr));
	d->ns_addr.sin_family	= AF_INET;
	inet_pton( AF_INET, LOOPBACK, &d->ns_addr.sin_addr );
	d->ns_addr.sin_port		= NSIPCPort.NotAnInteger;
#ifndef NOT_HAVE_SA_LEN
	d->ns_addr.sin_len		= sizeof( d->ns_addr );
#endif

	// setup our ports

	d->private_port = PrivateDNSPort;
	d->llq_port     = DNSEXTPort;

	while ((opt = getopt(argc, argv, "f:hdv")) != -1)
		{
		switch(opt)
			{
			case 'f': free( cfgfile ); cfgfile = strdup( optarg ); require_action( cfgfile, arg_error, err = mStatus_NoMemoryErr ); break;
			case 'h': PrintHelp();    return -1;
			case 'd': foreground = 1; break;		// Also used when launched via OS X's launchd mechanism
			case 'v': verbose = 1;    break;
			default:  goto arg_error;
			}
		}

	err = ParseConfig( d, cfgfile );
	require_noerr( err, arg_error );

	// Make sure we've specified some zones

	require_action( d->zones, arg_error, err = mStatus_UnknownErr );

	// if we have a shared secret, use it for the entire zone

	for ( zone = d->zones; zone; zone = zone->next )
		{
		if ( zone->updateKeys )
			{
			AssignDomainName( &zone->updateKeys->domain, &zone->name );
			}
		}

	return 0;
	
arg_error:

	PrintUsage();
	return -1;
	}


//
// Initialization Routines
//

// Allocate memory, initialize locks and bookkeeping variables
mDNSlocal int InitLeaseTable(DaemonInfo *d)
	{
	if (pthread_mutex_init(&d->tablelock, NULL)) { LogErr("InitLeaseTable", "pthread_mutex_init"); return -1; }
	d->nbuckets = LEASETABLE_INIT_NBUCKETS;
	d->nelems = 0;
	d->table = malloc(sizeof(RRTableElem *) * LEASETABLE_INIT_NBUCKETS);
	if (!d->table) { LogErr("InitLeaseTable", "malloc"); return -1; }
	mDNSPlatformMemZero(d->table, sizeof(RRTableElem *) * LEASETABLE_INIT_NBUCKETS);
	return 0;
	}


mDNSlocal int
SetupSockets
	(
	DaemonInfo * self
	)
	{
	static const int kOn = 1;
	int					sockpair[2];
	mDNSBool			private = mDNSfalse;
	struct sockaddr_in	daddr;
	DNSZone			*	zone;
	mStatus				err = 0;
	
	// set up sockets on which we all ns requests

	self->tcpsd = socket( AF_INET, SOCK_STREAM, 0 );
	require_action( dnssd_SocketValid(self->tcpsd), exit, err = mStatus_UnknownErr; LogErr( "SetupSockets", "socket" ) );

#if defined(SO_REUSEADDR)
	err = setsockopt(self->tcpsd, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
	require_action( !err, exit, LogErr( "SetupSockets", "SO_REUSEADDR self->tcpsd" ) );
#endif

	err = bind( self->tcpsd, ( struct sockaddr* ) &self->addr, sizeof( self->addr ) );
	require_action( !err, exit, LogErr( "SetupSockets", "bind self->tcpsd" ) );

	err = listen( self->tcpsd, LISTENQ );
	require_action( !err, exit, LogErr( "SetupSockets", "listen" ) );

	self->udpsd = socket( AF_INET, SOCK_DGRAM, 0 );
	require_action( dnssd_SocketValid(self->udpsd), exit, err = mStatus_UnknownErr; LogErr( "SetupSockets", "socket" ) );

#if defined(SO_REUSEADDR)
	err = setsockopt(self->udpsd, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
	require_action( !err, exit, LogErr( "SetupSockets", "SO_REUSEADDR self->udpsd" ) );
#endif

	err = bind( self->udpsd, ( struct sockaddr* ) &self->addr, sizeof( self->addr ) );
	require_action( !err, exit, LogErr( "SetupSockets", "bind self->udpsd" ) );

	// set up sockets on which we receive llq requests

	mDNSPlatformMemZero(&self->llq_addr, sizeof(self->llq_addr));
	self->llq_addr.sin_family		= AF_INET;
	self->llq_addr.sin_addr.s_addr	= zerov4Addr.NotAnInteger;
	self->llq_addr.sin_port			= ( self->llq_port.NotAnInteger ) ? self->llq_port.NotAnInteger : DNSEXTPort.NotAnInteger;

	if (self->llq_addr.sin_port == self->addr.sin_port)
		{
		self->llq_tcpsd = self->tcpsd;
		self->llq_udpsd = self->udpsd;
		}
	else
		{
		self->llq_tcpsd = socket( AF_INET, SOCK_STREAM, 0 );
		require_action( dnssd_SocketValid(self->llq_tcpsd), exit, err = mStatus_UnknownErr; LogErr( "SetupSockets", "socket" ) );
	
#if defined(SO_REUSEADDR)
		err = setsockopt(self->llq_tcpsd, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
		require_action( !err, exit, LogErr( "SetupSockets", "SO_REUSEADDR self->llq_tcpsd" ) );
#endif
	
		err = bind( self->llq_tcpsd, ( struct sockaddr* ) &self->llq_addr, sizeof( self->llq_addr ) );
		require_action( !err, exit, LogErr( "SetupSockets", "bind self->llq_tcpsd" ) );
	
		err = listen( self->llq_tcpsd, LISTENQ );
		require_action( !err, exit, LogErr( "SetupSockets", "listen" ) );
	
		self->llq_udpsd = socket( AF_INET, SOCK_DGRAM, 0 );
		require_action( dnssd_SocketValid(self->llq_udpsd), exit, err = mStatus_UnknownErr; LogErr( "SetupSockets", "socket" ) );
	
#if defined(SO_REUSEADDR)
		err = setsockopt(self->llq_udpsd, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
		require_action( !err, exit, LogErr( "SetupSockets", "SO_REUSEADDR self->llq_udpsd" ) );
#endif
	
		err = bind(self->llq_udpsd, ( struct sockaddr* ) &self->llq_addr, sizeof( self->llq_addr ) );
		require_action( !err, exit, LogErr( "SetupSockets", "bind self->llq_udpsd" ) );
		}

	// set up Unix domain socket pair for LLQ polling thread to signal main thread that a change to the zone occurred

	err = socketpair( AF_LOCAL, SOCK_STREAM, 0, sockpair );
	require_action( !err, exit, LogErr( "SetupSockets", "socketpair" ) );

	self->LLQEventListenSock = sockpair[0];
	self->LLQEventNotifySock = sockpair[1];

	// set up socket on which we receive private requests

	self->llq_tcpsd = socket( AF_INET, SOCK_STREAM, 0 );
	require_action( dnssd_SocketValid(self->tlssd), exit, err = mStatus_UnknownErr; LogErr( "SetupSockets", "socket" ) );
	mDNSPlatformMemZero(&daddr, sizeof(daddr));
	daddr.sin_family		= AF_INET;
	daddr.sin_addr.s_addr	= zerov4Addr.NotAnInteger;
	daddr.sin_port			= ( self->private_port.NotAnInteger ) ? self->private_port.NotAnInteger : PrivateDNSPort.NotAnInteger;

	self->tlssd = socket( AF_INET, SOCK_STREAM, 0 );
	require_action( dnssd_SocketValid(self->tlssd), exit, err = mStatus_UnknownErr; LogErr( "SetupSockets", "socket" ) );

#if defined(SO_REUSEADDR)
	err = setsockopt(self->tlssd, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
	require_action( !err, exit, LogErr( "SetupSockets", "SO_REUSEADDR self->tlssd" ) );
#endif

	err = bind( self->tlssd, ( struct sockaddr* ) &daddr, sizeof( daddr ) );
	require_action( !err, exit, LogErr( "SetupSockets", "bind self->tlssd" ) );

	err = listen( self->tlssd, LISTENQ );
	require_action( !err, exit, LogErr( "SetupSockets", "listen" ) );

	// Do we have any private zones?

	for ( zone = self->zones; zone; zone = zone->next )
		{
		if ( zone->type == kDNSZonePrivate )
			{
			private = mDNStrue;
			break;
			}
		}

	if ( private )
		{
		err = mDNSPlatformTLSSetupCerts();
		require_action( !err, exit, LogErr( "SetupSockets", "mDNSPlatformTLSSetupCerts" ) );
		}

exit:

	return err;
	}

//
// periodic table updates
//

// Delete a resource record from the nameserver via a dynamic update
// sd is a socket already connected to the server
mDNSlocal void DeleteOneRecord(DaemonInfo *d, CacheRecord *rr, domainname *zname, TCPSocket *sock)
	{
	DNSZone	*	zone;
	PktMsg pkt;
	mDNSu8 *ptr = pkt.msg.data;
	mDNSu8 *end = (mDNSu8 *)&pkt.msg + sizeof(DNSMessage);
	char buf[MaxMsg];
	mDNSBool closed;
	PktMsg *reply = NULL;

	VLog("Expiring record %s", GetRRDisplayString_rdb(&rr->resrec, &rr->resrec.rdata->u, buf));
	
	InitializeDNSMessage(&pkt.msg.h, zeroID, UpdateReqFlags);
	
	ptr = putZone(&pkt.msg, ptr, end, zname, mDNSOpaque16fromIntVal(rr->resrec.rrclass));
	if (!ptr) goto end;
	ptr = putDeletionRecord(&pkt.msg, ptr, &rr->resrec);
	if (!ptr) goto end;

	HdrHToN(&pkt);

	zone = FindZone( d, zname );

	if ( zone && zone->updateKeys)
		{
		DNSDigest_SignMessage(&pkt.msg, &ptr, zone->updateKeys, 0 );
		if (!ptr) goto end;
		}

	pkt.len = ptr - (mDNSu8 *)&pkt.msg;
	pkt.src.sin_addr.s_addr = zerov4Addr.NotAnInteger; // address field set solely for verbose logging in subroutines
	pkt.src.sin_family = AF_INET;
	if (SendPacket( sock, &pkt)) { Log("DeleteOneRecord: SendPacket failed"); }
	reply = RecvPacket( sock, NULL, &closed );
	if (reply) HdrNToH(reply);
	require_action( reply, end, Log( "DeleteOneRecord: RecvPacket returned NULL" ) );

	if (!SuccessfulUpdateTransaction(&pkt, reply))
		Log("Expiration update failed with rcode %d", reply ? reply->msg.h.flags.b[1] & kDNSFlag1_RC_Mask : -1);
					  
	end:
	if (!ptr) { Log("DeleteOneRecord: Error constructing lease expiration update"); }
	if (reply) free(reply);
	}

// iterate over table, deleting expired records (or all records if DeleteAll is true)
mDNSlocal void DeleteRecords(DaemonInfo *d, mDNSBool DeleteAll)
	{
	struct timeval now;
	int i;
	TCPSocket *sock = ConnectToServer(d);
	if (!sock) { Log("DeleteRecords: ConnectToServer failed"); return; }
	if (gettimeofday(&now, NULL)) { LogErr("DeleteRecords ", "gettimeofday"); return; }
	if (pthread_mutex_lock(&d->tablelock)) { LogErr("DeleteRecords", "pthread_mutex_lock"); return; }

	for (i = 0; i < d->nbuckets; i++)
		{
		RRTableElem **ptr = &d->table[i];
		while (*ptr)
			{
			if (DeleteAll || (*ptr)->expire - now.tv_sec < 0)
				{
				RRTableElem *fptr;
				// delete record from server
				DeleteOneRecord(d, &(*ptr)->rr, &(*ptr)->zone, sock);
				fptr = *ptr;
				*ptr = (*ptr)->next;
				free(fptr);
				d->nelems--;
				}
			else ptr = &(*ptr)->next;
			}
		}
	pthread_mutex_unlock(&d->tablelock);
	mDNSPlatformTCPCloseConnection( sock );
	}

//
// main update request handling
//

// Add, delete, or refresh records in table based on contents of a successfully completed dynamic update
mDNSlocal void UpdateLeaseTable(PktMsg *pkt, DaemonInfo *d, mDNSs32 lease)
	{
	RRTableElem **rptr, *tmp;
	int i, allocsize, bucket;
	LargeCacheRecord lcr;
	ResourceRecord *rr = &lcr.r.resrec;
	const mDNSu8 *ptr, *end;
	struct timeval tv;
	DNSQuestion zone;
	char buf[MaxMsg];
	
	if (pthread_mutex_lock(&d->tablelock)) { LogErr("UpdateLeaseTable", "pthread_mutex_lock"); return; }
	HdrNToH(pkt);
	ptr = pkt->msg.data;
	end = (mDNSu8 *)&pkt->msg + pkt->len;
	ptr = getQuestion(&pkt->msg, ptr, end, 0, &zone);
	if (!ptr) { Log("UpdateLeaseTable: cannot read zone");  goto cleanup; }
	ptr = LocateAuthorities(&pkt->msg, end);
	if (!ptr) { Log("UpdateLeaseTable: Format error");  goto cleanup; }
	
	for (i = 0; i < pkt->msg.h.mDNS_numUpdates; i++)
		{
		mDNSBool DeleteAllRRSets = mDNSfalse, DeleteOneRRSet = mDNSfalse, DeleteOneRR = mDNSfalse;
		
		ptr = GetLargeResourceRecord(NULL, &pkt->msg, ptr, end, 0, kDNSRecordTypePacketAns, &lcr);
		if (!ptr || lcr.r.resrec.RecordType == kDNSRecordTypePacketNegative) { Log("UpdateLeaseTable: GetLargeResourceRecord failed"); goto cleanup; }
		bucket = rr->namehash % d->nbuckets;
		rptr = &d->table[bucket];

		// handle deletions		
		if (rr->rrtype == kDNSQType_ANY && !rr->rroriginalttl && rr->rrclass == kDNSQClass_ANY && !rr->rdlength)
			DeleteAllRRSets = mDNStrue; // delete all rrsets for a name
		else if (!rr->rroriginalttl && rr->rrclass == kDNSQClass_ANY && !rr->rdlength)
			DeleteOneRRSet = mDNStrue;
		else if (!rr->rroriginalttl && rr->rrclass == kDNSClass_NONE)
			DeleteOneRR = mDNStrue;

		if (DeleteAllRRSets || DeleteOneRRSet || DeleteOneRR)
			{
			while (*rptr)
			  {
			  if (SameDomainName((*rptr)->rr.resrec.name, rr->name) &&
				 (DeleteAllRRSets ||
				 (DeleteOneRRSet && (*rptr)->rr.resrec.rrtype == rr->rrtype) ||
				  (DeleteOneRR && IdenticalResourceRecord(&(*rptr)->rr.resrec, rr))))
				  {
				  tmp = *rptr;
				  VLog("Received deletion update for %s", GetRRDisplayString_rdb(&tmp->rr.resrec, &tmp->rr.resrec.rdata->u, buf));
				  *rptr = (*rptr)->next;
				  free(tmp);
				  d->nelems--;
				  }
			  else rptr = &(*rptr)->next;
			  }
			}
		else if (lease > 0)
			{
			// see if add or refresh
			while (*rptr && !IdenticalResourceRecord(&(*rptr)->rr.resrec, rr)) rptr = &(*rptr)->next;
			if (*rptr)
				{
				// refresh
				if (gettimeofday(&tv, NULL)) { LogErr("UpdateLeaseTable", "gettimeofday"); goto cleanup; }
				(*rptr)->expire = tv.tv_sec + (unsigned)lease;
				VLog("Refreshing lease for %s", GetRRDisplayString_rdb(&lcr.r.resrec, &lcr.r.resrec.rdata->u, buf));
				}
			else
				{
				// New record - add to table
				if (d->nelems > d->nbuckets)
					{
					RehashTable(d);
					bucket = rr->namehash % d->nbuckets;
					rptr = &d->table[bucket];
					}
				if (gettimeofday(&tv, NULL)) { LogErr("UpdateLeaseTable", "gettimeofday"); goto cleanup; }
				allocsize = sizeof(RRTableElem);
				if (rr->rdlength > InlineCacheRDSize) allocsize += (rr->rdlength - InlineCacheRDSize);
				tmp = malloc(allocsize);
				if (!tmp) { LogErr("UpdateLeaseTable", "malloc"); goto cleanup; }
				memcpy(&tmp->rr, &lcr.r, sizeof(CacheRecord) + rr->rdlength - InlineCacheRDSize);
				tmp->rr.resrec.rdata = (RData *)&tmp->rr.smallrdatastorage;
				AssignDomainName(&tmp->name, rr->name);
				tmp->rr.resrec.name = &tmp->name;
				tmp->expire = tv.tv_sec + (unsigned)lease;
				tmp->cli.sin_addr = pkt->src.sin_addr;
				AssignDomainName(&tmp->zone, &zone.qname);
				tmp->next = d->table[bucket];
				d->table[bucket] = tmp;
				d->nelems++;
				VLog("Adding update for %s to lease table", GetRRDisplayString_rdb(&lcr.r.resrec, &lcr.r.resrec.rdata->u, buf));
				}
			}
		}
					
	cleanup:
	pthread_mutex_unlock(&d->tablelock);
	HdrHToN(pkt);
	}

// Given a successful reply from a server, create a new reply that contains lease information
// Replies are currently not signed !!!KRS change this
mDNSlocal PktMsg *FormatLeaseReply(DaemonInfo *d, PktMsg *orig, mDNSu32 lease)
	{
	PktMsg *reply;
	mDNSu8 *ptr, *end;
	mDNSOpaque16 flags;

	(void)d;  //unused
	reply = malloc(sizeof(*reply));
	if (!reply) { LogErr("FormatLeaseReply", "malloc"); return NULL; }
	flags.b[0] = kDNSFlag0_QR_Response | kDNSFlag0_OP_Update;
	flags.b[1] = 0;
 
	InitializeDNSMessage(&reply->msg.h, orig->msg.h.id, flags);
	reply->src.sin_addr.s_addr = zerov4Addr.NotAnInteger;            // unused except for log messages
	reply->src.sin_family = AF_INET;
	ptr = reply->msg.data;
	end = (mDNSu8 *)&reply->msg + sizeof(DNSMessage);
	ptr = putUpdateLease(&reply->msg, ptr, lease);
	if (!ptr) { Log("FormatLeaseReply: putUpdateLease failed"); free(reply); return NULL; }
	reply->len = ptr - (mDNSu8 *)&reply->msg;
	HdrHToN(reply);
	return reply;
	}


// pkt is thread-local, not requiring locking

mDNSlocal PktMsg*
HandleRequest
	(
	DaemonInfo	*	self,
	PktMsg		*	request
	)
	{
	PktMsg		*	reply = NULL;
	PktMsg		*	leaseReply;
	PktMsg	 		buf;
	char			addrbuf[32];
	TCPSocket *	sock = NULL;
	mStatus			err;
	mDNSs32		lease = 0;
	if ((request->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask) == kDNSFlag0_OP_Update)
		{
		int i, adds = 0, dels = 0;
		const mDNSu8 *ptr, *end = (mDNSu8 *)&request->msg + request->len;
		HdrNToH(request);
		lease = GetPktLease(&mDNSStorage, &request->msg, end);
		ptr = LocateAuthorities(&request->msg, end);
		for (i = 0; i < request->msg.h.mDNS_numUpdates; i++)
			{
			LargeCacheRecord lcr;
			ptr = GetLargeResourceRecord(NULL, &request->msg, ptr, end, 0, kDNSRecordTypePacketAns, &lcr);
			if (lcr.r.resrec.RecordType != kDNSRecordTypePacketNegative && lcr.r.resrec.rroriginalttl) adds++; else dels++;
			}
		HdrHToN(request);
		if (adds && !lease)
			{
			static const mDNSOpaque16 UpdateRefused = { { kDNSFlag0_QR_Response | kDNSFlag0_OP_Update, kDNSFlag1_RC_Refused } };
			Log("Rejecting Update Request with %d additions but no lease", adds);
			reply = malloc(sizeof(*reply));
			mDNSPlatformMemZero(&reply->src, sizeof(reply->src));
			reply->len = sizeof(DNSMessageHeader);
			reply->zone = NULL;
			reply->isZonePublic = 0;
			InitializeDNSMessage(&reply->msg.h, request->msg.h.id, UpdateRefused);
			return(reply);
			}
		if (lease > 7200)	// Don't allow lease greater than two hours; typically 90-minute renewal period
			lease = 7200;
		}
	// Send msg to server, read reply

	if ( request->len <= 512 )
		{
		mDNSBool trunc;

		if ( UDPServerTransaction( self, request, &buf, &trunc) < 0 )
			{
			Log("HandleRequest - UDPServerTransaction failed.  Trying TCP");
			}
		else if ( trunc )
			{
			VLog("HandleRequest - answer truncated.  Using TCP");
			}
		else
			{
			reply = &buf; // success
			}
		}
	
	if ( !reply )
		{
		mDNSBool closed;
		int res;

		sock = ConnectToServer( self );
		require_action_quiet( sock, exit, err = mStatus_UnknownErr ; Log( "Discarding request from %s due to connection errors", inet_ntop( AF_INET, &request->src.sin_addr, addrbuf, 32 ) ) );

		res = SendPacket( sock, request );
		require_action_quiet( res >= 0, exit, err = mStatus_UnknownErr ; Log( "Couldn't relay message from %s to server.  Discarding.", inet_ntop(AF_INET, &request->src.sin_addr, addrbuf, 32 ) ) );

		reply = RecvPacket( sock, &buf, &closed );
		}
	
	// IMPORTANT: reply is in network byte order at this point in the code
	// We keep it this way because we send it back to the client in the same form
	
	// Is it an update?

	if ( reply && ( ( reply->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask ) == ( kDNSFlag0_OP_Update | kDNSFlag0_QR_Response ) ) )
		{
		char 		pingmsg[4];
		mDNSBool	ok = SuccessfulUpdateTransaction( request, reply );
		require_action( ok, exit, err = mStatus_UnknownErr; VLog( "Message from %s not a successful update.", inet_ntop(AF_INET, &request->src.sin_addr, addrbuf, 32 ) ) );

		UpdateLeaseTable( request, self, lease );

		if ( lease > 0 )
			{
			leaseReply = FormatLeaseReply( self, reply, lease );

			if ( !leaseReply )
				{
				Log("HandleRequest - unable to format lease reply");
				}

			// %%% Looks like a potential memory leak -- who frees the original reply?
			reply = leaseReply;
			}

		// tell the main thread there was an update so it can send LLQs

		if ( send( self->LLQEventNotifySock, pingmsg, sizeof( pingmsg ), 0 ) != sizeof( pingmsg ) )
			{
			LogErr("HandleRequest", "send");
			}
		}

exit:

	if ( sock )
		{
		mDNSPlatformTCPCloseConnection( sock );
		}

	if ( reply == &buf )
		{
		reply = malloc( sizeof( *reply ) );

		if ( reply )
			{
			reply->len = buf.len;
			memcpy(&reply->msg, &buf.msg, buf.len);
			}
		else
			{
			LogErr("HandleRequest", "malloc");
			}
		}

	return reply;
	}


//
// LLQ Support Routines
//

// Set fields of an LLQ OPT Resource Record
mDNSlocal void FormatLLQOpt(AuthRecord *opt, int opcode, const mDNSOpaque64 *const id, mDNSs32 lease)
	{
	mDNSPlatformMemZero(opt, sizeof(*opt));
	mDNS_SetupResourceRecord(opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
	opt->resrec.rrclass = NormalMaxDNSMessageData;
	opt->resrec.rdlength   = sizeof(rdataOPT);	// One option in this OPT record
	opt->resrec.rdestimate = sizeof(rdataOPT);
	opt->resrec.rdata->u.opt[0].opt = kDNSOpt_LLQ;
	opt->resrec.rdata->u.opt[0].u.llq.vers  = kLLQ_Vers;
	opt->resrec.rdata->u.opt[0].u.llq.llqOp = opcode;
	opt->resrec.rdata->u.opt[0].u.llq.err   = LLQErr_NoError;
	opt->resrec.rdata->u.opt[0].u.llq.id    = *id;
	opt->resrec.rdata->u.opt[0].u.llq.llqlease = lease;
	}

// Calculate effective remaining lease of an LLQ
mDNSlocal mDNSu32 LLQLease(LLQEntry *e)
	{
	struct timeval t;
	
	gettimeofday(&t, NULL);
	if (e->expire < t.tv_sec) return 0;
	else return e->expire - t.tv_sec;
	}

mDNSlocal void DeleteLLQ(DaemonInfo *d, LLQEntry *e)
	{
	int  bucket = DomainNameHashValue(&e->qname) % LLQ_TABLESIZE;
	LLQEntry **ptr = &d->LLQTable[bucket];
	AnswerListElem *a = e->AnswerList;
	char addr[32];
	
	inet_ntop(AF_INET, &e->cli.sin_addr, addr, 32);
	VLog("Deleting LLQ table entry for %##s client %s", e->qname.c, addr);

	if (a && !(--a->refcount) && d->AnswerTableCount >= LLQ_TABLESIZE)
		{
		// currently, generating initial answers blocks the main thread, so we keep the answer list
		// even if the ref count drops to zero.  To prevent unbounded table growth, we free shared answers
		// if the ref count drops to zero AND there are more table elements than buckets
		// !!!KRS update this when we make the table dynamically growable

		CacheRecord *cr = a->KnownAnswers, *tmp;
		AnswerListElem **tbl = &d->AnswerTable[bucket];

		while (cr)
			{
			tmp = cr;
			cr = cr->next;
			free(tmp);
			}

		while (*tbl && *tbl != a) tbl = &(*tbl)->next;
		if (*tbl) { *tbl = (*tbl)->next; free(a); d->AnswerTableCount--; }
		else Log("Error: DeleteLLQ - AnswerList not found in table");
		}

	// remove LLQ from table, free memory
	while(*ptr && *ptr != e) ptr = &(*ptr)->next;
	if (!*ptr) { Log("Error: DeleteLLQ - LLQ not in table"); return; }
	*ptr = (*ptr)->next;
	free(e);
	}

mDNSlocal int SendLLQ(DaemonInfo *d, PktMsg *pkt, struct sockaddr_in dst, TCPSocket *sock)
	{
	char addr[32];
	int err = -1;

	HdrHToN(pkt);

	if ( sock )
		{
		if ( SendPacket( sock, pkt ) != 0 )
			{
			LogErr("DaemonInfo", "MySend");
			Log("Could not send response to client %s", inet_ntop(AF_INET, &dst.sin_addr, addr, 32));
			}
		}
	else
		{
		if (sendto(d->llq_udpsd, &pkt->msg, pkt->len, 0, (struct sockaddr *)&dst, sizeof(dst)) != (int)pkt->len)
			{
			LogErr("DaemonInfo", "sendto");
			Log("Could not send response to client %s", inet_ntop(AF_INET, &dst.sin_addr, addr, 32));
			}
		}

	err = 0;
	HdrNToH(pkt);
	return err;
	}

mDNSlocal CacheRecord *AnswerQuestion(DaemonInfo *d, AnswerListElem *e)
	{
	PktMsg q;
	int i;
	TCPSocket *sock = NULL;
	const mDNSu8 *ansptr;
	mDNSu8 *end = q.msg.data;
	PktMsg buf, *reply = NULL;
	LargeCacheRecord lcr;
	CacheRecord *AnswerList = NULL;
	mDNSu8 rcode;
	
	VLog("Querying server for %##s type %d", e->name.c, e->type);
	
	InitializeDNSMessage(&q.msg.h, zeroID, uQueryFlags);
	
	end = putQuestion(&q.msg, end, end + AbsoluteMaxDNSMessageData, &e->name, e->type, kDNSClass_IN);
	if (!end) { Log("Error: AnswerQuestion - putQuestion returned NULL"); goto end; }
	q.len = (int)(end - (mDNSu8 *)&q.msg);

	HdrHToN(&q);

	if (!e->UseTCP)
		{
		mDNSBool trunc;

		if (UDPServerTransaction(d, &q, &buf, &trunc) < 0)
			Log("AnswerQuestion %##s - UDPServerTransaction failed.  Trying TCP", e->name.c);
		else if (trunc)
			{ VLog("AnswerQuestion %##s - answer truncated.  Using TCP", e->name.c); e->UseTCP = mDNStrue; }
		else reply = &buf;  // success
		}
	
	if (!reply)
		{
		mDNSBool closed;

		sock = ConnectToServer(d);
		if (!sock) { Log("AnswerQuestion: ConnectToServer failed"); goto end; }
		if (SendPacket( sock, &q)) { Log("AnswerQuestion: SendPacket failed"); mDNSPlatformTCPCloseConnection( sock ); goto end; }
		reply = RecvPacket( sock, NULL, &closed );
		mDNSPlatformTCPCloseConnection( sock );
		require_action( reply, end, Log( "AnswerQuestion: RecvPacket returned NULL" ) );
		}

	HdrNToH(&q);
	if (reply) HdrNToH(reply);

	if ((reply->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask) != (kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery))
		{ Log("AnswerQuestion: %##s type %d - Invalid response flags from server"); goto end; }
	rcode = (mDNSu8)(reply->msg.h.flags.b[1] & kDNSFlag1_RC_Mask);
	if (rcode && rcode != kDNSFlag1_RC_NXDomain) { Log("AnswerQuestion: %##s type %d - non-zero rcode %d from server", e->name.c, e->type, rcode); goto end; }

	end = (mDNSu8 *)&reply->msg + reply->len;
	ansptr = LocateAnswers(&reply->msg, end);
	if (!ansptr) { Log("Error: AnswerQuestion - LocateAnswers returned NULL"); goto end; }

	for (i = 0; i < reply->msg.h.numAnswers; i++)
		{
		ansptr = GetLargeResourceRecord(NULL, &reply->msg, ansptr, end, 0, kDNSRecordTypePacketAns, &lcr);
		if (!ansptr) { Log("AnswerQuestions: GetLargeResourceRecord returned NULL"); goto end; }
		if (lcr.r.resrec.RecordType != kDNSRecordTypePacketNegative)
			{
			if (lcr.r.resrec.rrtype != e->type || lcr.r.resrec.rrclass != kDNSClass_IN || !SameDomainName(lcr.r.resrec.name, &e->name))
				{
				Log("AnswerQuestion: response %##s type #d does not answer question %##s type #d.  Discarding",
					  lcr.r.resrec.name->c, lcr.r.resrec.rrtype, e->name.c, e->type);
				}
			else
				{
				CacheRecord *cr = CopyCacheRecord(&lcr.r, &e->name);
				if (!cr) { Log("Error: AnswerQuestion - CopyCacheRecord returned NULL"); goto end; }
				cr->next = AnswerList;
				AnswerList = cr;
				}
			}
		}
	
	end:
	if (reply && reply != &buf) free(reply);
	return AnswerList;
	}

// Routine forks a thread to set EventList to contain Add/Remove events, and deletes any removes from the KnownAnswer list
mDNSlocal void *UpdateAnswerList(void *args)
	{
	CacheRecord *cr, *NewAnswers, **na, **ka; // "new answer", "known answer"
	DaemonInfo *d = ((UpdateAnswerListArgs *)args)->d;
	AnswerListElem *a = ((UpdateAnswerListArgs *)args)->a;

	free(args);
	args = NULL;
	
	// get up to date answers
	NewAnswers = AnswerQuestion(d, a);
	
	// first pass - mark all answers for deletion
	for (ka = &a->KnownAnswers; *ka; ka = &(*ka)->next)
		(*ka)->resrec.rroriginalttl = (unsigned)-1; // -1 means delete

	// second pass - mark answers pre-existent
	for (ka = &a->KnownAnswers; *ka; ka = &(*ka)->next)
		{
		for (na = &NewAnswers; *na; na = &(*na)->next)
			{
			if (IdenticalResourceRecord(&(*ka)->resrec, &(*na)->resrec))
				{ (*ka)->resrec.rroriginalttl = 0; break; } // 0 means no change
			}
		}

	// third pass - add new records to Event list
	na = &NewAnswers;
	while (*na)
		{
		for (ka = &a->KnownAnswers; *ka; ka = &(*ka)->next)
			if (IdenticalResourceRecord(&(*ka)->resrec, &(*na)->resrec)) break;
		if (!*ka)
			{
			// answer is not in list - splice from NewAnswers list, add to Event list
			cr = *na;
			*na = (*na)->next;        // splice from list
			cr->next = a->EventList;  // add spliced record to event list
			a->EventList = cr;
			cr->resrec.rroriginalttl = 1; // 1 means add
			}
		else na = &(*na)->next;
		}
	
	// move all the removes from the answer list to the event list	
	ka = &a->KnownAnswers;
	while (*ka)
		{
		if ((*ka)->resrec.rroriginalttl == (unsigned)-1)
			{
			cr = *ka;
			*ka = (*ka)->next;
			cr->next = a->EventList;
			a->EventList = cr;
			}
		else ka = &(*ka)->next;
		}
	
	// lastly, free the remaining records (known answers) in NewAnswers list
	while (NewAnswers)
		{
		cr = NewAnswers;
		NewAnswers = NewAnswers->next;
		free(cr);
		}
	
	return NULL;
	}

mDNSlocal void SendEvents(DaemonInfo *d, LLQEntry *e)
	{
	PktMsg  response;
	CacheRecord *cr;
	mDNSu8 *end = (mDNSu8 *)&response.msg.data;
	mDNSOpaque16 msgID;
	char rrbuf[MaxMsg], addrbuf[32];
	AuthRecord opt;
	
	// Should this really be random?  Do we use the msgID on the receiving end?
	msgID.NotAnInteger = random();
	if (verbose) inet_ntop(AF_INET, &e->cli.sin_addr, addrbuf, 32);
	InitializeDNSMessage(&response.msg.h, msgID, ResponseFlags);
	end = putQuestion(&response.msg, end, end + AbsoluteMaxDNSMessageData, &e->qname, e->qtype, kDNSClass_IN);
	if (!end) { Log("Error: SendEvents - putQuestion returned NULL"); return; }
	
	// put adds/removes in packet
	for (cr = e->AnswerList->EventList; cr; cr = cr->next)
		{
		if (verbose) GetRRDisplayString_rdb(&cr->resrec, &cr->resrec.rdata->u, rrbuf);
		VLog("%s (%s): %s", addrbuf, (mDNSs32)cr->resrec.rroriginalttl < 0 ? "Remove": "Add", rrbuf);
		end = PutResourceRecordTTLJumbo(&response.msg, end, &response.msg.h.numAnswers, &cr->resrec, cr->resrec.rroriginalttl);
		if (!end) { Log("Error: SendEvents - PutResourceRecordTTLJumbo returned NULL"); return; }
		}
			   
	FormatLLQOpt(&opt, kLLQOp_Event, &e->id, LLQLease(e));
	end = PutResourceRecordTTLJumbo(&response.msg, end, &response.msg.h.numAdditionals, &opt.resrec, 0);
	if (!end) { Log("Error: SendEvents - PutResourceRecordTTLJumbo"); return; }

	response.len = (int)(end - (mDNSu8 *)&response.msg);
	if (SendLLQ(d, &response, e->cli, NULL ) < 0) LogMsg("Error: SendEvents - SendLLQ");
	}

mDNSlocal void PrintLLQAnswers(DaemonInfo *d)
	{
	int i;
	char rrbuf[MaxMsg];
	
	Log("Printing LLQ Answer Table contents");

	for (i = 0; i < LLQ_TABLESIZE; i++)
		{
		AnswerListElem *a = d->AnswerTable[i];
		while(a)
			{
			int ancount = 0;
			const CacheRecord *rr = a->KnownAnswers;
			while (rr) { ancount++; rr = rr->next; }
			Log("%p : Question %##s;  type %d;  referenced by %d LLQs; %d answers:", a, a->name.c, a->type, a->refcount, ancount);
			for (rr = a->KnownAnswers; rr; rr = rr->next) Log("\t%s", GetRRDisplayString_rdb(&rr->resrec, &rr->resrec.rdata->u, rrbuf));
			a = a->next;
			}
		}
	}

mDNSlocal void PrintLLQTable(DaemonInfo *d)
	{
	LLQEntry *e;
	char addr[32];
	int i;
	
	Log("Printing LLQ table contents");

	for (i = 0; i < LLQ_TABLESIZE; i++)
		{
		e = d->LLQTable[i];
		while(e)
			{
			char *state;
			
			switch (e->state)
				{
				case RequestReceived: state = "RequestReceived"; break;
				case ChallengeSent:   state = "ChallengeSent";   break;
				case Established:     state = "Established";     break;
				default:              state = "unknown";
				}
			inet_ntop(AF_INET, &e->cli.sin_addr, addr, 32);
			
			Log("LLQ from %s in state %s; %##s; type %d; orig lease %d; remaining lease %d; AnswerList %p)",
				addr, state, e->qname.c, e->qtype, e->lease, LLQLease(e), e->AnswerList);
			e = e->next;
			}
		}
	}

// Send events to clients as a result of a change in the zone
mDNSlocal void GenLLQEvents(DaemonInfo *d)
	{
	LLQEntry **e;
	int i;
	struct timeval t;
	UpdateAnswerListArgs *args;
	
	VLog("Generating LLQ Events");

	gettimeofday(&t, NULL);

	// get all answers up to date
	for (i = 0; i < LLQ_TABLESIZE; i++)
		{
		AnswerListElem *a = d->AnswerTable[i];
		while(a)
			{
			args = malloc(sizeof(*args));
			if (!args) { LogErr("GenLLQEvents", "malloc"); return; }
			args->d = d;
			args->a = a;
			if (pthread_create(&a->tid, NULL, UpdateAnswerList, args) < 0) { LogErr("GenLLQEvents", "pthread_create"); return; }
			usleep(1);
			a = a->next;
			}
		}

	for (i = 0; i < LLQ_TABLESIZE; i++)
		{
		AnswerListElem *a = d->AnswerTable[i];
		while(a)
			{
			if (pthread_join(a->tid, NULL)) LogErr("GenLLQEvents", "pthread_join");
			a = a->next;
			}
		}
	
    // for each established LLQ, send events
	for (i = 0; i < LLQ_TABLESIZE; i++)
		{
		e = &d->LLQTable[i];
		while(*e)
			{
			if ((*e)->expire < t.tv_sec) DeleteLLQ(d, *e);
			else
				{
				if ((*e)->state == Established && (*e)->AnswerList->EventList) SendEvents(d, *e);
				e = &(*e)->next;
				}
			}
		}
	
	// now that all LLQs are updated, we move Add events from the Event list to the Known Answer list, and free Removes
	for (i = 0; i < LLQ_TABLESIZE; i++)
		{
		AnswerListElem *a = d->AnswerTable[i];
		while(a)
			{
			if (a->EventList)
				{
				CacheRecord *cr = a->EventList, *tmp;
				while (cr)
					{
					tmp = cr;
					cr = cr->next;
					if ((signed)tmp->resrec.rroriginalttl < 0) free(tmp);
					else
						{
						tmp->next = a->KnownAnswers;
						a->KnownAnswers = tmp;
						tmp->resrec.rroriginalttl = 0;
						}
					}
				a->EventList = NULL;
				}
			a = a->next;
			}
		}
	}

mDNSlocal void SetAnswerList(DaemonInfo *d, LLQEntry *e)
	{
	int bucket = DomainNameHashValue(&e->qname) % LLQ_TABLESIZE;
	AnswerListElem *a = d->AnswerTable[bucket];
	while (a && (a->type != e->qtype ||!SameDomainName(&a->name, &e->qname))) a = a->next;
	if (!a)
		{
		a = malloc(sizeof(*a));
		if (!a) { LogErr("SetAnswerList", "malloc"); return; }
		AssignDomainName(&a->name, &e->qname);
		a->type = e->qtype;
		a->refcount = 0;
		a->EventList = NULL;
		a->UseTCP = mDNSfalse;
		a->next = d->AnswerTable[bucket];
		d->AnswerTable[bucket] = a;
		d->AnswerTableCount++;
		a->KnownAnswers = AnswerQuestion(d, a);
		}
	
	e->AnswerList = a;
	a->refcount ++;
	}
	
 // Allocate LLQ entry, insert into table
mDNSlocal LLQEntry *NewLLQ(DaemonInfo *d, struct sockaddr_in cli, domainname *qname, mDNSu16 qtype, mDNSu32 lease )
	{
	char addr[32];
	struct timeval t;
	int bucket = DomainNameHashValue(qname) % LLQ_TABLESIZE;
   	LLQEntry *e;

	e = malloc(sizeof(*e));
	if (!e) { LogErr("NewLLQ", "malloc"); return NULL; }

	inet_ntop(AF_INET, &cli.sin_addr, addr, 32);
	VLog("Allocating LLQ entry for client %s question %##s type %d", addr, qname->c, qtype);
	
	// initialize structure
	e->cli = cli;
	AssignDomainName(&e->qname, qname);
	e->qtype = qtype;
	e->id    = zeroOpaque64;
	e->state = RequestReceived;
	e->AnswerList = NULL;
	
	if (lease < LLQ_MIN_LEASE) lease = LLQ_MIN_LEASE;
	else if (lease > LLQ_MAX_LEASE) lease = LLQ_MAX_LEASE;

	gettimeofday(&t, NULL);
	e->expire = t.tv_sec + (int)lease;
	e->lease = lease;
	
	// add to table
	e->next = d->LLQTable[bucket];
	d->LLQTable[bucket] = e;
	
	return e;
	}

// Handle a refresh request from client
mDNSlocal void LLQRefresh(DaemonInfo *d, LLQEntry *e, LLQOptData *llq, mDNSOpaque16 msgID, TCPSocket *sock )
	{
	AuthRecord opt;
	PktMsg ack;
	mDNSu8 *end = (mDNSu8 *)&ack.msg.data;
	char addr[32];

	inet_ntop(AF_INET, &e->cli.sin_addr, addr, 32);
	VLog("%s LLQ for %##s from %s", llq->llqlease ? "Refreshing" : "Deleting", e->qname.c, addr);
	
	if (llq->llqlease)
		{
		struct timeval t;
		if (llq->llqlease < LLQ_MIN_LEASE) llq->llqlease = LLQ_MIN_LEASE;
		else if (llq->llqlease > LLQ_MAX_LEASE) llq->llqlease = LLQ_MIN_LEASE;
		gettimeofday(&t, NULL);
		e->expire = t.tv_sec + llq->llqlease;
		}
	
	ack.src.sin_addr.s_addr = 0; // unused 
	InitializeDNSMessage(&ack.msg.h, msgID, ResponseFlags);
	end = putQuestion(&ack.msg, end, end + AbsoluteMaxDNSMessageData, &e->qname, e->qtype, kDNSClass_IN);
	if (!end) { Log("Error: putQuestion"); return; }

	FormatLLQOpt(&opt, kLLQOp_Refresh, &e->id, llq->llqlease ? LLQLease(e) : 0);
	end = PutResourceRecordTTLJumbo(&ack.msg, end, &ack.msg.h.numAdditionals, &opt.resrec, 0);
	if (!end) { Log("Error: PutResourceRecordTTLJumbo"); return; }

	ack.len = (int)(end - (mDNSu8 *)&ack.msg);
	if (SendLLQ(d, &ack, e->cli, sock)) Log("Error: LLQRefresh");

	if (llq->llqlease) e->state = Established;
	else DeleteLLQ(d, e);
	}

// Complete handshake with Ack an initial answers
mDNSlocal void LLQCompleteHandshake(DaemonInfo *d, LLQEntry *e, LLQOptData *llq, mDNSOpaque16 msgID, TCPSocket *sock)
	{
	char addr[32];
	CacheRecord *ptr;
	AuthRecord opt;
	PktMsg ack;
	mDNSu8 *end = (mDNSu8 *)&ack.msg.data;
	char rrbuf[MaxMsg], addrbuf[32];
	
	inet_ntop(AF_INET, &e->cli.sin_addr, addr, 32);

	if (!mDNSSameOpaque64(&llq->id, &e->id) ||
		llq->vers  != kLLQ_Vers             ||
		llq->llqOp != kLLQOp_Setup          ||
		llq->err   != LLQErr_NoError        ||
		llq->llqlease > e->lease + LLQ_LEASE_FUDGE ||
		llq->llqlease < e->lease - LLQ_LEASE_FUDGE)
		{
			Log("Incorrect challenge response from %s", addr);
			return;
		}

	if (e->state == Established) VLog("Retransmitting LLQ ack + answers for %##s", e->qname.c);
	else                         VLog("Delivering LLQ ack + answers for %##s", e->qname.c);
	
	// format ack + answers
	ack.src.sin_addr.s_addr = 0; // unused 
	InitializeDNSMessage(&ack.msg.h, msgID, ResponseFlags);
	end = putQuestion(&ack.msg, end, end + AbsoluteMaxDNSMessageData, &e->qname, e->qtype, kDNSClass_IN);
	if (!end) { Log("Error: putQuestion"); return; }
	
	if (e->state != Established) { SetAnswerList(d, e); e->state = Established; }
	
	if (verbose) inet_ntop(AF_INET, &e->cli.sin_addr, addrbuf, 32);
	for (ptr = e->AnswerList->KnownAnswers; ptr; ptr = ptr->next)
		{
		if (verbose) GetRRDisplayString_rdb(&ptr->resrec, &ptr->resrec.rdata->u, rrbuf);
		VLog("%s Intitial Answer - %s", addr, rrbuf);
		end = PutResourceRecordTTLJumbo(&ack.msg, end, &ack.msg.h.numAnswers, &ptr->resrec, 1);
		if (!end) { Log("Error: PutResourceRecordTTLJumbo"); return; }
		}

	FormatLLQOpt(&opt, kLLQOp_Setup, &e->id, LLQLease(e));
	end = PutResourceRecordTTLJumbo(&ack.msg, end, &ack.msg.h.numAdditionals, &opt.resrec, 0);
	if (!end) { Log("Error: PutResourceRecordTTLJumbo"); return; }

	ack.len = (int)(end - (mDNSu8 *)&ack.msg);
	if (SendLLQ(d, &ack, e->cli, sock)) Log("Error: LLQCompleteHandshake");
	}

mDNSlocal void LLQSetupChallenge(DaemonInfo *d, LLQEntry *e, LLQOptData *llq, mDNSOpaque16 msgID)
	{
	struct timeval t;
	PktMsg challenge;
	mDNSu8 *end = challenge.msg.data;
	AuthRecord opt;

	if (e->state == ChallengeSent) VLog("Retransmitting LLQ setup challenge for %##s", e->qname.c);
	else                           VLog("Sending LLQ setup challenge for %##s", e->qname.c);
	
	if (!mDNSOpaque64IsZero(&llq->id)) { Log("Error: LLQSetupChallenge - nonzero ID"); return; } // server bug
	if (llq->llqOp != kLLQOp_Setup) { Log("LLQSetupChallenge - incorrrect operation from client"); return; } // client error
	
	if (mDNSOpaque64IsZero(&e->id)) // don't regenerate random ID for retransmissions
		{
		// construct ID <time><random>
		gettimeofday(&t, NULL);
		e->id.l[0] = t.tv_sec;
		e->id.l[1] = random();
		}

	// format response (query + LLQ opt rr)
	challenge.src.sin_addr.s_addr = 0; // unused 
	InitializeDNSMessage(&challenge.msg.h, msgID, ResponseFlags);
	end = putQuestion(&challenge.msg, end, end + AbsoluteMaxDNSMessageData, &e->qname, e->qtype, kDNSClass_IN);
	if (!end) { Log("Error: putQuestion"); return; }
	FormatLLQOpt(&opt, kLLQOp_Setup, &e->id, LLQLease(e));
	end = PutResourceRecordTTLJumbo(&challenge.msg, end, &challenge.msg.h.numAdditionals, &opt.resrec, 0);
	if (!end) { Log("Error: PutResourceRecordTTLJumbo"); return; }
	challenge.len = (int)(end - (mDNSu8 *)&challenge.msg);
	if (SendLLQ(d, &challenge, e->cli, NULL)) { Log("Error: LLQSetupChallenge"); return; }
	e->state = ChallengeSent;
	}

// Take action on an LLQ message from client.  Entry must be initialized and in table
mDNSlocal void UpdateLLQ(DaemonInfo *d, LLQEntry *e, LLQOptData *llq, mDNSOpaque16 msgID, TCPSocket *sock )
	{
	switch(e->state)
		{
		case RequestReceived:
			if ( sock )
				{
				struct timeval t;
				gettimeofday(&t, NULL);
				e->id.l[0] = t.tv_sec;	// construct ID <time><random>
				e->id.l[1] = random();
				llq->id = e->id;
				LLQCompleteHandshake( d, e, llq, msgID, sock );

				// Set the state to established because we've just set the LLQ up using TCP
				e->state = Established;
				}
			else
				{
				LLQSetupChallenge(d, e, llq, msgID);
				}
			return;
		case ChallengeSent:
			if (mDNSOpaque64IsZero(&llq->id)) LLQSetupChallenge(d, e, llq, msgID); // challenge sent and lost
			else LLQCompleteHandshake(d, e, llq, msgID, sock );
			return;
		case Established:
			if (mDNSOpaque64IsZero(&llq->id))
				{
				// client started over.  reset state.
				LLQEntry *newe = NewLLQ(d, e->cli, &e->qname, e->qtype, llq->llqlease );
				if (!newe) return;
				DeleteLLQ(d, e);
				LLQSetupChallenge(d, newe, llq, msgID);
				return;
				}
			else if (llq->llqOp == kLLQOp_Setup)
				{ LLQCompleteHandshake(d, e, llq, msgID, sock); return; } // Ack lost				
			else if (llq->llqOp == kLLQOp_Refresh)
				{ LLQRefresh(d, e, llq, msgID, sock); return; }
			else { Log("Unhandled message for established LLQ"); return; }
		}
	}

mDNSlocal LLQEntry *LookupLLQ(DaemonInfo *d, struct sockaddr_in cli, domainname *qname, mDNSu16 qtype, const mDNSOpaque64 *const id)
	{
	int bucket = bucket = DomainNameHashValue(qname) % LLQ_TABLESIZE;
	LLQEntry *ptr = d->LLQTable[bucket];

	while(ptr)
		{
		if (((ptr->state == ChallengeSent && mDNSOpaque64IsZero(id) && (cli.sin_port == ptr->cli.sin_port)) || // zero-id due to packet loss OK in state ChallengeSent
			 mDNSSameOpaque64(id, &ptr->id)) &&                        // id match
			(cli.sin_addr.s_addr == ptr->cli.sin_addr.s_addr) && (qtype == ptr->qtype) && SameDomainName(&ptr->qname, qname)) // same source, type, qname
			return ptr;
		ptr = ptr->next;
		}
	return NULL;
	}

mDNSlocal int
RecvNotify
	(
	DaemonInfo	*	d,
	PktMsg		*	pkt
	)
	{
	int	res;
	int	err = 0;

	pkt->msg.h.flags.b[0] |= kDNSFlag0_QR_Response;

	res = sendto( d->udpsd, &pkt->msg, pkt->len, 0, ( struct sockaddr* ) &pkt->src, sizeof( pkt->src ) );
	require_action( res == ( int ) pkt->len, exit, err = mStatus_UnknownErr; LogErr( "RecvNotify", "sendto" ) );

exit:

	return err;
	}


mDNSlocal int RecvLLQ( DaemonInfo *d, PktMsg *pkt, TCPSocket *sock )
	{
	DNSQuestion q;
	LargeCacheRecord opt;
	int i, err = -1;
	char addr[32];
	const mDNSu8 *qptr = pkt->msg.data;
    const mDNSu8 *end = (mDNSu8 *)&pkt->msg + pkt->len;
	const mDNSu8 *aptr;
	LLQOptData *llq = NULL;
	LLQEntry *e = NULL;
	
	HdrNToH(pkt);
	aptr = LocateAdditionals(&pkt->msg, end);	// Can't do this until after HdrNToH(pkt);
	inet_ntop(AF_INET, &pkt->src.sin_addr, addr, 32);

	VLog("Received LLQ msg from %s", addr);
	// sanity-check packet
	if (!pkt->msg.h.numQuestions || !pkt->msg.h.numAdditionals)
		{
		Log("Malformatted LLQ from %s with %d questions, %d additionals", addr, pkt->msg.h.numQuestions, pkt->msg.h.numAdditionals);
		goto end;
		}

	// Locate the OPT record.
	// According to RFC 2671, "One OPT pseudo-RR can be added to the additional data section of either a request or a response."
	// This implies that there may be *at most* one OPT record per DNS message, in the Additional Section,
	// but not necessarily the *last* entry in the Additional Section.
	for (i = 0; i < pkt->msg.h.numAdditionals; i++)
		{
		aptr = GetLargeResourceRecord(NULL, &pkt->msg, aptr, end, 0, kDNSRecordTypePacketAdd, &opt);
		if (!aptr) { Log("Malformatted LLQ from %s: could not get Additional record %d", addr, i); goto end; }
		if (opt.r.resrec.RecordType != kDNSRecordTypePacketNegative && opt.r.resrec.rrtype == kDNSType_OPT) break;
		}

	// validate OPT
	if (opt.r.resrec.rrtype != kDNSType_OPT) { Log("Malformatted LLQ from %s: last Additional not an OPT RR", addr); goto end; }
	if (opt.r.resrec.rdlength < pkt->msg.h.numQuestions * DNSOpt_LLQData_Space) { Log("Malformatted LLQ from %s: OPT RR to small (%d bytes for %d questions)", addr, opt.r.resrec.rdlength, pkt->msg.h.numQuestions); }
	
	// dispatch each question
	for (i = 0; i < pkt->msg.h.numQuestions; i++)
		{
		qptr = getQuestion(&pkt->msg, qptr, end, 0, &q);
		if (!qptr) { Log("Malformatted LLQ from %s: cannot read question %d", addr, i); goto end; }
		llq = (LLQOptData *)&opt.r.resrec.rdata->u.opt[0].u.llq + i; // point into OptData at index i
		if (llq->vers != kLLQ_Vers) { Log("LLQ from %s contains bad version %d (expected %d)", addr, llq->vers, kLLQ_Vers); goto end; }
		
		e = LookupLLQ(d, pkt->src, &q.qname, q.qtype, &llq->id);
		if (!e)
			{
			// no entry - if zero ID, create new
			e = NewLLQ(d, pkt->src, &q.qname, q.qtype, llq->llqlease );
			if (!e) goto end;
			}
		UpdateLLQ(d, e, llq, pkt->msg.h.id, sock);
		}
	err = 0;
	
	end:
	HdrHToN(pkt);
	return err;
	}


mDNSlocal mDNSBool IsAuthorized( DaemonInfo * d, PktMsg * pkt, DomainAuthInfo ** key, mDNSu16 * rcode, mDNSu16 * tcode )
	{
	const mDNSu8 	*	lastPtr = NULL;
	const mDNSu8 	*	ptr = NULL;
	DomainAuthInfo	*	keys;
	mDNSu8 			*	end	= ( mDNSu8* ) &pkt->msg + pkt->len;
	LargeCacheRecord	lcr;
	mDNSBool			hasTSIG = mDNSfalse;
	mDNSBool			strip = mDNSfalse;
	mDNSBool			ok = mDNSfalse;
	int					i;

	// Unused parameters

	( void ) d;

	HdrNToH(pkt);

	*key = NULL;

	if ( pkt->msg.h.numAdditionals )
		{
		ptr = LocateAdditionals(&pkt->msg, end);
		if (ptr)
			{
			for (i = 0; i < pkt->msg.h.numAdditionals; i++)
				{
				lastPtr = ptr;
				ptr = GetLargeResourceRecord(NULL, &pkt->msg, ptr, end, 0, kDNSRecordTypePacketAdd, &lcr);
				if (!ptr)
					{
					Log("Unable to read additional record");
					lastPtr = NULL;
					break;
					}
				}

				hasTSIG = ( ptr && lcr.r.resrec.RecordType != kDNSRecordTypePacketNegative && lcr.r.resrec.rrtype == kDNSType_TSIG );
			}
		else
			{
			LogMsg( "IsAuthorized: unable to find Additional section" );
			}
		}

	// If we don't know what zone this is, then it's authorized.

	if ( !pkt->zone )
		{
		ok = mDNStrue;
		strip = mDNSfalse;
		goto exit;
		}

	if ( IsQuery( pkt ) )
		{
		keys = pkt->zone->queryKeys;
		strip = mDNStrue;
		}
	else if ( IsUpdate( pkt ) )
		{
		keys = pkt->zone->updateKeys;
		strip = mDNSfalse;
		}
	else
		{
		ok = mDNStrue;
		strip = mDNSfalse;
		goto exit;
		}
		
	if ( pkt->isZonePublic )
		{
		ok = mDNStrue;
		goto exit;
		}

	// If there are no keys, then we're authorized

	if ( ( hasTSIG && !keys ) || ( !hasTSIG && keys ) )
		{
		Log( "Invalid TSIG spec %##s for zone %##s", lcr.r.resrec.name->c, pkt->zone->name.c );
		*rcode = kDNSFlag1_RC_NotAuth;
		*tcode = TSIG_ErrBadKey;
		strip = mDNStrue;
		ok = mDNSfalse;
		goto exit;
		}

	// Find the right key

	for ( *key = keys; *key; *key = (*key)->next )
		{
		if ( SameDomainName( lcr.r.resrec.name, &(*key)->keyname ) )
			{
			break;
			}
		}

	if ( !(*key) )
		{
		Log( "Invalid TSIG name %##s for zone %##s", lcr.r.resrec.name->c, pkt->zone->name.c );
		*rcode = kDNSFlag1_RC_NotAuth;
		*tcode = TSIG_ErrBadKey;
		strip = mDNStrue;
		ok = mDNSfalse;
		goto exit;
		}

	// Okay, we have the correct key and a TSIG record.  DNSDigest_VerifyMessage does the heavy
	// lifting of message verification

	pkt->msg.h.numAdditionals--;

	HdrHToN( pkt );

	ok = DNSDigest_VerifyMessage( &pkt->msg, ( mDNSu8* ) lastPtr, &lcr, (*key), rcode, tcode );

	HdrNToH( pkt );

	pkt->msg.h.numAdditionals++;

exit:

	if ( hasTSIG && strip )
		{
		// Strip the TSIG from the message

		pkt->msg.h.numAdditionals--;
		pkt->len = lastPtr - ( mDNSu8* ) ( &pkt->msg );
		}

	HdrHToN(pkt);

	return ok;
	}

// request handler wrappers for TCP and UDP requests
// (read message off socket, fork thread that invokes main processing routine and handles cleanup)

mDNSlocal void*
UDPMessageHandler
	(
	void * vptr
	)
	{
	UDPContext	*	context	= ( UDPContext* ) vptr;
	PktMsg		*	reply	= NULL;
	int				res;
	mStatus			err;

	// !!!KRS strictly speaking, we shouldn't use TCP for a UDP request because the server
	// may give us a long answer that would require truncation for UDP delivery to client

	reply = HandleRequest( context->d, &context->pkt );
	require_action( reply, exit, err = mStatus_UnknownErr );

	res = sendto( context->sd, &reply->msg, reply->len, 0, ( struct sockaddr* ) &context->pkt.src, sizeof( context->pkt.src ) );
	require_action_quiet( res == ( int ) reply->len, exit, LogErr( "UDPMessageHandler", "sendto" ) );

exit:

	if ( reply )
		{
		free( reply );
		}

	free( context );

	pthread_exit( NULL );

	return NULL;
	}


mDNSlocal int
RecvUDPMessage
	(
	DaemonInfo	*	self,
	int				sd
	)
	{
	UDPContext		*	context = NULL;
	pthread_t			tid;
	mDNSu16				rcode;
	mDNSu16				tcode;
	DomainAuthInfo	*	key;
	unsigned int		clisize = sizeof( context->cliaddr );
	int					res;
	mStatus				err = mStatus_NoError;
	
	context = malloc( sizeof( UDPContext ) );
	require_action( context, exit, err = mStatus_NoMemoryErr ; LogErr( "RecvUDPMessage", "malloc" ) );

	mDNSPlatformMemZero( context, sizeof( *context ) );
	context->d = self;
	context->sd = sd;

	res = recvfrom(sd, &context->pkt.msg, sizeof(context->pkt.msg), 0, (struct sockaddr *)&context->cliaddr, &clisize);

	require_action( res >= 0, exit, err = mStatus_UnknownErr ; LogErr( "RecvUDPMessage", "recvfrom" ) );
	context->pkt.len = res;
	require_action( clisize == sizeof( context->cliaddr ), exit, err = mStatus_UnknownErr ; Log( "Client address of unknown size %d", clisize ) );
	context->pkt.src = context->cliaddr;

	// Set the zone in the packet

	SetZone( context->d, &context->pkt );

	// Notify messages handled by main thread

	if ( IsNotify( &context->pkt ) )
		{
		int e = RecvNotify( self, &context->pkt );
		free(context);
		return e;
		}
	else if ( IsAuthorized( context->d, &context->pkt, &key, &rcode, &tcode ) )
		{
		if ( IsLLQRequest( &context->pkt ) )
			{
			// LLQ messages handled by main thread
			int e = RecvLLQ( self, &context->pkt, NULL );
			free(context);
			return e;
			}

		if ( IsLLQAck(&context->pkt ) )
			{
			// !!!KRS need to do acks + retrans
	
			free(context);
			return 0;
			}
	
		err = pthread_create( &tid, NULL, UDPMessageHandler, context );
		require_action( !err, exit, LogErr( "RecvUDPMessage", "pthread_create" ) );

		pthread_detach(tid);
		}
	else
		{
		PktMsg reply;
		int    e;

		memcpy( &reply, &context->pkt, sizeof( PktMsg ) );

		reply.msg.h.flags.b[0]  =  kDNSFlag0_QR_Response | kDNSFlag0_AA | kDNSFlag0_RD;
		reply.msg.h.flags.b[1]  =  kDNSFlag1_RA | kDNSFlag1_RC_NXDomain;

		e = sendto( sd, &reply.msg, reply.len, 0, ( struct sockaddr* ) &context->pkt.src, sizeof( context->pkt.src ) );
		require_action_quiet( e == ( int ) reply.len, exit, LogErr( "RecvUDPMessage", "sendto" ) );

		err = mStatus_NoAuth;
		}

exit:

	if ( err && context )
		{
		free( context );
		}

	return err;
	}


mDNSlocal void
FreeTCPContext
	(
	TCPContext * context
	)
	{
	if ( context )
		{
		if ( context->sock )
			{
			mDNSPlatformTCPCloseConnection( context->sock );
			}

		free( context );
		}
	}


mDNSlocal void*
TCPMessageHandler
	(
	void * vptr
	)
	{
	TCPContext	*	context	= ( TCPContext* ) vptr;
	PktMsg		*	reply = NULL;
	int				res;
	char 			buf[32];

    //!!!KRS if this read blocks indefinitely, we can run out of threads
	// read the request

	reply = HandleRequest( context->d, &context->pkt );
	require_action_quiet( reply, exit, LogMsg( "TCPMessageHandler: No reply for client %s", inet_ntop( AF_INET, &context->cliaddr.sin_addr, buf, 32 ) ) );

	// deliver reply to client

	res = SendPacket( context->sock, reply );
	require_action( res >= 0, exit, LogMsg("TCPMessageHandler: Unable to send reply to client %s", inet_ntop(AF_INET, &context->cliaddr.sin_addr, buf, 32 ) ) );

exit:

	FreeTCPContext( context );

	if ( reply )
		{
		free( reply );
		}

	pthread_exit(NULL);
	}


mDNSlocal void
RecvTCPMessage
	(
	void * param
	)
	{
	TCPContext		*	context = ( TCPContext* ) param;
	mDNSu16				rcode;
	mDNSu16				tcode;
	pthread_t			tid;
	DomainAuthInfo	*	key;
	PktMsg			*	pkt;
	mDNSBool			closed;
	mDNSBool			freeContext = mDNStrue;
	mStatus				err = mStatus_NoError;

	// Receive a packet.  It's okay if we don't actually read a packet, as long as the closed flag is
	// set to false.  This is because SSL/TLS layer might gobble up the first packet that we read off the
	// wire.  We'll let it do that, and wait for the next packet which will be ours.

	pkt = RecvPacket( context->sock, &context->pkt, &closed );
	if (pkt) HdrNToH(pkt);
	require_action( pkt || !closed, exit, err = mStatus_UnknownErr; LogMsg( "client disconnected" ) );

	if ( pkt )
		{
		// Always do this, regardless of what kind of packet it is.  If we wanted LLQ events to be sent over TCP,
		// we would change this line of code.  As it is now, we will reply to an LLQ via TCP, but then events
		// are sent over UDP

		RemoveSourceFromEventLoop( context->d, context->sock );

		// Set's the DNS Zone that is associated with this message

		SetZone( context->d, &context->pkt );

		// IsAuthorized will make sure the message is authorized for the designated zone.
		// After verifying the signature, it will strip the TSIG from the message

		if ( IsAuthorized( context->d, &context->pkt, &key, &rcode, &tcode ) )
			{
			if ( IsLLQRequest( &context->pkt ) )
				{
				// LLQ messages handled by main thread
				RecvLLQ( context->d, &context->pkt, context->sock);
				}
			else
				{
				err = pthread_create( &tid, NULL, TCPMessageHandler, context );

				if ( err )
					{
					LogErr( "RecvTCPMessage", "pthread_create" );
					err = mStatus_NoError;
					goto exit;
					}

				// Let the thread free the context

				freeContext = mDNSfalse;
					
				pthread_detach(tid);
				}
			}
		else
			{
			PktMsg reply;

			LogMsg( "Client %s Not authorized for zone %##s", inet_ntoa( context->pkt.src.sin_addr ), pkt->zone->name.c );

			memcpy( &reply, &context->pkt, sizeof( PktMsg ) );

			reply.msg.h.flags.b[0]  =  kDNSFlag0_QR_Response | kDNSFlag0_AA | kDNSFlag0_RD;
			reply.msg.h.flags.b[1]  =  kDNSFlag1_RA | kDNSFlag1_RC_Refused;

			SendPacket( context->sock, &reply );
			}
		}
	else
		{
		freeContext = mDNSfalse;
		}

exit:

	if ( err )
		{
		RemoveSourceFromEventLoop( context->d, context->sock );
		}

	if ( freeContext )
		{
		FreeTCPContext( context );
		}
	}


mDNSlocal int
AcceptTCPConnection
	(
	DaemonInfo		*	self,
	int					sd,
	TCPSocketFlags	flags
	)
	{
	TCPContext *	context = NULL;
	unsigned int	clilen = sizeof( context->cliaddr);
	int				newSock;
	mStatus			err = mStatus_NoError;
	
	context = ( TCPContext* ) malloc( sizeof( TCPContext ) );
	require_action( context, exit, err = mStatus_NoMemoryErr; LogErr( "AcceptTCPConnection", "malloc" ) );
	mDNSPlatformMemZero( context, sizeof( sizeof( TCPContext ) ) );
	context->d		 = self;
	newSock = accept( sd, ( struct sockaddr* ) &context->cliaddr, &clilen );
	require_action( newSock != -1, exit, err = mStatus_UnknownErr; LogErr( "AcceptTCPConnection", "accept" ) );

	context->sock = mDNSPlatformTCPAccept( flags, newSock );
	require_action( context->sock, exit, err = mStatus_UnknownErr; LogErr( "AcceptTCPConnection", "mDNSPlatformTCPAccept" ) );

	err = AddSourceToEventLoop( self, context->sock, RecvTCPMessage, context );
	require_action( !err, exit, LogErr( "AcceptTCPConnection", "AddSourceToEventLoop" ) );

exit:

	if ( err && context )
		{
		free( context );
		context = NULL;
		}

	return err;
	}


// main event loop
// listen for incoming requests, periodically check table for expired records, respond to signals
mDNSlocal int Run(DaemonInfo *d)
	{
	int staticMaxFD, nfds;
	fd_set rset;
	struct timeval timenow, timeout, EventTS, tablecheck = { 0, 0 };
	mDNSBool EventsPending = mDNSfalse;
	
   	VLog("Listening for requests...");

	staticMaxFD = 0;

	if ( d->tcpsd + 1  > staticMaxFD )				staticMaxFD = d->tcpsd + 1;
	if ( d->udpsd + 1  > staticMaxFD )				staticMaxFD = d->udpsd + 1;
	if ( d->tlssd + 1  > staticMaxFD )				staticMaxFD = d->tlssd + 1;
	if ( d->llq_tcpsd + 1 > staticMaxFD )			staticMaxFD = d->llq_tcpsd + 1;
	if ( d->llq_udpsd + 1 > staticMaxFD )			staticMaxFD = d->llq_udpsd + 1;
	if ( d->LLQEventListenSock + 1 > staticMaxFD )	staticMaxFD = d->LLQEventListenSock + 1;
	
	while(1)
		{
		EventSource	* source;
		int           maxFD;

		// set timeout
		timeout.tv_sec = timeout.tv_usec = 0;
		if (gettimeofday(&timenow, NULL)) { LogErr("Run", "gettimeofday"); return -1; }

		if (EventsPending)
			{
			if (timenow.tv_sec - EventTS.tv_sec >= 5)           // if we've been waiting 5 seconds for a "quiet" period to send
				{ GenLLQEvents(d); EventsPending = mDNSfalse; } // events, we go ahead and do it now
			else timeout.tv_usec = 500000;                      // else do events after 1/2 second with no new events or LLQs
			}
		if (!EventsPending)
			{
			// if no pending events, timeout when we need to check for expired records
			if (tablecheck.tv_sec && timenow.tv_sec - tablecheck.tv_sec >= 0)
				{ DeleteRecords(d, mDNSfalse); tablecheck.tv_sec = 0; } // table check overdue				
			if (!tablecheck.tv_sec) tablecheck.tv_sec = timenow.tv_sec + EXPIRATION_INTERVAL;
			timeout.tv_sec = tablecheck.tv_sec - timenow.tv_sec;
			}

		FD_ZERO(&rset);
		FD_SET( d->tcpsd, &rset );
		FD_SET( d->udpsd, &rset );
		FD_SET( d->tlssd, &rset );
		FD_SET( d->llq_tcpsd, &rset );
		FD_SET( d->llq_udpsd, &rset );
		FD_SET( d->LLQEventListenSock, &rset );

		maxFD = staticMaxFD;

		for ( source = ( EventSource* ) d->eventSources.Head; source; source = source->next )
			{
			FD_SET( source->fd, &rset );

			if ( source->fd > maxFD )
				{
				maxFD = source->fd;
				}
			}

		nfds = select( maxFD + 1, &rset, NULL, NULL, &timeout);
		if (nfds < 0)
			{
			if (errno == EINTR)
				{
				if (terminate)
					{
					// close sockets to prevent clients from making new requests during shutdown
					close( d->tcpsd );
					close( d->udpsd );
					close( d->tlssd );
					close( d->llq_tcpsd );
					close( d->llq_udpsd );
					d->tcpsd = d->udpsd = d->tlssd = d->llq_tcpsd = d->llq_udpsd = -1;
					DeleteRecords(d, mDNStrue);
					return 0;
					}
				else if (dumptable)
					{
					Log( "Received SIGINFO" );

					PrintLeaseTable(d);
					PrintLLQTable(d);
					PrintLLQAnswers(d);
					dumptable = 0;
					}
				else if (hangup)
					{
					int err;

					Log( "Received SIGHUP" );

					err = ParseConfig( d, cfgfile );

					if ( err )
						{
						LogErr( "Run", "ParseConfig" );
						return -1;
						}

					hangup = 0;
					}
				else
					{
					Log("Received unhandled signal - continuing");
					}
				}
			else
				{
				LogErr("Run", "select"); return -1;
				}
			}
		else if (nfds)
			{
			if (FD_ISSET(d->udpsd, &rset))		RecvUDPMessage( d, d->udpsd );
			if (FD_ISSET(d->llq_udpsd, &rset))	RecvUDPMessage( d, d->llq_udpsd );
			if (FD_ISSET(d->tcpsd, &rset))		AcceptTCPConnection( d, d->tcpsd, 0 );
			if (FD_ISSET(d->llq_tcpsd, &rset))	AcceptTCPConnection( d, d->llq_tcpsd, 0 );
			if (FD_ISSET(d->tlssd, &rset))  	AcceptTCPConnection( d, d->tlssd, TCP_SOCKET_FLAGS );
			if (FD_ISSET(d->LLQEventListenSock, &rset))
				{
				// clear signalling data off socket
				char buf[256];
				recv(d->LLQEventListenSock, buf, 256, 0);
				if (!EventsPending)
					{
					EventsPending = mDNStrue;
					if (gettimeofday(&EventTS, NULL)) { LogErr("Run", "gettimeofday"); return -1; }
					}
				}

			for ( source = ( EventSource* ) d->eventSources.Head; source; source = source->next )
				{
				if ( FD_ISSET( source->fd, &rset ) )
					{
					source->callback( source->context );
					break;  // in case we removed this guy from the event loop
					}
				}
			}
		else
			{
			// timeout
			if (EventsPending) { GenLLQEvents(d); EventsPending = mDNSfalse; }
			else { DeleteRecords(d, mDNSfalse); tablecheck.tv_sec = 0; }
			}
		}
	return 0;
	}

// signal handler sets global variables, which are inspected by main event loop
// (select automatically returns due to the handled signal)
mDNSlocal void HndlSignal(int sig)
	{
	if (sig == SIGTERM || sig == SIGINT ) { terminate = 1; return; }
	if (sig == INFO_SIGNAL)               { dumptable = 1; return; }
	if (sig == SIGHUP)                    { hangup    = 1; return; }
	}

mDNSlocal mStatus
SetPublicSRV
	(
	DaemonInfo	*	d,
	const char	*	name
	)
	{
	DNameListElem * elem;
	mStatus			err = mStatus_NoError;

	elem = ( DNameListElem* ) malloc( sizeof( DNameListElem ) );
	require_action( elem, exit, err = mStatus_NoMemoryErr );
	MakeDomainNameFromDNSNameString( &elem->name, name );
	elem->next = d->public_names;
	d->public_names = elem;

exit:

	return err;
	}


int main(int argc, char *argv[])
	{
	int started_via_launchd = 0;
	DaemonInfo *d;
	struct rlimit rlim;

	Log("dnsextd starting");

	d = malloc(sizeof(*d));
	if (!d) { LogErr("main", "malloc"); exit(1); }
	mDNSPlatformMemZero(d, sizeof(DaemonInfo));

	// Setup the public SRV record names

	SetPublicSRV(d, "_dns-update._udp.");
	SetPublicSRV(d, "_dns-llq._udp.");
	SetPublicSRV(d, "_dns-update-tls._tcp.");
	SetPublicSRV(d, "_dns-query-tls._tcp.");
	SetPublicSRV(d, "_dns-llq-tls._tcp.");

	// Setup signal handling
	
	if (signal(SIGHUP,      HndlSignal) == SIG_ERR) perror("Can't catch SIGHUP");
	if (signal(SIGTERM,     HndlSignal) == SIG_ERR) perror("Can't catch SIGTERM");
	if (signal(INFO_SIGNAL, HndlSignal) == SIG_ERR) perror("Can't catch SIGINFO");
	if (signal(SIGINT,      HndlSignal) == SIG_ERR) perror("Can't catch SIGINT");
	if (signal(SIGPIPE,     SIG_IGN  )  == SIG_ERR) perror("Can't ignore SIGPIPE");

	// remove open file limit
	rlim.rlim_max = RLIM_INFINITY;
	rlim.rlim_cur = RLIM_INFINITY;
	if (setrlimit(RLIMIT_NOFILE, &rlim) < 0)
		{
		LogErr("main", "setrlimit");
		Log("Using default file descriptor resource limit");
		}
	
	if (argc > 1 && !strcasecmp(argv[1], "-launchd"))
		{
		Log("started_via_launchd");
		started_via_launchd = 1;
		argv++;
		argc--;
		}
	if (ProcessArgs(argc, argv, d) < 0) { LogErr("main", "ProcessArgs"); exit(1); }

	if (!foreground && !started_via_launchd)
		{
		if (daemon(0,0))
			{
			LogErr("main", "daemon");
			foreground = 1;
			}
		}

	if (InitLeaseTable(d) < 0) { LogErr("main", "InitLeaseTable"); exit(1); }
	if (SetupSockets(d) < 0) { LogErr("main", "SetupSockets"); exit(1); }
	if (SetUpdateSRV(d) < 0) { LogErr("main", "SetUpdateSRV"); exit(1); }

	Run(d);

	Log("dnsextd stopping");

	if (ClearUpdateSRV(d) < 0) { LogErr("main", "ClearUpdateSRV"); exit(1); }  // clear update srv's even if Run or pthread_create returns an error
	free(d);
	exit(0);
	}


// These are stubbed out implementations of up-call routines that the various platform support layers
// call.  These routines are fully implemented in both mDNS.c and uDNS.c, but dnsextd doesn't
// link this code in.
//
// It's an error for these routines to actually be called, so perhaps we should log any call
// to them.
void mDNSCoreInitComplete( mDNS * const m, mStatus result) { ( void ) m; ( void ) result; }
void mDNS_ConfigChanged(mDNS *const m)  { ( void ) m; }
void mDNSCoreMachineSleep(mDNS * const m, mDNSBool wake) { ( void ) m; ( void ) wake; }
void mDNSCoreReceive(mDNS *const m, void *const msg, const mDNSu8 *const end,
                                const mDNSAddr *const srcaddr, const mDNSIPPort srcport,
                                const mDNSAddr *const dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID iid)
	{ ( void ) m; ( void ) msg; ( void ) end; ( void ) srcaddr; ( void ) srcport; ( void ) dstaddr; ( void ) dstport; ( void ) iid; }
DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSAddr *addr, const mDNSIPPort port, mDNSBool scoped, mDNSu32 timeout)
	{ ( void ) m; ( void ) d; ( void ) interface; ( void ) addr; ( void ) port; ( void ) scoped; ( void ) timeout; return(NULL); }
void mDNS_AddSearchDomain(const domainname *const domain, mDNSInterfaceID InterfaceID) { (void)domain; (void) InterfaceID;}
void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCallback *StatusCallback, const void *StatusContext)
	{ ( void ) m; ( void ) fqdn; ( void ) StatusCallback; ( void ) StatusContext; }
mDNSs32 mDNS_Execute   (mDNS *const m) { ( void ) m; return 0; }
mDNSs32 mDNS_TimeNow(const mDNS *const m) { ( void ) m; return 0; }
mStatus mDNS_Deregister(mDNS *const m, AuthRecord *const rr) { ( void ) m; ( void ) rr; return 0; }
void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping)
	{ ( void ) m; ( void ) set; ( void ) flapping; }
const char * const  mDNS_DomainTypeNames[1] = {};
mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, mDNS_DomainType DomainType, const domainname *dom,
                                const mDNSInterfaceID InterfaceID, mDNSQuestionCallback *Callback, void *Context)
	{ ( void ) m; ( void ) question; ( void ) DomainType; ( void ) dom; ( void ) InterfaceID; ( void ) Callback; ( void ) Context; return 0; }
mStatus mDNS_Register(mDNS *const m, AuthRecord *const rr) { ( void ) m; ( void ) rr; return 0; }
mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping)
	{ ( void ) m; ( void ) set; ( void ) flapping; return 0; }
void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn) { ( void ) m; ( void ) fqdn; }
void mDNS_SetFQDN(mDNS * const m) { ( void ) m; }
void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr,  const mDNSAddr *v6addr, const mDNSAddr *router)
	{ ( void ) m; ( void ) v4addr; ( void ) v6addr; ( void ) router; }
mStatus uDNS_SetupDNSConfig( mDNS *const m ) { ( void ) m; return 0; }
mStatus mDNS_SetSecretForDomain(mDNS *m, DomainAuthInfo *info,
	const domainname *domain, const domainname *keyname, const char *b64keydata, const domainname *hostname, mDNSIPPort *port, const char *autoTunnelPrefix)
	{ ( void ) m; ( void ) info; ( void ) domain; ( void ) keyname; ( void ) b64keydata; ( void ) hostname; (void) port; ( void ) autoTunnelPrefix; return 0; }
mStatus mDNS_StopQuery(mDNS *const m, DNSQuestion *const question) { ( void ) m; ( void ) question; return 0; }
void TriggerEventCompletion(void);
void TriggerEventCompletion() {}
mDNS mDNSStorage;


// For convenience when using the "strings" command, this is the last thing in the file
// The "@(#) " pattern is a special prefix the "what" command looks for
const char mDNSResponderVersionString_SCCS[] = "@(#) dnsextd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";

#if _BUILDING_XCODE_PROJECT_
// If the process crashes, then this string will be magically included in the automatically-generated crash log
const char *__crashreporter_info__ = mDNSResponderVersionString_SCCS + 5;
asm(".desc ___crashreporter_info__, 0x10");
#endif
