2 * Copyright (c) 2019 Apple Inc. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * https://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "mdns_symptoms.h"
19 #include <CoreUtils/CoreUtils.h>
20 #include <SymptomReporter/SymptomReporter.h>
22 #define MAX_DOMAIN_NAME 256
24 #define SYMPTOM_REPORTER_mDNSResponder_NUMERIC_ID 101
25 #define SYMPTOM_REPORTER_mDNSResponder_TEXT_ID "com.apple.mDNSResponder"
27 #define SYMPTOM_DNS_NO_REPLIES 0x00065001
28 #define SYMPTOM_DNS_RESUMED_RESPONDING 0x00065002
29 #define SYMPTOM_DNS_ENCRYPTED_CONNECTION_FAILURE 0x00065004
31 //======================================================================================================================
32 // MARK: - Soft Linking
34 SOFT_LINK_FRAMEWORK_EX(PrivateFrameworks
, SymptomReporter
);
35 SOFT_LINK_FUNCTION_EX(SymptomReporter
, symptom_framework_init
,
37 (symptom_ident_t id
, const char *originator_string
),
38 (id
, originator_string
));
39 SOFT_LINK_FUNCTION_EX(SymptomReporter
, symptom_new
,
41 (symptom_framework_t framework
, symptom_ident_t id
),
43 SOFT_LINK_FUNCTION_EX(SymptomReporter
, symptom_set_additional_qualifier
,
45 (symptom_t symptom
, uint32_t qualifier_type
, size_t qualifier_len
, const void *qualifier_data
),
46 (symptom
, qualifier_type
, qualifier_len
, qualifier_data
));
47 SOFT_LINK_FUNCTION_EX(SymptomReporter
, symptom_send
,
52 //======================================================================================================================
53 // MARK: - Local Helper Prototypes
55 static symptom_framework_t
56 _mdns_symptoms_get_reporter(void);
59 _mdns_symptoms_report_dns_server_symptom(symptom_ident_t id
, const struct sockaddr
*address
);
62 _mdns_symptoms_report_dns_host_symptom(symptom_ident_t id
, const char *host
);
64 //======================================================================================================================
65 // MARK - External Functions
68 mdns_symptoms_report_unresponsive_server(const struct sockaddr
*address
)
70 _mdns_symptoms_report_dns_server_symptom(SYMPTOM_DNS_NO_REPLIES
, address
);
73 //======================================================================================================================
76 mdns_symptoms_report_encrypted_dns_connection_failure(const char *host
)
78 _mdns_symptoms_report_dns_host_symptom(SYMPTOM_DNS_ENCRYPTED_CONNECTION_FAILURE
, host
);
81 //======================================================================================================================
84 mdns_symptoms_report_responsive_server(const struct sockaddr
*address
)
86 _mdns_symptoms_report_dns_server_symptom(SYMPTOM_DNS_RESUMED_RESPONDING
, address
);
89 //======================================================================================================================
90 // MARK - Local Helpers
92 static symptom_framework_t
93 _mdns_symptoms_get_reporter(void)
95 static dispatch_once_t s_once
= 0;
96 static symptom_framework_t s_reporter
= NULL
;
98 dispatch_once(&s_once
,
100 if (SOFT_LINK_HAS_FUNCTION(SymptomReporter
, symptom_framework_init
)) {
101 s_reporter
= soft_symptom_framework_init(SYMPTOM_REPORTER_mDNSResponder_NUMERIC_ID
,
102 SYMPTOM_REPORTER_mDNSResponder_TEXT_ID
);
108 //======================================================================================================================
111 _mdns_symptoms_report_dns_server_symptom(symptom_ident_t id
, const struct sockaddr
*address
)
113 const symptom_framework_t reporter
= _mdns_symptoms_get_reporter();
114 require_quiet(reporter
, exit
);
117 if (address
->sa_family
== AF_INET
) {
118 address_len
= sizeof(struct sockaddr_in
);
119 } else if (address
->sa_family
== AF_INET6
) {
120 address_len
= sizeof(struct sockaddr_in6
);
124 const symptom_t symptom
= soft_symptom_new(reporter
, id
);
125 soft_symptom_set_additional_qualifier(symptom
, 1, address_len
, address
);
126 soft_symptom_send(symptom
);
132 //======================================================================================================================
135 _mdns_symptoms_report_dns_host_symptom(symptom_ident_t id
, const char *host
)
137 const symptom_framework_t reporter
= _mdns_symptoms_get_reporter();
138 require_quiet(reporter
, exit
);
140 size_t hostname_len
= strnlen(host
, MAX_DOMAIN_NAME
);
141 const symptom_t symptom
= soft_symptom_new(reporter
, id
);
142 soft_symptom_set_additional_qualifier(symptom
, 2, hostname_len
, host
);
143 soft_symptom_send(symptom
);