add a secondary check for local IP address

This commit is contained in:
Stephen Birarda 2016-03-07 18:00:09 -08:00
parent 5078f486b1
commit ed9faf4189
6 changed files with 71 additions and 17 deletions

View file

@ -981,7 +981,7 @@ void OctreeServer::readConfiguration() {
_settings = settingsSectionObject; // keep this for later
if (!readOptionString(QString("statusHost"), settingsSectionObject, _statusHost) || _statusHost.isEmpty()) {
_statusHost = getLocalAddress().toString();
_statusHost = getGuessedLocalAddress().toString();
}
qDebug("statusHost=%s", qPrintable(_statusHost));

View file

@ -32,7 +32,7 @@ static const uint64_t MAX_LOG_AGE_USECS = USECS_PER_SECOND * 3600;
QString getLogRollerFilename() {
QString result = FileUtils::standardPath(LOGS_DIRECTORY);
QHostAddress clientAddress = getLocalAddress();
QHostAddress clientAddress = getGuessedLocalAddress();
QDateTime now = QDateTime::currentDateTime();
result.append(QString(FILENAME_FORMAT).arg(clientAddress.toString(), now.toString(DATETIME_FORMAT)));
return result;

View file

@ -124,7 +124,7 @@ QDataStream& operator>>(QDataStream& dataStream, HifiSockAddr& sockAddr) {
return dataStream;
}
QHostAddress getLocalAddress() {
QHostAddress getGuessedLocalAddress() {
QHostAddress localAddress;

View file

@ -92,7 +92,7 @@ namespace std {
}
QHostAddress getLocalAddress();
QHostAddress getGuessedLocalAddress();
Q_DECLARE_METATYPE(HifiSockAddr);

View file

@ -77,7 +77,7 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short
// check for local socket updates every so often
const int LOCAL_SOCKET_UPDATE_INTERVAL_MSECS = 5 * 1000;
QTimer* localSocketUpdate = new QTimer(this);
connect(localSocketUpdate, &QTimer::timeout, this, &LimitedNodeList::updateLocalSockAddr);
connect(localSocketUpdate, &QTimer::timeout, this, &LimitedNodeList::updateLocalSocket);
localSocketUpdate->start(LOCAL_SOCKET_UPDATE_INTERVAL_MSECS);
QTimer* silentNodeTimer = new QTimer(this);
@ -85,7 +85,7 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short
silentNodeTimer->start(NODE_SILENCE_THRESHOLD_MSECS);
// check the local socket right now
updateLocalSockAddr();
updateLocalSocket();
// set &PacketReceiver::handleVerifiedPacket as the verified packet callback for the udt::Socket
_nodeSocket.setPacketHandler(
@ -886,17 +886,66 @@ void LimitedNodeList::stopInitialSTUNUpdate(bool success) {
stunOccasionalTimer->start(STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS);
}
void LimitedNodeList::updateLocalSockAddr() {
HifiSockAddr newSockAddr(getLocalAddress(), _nodeSocket.localPort());
if (newSockAddr != _localSockAddr) {
void LimitedNodeList::updateLocalSocket() {
// when update is called, if the local socket is empty then start with the guessed local socket
if (_localSockAddr.isNull()) {
setLocalSocket(HifiSockAddr { getGuessedLocalAddress(), _nodeSocket.localPort() });
}
if (_localSockAddr.isNull()) {
qCDebug(networking) << "Local socket is" << newSockAddr;
} else {
qCDebug(networking) << "Local socket has changed from" << _localSockAddr << "to" << newSockAddr;
// attempt to use Google's DNS to confirm that local IP
static const QHostAddress RELIABLE_LOCAL_IP_CHECK_HOST = QHostAddress { "8.8.8.8" };
static const int RELIABLE_LOCAL_IP_CHECK_PORT = 53;
QTcpSocket* localIPTestSocket = new QTcpSocket;
connect(localIPTestSocket, &QTcpSocket::connected, this, &LimitedNodeList::connectedForLocalSocketTest);
connect(localIPTestSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(errorTestingLocalSocket(QAbstractSocket::SocketError)));
// attempt to connect to our reliable host
localIPTestSocket->connectToHost(RELIABLE_LOCAL_IP_CHECK_HOST, RELIABLE_LOCAL_IP_CHECK_PORT);
}
void LimitedNodeList::connectedForLocalSocketTest() {
auto localIPTestSocket = qobject_cast<QTcpSocket*>(sender());
if (localIPTestSocket) {
auto localHostAddress = localIPTestSocket->localAddress();
if (localHostAddress.protocol() == QAbstractSocket::IPv4Protocol) {
_hasTCPCheckedLocalSocket = true;
setLocalSocket(HifiSockAddr { localHostAddress, _nodeSocket.localPort() });
}
_localSockAddr = newSockAddr;
localIPTestSocket->deleteLater();
}
}
void LimitedNodeList::errorTestingLocalSocket(QAbstractSocket::SocketError error) {
auto localIPTestSocket = qobject_cast<QTcpSocket*>(sender());
qDebug() << sender() << error;
if (localIPTestSocket) {
// error connecting to the test socket - if we've never set our local socket using this test socket
// then use our possibly updated guessed local address as fallback
if (!_hasTCPCheckedLocalSocket) {
setLocalSocket(HifiSockAddr { getGuessedLocalAddress(), _nodeSocket.localPort() });
}
localIPTestSocket->deleteLater();;
}
}
void LimitedNodeList::setLocalSocket(const HifiSockAddr& sockAddr) {
if (sockAddr != _localSockAddr) {
if (_localSockAddr.isNull()) {
qCInfo(networking) << "Local socket is" << sockAddr;
} else {
qCInfo(networking) << "Local socket has changed from" << _localSockAddr << "to" << sockAddr;
}
_localSockAddr = sockAddr;
emit localSockAddrChanged(_localSockAddr);
}

View file

@ -225,7 +225,7 @@ public slots:
void removeSilentNodes();
void updateLocalSockAddr();
void updateLocalSocket();
void startSTUNPublicSocketUpdate();
virtual void sendSTUNRequest();
@ -247,6 +247,10 @@ signals:
void isAllowedEditorChanged(bool isAllowedEditor);
void canRezChanged(bool canRez);
protected slots:
void connectedForLocalSocketTest();
void errorTestingLocalSocket(QAbstractSocket::SocketError error);
protected:
LimitedNodeList(unsigned short socketListenPort = 0, unsigned short dtlsListenPort = 0);
LimitedNodeList(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton
@ -258,6 +262,8 @@ protected:
const QUuid& connectionSecret = QUuid());
void collectPacketStats(const NLPacket& packet);
void fillPacketHeader(const NLPacket& packet, const QUuid& connectionSecret = QUuid());
void setLocalSocket(const HifiSockAddr& sockAddr);
bool isPacketVerified(const udt::Packet& packet);
bool packetVersionMatch(const udt::Packet& packet);
@ -271,8 +277,6 @@ protected:
void sendPacketToIceServer(PacketType packetType, const HifiSockAddr& iceServerSockAddr, const QUuid& clientID,
const QUuid& peerRequestID = QUuid());
QUuid _sessionUUID;
NodeHash _nodeHash;
QReadWriteLock _nodeMutex;
@ -281,6 +285,7 @@ protected:
HifiSockAddr _localSockAddr;
HifiSockAddr _publicSockAddr;
HifiSockAddr _stunSockAddr;
bool _hasTCPCheckedLocalSocket { false };
PacketReceiver* _packetReceiver;