2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
26 #include <netdb_async.h> /* async gethostbyXXX function prototypes */
29 #include <mach/mach.h>
30 #include <netinfo/_lu_types.h>
31 #include <netinfo/lookup.h>
32 #include <rpc/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
43 extern mach_port_t _lu_port
;
44 extern int _lu_running(void);
49 #define msgh_request_port msgh_remote_port
50 #define msgh_reply_port msgh_local_port
54 gethostbyaddr_async_callback hostAddr
;
55 gethostbyname_async_callback hostName
;
56 getipnodebyaddr_async_callback nodeAddr
;
57 getipnodebyname_async_callback nodeName
;
58 } a_request_callout_t
;
60 typedef struct a_requests
{
61 struct a_requests
*next
;
69 mach_port_t replyPort
;
70 a_request_callout_t callout
;
72 struct hostent
*hent
; /* if reply known in XXX_start() */
75 static a_requests_t
*a_requests
= NULL
;
76 static pthread_mutex_t a_requests_lock
= PTHREAD_MUTEX_INITIALIZER
;
78 #define MAX_LOOKUP_ATTEMPTS 10
87 mach_msg_type_number_t indataCnt
,
88 mach_port_t
*replyPort
92 mach_msg_header_t Head
;
95 mach_msg_type_number_t indataCnt
;
100 register Request
*InP
= &In
;
101 mach_msg_return_t mr
;
102 unsigned int msgh_size
;
104 if (indataCnt
> 4096) {
105 return MIG_ARRAY_TOO_LARGE
;
108 if (*replyPort
== MACH_PORT_NULL
) {
109 mr
= mach_port_allocate(mach_task_self(),
110 MACH_PORT_RIGHT_RECEIVE
,
112 if (mr
!= KERN_SUCCESS
) {
117 msgh_size
= (sizeof(Request
) - 16384) + ((4 * indataCnt
));
118 InP
->Head
.msgh_bits
= MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE
);
119 /* InP->Head.msgh_size = msgh_size; /* msgh_size passed as argument */
120 InP
->Head
.msgh_request_port
= server
;
121 InP
->Head
.msgh_reply_port
= *replyPort
;
122 InP
->Head
.msgh_id
= 4241776;
123 InP
->NDR
= NDR_record
;
125 InP
->indataCnt
= indataCnt
;
126 (void)memcpy((char *)InP
->indata
, (const char *)indata
, 4 * indataCnt
);
128 mr
= mach_msg(&InP
->Head
, /* msg */
129 MACH_SEND_MSG
, /* options */
130 msgh_size
, /* send_size */
132 MACH_PORT_NULL
, /* rcv_name */
133 MACH_MSG_TIMEOUT_NONE
, /* timeout */
134 MACH_PORT_NULL
); /* notify */
136 case MACH_MSG_SUCCESS
:
139 case MACH_SEND_INVALID_REPLY
:
140 (void)mach_port_destroy(mach_task_self(), *replyPort
);
154 ooline_data
*outdata
,
155 mach_msg_type_number_t
*outdataCnt
,
156 security_token_t
*token
160 mach_msg_header_t Head
;
161 mach_msg_body_t msgh_body
;
162 mach_msg_ool_descriptor_t outdata
;
164 mach_msg_type_number_t outdataCnt
;
165 mach_msg_format_0_trailer_t trailer
;
170 * mach_msg_header_t Head;
172 * kern_return_t RetCode;
173 * } mig_reply_error_t;
176 register Reply
*OutP
= msg
;
177 mach_msg_format_0_trailer_t
*TrailerP
;
178 boolean_t msgh_simple
;
180 if (OutP
->Head
.msgh_id
!= (4241776 + 100)) {
181 if (OutP
->Head
.msgh_id
== MACH_NOTIFY_SEND_ONCE
)
182 return MIG_SERVER_DIED
;
184 return MIG_REPLY_MISMATCH
;
187 msgh_simple
= !(OutP
->Head
.msgh_bits
& MACH_MSGH_BITS_COMPLEX
);
189 TrailerP
= (mach_msg_format_0_trailer_t
*)((vm_offset_t
)OutP
+
190 round_msg(OutP
->Head
.msgh_size
));
191 if (TrailerP
->msgh_trailer_type
!= MACH_MSG_TRAILER_FORMAT_0
)
192 return MIG_TRAILER_ERROR
;
194 if (msgh_simple
&& ((mig_reply_error_t
*)OutP
)->RetCode
!= KERN_SUCCESS
)
195 return ((mig_reply_error_t
*)OutP
)->RetCode
;
197 *outdata
= (ooline_data
)(OutP
->outdata
.address
);
198 *outdataCnt
= OutP
->outdataCnt
;
200 *token
= TrailerP
->msgh_sender
;
206 static a_requests_t
*
207 request_extract(mach_port_t port
)
209 a_requests_t
*request0
, *request
;
211 pthread_mutex_lock(&a_requests_lock
);
213 request
= a_requests
;
215 if (port
== request
->replyPort
) {
216 /* request found, remove from list */
218 request0
->next
= request
->next
;
220 a_requests
= request
->next
;
224 /* not this request, skip to next */
226 request
= request
->next
;
229 pthread_mutex_unlock(&a_requests_lock
);
236 request_queue(a_requests_t
*request
)
238 pthread_mutex_lock(&a_requests_lock
);
239 request
->next
= a_requests
;
240 a_requests
= request
;
241 pthread_mutex_unlock(&a_requests_lock
);
248 sendCannedReply(a_requests_t
*request
, int *error
)
252 * mach_msg_header_t Head;
254 * kern_return_t RetCode;
255 * } mig_reply_error_t;
258 mig_reply_error_t Out
;
259 register mig_reply_error_t
*OutP
= &Out
;
262 mach_msg_return_t mr
;
263 unsigned int msgh_size
;
266 * allocate reply port
268 kr
= mach_port_allocate(mach_task_self(),
269 MACH_PORT_RIGHT_RECEIVE
,
270 &request
->replyPort
);
271 if (kr
!= KERN_SUCCESS
) {
272 *error
= NO_RECOVERY
;
276 kr
= mach_port_insert_right(mach_task_self(),
279 MACH_MSG_TYPE_MAKE_SEND
);
280 if (kr
!= KERN_SUCCESS
) {
281 (void) mach_port_destroy(mach_task_self(), request
->replyPort
);
282 *error
= NO_RECOVERY
;
287 * queue reply message
289 msgh_size
= sizeof(Out
);
290 OutP
->Head
.msgh_bits
= MACH_MSGH_BITS(19, 0);
291 /* OutP->Head.msgh_size = msgh_size; /* msgh_size passed as argument */
292 OutP
->Head
.msgh_request_port
= request
->replyPort
;
293 OutP
->Head
.msgh_reply_port
= MACH_PORT_NULL
;
294 OutP
->Head
.msgh_id
= 4241776 + 100;
295 OutP
->RetCode
= MIG_REMOTE_ERROR
;
296 OutP
->NDR
= NDR_record
;
298 mr
= mach_msg(&OutP
->Head
, /* msg */
299 MACH_SEND_MSG
, /* options */
300 msgh_size
, /* send_size */
302 MACH_PORT_NULL
, /* rcv_name */
303 MACH_MSG_TIMEOUT_NONE
, /* timeout */
304 MACH_PORT_NULL
); /* notify */
305 if (mr
!= MACH_MSG_SUCCESS
) {
306 if (mr
== MACH_SEND_INVALID_REPLY
) {
307 (void)mach_port_destroy(mach_task_self(), request
->replyPort
);
309 *error
= NO_RECOVERY
;
318 _gethostbyaddr_async_start(const char *addr
,
321 a_request_callout_t callout
,
327 a_requests_t
*request
;
333 static int proc4
= -1;
334 struct in_addr
*v4addr
;
337 if (_lookup_link(_lu_port
, "gethostbyaddr", &proc4
) != KERN_SUCCESS
) {
338 *error
= NO_RECOVERY
;
339 return MACH_PORT_NULL
;
343 if (len
!= sizeof(struct in_addr
)) {
344 *error
= NO_RECOVERY
;
348 v4addr
= malloc(len
);
349 memmove(v4addr
, addr
, len
);
350 v4addr
->s_addr
= htonl(v4addr
->s_addr
);
352 address
= (void *)v4addr
;
360 static int proc6
= -1;
361 struct in6_addr
*v6addr
;
364 if (_lookup_link(_lu_port
, "getipv6nodebyaddr", &proc6
) != KERN_SUCCESS
) {
365 *error
= NO_RECOVERY
;
366 return MACH_PORT_NULL
;
370 if (len
!= sizeof(struct in6_addr
)) {
371 *error
= NO_RECOVERY
;
375 v6addr
= malloc(len
);
376 memmove(v6addr
, addr
, len
);
377 v6addr
->__u6_addr
.__u6_addr32
[0] = htonl(v6addr
->__u6_addr
.__u6_addr32
[0]);
378 v6addr
->__u6_addr
.__u6_addr32
[1] = htonl(v6addr
->__u6_addr
.__u6_addr32
[1]);
379 v6addr
->__u6_addr
.__u6_addr32
[2] = htonl(v6addr
->__u6_addr
.__u6_addr32
[2]);
380 v6addr
->__u6_addr
.__u6_addr32
[3] = htonl(v6addr
->__u6_addr
.__u6_addr32
[3]);
382 address
= (void *)v6addr
;
389 *error
= NO_RECOVERY
;
390 return MACH_PORT_NULL
;
393 request
= malloc(sizeof(a_requests_t
));
394 request
->next
= NULL
;
395 request
->retry
= MAX_LOOKUP_ATTEMPTS
;
396 request
->request
.proc
= proc
;
397 request
->request
.data
= (ooline_data
)address
;
398 request
->request
.dataLen
= len
/ BYTES_PER_XDR_UNIT
;
399 request
->request
.want
= want
;
400 request
->replyPort
= MACH_PORT_NULL
;
401 request
->callout
= callout
;
402 request
->context
= context
;
403 request
->hent
= NULL
;
406 * allocate reply port, send query to lookupd
408 if (_lookup_all_tx(_lu_port
,
409 request
->request
.proc
,
410 request
->request
.data
,
411 request
->request
.dataLen
,
412 &request
->replyPort
) == KERN_SUCCESS
) {
413 request_queue(request
);
415 if (request
->request
.data
) free(request
->request
.data
);
417 *error
= NO_RECOVERY
;
418 return MACH_PORT_NULL
;
421 return request
->replyPort
;
426 _gethostbyaddr_async_handleReply(void *replyMsg
,
427 a_requests_t
**requestP
,
433 unsigned int datalen
;
435 mach_msg_header_t
*msg
= (mach_msg_header_t
*)replyMsg
;
436 a_requests_t
*request
;
437 kern_return_t status
;
438 security_token_t token
;
440 request
= request_extract(msg
->msgh_local_port
);
442 /* excuse me, what happenned to the request info? */
450 /* unpack the reply */
451 status
= _lookup_all_rx(replyMsg
, &data
, &datalen
, &token
);
456 case MIG_SERVER_DIED
:
457 if (--request
->retry
> 0) {
458 /* retry the request */
459 if (_lookup_all_tx(_lu_port
,
460 request
->request
.proc
,
461 request
->request
.data
,
462 request
->request
.dataLen
,
463 &request
->replyPort
) == KERN_SUCCESS
) {
464 request_queue(request
);
471 *error
= HOST_NOT_FOUND
;
475 datalen
*= BYTES_PER_XDR_UNIT
;
477 if (token
.val
[0] != 0) {
478 vm_deallocate(mach_task_self(), (vm_address_t
)data
, datalen
);
479 *error
= NO_RECOVERY
;
483 xdrmem_create(&inxdr
, data
, datalen
, XDR_DECODE
);
486 if (!xdr_int(&inxdr
, &count
)) {
488 vm_deallocate(mach_task_self(), (vm_address_t
)data
, datalen
);
489 *error
= NO_RECOVERY
;
495 vm_deallocate(mach_task_self(), (vm_address_t
)data
, datalen
);
496 *error
= HOST_NOT_FOUND
;
501 *he
= extract_host(&inxdr
, request
->request
.want
, error
);
503 vm_deallocate(mach_task_self(), (vm_address_t
)data
, datalen
);
509 gethostbyaddr_async_start(const char *addr
,
512 gethostbyaddr_async_callback callout
,
515 a_request_callout_t cb
;
518 if (!_lu_running()) {
519 h_errno
= NO_RECOVERY
;
520 return MACH_PORT_NULL
;
523 cb
.hostAddr
= callout
;
524 mp
= _gethostbyaddr_async_start(addr
, len
, type
, cb
, context
, &h_errno
);
530 gethostbyaddr_async_handleReply(void *replyMsg
)
533 struct hostent
*he
= NULL
;
534 a_requests_t
*request
= NULL
;
536 if (_gethostbyaddr_async_handleReply(replyMsg
, &request
, &he
, &error
)) {
537 /* if we have an answer to provide */
539 (request
->callout
.hostAddr
)(he
, request
->context
);
541 (void)mach_port_destroy(mach_task_self(), request
->replyPort
);
542 if (request
->request
.data
) free(request
->request
.data
);
544 if (he
) freehostent(he
);
552 getipnodebyaddr_async_start(const void *addr
,
556 getipnodebyaddr_async_callback callout
,
559 a_request_callout_t cb
;
562 if (!_lu_running()) {
563 *error
= NO_RECOVERY
;
564 return MACH_PORT_NULL
;
567 if ((af
== AF_INET6
) &&
568 (len
== sizeof(struct in6_addr
)) &&
569 (is_a4_mapped((const char *)addr
) || is_a4_compat((const char *)addr
))) {
571 * this is really a v4 address
573 addr
+= sizeof(struct in6_addr
) - sizeof(struct in_addr
);
574 len
= sizeof(struct in_addr
);
578 cb
.nodeAddr
= callout
;
579 mp
= _gethostbyaddr_async_start(addr
, len
, af
, cb
, context
, error
);
585 getipnodebyaddr_async_handleReply(void *replyMsg
)
588 struct hostent
*he
= NULL
;
589 a_requests_t
*request
= NULL
;
591 if (_gethostbyaddr_async_handleReply(replyMsg
, &request
, &he
, &error
)) {
592 /* if we have an answer to provide */
593 (request
->callout
.nodeAddr
)(he
, error
, request
->context
);
595 (void)mach_port_destroy(mach_task_self(), request
->replyPort
);
596 if (request
->request
.data
) free(request
->request
.data
);
599 * Note: it is up to the callback function to call
609 _gethostbyname_async_start(const char *name
,
612 a_request_callout_t callout
,
616 boolean_t is_addr
= FALSE
;
617 mach_port_t mp
= MACH_PORT_NULL
;
620 a_requests_t
*request
;
622 if ((name
== NULL
) || (name
[0] == '\0')) {
624 return MACH_PORT_NULL
;
627 af
= (want
== WANT_A4_ONLY
) ? AF_INET
: AF_INET6
;
629 if ((af
== AF_INET
) || (want
== WANT_MAPPED_A4_ONLY
)) {
630 static int proc4
= -1;
633 if (_lookup_link(_lu_port
, "gethostbyname", &proc4
) != KERN_SUCCESS
) {
634 *error
= NO_RECOVERY
;
635 return MACH_PORT_NULL
;
639 } else /* if (af == AF_INET6) */ {
640 static int proc6
= -1;
643 if (_lookup_link(_lu_port
, "getipv6nodebyname", &proc6
) != KERN_SUCCESS
)
645 *error
= NO_RECOVERY
;
646 return MACH_PORT_NULL
;
652 request
= malloc(sizeof(a_requests_t
));
653 request
->next
= NULL
;
654 request
->retry
= MAX_LOOKUP_ATTEMPTS
;
655 request
->request
.proc
= proc
;
656 request
->request
.data
= NULL
;
657 request
->request
.dataLen
= 0;
658 request
->request
.want
= want
;
659 request
->replyPort
= MACH_PORT_NULL
;
660 request
->callout
= callout
;
661 request
->context
= context
;
662 request
->hent
= NULL
;
667 struct in_addr v4addr
;
669 memset(&v4addr
, 0, sizeof(struct in_addr
));
670 if (inet_aton(name
, &v4addr
) == 1) {
671 /* return a fake hostent */
672 request
->hent
= fake_hostent(name
, v4addr
);
680 struct in_addr v4addr
;
681 struct in6_addr v6addr
;
683 memset(&v6addr
, 0, sizeof(struct in6_addr
));
684 if (inet_pton(af
, name
, &v6addr
) == 1) {
685 /* return a fake hostent */
686 request
->hent
= fake_hostent6(name
, v6addr
);
691 memset(&v4addr
, 0, sizeof(struct in_addr
));
692 if (inet_aton(name
, &v4addr
) == 1) {
693 if (want
== WANT_A4_ONLY
) {
695 *error
= HOST_NOT_FOUND
;
696 return MACH_PORT_NULL
;
699 v6addr
.__u6_addr
.__u6_addr32
[0] = 0x00000000;
700 v6addr
.__u6_addr
.__u6_addr32
[1] = 0x00000000;
701 v6addr
.__u6_addr
.__u6_addr32
[2] = htonl(0x0000ffff);
702 memmove(&(v6addr
.__u6_addr
.__u6_addr32
[3]), &(v4addr
.s_addr
), sizeof(struct in_addr
));
704 /* return a fake hostent */
705 request
->hent
= fake_hostent6(name
, v6addr
);
713 *error
= NO_RECOVERY
;
714 return MACH_PORT_NULL
;
719 * queue reply message
721 if (sendCannedReply(request
, error
)) {
722 request_queue(request
);
723 return request
->replyPort
;
725 freehostent(request
->hent
);
727 return MACH_PORT_NULL
;
731 request
->request
.dataLen
= _LU_MAXLUSTRLEN
+ BYTES_PER_XDR_UNIT
;
732 request
->request
.data
= malloc(request
->request
.dataLen
);
734 xdrmem_create(&outxdr
, request
->request
.data
, request
->request
.dataLen
, XDR_ENCODE
);
735 if (!xdr__lu_string(&outxdr
, (_lu_string
*)&name
)) {
736 xdr_destroy(&outxdr
);
737 free(request
->request
.data
);
739 *error
= NO_RECOVERY
;
740 return MACH_PORT_NULL
;
743 request
->request
.dataLen
= xdr_getpos(&outxdr
) / BYTES_PER_XDR_UNIT
;
746 * allocate reply port, send query to lookupd
748 if (_lookup_all_tx(_lu_port
,
749 request
->request
.proc
,
750 request
->request
.data
,
751 request
->request
.dataLen
,
752 &request
->replyPort
) == KERN_SUCCESS
) {
753 request_queue(request
);
754 mp
= request
->replyPort
;
756 free(request
->request
.data
);
758 *error
= NO_RECOVERY
;
762 xdr_destroy(&outxdr
);
768 _gethostbyname_async_handleReply(void *replyMsg
,
769 a_requests_t
**requestP
,
775 unsigned int datalen
;
778 mach_msg_header_t
*msg
= (mach_msg_header_t
*)replyMsg
;
779 a_requests_t
*request
;
780 kern_return_t status
;
781 security_token_t token
;
784 request
= request_extract(msg
->msgh_local_port
);
786 /* excuse me, what happenned to the request info? */
796 * if the reply was already available when the
803 /* unpack the reply */
804 status
= _lookup_all_rx(replyMsg
, &data
, &datalen
, &token
);
809 case MIG_SERVER_DIED
:
810 if (--request
->retry
> 0) {
814 if (_lookup_all_tx(_lu_port
,
815 request
->request
.proc
,
816 request
->request
.data
,
817 request
->request
.dataLen
,
818 &request
->replyPort
) == KERN_SUCCESS
) {
819 request_queue(request
);
826 *error
= HOST_NOT_FOUND
;
830 datalen
*= BYTES_PER_XDR_UNIT
;
832 if (token
.val
[0] != 0) {
833 vm_deallocate(mach_task_self(), (vm_address_t
)data
, datalen
);
834 *error
= NO_RECOVERY
;
838 xdrmem_create(&inxdr
, data
, datalen
, XDR_DECODE
);
841 if (!xdr_int(&inxdr
, &count
)) {
843 vm_deallocate(mach_task_self(), (vm_address_t
)data
, datalen
);
844 *error
= NO_RECOVERY
;
850 vm_deallocate(mach_task_self(), (vm_address_t
)data
, datalen
);
851 *error
= HOST_NOT_FOUND
;
855 want
= request
->request
.want
;
856 if (want
== WANT_A6_OR_MAPPED_A4_IF_NO_A6
) want
= WANT_A6_ONLY
;
858 *he
= extract_host(&inxdr
, want
, error
);
860 vm_deallocate(mach_task_self(), (vm_address_t
)data
, datalen
);
866 gethostbyname_async_start(const char *name
,
867 gethostbyname_async_callback callout
,
870 a_request_callout_t cb
;
872 mach_port_t mp
= MACH_PORT_NULL
;
874 if (!_lu_running()) {
875 h_errno
= NO_RECOVERY
;
876 return MACH_PORT_NULL
;
879 cb
.hostName
= callout
;
880 mp
= _gethostbyname_async_start(name
, WANT_A4_ONLY
, &error
, cb
, context
);
889 gethostbyname_async_handleReply(void *replyMsg
)
893 a_requests_t
*request
;
895 if (_gethostbyname_async_handleReply(replyMsg
, &request
, &he
, &error
)) {
896 /* if we have an answer to provide */
898 (request
->callout
.hostAddr
)(he
, request
->context
);
900 (void)mach_port_destroy(mach_task_self(), request
->replyPort
);
901 if (request
->request
.data
) free(request
->request
.data
);
903 if (he
) freehostent(he
);
911 getipnodebyname_async_start(const char *name
,
915 getipnodebyname_async_callback callout
,
918 a_request_callout_t cb
;
921 mach_port_t mp
= MACH_PORT_NULL
;
922 int want
= WANT_A4_ONLY
;
924 if (!_lu_running()) {
925 h_errno
= NO_RECOVERY
;
926 return MACH_PORT_NULL
;
930 * IF AI_ADDRCONFIG is set, we need to know what interface flavors we really have.
932 if (flags
& AI_ADDRCONFIG
) {
933 struct ifaddrs
*ifa
, *ifap
;
935 if (getifaddrs(&ifa
) < 0) {
936 *error
= NO_RECOVERY
;
937 return MACH_PORT_NULL
;
940 for (ifap
= ifa
; ifap
!= NULL
; ifap
= ifap
->ifa_next
) {
941 if (ifap
->ifa_addr
== NULL
)
943 if ((ifap
->ifa_flags
& IFF_UP
) == 0)
945 if (ifap
->ifa_addr
->sa_family
== AF_INET
) {
947 } else if (ifap
->ifa_addr
->sa_family
== AF_INET6
) {
954 /* Bail out if there are no interfaces */
955 if ((if4
== 0) && (if6
== 0)) {
957 return MACH_PORT_NULL
;
962 * Figure out what we want.
963 * If user asked for AF_INET, we only want V4 addresses.
969 if ((flags
& AI_ADDRCONFIG
) && (if4
== 0)) {
971 return MACH_PORT_NULL
;
978 if (flags
& (AI_V4MAPPED
|AI_V4MAPPED_CFG
)) {
979 if (flags
& AI_ALL
) {
980 want
= WANT_A6_PLUS_MAPPED_A4
;
982 want
= WANT_A6_OR_MAPPED_A4_IF_NO_A6
;
985 if ((flags
& AI_ADDRCONFIG
) && (if6
== 0)) {
987 return MACH_PORT_NULL
;
994 cb
.nodeName
= callout
;
995 mp
= _gethostbyname_async_start(name
, want
, &h_errno
, cb
, context
);
1001 getipnodebyname_async_handleReply(void *replyMsg
)
1004 struct hostent
*he
= NULL
;
1005 a_requests_t
*request
= NULL
;
1007 if (_gethostbyname_async_handleReply(replyMsg
, &request
, &he
, &error
)) {
1009 * we have an answer to provide
1012 (error
== HOST_NOT_FOUND
) &&
1013 ((request
->request
.want
== WANT_A6_PLUS_MAPPED_A4
) ||
1014 (request
->request
.want
== WANT_A6_OR_MAPPED_A4_IF_NO_A6
))) {
1016 * no host found (yet), if requested we send a
1017 * followup query to lookupd.
1019 static int proc4
= -1;
1022 if (_lookup_link(_lu_port
, "gethostbyname", &proc4
) != KERN_SUCCESS
) {
1023 error
= NO_RECOVERY
;
1028 request
->request
.proc
= proc4
;
1029 request
->request
.want
= WANT_MAPPED_A4_ONLY
;
1030 if (_lookup_all_tx(_lu_port
,
1031 request
->request
.proc
,
1032 request
->request
.data
,
1033 request
->request
.dataLen
,
1034 &request
->replyPort
) == KERN_SUCCESS
) {
1035 request_queue(request
);
1038 error
= NO_RECOVERY
;
1043 (request
->callout
.nodeName
)(he
, error
, request
->context
);
1044 (void)mach_port_destroy(mach_task_self(), request
->replyPort
);
1045 if (request
->request
.data
) free(request
->request
.data
);
1048 * Note: it is up to the callback function to call