hdr->nscount = 0;
hdr->arcount = 0;
- /* if this is a negative reply, we are authorative */
+ /* if this is a negative reply, we are authoritative */
if (answers == 0)
hdr->aa = 1;
else
char **uncompressed_ptr)
{
char *uptr = *uncompressed_ptr; /* position in result buffer */
+ char * const uncomp_end = uncompressed + uncomp_len - 1;
debug("count %d ptr %p end %p uptr %p", field_count, ptr, end, uptr);
* tmp buffer.
*/
- ulen = strlen(name);
- strncpy(uptr, name, uncomp_len - (uptr - uncompressed));
+ ulen = strlen(name) + 1;
+ if ((uptr + ulen) > uncomp_end)
+ goto out;
+ strncpy(uptr, name, ulen);
debug("pos %d ulen %d left %d name %s", pos, ulen,
- (int)(uncomp_len - (uptr - uncompressed)), uptr);
+ (int)(uncomp_end - (uptr + ulen)), uptr);
uptr += ulen;
- *uptr++ = '\0';
ptr += pos;
* We copy also the fixed portion of the result (type, class,
* ttl, address length and the address)
*/
+ if ((uptr + NS_RRFIXEDSZ) > uncomp_end) {
+ debug("uncompressed data too large for buffer");
+ goto out;
+ }
memcpy(uptr, ptr, NS_RRFIXEDSZ);
dns_type = uptr[0] << 8 | uptr[1];
} else if (dns_type == ns_t_a || dns_type == ns_t_aaaa) {
dlen = uptr[-2] << 8 | uptr[-1];
- if (ptr + dlen > end) {
+ if ((ptr + dlen) > end || (uptr + dlen) > uncomp_end) {
debug("data len %d too long", dlen);
goto out;
}
* refresh interval, retry interval, expiration
* limit and minimum ttl). They are 20 bytes long.
*/
+ if ((uptr + 20) > uncomp_end || (ptr + 20) > end) {
+ debug("soa record too long");
+ goto out;
+ }
memcpy(uptr, ptr, 20);
uptr += 20;
ptr += 20;
req->resplen = 0;
req->resp = g_try_malloc(reply_len);
+#if defined TIZEN_EXT
+ if (!req->resp) {
+ g_free(new_reply);
+ return -ENOMEM;
+ }
+#else
if (!req->resp)
return -ENOMEM;
+#endif
memcpy(req->resp, reply, reply_len);
req->resplen = reply_len;
bool server_enabled = false;
GSList *list;
int index;
+ int vpn_index;
DBG("service %p", service);
if (index < 0)
return;
+ /*
+ * In case non-split-routed VPN is set as split routed the DNS servers
+ * the VPN must be enabled as well, when the transport becomes the
+ * default service.
+ */
+ vpn_index = __connman_connection_get_vpn_index(index);
+
for (list = server_list; list; list = list->next) {
struct server_data *data = list->data;
DBG("Enabling DNS server %s", data->server);
data->enabled = true;
server_enabled = true;
+ } else if (data->index == vpn_index) {
+ DBG("Enabling DNS server of VPN %s", data->server);
+ data->enabled = true;
} else {
DBG("Disabling DNS server %s", data->server);
data->enabled = false;
cache_refresh();
}
+static void dnsproxy_service_state_changed(struct connman_service *service,
+ enum connman_service_state state)
+{
+ GSList *list;
+ int index;
+
+ switch (state) {
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ break;
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ case CONNMAN_SERVICE_STATE_READY:
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ return;
+ }
+
+ index = __connman_service_get_index(service);
+ list = server_list;
+
+ while (list) {
+ struct server_data *data = list->data;
+
+ /* Get next before the list is changed by destroy_server() */
+ list = list->next;
+
+ if (data->index == index) {
+ DBG("removing server data of index %d", index);
+ destroy_server(data);
+ }
+ }
+}
+
static const struct connman_notifier dnsproxy_notifier = {
.name = "dnsproxy",
.default_changed = dnsproxy_default_changed,
.offline_mode = dnsproxy_offline_mode,
+ .service_state_changed = dnsproxy_service_state_changed,
};
static const unsigned char opt_edns0_type[2] = { 0x00, 0x29 };
&ifdata->tcp6_listener_watch);
}
+#if defined TIZEN_EXT
+struct request_data * create_request(int sk, unsigned char *buf, size_t len,
+ const struct sockaddr *to, socklen_t tolen,
+ int protocol)
+{
+ struct request_data *req;
+ req = g_try_new0(struct request_data, 1);
+ if (!req)
+ return NULL;
+ memcpy(&req->sa, to, tolen);
+ req->sa_len = tolen;
+ req->client_sk = sk;
+ req->protocol = protocol;
+ req->request_len = len;
+ req->request = g_malloc(len);
+ memcpy(req->request, buf, len);
+ return req;
+
+}
+static gboolean send_response_timeout (gpointer user_data)
+{
+ struct request_data *req = user_data;
+
+ send_response(req->client_sk, req->request,(size_t) req->request_len, (const struct sockaddr *)&req->sa,
+ (socklen_t)req->sa_len, req->protocol);
+ g_free(req->request);
+ g_free(req);
+
+ return FALSE;
+
+}
+#endif
+
static bool udp_listener_event(GIOChannel *channel, GIOCondition condition,
struct listener_data *ifdata, int family,
guint *listener_watch)
err = parse_request(buf, len, query, sizeof(query));
if (err < 0 || (g_slist_length(server_list) == 0)) {
+#if defined TIZEN_EXT
+ /** TEMP Fix
+ * Reason: In tizen6.0 same code working fine because it seems some delay in 6.0 platform
+ * where as in tizen6.5 this loop is continuously executing due to this unable to receive
+ * the response from telephony deamon and wpa_supplicant. To stop continuously execution
+ * of this code added 10ms delay.
+ */
+ req = create_request(sk, buf, len, client_addr,
+ *client_addr_len, IPPROTO_UDP);
+ if(!req)
+ return true;;
+ g_timeout_add(10, send_response_timeout, req);
+#else
send_response(sk, buf, len, client_addr,
*client_addr_len, IPPROTO_UDP);
+#endif
return true;
}