1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
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
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#ifndef _DNS_DNSTLSTRANSPORT_H
18#define _DNS_DNSTLSTRANSPORT_H
19
20#include <future>
21#include <map>
22#include <mutex>
23#include <vector>
24
25#include <android-base/thread_annotations.h>
26#include <android-base/unique_fd.h>
27
28#include "dns/DnsTlsSessionCache.h"
29#include "dns/DnsTlsQueryMap.h"
30#include "dns/DnsTlsServer.h"
31#include "dns/IDnsTlsSocket.h"
32#include "dns/IDnsTlsSocketObserver.h"
33
34#include <netdutils/Slice.h>
35
36namespace android {
37namespace net {
38
39class IDnsTlsSocketFactory;
40
41// Manages at most one DnsTlsSocket at a time.  This class handles socket lifetime issues,
42// such as reopening the socket and reissuing pending queries.
43class DnsTlsTransport : public IDnsTlsSocketObserver {
44public:
45    DnsTlsTransport(const DnsTlsServer& server, unsigned mark,
46                    IDnsTlsSocketFactory* _Nonnull factory) :
47            mMark(mark), mServer(server), mFactory(factory) {}
48    ~DnsTlsTransport();
49
50    typedef DnsTlsServer::Response Response;
51    typedef DnsTlsServer::Result Result;
52
53    // Given a |query|, this method sends it to the server and returns the result asynchronously.
54    std::future<Result> query(const netdutils::Slice query) EXCLUDES(mLock);
55
56    // Check that a given TLS server is fully working on the specified netid, and has the
57    // provided SHA-256 fingerprint (if nonempty).  This function is used in ResolverController
58    // to ensure that we don't enable DNS over TLS on networks where it doesn't actually work.
59    static bool validate(const DnsTlsServer& server, unsigned netid);
60
61    // Implement IDnsTlsSocketObserver
62    void onResponse(std::vector<uint8_t> response) override;
63    void onClosed() override EXCLUDES(mLock);
64
65private:
66    std::mutex mLock;
67
68    DnsTlsSessionCache mCache;
69    DnsTlsQueryMap mQueries;
70
71    const unsigned mMark;  // Socket mark
72    const DnsTlsServer mServer;
73    IDnsTlsSocketFactory* _Nonnull const mFactory;
74
75    void doConnect() REQUIRES(mLock);
76
77    // doReconnect is used by onClosed.  It runs on the reconnect thread.
78    void doReconnect() EXCLUDES(mLock);
79    std::unique_ptr<std::thread> mReconnectThread GUARDED_BY(mLock);
80
81    // Used to prevent onClosed from starting a reconnect during the destructor.
82    bool mClosing GUARDED_BY(mLock) = false;
83
84    // Sending queries on the socket is thread-safe, but construction/destruction is not.
85    std::unique_ptr<IDnsTlsSocket> mSocket GUARDED_BY(mLock);
86
87    // Send a query to the socket.
88    bool sendQuery(const DnsTlsQueryMap::Query q) REQUIRES(mLock);
89};
90
91}  // end of namespace net
92}  // end of namespace android
93
94#endif  // _DNS_DNSTLSTRANSPORT_H
95