blob: ef878f8109ac2652d805c1aa8855ecc2983d9d85 [file] [log] [blame]
// Copyright 2025 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "DnsProxy.h"
#include <cstdint>
#include <memory>
#include "DnsResolver.h"
#include "dns_proxy_cxx_bridge.rs.h"
#include "include/netd_resolv/resolv.h"
namespace android {
namespace net {
namespace dns_proxy_ffi {
// getDnsMark must be thread-safe since it is used in DnsMarkCallback.
uint32_t getDnsMark(ResolverNetdCallbacks& resNetdCallbacks, uint32_t netId, uint32_t uid) {
android_net_context netContext;
// Safety: get_network_context is thread-safe since the implementation is
// behind a mutex lock.
resNetdCallbacks.get_network_context(netId, uid, &netContext);
return netContext.dns_mark;
}
// Safety: thread-safe since it is a lambda wrapper of a thread-safe function.
DnsMarkCallback makeDnsMarkCallback(ResolverNetdCallbacks resNetdCallbacks) {
return [resNetdCallbacks = std::move(resNetdCallbacks)](uint32_t netId, uint32_t uid) mutable {
return getDnsMark(resNetdCallbacks, netId, uid);
};
}
// getNameServers must be thread-safe since it is used in NameServersCallback.
std::unique_ptr<std::vector<std::string>> getNameServers(DnsResolver& dnsResolv, uint32_t netId) {
std::vector<std::string> res_servers;
std::vector<std::string> res_domains;
std::vector<std::string> res_tls_servers;
std::vector<std::string> res_interface_names;
std::vector<int32_t> params32;
std::vector<int32_t> stats32;
int32_t wait_for_pending_req_timeout_count32 = 0;
// Safety: getResolverInfo is thread-safe since in its implementation, mutex
// lock is applied when shared information is accessed.
dnsResolv.resolverCtrl.getResolverInfo(netId, &res_servers, &res_domains, &res_tls_servers,
&res_interface_names, &params32, &stats32,
&wait_for_pending_req_timeout_count32);
return std::make_unique<std::vector<std::string>>(std::move(res_servers));
}
// Safety: thread-safe since it is a lambda wrapper of a thread-safe function.
NameServersCallback makeNameServersCallback(DnsResolver& dnsResolv) {
return [&dnsResolv](uint32_t netId) { return getNameServers(dnsResolv, netId); };
}
DnsProxy::DnsProxy(DnsMarkCallback&& dnsMarkCallback, NameServersCallback&& nameServersCallback)
: mServer(proxy_server_new(std::make_unique<DnsMarkCallback>(dnsMarkCallback),
std::make_unique<NameServersCallback>(nameServersCallback))) {}
// Default constructor depending on DnsResolver global variables.
DnsProxy::DnsProxy()
: DnsProxy(makeDnsMarkCallback(android::net::gResNetdCallbacks),
makeNameServersCallback(*android::net::gDnsResolv)) {}
void DnsProxy::configureDnsProxy(uint32_t upstreamNetId, uint32_t uid, uint32_t downstreamIfIndex,
uint16_t downstreamPort) {
mServer->configure_dns_proxy_ffi(upstreamNetId, uid, downstreamIfIndex, downstreamPort);
}
void DnsProxy::stopDnsProxy(uint32_t downstreamIfIndex, uint16_t downstreamPort) {
mServer->stop_dns_proxy_ffi(downstreamIfIndex, downstreamPort);
}
} // namespace dns_proxy_ffi
} // namespace net
} // namespace android