Skip to content
Snippets Groups Projects
Commit 50f7674b authored by Gus Grubba's avatar Gus Grubba
Browse files

Fixed wrong logic when testing _socket for wrtites. It was never writing (sending anything).

Work around a new Windows issue where the call to list the local network interfaces takes for freaking ever to return, blocking the UDP thread altogether.
parent 83030ca6
No related branches found
No related tags found
No related merge requests found
...@@ -68,27 +68,6 @@ static QString get_ip_address(const QString& address) ...@@ -68,27 +68,6 @@ static QString get_ip_address(const QString& address)
return QString(""); return QString("");
} }
static bool is_ip_local(const QHostAddress& add)
{
// In simulation and testing setups the vehicle and the GCS can be
// running on the same host. This leads to packets arriving through
// the local network or the loopback adapter, which makes it look
// like the vehicle is connected through two different links,
// complicating routing.
//
// We detect this case and force all traffic to a simulated instance
// onto the local loopback interface.
// Run through all IPv4 interfaces and check if their canonical
// IP address in string representation matches the source IP address
foreach (const QHostAddress &address, QNetworkInterface::allAddresses()) {
if (address == add) {
// This is a local address of the same host
return true;
}
}
return false;
}
static bool contains_target(const QList<UDPCLient*> list, const QHostAddress& address, quint16 port) static bool contains_target(const QList<UDPCLient*> list, const QHostAddress& address, quint16 port)
{ {
foreach(UDPCLient* target, list) { foreach(UDPCLient* target, list) {
...@@ -112,6 +91,9 @@ UDPLink::UDPLink(SharedLinkConfigurationPointer& config) ...@@ -112,6 +91,9 @@ UDPLink::UDPLink(SharedLinkConfigurationPointer& config)
if (!_udpConfig) { if (!_udpConfig) {
qWarning() << "Internal error"; qWarning() << "Internal error";
} }
foreach (const QHostAddress &address, QNetworkInterface::allAddresses()) {
_localAddress.append(QHostAddress(address));
}
moveToThread(this); moveToThread(this);
} }
...@@ -158,10 +140,36 @@ QString UDPLink::getName() const ...@@ -158,10 +140,36 @@ QString UDPLink::getName() const
return _udpConfig->name(); return _udpConfig->name();
} }
bool UDPLink::_isIpLocal(const QHostAddress& add)
{
// In simulation and testing setups the vehicle and the GCS can be
// running on the same host. This leads to packets arriving through
// the local network or the loopback adapter, which makes it look
// like the vehicle is connected through two different links,
// complicating routing.
//
// We detect this case and force all traffic to a simulated instance
// onto the local loopback interface.
// Run through all IPv4 interfaces and check if their canonical
// IP address in string representation matches the source IP address
//
// On Windows, this is a very expensive call only Redmond would know
// why. As such, we make it once and keep the list locally. If a new
// interface shows up after we start, it won't be on this list.
foreach (const QHostAddress &address, _localAddress) {
if (address == add) {
// This is a local address of the same host
return true;
}
}
return false;
}
void UDPLink::_writeBytes(const QByteArray data) void UDPLink::_writeBytes(const QByteArray data)
{ {
if (!_socket) if (!_socket) {
return; return;
}
// Send to all manually targeted systems // Send to all manually targeted systems
foreach(UDPCLient* target, _udpConfig->targetHosts()) { foreach(UDPCLient* target, _udpConfig->targetHosts()) {
// Skip it if it's part of the session clients below // Skip it if it's part of the session clients below
...@@ -177,6 +185,7 @@ void UDPLink::_writeBytes(const QByteArray data) ...@@ -177,6 +185,7 @@ void UDPLink::_writeBytes(const QByteArray data)
void UDPLink::_writeDataGram(const QByteArray data, const UDPCLient* target) void UDPLink::_writeDataGram(const QByteArray data, const UDPCLient* target)
{ {
//qDebug() << "UDP Out" << target->address << target->port;
if(_socket->writeDatagram(data, target->address, target->port) < 0) { if(_socket->writeDatagram(data, target->address, target->port) < 0) {
qWarning() << "Error writing to" << target->address << target->port; qWarning() << "Error writing to" << target->address << target->port;
} else { } else {
...@@ -193,10 +202,9 @@ void UDPLink::_writeDataGram(const QByteArray data, const UDPCLient* target) ...@@ -193,10 +202,9 @@ void UDPLink::_writeDataGram(const QByteArray data, const UDPCLient* target)
**/ **/
void UDPLink::readBytes() void UDPLink::readBytes()
{ {
if (_socket) { if (!_socket) {
return; return;
} }
QByteArray databuffer; QByteArray databuffer;
while (_socket->hasPendingDatagrams()) while (_socket->hasPendingDatagrams())
{ {
...@@ -204,6 +212,7 @@ void UDPLink::readBytes() ...@@ -204,6 +212,7 @@ void UDPLink::readBytes()
datagram.resize(_socket->pendingDatagramSize()); datagram.resize(_socket->pendingDatagramSize());
QHostAddress sender; QHostAddress sender;
quint16 senderPort; quint16 senderPort;
//-- Note: This call is broken in Qt 5.9.3 on Windows. It always returns a blank sender and 0 for the port.
_socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); _socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
databuffer.append(datagram); databuffer.append(datagram);
//-- Wait a bit before sending it over //-- Wait a bit before sending it over
...@@ -217,7 +226,7 @@ void UDPLink::readBytes() ...@@ -217,7 +226,7 @@ void UDPLink::readBytes()
// would trigger this. // would trigger this.
// Add host to broadcast list if not yet present, or update its port // Add host to broadcast list if not yet present, or update its port
QHostAddress asender = sender; QHostAddress asender = sender;
if(is_ip_local(sender)) { if(_isIpLocal(sender)) {
asender = QHostAddress(QString("127.0.0.1")); asender = QHostAddress(QString("127.0.0.1"));
} }
if(!contains_target(_sessionTargets, asender, senderPort)) { if(!contains_target(_sessionTargets, asender, senderPort)) {
......
...@@ -184,6 +184,7 @@ private: ...@@ -184,6 +184,7 @@ private:
bool _connect (void) override; bool _connect (void) override;
void _disconnect (void) override; void _disconnect (void) override;
bool _isIpLocal (const QHostAddress& add);
bool _hardwareConnect (); bool _hardwareConnect ();
void _restartConnection (); void _restartConnection ();
void _registerZeroconf (uint16_t port, const std::string& regType); void _registerZeroconf (uint16_t port, const std::string& regType);
...@@ -199,6 +200,7 @@ private: ...@@ -199,6 +200,7 @@ private:
UDPConfiguration* _udpConfig; UDPConfiguration* _udpConfig;
bool _connectState; bool _connectState;
QList<UDPCLient*> _sessionTargets; QList<UDPCLient*> _sessionTargets;
QList<QHostAddress> _localAddress;
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment