Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cli] update borderagent discover to allow network interface selection for mDNS binding #259

Merged
merged 13 commits into from
Apr 29, 2024
Merged
4 changes: 2 additions & 2 deletions src/app/border_agent_functions_mock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ void ClearBorderAgentFunctionsMock()
gBorderAgentFunctionsMock = nullptr;
}

Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout)
Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout, const std::string &aNetIf)
{
return gBorderAgentFunctionsMock->DiscoverBorderAgent(aBorderAgentHandler, aTimeout);
return gBorderAgentFunctionsMock->DiscoverBorderAgent(aBorderAgentHandler, aTimeout, aNetIf);
}

} // namespace commissioner
Expand Down
2 changes: 1 addition & 1 deletion src/app/border_agent_functions_mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class BorderAgentFunctionsMock
public:
virtual ~BorderAgentFunctionsMock() = default;

MOCK_METHOD(Error, DiscoverBorderAgent, (BorderAgentHandler, size_t));
MOCK_METHOD(Error, DiscoverBorderAgent, (BorderAgentHandler, size_t, const std::string&));
};

void SetBorderAgentFunctionsMock(ot::commissioner::BorderAgentFunctionsMock *ptr);
Expand Down
10 changes: 9 additions & 1 deletion src/app/br_discover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,19 @@
#include "br_discover.hpp"

#include <chrono>
#include <sys/socket.h>
#include <thread>

#include "common/error_macros.hpp"
#include "common/utils.hpp"

#define SO_BINDTODEVICE 25

ZhangLe2016 marked this conversation as resolved.
Show resolved Hide resolved
namespace ot {

namespace commissioner {

Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout)
Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout, const std::string &aNetIf)
{
static constexpr size_t kDefaultBufferSize = 1024 * 16;
static constexpr mdns_record_type_t kMdnsQueryType = MDNS_RECORDTYPE_PTR;
Expand All @@ -52,6 +55,11 @@ Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeou
int socket = mdns_socket_open_ipv4();
VerifyOrExit(socket >= 0, error = ERROR_IO_ERROR("failed to open mDNS IPv4 socket"));

if (!aNetIf.empty() && setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, &aNetIf[0], sizeof(aNetIf)) < 0)
{
ExitNow(error = ERROR_INVALID_ARGS("failed to bind network interface {}: {}", aNetIf, strerror(errno)));
}

if (mdns_query_send(socket, kMdnsQueryType, kServiceName, strlen(kServiceName), buf, sizeof(buf)) != 0)
{
ExitNow(error = ERROR_IO_ERROR("failed to send mDNS query"));
Expand Down
4 changes: 3 additions & 1 deletion src/app/br_discover.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@ using BorderAgentHandler = std::function<void(const BorderAgent *aBorderAgent, c
* @param[in] aBorderAgentHandler The handler of a single Border Agent response.
* @param[in] aTimeout The time to wait for mDNS responses. Any
* response not within the interval is ignored.
* @param[in] aNetIf The specified network interface for mDNS binding. Can be an empty string
*
*
*/
Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout);
Error DiscoverBorderAgent(BorderAgentHandler aBorderAgentHandler, size_t aTimeout, const std::string &aNetIf);

} // namespace commissioner

Expand Down
2 changes: 1 addition & 1 deletion src/app/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ The command `borderagent` provides access to Border Agent information and scans
```shell
> help borderagent
usage:
borderagent discover [<timeout-in-milliseconds>]
borderagent discover [<timeout-in-milliseconds>] [<specified-network-interface>]
borderagent get locator
[done]
>
Expand Down
10 changes: 8 additions & 2 deletions src/app/cli/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1787,14 +1787,20 @@ Interpreter::Value Interpreter::ProcessBorderAgent(const Expression &aExpr)

if (CaseInsensitiveEqual(aExpr[1], "discover"))
{
uint64_t timeout = 4000;
uint64_t timeout = 4000;
std::string netIf = "";

if (aExpr.size() >= 3)
{
SuccessOrExit(value = ParseInteger(timeout, aExpr[2]));
}

SuccessOrExit(value = DiscoverBorderAgent(BorderAgentHandler, static_cast<size_t>(timeout)));
if (aExpr.size() == 4)
{
netIf = aExpr[3];
}

SuccessOrExit(value = DiscoverBorderAgent(BorderAgentHandler, static_cast<size_t>(timeout), netIf));
}
else if (CaseInsensitiveEqual(aExpr[1], "get"))
{
Expand Down
2 changes: 1 addition & 1 deletion src/app/cli/interpreter_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1629,7 +1629,7 @@ TEST_F(InterpreterTestSuite, PC_BorderagentDiscover)
BorderAgentFunctionsMock bafm;
SetBorderAgentFunctionsMock(&bafm);

EXPECT_CALL(bafm, DiscoverBorderAgent(_, _)).WillOnce(Return(Error{}));
EXPECT_CALL(bafm, DiscoverBorderAgent(_, _, _)).WillOnce(Return(Error{}));

Interpreter::Expression expr;
Interpreter::Value value;
Expand Down
Loading