Skip to content

Commit 33661cf

Browse files
committed
Adding loopback interface support
1 parent fe026b0 commit 33661cf

File tree

6 files changed

+38
-6
lines changed

6 files changed

+38
-6
lines changed

src/command_line.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ void CommandLine::parse(int argc, char * argv[]) {
274274
handler([this](std::string_view val){
275275
this->sourcePort = Argum::parseIntegral<unsigned>(val);
276276
}));
277+
parser.add(Option("--enable-loopback").
278+
help("enable receiving/sending on loopback interface.").
279+
handler([this]() {
280+
this->enableLoopback = true;
281+
}));
277282

278283
//Machine info
279284
parser.add(Option("--uuid").
@@ -432,6 +437,12 @@ void CommandLine::parseConfigKey(std::string_view keyName, const toml::node & va
432437
this->sourcePort = uint16_t(*val);
433438
});
434439

440+
} else if (keyName == "enable-loopback"sv) {
441+
442+
setConfigValue<bool>(bool(this->enableLoopback), keyName, value, [this](const toml::value<bool> & val) {
443+
this->enableLoopback = *val;
444+
});
445+
435446
} else
436447

437448
//Machine info

src/command_line.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct CommandLine {
1515
std::optional<AllowedAddressFamily> allowedAddressFamily;
1616
std::optional<int> hoplimit;
1717
std::optional<uint16_t> sourcePort;
18+
std::optional<bool> enableLoopback;
1819

1920
std::optional<Uuid> uuid;
2021
std::optional<sys_string> hostname;

src/config.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Config::Config(const CommandLine & cmdline):
1212
m_allowedAddressFamily = cmdline.allowedAddressFamily.value_or(BothIPv4AndIPv6);
1313
m_interfaceWhitelist.insert(cmdline.interfaces.begin(), cmdline.interfaces.end());
1414
m_sourcePort = cmdline.sourcePort.value_or(0);
15+
m_enableLoopback = cmdline.enableLoopback.value_or(false);
1516

1617
m_fullHostName = getHostName();
1718
m_simpleHostName = m_fullHostName.prefix_before_first(U'.').value_or(m_fullHostName);

src/config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Config : public ref_counted<Config> {
4848
auto enableIPv4() const -> bool { return m_allowedAddressFamily != IPv6Only; }
4949
auto enableIPv6() const -> bool { return m_allowedAddressFamily != IPv4Only; }
5050
auto hopLimit() const -> int { return m_hopLimit; }
51+
auto enableLoopback() const -> bool { return m_enableLoopback; }
5152
auto isAllowedInterface(const sys_string & name) const -> bool {
5253
return m_interfaceWhitelist.empty() || m_interfaceWhitelist.contains(name);
5354
}
@@ -82,6 +83,7 @@ class Config : public ref_counted<Config> {
8283
int m_hopLimit = 1;
8384
std::set<sys_string> m_interfaceWhitelist;
8485
uint16_t m_sourcePort;
86+
bool m_enableLoopback;
8587

8688
size_t m_pageSize;
8789
};

src/interface_monitor_bsd.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class InterfaceMonitorImpl : public InterfaceMonitor {
118118
sys_string name(req.lifr_name);
119119

120120
auto interfaceFlags = ioctlSocket<GetLInterfaceFlags>(m_socket, name).value();
121-
if ((interfaceFlags & IFF_LOOPBACK) || !(interfaceFlags & IFF_MULTICAST))
121+
if (isUnusableInterface(interfaceFlags))
122122
continue;
123123
auto index = ioctlSocket<GetLInterfaceIndex>(m_socket, name).value();
124124
m_handler->addAddress(NetworkInterface(index, name), addr);
@@ -204,7 +204,7 @@ class InterfaceMonitorImpl : public InterfaceMonitor {
204204
}
205205

206206
if (header->rtm_type == RTM_IFINFO) {
207-
knownIfaces[result.iface->index] = (interfaceFlags & IFF_LOOPBACK) || !(interfaceFlags & IFF_MULTICAST);
207+
knownIfaces[result.iface->index] = isUnusableInterface(interfaceFlags);
208208
} else {
209209
if (auto it = knownIfaces.find(result.iface->index); it == knownIfaces.end()) {
210210
#if HAVE_SIOCGLIFCONF
@@ -214,7 +214,7 @@ class InterfaceMonitorImpl : public InterfaceMonitor {
214214
#endif
215215
if (auto flagsRes = ioctlSocket<GetInterfaceFlagsType>(m_socket, result.iface->name)) {
216216
interfaceFlags = flagsRes.assume_value();
217-
bool ignore = (interfaceFlags & IFF_LOOPBACK) || !(interfaceFlags & IFF_MULTICAST);
217+
bool ignore = isUnusableInterface(interfaceFlags);
218218
knownIfaces.emplace(result.iface->index, ignore);
219219
}
220220
}
@@ -288,17 +288,29 @@ class InterfaceMonitorImpl : public InterfaceMonitor {
288288
ignore = it->second;
289289
}
290290

291-
if (!ignore)
291+
if (!ignore) {
292292
m_handler->addAddress(iface, addr);
293-
else
293+
} else if (m_config->enableLoopback()) {
294+
WSDLOG_DEBUG("Interface {} doesn't support multicast - ignoring", iface);
295+
} else {
294296
WSDLOG_DEBUG("Interface {} is loopback or doesn't support multicast - ignoring", iface);
297+
}
295298

296299
} else {
297300

298301
m_handler->removeAddress(iface, addr);
299302
}
300303
}
301304

305+
template<class T>
306+
bool isUnusableInterface(T interfaceFlags) {
307+
bool res = !(interfaceFlags & IFF_MULTICAST);
308+
if (!res && !m_config->enableLoopback()) {
309+
res = (interfaceFlags & IFF_LOOPBACK);
310+
}
311+
return res;
312+
}
313+
302314
private:
303315
const refcnt_ptr<Config> m_config;
304316
Handler * m_handler = nullptr;

src/interface_monitor_linux.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,10 @@ class InterfaceMonitorImpl : public InterfaceMonitor {
226226
if (auto it = knownIfaces.find(iface.index); it == knownIfaces.end()) {
227227
if (auto flagsRes = ioctlSocket<GetInterfaceFlags>(m_socket, iface.name)) {
228228
auto flags = flagsRes.assume_value();
229-
ignore = (flags & IFF_LOOPBACK) || !(flags & IFF_MULTICAST);
229+
ignore = !(interfaceFlags & IFF_MULTICAST);
230+
if (!ignore && !m_config->enableLoopback()) {
231+
ignore = (interfaceFlags & IFF_LOOPBACK);
232+
}
230233
knownIfaces[iface.index] = ignore;
231234
} else {
232235
WSDLOG_ERROR("Unable to obtain flags for interface {0}, {1}", iface, flagsRes.assume_error().message());
@@ -237,6 +240,8 @@ class InterfaceMonitorImpl : public InterfaceMonitor {
237240

238241
if (!ignore)
239242
m_handler->addAddress(iface, addr);
243+
else if (m_config->enableLoopback())
244+
WSDLOG_DEBUG("Interface {} doesn't support multicast - ignoring", iface);
240245
else
241246
WSDLOG_DEBUG("Interface {} is loopback or doesn't support multicast - ignoring", iface);
242247
} else {

0 commit comments

Comments
 (0)