Feature: Ostinato client now accepts hostnames for drones and does DNS resolution for the same; IPv6 addresses are also accepted. Introduced Drone setting to listen to specific or 'any' IPv4 (or IPv6) address

Fixes #152
This commit is contained in:
Srivats P 2015-11-06 18:57:07 +05:30
parent 01e8524491
commit efdfa7f95d
10 changed files with 65 additions and 30 deletions

View File

@ -37,7 +37,7 @@ extern char *version;
quint32 PortGroup::mPortGroupAllocId = 0;
PortGroup::PortGroup(QHostAddress ip, quint16 port)
PortGroup::PortGroup(QString serverName, quint16 port)
{
// Allocate an id for self
mPortGroupId = PortGroup::mPortGroupAllocId++;
@ -57,7 +57,7 @@ PortGroup::PortGroup(QHostAddress ip, quint16 port)
connect(reconnectTimer, SIGNAL(timeout()),
this, SLOT(on_reconnectTimer_timeout()));
rpcChannel = new PbRpcChannel(ip, port,
rpcChannel = new PbRpcChannel(serverName, port,
OstProto::Notification::default_instance());
serviceStub = new OstProto::OstService::Stub(rpcChannel);
@ -272,7 +272,7 @@ void PortGroup::when_portListChanged(quint32 /*portGroupId*/)
"For more information see "
"http://code.google.com/p/ostinato/wiki/FAQ#"
"Q._Port_group_has_no_interfaces")
.arg(serverAddress().toString())
.arg(serverName())
.arg(int(serverPort())));
}
}

View File

