mirror of
https://github.com/darlinghq/darling-libresolv.git
synced 2024-11-26 22:10:20 +00:00
e67010e4cc
Not sure what version this is based on...
186 lines
4.1 KiB
C
186 lines
4.1 KiB
C
/*
|
|
* Copyright (c) 2003 - 2008 Apple, Inc. All rights reserved.
|
|
*
|
|
* @APPLE_LICENSE_HEADER_START@
|
|
*
|
|
* This file contains Original Code and/or Modifications of Original Code
|
|
* as defined in and that are subject to the Apple Public Source License
|
|
* Version 2.0 (the 'License'). You may not use this file except in
|
|
* compliance with the License. Please obtain a copy of the License at
|
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
|
* file.
|
|
*
|
|
* The Original Code and all software distributed under the License are
|
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
|
* Please see the License for the specific language governing rights and
|
|
* limitations under the License.
|
|
*
|
|
* @APPLE_LICENSE_HEADER_END@
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <mach/mach.h>
|
|
#include <pthread.h>
|
|
#include <netdb.h>
|
|
#include <netdb_async.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <dns.h>
|
|
#include <dns_util.h>
|
|
#include <stdarg.h>
|
|
#include <si_module.h>
|
|
|
|
extern void *LI_ils_create(char *fmt, ...);
|
|
|
|
/*
|
|
typedef void (*dns_async_callback)(int32_t status, char *buf, uint32_t len, struct sockaddr *from, int fromlen, void *context);
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
void *orig_callback;
|
|
void *orig_context;
|
|
si_mod_t *dns;
|
|
} _dns_context_t;
|
|
|
|
static void
|
|
_dns_callback(si_item_t *item, uint32_t status, void *ctx)
|
|
{
|
|
_dns_context_t *my_ctx;
|
|
si_dnspacket_t *res;
|
|
char *packet;
|
|
struct sockaddr *from;
|
|
uint32_t pl;
|
|
int fl;
|
|
|
|
if (ctx == NULL) return;
|
|
|
|
my_ctx = (_dns_context_t *)ctx;
|
|
if (my_ctx->orig_callback == NULL)
|
|
{
|
|
si_item_release(item);
|
|
si_module_release(my_ctx->dns);
|
|
free(my_ctx);
|
|
return;
|
|
}
|
|
|
|
if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
|
|
|
|
packet = NULL;
|
|
pl = 0;
|
|
from = NULL;
|
|
fl = 0;
|
|
|
|
res = NULL;
|
|
if (item != NULL) res = (si_dnspacket_t *)((char *)item + sizeof(si_item_t));
|
|
|
|
if ((res != NULL) && (res->dns_packet_len > 0))
|
|
{
|
|
packet = malloc(res->dns_packet_len);
|
|
if (packet == NULL) status = NO_RECOVERY;
|
|
else
|
|
{
|
|
pl = res->dns_packet_len;
|
|
memcpy(packet, res->dns_packet, res->dns_packet_len);
|
|
|
|
if (res->dns_server_len > 0)
|
|
{
|
|
from = malloc(res->dns_server_len);
|
|
if (from == NULL)
|
|
{
|
|
status = NO_RECOVERY;
|
|
free(packet);
|
|
packet = NULL;
|
|
pl = 0;
|
|
}
|
|
else
|
|
{
|
|
fl = res->dns_server_len;
|
|
memcpy(from, res->dns_server, res->dns_server_len);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
si_item_release(item);
|
|
|
|
((dns_async_callback)(my_ctx->orig_callback))(status, packet, pl, from, fl, my_ctx->orig_context);
|
|
|
|
si_module_release(my_ctx->dns);
|
|
free(my_ctx);
|
|
}
|
|
|
|
int32_t
|
|
dns_async_start(mach_port_t *p, const char *name, uint16_t dnsclass, uint16_t dnstype, uint32_t do_search, dns_async_callback callback, void *context)
|
|
{
|
|
si_mod_t *dns;
|
|
int call;
|
|
uint32_t c, t;
|
|
_dns_context_t *my_ctx;
|
|
|
|
*p = MACH_PORT_NULL;
|
|
|
|
if (name == NULL) return NO_RECOVERY;
|
|
|
|
dns = si_module_with_name("mdns");
|
|
if (dns == NULL) return NO_RECOVERY;
|
|
|
|
my_ctx = (_dns_context_t *)calloc(1, sizeof(_dns_context_t));
|
|
if (my_ctx == NULL)
|
|
{
|
|
si_module_release(dns);
|
|
return NO_RECOVERY;
|
|
}
|
|
|
|
my_ctx->orig_callback = callback;
|
|
my_ctx->orig_context = context;
|
|
my_ctx->dns = dns;
|
|
|
|
call = SI_CALL_DNS_QUERY;
|
|
if (do_search != 0) call = SI_CALL_DNS_SEARCH;
|
|
|
|
c = dnsclass;
|
|
t = dnstype;
|
|
|
|
*p = si_async_call(dns, call, name, NULL, NULL, c, t, 0, 0, (void *)_dns_callback, (void *)my_ctx);
|
|
if (*p == MACH_PORT_NULL)
|
|
{
|
|
free(my_ctx);
|
|
si_module_release(dns);
|
|
return NO_RECOVERY;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
dns_async_cancel(mach_port_t p)
|
|
{
|
|
si_async_cancel(p);
|
|
}
|
|
|
|
int32_t
|
|
dns_async_send(mach_port_t *p, const char *name, uint16_t dnsclass, uint16_t dnstype, uint32_t do_search)
|
|
{
|
|
return dns_async_start(p, name, dnsclass, dnstype, do_search, NULL, NULL);
|
|
}
|
|
|
|
/* unsupported */
|
|
int32_t
|
|
dns_async_receive(mach_port_t p, char **buf, uint32_t *len, struct sockaddr **from, uint32_t *fromlen)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int32_t
|
|
dns_async_handle_reply(void *msg)
|
|
{
|
|
si_async_handle_reply(msg);
|
|
return 0;
|
|
}
|