Skip to content

Commit 0ecae0e

Browse files
committed
Update inlet protocol (IPv4/IPv6) on reconnection. Issue found by @mgrivich
1 parent 8ba9285 commit 0ecae0e

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

src/inlet_connection.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
using namespace lsl;
1616
namespace ip = asio::ip;
17+
1718
inlet_connection::inlet_connection(const stream_info_impl &info, bool recover)
1819
: type_info_(info), host_info_(info), tcp_protocol_(tcp::v4()), udp_protocol_(udp::v4()),
1920
recovery_enabled_(recover), lost_(false), shutdown_(false), last_receive_time_(lsl_clock()),
@@ -28,19 +29,7 @@ inlet_connection::inlet_connection(const stream_info_impl &info, bool recover)
2829
") uses a newer protocol version than this inlet. Please update.");
2930

3031
// select TCP/UDP protocol versions
31-
if (api_config::get_instance()->allow_ipv6()) {
32-
// if IPv6 is optionally allowed...
33-
if (host_info_.v4address().empty() || !host_info_.v4data_port() ||
34-
!host_info_.v4service_port()) {
35-
// then use it but only iff there are problems with the IPv4 connection data
36-
tcp_protocol_ = tcp::v6();
37-
udp_protocol_ = udp::v6();
38-
} else {
39-
// (otherwise stick to IPv4)
40-
tcp_protocol_ = tcp::v4();
41-
udp_protocol_ = udp::v4();
42-
}
43-
} else {
32+
if (!set_protocols(info, false)) {
4433
// otherwise use the protocol type that is selected in the config
4534
tcp_protocol_ = api_config::get_instance()->allow_ipv4() ? tcp::v4() : tcp::v6();
4635
udp_protocol_ = api_config::get_instance()->allow_ipv4() ? udp::v4() : udp::v6();
@@ -54,7 +43,6 @@ inlet_connection::inlet_connection(const stream_info_impl &info, bool recover)
5443
host_info_.name().c_str());
5544
recovery_enabled_ = false;
5645
}
57-
5846
} else {
5947
// the actual endpoint is not known yet -- we need to discover it later on the fly
6048
// check that all the necessary information for this has been fully specified
@@ -202,6 +190,10 @@ void inlet_connection::try_recover() {
202190
// ensure that the query result is unique (since someone might have used a
203191
// non-unique stream ID)
204192
if (infos.size() == 1) {
193+
// update the protocols from the stream info,
194+
// preferring IPv6 if previously used as well
195+
if (!set_protocols(infos[0], tcp_protocol_ == tcp::v6()))
196+
throw std::logic_error("No suitable protocol found in discovery");
205197
// update the endpoint
206198
host_info_ = infos[0];
207199
// cancel all cancellable operations registered with this connection
@@ -236,6 +228,23 @@ void inlet_connection::try_recover() {
236228
}
237229
}
238230

231+
bool inlet_connection::set_protocols(const stream_info_impl &info, bool prefer_v6) {
232+
bool has_v4 = !info.v4address().empty() && info.v4data_port() && info.v4service_port();
233+
bool has_v6 = !info.v6address().empty() && info.v6data_port() && info.v6service_port();
234+
bool can_v4 = api_config::get_instance()->allow_ipv4() && has_v4;
235+
bool can_v6 = api_config::get_instance()->allow_ipv6() && has_v6;
236+
if ((prefer_v6 && can_v6) || !can_v4) {
237+
tcp_protocol_ = tcp::v6();
238+
udp_protocol_ = udp::v6();
239+
return true;
240+
} else if (can_v4) {
241+
tcp_protocol_ = tcp::v4();
242+
udp_protocol_ = udp::v4();
243+
return true;
244+
}
245+
return false;
246+
}
247+
239248
void inlet_connection::watchdog_thread() {
240249
loguru::set_thread_name((std::string("W_") += type_info().name().substr(0, 12)).c_str());
241250
while (!lost_ && !shutdown_) {

src/inlet_connection.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ class inlet_connection : public cancellable_registry {
156156
/// A (potentially speculative) resolve-and-recover operation.
157157
void try_recover();
158158

159+
/// Sets the endpoints from a stream info considering a previous connection
160+
bool set_protocols(const stream_info_impl &info, bool prefer_v6);
161+
159162
// core connection properties
160163
/// static/read-only information of the stream (type & format)
161164
const stream_info_impl type_info_;

0 commit comments

Comments
 (0)