diff --git a/src/config.c b/src/config.c
index 34f134e0c3550a0c2b8ad6014a622b6d4330509b..dc05072f537aad9157cced1e0da5b3db8819af8d 100644
--- a/src/config.c
+++ b/src/config.c
@@ -299,18 +299,40 @@ static void create_mac_list(size_t i, struct uci_section *s)
 static void update_profile_pointer(size_t i, struct uci_section *s)
 {
 	struct uci_element *element = NULL;
+	struct uci_element *e = NULL;
+	struct uci_section *sec = NULL;
+	int profile_found = 0;
 
 	uci_foreach_element(&s->options, element) {
-	struct uci_option *option = (uci_to_option(element));
+		struct uci_option *option = (uci_to_option(element));
 		if (strcmp(option->e.name, "profile") != 0)
 			continue;
 
-		int j;
+		uci_foreach_element(&url_pkg->sections, e) {
+			struct uci_element *elem = NULL;
+			struct uci_option *opt = NULL;
+
+			profile_found = 0;
+			sec = uci_to_section(e);
+			if (strcmp(sec->type, "profile") != 0)
+				continue;
+			uci_foreach_element(&sec->options, elem) {
+				opt = (uci_to_option(elem));
+				if (strcmp(opt->e.name, "name") == 0) {
+					profile_found = 1;
+					break;
+				}
+			}
+
+			if (profile_found == 1) {
+				int j;
 
-		for (j = 0; j < profile_cnt; j++) {
-			if (strcmp(option->v.string, (url_profile + j)->name) == 0) {
-				(url_filter + i)->p = &url_profile[j];
-				break;
+				for (j = 0; j < profile_cnt; j++) {
+					if (strcmp(opt->v.string, (url_profile + j)->name) == 0) {
+						(url_filter + i)->p = &url_profile[j];
+						return;
+					}
+				}
 			}
 		}
 
diff --git a/src/filter.c b/src/filter.c
index 876179c5cd235a6d3c82dbbe698ce4c952dc08e9..931dbd22977e273ac4706c9ac45ff5e58e88e524 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -46,6 +46,7 @@
 #define CHECK_GLOBAL_URL_LIST -1
 #define URL_SUCCESS 1
 #define MAX_IP_LEN 32
+#define DNS_HDR_LEN_OVER_TCP 2U
 
 struct ubus_context *ctx;
 struct nfq_handle *nfq_h;
@@ -186,9 +187,31 @@ static int get_ip_packet_payload(unsigned char *data_p, uint8_t *proto, size_t l
 			payload_offset = (((size_t)iph->ihl)<<2U) + sizeof(struct udphdr) + sizeof(struct dnshdr);
 
 		} else if (*proto == IPPROTO_TCP) {
-			// Return the payload offset in case of tcp packet.
 			tcp_header = (const struct tcphdr *)(data_p + (iph->ihl<<2U));
-			payload_offset = (((size_t)iph->ihl)<<2U) + ((size_t)tcp_header->doff<<2U);
+
+			// If the packet is dns response then return the payload_offset as
+			// 0 and update the dns cache with the ip address.
+			if (ntohs(tcp_header->source) == DNS_PORT) {
+				unsigned char dns_payload[len + 1];
+
+				memset(dns_payload, '\0', len + 1U);
+				if (len <= ((((size_t)iph->ihl)<<2U) + ((size_t)tcp_header->doff<<2U) + DNS_HDR_LEN_OVER_TCP)) {
+					return -1;
+				}
+				memcpy(dns_payload, data_p+(((size_t)iph->ihl)<<2U) + ((size_t)tcp_header->doff<<2U) + DNS_HDR_LEN_OVER_TCP, len-((((size_t)iph->ihl)<<2U) + ((size_t)tcp_header->doff<<2U) + DNS_HDR_LEN_OVER_TCP) + 1U);
+				if ('\0' == dns_payload[0]) {
+					syslog(LOG_ERR, "payload is null");
+					return -1;
+				}
+				parse_dns_response(dns_payload);
+				return 0;
+			}
+			else if (ntohs(tcp_header->dest) == DNS_PORT) {
+				// If the packet is dns query then return the payload offset.
+				payload_offset = (((size_t)iph->ihl)<<2U) + ((size_t)tcp_header->doff<<2U) + sizeof(struct dnshdr) + DNS_HDR_LEN_OVER_TCP;
+			}
+			else
+				payload_offset = (((size_t)iph->ihl)<<2U) + ((size_t)tcp_header->doff<<2U);
 		} else {
 			syslog(LOG_ERR, "Unknown protocol");
 			return -1;
@@ -235,7 +258,33 @@ static int get_ip_packet_payload(unsigned char *data_p, uint8_t *proto, size_t l
 			payload_offset += sizeof(struct udphdr) + sizeof(struct dnshdr);
 		} else if (*proto == IPPROTO_TCP) {
 			tcp_header = (const struct tcphdr *)((uint8_t *)ip6h + payload_offset);
-			payload_offset += ((size_t)tcp_header->doff<<2U);
+
+			// Don't process DNS packets if ipv6 is not enabled
+			if (!is_ipv6_enabled())
+				return 1;
+			// If the packet is dns response then return the payload_offset as
+			// 0 and update the dns cache with the ip address.
+			if (ntohs(tcp_header->source) == DNS_PORT) {
+				unsigned char dns_payload[len + 1];
+
+				memset(dns_payload, '\0', len + 1U);
+				if (len <= ((((size_t)iph->ihl)<<2U) + ((size_t)tcp_header->doff<<2U) + DNS_HDR_LEN_OVER_TCP)) {
+					return -1;
+				}
+				memcpy(dns_payload, data_p+payload_offset+((size_t)tcp_header->doff<<2U) + DNS_HDR_LEN_OVER_TCP, len-(payload_offset+((size_t)tcp_header->doff<<2U) + DNS_HDR_LEN_OVER_TCP) + 1U);
+				if ('\0' == dns_payload[0]) {
+					syslog(LOG_ERR, "payload is null");
+					return -1;
+				}
+				parse_dns_response(dns_payload);
+				return 0;
+			}
+			else if (ntohs(tcp_header->dest) == DNS_PORT) {
+				// If the packet is dns query then return the payload offset.
+				payload_offset += ((size_t)tcp_header->doff<<2U) + sizeof(struct dnshdr) + DNS_HDR_LEN_OVER_TCP;
+			}
+			else
+				payload_offset += ((size_t)tcp_header->doff<<2U);
 		} else {
 			syslog(LOG_ERR, "Unknown protocol");
 			return -1;
@@ -681,6 +730,9 @@ static int get_payload_pkt(int proto, unsigned char *data, int payload_offset,
 {
 
 	if (proto == IPPROTO_TCP) {
+		// If the packet is a dns reponse then accept the packet.
+		if (payload_offset == 0)
+			return PKT_ACCEPT;
 		// Check if its https packet or not, if yes then update the
 		// payload_pkt with destination ip address.
 		if (!is_ipv6) {
@@ -776,6 +828,9 @@ static int handle_packet_filtering(struct nfq_data *payload)
 
 	// Get the URL(http)/Destination IP address(https)/Domain name(DNS)
 	if ((proto == IPPROTO_TCP) && is_ipv6) {
+		// If the packet is a dns reponse then accept the packet.
+		if (payload_offset == 0)
+			return PKT_ACCEPT;
 		memset(ipv6_addr_str, 0, MAX_IPV6_LEN);
 		ret = get_ipv6_tcp_payload_pkt(data, ipv6_addr_str, &is_https_packet);