summaryrefslogtreecommitdiffstats
path: root/netwerk/dns/ODoH.cpp
blob: dd752f74e2904ba76549cb5776d27284b42ae31a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "ODoH.h"

#include "mozilla/Base64.h"
#include "nsIURIMutator.h"
#include "ODoHService.h"
#include "TRRService.h"
// Put DNSLogging.h at the end to avoid LOG being overwritten by other headers.
#include "DNSLogging.h"
#include "nsNetUtil.h"

namespace mozilla {
namespace net {

NS_IMETHODIMP
ODoH::Run() {
  if (!gODoHService) {
    RecordReason(TRRSkippedReason::TRR_SEND_FAILED);
    FailData(NS_ERROR_FAILURE);
    return NS_OK;
  }

  if (!gODoHService->ODoHConfigs()) {
    LOG((
        "ODoH::Run ODoHConfigs is not available mTriedDownloadODoHConfigs=%d\n",
        mTriedDownloadODoHConfigs));
    // Make this lookup fail if we don't have a valid ODoHConfig and we already
    // tried before.
    if (NS_SUCCEEDED(gODoHService->UpdateODoHConfig()) &&
        !mTriedDownloadODoHConfigs) {
      gODoHService->AppendPendingODoHRequest(this);
      mTriedDownloadODoHConfigs = true;
    } else {
      RecordReason(TRRSkippedReason::ODOH_UPDATE_KEY_FAILED);
      FailData(NS_ERROR_FAILURE);
      return NS_OK;
    }
    return NS_OK;
  }

  return TRR::Run();
}

DNSPacket* ODoH::GetOrCreateDNSPacket() {
  if (!mPacket) {
    mPacket = MakeUnique<ODoHDNSPacket>();
  }

  return mPacket.get();
}

nsresult ODoH::CreateQueryURI(nsIURI** aOutURI) {
  nsAutoCString uri;
  nsCOMPtr<nsIURI> dnsURI;
  gODoHService->GetRequestURI(uri);

  nsresult rv = NS_NewURI(getter_AddRefs(dnsURI), uri);
  if (NS_FAILED(rv)) {
    return rv;
  }

  dnsURI.forget(aOutURI);
  return NS_OK;
}

void ODoH::HandleTimeout() {
  // If this request is still in the pending queue, it means we can't get the
  // ODoHConfigs within the timeout.
  if (gODoHService->RemovePendingODoHRequest(this)) {
    RecordReason(TRRSkippedReason::ODOH_KEY_NOT_AVAILABLE);
  }

  TRR::HandleTimeout();
}

void ODoH::HandleEncodeError(nsresult aStatusCode) {
  MOZ_ASSERT(NS_FAILED(aStatusCode));

  DNSPacketStatus status = mPacket->PacketStatus();
  MOZ_ASSERT(status != DNSPacketStatus::Success);

  if (status == DNSPacketStatus::KeyNotAvailable) {
    RecordReason(TRRSkippedReason::ODOH_KEY_NOT_AVAILABLE);
  } else if (status == DNSPacketStatus::KeyNotUsable) {
    RecordReason(TRRSkippedReason::ODOH_KEY_NOT_USABLE);
  } else if (status == DNSPacketStatus::EncryptError) {
    RecordReason(TRRSkippedReason::ODOH_ENCRYPTION_FAILED);
  } else {
    MOZ_ASSERT_UNREACHABLE("Unexpected status code.");
  }
}

void ODoH::HandleDecodeError(nsresult aStatusCode) {
  MOZ_ASSERT(NS_FAILED(aStatusCode));

  DNSPacketStatus status = mPacket->PacketStatus();
  MOZ_ASSERT(status != DNSPacketStatus::Success);

  if (status == DNSPacketStatus::DecryptError) {
    RecordReason(TRRSkippedReason::ODOH_DECRYPTION_FAILED);
  }

  TRR::HandleDecodeError(aStatusCode);
}

}  // namespace net
}  // namespace mozilla