Skip to content

Commit

Permalink
libdeng2: Improved Beacon to include server's listening port in message
Browse files Browse the repository at this point in the history
This allows Beacon to identify a server fully at the lowest level.
  • Loading branch information
skyjake committed Feb 4, 2013
1 parent 45817b6 commit 47e2daa
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 20 deletions.
11 changes: 8 additions & 3 deletions doomsday/client/src/network/sys_network.cpp
Expand Up @@ -106,7 +106,7 @@ static foundhost_t located;

#ifdef __SERVER__
// Beacon for informing clients that a server is present.
static de::Beacon beacon(53209);
static de::Beacon beacon(13209);
#endif

void N_Register(void)
Expand Down Expand Up @@ -155,6 +155,11 @@ void N_IPToString(char *buf, ipaddress_t *ip)
sprintf(buf, "%s:%i", ip->host, ip->port);
}

de::duint16 N_ServerPort()
{
return (!nptIPPort ? defaultTCPPort : nptIPPort);
}

/**
* Initialize the chosen service provider each in server or client
* mode. If a service provider has already been initialized, it will
Expand All @@ -175,7 +180,7 @@ boolean N_InitService(boolean inServerMode)

if(inServerMode)
{
port = (!nptIPPort ? defaultTCPPort : nptIPPort);
port = N_ServerPort();

Con_Message("Listening on TCP port %i.\n", port);

Expand Down Expand Up @@ -461,7 +466,7 @@ boolean N_ServerOpen(void)
}

// Start the beacon.
beacon.start();
beacon.start(N_ServerPort());

return true;
}
Expand Down
2 changes: 2 additions & 0 deletions doomsday/libdeng2/include/de/net/address.h
Expand Up @@ -95,6 +95,8 @@ class DENG2_PUBLIC Address : public LogEntry::Arg::Base
*/
String asText() const;

static Address parse(String const &addressWithOptionalPort, duint16 defaultPort = 0);

// Implements LogEntry::Arg::Base.
LogEntry::Arg::Type logEntryArgType() const { return LogEntry::Arg::STRING; }

Expand Down
15 changes: 9 additions & 6 deletions doomsday/libdeng2/include/de/net/beacon.h
Expand Up @@ -46,10 +46,11 @@ class Beacon : public QObject
/**
* Starts the beacon with a message to give out.
*
* @param advertisedMessage Message to send to requesters.
* @param port UDP port to advertise on.
* @param serviceListenPort
* TCP port that the advertised service listens on. Recipients will
* pair this with the IP address to form a full address.
*/
void start();
void start(duint16 serviceListenPort);

/**
* Changes the message to advertise.
Expand All @@ -66,10 +67,12 @@ class Beacon : public QObject
/**
* Looks for any beacons on all accessible networks.
*
* @param port UDP port to discover on.
* @param timeOut Maximum time to spend discovering.
* @param port UDP port to discover on.
* @param timeOut Maximum time to spend discovering. If the timeout
* is zero or negative, discovery will not end.
* @param interval Interval between query broadcasts.
*/
void discover(TimeDelta const &timeOut = 10);
void discover(TimeDelta const &timeOut, TimeDelta const &interval = TimeDelta(1.0));

QList<Address> foundHosts() const;
Block messageFromHost(Address const &host) const;
Expand Down
13 changes: 13 additions & 0 deletions doomsday/libdeng2/src/net/address.cpp
Expand Up @@ -121,6 +121,19 @@ String Address::asText() const
return result;
}

Address Address::parse(String const &addressWithOptionalPort, duint16 defaultPort)
{
duint16 port = defaultPort;
String str = addressWithOptionalPort;
if(str.contains(':'))
{
int pos = str.indexOf(':');
port = str.mid(pos + 1).toInt();
str = str.left(pos);
}
return Address(str.toAscii(), port);
}

