RDKB-64441: Maximum number of concurrent DNS queries reached | Web browsing affected - #407
RDKB-64441: Maximum number of concurrent DNS queries reached | Web browsing affected#407sowmiyachelliah wants to merge 27 commits into
Conversation
Reason for change: For test purpose Test Procedure: For test purpose Risks: Low Priority: P1 Signed-off-by:Sowmiya_Chelliah@comcast.com
…eature/dnsmasq_issue
…eature/dnsmasq_issue
There was a problem hiding this comment.
Pull request overview
This PR enables runtime configuration of dnsmasq’s concurrent DNS query limit by reading the persisted syscfg value (dnsmasq_dns_forward_max, set via TR-181 Device.DNS.Config.X_RDKCENTRAL-COM_DNSForwardMax) and passing it to dnsmasq as --dns-forward-max.
Changes:
- Read
dnsmasq_dns_forward_maxfrom syscfg and apply it when launching dnsmasq from the C dhcp service. - Apply the same syscfg-driven
--dns-forward-maxbehavior in the init script path (including XDNS and non-XDNS flows).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| source/service_dhcp/service_dhcp_server.c | Adds syscfg-driven construction of --dns-forward-max and appends it to dnsmasq command lines. |
| source/scripts/init/service.d/service_dhcp_server.sh | Adds syscfg-driven --dns-forward-max argument to dnsmasq invocation across XDNS/non-XDNS branches. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
source/scripts/init/service.d/service_dhcp_server.sh:129
dnsmasq_dns_forward_maxis inserted into the dnsmasq command line without validating that it is digits-only. Because$DNS_FORWARD_MAX_ARGis expanded unquoted, a value containing whitespace or extra tokens would be split into additional arguments (changing dnsmasq behavior). Validate the syscfg value before constructing--dns-forward-max=and fall back to the default on invalid input.
DNS_FORWARD_MAX=`syscfg get dnsmasq_dns_forward_max`
DNS_FORWARD_MAX_ARG=""
if [ -n "$DNS_FORWARD_MAX" ] && [ "$DNS_FORWARD_MAX" != "0" ]; then
DNS_FORWARD_MAX_ARG="--dns-forward-max=$DNS_FORWARD_MAX"
else
DNS_FORWARD_MAX_ARG="--dns-forward-max=150"
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
source/scripts/init/service.d/service_dhcp_server.sh:128
- dnsmasq_dns_forward_max is still incorporated into the dnsmasq command line without validating that it is numeric (and within the intended 1-600 range). If the syscfg value contains spaces or other characters, it can be split into extra args/options or cause dnsmasq startup failures. Please validate digits-only and enforce the 1-600 range before building DNS_FORWARD_MAX_ARG.
DNS_FORWARD_MAX=`syscfg get dnsmasq_dns_forward_max`
DNS_FORWARD_MAX_ARG=""
if [ -n "$DNS_FORWARD_MAX" ] && [ "$DNS_FORWARD_MAX" != "0" ]; then
DNS_FORWARD_MAX_ARG="--dns-forward-max=$DNS_FORWARD_MAX"
else
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (2)
source/service_dhcp/service_dhcp_server.c:283
- Using
atoi()on a digits-only syscfg string can still invoke undefined behavior on overflow (e.g., if syscfg contains a very large numeric string). Preferstrtoul()witherrno/end-pointer checks, then apply the 1–600 range validation.
if (is_valid)
{
unsigned int value = (unsigned int)atoi(l_cDnsForwardMax);
/* Validate range: 1-600 (same as TR-181 setter) */
if (value >= 1 && value <= 600)
{
safec_rc = sprintf_s(l_cDnsForwardMaxArg, sizeof(l_cDnsForwardMaxArg),
"--dns-forward-max=%u", value);
}
else
{
fprintf(g_fArmConsoleLog, "SECURITY: Invalid dnsmasq_dns_forward_max value (out of range 1-600): %u\n", value);
is_valid = 0;
source/scripts/init/service.d/service_dhcp_server.sh:130
dnsmasq_dns_forward_maxfrom syscfg is still used without validating that it’s numeric and within the intended 1–600 range. The current check only excludes empty/"0" and will accept values like "000" (treated as 0) or non-numeric strings, which can change dnsmasq behavior unexpectedly.
# Read DNS forward max from syscfg (set via TR-181 X_RDKCENTRAL-COM_DNSForwardMax)
DNS_FORWARD_MAX=`syscfg get dnsmasq_dns_forward_max`
DNS_FORWARD_MAX_ARG=""
if [ -n "$DNS_FORWARD_MAX" ] && [ "$DNS_FORWARD_MAX" != "0" ]; then
DNS_FORWARD_MAX_ARG="--dns-forward-max=$DNS_FORWARD_MAX"
else
DNS_FORWARD_MAX_ARG="--dns-forward-max=150"
fi
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
source/service_dhcp/service_dhcp_server.c:407
- This non-XDNS start path drops the DNSStrictOrder option built in dnsOption (getRFC_Value(dnsOption) above). As a result, DNSStrictOrder has no effect in this branch. Include dnsOption here as in the other dnsmasq invocations.
safec_rc = sprintf_s(l_cSystemCmd, sizeof(l_cSystemCmd),"%s -P 4096 -C %s %s",SERVER, DHCP_CONF, l_cDnsForwardMaxArg);
source/service_dhcp/service_dhcp_server.c:276
- Using atoi() on a syscfg string can invoke undefined behavior on overflow. Even with digits-only validation, a corrupted/very large value could overflow; prefer strtoul() with errno/endptr checks and then apply the 1–600 range validation.
unsigned int value = (unsigned int)atoi(l_cDnsForwardMax);
/* Validate range: 1-600 (same as TR-181 setter) */
if (value >= 1 && value <= 600)
{
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
source/scripts/init/service.d/service_dhcp_server.sh:143
- The
-ge/-lenumeric comparisons can emit errors (and behave unpredictably) ifdnsmasq_dns_forward_maxcontains a very large digits-only value (e.g., corrupted syscfg like999999999999...). Add a simple length guard (max 3 digits, since the valid range is 1-600) so the script never attempts numeric comparison on oversized values.
if [ -n "$DNS_FORWARD_MAX" ]; then
# Validate: must contain only digits
case "$DNS_FORWARD_MAX" in
*[!0-9]*)
echo_t "SECURITY: Invalid dnsmasq_dns_forward_max value (non-digit): $DNS_FORWARD_MAX"
DNS_FORWARD_MAX_ARG="--dns-forward-max=150"
;;
*)
# Validate range: 1-600 (same as TR-181 setter)
if [ "$DNS_FORWARD_MAX" -ge 1 ] && [ "$DNS_FORWARD_MAX" -le 600 ]; then
DNS_FORWARD_MAX_ARG="--dns-forward-max=$DNS_FORWARD_MAX"
else
echo_t "SECURITY: Invalid dnsmasq_dns_forward_max value (out of range 1-600): $DNS_FORWARD_MAX"
DNS_FORWARD_MAX_ARG="--dns-forward-max=150"
fi
;;
esac
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
source/service_dhcp/service_dhcp_server.c:410
- If
sprintf_sfails while buildingl_cSystemCmd, the code logs viaERR_CHKbut still proceeds toexecuteCmd(l_cSystemCmd). Sincel_cSystemCmdis zero-initialized, this can result in executing an empty command string and reporting success, masking the real failure to construct the dnsmasq invocation (risk increases as more arguments are appended). Add a hard failure path when the command buffer is empty before callingexecuteCmd.
safec_rc = sprintf_s(l_cSystemCmd, sizeof(l_cSystemCmd),"%s -P 4096 -C %s %s",SERVER, DHCP_CONF, l_cDnsForwardMaxArg);
if(safec_rc < EOK)
{
ERR_CHK(safec_rc);
}
| /* Read dns-forward-max from syscfg (set via TR-181 X_RDKCENTRAL-COM_DNSForwardMax) */ | ||
| syscfg_get(NULL, "dnsmasq_dns_forward_max", l_cDnsForwardMax, sizeof(l_cDnsForwardMax)); | ||
|
|
||
| if (l_cDnsForwardMax[0] != '\0') | ||
| { | ||
| char *endptr = NULL; | ||
| unsigned long value_ul = 0; | ||
|
|
||
| /* Reset errno before strtoul */ | ||
| errno = 0; | ||
| value_ul = strtoul(l_cDnsForwardMax, &endptr, 10); | ||
|
|
||
| /* Validate: check for conversion errors */ | ||
| if (errno == ERANGE) | ||
| { | ||
| fprintf(g_fArmConsoleLog, "SECURITY: Invalid dnsmasq_dns_forward_max value (overflow): %s\n", l_cDnsForwardMax); | ||
| is_valid = 0; | ||
| } | ||
| else if (endptr == l_cDnsForwardMax || *endptr != '\0') | ||
| { | ||
| fprintf(g_fArmConsoleLog, "SECURITY: Invalid dnsmasq_dns_forward_max value (non-numeric): %s\n", l_cDnsForwardMax); | ||
| is_valid = 0; | ||
| } | ||
| else if (value_ul < 1 || value_ul > 600) | ||
| { | ||
| fprintf(g_fArmConsoleLog, "SECURITY: Invalid dnsmasq_dns_forward_max value (out of range 1-600): %lu\n", value_ul); | ||
| is_valid = 0; | ||
| } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (1)
source/service_dhcp/service_dhcp_server.c:254
- New behavior is introduced by reading
dnsmasq_dns_forward_max, validating it, and injecting--dns-forward-max=into the dnsmasq command line, but there are no unit tests exercisingdnsmasq_server_start()or asserting the constructed command for valid/invalid syscfg values (the existing C++ test suite covers other functions in this module). Please add tests for at least: unset -> default 150, valid 1..600, non-numeric, and out-of-range values.
/* Read dns-forward-max from syscfg (set via TR-181 X_RDKCENTRAL-COM_DNSForwardMax) */
syscfg_get(NULL, "dnsmasq_dns_forward_max", l_cDnsForwardMax, sizeof(l_cDnsForwardMax));
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (1)
source/service_dhcp/service_dhcp_server.c:410
- If any sprintf_s() building l_cSystemCmd fails (now more likely with the extra --dns-forward-max argument), the function still falls through and calls executeCmd(l_cSystemCmd). In this codebase executeCmd() uses system(cmd); if cmd is empty, dnsmasq will not start and the failure may be hard to diagnose. Bail out when command formatting fails (and/or guard against an empty command) before calling executeCmd().
safec_rc = sprintf_s(l_cSystemCmd, sizeof(l_cSystemCmd),"%s -P 4096 -C %s %s",SERVER, DHCP_CONF, l_cDnsForwardMaxArg);
if(safec_rc < EOK)
{
ERR_CHK(safec_rc);
}
Reason for change:
Enable runtime configuration of dnsmasq's concurrent DNS query limit
via TR-181 parameter Device.DNS.Config.X_RDKCENTRAL-COM_DNSForwardMax.
Test Procedure:
Risks: Low
Priority: P1
Signed-off-by: Sowmiya_Chelliah@comcast.com