summaryrefslogtreecommitdiff
path: root/netwerk/dns/DNS.h
blob: 22e1f31f121f297c4556a317d84d04207bb5e813 (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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/. */

#ifndef DNS_h_
#define DNS_h_

#include "nscore.h"
#include "prio.h"
#include "prnetdb.h"
#include "plstr.h"
#include "mozilla/LinkedList.h"
#include "mozilla/MemoryReporting.h"

#if !defined(XP_WIN)
#include <arpa/inet.h>
#endif

#ifdef XP_WIN
#include "winsock2.h"
#endif

#ifndef AF_LOCAL
#define AF_LOCAL 1  // used for named pipe
#endif

#define IPv6ADDR_IS_LOOPBACK(a) \
  (((a)->u32[0] == 0)     &&    \
   ((a)->u32[1] == 0)     &&    \
   ((a)->u32[2] == 0)     &&    \
   ((a)->u8[12] == 0)     &&    \
   ((a)->u8[13] == 0)     &&    \
   ((a)->u8[14] == 0)     &&    \
   ((a)->u8[15] == 0x1U))

#define IPv6ADDR_IS_V4MAPPED(a) \
  (((a)->u32[0] == 0)     &&    \
   ((a)->u32[1] == 0)     &&    \
   ((a)->u8[8] == 0)      &&    \
   ((a)->u8[9] == 0)      &&    \
   ((a)->u8[10] == 0xff)  &&    \
   ((a)->u8[11] == 0xff))

#define IPv6ADDR_V4MAPPED_TO_IPADDR(a) ((a)->u32[3])

#define IPv6ADDR_IS_UNSPECIFIED(a) \
  (((a)->u32[0] == 0)  &&          \
   ((a)->u32[1] == 0)  &&          \
   ((a)->u32[2] == 0)  &&          \
   ((a)->u32[3] == 0))

namespace mozilla {
namespace net {

// Required buffer size for text form of an IP address.
// Includes space for null termination. We make our own contants
// because we don't want higher-level code depending on things
// like INET6_ADDRSTRLEN and having to include the associated
// platform-specific headers.
#ifdef XP_WIN
// Windows requires longer buffers for some reason.
const int kIPv4CStrBufSize = 22;
const int kIPv6CStrBufSize = 65;
const int kNetAddrMaxCStrBufSize = kIPv6CStrBufSize;
#else
const int kIPv4CStrBufSize = 16;
const int kIPv6CStrBufSize = 46;
const int kLocalCStrBufSize = 108;
const int kNetAddrMaxCStrBufSize = kLocalCStrBufSize;
#endif

// This was all created at a time in which we were using NSPR for host
// resolution and we were propagating NSPR types like "PRAddrInfo" and
// "PRNetAddr" all over Gecko. This made it hard to use another host
// resolver -- we were locked into NSPR. The goal here is to get away
// from that. We'll translate what we get from NSPR or any other host
// resolution library into the types below and use them in Gecko.

union IPv6Addr {
  uint8_t  u8[16];
  uint16_t u16[8];
  uint32_t u32[4];
  uint64_t u64[2];
};

// This struct is similar to operating system structs like "sockaddr", used for
// things like "connect" and "getsockname". When tempted to cast or do dumb
// copies of this struct to another struct, bear compiler-computed padding
// in mind. The size of this struct, and the layout of the data in it, may
// not be what you expect.
union NetAddr {
  struct {
    uint16_t family;                /* address family (0x00ff maskable) */
    char data[14];                  /* raw address data */
  } raw;
  struct {
    uint16_t family;                /* address family (AF_INET) */
    uint16_t port;                  /* port number */
    uint32_t ip;                    /* The actual 32 bits of address */
  } inet;
  struct {
    uint16_t family;                /* address family (AF_INET6) */
    uint16_t port;                  /* port number */
    uint32_t flowinfo;              /* routing information */
    IPv6Addr ip;                    /* the actual 128 bits of address */
    uint32_t scope_id;              /* set of interfaces for a scope */
  } inet6;
#if defined(XP_UNIX) || defined(XP_WIN)
  struct {                          /* Unix domain socket or
                                       Windows Named Pipes address */
    uint16_t family;                /* address family (AF_UNIX) */
    char path[104];                 /* null-terminated pathname */
  } local;
#endif
  // introduced to support nsTArray<NetAddr> comparisons and sorting
  bool operator == (const NetAddr& other) const;
  bool operator < (const NetAddr &other) const;
};

// This class wraps a NetAddr union to provide C++ linked list
// capabilities and other methods. It is created from a PRNetAddr,
// which is converted to a mozilla::dns::NetAddr.
class NetAddrElement : public LinkedListElement<NetAddrElement> {
public:
  explicit NetAddrElement(const PRNetAddr *prNetAddr);
  NetAddrElement(const NetAddrElement& netAddr);
  ~NetAddrElement();

  NetAddr mAddress;
};

class AddrInfo {
public:
  // Creates an AddrInfo object. It calls the AddrInfo(const char*, const char*)
  // to initialize the host and the cname.
  AddrInfo(const char *host, const PRAddrInfo *prAddrInfo, bool disableIPv4,
           bool filterNameCollision, const char *cname);

  // Creates a basic AddrInfo object (initialize only the host and the cname).
  AddrInfo(const char *host, const char *cname);
  ~AddrInfo();

  void AddAddress(NetAddrElement *address);

  size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;

  char *mHostName;
  char *mCanonicalName;
  uint16_t ttl;
  static const uint16_t NO_TTL_DATA = (uint16_t) -1;

  LinkedList<NetAddrElement> mAddresses;

private:
  void Init(const char *host, const char *cname);
};

// Copies the contents of a PRNetAddr to a NetAddr.
// Does not do a ptr safety check!
void PRNetAddrToNetAddr(const PRNetAddr *prAddr, NetAddr *addr);

// Copies the contents of a NetAddr to a PRNetAddr.
// Does not do a ptr safety check!
void NetAddrToPRNetAddr(const NetAddr *addr, PRNetAddr *prAddr);

bool NetAddrToString(const NetAddr *addr, char *buf, uint32_t bufSize);

bool IsLoopBackAddress(const NetAddr *addr);

bool IsIPAddrAny(const NetAddr *addr);

bool IsIPAddrV4Mapped(const NetAddr *addr);

bool IsIPAddrLocal(const NetAddr *addr);

nsresult GetPort(const NetAddr *aAddr, uint16_t *aResult);

} // namespace net
} // namespace mozilla

#endif // DNS_h_