source: rtems-libbsd/mDNSResponder/mDNSMacOSX/Private/dns_services.c @ 9449f15

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 9449f15 was 9449f15, checked in by Sebastian Huber <sebastian.huber@…>, on 01/30/14 at 12:52:13

mDNS: Import

The sources can be obtained via:

http://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-544.tar.gz

  • Property mode set to 100644
File size: 7.4 KB
Line 
1/* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2012 Apple Inc. All rights reserved.
4 *
5 * PRIVATE DNSX CLIENT LIBRARY --FOR Apple Platforms ONLY OSX/iOS--
6 * Resides in /usr/lib/libdns_services.dylib
7 */
8
9#include "dns_services.h"
10#include "dns_xpc.h"
11#include <xpc/xpc.h>
12#include <Block.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <syslog.h>
16
17//*************************************************************************************************************
18// Globals
19
20#define connection_t xpc_connection_t
21
22struct _DNSXConnRef_t
23{
24    connection_t      conn_ref;      // xpc_connection between client and daemon
25    dispatch_queue_t  lib_q;         // internal queue created in library itself   
26    void              *AppCallBack;  // Callback function ptr for Client
27    dispatch_queue_t  client_q;      // Queue specified by client for scheduling its Callback
28};
29
30//*************************************************************************************************************
31// Utility Functions
32
33static bool LogDebugEnabled()
34{
35    return false;
36}
37
38static void LogDebug(const char *prefix, xpc_object_t o)
39{
40    if (!LogDebugEnabled())
41        return;
42   
43    char *desc = xpc_copy_description(o);
44    syslog(LOG_INFO, "%s: %s", prefix, desc);
45    free(desc);
46}
47
48//**************************************************************************************************************
49
50void DNSXRefDeAlloc(DNSXConnRef connRef)
51{
52    if (!connRef)
53    {
54        syslog(LOG_WARNING, "dns_services: DNSXRefDeAlloc called with NULL DNSXConnRef");
55        return;
56    }
57
58    // Schedule this work on the internal library queue
59    dispatch_sync(connRef->lib_q, ^{
60
61        xpc_release(connRef->conn_ref);
62        connRef->AppCallBack = NULL;
63        dispatch_release(connRef->client_q);
64
65    });
66
67    dispatch_release(connRef->lib_q);
68    free(connRef);
69
70    syslog(LOG_INFO, "dns_services: DNSXRefDeAlloc successfully DeAllocated connRef");
71
72}
73
74// Sends the Msg(Dictionary) to the Server
75static DNSXErrorType SendMsgToServer(DNSXConnRef *connRef, xpc_object_t msg, bool old_conn)
76{
77    DNSXErrorType errx = kDNSX_NoError;
78
79    LogDebug("dns_services: SendMsgToServer", msg);
80   
81    xpc_connection_set_event_handler((*connRef)->conn_ref, ^(xpc_object_t recv_msg)
82    {
83        xpc_type_t type = xpc_get_type(recv_msg);
84
85        if (type == XPC_TYPE_DICTIONARY)
86        {
87            LogDebug("dns_services: SendMsgToServer SUCCESS CALLBACK FROM SERVER", recv_msg);
88            syslog(LOG_INFO, "dns_services: Successfully Sent Msg to the Daemon");
89            uint64_t daemon_status = xpc_dictionary_get_uint64(recv_msg, kDNSDaemonReply);
90 
91            // Schedule the AppCallBacks on the Client Specified Queue
92            switch (daemon_status)
93            {   
94                case kDNSDaemonEngaged:
95                        dispatch_async((*connRef)->client_q, ^{ 
96                                        ((DNSXEnableProxyReply)(*connRef)->AppCallBack)((*connRef), kDNSX_Engaged);
97                                        });
98                                        break;
99                case kDNSMsgReceived:
100                        dispatch_async((*connRef)->client_q, ^{
101                                        ((DNSXEnableProxyReply)(*connRef)->AppCallBack)((*connRef), kDNSX_NoError);
102                                        });
103                                        break;
104                default:
105                        dispatch_async((*connRef)->client_q, ^{
106                                        ((DNSXEnableProxyReply)(*connRef)->AppCallBack)((*connRef), kDNSX_UnknownErr);
107                                        });
108                                        break;
109            }   
110
111        }
112        else
113        {
114            LogDebug("dns_services: SendMsgToServer UNEXPECTED CALLBACK FROM SERVER", recv_msg);
115            syslog(LOG_WARNING, "dns_services: Connection failed since NO privileges to access service OR Daemon NOT Running");
116            dispatch_async((*connRef)->client_q, ^{
117                            ((DNSXEnableProxyReply)(*connRef)->AppCallBack)((*connRef), kDNSX_DaemonNotRunning);
118                            });
119        }
120    });
121   
122    // To prevent Over-Resume of a connection
123    if (!old_conn)
124        xpc_connection_resume((*connRef)->conn_ref);
125    xpc_connection_send_message((*connRef)->conn_ref, msg);
126    if (!errx)
127        syslog(LOG_INFO, "dns_services: SendMSgToServer sent Msg Dict successfully to Daemon");
128    return errx;
129}
130
131// Creates a new DNSX Connection Reference(DNSXConnRef).
132// If DNSXConnRef exists, you may want to use that depending on the use case
133static DNSXErrorType InitConnection(DNSXConnRef *connRef, const char *servname, dispatch_queue_t clientq, void *AppCallBack)
134{
135    if (!connRef)
136    {
137        syslog(LOG_WARNING, "dns_services: InitConnection() called with NULL DNSXConnRef");
138        return kDNSX_BadParam;   
139    }
140
141    *connRef = malloc(sizeof(struct _DNSXConnRef_t));
142    if (!(*connRef))
143    {
144        syslog(LOG_WARNING, "dns_services: InitConnection() No memory to allocate");
145        return kDNSX_NoMem;
146    }
147
148    // Initialize the DNSXConnRef 
149    dispatch_retain(clientq);
150    (*connRef)->client_q     = clientq;
151    (*connRef)->AppCallBack  = AppCallBack;   
152    (*connRef)->lib_q        = dispatch_queue_create("com.apple.mDNSResponder.libdns_services.q", NULL);
153    (*connRef)->conn_ref     = xpc_connection_create_mach_service(servname, (*connRef)->lib_q, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
154
155    syslog(LOG_INFO, "dns_services: InitConnection() successfully create a new DNSXConnRef");
156    return kDNSX_NoError;
157}
158
159DNSXErrorType DNSXEnableProxy(DNSXConnRef *connRef, DNSProxyParameters proxyparam, IfIndex inIfindexArr[MaxInputIf],
160                               IfIndex outIfindex, dispatch_queue_t clientq, DNSXEnableProxyReply callBack)
161{
162
163    DNSXErrorType errx = kDNSX_NoError;
164    bool old_conn = false;   
165
166    // Sanity Checks
167    if (!connRef || !callBack || !clientq)
168    {
169        syslog(LOG_WARNING, "dns_services: DNSXEnableProxy called with NULL DNSXConnRef OR Callback OR ClientQ parameter");
170        return kDNSX_BadParam;
171    }   
172
173    // If no connRef, get it from InitConnection()
174    if (!*connRef)
175    {
176        errx = InitConnection(connRef, kDNSProxyService, clientq, callBack);
177        if (errx) // On error InitConnection() leaves *connRef set to NULL
178        {
179            syslog(LOG_WARNING, "dns_services: Since InitConnection() returned %d error returning w/o sending msg", errx);
180            return errx;
181        }
182    }
183    else // Client already has a valid connRef
184    {
185        old_conn = true;
186    }
187
188    // Create Dictionary To Send
189    xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
190    if (!dict)
191    {
192        syslog(LOG_WARNING, "dns_services: DNSXEnableProxy could not create the Msg Dict To Send!");
193        DNSXRefDeAlloc(*connRef);
194        return kDNSX_DictError;
195    }
196
197    xpc_dictionary_set_uint64(dict, kDNSProxyParameters, proxyparam);
198
199    xpc_dictionary_set_uint64(dict, kDNSInIfindex0,      inIfindexArr[0]);
200    xpc_dictionary_set_uint64(dict, kDNSInIfindex1,      inIfindexArr[1]);
201    xpc_dictionary_set_uint64(dict, kDNSInIfindex2,      inIfindexArr[2]);
202    xpc_dictionary_set_uint64(dict, kDNSInIfindex3,      inIfindexArr[3]);
203    xpc_dictionary_set_uint64(dict, kDNSInIfindex4,      inIfindexArr[4]);
204
205    xpc_dictionary_set_uint64(dict, kDNSOutIfindex,      outIfindex);
206 
207    errx = SendMsgToServer(connRef, dict, old_conn);
208    xpc_release(dict);
209
210    return errx;
211}
212
Note: See TracBrowser for help on using the repository browser.