Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion common/network/FakeInterfacePicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ class FakeInterfacePicker: public InterfacePicker {
m_interfaces(interfaces) {
}

std::vector<Interface> GetInterfaces(bool include_loopback) const {
std::vector<Interface> GetInterfaces(bool include_loopback,
bool include_down) const {
(void) include_down;
if (include_loopback) {
return m_interfaces;
} else {
Expand Down
6 changes: 4 additions & 2 deletions common/network/InterfacePicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ bool InterfacePicker::ChooseInterface(
const string &ip_or_name,
const Options &options) const {
bool found = false;
vector<Interface> interfaces = GetInterfaces(options.include_loopback);
vector<Interface> interfaces = GetInterfaces(options.include_loopback,
options.include_down);

if (interfaces.empty()) {
OLA_INFO << "No interfaces found";
Expand Down Expand Up @@ -110,7 +111,8 @@ bool InterfacePicker::ChooseInterface(
int32_t index,
const Options &options) const {
bool found = false;
vector<Interface> interfaces = GetInterfaces(options.include_loopback);
vector<Interface> interfaces = GetInterfaces(options.include_loopback,
options.include_down);

if (interfaces.empty()) {
OLA_INFO << "No interfaces found";
Expand Down
4 changes: 2 additions & 2 deletions common/network/InterfacePickerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION(InterfacePickerTest);
*/
void InterfacePickerTest::testGetInterfaces() {
auto_ptr<InterfacePicker> picker(InterfacePicker::NewPicker());
vector<Interface> interfaces = picker->GetInterfaces(true);
vector<Interface> interfaces = picker->GetInterfaces(true, true);
#ifndef _WIN32
// If a Windows box is not on a network, and doesn't have it's loopback, there
// may be zero interfaces present so we skip this check
Expand All @@ -87,7 +87,7 @@ void InterfacePickerTest::testGetInterfaces() {
*/
void InterfacePickerTest::testGetLoopbackInterfaces() {
auto_ptr<InterfacePicker> picker(InterfacePicker::NewPicker());
vector<Interface> interfaces = picker->GetInterfaces(true);
vector<Interface> interfaces = picker->GetInterfaces(true, true);
#ifndef _WIN32
// If a Windows box is not on a network, and doesn't have it's loopback, there
// may be zero interfaces present so we skip this check
Expand Down
5 changes: 3 additions & 2 deletions common/network/PosixInterfacePicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ using std::vector;
* Return a vector of interfaces on the system.
*/
vector<Interface> PosixInterfacePicker::GetInterfaces(
bool include_loopback) const {
bool include_loopback,
bool include_down) const {
vector<Interface> interfaces;

#ifdef HAVE_SOCKADDR_DL_STRUCT
Expand Down Expand Up @@ -152,7 +153,7 @@ vector<Interface> PosixInterfacePicker::GetInterfaces(
continue;
}

if (!(ifrcopy.ifr_flags & IFF_UP)) {
if (!(ifrcopy.ifr_flags & IFF_UP) && !include_down) {
OLA_DEBUG << "Skipping " << iface->ifr_name
<< " because it's down";
continue;
Expand Down
3 changes: 2 additions & 1 deletion common/network/PosixInterfacePicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ namespace network {
*/
class PosixInterfacePicker: public InterfacePicker {
public:
std::vector<Interface> GetInterfaces(bool include_loopback) const;
std::vector<Interface> GetInterfaces(bool include_loopback,
bool include_down) const;

private:
static const unsigned int INITIAL_IFACE_COUNT = 10;
Expand Down
27 changes: 20 additions & 7 deletions common/network/Socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,21 +364,34 @@ bool UDPSocket::EnableBroadcast() {
}


bool UDPSocket::SetMulticastInterface(const IPV4Address &iface) {
struct in_addr addr;
addr.s_addr = iface.AsInt();
bool UDPSocket::SetMulticastInterface(const Interface &iface) {
#ifdef _WIN32
struct in_addr addr;
addr.s_addr = htonl(iface.index());
int ok = setsockopt(m_handle.m_handle.m_fd,
#else
int ok = setsockopt(m_handle,
#endif // _WIN32
IPPROTO_IP,
IP_MULTICAST_IF,
reinterpret_cast<const char*>(&addr),
sizeof(addr));
#else
struct ip_mreqn req = {0, 0, 0};
req.imr_ifindex = iface.index;
int ok = setsockopt(m_handle,
IPPROTO_IP,
IP_MULTICAST_IF,
reinterpret_cast<const char*>(&req),
sizeof(req));
#endif // _WIN32
if (ok < 0) {
std::string iface_desc;
if(!iface.name.empty())
iface_desc = iface.name
+ "(" + std::to_string(iface.index) + ")";
else
iface_desc = iface.ip_address.ToString()
+ "(" + std::to_string(iface.index) + ")";
OLA_WARN << "Failed to set outgoing multicast interface to " <<
iface << ": " << strerror(errno);
iface_desc << ": " << strerror(errno);
return false;
}
return true;
Expand Down
32 changes: 17 additions & 15 deletions common/network/WindowsInterfacePicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ using std::vector;
* Return a vector of interfaces on the system.
*/
vector<Interface> WindowsInterfacePicker::GetInterfaces(
bool include_loopback) const {
bool include_loopback,
bool include_down) const {
vector<Interface> interfaces;

PIP_ADAPTER_INFO pAdapter = NULL;
Expand Down Expand Up @@ -94,22 +95,23 @@ vector<Interface> WindowsInterfacePicker::GetInterfaces(
net = inet_addr(ipAddress->IpAddress.String);
// Windows doesn't seem to have the notion of an interface being 'up'
// so we check if this interface has an address assigned.
if (net) {
Interface iface;
iface.name = pAdapter->AdapterName; // IFNAME_SIZE
iface.index = pAdapter->Index;
uint8_t macaddr[MACAddress::LENGTH];
memcpy(macaddr, pAdapter->Address, MACAddress::LENGTH);
iface.hw_address = MACAddress(macaddr);
iface.ip_address = IPV4Address(net);
if(!net && !include_down)
continue;

mask = inet_addr(ipAddress->IpMask.String);
iface.subnet_mask = IPV4Address(mask);
iface.bcast_address = IPV4Address((iface.ip_address.AsInt() & mask) |
(0xFFFFFFFF ^ mask));
Interface iface;
iface.name = pAdapter->AdapterName; // IFNAME_SIZE
iface.index = pAdapter->Index;
uint8_t macaddr[MACAddress::LENGTH];
memcpy(macaddr, pAdapter->Address, MACAddress::LENGTH);
iface.hw_address = MACAddress(macaddr);
iface.ip_address = IPV4Address(net);

interfaces.push_back(iface);
}
mask = inet_addr(ipAddress->IpMask.String);
iface.subnet_mask = IPV4Address(mask);
iface.bcast_address = IPV4Address((iface.ip_address.AsInt() & mask) |
(0xFFFFFFFF ^ mask));

interfaces.push_back(iface);
}
}
delete[] pAdapterInfo;
Expand Down
4 changes: 2 additions & 2 deletions common/network/WindowsInterfacePicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ namespace network {
*/
class WindowsInterfacePicker: public InterfacePicker {
public:
std::vector<Interface> GetInterfaces(bool include_loopback) const;
std::vector<Interface> GetInterfaces(bool include_loopback,
bool include_down) const;
};
} // namespace network
} // namespace ola
#endif // COMMON_NETWORK_WINDOWSINTERFACEPICKER_H_

2 changes: 1 addition & 1 deletion common/rdm/ResponderHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ RDMResponse *ResponderHelper::GetListInterfaces(
}

vector<Interface> interfaces =
network_manager->GetInterfacePicker()->GetInterfaces(false);
network_manager->GetInterfacePicker()->GetInterfaces(false, false);

if (interfaces.size() == 0) {
return EmptyGetResponse(request, queued_message_count);
Expand Down
17 changes: 10 additions & 7 deletions common/testing/MockUDPSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <string>

#include "ola/Logging.h"
#include "ola/network/Interface.h"
#include "ola/network/IPV4Address.h"
#include "ola/network/NetworkUtils.h"
#include "ola/testing/MockUDPSocket.h"
Expand All @@ -41,6 +42,7 @@ using ola::io::IOQueue;
using ola::io::IOVec;
using ola::io::IOVecInterface;
using ola::network::HostToNetwork;
using ola::network::Interface;
using ola::network::IPV4Address;
using ola::network::IPV4SocketAddress;

Expand Down Expand Up @@ -212,23 +214,24 @@ bool MockUDPSocket::EnableBroadcast() {
}


bool MockUDPSocket::SetMulticastInterface(const IPV4Address &iface) {
OLA_ASSERT_EQ(m_interface, iface);
bool MockUDPSocket::SetMulticastInterface(const Interface &iface) {
OLA_ASSERT_EQ(m_interface.ip_address, iface.ip_address);
OLA_ASSERT_EQ(m_interface.index, iface.index);
return true;
}


bool MockUDPSocket::JoinMulticast(const IPV4Address &iface,
bool MockUDPSocket::JoinMulticast(const IPV4Address &ip_addr,
OLA_UNUSED const IPV4Address &group,
OLA_UNUSED bool loop) {
OLA_ASSERT_EQ(m_interface, iface);
OLA_ASSERT_EQ(m_interface.ip_address, ip_addr);
return true;
}


bool MockUDPSocket::LeaveMulticast(const IPV4Address &iface,
bool MockUDPSocket::LeaveMulticast(const IPV4Address &ip_addr,
OLA_UNUSED const IPV4Address &group) {
OLA_ASSERT_EQ(m_interface, iface);
OLA_ASSERT_EQ(m_interface.ip_address, ip_addr);
return true;
}

Expand Down Expand Up @@ -318,7 +321,7 @@ bool MockUDPSocket::CheckNetworkParamsMatch(bool init_called,
}


void MockUDPSocket::SetInterface(const IPV4Address &iface) {
void MockUDPSocket::SetInterface(const Interface &iface) {
m_interface = iface;
}

Expand Down
13 changes: 11 additions & 2 deletions include/ola/network/InterfacePicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,17 @@ class InterfacePicker {
*/
bool specific_only;

/**
* If False do not return an interface if it is down on posix or has no
* address configured on windows.
*/
bool include_down;


Options()
: include_loopback(false),
specific_only(false) {
specific_only(false),
include_down(false) {
}
};

Expand All @@ -86,7 +94,8 @@ class InterfacePicker {
int32_t index,
const Options &options = Options()) const;

virtual std::vector<Interface> GetInterfaces(bool include_loopback) const = 0;
virtual std::vector<Interface> GetInterfaces(bool include_loopback,
bool include_down) const = 0;

static InterfacePicker *NewPicker();
};
Expand Down
7 changes: 4 additions & 3 deletions include/ola/network/Socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <ola/io/Descriptor.h>
#include <ola/io/IOQueue.h>
#include <ola/network/IPV4Address.h>
#include <ola/network/Interface.h>
#include <string>

namespace ola {
Expand Down Expand Up @@ -196,9 +197,9 @@ class UDPSocketInterface: public ola::io::BidirectionalFileDescriptor {

/**
* @brief Set the outgoing interface to be used for multicast transmission.
* @param iface the address of the interface to use.
* @param iface the interface to use.
*/
virtual bool SetMulticastInterface(const IPV4Address &iface) = 0;
virtual bool SetMulticastInterface(const Interface &iface) = 0;

/**
* @brief Join a multicast group
Expand Down Expand Up @@ -277,7 +278,7 @@ class UDPSocket: public UDPSocketInterface {
IPV4SocketAddress *source);

bool EnableBroadcast();
bool SetMulticastInterface(const IPV4Address &iface);
bool SetMulticastInterface(const Interface &iface);
bool JoinMulticast(const IPV4Address &iface,
const IPV4Address &group,
bool multicast_loop = false);
Expand Down
7 changes: 4 additions & 3 deletions include/ola/testing/MockUDPSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <cppunit/extensions/HelperMacros.h>

#include <ola/base/Macro.h>
#include <ola/network/Interface.h>
#include <ola/network/IPV4Address.h>
#include <ola/network/Socket.h>
#include <ola/network/SocketAddress.h>
Expand Down Expand Up @@ -94,7 +95,7 @@ class MockUDPSocket: public ola::network::UDPSocketInterface {
ssize_t *data_read,
ola::network::IPV4SocketAddress *source);
bool EnableBroadcast();
bool SetMulticastInterface(const ola::network::IPV4Address &iface);
bool SetMulticastInterface(const ola::network::Interface &iface);
bool JoinMulticast(const ola::network::IPV4Address &iface,
const ola::network::IPV4Address &group,
bool multicast_loop = false);
Expand Down Expand Up @@ -131,7 +132,7 @@ class MockUDPSocket: public ola::network::UDPSocketInterface {
uint16_t port,
bool broadcast_set);

void SetInterface(const ola::network::IPV4Address &iface);
void SetInterface(const ola::network::Interface &iface);

private:
typedef struct {
Expand All @@ -154,7 +155,7 @@ class MockUDPSocket: public ola::network::UDPSocketInterface {
uint8_t m_tos;
mutable std::queue<expected_call> m_expected_calls;
mutable std::queue<received_data> m_received_data;
ola::network::IPV4Address m_interface;
ola::network::Interface m_interface;
bool m_discard_mode;

uint8_t* IOQueueToBuffer(ola::io::IOQueue *ioqueue,
Expand Down
11 changes: 9 additions & 2 deletions libs/acn/E131Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,16 @@ E131Node::~E131Node() {


bool E131Node::Start() {


ola::network::InterfacePicker::Options opts;
opts.include_loopback = false;
opts.specific_only = m_options.force_interface;
opts.include_down = m_options.force_interface;

auto_ptr<ola::network::InterfacePicker> picker(
ola::network::InterfacePicker::NewPicker());
if (!picker->ChooseInterface(&m_interface, m_preferred_ip)) {
if (!picker->ChooseInterface(&m_interface, m_preferred_ip, opts)) {
OLA_INFO << "Failed to find an interface";
return false;
}
Expand All @@ -181,7 +188,7 @@ bool E131Node::Start() {
}

m_socket.SetTos(m_options.dscp);
m_socket.SetMulticastInterface(m_interface.ip_address);
m_socket.SetMulticastInterface(m_interface);

m_socket.SetOnData(NewCallback(&m_incoming_udp_transport,
&IncomingUDPTransport::Receive));
Expand Down
2 changes: 2 additions & 0 deletions libs/acn/E131Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class E131Node {
: use_rev2(false),
ignore_preview(true),
enable_draft_discovery(false),
force_interface(false),
dscp(0),
port(ola::acn::ACN_PORT),
source_name(ola::OLA_DEFAULT_INSTANCE_NAME) {
Expand All @@ -66,6 +67,7 @@ class E131Node {
bool use_rev2; /**< Use Revision 0.2 of the 2009 draft */
bool ignore_preview; /**< Ignore preview data */
bool enable_draft_discovery; /**< Enable 2014 draft discovery */
bool force_interface;
uint8_t dscp; /**< The DSCP value to tag packets with */
uint16_t port; /**< The UDP port to use, defaults to ACN_PORT */
std::string source_name; /**< The source name to use */
Expand Down
Loading