@@ -92,6 +92,8 @@ defmodule DNSCluster do
92
92
`"myapp.internal"` or `["foo.internal", "bar.internal"]`. If the basename
93
93
differs between nodes, a tuple of `{basename, query}` can be provided as well.
94
94
The value `:ignore` can be used to ignore starting the DNSCluster.
95
+ * `:dns_rr_types` - the resource records types that are used for node discovery.
96
+ Defaults to `[:a, :aaaa, :srv]` which are all currently supported types.
95
97
* `:interval` - the millisec interval between DNS queries. Defaults to `5000`.
96
98
* `:connect_timeout` - the millisec timeout to allow discovered nodes to connect.
97
99
Defaults to `10_000`.
@@ -108,21 +110,29 @@ defmodule DNSCluster do
108
110
GenServer . start_link ( __MODULE__ , opts , name: Keyword . get ( opts , :name , __MODULE__ ) )
109
111
end
110
112
113
+ @ valid_rr_types [ :a , :aaaa , :srv ]
114
+
111
115
@ impl true
112
116
def init ( opts ) do
117
+ dns_rr_types = Keyword . get ( opts , :dns_rr_types , @ valid_rr_types )
118
+
113
119
case Keyword . fetch ( opts , :query ) do
114
120
{ :ok , :ignore } ->
115
121
:ignore
116
122
117
123
{ :ok , query } ->
118
- if valid_query? ( query ) do
124
+ with (
125
+ { :valid_query? , true } <- { :valid_query? , valid_query? ( query ) } ,
126
+ { :valid_rr_types? , true } <- { :valid_rr_types? , valid_rr_types? ( dns_rr_types ) }
127
+ ) do
119
128
warn_on_invalid_dist ( )
120
129
resolver = Keyword . get ( opts , :resolver , Resolver )
121
130
122
131
state = % {
123
132
interval: Keyword . get ( opts , :interval , 5_000 ) ,
124
133
basename: resolver . basename ( node ( ) ) ,
125
134
query: List . wrap ( query ) ,
135
+ dns_rr_types: dns_rr_types ,
126
136
log: Keyword . get ( opts , :log , false ) ,
127
137
poll_timer: nil ,
128
138
connect_timeout: Keyword . get ( opts , :connect_timeout , 10_000 ) ,
@@ -131,8 +141,13 @@ defmodule DNSCluster do
131
141
132
142
{ :ok , state , { :continue , :discover_ips } }
133
143
else
134
- raise ArgumentError ,
135
- "expected :query to be a string, {basename, query}, or list, got: #{ inspect ( query ) } "
144
+ { :valid_query? , false } ->
145
+ raise ArgumentError ,
146
+ "expected :query to be a string, {basename, query}, or list, got: #{ inspect ( query ) } "
147
+
148
+ { :valid_rr_types? , false } ->
149
+ raise ArgumentError ,
150
+ "expected :dns_rr_types to be a subset of [:a, :aaaa, :srv], got: #{ inspect ( dns_rr_types ) } "
136
151
end
137
152
138
153
:error ->
@@ -186,8 +201,8 @@ defmodule DNSCluster do
186
201
% { state | poll_timer: Process . send_after ( self ( ) , :discover_ips , state . interval ) }
187
202
end
188
203
189
- defp discover_ips ( % { resolver: resolver , query: queries } = state ) do
190
- [ :a , :aaaa , :srv ]
204
+ defp discover_ips ( % { resolver: resolver , query: queries , dns_rr_types: dns_rr_types } = state ) do
205
+ dns_rr_types
191
206
|> Enum . flat_map ( fn type ->
192
207
Enum . flat_map ( queries , fn query ->
193
208
{ basename , query } =
@@ -220,6 +235,13 @@ defmodule DNSCluster do
220
235
end )
221
236
end
222
237
238
+ defp valid_rr_types? ( [ ] ) , do: false
239
+
240
+ defp valid_rr_types? ( dns_rr_types ) do
241
+ MapSet . new ( dns_rr_types )
242
+ |> MapSet . subset? ( MapSet . new ( @ valid_rr_types ) )
243
+ end
244
+
223
245
defp warn_on_invalid_dist do
224
246
release? = is_binary ( System . get_env ( "RELEASE_NAME" ) )
225
247
net_state = if function_exported? ( :net_kernel , :get_state , 0 ) , do: :net_kernel . get_state ( )
0 commit comments