]> git.saurik.com Git - apple/libinfo.git/commitdiff
Libinfo-330.tar.gz mac-os-x-1063 v330
authorApple <opensource@apple.com>
Tue, 13 Oct 2009 18:05:29 +0000 (18:05 +0000)
committerApple <opensource@apple.com>
Tue, 13 Oct 2009 18:05:29 +0000 (18:05 +0000)
15 files changed:
lookup.subproj/aliasdb.h
lookup.subproj/bootparams.h
lookup.subproj/cache_module.c
lookup.subproj/ds_module.c
lookup.subproj/file_module.c
lookup.subproj/ils.c
lookup.subproj/ils.h
lookup.subproj/libinfo.c
lookup.subproj/mdns_module.c
lookup.subproj/netdb.h
lookup.subproj/netdb_async.h
lookup.subproj/search_module.c
lookup.subproj/si_getaddrinfo.c
lookup.subproj/si_module.c
lookup.subproj/si_module.h

index 7961135f1eb3e75c13d97a3aefbbded6c20b5776..fc8b20258e7e970e646cc27a58682aabdf92cc11 100644 (file)
@@ -1,23 +1,22 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2009 Apple Inc.  All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  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 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * 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
+ * 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 OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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@
  */
index 377298d5edabf6683902ddbb0b20802a85e172b6..ab172061aa22cfdcbeed5686025f61dddd106d26 100644 (file)
@@ -1,23 +1,22 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2009 Apple Inc.  All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  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 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * 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
+ * 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 OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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@
  */
index 8423f627b0872b02c8c4598ecf0e839596b741a0..3fa0071dbebc2fb2dd9c77db80ccb6e8bf6f09fe 100644 (file)
@@ -208,7 +208,7 @@ cache_alias_all(si_mod_t *si)
 }
 
 __private_extern__ si_item_t *
-cache_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+cache_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
 
@@ -224,7 +224,7 @@ cache_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
 }
 
 __private_extern__ si_item_t *
-cache_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+cache_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
 
@@ -362,7 +362,7 @@ cache_mac_all(si_mod_t *si)
 }
 
 __private_extern__ si_item_t *
-cache_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, uint32_t *err)
+cache_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *ignored, uint32_t *err)
 {
        /*
         * Caching of getnameinfo(3) is not supported.
@@ -476,7 +476,6 @@ si_module_static_cache()
        out->sim_wants_addrinfo = NULL;
        out->sim_addrinfo = NULL;
 
-       /* no nameinfo support */
        out->sim_nameinfo = cache_nameinfo;
 
        return out;
index b5496b020e11da7e6c52f1b7ad8e57b4f008d79d..ac3af3dcce77ce518383e0a90e4368f6bb92526b 100644 (file)
@@ -1512,7 +1512,7 @@ ds_alias_all(si_mod_t *si)
 }
 
 __private_extern__ si_item_t *
-ds_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+ds_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
 {
        static int proc = -1;
        kvbuf_t *request;
@@ -1564,7 +1564,7 @@ ds_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
 }
 
 __private_extern__ si_item_t *
-ds_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+ds_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
 {
        static int proc = -1;
        kvbuf_t *request;
@@ -1915,7 +1915,7 @@ ds_mac_bymac(si_mod_t *si, const char *mac)
 }
 
 static si_list_t *
-ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, uint32_t *err)
+ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *ignored, uint32_t *err)
 {
        static int proc = -1;
        si_list_t *list, *out;
@@ -1972,7 +1972,7 @@ ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, u
        /* look up canonical name of numeric host */
        if ((numerichost == 1) && (flags & AI_CANONNAME) && (node != NULL))
        {
-               item = si_host_byaddr(si, node, family, NULL);
+               item = si_host_byaddr(si, node, family, NULL, NULL);
                if (item != NULL)
                {
                        h = (struct hostent *)((uintptr_t)item + sizeof(si_item_t));
index b58558f50a45dc1248a16e7f701aa23099fbbfec..1744e1d53fb3712f7e22ec6071ba267c8302f57a 100644 (file)
@@ -1524,7 +1524,7 @@ file_grouplist(si_mod_t *si, const char *name)
 }
 
 __private_extern__ si_item_t *
-file_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+file_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
 
@@ -1537,7 +1537,7 @@ file_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
 }
 
 __private_extern__ si_item_t *
-file_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+file_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
 
index bdf121b89eda4453cdcd9d660d68ece8121b328a..776c6a60f2f87b80870d228b83d0bc0ec6d03096 100644 (file)
@@ -1,23 +1,22 @@
 /*
- * Copyright (c) 1999-2009 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2009 Apple Inc.  All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  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 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * 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
+ * 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 OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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@
  */
index 7a9eef8e8b715892c6e644a12908bf98574d6da9..49a5280d2080910d6970a7c8b46a1f5f841548d5 100644 (file)
@@ -1,23 +1,22 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2009 Apple Inc.  All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  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 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * 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
+ * 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 OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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@
  */
index 30dd71ef8dafc80b848599b3f8c69fd357085491..127d78f349dc2330706037b33bfc95cb2ac28821 100644 (file)
@@ -73,7 +73,7 @@ si_search(void)
 {
        static si_mod_t *search = NULL;
        static OSSpinLock spin = OS_SPINLOCK_INIT;
-       
+
        if (search == NULL)
        {
                OSSpinLockLock(&spin);
@@ -209,7 +209,7 @@ getpwnam_async_call(const char *name, si_user_async_callback callback, void *con
        sictx->cat = CATEGORY_USER;
        sictx->key_offset = 100;
 
-       return si_async_call(si_search(), SI_CALL_USER_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_USER_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -255,7 +255,7 @@ getpwuid_async_call(uid_t uid, si_user_async_callback callback, void *context)
        sictx->cat = CATEGORY_USER;
        sictx->key_offset = 200;
 
-       return si_async_call(si_search(), SI_CALL_USER_BYUID, NULL, NULL, (uint32_t)uid, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_USER_BYUID, NULL, NULL, NULL, (uint32_t)uid, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -315,11 +315,11 @@ int
 setpassent(int ignored)
 {
        si_list_t *list;
-       
+
 #ifdef CALL_TRACE
        fprintf(stderr, "-> %s\n", __func__);
 #endif
-       
+
        list = LI_get_thread_list(CATEGORY_USER);
        si_list_reset(list);
 
@@ -362,7 +362,7 @@ getgrnam_async_call(const char *name, si_group_async_callback callback, void *co
        sictx->cat = CATEGORY_GROUP;
        sictx->key_offset = 100;
 
-       return si_async_call(si_search(), SI_CALL_GROUP_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_GROUP_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -408,7 +408,7 @@ getgrgid_async_call(gid_t gid, si_group_async_callback callback, void *context)
        sictx->cat = CATEGORY_GROUP;
        sictx->key_offset = 200;
 
-       return si_async_call(si_search(), SI_CALL_GROUP_BYGID, NULL, NULL, (uint32_t)gid, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_GROUP_BYGID, NULL, NULL, NULL, (uint32_t)gid, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -468,11 +468,11 @@ int
 setgroupent(int ignored)
 {
        si_list_t *list;
-       
+
 #ifdef CALL_TRACE
        fprintf(stderr, "-> %s\n", __func__);
 #endif
-       
+
        list = LI_get_thread_list(CATEGORY_GROUP);
        si_list_reset(list);
 
@@ -698,28 +698,28 @@ getgroupcount(const char *name, gid_t basegid)
        si_item_t *item;
        si_grouplist_t *gl;
        gid_t *groups;
-       
+
 #ifdef CALL_TRACE
        fprintf(stderr, "-> %s %s %d\n", __func__, name, basegid);
 #endif
-       
+
        if (name == NULL) return 0;
-       
+
        item = si_grouplist(si_search(), name);
        LI_set_thread_item(CATEGORY_GROUPLIST, item);
        if (item == NULL) return -1;
-       
+
        gl = (si_grouplist_t *)((uintptr_t)item + sizeof(si_item_t));
-       
+
        count = 0;
        groups = NULL;
-       
+
        status = merge_gid(&groups, basegid, &count);
        if (status != 0) return status;
-       
+
        status = merge_gid(&groups, gl->gl_basegid, &count);
        if (status != 0) return status;
-       
+
        for (i = 0; i < gl->gl_count; i++)
        {
                g = (gid_t)*(gl->gl_gid[i]);
@@ -813,7 +813,7 @@ alias_getbyname_async_call(const char *name, si_alias_async_callback callback, v
        sictx->cat = CATEGORY_ALIAS;
        sictx->key_offset = 100;
 
-       return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -895,8 +895,8 @@ gethostbynameerrno(const char *name, int *err)
        status = SI_STATUS_NO_ERROR;
        item = NULL;
 
-       if (inet_aton(name, &addr4) == 1) item = si_ipnode_byname(si_search(), name, AF_INET, 0, &status);
-       else item = si_host_byname(si_search(), name, AF_INET, &status);
+       if (inet_aton(name, &addr4) == 1) item = si_ipnode_byname(si_search(), name, AF_INET, 0, NULL, &status);
+       else item = si_host_byname(si_search(), name, AF_INET, NULL, &status);
 
        if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
        if (err != NULL) *err = status;
@@ -922,8 +922,8 @@ gethostbyname(const char *name)
        status = SI_STATUS_NO_ERROR;
        item = NULL;
 
-       if (inet_aton(name, &addr4) == 1) item = si_ipnode_byname(si_search(), name, AF_INET, 0, &status);
-       else item = si_host_byname(si_search(), name, AF_INET, &status);
+       if (inet_aton(name, &addr4) == 1) item = si_ipnode_byname(si_search(), name, AF_INET, 0, NULL, &status);
+       else item = si_host_byname(si_search(), name, AF_INET, NULL, &status);
 
        if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
        h_errno = status;
@@ -951,7 +951,7 @@ gethostbyname_async_call(const char *name, si_host_async_callback callback, void
        sictx->cat = CATEGORY_HOST;
        sictx->key_offset = 100;
 
-       return si_async_call(si_search(), SI_CALL_HOST_BYNAME, name, NULL, AF_INET, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_HOST_BYNAME, name, NULL, NULL, AF_INET, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 mach_port_t
@@ -979,7 +979,7 @@ gethostbyname_async_handle_reply(void *param)
 #ifdef CALL_TRACE
        fprintf(stderr, "<< %s\n", __func__);
 #endif
-       
+
        msg = (mach_msg_header_t *)param;
        si_async_handle_reply(msg);
 }
@@ -989,7 +989,7 @@ void
 gethostbyname_async_handleReply(void *param)
 {
        mach_msg_header_t *msg;
-               
+
 #ifdef CALL_TRACE
        fprintf(stderr, "<< %s\n", __func__);
 #endif
@@ -1018,11 +1018,11 @@ gethostbyname2(const char *name, int af)
 
        if (((af == AF_INET) && (inet_aton(name, &addr4) == 1)) || ((af == AF_INET6) && (inet_pton(af, name, &addr6) == 1)))
        {
-               item = si_ipnode_byname(search, name, (uint32_t)af, 0, &status);
+               item = si_ipnode_byname(search, name, (uint32_t)af, 0, NULL, &status);
        }
        else
        {
-               item = si_host_byname(search, name, (uint32_t)af, &status);
+               item = si_host_byname(search, name, (uint32_t)af, NULL, &status);
        }
 
        if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
@@ -1051,7 +1051,7 @@ gethostbyname2_async_call(const char *name, int af, si_group_async_callback call
        sictx->cat = CATEGORY_HOST;
        sictx->key_offset = 100;
 
-       return si_async_call(si_search(), SI_CALL_HOST_BYNAME, name, NULL, (uint32_t)af, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_HOST_BYNAME, name, NULL, NULL, (uint32_t)af, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -1086,7 +1086,7 @@ gethostbyaddr(const void *addr, socklen_t len, int type)
 
        status = SI_STATUS_NO_ERROR;
 
-       item = si_host_byaddr(si_search(), addr, (uint32_t)type, &status);
+       item = si_host_byaddr(si_search(), addr, (uint32_t)type, NULL, &status);
        if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
        h_errno = status;
 
@@ -1116,7 +1116,7 @@ gethostbyaddr_async_call(const void *addr, socklen_t len, int type, si_host_asyn
 
        /* addr is not a C string - pass length in num3 */
        addrlen = len;
-       return si_async_call(si_search(), SI_CALL_HOST_BYADDR, addr, NULL, (uint32_t)type, 0, addrlen, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_HOST_BYADDR, addr, NULL, NULL, (uint32_t)type, 0, addrlen, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 mach_port_t
@@ -1147,7 +1147,7 @@ gethostbyaddr_async_handle_reply(void *param)
 #ifdef CALL_TRACE
        fprintf(stderr, "<< %s\n", __func__);
 #endif
-       
+
        msg = (mach_msg_header_t *)param;
        si_async_handle_reply(msg);
 }
@@ -1178,7 +1178,7 @@ getipnodebyname(const char *name, int family, int flags, int *err)
 
        status = SI_STATUS_NO_ERROR;
 
-       item = si_ipnode_byname(si_search(), name, family, flags, &status);
+       item = si_ipnode_byname(si_search(), name, family, flags, NULL, &status);
        if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
        if (err != NULL) *err = status;
 
@@ -1205,7 +1205,7 @@ getipnodebyname_async_call(const char *name, int family, int flags, int *err, si
        sictx->cat = CATEGORY_HOST;
        sictx->key_offset = -1;
 
-       return si_async_call(si_search(), SI_CALL_IPNODE_BYNAME, name, NULL, (uint32_t)family, (uint32_t)flags, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_IPNODE_BYNAME, name, NULL, NULL, (uint32_t)family, (uint32_t)flags, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 mach_port_t
@@ -1314,7 +1314,7 @@ getipnodebyaddr(const void *src, size_t len, int family, int *err)
                family = AF_INET;
        }
 
-       item = si_host_byaddr(si_search(), src, family, (uint32_t *)err);
+       item = si_host_byaddr(si_search(), src, family, NULL, (uint32_t *)err);
        if (item == NULL) return NULL;
 
        return (struct hostent *)((uintptr_t)item + sizeof(si_item_t));
@@ -1379,7 +1379,7 @@ getipnodebyaddr_async_call(const void *src, socklen_t len, int family, int *err,
 
        /* src is not a C string - pass length in num3 */
        srclen = len;
-       return si_async_call(si_search(), SI_CALL_HOST_BYADDR, src, NULL, (uint32_t)family, 0, srclen, 0, (void *)si_libinfo_ipnode_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_HOST_BYADDR, src, NULL, NULL, (uint32_t)family, 0, srclen, 0, (void *)si_libinfo_ipnode_callback, sictx);
 }
 
 mach_port_t
@@ -1427,7 +1427,7 @@ sethostent(int ignored)
 #ifdef CALL_TRACE
        fprintf(stderr, "-- %s\n", __func__);
 #endif
-       
+
        LI_set_thread_list(CATEGORY_HOST, NULL);
 }
 
@@ -1496,7 +1496,8 @@ ether_hostton(const char *name, struct ether_addr *e)
 
 /* XXX to do? async ether_hostton */
 
-int ether_ntohost(char *name, const struct ether_addr *e)
+int
+ether_ntohost(char *name, const struct ether_addr *e)
 {
        si_item_t *item;
        char *cname;
@@ -1560,7 +1561,7 @@ getnetbyname_async_call(const char *name, si_network_async_callback callback, vo
        sictx->cat = CATEGORY_NETWORK;
        sictx->key_offset = 100;
 
-       return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -1610,7 +1611,7 @@ getnetbyaddr_async_call(uint32_t net, int type, si_group_async_callback callback
        sictx->cat = CATEGORY_NETWORK;
        sictx->key_offset = 200;
 
-       return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR, NULL, NULL, net, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR, NULL, NULL, NULL, net, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -1629,7 +1630,7 @@ setnetent(int ignored)
 #ifdef CALL_TRACE
        fprintf(stderr, "-- %s\n", __func__);
 #endif
-       
+
        LI_set_thread_list(CATEGORY_NETWORK, NULL);
 }
 
@@ -1701,7 +1702,7 @@ getservbyname_async_call(const char *name, const char *proto, si_service_async_c
        sictx->cat = CATEGORY_SERVICE;
        sictx->key_offset = 100;
 
-       return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME, name, proto, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME, name, proto, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -1747,7 +1748,7 @@ getservbyport_async_call(int port, const char *proto, si_group_async_callback ca
        sictx->cat = CATEGORY_SERVICE;
        sictx->key_offset = 200;
 
-       return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT, NULL, proto, port, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT, NULL, proto, NULL, port, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -1766,7 +1767,7 @@ setservent(int ignored)
 #ifdef CALL_TRACE
        fprintf(stderr, "-- %s\n", __func__);
 #endif
-       
+
        LI_set_thread_list(CATEGORY_SERVICE, NULL);
 }
 
@@ -1838,7 +1839,7 @@ getprotobyname_async_call(const char *name, si_protocol_async_callback callback,
        sictx->cat = CATEGORY_PROTOCOL;
        sictx->key_offset = 100;
 
-       return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -1884,7 +1885,7 @@ getprotobynumber_async_call(int number, si_group_async_callback callback, void *
        sictx->cat = CATEGORY_PROTOCOL;
        sictx->key_offset = 200;
 
-       return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER, NULL, NULL, number, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER, NULL, NULL, NULL, number, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -1903,7 +1904,7 @@ setprotoent(int ignored)
 #ifdef CALL_TRACE
        fprintf(stderr, "-- %s\n", __func__);
 #endif
-       
+
        LI_set_thread_list(CATEGORY_PROTOCOL, NULL);
 }
 
@@ -1975,7 +1976,7 @@ getrpcbyname_async_call(const char *name, si_rpc_async_callback callback, void *
        sictx->cat = CATEGORY_RPC;
        sictx->key_offset = 100;
 
-       return si_async_call(si_search(), SI_CALL_RPC_BYNAME, name, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_RPC_BYNAME, name, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -2028,7 +2029,7 @@ getrpcbynumber_async_call(int number, si_group_async_callback callback, void *co
        sictx->cat = CATEGORY_RPC;
        sictx->key_offset = 200;
 
-       return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER, NULL, NULL, number, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER, NULL, NULL, NULL, number, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -2047,7 +2048,7 @@ setrpcent(int ignored)
 #ifdef CALL_TRACE
        fprintf(stderr, "-- %s\n", __func__);
 #endif
-       
+
        LI_set_thread_list(CATEGORY_RPC, NULL);
 }
 
@@ -2129,7 +2130,7 @@ getfsspec_async_call(const char *spec, si_fs_async_callback callback, void *cont
        sictx->cat = CATEGORY_FS;
        sictx->key_offset = 100;
 
-       return si_async_call(si_search(), SI_CALL_FS_BYSPEC, spec, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_FS_BYSPEC, spec, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -2175,7 +2176,7 @@ getfsfile_async_call(const char *file, si_fs_async_callback callback, void *cont
        sictx->cat = CATEGORY_FS;
        sictx->key_offset = 200;
 
-       return si_async_call(si_search(), SI_CALL_FS_BYFILE, file, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_FS_BYFILE, file, NULL, NULL, 0, 0, 0, 0, (void *)si_libinfo_general_callback, sictx);
 }
 
 void
@@ -2234,8 +2235,8 @@ endfsent(void)
 
 /* GETADDRINFO */
 
-int
-getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
+static int
+_getaddrinfo_internal(const char *nodename, const char *servname, const struct addrinfo *hints, const char *interface, struct addrinfo **res)
 {
        si_list_t *list;
        uint32_t family, socktype, protocol, flags, status;
@@ -2259,10 +2260,10 @@ getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *h
        }
 
 #ifdef CALL_TRACE
-       fprintf(stderr, "-> %s %s %s %u %u %u 0x%08x\n", __func__, nodename, servname, family, socktype, protocol, flags);
+       fprintf(stderr, "-> %s %s %s %u %u %u 0x%08x %s\n", __func__, nodename, servname, family, socktype, protocol, flags, (interface == NULL) ? "" : interface);
 #endif
 
-       list = si_addrinfo(si_search(), nodename, servname, family, socktype, protocol, flags, &status);
+       list = si_addrinfo(si_search(), nodename, servname, family, socktype, protocol, flags, interface, &status);
        if ((status != SI_STATUS_NO_ERROR) || (list == NULL))
        {
                si_list_release(list);
@@ -2291,6 +2292,12 @@ getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *h
        return status;
 }
 
+int
+getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
+{
+       return _getaddrinfo_internal(nodename, servname, hints, NULL, res);
+}
+
 #ifdef CALL_TRACE
 
 static char *
@@ -2509,8 +2516,9 @@ si_libinfo_addrinfo_callback(si_list_t *list, uint32_t status, void *ctx)
        free(sictx);
 }
 
+/* SPI */
 mach_port_t
-getaddrinfo_async_call(const char *nodename, const char *servname, const struct addrinfo *hints, si_addrinfo_async_callback callback, void *context)
+_getaddrinfo_interface_async_call(const char *nodename, const char *servname, const struct addrinfo *hints, const char *interface, si_addrinfo_async_callback callback, void *context)
 {
        si_context_t *sictx;
        uint32_t family, socktype, protocol, flags;
@@ -2540,7 +2548,13 @@ getaddrinfo_async_call(const char *nodename, const char *servname, const struct
        sictx->cat = CATEGORY_ADDRINFO;
        sictx->key_offset = 0;
 
-       return si_async_call(si_search(), SI_CALL_ADDRINFO, nodename, servname, family, socktype, protocol, flags, (void *)si_libinfo_addrinfo_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_ADDRINFO, nodename, servname, interface, family, socktype, protocol, flags, (void *)si_libinfo_addrinfo_callback, sictx);
+}
+
+mach_port_t
+getaddrinfo_async_call(const char *nodename, const char *servname, const struct addrinfo *hints, si_addrinfo_async_callback callback, void *context)
+{
+       return _getaddrinfo_interface_async_call(nodename, servname, hints, NULL, callback, context);
 }
 
 int32_t
@@ -2594,8 +2608,8 @@ getaddrinfo_async_handle_reply(void *param)
 
 /* GETNAMEINFO */
 
-int
-getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *service, socklen_t servicelen, int flags)
+static int
+_getnameinfo_interface_internal(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *service, socklen_t servicelen, int flags, const char *interface)
 {
        si_item_t *item;
        si_nameinfo_t *ni;
@@ -2618,11 +2632,11 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t no
        if (wantn == 0) flags |= NI_NUMERICHOST;
        if (wants == 0) flags |= NI_NUMERICSERV;
 
-       item = si_nameinfo(si_search(), sa, flags, &status);
+       item = si_nameinfo(si_search(), sa, flags, interface, &status);
        if ((status != SI_STATUS_NO_ERROR) || (item == NULL))
        {
                si_item_release(item);
-       
+
                if (status == SI_STATUS_NO_ERROR) status = EAI_NONAME;
                else if (status <= SI_STATUS_EAI_PLUS_100) status = EAI_FAIL;
                else if (status >= SI_STATUS_ERRNO_PLUS_200) status = EAI_FAIL;
@@ -2664,6 +2678,12 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t no
        return 0;
 }
 
+int
+getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *service, socklen_t servicelen, int flags)
+{
+       return _getnameinfo_interface_internal(sa, salen, node, nodelen, service, servicelen, flags, NULL);
+}
+
 static void
 si_libinfo_nameinfo_callback(si_item_t *item, uint32_t status, void *ctx)
 {
@@ -2709,8 +2729,9 @@ si_libinfo_nameinfo_callback(si_item_t *item, uint32_t status, void *ctx)
        free(sictx);
 }
 
+/* SPI */
 mach_port_t
-getnameinfo_async_call(const struct sockaddr *sa, size_t len, int flags, si_nameinfo_async_callback callback, void *context)
+_getnameinfo_interface_async_call(const struct sockaddr *sa, size_t len, int flags, const char *interface, si_nameinfo_async_callback callback, void *context)
 {
        si_context_t *sictx;
        uint32_t salen;
@@ -2729,7 +2750,13 @@ getnameinfo_async_call(const struct sockaddr *sa, size_t len, int flags, si_name
 
        /* sa is not a C string - pass length in num3 */
        salen = len;
-       return si_async_call(si_search(), SI_CALL_NAMEINFO, (const char *)sa, NULL, flags, 0, salen, 0, (void *)si_libinfo_nameinfo_callback, sictx);
+       return si_async_call(si_search(), SI_CALL_NAMEINFO, (const char *)sa, NULL, interface, flags, 0, salen, 0, (void *)si_libinfo_nameinfo_callback, sictx);
+}
+
+mach_port_t
+getnameinfo_async_call(const struct sockaddr *sa, size_t len, int flags, si_nameinfo_async_callback callback, void *context)
+{
+       return _getnameinfo_interface_async_call(sa, len, flags, NULL, callback, context);
 }
 
 int32_t
@@ -3069,14 +3096,14 @@ user_from_uid(uid_t uid, int nouser)
 {
        struct passwd *pw;
        static char buf[16];
-       
+
        pw = getpwuid(uid);
        if (pw != NULL) return pw->pw_name;
-       
+
        if (nouser) return NULL;
-       
+
        snprintf(buf, sizeof(buf), "%u", uid);
-       return buf;     
+       return buf;
 }
 
 char *
@@ -3084,14 +3111,14 @@ group_from_gid(gid_t gid, int nogroup)
 {
        struct group *gr;
        static char buf[16];
-       
+
        gr = getgrgid(gid);
        if (gr != NULL) return gr->gr_name;
-       
+
        if (nogroup) return NULL;
-       
+
        snprintf(buf, sizeof(buf), "%u", gid);
-       return buf;     
+       return buf;
 }
 
 /* no longer supported */
@@ -3181,4 +3208,3 @@ bootp_getbyip(struct ether_addr *enaddr, char **name, struct in_addr *ipaddr, ch
 #endif
        return 0;
 }
-
index b90fb5bad5e646077404ba214bdbcc55ef44b3cd..9b61a4efab008da6e9ced722c61ab8f04146f5ce 100644 (file)
 #include <sys/param.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
 #include <time.h>
 #include <unistd.h>
 #include <asl.h>
@@ -176,9 +178,9 @@ typedef struct {
 DNSServiceRef _mdns_sdref;
 DNSServiceRef _mdns_old_sdref;
 
-static int _mdns_query_mDNSResponder(const char *name, int class, int type, 
-       uint8_t *answer, uint32_t *anslen,
-       mdns_reply_t *reply, uint32_t timeout);
+static int _mdns_query_mDNSResponder(const char *name, int class, int type, const char *interface,
+                                                                        uint8_t *answer, uint32_t *anslen,
+                                                                        mdns_reply_t *reply, uint32_t timeout);
 
 static int _mdns_resolver_get_option(dns_resolver_t *resolver, const char* option);
 static void _mdns_hostent_clear(mdns_hostent_t *h);
@@ -237,34 +239,34 @@ _mdns_create_search_list(dns_resolver_t *resolver)
        if (resolver->domain == NULL) return NULL;
        domain = strdup(resolver->domain);
        if (domain == NULL) return NULL;
-       
+
        // count dots
        n = 0;
        for (p = domain; *p != '\0'; p++) {
                if (*p == '.') n++;
        }
-       
+
        // trim trailing dots
        for (p--; (p >= domain) && (*p == '.'); p--) {
                *p = '\0';
                n--;
        }
-       
+
        // make sure the resulting string is not empty
        if (p < domain) {
                free(domain);
                return NULL;
        }
-       
+
        // dots are separators, so number of components is one larger
        n++;
-       
+
        m = 0;
        list = (char **)calloc(n+1, sizeof(char *));
        if (list == NULL) return NULL;
        // first item in list is domain itself
        list[m++] = domain;
-       
+
        // include parent domains with at least LOCALDOMAINPARTS components
        p = domain;
        while (n > LOCALDOMAINPARTS) {
@@ -347,8 +349,7 @@ _mdns_config_init_default_resolvers(mdns_config_t *config)
        }
        config->n_defaults = m;
        // sort list by search order ascending
-        qsort(config->defaults, config->n_defaults,
-               sizeof(dns_resolver_t *), _mdns_compare_resolvers);
+       qsort(config->defaults, config->n_defaults, sizeof(dns_resolver_t *), _mdns_compare_resolvers);
 }
 
 #if 0
@@ -423,20 +424,25 @@ _mdns_print_hostent(mdns_hostent_t* h)
  * Retain the mdns configuration.
  */
 static mdns_config_t *
-_mdns_config_retain(mdns_config_t *config) {
+_mdns_config_retain(mdns_config_t *config)
+{
        int32_t rc;
+
        if (config == NULL) return NULL;
        rc = OSAtomicIncrement32Barrier(&config->rc);
        assert(rc > 1);
        return config;
 }
+
 /* _mdns_config_release
  * Releases the mdns configuration structure and
  * frees the data if no references remain.
  */
 static void
-_mdns_config_release(mdns_config_t *config) {
+_mdns_config_release(mdns_config_t *config)
+{
        int32_t rc;
+
        if (config == NULL) return;
        rc = OSAtomicDecrement32Barrier(&config->rc);
        assert(rc >= 0);
@@ -471,6 +477,7 @@ _mdns_copy_system_config(void)
                res = notify_register_check(dns_configuration_notify_key(), &_dns_config_token);
                if (res != NOTIFY_STATUS_OK) _dns_config_token = -1;
        }
+
        if (_dns_config_token != -1) {
                res = notify_check(_dns_config_token, &refresh);
                if (res != NOTIFY_STATUS_OK) refresh = 1;
@@ -557,17 +564,16 @@ _mdns_timeout_for_name(mdns_config_t *config, const char *name)
  * of the default resolver's domains).
  */
 static int
-_mdns_query_unqualified(mdns_config_t *config, const char *name, uint32_t class, uint32_t type, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
+_mdns_query_unqualified(mdns_config_t *config, const char *name, uint32_t class, uint32_t type, const char *interface, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
 {
        int i, res = -1;
 
        for (i = 0; i < config->n_defaults; ++i) {
                dns_resolver_t *resolver = config->defaults[i];
                char *qname;
-               
-               asprintf(&qname, "%s.%s", name,
-                       resolver->domain ? resolver->domain : "");
-               res = _mdns_query_mDNSResponder(qname, class, type, buf, len, reply, resolver->timeout);
+
+               asprintf(&qname, "%s.%s", name, resolver->domain ? resolver->domain : "");
+               res = _mdns_query_mDNSResponder(qname, class, type, interface, buf, len, reply, resolver->timeout);
                free(qname);
 
                if (res == 0) break;
@@ -581,22 +587,22 @@ _mdns_query_unqualified(mdns_config_t *config, const char *name, uint32_t class,
  * additional domains).
  */
 static int
-_mdns_query_absolute(mdns_config_t *config, const char *name, uint32_t class, uint32_t type, uint32_t fqdn, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
+_mdns_query_absolute(mdns_config_t *config, const char *name, uint32_t class, uint32_t type, const char *interface, uint32_t fqdn, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
 {
        int res = -1;
        char *qname = (char *)name;
-       
+
        uint32_t timeout = _mdns_timeout_for_name(config, name);
 
        if (fqdn == 0) asprintf(&qname, "%s.", name);
-       res = _mdns_query_mDNSResponder(qname, class, type, buf, len, reply, timeout);
+       res = _mdns_query_mDNSResponder(qname, class, type, interface, buf, len, reply, timeout);
        if (fqdn == 0) free(qname);
        if (res != 0) _mdns_reply_clear(reply);
        return res;
 }
 
 static int
-_mdns_search(const char *name, uint32_t class, uint32_t type, uint32_t fqdn, uint32_t recurse, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
+_mdns_search(const char *name, uint32_t class, uint32_t type, const char *interface, uint32_t fqdn, uint32_t recurse, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
 {
        int res = -1;
        int i, n, ndots;
@@ -610,7 +616,7 @@ _mdns_search(const char *name, uint32_t class, uint32_t type, uint32_t fqdn, uin
        // NDOTS is the threshold for trying a qualified name "as is"
        ndots = config->ndots;
        if (ndots == 0) ndots = 1;
-       
+
        // count the dots, and remember position of the last one
        n = 0;
        dot = NULL;
@@ -626,19 +632,19 @@ _mdns_search(const char *name, uint32_t class, uint32_t type, uint32_t fqdn, uin
        // if the name has at least ndots, try first as an absolute query.
        // FQDN and PTR queries are always absolute.
        if (n >= ndots || fqdn == 1 || type == ns_t_ptr) {
-               res = _mdns_query_absolute(config, name, class, type, fqdn, buf, len, reply);
+               res = _mdns_query_absolute(config, name, class, type, interface, fqdn, buf, len, reply);
                if (res == 0) {
                        _mdns_config_release(config);
                        return res;
                }
        }
-       
+
        // stop if FQDN, PTR, or no recursion requested
        if (fqdn == 1 || type == ns_t_ptr || recurse == 0) {
                _mdns_config_release(config);
                return -1;
        }
-       
+
        // Qualify the name with each of the search domains looking for a match.
        char **search = config->search_list;
        if (search != NULL) {
@@ -646,7 +652,7 @@ _mdns_search(const char *name, uint32_t class, uint32_t type, uint32_t fqdn, uin
                for (i = 0; i < MAXDNSRCH && search[i] != NULL; ++i) {
                        char *qname;
                        asprintf(&qname, "%s.%s", name, search[i]);
-                       res = _mdns_search(qname, class, type, 0, 0, buf, len, reply);
+                       res = _mdns_search(qname, class, type, interface, 0, 0, buf, len, reply);
                        free(qname);
                        if (res == 0) break;
                }
@@ -654,7 +660,7 @@ _mdns_search(const char *name, uint32_t class, uint32_t type, uint32_t fqdn, uin
                // The name is not fully qualified and there is no search list.
                // Try each default resolver, qualifying the name with that
                // resolver's domain.
-               res = _mdns_query_unqualified(config, name, class, type, buf, len, reply);
+               res = _mdns_query_unqualified(config, name, class, type, interface, buf, len, reply);
        }
        _mdns_config_release(config);
        return res;
@@ -669,11 +675,11 @@ _mdns_reverse_ipv4(const char *addr)
                unsigned char b[4];
        } ab;
        char *p;
-       
+
        if (addr == NULL) return NULL;
-       
+
        memcpy(&(ab.a), addr, 4);
-       
+
        asprintf(&p, "%u.%u.%u.%u.in-addr.arpa.", ab.b[3], ab.b[2], ab.b[1], ab.b[0]);
        return p;
 }
@@ -684,9 +690,9 @@ _mdns_reverse_ipv6(const char *addr)
        char x[65], *p;
        int i, j;
        u_int8_t d, hi, lo;
-       
+
        if (addr == NULL) return NULL;
-       
+
        x[64] = '\0';
        j = 63;
        for (i = 0; i < 16; i++)
@@ -699,7 +705,7 @@ _mdns_reverse_ipv6(const char *addr)
                x[j--] = '.';
                x[j--] = hexchar[lo];
        }
-       
+
        asprintf(&p, "%sip6.arpa.", x);
 
        return p;
@@ -748,7 +754,7 @@ _mdns_hostent_append_alias(mdns_hostent_t *h, const char *alias)
                        return 0;
                }
        }
-       
+
        // add the alias and NULL terminate the list
        h->host.h_aliases = (char **)reallocf(h->host.h_aliases, (h->alias_count+2) * sizeof(char *));
        if (h->host.h_aliases == NULL) {
@@ -801,7 +807,7 @@ _mdns_hostent_clear(mdns_hostent_t *h)
        free(h->host.h_aliases);
        h->host.h_aliases = NULL;
        h->alias_count = 0;
-       
+
        char **addrs = h->host.h_addr_list;
        while (addrs && *addrs) {
                free(*addrs++);
@@ -830,7 +836,7 @@ _mdns_reply_clear(mdns_reply_t *r)
 }
 
 static si_item_t *
-_mdns_hostbyname(si_mod_t *si, const char *name, int af, uint32_t *err)
+_mdns_hostbyname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
 {
        uint32_t type;
        mdns_hostent_t h;
@@ -838,7 +844,7 @@ _mdns_hostbyname(si_mod_t *si, const char *name, int af, uint32_t *err)
        si_item_t *out = NULL;
        uint64_t bb;
        int status;
-       
+
        if (err != NULL) *err = SI_STATUS_NO_ERROR;
 
        if (name == NULL) {
@@ -866,13 +872,13 @@ _mdns_hostbyname(si_mod_t *si, const char *name, int af, uint32_t *err)
        }
        h.host.h_addrtype = af;
 
-       status = _mdns_search(name, ns_c_in, type, 0, 1, NULL, NULL, &reply);
+       status = _mdns_search(name, ns_c_in, type, interface, 0, 1, NULL, NULL, &reply);
        if (status != 0 || h.addr_count == 0) {
                _mdns_reply_clear(&reply);
                if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
                return NULL;
        }
-       
+
        bb = reply.ttl + time(NULL);
 
        switch (af) {
@@ -887,12 +893,12 @@ _mdns_hostbyname(si_mod_t *si, const char *name, int af, uint32_t *err)
        _mdns_reply_clear(&reply);
 
        if (out == NULL && err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
-       
+
        return out;
 }
 
 static si_item_t *
-_mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+_mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
 {
        mdns_hostent_t h;
        mdns_reply_t reply;
@@ -901,9 +907,9 @@ _mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
        uint64_t bb;
        int cat;
        int status;
-       
+
        if (err != NULL) *err = SI_STATUS_NO_ERROR;
-       
+
        if (addr == NULL || si == NULL) {
                if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
                return NULL;
@@ -931,13 +937,13 @@ _mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
        }
        h.host.h_addrtype = af;
 
-       status = _mdns_search(name, ns_c_in, ns_t_ptr, 0, 1, NULL, NULL, &reply);
+       status = _mdns_search(name, ns_c_in, ns_t_ptr, interface, 0, 1, NULL, NULL, &reply);
        free(name);
        if (status != 0) {
                _mdns_reply_clear(&reply);
                if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
                return NULL;
-       }       
+       }
 
        status = _mdns_hostent_append_addr(&h, addr, h.host.h_length);
        if (status != 0) {
@@ -958,14 +964,14 @@ _mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
 // embedded does not do parallel A/AAAA
 #if !TARGET_OS_EMBEDDED
 static si_list_t *
-_mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, uint32_t *err)
+_mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
 {
        int wantv4 = 1;
        int wantv6 = 1;
        if (family == AF_INET6) wantv4 = 0;
        else if (family == AF_INET) wantv6 = 0;
        else if (family != AF_UNSPEC) return NULL;
-       
+
        struct in_addr a4;
        struct in6_addr a6;
        mdns_hostent_t h4;
@@ -981,12 +987,12 @@ _mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family
        memset(&h4, 0, sizeof(h4));
        memset(&h6, 0, sizeof(h6));
        memset(&reply, 0, sizeof(reply));
-       
+
        h4.host.h_addrtype = AF_INET;
        h4.host.h_length = 4;
        h6.host.h_addrtype = AF_INET6;
        h6.host.h_length = 16;
-       
+
        if (wantv4 && wantv6) {
                type = 0;
                reply.h4 = &h4;
@@ -1024,16 +1030,15 @@ _mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family
                        p6 = &a6;
                        memcpy(p6, node, sizeof(a6));
                }
-               out = si_addrinfo_list(si, socktype, proto,
-                               p4, p6, port, 0, cname, cname);
+               out = si_addrinfo_list(si, socktype, proto, p4, p6, port, 0, cname, cname);
        } else {
                int res;
-               res = _mdns_search(node, ns_c_in, type, 0, 1, NULL, NULL, &reply);
+               res = _mdns_search(node, ns_c_in, type, interface, 0, 1, NULL, NULL, &reply);
                if (res == 0 && (h4.addr_count > 0 || h6.addr_count > 0)) {
                        out = si_addrinfo_list_from_hostent(si, socktype, proto,
-                               port, 0,
-                               (wantv4 ? &h4.host : NULL),
-                               (wantv6 ? &h6.host : NULL));    
+                                                                                               port, 0,
+                                                                                               (wantv4 ? &h4.host : NULL),
+                                                                                               (wantv6 ? &h6.host : NULL));
                } else if (err != NULL) {
                        *err = SI_STATUS_EAI_NONAME;
                }
@@ -1044,7 +1049,7 @@ _mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family
 #endif // !TARGET_OS_EMBEDDED
 
 static si_list_t *
-_mdns_srv_byname(si_mod_t* si, const char *qname, uint32_t *err)
+_mdns_srv_byname(si_mod_t* si, const char *qname, const char *interface, uint32_t *err)
 {
        si_list_t *out = NULL;
        mdns_reply_t reply;
@@ -1053,9 +1058,9 @@ _mdns_srv_byname(si_mod_t* si, const char *qname, uint32_t *err)
        const uint64_t unused = 0;
 
        if (err != NULL) *err = SI_STATUS_NO_ERROR;
-       
+
        memset(&reply, 0, sizeof(reply));
-       res = _mdns_search(qname, ns_c_in, ns_t_srv, 0, 1, NULL, NULL, &reply);
+       res = _mdns_search(qname, ns_c_in, ns_t_srv, interface, 0, 1, NULL, NULL, &reply);
        if (res == 0) {
                srv = reply.srv;
                while (srv) {
@@ -1074,7 +1079,7 @@ _mdns_srv_byname(si_mod_t* si, const char *qname, uint32_t *err)
  * We support dns_async_start / cancel / handle_reply using dns_item_call
  */
 static si_item_t *
-_mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, uint32_t class, uint32_t type, uint32_t *err)
+_mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, const char *interface, uint32_t class, uint32_t type, uint32_t *err)
 {
        int res;
        uint8_t buf[DNS_MAX_RECEIVE_SIZE];
@@ -1084,7 +1089,7 @@ _mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, u
        mdns_hostent_t h6;
        si_item_t *out;
        int norecurse = 0;
-       
+
        if (err != NULL) *err = SI_STATUS_NO_ERROR;
 
        switch (call) {
@@ -1107,21 +1112,21 @@ _mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, u
        memset(&h4, 0, sizeof(h4));
        memset(&h6, 0, sizeof(h6));
        memset(&reply, 0, sizeof(reply));
-       
+
        h4.host.h_addrtype = AF_INET;
        h4.host.h_length = 4;
        h6.host.h_addrtype = AF_INET6;
        h6.host.h_length = 16;
        reply.h4 = &h4;
        reply.h6 = &h6;
-       
-       res = _mdns_search(name, class, type, norecurse, 1, buf, &len, &reply);
+
+       res = _mdns_search(name, class, type, interface, norecurse, 1, buf, &len, &reply);
        if (res != 0 || len <= 0 || len > DNS_MAX_RECEIVE_SIZE) {
                _mdns_reply_clear(&reply);
                if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
                return NULL;
        }
-       
+
        struct sockaddr_in6 from;
        uint32_t fromlen = sizeof(from);
        memset(&from, 0, fromlen);
@@ -1150,7 +1155,7 @@ _mdns_is_valid(si_mod_t *si, si_item_t *item)
 static void
 _mdns_close(si_mod_t *si)
 {
-       if (_dns_config_token != -1) notify_cancel(_dns_config_token);  
+       if (_dns_config_token != -1) notify_cancel(_dns_config_token);
        //_mdns_dir_token;
 }
 
@@ -1190,12 +1195,12 @@ si_module_static_mdns(void)
                free(outname);
                return NULL;
        }
-       
+
        out->name = outname;
        out->vers = 1;
        out->refcount = 1;
        out->private = NULL;
-       
+
        out->sim_close = _mdns_close;
        out->sim_is_valid = _mdns_is_valid;
        out->sim_host_byname = _mdns_hostbyname;
@@ -1205,9 +1210,9 @@ si_module_static_mdns(void)
        out->sim_addrinfo = _mdns_addrinfo;
 #endif
        out->sim_srv_byname = _mdns_srv_byname;
-       
+
        int res;
-       
+
        res = notify_register_check(dns_configuration_notify_key(), &_dns_config_token);
        if (res != NOTIFY_STATUS_OK) _dns_config_token = -1;
 
@@ -1230,7 +1235,7 @@ _mdns_parse_domain_name(const uint8_t *data, uint32_t datalen)
        uint32_t len;
        uint32_t domainlen = 0;
        char *domain = NULL;
-       
+
        // i: index into input data
        // j: index into output string
        while (datalen-- > 0) {
@@ -1242,7 +1247,7 @@ _mdns_parse_domain_name(const uint8_t *data, uint32_t datalen)
                if (j > 0) {
                        domain[j++] = datalen ? '.' : '\0'; 
                }
-                       
+
                while ((len-- > 0) && (datalen--)) {
                        if (data[i] == '.') {
                                // special case: escape the '.' with a '\'
@@ -1254,7 +1259,7 @@ _mdns_parse_domain_name(const uint8_t *data, uint32_t datalen)
                }
        }
        domain[j] = '\0';
-       
+
        return domain;
 }
 
@@ -1290,23 +1295,23 @@ static int
 _is_rev_link_local(const char *name)
 {
        int len, i;
-       
+
        if (name == NULL) return 0;
-       
+
        len = strlen(name);
        if (len == 0) return 0;
-       
+
        /* check for trailing '.' */
        if (name[len - 1] == '.') len--;
-       
+
        if (len != IPv6_REVERSE_LEN) return 0;
-       
+
        i = IPv6_REVERSE_LINK_LOCAL_TRAILING_CHAR;
        if ((name[i] != '8') && (name[i] != '9') && (name[i] != 'A') && (name[i] != 'a') && (name[i] != 'B') && (name[i] != 'b')) return 0;
-       
+
        i = IPv6_REVERSE_LINK_LOCAL_TRAILING_CHAR + 1;
        if (strncasecmp(name + i, ".e.f.ip6.arpa", 13)) return 0;
-       
+
        for (i = 0; i < IPv6_REVERSE_LINK_LOCAL_TRAILING_CHAR; i += 2)
        {
                if (name[i] < '0') return 0;
@@ -1315,58 +1320,59 @@ _is_rev_link_local(const char *name)
                if (name[i] > 'f') return 0;
                if (name[i + 1] != '.') return 0;
        }
-       
+
        return 1;
 }
 
 /* _mdns_ipv6_extract_scope_id
  * If the input string is a link local IPv6 address with an encoded scope id,
- * the scope id is extracted to the "iface" parameter and a new string is
- * returned with it removed.
+ * the scope id is extracted and a new string is constructed with the scope id removed.
  */
 static char *
-_mdns_ipv6_extract_scope_id(const char *name, uint32_t *outscope)
+_mdns_ipv6_extract_scope_id(const char *name, uint32_t *out_ifnum)
 {
        char *qname = NULL;
        uint16_t nibble;
+       uint32_t iface;
        int i;
-       
-       if (outscope) *outscope = 0;
-       
-       if (name && _is_rev_link_local(name)) {
-               uint32_t iface;
-               
+
+       if (out_ifnum != NULL) *out_ifnum = 0;
+
+       /* examine the address, extract the scope id if present */
+       if ((name != NULL) && (_is_rev_link_local(name)))
+       {
                /* _is_rev_link_local rejects chars > 127 so it's safe to index into hexval */
                i = IPv6_REVERSE_LINK_LOCAL_SCOPE_ID_LOW;
                nibble = hexval[(uint32_t)name[i]];
                iface = nibble;
-               
+
                i += 2;
                nibble = hexval[(uint32_t)name[i]];
                iface += (nibble << 4);
-               
+
                i += 2;
                nibble = hexval[(uint32_t)name[i]];
                iface += (nibble << 8);
-               
+
                i += 2;
                nibble = hexval[(uint32_t)name[i]];
                iface += (nibble << 12);
-               
+
                if (iface != 0)
                {
                        qname = strdup(name);
                        if (qname == NULL) return NULL;
-                       
+
                        i = IPv6_REVERSE_LINK_LOCAL_SCOPE_ID_LOW;
                        qname[i] = '0';
                        qname[i + 2] = '0';
                        qname[i + 4] = '0';
                        qname[i + 6] = '0';
-                       
-                       if (outscope) *outscope = iface;
+
+                       if (out_ifnum) *out_ifnum = iface;
                }
        }
+
        return qname;
 }
 
@@ -1374,11 +1380,11 @@ static int
 _mdns_make_query(const char* name, int class, int type, uint8_t *buf, uint32_t buflen)
 {
        uint32_t len = 0;
-       
+
        if (buf == NULL || buflen < (NS_HFIXEDSZ + NS_QFIXEDSZ)) return -1;
        memset(buf, 0, NS_HFIXEDSZ);
        HEADER *hp = (HEADER *)buf;
-       
+
        len += NS_HFIXEDSZ;
        hp->id = arc4random();
        hp->qr = 1;
@@ -1386,10 +1392,10 @@ _mdns_make_query(const char* name, int class, int type, uint8_t *buf, uint32_t b
        hp->rd = 1;
        hp->rcode = ns_r_noerror;
        hp->qdcount = htons(1);
-       
+
        int n = _mdns_pack_domain_name(name, &buf[len], buflen - len);
        if (n < 0) return -1;
-       
+
        len += n;
        uint16_t word;
        word = htons(type);
@@ -1422,14 +1428,14 @@ _mdns_query_callback(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorTy
  * initializes the context and starts a DNS-SD query.
  */
 static DNSServiceErrorType
-_mdns_query_start(mdns_query_context_t *ctx, mdns_reply_t *reply, uint8_t *answer, uint32_t *anslen, const char* name, int class, int type, int kq)
+_mdns_query_start(mdns_query_context_t *ctx, mdns_reply_t *reply, uint8_t *answer, uint32_t *anslen, const char* name, int class, int type, const char *interface, int kq)
 {
        DNSServiceErrorType status;
-       
+
        int dns_flags = kDNSServiceFlagsShareConnection | kDNSServiceFlagsReturnIntermediates;
-       
+
        memset(ctx, 0, sizeof(mdns_query_context_t));
-       
+
        if (answer && anslen) {
                // build a dummy DNS header to return to the caller
                ctx->answer = answer;
@@ -1437,7 +1443,7 @@ _mdns_query_start(mdns_query_context_t *ctx, mdns_reply_t *reply, uint8_t *answe
                ctx->anslen = _mdns_make_query(name, class, type, answer, ctx->ansmaxlen);
                if (ctx->anslen <= 0) return -1;
        }
-       
+
        ctx->type = type;
        ctx->sd = _mdns_sdref;
        ctx->kq = kq;
@@ -1449,13 +1455,27 @@ _mdns_query_start(mdns_query_context_t *ctx, mdns_reply_t *reply, uint8_t *answe
                else if (type == ns_t_ptr && reply->h6) ctx->host = reply->h6;
                else if (type != ns_t_srv && type != ns_t_cname) abort();
        }
-       
+
        uint32_t iface = 0;
        char *qname = _mdns_ipv6_extract_scope_id(name, &iface);
        if (qname == NULL) qname = (char *)name;
+
+       if (interface != NULL)
+       {
+               /* get interface number from name */
+               int iface2 = if_nametoindex(interface);
+
+               /* balk if interface name lookup failed */
+               if (iface2 == 0) return -1;
+
+               /* balk if scope id is set AND interface is given AND they don't match */
+               if ((iface != 0) && (iface2 != 0) && (iface != iface2)) return -1;
+               if (iface2 != 0) iface = iface2;
+       }
+
        if (_mdns_debug) printf(";; mdns query %s %d %d\n", qname, type, class);
        status = DNSServiceQueryRecord(&ctx->sd, dns_flags, iface, qname, type, class, _mdns_query_callback, ctx);
-       if (iface != 0) free(qname);
+       if (qname != name) free(qname);
        return status;
 }
 
@@ -1501,14 +1521,14 @@ _mdns_query_clear(mdns_query_context_t *ctx)
 {
        int complete = _mdns_query_is_complete(ctx);
        if (ctx == NULL) return complete;
-       
+
        if (ctx->sd != NULL) {
                DNSServiceRefDeallocate(ctx->sd);
                ctx->sd = NULL;
        }
        ctx->flags = 0;
        ctx->kq = -1;
-       
+
        if (!complete) {
                _mdns_hostent_clear(ctx->host);
                ctx->anslen = -1;
@@ -1527,19 +1547,19 @@ _mdns_query_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifInde
        context->flags = flags;
        context->error = errorCode;
        context->last_type = rrtype;
-       
+
        if (errorCode != kDNSServiceErr_NoError) {
                if (_mdns_debug) printf(";; [%s %hu %hu]: error %d\n", fullname, rrtype, rrclass, errorCode);
                goto wakeup_kevent;
        }
 
-        // embed the scope ID into link-local IPv6 addresses
+       // embed the scope ID into link-local IPv6 addresses
        if (rrtype == ns_t_aaaa && rdlen == sizeof(struct in6_addr) &&
            IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)rdata)) {
                memcpy(&a6, rdata, rdlen);
                a6.__u6_addr.__u6_addr16[1] = htons(ifIndex);
                rdata = &a6;
-        }
+       }
 
        if (context->reply) {
                char *name;
@@ -1552,9 +1572,9 @@ _mdns_query_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifInde
 
                _mdns_hostent_append_alias(context->host, fullname);
                if (reply->ttl == 0 || ttl < reply->ttl) reply->ttl = ttl;
-               
+
                switch (rrtype) {
-                       case ns_t_a:                            
+                       case ns_t_a:
                        case ns_t_aaaa:
                                if (((rrtype == ns_t_a && context->host->host.h_addrtype == AF_INET) ||
                                         (rrtype == ns_t_aaaa && context->host->host.h_addrtype == AF_INET6)) &&
@@ -1666,7 +1686,7 @@ _mdns_query_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifInde
 
                uint16_t word;
                uint32_t longword;
-               
+
                word = htons(rrtype);
                memcpy(cp, &word, sizeof(word));
                cp += sizeof(word);
@@ -1678,7 +1698,7 @@ _mdns_query_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifInde
                longword = htonl(ttl);
                memcpy(cp, &longword, sizeof(longword));
                cp += sizeof(longword);
-               
+
                word = htons(rdlen);
                memcpy(cp, &word, sizeof(word));
                cp += sizeof(word);
@@ -1753,7 +1773,7 @@ _mdns_timeout(struct timespec *timeout, const struct timespec *deadline)
 }
 
 int
-_mdns_query_mDNSResponder(const char *name, int class, int type, uint8_t *answer, uint32_t *anslen, mdns_reply_t *reply, uint32_t timeout_sec)
+_mdns_query_mDNSResponder(const char *name, int class, int type, const char *interface, uint8_t *answer, uint32_t *anslen, mdns_reply_t *reply, uint32_t timeout_sec)
 {
        DNSServiceErrorType err = 0;
        int kq, n, wait = 1;
@@ -1773,7 +1793,7 @@ _mdns_query_mDNSResponder(const char *name, int class, int type, uint8_t *answer
        // log a warning for queries from the main thread 
        if (pthread_main_np()) asl_log(NULL, NULL, ASL_LEVEL_WARNING, "Warning: Libinfo call to mDNSResponder on main thread");
 #endif // #if TARGET_OS_EMBEDDED
-                                                                  
+
        // Timeout Logic
        // The kevent(2) API timeout parameter is used to enforce the total
        // timeout of the DNS query.  Each iteraion recalculates the relative
@@ -1827,17 +1847,17 @@ _mdns_query_mDNSResponder(const char *name, int class, int type, uint8_t *answer
                        }
 
                        // issue (or reissue) the queries
-                       // unspecified type: do parallel A and AAAA
+                       // unspecified type: do parallel A and AAAA
                        if (err == 0) {
                                err = _mdns_query_start(&ctx[n_ctx++], reply,
-                                       answer, anslen,
-                                       name, class,
-                                       (type == 0) ? ns_t_a : type, kq);
+                                                                               answer, anslen,
+                                                                               name, class,
+                                                                               (type == 0) ? ns_t_a : type, interface, kq);
                        }
                        if (err == 0 && type == 0) {
                                err = _mdns_query_start(&ctx[n_ctx++], reply,
-                                       answer, anslen,
-                                       name, class, ns_t_aaaa, kq);
+                                                                               answer, anslen,
+                                                                               name, class, ns_t_aaaa, interface, kq);
                        }
                        if (err && _mdns_debug) printf(";; initialization error %d\n", err);
                        // try to reinitialize
@@ -1859,7 +1879,7 @@ _mdns_query_mDNSResponder(const char *name, int class, int type, uint8_t *answer
 
                        // (re)register the fd with kqueue
                        int fd = DNSServiceRefSockFD(_mdns_sdref);
-                       EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
+                       EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
                        n = kevent(kq, &ev, 1, NULL, 0, NULL);
                        pthread_mutex_unlock(&_mdns_mutex);
                        if (err != 0 || n != 0) break;
@@ -1957,4 +1977,3 @@ _mdns_query_mDNSResponder(const char *name, int class, int type, uint8_t *answer
        if (anslen) *anslen = ctx[0].anslen;
        return res;
 }
-
index 552c8aae2625de59ec88bbfdb96b1d1e90626375..13e3bd82334a703b0a528da990a570571b5ecbba 100644 (file)
@@ -1,21 +1,22 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * 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.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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 OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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@
  */
index 46453ec34f6bcff8b0b8c378afb31ced408f9c6c..6fd7bbfe4d773322855d6161f70af863aba19db4 100644 (file)
@@ -1,24 +1,23 @@
 /*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2009 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- *
- * Portions Copyright (c) 2002 Apple Computer, Inc. All Rights
- * Reserved. 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 1.1 (the "License"). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- *
+ * 
+ * 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
+ * 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 OR NON- INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * 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@
  */
 
index adc18c32ec18f16bc84c4a9d47b5a43fdafe57c8..8ea0f1dee7fba75963632cf5ef8ec3102a139f37 100644 (file)
@@ -369,7 +369,7 @@ search_alias_all(si_mod_t *si)
 }
 
 __private_extern__ si_item_t *
-search_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+search_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
 {
        int i, cat;
        search_si_private_t *pp;
@@ -398,7 +398,7 @@ search_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
 
        while (NULL != (src = search_get_module(pp, cat, &i)))
        {
-               item = si_host_byname(src, name, af, err);
+               item = si_host_byname(src, name, af, interface, err);
                if (item != NULL)
                {
                        si_cache_add_item(search_cat_cache(pp, cat), src, item);
@@ -411,7 +411,7 @@ search_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
 }
 
 __private_extern__ si_item_t *
-search_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+search_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
 {
        int i, cat;
        search_si_private_t *pp;
@@ -440,7 +440,7 @@ search_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
 
        while (NULL != (src = search_get_module(pp, cat, &i)))
        {
-               item = si_host_byaddr(src, addr, af, err);
+               item = si_host_byaddr(src, addr, af, interface, err);
                if (item != NULL)
                {
                        si_cache_add_item(search_cat_cache(pp, cat), src, item);
@@ -637,7 +637,7 @@ search_mac_all(si_mod_t *si)
 }
 
 __private_extern__ si_list_t *
-search_srv_byname(si_mod_t *si, const char* qname, uint32_t *err)
+search_srv_byname(si_mod_t *si, const char* qname, const char *interface, uint32_t *err)
 {
        int i, cat;
        si_list_t *list = NULL;
@@ -658,7 +658,7 @@ search_srv_byname(si_mod_t *si, const char* qname, uint32_t *err)
 
                if (src->sim_srv_byname != NULL)
                {
-                       list = src->sim_srv_byname(src, qname, err);
+                       list = src->sim_srv_byname(src, qname, interface, err);
                        if (list != NULL) return list;
                }
        }
@@ -692,7 +692,7 @@ search_wants_addrinfo(si_mod_t *si)
 }
 
 __private_extern__ si_list_t *
-search_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, uint32_t *err)
+search_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, const char *interface, uint32_t *err)
 {
        int i, cat;
        search_si_private_t *pp;
@@ -715,7 +715,7 @@ search_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t famil
 
                if (src->sim_addrinfo != NULL)
                {
-                       list = src->sim_addrinfo(src, node, serv, family, socktype, protocol, flags, err);
+                       list = src->sim_addrinfo(src, node, serv, family, socktype, protocol, flags, interface, err);
                        if (list != NULL) return list;
                }
        }
@@ -725,7 +725,7 @@ search_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t famil
 }
 
 __private_extern__ si_item_t *
-search_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, uint32_t *err)
+search_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err)
 {
        int i, cat;
        search_si_private_t *pp;
@@ -744,7 +744,7 @@ search_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, uint32_t *er
 
        while (NULL != (src = search_get_module(pp, cat, &i)))
        {
-               item = si_nameinfo(src, sa, flags, err);
+               item = si_nameinfo(src, sa, flags, interface, err);
                if (item != NULL)
                {
                        si_cache_add_item(search_cat_cache(pp, cat), src, item);
index 6c64a05faab3b7d306a96e78c84d251bd64f0e9c..9bd03f4e5df1b723c664157108d7dfda4be352a7 100644 (file)
@@ -108,7 +108,7 @@ gai_strerror(int32_t err)
  * we inet_ntop() and printf() and return the results.
  */
 __private_extern__ si_item_t *
-si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, uint32_t *err)
+si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err)
 {
        si_item_t *out = NULL;
        const struct sockaddr *lookup_sa;
@@ -195,10 +195,10 @@ si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, uint32_t *err)
 #if 0
                if ((do_serv_lookup == 1) && (si->sim_nameinfo != NULL))
                {
-                       return si->sim_nameinfo(si, lookup_sa, flags, err);
+                       return si->sim_nameinfo(si, lookup_sa, flags, interface, err);
                }
 #endif
-               si_item_t *item = si_host_byaddr(si, addr, lookup_sa->sa_family, NULL);
+               si_item_t *item = si_host_byaddr(si, addr, lookup_sa->sa_family, interface, NULL);
                if (item != NULL)
                {
                        struct hostent *h;
@@ -577,7 +577,7 @@ si_addrinfo_list_from_hostent(si_mod_t *si, uint32_t socktype, uint32_t proto, u
  * Simple lookup via gethostbyname2(3) mechanism.
  */
 static si_list_t *
-_gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, uint32_t *err)
+_gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
 {
        si_item_t *h4_item = NULL, *h6_item = NULL;
        struct hostent *h4 = NULL, *h6 = NULL;
@@ -601,25 +601,24 @@ _gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t fam
        {
                if (family == AF_INET)
                {
-                       h4_item = si_host_byaddr(si, nodeptr, AF_INET, NULL);
+                       h4_item = si_host_byaddr(si, nodeptr, AF_INET, interface, NULL);
                }
                else if (family == AF_INET6)
                {
-                       h6_item = si_host_byaddr(si, nodeptr, AF_INET6, NULL);
+                       h6_item = si_host_byaddr(si, nodeptr, AF_INET6, interface, NULL);
                }
        }
        else
        {
                if ((family == AF_INET) || (family == AF_UNSPEC))
                {
-                       h4_item = si_host_byname(si, nodeptr, AF_INET, NULL);
+                       h4_item = si_host_byname(si, nodeptr, AF_INET, interface, NULL);
                }
-#if !TARGET_OS_EMBEDDED
+
                if ((family == AF_INET6) || (family == AF_UNSPEC))
                {
-                       h6_item = si_host_byname(si, nodeptr, AF_INET6, NULL);
+                       h6_item = si_host_byname(si, nodeptr, AF_INET6, interface, NULL);
                }
-#endif /* !TARGET_OS_EMBEDDED */
        }
 
        if (h4_item != NULL)
@@ -640,12 +639,12 @@ _gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t fam
 }
 
 __private_extern__ si_list_t *
-si_srv_byname(si_mod_t *si, const char *qname, uint32_t *err)
+si_srv_byname(si_mod_t *si, const char *qname, const char *interface, uint32_t *err)
 {
        if (si == NULL) return 0;
        if (si->sim_srv_byname == NULL) return 0;
 
-       return si->sim_srv_byname(si, qname, err);
+       return si->sim_srv_byname(si, qname, interface, err);
 }
 
 __private_extern__ int
@@ -659,7 +658,7 @@ si_wants_addrinfo(si_mod_t *si)
 }
 
 static si_list_t *
-_gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, uint32_t *err)
+_gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
 {
        int i;
        char *qname;
@@ -676,7 +675,7 @@ _gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint
        if (node == NULL || serv == NULL) return NULL;
        
        asprintf(&qname, "%s.%s", serv, node);
-       list = si_srv_byname(si, qname, err);
+       list = si_srv_byname(si, qname, interface, err);
        free(qname);
        
        /* Iterate the SRV records starting at lowest priority and attempt to
@@ -722,7 +721,7 @@ _gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint
                                /* So that _gai_simple expects an integer service. */
                                flags |= AI_NUMERICSERV;
 
-                               result = _gai_simple(si, srv->target, &srv->port, family, socktype, proto, flags, err);
+                               result = _gai_simple(si, srv->target, &srv->port, family, socktype, proto, flags, interface, err);
                                if (result)
                                {
                                        break;
@@ -740,7 +739,7 @@ _gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint
 }
 
 __private_extern__ si_list_t *
-si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, uint32_t *err)
+si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
 {
        int numerichost, numericserv = 0;
        const void *nodeptr = NULL, *servptr = NULL;
@@ -772,9 +771,6 @@ si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, u
        switch (family)
        {
                case AF_UNSPEC:
-#if TARGET_OS_EMBEDDED
-                       family = AF_INET;
-#endif
                case AF_INET:
                case AF_INET6:
                        break;
@@ -829,7 +825,7 @@ si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, u
        if ((flags & AI_SRV) != 0)
        {
                /* AI_SRV SPI */
-               return _gai_srv(si, node, serv, family, socktype, proto, flags, err);
+               return _gai_srv(si, node, serv, family, socktype, proto, flags, interface, err);
        }
        else
        {
@@ -913,11 +909,11 @@ si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, u
        else if ((si->sim_wants_addrinfo != NULL) && si->sim_wants_addrinfo(si))
        {
                /* or let the current module handle the host lookups intelligently */
-               return si->sim_addrinfo(si, nodeptr, servptr, family, socktype, proto, flags, err);
+               return si->sim_addrinfo(si, nodeptr, servptr, family, socktype, proto, flags, interface, err);
        }
 
        /* fall back to a default path */
-       return _gai_simple(si, nodeptr, servptr, family, socktype, proto, flags, err);
+       return _gai_simple(si, nodeptr, servptr, family, socktype, proto, flags, interface, err);
 }
 
 static struct addrinfo *
@@ -1137,7 +1133,7 @@ free_build_hostent(build_hostent_t *h)
 }
 
 __private_extern__ si_item_t *
-si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, uint32_t *err)
+si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const char *interface, uint32_t *err)
 {
        int i, status, want, if4, if6;
        struct ifaddrs *ifa, *ifap;
@@ -1300,13 +1296,13 @@ si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, uint32_t
        /* fetch IPv6 data if required */
        if ((want == WANT_A6_ONLY) || (want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) || (want == WANT_A6_PLUS_MAPPED_A4))
        {
-               item6 = si_host_byname(si, name, AF_INET6, (uint32_t *)err);
+               item6 = si_host_byname(si, name, AF_INET6, interface, (uint32_t *)err);
        }
 
        /* fetch IPv4 data if required */
        if ((want == WANT_A4_ONLY) || (want == WANT_A6_PLUS_MAPPED_A4) || ((want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) && (item6 == NULL)))
        {
-               item4 = si_host_byname(si, name, AF_INET, (uint32_t *)err);
+               item4 = si_host_byname(si, name, AF_INET, interface, (uint32_t *)err);
        }
 
        if (want == WANT_A4_ONLY)
index 42ce205ffb640507e947947ec70563b41bf2fb6b..ada6b2560bc135c3617a5ec648faf98db24bb0bc 100644 (file)
@@ -47,6 +47,7 @@ typedef struct si_async_workunit_s
        uint32_t call;
        char *str1;
        char *str2;
+       char *str3;
        uint32_t num1;
        uint32_t num2;
        uint32_t num3;
@@ -592,19 +593,19 @@ si_alias_all(si_mod_t *si)
 }
 
 __private_extern__ si_item_t *
-si_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+si_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
 {
        if (si == NULL) return NULL;
        if (si->sim_host_byname == NULL) return NULL;
-       return si->sim_host_byname(si, name, af, err);
+       return si->sim_host_byname(si, name, af, interface, err);
 }
 
 __private_extern__ si_item_t *
-si_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+si_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
 {
        if (si == NULL) return NULL;
        if (si->sim_host_byaddr == NULL) return NULL;
-       return si->sim_host_byaddr(si, addr, af, err);
+       return si->sim_host_byaddr(si, addr, af, interface, err);
 }
 
 __private_extern__ si_list_t *
@@ -760,7 +761,7 @@ si_fs_all(si_mod_t *si)
 }
 
 __private_extern__ si_item_t *
-si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t *err)
+si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t *err)
 {
        if (si == NULL) return NULL;
 
@@ -772,8 +773,8 @@ si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2,
                case SI_CALL_GROUP_BYGID: return si_group_bygid(si, (gid_t)num1);
                case SI_CALL_GROUPLIST: return si_grouplist(si, str1);
                case SI_CALL_ALIAS_BYNAME: return si_alias_byname(si, str1);
-               case SI_CALL_HOST_BYNAME: return si_host_byname(si, str1, num1, err);
-               case SI_CALL_HOST_BYADDR: return si_host_byaddr(si, (void *)str1, num1, err);
+               case SI_CALL_HOST_BYNAME: return si_host_byname(si, str1, num1, str3, err);
+               case SI_CALL_HOST_BYADDR: return si_host_byaddr(si, (void *)str1, num1, str3, err);
                case SI_CALL_NETWORK_BYNAME: return si_network_byname(si, str1);
                case SI_CALL_NETWORK_BYADDR: return si_network_byaddr(si, num1);
                case SI_CALL_SERVICE_BYNAME: return si_service_byname(si, str1, str2);
@@ -784,8 +785,8 @@ si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2,
                case SI_CALL_RPC_BYNUMBER: return si_rpc_bynumber(si, num1);
                case SI_CALL_FS_BYSPEC: return si_fs_byspec(si, str1);
                case SI_CALL_FS_BYFILE: return si_fs_byfile(si, str1);
-               case SI_CALL_NAMEINFO: return si_nameinfo(si, (const struct sockaddr *)str1, num1, err);
-               case SI_CALL_IPNODE_BYNAME: return si_ipnode_byname(si, (const char *)str1, num1, num2, err);
+               case SI_CALL_NAMEINFO: return si_nameinfo(si, (const struct sockaddr *)str1, num1, str3, err);
+               case SI_CALL_IPNODE_BYNAME: return si_ipnode_byname(si, (const char *)str1, num1, num2, str3, err);
                case SI_CALL_MAC_BYNAME: return si_mac_byname(si, (const char *)str1);
                case SI_CALL_MAC_BYMAC: return si_mac_bymac(si, (const char *)str1);
 
@@ -794,7 +795,7 @@ si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2,
                case SI_CALL_DNS_SEARCH:
                {
                        if (si->sim_item_call == NULL) return NULL;
-                       return si->sim_item_call(si, call, str1, str2, num1, num2, err);
+                       return si->sim_item_call(si, call, str1, str2, str3, num1, num2, err);
                }
 
                default: return NULL;
@@ -804,7 +805,7 @@ si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2,
 }
 
 __private_extern__ si_list_t *
-si_list_call(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err)
+si_list_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err)
 {
        if (si == NULL) return NULL;
 
@@ -820,7 +821,7 @@ si_list_call(struct si_mod_s *si, int call, const char *str1, const char *str2,
                case SI_CALL_RPC_ALL: return si_rpc_all(si);
                case SI_CALL_FS_ALL: return si_fs_all(si);
                case SI_CALL_MAC_ALL: return si_mac_all(si);
-               case SI_CALL_ADDRINFO: return si_addrinfo(si, str1, str2, num1, num2, num3, num4, err);
+               case SI_CALL_ADDRINFO: return si_addrinfo(si, str1, str2, num1, num2, num3, num4, str3, err);
                default: return NULL;
        }
 
@@ -867,16 +868,17 @@ si_async_worklist_find_unit(mach_port_t p)
 }
 
 static si_async_workunit_t *
-si_async_workunit_create(si_mod_t *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context)
+si_async_workunit_create(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context)
 {
        si_async_workunit_t *r;
        kern_return_t status;
        mach_port_t reply, send;
        mach_msg_type_name_t type;
-       char *s1, *s2;
+       char *s1, *s2, *s3;
 
        s1 = NULL;
        s2 = NULL;
+       s3 = NULL;
 
        if (si_call_str1_is_buffer(call))
        {
@@ -903,11 +905,23 @@ si_async_workunit_create(si_mod_t *si, int call, const char *str1, const char *s
                }
        }
 
+       if (str3 != NULL)
+       {
+               s3 = strdup(str3);
+               if (s3 == NULL)
+               {
+                       if (s1 != NULL) free(s1);
+                       if (s2 != NULL) free(s2);
+                       return NULL;
+               }
+       }
+
        r = (si_async_workunit_t *)calloc(1, sizeof(si_async_workunit_t));
        if (r == NULL)
        {
                if (s1 != NULL) free(s1);
                if (s2 != NULL) free(s2);
+               if (s3 != NULL) free(s3);
                return NULL;
        }
 
@@ -922,6 +936,7 @@ si_async_workunit_create(si_mod_t *si, int call, const char *str1, const char *s
                if (reply != MACH_PORT_NULL) mach_port_mod_refs(mach_task_self(), reply, MACH_PORT_RIGHT_RECEIVE, -1);
                if (s1 != NULL) free(s1);
                if (s2 != NULL) free(s2);
+               if (s3 != NULL) free(s3);
                free(r);
                return NULL;
        }
@@ -930,6 +945,7 @@ si_async_workunit_create(si_mod_t *si, int call, const char *str1, const char *s
        r->call = call;
        r->str1 = s1;
        r->str2 = s2;
+       r->str3 = s3;
        r->num1 = num1;
        r->num2 = num2;
        r->num3 = num3;
@@ -962,6 +978,7 @@ si_async_workunit_release(si_async_workunit_t *r)
 
        if (r->str1 != NULL) free(r->str1);
        if (r->str2 != NULL) free(r->str2);
+       if (r->str3 != NULL) free(r->str3);
 
        free(r);
 }
@@ -976,8 +993,8 @@ si_async_launchpad(void *x)
        if (x == NULL) pthread_exit(NULL);
        r = (si_async_workunit_t *)x;
 
-       if (r->flags & WORKUNIT_RETURNS_LIST) r->reslist = si_list_call(r->si, r->call, r->str1, r->str2, r->num1, r->num2, r->num3, r->num4, &(r->err));
-       else r->resitem = si_item_call(r->si, r->call, r->str1, r->str2, r->num1, r->num2, &(r->err));
+       if (r->flags & WORKUNIT_RETURNS_LIST) r->reslist = si_list_call(r->si, r->call, r->str1, r->str2, r->str3, r->num1, r->num2, r->num3, r->num4, &(r->err));
+       else r->resitem = si_item_call(r->si, r->call, r->str1, r->str2, r->str3, r->num1, r->num2, &(r->err));
 
        memset(&msg, 0, sizeof(mach_msg_empty_send_t));
 
@@ -1005,7 +1022,7 @@ si_async_launchpad(void *x)
 }
 
 mach_port_t
-si_async_call(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context)
+si_async_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context)
 {
        si_async_workunit_t *req;
        pthread_attr_t attr;
@@ -1017,10 +1034,10 @@ si_async_call(struct si_mod_s *si, int call, const char *str1, const char *str2,
        /* if module does async on it's own, hand off the call */
        if (si->sim_async_call != NULL)
        {
-               return si->sim_async_call(si, call, str1, str2, num1, num2, num3, num4, callback, context);
+               return si->sim_async_call(si, call, str1, str2, str3, num1, num2, num3, num4, callback, context);
        }
 
-       req = si_async_workunit_create(si, call, str1, str2, num1, num2, num3, num4, callback, context);
+       req = si_async_workunit_create(si, call, str1, str2, str3, num1, num2, num3, num4, callback, context);
        if (req == NULL) return MACH_PORT_NULL;
 
        /* start a new thread to do the work */
index a8e1c34df7b0c7fd97bf100edd6d962138b2cc01..16ea8f3dd68ca90161d5af4e44aecbdbeb3fbcda 100644 (file)
@@ -191,7 +191,8 @@ typedef struct dnspacket_s
        struct sockaddr *dns_server;
 } si_dnspacket_t;
 
-typedef struct si_srv_s {
+typedef struct si_srv_s
+{
        uint16_t priority;
        uint16_t weight;
        uint16_t port;
@@ -227,8 +228,8 @@ typedef struct si_mod_s
        si_item_t *(*sim_alias_byname)(struct si_mod_s *si, const char *name);
        si_list_t *(*sim_alias_all)(struct si_mod_s *si);
 
-       si_item_t *(*sim_host_byname)(struct si_mod_s *si, const char *name, int af, uint32_t *err);
-       si_item_t *(*sim_host_byaddr)(struct si_mod_s *si, const void *addr, int af, uint32_t *err);
+       si_item_t *(*sim_host_byname)(struct si_mod_s *si, const char *name, int af, const char *interface, uint32_t *err);
+       si_item_t *(*sim_host_byaddr)(struct si_mod_s *si, const void *addr, int af, const char *interface, uint32_t *err);
        si_list_t *(*sim_host_all)(struct si_mod_s *si);
 
        si_item_t *(*sim_network_byname)(struct si_mod_s *si, const char *name);
@@ -255,17 +256,17 @@ typedef struct si_mod_s
        si_item_t *(*sim_mac_bymac)(struct si_mod_s *si, const char *mac);
        si_list_t *(*sim_mac_all)(struct si_mod_s *si);
 
-       si_list_t *(*sim_addrinfo)(struct si_mod_s *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, uint32_t *err);
+       si_list_t *(*sim_addrinfo)(struct si_mod_s *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, const char *interface, uint32_t *err);
        int (*sim_wants_addrinfo)(struct si_mod_s *si);
 
-       si_item_t *(*sim_nameinfo)(struct si_mod_s *si, const struct sockaddr *sa, int flags, uint32_t *err);
+       si_item_t *(*sim_nameinfo)(struct si_mod_s *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err);
 
-       si_list_t *(*sim_srv_byname)(struct si_mod_s *si, const char *qname, uint32_t *err);
+       si_list_t *(*sim_srv_byname)(struct si_mod_s *si, const char *qname, const char *interface, uint32_t *err);
 
-       si_item_t *(*sim_item_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t *err);
-       si_list_t *(*sim_list_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err);
+       si_item_t *(*sim_item_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t *err);
+       si_list_t *(*sim_list_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err);
 
-       mach_port_t (*sim_async_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
+       mach_port_t (*sim_async_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
        void (*sim_async_cancel)(mach_port_t p);
        void (*sim_async_handle_reply)(mach_msg_header_t *msg);
 } si_mod_t;
@@ -298,8 +299,8 @@ __private_extern__ si_list_t *si_netgroup_byname(struct si_mod_s *si, const char
 __private_extern__ si_item_t *si_alias_byname(struct si_mod_s *si, const char *name);
 __private_extern__ si_list_t *si_alias_all(struct si_mod_s *si);
 
-__private_extern__ si_item_t *si_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err);
-__private_extern__ si_item_t *si_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err);
+__private_extern__ si_item_t *si_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err);
+__private_extern__ si_item_t *si_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err);
 __private_extern__ si_list_t *si_host_all(si_mod_t *si);
 
 __private_extern__ si_item_t *si_mac_byname(struct si_mod_s *si, const char *name);
@@ -327,17 +328,17 @@ __private_extern__ si_item_t *si_fs_byfile(si_mod_t *si, const char *file);
 __private_extern__ si_list_t *si_fs_all(si_mod_t *si);
 
 __private_extern__ int si_wants_addrinfo(si_mod_t *s);
-__private_extern__ si_list_t *si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, uint32_t *err);
+__private_extern__ si_list_t *si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, const char *interface, uint32_t *err);
 
-__private_extern__ si_item_t *si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, uint32_t *err);
-__private_extern__ si_item_t *si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, uint32_t *err);
+__private_extern__ si_item_t *si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err);
+__private_extern__ si_item_t *si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const char *interface, uint32_t *err);
 
-__private_extern__ si_list_t *si_srv_byname(si_mod_t *si, const char *qname, uint32_t *err);
+__private_extern__ si_list_t *si_srv_byname(si_mod_t *si, const char *qname, const char *interface, uint32_t *err);
 
-__private_extern__ si_item_t *si_item_call(si_mod_t *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t *err);
-__private_extern__ si_list_t *si_list_call(si_mod_t *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err);
+__private_extern__ si_item_t *si_item_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t *err);
+__private_extern__ si_list_t *si_list_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err);
 
-extern mach_port_t si_async_call(si_mod_t *si, int call, const char *str1, const char *str2, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
+extern mach_port_t si_async_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
 extern void si_async_cancel(mach_port_t p);
 extern void si_async_handle_reply(mach_msg_header_t *msg);