Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

jabber offer/connection logic, with determinism to avoid duplicate co…

…nnections
  • Loading branch information...
commit 27abfb122d605e4fb9db6117f2f8d5fd2f3df9bd 1 parent bd79b30
@RJ authored
View
1  qxmpp/QXmppClient.cpp
@@ -91,3 +91,4 @@ QXmppRoster& QXmppClient::getRoster()
{
return m_stream->getRoster();
}
+
View
1  qxmpp/QXmppClient.h
@@ -54,6 +54,7 @@ class QXmppClient : public QObject
void presenceReceived(const QXmppPresence&);
void iqReceived(const QXmppIq&);
+
public slots:
void sendPacket(const QXmppPacket&);
View
2  qxmpp/QXmppStream.cpp
@@ -418,7 +418,7 @@ void QXmppStream::sendInitialPresence()
QString statusText = getConfiguration().getStatus();
QXmppPresence presence(QXmppPresence::Available);
- presence.setStatus(QXmppPresence::Status(QXmppPresence::Status::Online, statusText));
+ presence.setStatus(QXmppPresence::Status(QXmppPresence::Status::XA, statusText));
sendPacket(presence);
}
View
135 src/conjist.cpp
@@ -1,67 +1,100 @@
#include "conjist.h"
#include "portfwd.h"
#include "getopt_helper.h"
+#include "QXmppLogger.h"
+#include "QXmppConfiguration.h"
#define CONJISTPORT 50210
conjist::conjist(int argc, char *argv[])
- : QCoreApplication(argc, argv), m_servent(0), m_publicPort(0)
+ : QCoreApplication(argc, argv), m_go(argc,argv), m_servent(0), m_externalPort(0), m_port(CONJISTPORT)
{
+ // do the setup once event loop started, so we can call exit() correctly
QTimer::singleShot(0, this, SLOT(setup()));
}
void conjist::setup()
{
- helper::GetOpt go;
- QString domain, username, password, server, sport;
- int port;
- go.addOption('d', "domain", &domain);
- go.addOption('u', "user", &username);
- go.addOption('p', "pass", &password);
- go.addOption('s', "server", &server);
- go.addOption('r', "port", &sport);
-
- if(!go.parse())
+ QString domain, username, password, server, sport, slport;
+ int jport;
+ bool noupnp, xmpplog;
+ m_go.addOption('d', "domain", &domain);
+ m_go.addOption('u', "user", &username);
+ m_go.addOption('p', "pass", &password);
+ m_go.addOption('s', "server", &server);
+ m_go.addOption('r', "jabberport", &sport);
+ m_go.addOption('l', "listenport", &slport);
+ m_go.addSwitch("noupnp", &noupnp);
+ m_go.addSwitch("xmpplog", &xmpplog);
+
+ bool ok = m_go.parse();
+ if(!ok || username=="" || password=="" || domain=="")
{
printf("You must supply your jabber details.\n");
printf("For example, if you were larry@gmail.com using gtalk:\n");
printf("Usage: conjist.exe --user larry --domain gmail.com --pass 123\n");
printf(" --server talk.google.com --port 5222\n");
+ printf("\n"
+ "Use --noupnp to disable UPnP detection.\n");
this->exit(1);
return;
}
- port = sport.toInt();
+ jport = sport.toInt();
+ if(!jport) jport=5222;
+
+ m_port = slport.toInt();
+ if(!m_port) m_port = CONJISTPORT;
+
+ if(server.isNull()) server = domain;
+
+ // jabber client setup
+
+ if(xmpplog) QXmppLogger::getLogger()->setLoggingType(QXmppLogger::STDOUT);
+ else QXmppLogger::getLogger()->setLoggingType(QXmppLogger::NONE);
m_jabber = new JabberClient(this);
connect(m_jabber, SIGNAL(peerOnline(QString)), this, SLOT(newJabberPeer(QString)));
+ connect(m_jabber, SIGNAL(msgReceived(QString,QString)), this, SLOT(jabberMsg(QString,QString)));
+
+ m_ourjid = QString("%1@%2").arg(username).arg(domain);
+ QXmppConfiguration conf;
+ conf.setHost(server);
+ conf.setDomain(domain);
+ conf.setUser(username);
+ conf.setPasswd(password);
+ conf.setPort(jport);
+ conf.setResource("conjist");
+ conf.setStatus("conjist software (not human)");
- m_ourjid = "playdartest2@jabber.org";
- m_jabber->connectToServer(domain, username, password, server, port);
+ m_jabber->connectToServer( conf );
- startServent();
+ startServent(!noupnp);
}
+
// figure out ports, external ips, and start the servent listening
-void conjist::startServent()
-{
- qDebug() << "Searching for UPnp Router...";
+void conjist::startServent(bool upnp)
+{
QString pubip;
Portfwd pf;
+ if(!upnp) goto nopublic;
+
+ qDebug() << "Searching for UPnp Router...";
if(!pf.init(2000))
{
qDebug() << "!! Couldn't find gateway.";
goto nopublic;
}
- if(!pf.add(CONJISTPORT))
+ if(!pf.add(m_port))
{
qDebug() << "!! Couldn't setup external port fwd for port " << CONJISTPORT;
goto nopublic;
}
pubip = QString(pf.external_ip().c_str());
- m_publicAddress = QHostAddress(pubip);
- m_publicPort = CONJISTPORT;
- qDebug() << "Public servent address detected as " << pubip << ":" << m_publicPort;
+ m_externalAddress = QHostAddress(pubip);
+ m_externalPort = m_port;
+ qDebug() << "External servent address detected as " << pubip << ":" << m_externalPort;
qDebug() << "Max upstream " << pf.max_upstream_bps() << "bps";
qDebug() << "Max downstream " << pf.max_downstream_bps() << "bps";
@@ -73,11 +106,12 @@ void conjist::startServent()
if(false)
{
nopublic:
+ qDebug() << "!! No external IP address configured / detected";
qDebug() << "!! You will be able to make outbound connections, but not listen for incoming";
}
- m_servent = new Servent(QHostAddress(QHostAddress::Any), CONJISTPORT, this);
- if(m_publicPort) m_servent->setExternalAddress(m_publicAddress, m_publicPort);
+ m_servent = new Servent(QHostAddress(QHostAddress::Any), m_port, this);
+ if(m_externalPort) m_servent->setExternalAddress(m_externalAddress, m_externalPort);
}
@@ -85,11 +119,36 @@ void conjist::startServent()
void conjist::newJabberPeer(QString name)
{
if(name.startsWith(m_ourjid)) return;
- qDebug() << "New jabber peer: " << name;
+
+ QVariantMap m;
+ if(m_servent->visibleExternally())
+ {
+ QString key = "blah-jabber-ofer-key";
+ ControlConnection * cc = new ControlConnection(m_servent);
+ cc->setName(name);
+ m_servent->registerOffer(key, cc);
+
+ m["visible"] = true;
+ m["ip"] = m_servent->externalAddress().toString();
+ m["port"] = m_servent->externalPort();
+ m["key"] = key;
+
+ qDebug() << "Extending an offer to " << name << " using key: " << key;
+ }
+ else
+ {
+ m["visible"] = false;
+ qDebug() << "Telling " << name << " we are not externally visible. Hope they are.";
+ }
+
+ QJson::Serializer serializer;
+ const QByteArray ser = serializer.serialize( m );
+ m_jabber->sendMsg(name, QString::fromAscii(ser));
}
void conjist::jabberMsg(QString from, QString msg)
{
+ qDebug() << "JMSG from " << from << " MSG: " << msg;
bool ok;
QVariantMap m = parser.parse(msg.toAscii(), &ok).toMap();
if(!ok)
@@ -97,5 +156,29 @@ void conjist::jabberMsg(QString from, QString msg)
qDebug() << "Malformed msg in jabber msg";
return;
}
-
+ bool visible = m.value("visible").toBool();
+ if(!visible)
+ {
+ if(m_servent->visibleExternally())
+ qDebug() << from << " is not externally visible, they should to connect to us.";
+ else
+ qDebug() << from << " is no externally visible, neither are we, no direct connection possible :(";
+ }
+ else
+ {
+ QString ip = m.value("ip").toString();
+ int port = m.value("port").toInt();
+ QString key = m.value("key").toString();
+ // if we are also externally visible, decide who will initate the connection
+ // based on the IP addresses (arbitrary but deterministic)
+ if(m_servent->visibleExternally() && m_servent->externalAddress().toString() < ip)
+ {
+ qDebug() << "both externally visible, but decided to let " << from << " initiate the connection.";
+ return;
+ }
+ qDebug() << "We will initiate a connection to " << from;
+ ControlConnection * cc = new ControlConnection(m_servent);
+ cc->setName(from);
+ m_servent->connectToPeer(QHostAddress(ip), port, cc, key);
+ }
}
View
11 src/conjist.h
@@ -10,6 +10,8 @@
#include "jabberclient.h"
#include "servent.h"
+#include "getopt_helper.h"
+#include "controlconnection.h"
class conjist : public QCoreApplication
{
@@ -27,14 +29,15 @@ private slots:
void setup();
private:
- void startServent();
-
+ void startServent(bool upnp);
+ helper::GetOpt m_go;
QString m_ourjid;
JabberClient * m_jabber;
Servent * m_servent;
- int m_publicPort;
- QHostAddress m_publicAddress;
+ int m_externalPort, m_port;
+ QHostAddress m_externalAddress;
QJson::Parser parser;
+
};
#endif // CONJIST_H
View
3  src/getopt_helper.cpp
@@ -7,6 +7,7 @@
#include <QFileInfo>
#include <QStack>
#include <stdlib.h>
+#include <QDebug>
#include <assert.h>
@@ -158,7 +159,9 @@ void GetOpt::init( int argc, char *argv[], int offset )
aname = QFileInfo( QString::fromUtf8( argv[0] ) ).fileName();
// arguments
for ( int i = offset; i < argc; ++i )
+ {
args.append( QString::fromUtf8( argv[i] ) );
+ }
}
}
View
8 src/jabberclient.cpp
@@ -22,7 +22,7 @@ void JabberClient::presenceReceived(QXmppPresence p)
case QXmppPresence::Status::XA:
case QXmppPresence::Status::DND:
case QXmppPresence::Status::Chat:
- qDebug() << "ONLINE presence: " << from << " type: " << p.getType();
+ //qDebug() << "ONLINE presence: " << from << " type: " << p.getType();
if(from.contains("/conjist"))
{
if(!m_peerjids.contains(from))
@@ -35,7 +35,7 @@ void JabberClient::presenceReceived(QXmppPresence p)
break;
default:
- qDebug() << "OFFLINE pres: " << p.getFrom();
+ //qDebug() << "OFFLINE pres: " << p.getFrom();
if(p.getFrom().contains("/conjist"))
{
if(m_peerjids.contains(from))
@@ -52,7 +52,7 @@ void JabberClient::messageReceived(const QXmppMessage& message)
{
QString from = message.getFrom();
QString msg = message.getBody();
- qDebug() << "Jabber rcvded from: " << from << " msg: " << msg;
+ //qDebug() << "Jabber rcvded from: " << from << " msg: " << msg;
if(m_peerjids.contains(from))
{
emit msgReceived(from, msg);
@@ -61,6 +61,6 @@ void JabberClient::messageReceived(const QXmppMessage& message)
void JabberClient::sendMsg(QString to, QString msg)
{
- qDebug() << "Jabber sending to " << to << " msg: " << msg;
+ //qDebug() << "Jabber sending to " << to << " msg: " << msg;
sendPacket(QXmppMessage("", to, msg));
}
View
7 src/main.cpp
@@ -4,17 +4,24 @@
#include <QThread>
#include <QTimer>
#include <stdlib.h>
+#include <cstdlib> // for putenv
//#include "servent.h"
//#include "testdriver.h"
//#include "proxyconnection.h"
#include "conjist.h"
+#include "getopt_helper.h"
int main(int argc, char *argv[])
{
+ // silence the warnings from avahi
+ putenv("AVAHI_COMPAT_NOWARN=1");
+
conjist app(argc, argv);
+
return app.exec();
+
/*
QCoreApplication app(argc, argv);
View
3  src/servent.h
@@ -50,8 +50,11 @@ Q_OBJECT
void connectToPeer(QHostAddress ha, int port, Connection * conn, QString key);
void reverseOfferRequest(Connection * orig_conn, QString key, QString theirkey);
void createDaapListener(ControlConnection * conn, QString key, QString name);
+
void setExternalAddress(QHostAddress ha, int port);
bool visibleExternally() const { return m_externalPort >0; };
+ QHostAddress externalAddress() const { return m_externalAddress; };
+ int externalPort() const { return m_externalPort; };
protected:
void incomingConnection(int sd);
Please sign in to comment.
Something went wrong with that request. Please try again.