QTextStream &operator << (QTextStream &os, Address const &address)
{
os << address.asText();
Expand Down
43 changes: 32 additions & 11 deletions doomsday/libdeng2/src/net/beacon.cpp
Expand Up @@ -17,6 +17,8 @@
*/

#include "de/Beacon"
#include "de/Reader"
#include "de/Writer"
#include <QUdpSocket>
#include <QHostInfo>
#include <QNetworkInterface>
Expand All @@ -30,6 +32,7 @@ static char const *discoveryMessage = "Doomsday Beacon 1.0";
struct Beacon::Instance
{
duint16 port;
duint16 servicePort;
QUdpSocket *socket;
Block message;
QTimer *timer;
Expand All @@ -56,10 +59,12 @@ Beacon::~Beacon()
delete d;
}

void Beacon::start()
void Beacon::start(duint16 serviceListenPort)
{
DENG2_ASSERT(!d->socket);

d->servicePort = serviceListenPort;

d->socket = new QUdpSocket;
connect(d->socket, SIGNAL(readyRead()), this, SLOT(readIncoming()));

Expand All @@ -72,7 +77,12 @@ void Beacon::start()

void Beacon::setMessage(IByteArray const &advertisedMessage)
{
d->message = advertisedMessage;
d->message.clear();

// Begin with the service listening port.
Writer(d->message) << d->servicePort;

d->message += Block(advertisedMessage);
}

void Beacon::stop()
Expand All @@ -81,7 +91,7 @@ void Beacon::stop()
d->socket = 0;
}

void Beacon::discover(TimeDelta const &timeOut)
void Beacon::discover(TimeDelta const &timeOut, TimeDelta const &interval)
{
if(d->timer) return; // Already discovering.

Expand All @@ -100,10 +110,17 @@ void Beacon::discover(TimeDelta const &timeOut)
d->found.clear();

// Time-out timer.
d->discoveryEndsAt = Time() + timeOut;
if(timeOut > 0.0)
{
d->discoveryEndsAt = Time() + timeOut;
}
else
{
d->discoveryEndsAt = Time::invalidTime();
}
d->timer = new QTimer;
connect(d->timer, SIGNAL(timeout()), this, SLOT(continueDiscovery()));
d->timer->start(500);
d->timer->start(interval.asMilliSeconds());
}

QList<Address> Beacon::foundHosts() const
Expand Down Expand Up @@ -131,7 +148,7 @@ void Beacon::readIncoming()
d->socket->readDatagram(reinterpret_cast<char *>(block.data()),
block.size(), &from, &port);

LOG_DEBUG("Received %i bytes from %s port %i") << block.size() << from.toString() << port;
LOG_TRACE("Received %i bytes from %s port %i") << block.size() << from.toString() << port;

if(block == discoveryMessage)
{
Expand All @@ -158,11 +175,15 @@ void Beacon::readDiscoveryReply()
if(block == discoveryMessage)
continue;

LOG_DEBUG("Received %i bytes from %s") << block.size() << from.toString();
// Remove the service listening port from the beginning.
duint16 listenPort = 0;
Reader(block) >> listenPort;
block.remove(0, 2);

d->found.insert(Address(from), block);
Address host(from, listenPort);
d->found.insert(host, block);

emit found(Address(from), block);
emit found(host, block);
}
}

Expand All @@ -172,7 +193,7 @@ void Beacon::continueDiscovery()
DENG2_ASSERT(d->timer);

// Time to stop discovering?
if(Time() > d->discoveryEndsAt)
if(d->discoveryEndsAt.isValid() && Time() > d->discoveryEndsAt)
{
d->timer->stop();

Expand All @@ -188,7 +209,7 @@ void Beacon::continueDiscovery()

Block block(discoveryMessage);

LOG_DEBUG("Broadcasting %i bytes") << block.size();
LOG_TRACE("Broadcasting %i bytes") << block.size();

// Send a new broadcast.
d->socket->writeDatagram(block,
Expand Down

0 comments on commit 47e2daa

Please sign in to comment.