/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1.  Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
 *     contributors may be used to endorse or promote products derived from this
 *     software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef DNSSD_IPC_H
#define DNSSD_IPC_H

#include "dns_sd.h"

//
// Common cross platform services
//
#if defined(WIN32)
#	include <winsock2.h>
#	define dnssd_InvalidSocket	INVALID_SOCKET
#	define dnssd_SocketValid(s) ((s) != INVALID_SOCKET)
#	define dnssd_EWOULDBLOCK	WSAEWOULDBLOCK
#	define dnssd_EINTR			WSAEINTR
#	define dnssd_ECONNRESET		WSAECONNRESET
#	define dnssd_sock_t			SOCKET
#	define dnssd_socklen_t		int
#	define dnssd_close(sock)	closesocket(sock)
#	define dnssd_errno			WSAGetLastError()
#	define dnssd_strerror(X)	win32_strerror(X)
#	define ssize_t				int
#	define getpid				_getpid
#	define unlink				_unlink
extern char *win32_strerror(int inErrorCode);
#else
#	include <sys/types.h>
#	include <unistd.h>
#ifdef __ANDROID__
#	include <sys/socket.h>
#endif
#	include <sys/un.h>
#	include <string.h>
#	include <stdio.h>
#	include <stdlib.h>
#	include <sys/stat.h>
#ifndef __ANDROID__
#	include <sys/socket.h>
#endif
#	include <netinet/in.h>
#	define dnssd_InvalidSocket	-1
#	define dnssd_SocketValid(s) ((s) >= 0)
#	define dnssd_EWOULDBLOCK	EWOULDBLOCK
#	define dnssd_EINTR			EINTR
#	define dnssd_ECONNRESET		ECONNRESET
#	define dnssd_EPIPE			EPIPE
#	define dnssd_sock_t			int
#	define dnssd_socklen_t		unsigned int
#	define dnssd_close(sock)	close(sock)
#	define dnssd_errno			errno
#	define dnssd_strerror(X)	strerror(X)
#endif

#if defined(USE_TCP_LOOPBACK)
#	define AF_DNSSD				AF_INET
#	define MDNS_TCP_SERVERADDR	"127.0.0.1"
#	define MDNS_TCP_SERVERPORT	5354
#	define LISTENQ				5
#	define dnssd_sockaddr_t		struct sockaddr_in
#else
#	define AF_DNSSD				AF_LOCAL
#	ifndef MDNS_UDS_SERVERPATH
#		define MDNS_UDS_SERVERPATH	"/var/run/mDNSResponder"
#	endif
#	define LISTENQ				100
    // longest legal control path length
#	define MAX_CTLPATH			256
#	define dnssd_sockaddr_t		struct sockaddr_un
#endif

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

// General UDS constants
#define TXT_RECORD_INDEX ((uint32_t)(-1))	// record index for default text record

// IPC data encoding constants and types
#define VERSION 1
#define IPC_FLAGS_NOREPLY 1	// set flag if no asynchronous replies are to be sent to client

// Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire
// structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed
// correctly, our compile-time assertion checks will catch it and prevent inadvertent generation of non-working code.
#ifndef packedstruct
 #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
  #define packedstruct struct __attribute__((__packed__))
  #define packedunion  union  __attribute__((__packed__))
 #else
  #define packedstruct struct
  #define packedunion  union
 #endif
#endif

typedef enum
    {
    request_op_none = 0,	// No request yet received on this connection
    connection_request = 1,	// connected socket via DNSServiceConnect()
    reg_record_request,		// reg/remove record only valid for connected sockets
    remove_record_request,
    enumeration_request,
    reg_service_request,
    browse_request,
    resolve_request,
    query_request,
    reconfirm_record_request,
    add_record_request,
    update_record_request,
    setdomain_request,		// Up to here is in Tiger and B4W 1.0.3
	getproperty_request,	// New in B4W 1.0.4
    port_mapping_request,	// New in Leopard and B4W 2.0
	addrinfo_request,
	send_bpf,				// New in SL
    sethost_request,
	cancel_request = 63
    } request_op_t;

typedef enum
    {
    enumeration_reply_op = 64,
    reg_service_reply_op,
    browse_reply_op,
    resolve_reply_op,
    query_reply_op,
    reg_record_reply_op,	// Up to here is in Tiger and B4W 1.0.3
    getproperty_reply_op,	// New in B4W 1.0.4
    port_mapping_reply_op,	// New in Leopard and B4W 2.0
	addrinfo_reply_op,
    sethost_reply,
    } reply_op_t;

#if defined(_WIN64)
#	pragma pack(4)
#endif

// Define context object big enough to hold a 64-bit pointer,
// to accomodate 64-bit clients communicating with 32-bit daemon.
// There's no reason for the daemon to ever be a 64-bit process, but its clients might be
typedef packedunion
    {
    void *context;
    uint32_t u32[2];
    } client_context_t;

typedef packedstruct
    {
    uint32_t version;
    uint32_t datalen;
    uint32_t ipc_flags;
    uint32_t op;		// request_op_t or reply_op_t
    client_context_t client_context; // context passed from client, returned by server in corresponding reply
    uint32_t reg_index;            // identifier for a record registered via DNSServiceRegisterRecord() on a
    // socket connected by DNSServiceCreateConnection().  Must be unique in the scope of the connection, such that and
    // index/socket pair uniquely identifies a record.  (Used to select records for removal by DNSServiceRemoveRecord())
    } ipc_msg_hdr;

// routines to write to and extract data from message buffers.
// caller responsible for bounds checking.
// ptr is the address of the pointer to the start of the field.
// it is advanced to point to the next field, or the end of the message

void put_uint32(const uint32_t l, char **ptr);
uint32_t get_uint32(const char **ptr, const char *end);

void put_uint16(uint16_t s, char **ptr);
uint16_t get_uint16(const char **ptr, const char *end);

#define put_flags put_uint32
#define get_flags get_uint32

#define put_error_code put_uint32
#define get_error_code get_uint32

int put_string(const char *str, char **ptr);
int get_string(const char **ptr, const char *const end, char *buffer, int buflen);

void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
const char *get_rdata(const char **ptr, const char *end, int rdlen);  // return value is rdata pointed to by *ptr -
                                         // rdata is not copied from buffer.

void ConvertHeaderBytes(ipc_msg_hdr *hdr);

struct CompileTimeAssertionChecks_dnssd_ipc
	{
	// Check that the compiler generated our on-the-wire packet format structure definitions
	// properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
	char assert0[(sizeof(client_context_t) ==  8) ? 1 : -1];
	char assert1[(sizeof(ipc_msg_hdr)      == 28) ? 1 : -1];
	};

#endif // DNSSD_IPC_H