@ -66,7 +66,7 @@ public: // FIXME(HIGH): member access
QList<Port*> mPorts;
public:
PortGroup(QHostAddress ip = QHostAddress::LocalHost,
PortGroup(QString serverName = "127.0.0.1",
quint16 port = DEFAULT_SERVER_PORT);
~PortGroup();
@ -75,10 +75,10 @@ public:
compat = kUnknown;
rpcChannel->establish();
}
void connectToHost(QHostAddress ip, quint16 port) {
void connectToHost(QString serverName, quint16 port) {
reconnect = true;
compat = kUnknown;
rpcChannel->establish(ip, port);
rpcChannel->establish(serverName, port);
}
void disconnectFromHost() { reconnect = false; rpcChannel->tearDown(); }
@ -88,8 +88,8 @@ public:
const QString& userAlias() const { return mUserAlias; }
void setUserAlias(QString alias) { mUserAlias = alias; };
const QHostAddress& serverAddress() const
{ return rpcChannel->serverAddress(); }
const QString serverName() const
{ return rpcChannel->serverName(); }
quint16 serverPort() const
{ return rpcChannel->serverPort(); }
QAbstractSocket::SocketState state() const {

View File

@ -121,10 +121,10 @@ QVariant PortModel::data(const QModelIndex &index, int role) const
if ((role == Qt::DisplayRole))
{
DBG0("Exit PortModel data 1\n");
return QString("Port Group %1: %2 [%3:%4] (%5)").
return QString("Port Group %1: %2 [%3]:%4 (%5)").
arg(pgl->mPortGroups.at(index.row())->id()).
arg(pgl->mPortGroups.at(index.row())->userAlias()).
arg(pgl->mPortGroups.at(index.row())->serverAddress().toString()).
arg(pgl->mPortGroups.at(index.row())->serverName()).
arg(pgl->mPortGroups.at(index.row())->serverPort()).
arg(pgl->mPortGroups.value(index.row())->numPorts());
}

View File

@ -503,15 +503,29 @@ void PortsWindow::on_actionNew_Port_Group_triggered()
{
bool ok;
QString text = QInputDialog::getText(this,
"Add Port Group", "Port Group Address (IP[:Port])",
"Add Port Group", "Port Group Address (HostName[:Port])",
QLineEdit::Normal, lastNewPortGroup, &ok);
if (ok)
{
QStringList addr = text.split(":");
if (addr.size() == 1) // Port unspecified
addr.append(QString().setNum(DEFAULT_SERVER_PORT));
PortGroup *pg = new PortGroup(QHostAddress(addr[0]),addr[1].toUShort());
quint16 port = DEFAULT_SERVER_PORT;
if (addr.size() > 2) { // IPv6 Address
// IPv6 addresses with port number SHOULD be specified as
// [2001:db8::1]:80 (RFC5952 Sec6) to avoid ambiguity due to ':'
addr = text.split("]:");
if (addr.size() > 1)
port = addr[1].toUShort();
}
else if (addr.size() == 2) // Hostname/IPv4 + Port specified
port = addr[1].toUShort();
// Play nice and remove square brackets irrespective of addr type
addr[0].remove(QChar('['));
addr[0].remove(QChar(']'));
PortGroup *pg = new PortGroup(addr[0], port);
plm->addPortGroup(*pg);
lastNewPortGroup = text;
}

View File

@ -25,7 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
static uchar msgBuf[4096];
PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port,
PbRpcChannel::PbRpcChannel(QString serverName, quint16 port,
const ::google::protobuf::Message &notifProto)
: notifPrototype(notifProto)
{
@ -36,7 +36,7 @@ PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port,
done = NULL;
response = NULL;
mServerAddress = ip;
mServerHost = serverName;
mServerPort = port;
mpSocket = new QTcpSocket(this);
@ -75,12 +75,12 @@ void PbRpcChannel::establish()
{
qDebug("In %s", __FUNCTION__);
mpSocket->connectToHost(mServerAddress, mServerPort);
mpSocket->connectToHost(mServerHost, mServerPort);
}
void PbRpcChannel::establish(QHostAddress ip, quint16 port)
void PbRpcChannel::establish(QString serverName, quint16 port)
{
mServerAddress = ip;
mServerHost = serverName;
mServerPort = port;
establish();
}

View File

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#ifndef _PB_RPC_CHANNEL_H
#define _PB_RPC_CHANNEL_H
#include <QString>
#include <QTcpServer>
#include <QTcpSocket>
@ -64,7 +65,7 @@ class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel
const ::google::protobuf::Message &notifPrototype;
::google::protobuf::Message *notif;
QHostAddress mServerAddress;
QString mServerHost;
quint16 mServerPort;
QTcpSocket *mpSocket;
@ -72,15 +73,18 @@ class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel
::google::protobuf::io::CopyingOutputStreamAdaptor *outStream;
public:
PbRpcChannel(QHostAddress ip, quint16 port,
PbRpcChannel(QString serverName, quint16 port,
const ::google::protobuf::Message &notifProto);
~PbRpcChannel();
void establish();
void establish(QHostAddress ip, quint16 port);
void establish(QString serverName, quint16 port);
void tearDown();
const QHostAddress& serverAddress() const { return mServerAddress; }
const QString serverName() const
{
return mpSocket->peerName();
}
quint16 serverPort() const { return mServerPort; }
QAbstractSocket::SocketState state() const

View File

@ -42,14 +42,15 @@ RpcServer::~RpcServer()
{
}
bool RpcServer::registerService(::google::protobuf::Service *service,
quint16 tcpPortNum)
bool RpcServer::registerService(::google::protobuf::Service *service,
QHostAddress address, quint16 tcpPortNum)
{
this->service = service;
if (!listen(QHostAddress::Any, tcpPortNum))
if (!listen(address, tcpPortNum))
{
qDebug("Unable to start the server: %s",
qDebug("Unable to start the server on <%s>: %s",
qPrintable(address.toString()),
errorString().toAscii().constData());
return false;
}

View File

@ -41,7 +41,7 @@ public:
virtual ~RpcServer();
bool registerService(::google::protobuf::Service *service,
quint16 tcpPortNum);
QHostAddress address, quint16 tcpPortNum);
signals:
void notifyClients(int notifType, SharedProtobufMessage notifData);

View File

@ -19,8 +19,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "drone.h"
#include "rpcserver.h"
#include "myservice.h"
#include "rpcserver.h"
#include "settings.h"
#include <QMetaType>
@ -43,11 +44,21 @@ Drone::~Drone()
bool Drone::init()
{
QString addr = appSettings->value(kRpcServerAddress).toString();
QHostAddress address = addr.isEmpty() ?
QHostAddress::Any : QHostAddress(addr);
Q_ASSERT(rpcServer);
qRegisterMetaType<SharedProtobufMessage>("SharedProtobufMessage");
if (!rpcServer->registerService(service, myport ? myport : 7878))
if (address.isNull()) {
qWarning("Invalid RpcServer Address <%s> specified. Using 'Any'",
qPrintable(addr));
address = QHostAddress::Any;
}
if (!rpcServer->registerService(service, address, myport ? myport : 7878))
{
//qCritical(qPrintable(rpcServer->errorString()));
return false;

View File

@ -31,6 +31,11 @@ extern QSettings *appSettings;
const QString kRateAccuracyKey("RateAccuracy");
const QString kRateAccuracyDefaultValue("High");
//
// RpcServer Section Keys
//
const QString kRpcServerAddress("RpcServer/Address");
//
// PortList Section Keys
//