From 6545716c073c88ad86458620c6dbc59ba1cd00bb Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Tue, 10 Oct 2017 17:53:14 -0400 Subject: VPP-1027: DNS name resolver This patch is a plausible first-cut, suitable for initial testing by vcl (host stack client library). Main features; - recursive name resolution - multiple ip4/ip6 name servers - cache size limit enforcement - currently limited to 65K - ttl / aging - static mapping support - show / clear / debug CLI commands Binary APIs provided for the following: - add/delete name servers - enable/disable the name cache - resolve a name To Do list: - Respond to ip4/ip6 client DNS requests (vs. binary API requests) - Perf / scale tuning - map pending transaction ids to pool indices, so the cache can (greatly) exceed 65K entries - Security improvements - Use unpredictable dns transaction IDs, related to previous item - Make sure that response-packet src ip addresses match the server - Add binary APIs - deliver raw response data to clients - control recursive name resolution - Documentation Change-Id: I48c373d5c05d7108ccd814d4055caf8c75ca10b7 Signed-off-by: Dave Barach --- src/vnet/dns/dns.h | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/vnet/dns/dns.h (limited to 'src/vnet/dns/dns.h') diff --git a/src/vnet/dns/dns.h b/src/vnet/dns/dns.h new file mode 100644 index 00000000000..5da26156f6c --- /dev/null +++ b/src/vnet/dns/dns.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#ifndef included_dns_h +#define included_dns_h + +#include +#include +#include + +#include +#include +#include + +typedef struct +{ + /** flags */ + volatile u8 flags; + + /** The name in "normal human being" notation, e.g. www.foobar.com */ + u8 *name; + + /** Expiration time */ + f64 expiration_time; + + /** Cached dns request, for sending retries */ + u8 *dns_request; + + /** Retry parameters */ + int retry_count; + int server_rotor; + int server_af; + f64 retry_timer; + + /** Cached dns response */ + u8 *dns_response; + + /** Clients awaiting responses */ + u32 *api_clients_to_notify; + u32 *api_client_contexts; + ip4_address_t *ip4_peers_to_notify; + ip6_address_t *ip6_peers_to_notify; +} dns_cache_entry_t; + +#define DNS_CACHE_ENTRY_FLAG_VALID (1<<0) /**< we have Actual Data */ +#define DNS_CACHE_ENTRY_FLAG_STATIC (1<<1) /**< static entry */ + +#define DNS_RETRIES_PER_SERVER 3 + +#define DNS_RESOLVER_EVENT_RESOLVED 1 +#define DNS_RESOLVER_EVENT_PENDING 2 + + +typedef struct +{ + /** Pool of cache entries */ + dns_cache_entry_t *entries; + + /** Pool indices of unresolved entries */ + u32 *unresolved_entries; + + /** Find cached record by name */ + uword *cache_entry_by_name; + uword *cache_lock; + + /** enable / disable flag */ + int is_enabled; + + /** upstream name servers, e.g. 8.8.8.8 */ + ip4_address_t *ip4_name_servers; + ip6_address_t *ip6_name_servers; + + /** config parameters */ + u32 name_cache_size; + u32 max_ttl_in_seconds; + u32 random_seed; + + /* convenience */ + vlib_main_t *vlib_main; + vnet_main_t *vnet_main; +} dns_main_t; + +extern dns_main_t dns_main; + +extern vlib_node_registration_t dns46_reply_node; +extern vlib_node_registration_t dns_resolver_node; + +#define foreach_dns46_reply_error \ +_(PROCESSED, "DNS reply pkts processed") \ +_(NO_ELT, "No DNS pool element") \ +_(FORMAT_ERROR, "DNS format errors") \ +_(TEST_DROP, "DNS reply pkt dropped for test purposes") + +typedef enum +{ +#define _(sym,str) DNS46_REPLY_ERROR_##sym, + foreach_dns46_reply_error +#undef _ + DNS46_REPLY_N_ERROR, +} dns46_reply_error_t; + +void vnet_send_dns_request (dns_main_t * dm, dns_cache_entry_t * ep); +int vnet_dns_cname_indirection_nolock (dns_main_t * dm, + dns_cache_entry_t * ep, u8 * reply); +int vnet_dns_delete_entry_by_index_nolock (dns_main_t * dm, u32 index); + +format_function_t format_dns_reply; + +static inline void +dns_cache_lock (dns_main_t * dm) +{ + if (dm->cache_lock) + { + while (__sync_lock_test_and_set (dm->cache_lock, 1)) + ; + } +} + +static inline void +dns_cache_unlock (dns_main_t * dm) +{ + if (dm->cache_lock) + { + CLIB_MEMORY_BARRIER (); + *dm->cache_lock = 0; + } +} + +#endif /* included_dns_h */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ -- cgit 1.2.3-korg