Fix memory leak setting transports

This commit is contained in:
Willem Toorop 2015-07-13 16:39:43 +02:00
parent 5c61954427
commit a8adf662d1
1 changed files with 79 additions and 65 deletions

View File

@ -1190,15 +1190,14 @@ getdns_context_set_namespaces(struct getdns_context *context,
} /* getdns_context_set_namespaces */ } /* getdns_context_set_namespaces */
static getdns_return_t static getdns_return_t
getdns_set_base_dns_transports(struct getdns_context *context, getdns_set_base_dns_transports(
size_t transport_count, getdns_transport_list_t *transports) getdns_context *context, size_t transport_count, getdns_transport_list_t *transports)
{ {
size_t i; size_t i;
getdns_transport_list_t *new_transports;
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); if (!context || transport_count == 0 || transports == NULL)
if (transport_count == 0 || transports == NULL) { return GETDNS_RETURN_INVALID_PARAMETER;
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
for(i=0; i<transport_count; i++) for(i=0; i<transport_count; i++)
{ {
@ -1208,18 +1207,23 @@ getdns_set_base_dns_transports(struct getdns_context *context,
&& transports[i] != GETDNS_TRANSPORT_STARTTLS) && transports[i] != GETDNS_TRANSPORT_STARTTLS)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
} }
if (!(new_transports = GETDNS_XMALLOC(context->my_mf,
getdns_transport_list_t, transport_count)))
GETDNS_FREE(context->my_mf, context->dns_transports); return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
/** duplicate **/ if (context->dns_transports)
context->dns_transports = GETDNS_XMALLOC(context->my_mf, GETDNS_FREE(context->my_mf, context->dns_transports);
getdns_transport_list_t, transport_count);
memcpy(context->dns_transports, transports, /** duplicate **/
transport_count * sizeof(getdns_transport_list_t)); context->dns_transports = new_transports;
memcpy(context->dns_transports, transports,
transport_count * sizeof(getdns_transport_list_t));
context->dns_transport_count = transport_count; context->dns_transport_count = transport_count;
dispatch_updated(context, GETDNS_CONTEXT_CODE_NAMESPACES); dispatch_updated(context, GETDNS_CONTEXT_CODE_NAMESPACES);
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
static getdns_return_t static getdns_return_t
@ -1278,62 +1282,72 @@ set_ub_dns_transport(struct getdns_context* context) {
* *
*/ */
getdns_return_t getdns_return_t
getdns_context_set_dns_transport(struct getdns_context *context, getdns_context_set_dns_transport(
getdns_transport_t value) getdns_context *context, getdns_transport_t value)
{ {
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER); size_t count = 2;
getdns_transport_list_t *new_transports;
size_t count = 2; if (value == GETDNS_TRANSPORT_UDP_ONLY ||
if (value == GETDNS_TRANSPORT_UDP_ONLY || value == GETDNS_TRANSPORT_TCP_ONLY ||
value == GETDNS_TRANSPORT_TCP_ONLY || value == GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN ||
value == GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN || value == GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN)
value == GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN) count = 1;
count = 1;
context->dns_transport_count = count;
context->dns_transports = GETDNS_XMALLOC(context->my_mf,
getdns_transport_list_t, count);
switch (value) { if (!context)
case GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP: return GETDNS_RETURN_INVALID_PARAMETER;
context->dns_transports[0] = GETDNS_TRANSPORT_UDP;
context->dns_transports[1] = GETDNS_TRANSPORT_TCP; if (!(new_transports = GETDNS_XMALLOC(
break; context->my_mf, getdns_transport_list_t, count)))
case GETDNS_TRANSPORT_UDP_ONLY: return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
context->dns_transports[0] = GETDNS_TRANSPORT_UDP;
break; if (context->dns_transports)
case GETDNS_TRANSPORT_TCP_ONLY: GETDNS_FREE(context->my_mf, context->dns_transports);
case GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN:
context->dns_transports[0] = GETDNS_TRANSPORT_TCP; context->dns_transport_count = count;
break; context->dns_transports = new_transports;
case GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN:
context->dns_transports[0] = GETDNS_TRANSPORT_TLS; switch (value) {
break; case GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP:
case GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN: context->dns_transports[0] = GETDNS_TRANSPORT_UDP;
context->dns_transports[0] = GETDNS_TRANSPORT_TLS; context->dns_transports[1] = GETDNS_TRANSPORT_TCP;
context->dns_transports[1] = GETDNS_TRANSPORT_TCP; break;
break; case GETDNS_TRANSPORT_UDP_ONLY:
case GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN: context->dns_transports[0] = GETDNS_TRANSPORT_UDP;
context->dns_transports[0] = GETDNS_TRANSPORT_STARTTLS; break;
context->dns_transports[1] = GETDNS_TRANSPORT_TCP; case GETDNS_TRANSPORT_TCP_ONLY:
break; case GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN:
default: context->dns_transports[0] = GETDNS_TRANSPORT_TCP;
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; break;
} case GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN:
/* Note that the call below does not have any effect in unbound after the context->dns_transports[0] = GETDNS_TRANSPORT_TLS;
* ctx is finalised so for recursive mode or stub + dnssec only the first break;
* transport specified on the first query is used. case GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
* However the method returns success as otherwise the transport could not context->dns_transports[0] = GETDNS_TRANSPORT_TLS;
* be reset for stub mode. context->dns_transports[1] = GETDNS_TRANSPORT_TCP;
* Also, not all transport options supported in libunbound yet */ break;
if (set_ub_dns_transport(context) != GETDNS_RETURN_GOOD) { case GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; context->dns_transports[0] = GETDNS_TRANSPORT_STARTTLS;
} context->dns_transports[1] = GETDNS_TRANSPORT_TCP;
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_TRANSPORT); break;
return GETDNS_RETURN_GOOD; default:
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
/* Note that the call below does not have any effect in unbound after the
* ctx is finalised so for recursive mode or stub + dnssec only the first
* transport specified on the first query is used.
* However the method returns success as otherwise the transport could not
* be reset for stub mode.
* Also, not all transport options supported in libunbound yet */
if (set_ub_dns_transport(context) != GETDNS_RETURN_GOOD) {
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_TRANSPORT);
return GETDNS_RETURN_GOOD;
} }
/* /*
* getdns_context_set_dns_transport * getdns_context_set_dns_transport_list
* *
*/ */
getdns_return_t getdns_return_t
@ -1354,7 +1368,7 @@ getdns_context_set_dns_transport_list(getdns_context *context,
} }
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_TRANSPORT); dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_TRANSPORT);
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} /* getdns_context_set_dns_transport */ } /* getdns_context_set_dns_transport_list */
static void static void
set_ub_limit_outstanding_queries(struct getdns_context* context, uint16_t value) { set_ub_limit_outstanding_queries(struct getdns_context* context, uint16_t value) {