]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/uDNSPathEvalulation.c
mDNSResponder-765.1.2.tar.gz
[apple/mdnsresponder.git] / mDNSMacOSX / uDNSPathEvalulation.c
1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2013, 2015 Apple Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include "mDNSMacOSX.h"
19 #include <libproc.h>
20 #include <network/private.h>
21
22 //Gets the DNSPolicy from NW PATH EVALUATOR
23 mDNSexport void mDNSPlatformGetDNSRoutePolicy(mDNS *const m, DNSQuestion *q, mDNSBool *isBlocked)
24 {
25 (void) m;
26 q->ServiceID = -1; // initialize the ServiceID to default value of -1
27
28 // Return for non-unicast DNS queries, invalid pid, if NWPathEvaluation is already done by the client, or NWPathEvaluation not available on this OS
29 if (mDNSOpaque16IsZero(q->TargetQID) || (q->pid < 0) || (q->flags & kDNSServiceFlagsPathEvaluationDone) || !nw_endpoint_create_host)
30 {
31 *isBlocked = mDNSfalse;
32 return;
33 }
34
35 mDNSs32 service_id;
36 mDNSu32 client_ifindex, dnspol_ifindex;
37 int retval;
38 struct proc_uniqidentifierinfo info;
39 mDNSBool isUUIDSet;
40
41 char unenc_name[MAX_ESCAPED_DOMAIN_NAME];
42 ConvertDomainNameToCString(&q->qname, unenc_name);
43
44 nw_endpoint_t host = nw_endpoint_create_host(unenc_name, "0");
45 if (host == NULL)
46 LogMsg("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] nw_endpoint_t host is NULL", q->qname.c,
47 DNSTypeName(q->qtype), q->pid, q->euid, q->ServiceID);
48
49 nw_parameters_t parameters = nw_parameters_create();
50 if (parameters == NULL)
51 LogMsg("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] nw_endpoint_t parameters is NULL", q->qname.c,
52 DNSTypeName(q->qtype), q->pid, q->euid, q->ServiceID);
53
54 // Check for all the special (negative) internal value interface indices before initializing client_ifindex
55 if ( (q->InterfaceID == mDNSInterface_Any)
56 || (q->InterfaceID == mDNSInterface_Unicast)
57 || (q->InterfaceID == mDNSInterface_LocalOnly)
58 || (q->InterfaceID == mDNSInterfaceMark)
59 || (q->InterfaceID == mDNSInterface_P2P)
60 || (q->InterfaceID == uDNSInterfaceMark))
61 {
62 client_ifindex = 0;
63 }
64 else
65 {
66 client_ifindex = (mDNSu32)(uintptr_t)q->InterfaceID;
67 }
68
69
70 if (client_ifindex > 0)
71 {
72 nw_interface_t client_intf = nw_interface_create_with_index(client_ifindex);
73 nw_parameters_require_interface(parameters, client_intf);
74 if (client_intf != NULL)
75 network_release(client_intf);
76 else
77 LogInfo("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: client_intf returned by nw_interface_create_with_index() is NULL");
78 }
79
80 nw_parameters_set_uid(parameters,(uid_t)q->euid);
81
82 if (q->pid != 0)
83 {
84 nw_parameters_set_pid(parameters, q->pid);
85 retval = proc_pidinfo(q->pid, PROC_PIDUNIQIDENTIFIERINFO, 1, &info, sizeof(info));
86 if (retval == (int)sizeof(info))
87 {
88 nw_parameters_set_e_proc_uuid(parameters, info.p_uuid);
89 isUUIDSet = mDNStrue;
90 }
91 else
92 {
93 debugf("mDNSPlatformGetDNSRoutePolicy: proc_pidinfo returned %d", retval);
94 isUUIDSet = mDNSfalse;
95 }
96 }
97 else
98 {
99 nw_parameters_set_e_proc_uuid(parameters, q->uuid);
100 isUUIDSet = mDNStrue;
101 }
102
103 nw_path_evaluator_t evaluator = nw_path_create_evaluator_for_endpoint(host, parameters);
104 if (evaluator == NULL)
105 LogMsg("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] nw_path_evaluator_t evaluator is NULL", q->qname.c,
106 DNSTypeName(q->qtype), q->pid, q->euid, q->ServiceID);
107
108 if (host != NULL)
109 network_release(host);
110 if (parameters != NULL)
111 network_release(parameters);
112
113 nw_path_t path = nw_path_evaluator_copy_path(evaluator);
114 if (path == NULL)
115 LogMsg("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] nw_path_t path is NULL", q->qname.c,
116 DNSTypeName(q->qtype), q->pid, q->euid, q->ServiceID);
117
118 service_id = nw_path_get_flow_divert_unit(path);
119 if (service_id != 0)
120 {
121 q->ServiceID = service_id;
122 LogInfo("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy: Query for %##s service ID is set ->service_ID:[%d] ", q->qname.c, service_id);
123 }
124 else
125 {
126 nw_interface_t nwpath_intf = nw_path_copy_scoped_interface(path);
127 if (nwpath_intf != NULL)
128 {
129 // Use the new scoped interface given by NW PATH EVALUATOR
130 dnspol_ifindex = nw_interface_get_index(nwpath_intf);
131 q->InterfaceID = (mDNSInterfaceID)(uintptr_t)dnspol_ifindex;
132
133 network_release(nwpath_intf);
134
135 if (dnspol_ifindex != client_ifindex)
136 LogInfo("mDNSPlatformGetDNSRoutePolicy: DNS Route Policy has changed the scoped ifindex from [%d] to [%d]",
137 client_ifindex, dnspol_ifindex);
138 }
139 else
140 {
141 debugf("mDNSPlatformGetDNSRoutePolicy: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] nw_interface_t nwpath_intf is NULL ", q->qname.c, DNSTypeName(q->qtype), q->pid, q->euid, q->ServiceID);
142 }
143 }
144
145 if (isUUIDSet && (nw_path_get_status(path) == nw_path_status_unsatisfied) && (nw_path_get_reason(path) == nw_path_reason_policy_drop))
146 *isBlocked = mDNStrue;
147 else
148 *isBlocked = mDNSfalse;
149
150 if (path != NULL)
151 network_release(path);
152 if (evaluator != NULL)
153 network_release(evaluator);
154
155 }