summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2009-07-18 19:04:32 (GMT)
committerRemko Tronçon <git@el-tramo.be>2009-07-18 20:40:56 (GMT)
commit4457bc810a326de8d7895b3f2ff36ade5f1ae1a0 (patch)
tree1556c4b0190453897d4799d23b05e651b0bb8a32 /Swiften/LinkLocal
parent4052a822acd9da9dab6a8e2343c6170fb08dd8d6 (diff)
downloadswift-4457bc810a326de8d7895b3f2ff36ade5f1ae1a0.zip
swift-4457bc810a326de8d7895b3f2ff36ade5f1ae1a0.tar.bz2
Implement incoming linklocal connections.
Diffstat (limited to 'Swiften/LinkLocal')
-rw-r--r--Swiften/LinkLocal/AppleDNSSDService.cpp4
-rw-r--r--Swiften/LinkLocal/IncomingLinkLocalSession.cpp69
-rw-r--r--Swiften/LinkLocal/IncomingLinkLocalSession.h39
-rw-r--r--Swiften/LinkLocal/LinkLocalRoster.cpp21
-rw-r--r--Swiften/LinkLocal/LinkLocalRoster.h3
-rw-r--r--Swiften/LinkLocal/LinkLocalSession.cpp59
-rw-r--r--Swiften/LinkLocal/LinkLocalSession.h82
-rw-r--r--Swiften/LinkLocal/Makefile.inc5
-rw-r--r--Swiften/LinkLocal/OutgoingLinkLocalSession.cpp74
-rw-r--r--Swiften/LinkLocal/OutgoingLinkLocalSession.h48
10 files changed, 398 insertions, 6 deletions
diff --git a/Swiften/LinkLocal/AppleDNSSDService.cpp b/Swiften/LinkLocal/AppleDNSSDService.cpp
index d4befd1..521c584 100644
--- a/Swiften/LinkLocal/AppleDNSSDService.cpp
+++ b/Swiften/LinkLocal/AppleDNSSDService.cpp
@@ -98,7 +98,6 @@ void AppleDNSSDService::stopResolvingService(const Service& service) {
void AppleDNSSDService::resolveHostname(const String& hostname, int interfaceIndex) {
boost::lock_guard<boost::mutex> lock(sdRefsMutex);
- std::cout << "Resolve " << hostname << std::endl;
DNSServiceRef hostnameResolveSDRef;
DNSServiceErrorType result = DNSServiceGetAddrInfo(&hostnameResolveSDRef, 0, interfaceIndex, kDNSServiceProtocol_IPv4, hostname.getUTF8Data(), &AppleDNSSDService::handleHostnameResolvedGlobal, this);
@@ -159,7 +158,6 @@ void AppleDNSSDService::doStart() {
// Hostname resolving
for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) {
- std::cout << "Adding ostname resolve " << std::endl;
int hostnameResolveSocket = DNSServiceRefSockFD(*i);
maxSocket = std::max(maxSocket, hostnameResolveSocket);
FD_SET(hostnameResolveSocket, &fdSet);
@@ -193,7 +191,6 @@ void AppleDNSSDService::doStart() {
for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) {
if (FD_ISSET(DNSServiceRefSockFD(*i), &fdSet)) {
DNSServiceProcessResult(*i);
- std::cout << "Removing hostnameResolve" << std::endl;
hostnameResolveSDRefs.erase(std::remove(hostnameResolveSDRefs.begin(), hostnameResolveSDRefs.end(), *i), hostnameResolveSDRefs.end());
DNSServiceRefDeallocate(*i);
break; // Stop the loop, because we removed an element
@@ -211,7 +208,6 @@ void AppleDNSSDService::doStart() {
resolveSDRefs.clear();
for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) {
- std::cout << "Removing hostnameResolve" << std::endl;
DNSServiceRefDeallocate(*i);
}
hostnameResolveSDRefs.clear();
diff --git a/Swiften/LinkLocal/IncomingLinkLocalSession.cpp b/Swiften/LinkLocal/IncomingLinkLocalSession.cpp
new file mode 100644
index 0000000..db4b007
--- /dev/null
+++ b/Swiften/LinkLocal/IncomingLinkLocalSession.cpp
@@ -0,0 +1,69 @@
+#include "Swiften/LinkLocal/IncomingLinkLocalSession.h"
+
+#include <boost/bind.hpp>
+
+#include "Swiften/Elements/ProtocolHeader.h"
+#include "Swiften/Network/Connection.h"
+#include "Swiften/StreamStack/StreamStack.h"
+#include "Swiften/StreamStack/ConnectionLayer.h"
+#include "Swiften/StreamStack/XMPPLayer.h"
+#include "Swiften/Elements/StreamFeatures.h"
+#include "Swiften/Elements/IQ.h"
+#include "Swiften/SASL/PLAINMessage.h"
+
+namespace Swift {
+
+IncomingLinkLocalSession::IncomingLinkLocalSession(
+ const JID& localJID,
+ boost::shared_ptr<Connection> connection,
+ PayloadParserFactoryCollection* payloadParserFactories,
+ PayloadSerializerCollection* payloadSerializers) :
+ LinkLocalSession(
+ localJID,
+ connection,
+ payloadParserFactories,
+ payloadSerializers) {
+}
+
+void IncomingLinkLocalSession::start() {
+ initializeStreamStack();
+}
+
+void IncomingLinkLocalSession::handleStreamStart(const ProtocolHeader& incomingHeader) {
+ remoteJID_ = JID(incomingHeader.getFrom());
+ if (!remoteJID_.isValid()) {
+ finishSession();
+ return;
+ }
+ ProtocolHeader header;
+ header.setFrom(getLocalJID());
+ getXMPPLayer()->writeHeader(header);
+
+ if (incomingHeader.getVersion() == "1.0") {
+ getXMPPLayer()->writeElement(boost::shared_ptr<StreamFeatures>(new StreamFeatures()));
+ }
+ else {
+ setInitialized();
+ }
+}
+
+void IncomingLinkLocalSession::handleElement(boost::shared_ptr<Element> element) {
+ boost::shared_ptr<Stanza> stanza = boost::dynamic_pointer_cast<Stanza>(element);
+ // If we get our first stanza before streamfeatures, our session is implicitly
+ // initialized
+ if (stanza && !isInitialized()) {
+ setInitialized();
+ }
+
+ if (isInitialized()) {
+ if (stanza) {
+ onStanzaReceived(stanza);
+ }
+ else {
+ std::cerr << "Received unexpected element" << std::endl;
+ }
+ }
+}
+
+
+}
diff --git a/Swiften/LinkLocal/IncomingLinkLocalSession.h b/Swiften/LinkLocal/IncomingLinkLocalSession.h
new file mode 100644
index 0000000..d4fa91a
--- /dev/null
+++ b/Swiften/LinkLocal/IncomingLinkLocalSession.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+#include <boost/signal.hpp>
+
+#include "Swiften/LinkLocal/LinkLocalSession.h"
+#include "Swiften/JID/JID.h"
+#include "Swiften/Network/Connection.h"
+
+namespace Swift {
+ class ProtocolHeader;
+ class String;
+ class Element;
+ class PayloadParserFactoryCollection;
+ class PayloadSerializerCollection;
+
+ class IncomingLinkLocalSession : public LinkLocalSession {
+ public:
+ IncomingLinkLocalSession(
+ const JID& localJID,
+ boost::shared_ptr<Connection> connection,
+ PayloadParserFactoryCollection* payloadParserFactories,
+ PayloadSerializerCollection* payloadSerializers);
+
+ const JID& getRemoteJID() const {
+ return remoteJID_;
+ }
+
+ void start();
+
+ private:
+ void handleElement(boost::shared_ptr<Element>);
+ void handleStreamStart(const ProtocolHeader&);
+
+ private:
+ bool initialized_;
+ JID remoteJID_;
+ };
+}
diff --git a/Swiften/LinkLocal/LinkLocalRoster.cpp b/Swiften/LinkLocal/LinkLocalRoster.cpp
index 89bfa55..6809377 100644
--- a/Swiften/LinkLocal/LinkLocalRoster.cpp
+++ b/Swiften/LinkLocal/LinkLocalRoster.cpp
@@ -77,6 +77,7 @@ void LinkLocalRoster::handleServiceAdded(const DNSSDService::Service& service) {
if (selfService && *selfService == service) {
return;
}
+ std::cout << "Service added: " << service.name << std::endl;
dnsSDService->startResolvingService(service);
}
@@ -93,7 +94,7 @@ void LinkLocalRoster::handleServiceRemoved(const DNSSDService::Service& service)
void LinkLocalRoster::handleServiceResolved(const DNSSDService::Service& service, const DNSSDService::ResolveResult& result) {
services.insert(std::make_pair(service, result));
- dnsSDService->resolveHostname(result.host);
+ std::cout << "Service resolved: " << service.name << std::endl;
boost::shared_ptr<RosterPayload> roster(new RosterPayload());
roster->addItem(getRosterItem(service, result));
@@ -109,4 +110,22 @@ void LinkLocalRoster::handleStopped(bool error) {
std::cout << "DNSSDService stopped: " << error << std::endl;
}
+bool LinkLocalRoster::hasItem(const JID& j) const {
+ for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) {
+ if (getJIDForService(i->first) == j) {
+ return true;
+ }
+ }
+ return false;
+}
+
+String LinkLocalRoster::getHostname(const JID& j) const {
+ for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) {
+ if (getJIDForService(i->first) == j) {
+ return i->second.host;
+ }
+ }
+ return "";
+}
+
}
diff --git a/Swiften/LinkLocal/LinkLocalRoster.h b/Swiften/LinkLocal/LinkLocalRoster.h
index 33dd455..bd774f4 100644
--- a/Swiften/LinkLocal/LinkLocalRoster.h
+++ b/Swiften/LinkLocal/LinkLocalRoster.h
@@ -23,6 +23,9 @@ namespace Swift {
boost::signal<void (boost::shared_ptr<RosterPayload>)> onRosterChanged;
boost::signal<void (boost::shared_ptr<Presence>)> onPresenceChanged;
+ bool hasItem(const JID&) const;
+ String getHostname(const JID&) const;
+
private:
RosterItemPayload getRosterItem(const DNSSDService::Service& service, const DNSSDService::ResolveResult& info) const;
String getRosterName(const DNSSDService::Service& service, const DNSSDService::ResolveResult& info) const;
diff --git a/Swiften/LinkLocal/LinkLocalSession.cpp b/Swiften/LinkLocal/LinkLocalSession.cpp
new file mode 100644
index 0000000..a308686
--- /dev/null
+++ b/Swiften/LinkLocal/LinkLocalSession.cpp
@@ -0,0 +1,59 @@
+#include "Swiften/LinkLocal/LinkLocalSession.h"
+
+#include <boost/bind.hpp>
+
+#include "Swiften/StreamStack/XMPPLayer.h"
+#include "Swiften/StreamStack/StreamStack.h"
+
+namespace Swift {
+
+LinkLocalSession::LinkLocalSession(
+ const JID& localJID,
+ boost::shared_ptr<Connection> connection,
+ PayloadParserFactoryCollection* payloadParserFactories,
+ PayloadSerializerCollection* payloadSerializers) :
+ localJID(localJID),
+ payloadParserFactories(payloadParserFactories),
+ payloadSerializers(payloadSerializers),
+ connection(connection),
+ initialized(false) {
+}
+
+LinkLocalSession::~LinkLocalSession() {
+ delete streamStack;
+}
+
+void LinkLocalSession::initializeStreamStack() {
+ assert(connection);
+ xmppLayer = boost::shared_ptr<XMPPLayer>(
+ new XMPPLayer(payloadParserFactories, payloadSerializers));
+ xmppLayer->onStreamStart.connect(
+ boost::bind(&LinkLocalSession::handleStreamStart, this, _1));
+ xmppLayer->onElement.connect(
+ boost::bind(&LinkLocalSession::handleElement, this, _1));
+ //xmppLayer->onError.connect(
+ // boost::bind(&LinkLocalSession::setError, this, XMLError));
+ connection->onDisconnected.connect(
+ boost::bind(&LinkLocalSession::handleDisconnected, shared_from_this(), _1));
+ connectionLayer = boost::shared_ptr<ConnectionLayer>(new ConnectionLayer(connection));
+ streamStack = new StreamStack(xmppLayer, connectionLayer);
+}
+
+void LinkLocalSession::finishSession() {
+ connection->disconnect();
+}
+
+void LinkLocalSession::sendStanza(boost::shared_ptr<Stanza> stanza) {
+ xmppLayer->writeElement(stanza);
+}
+
+void LinkLocalSession::handleDisconnected(const boost::optional<Connection::Error>&) {
+ onSessionFinished();
+}
+
+void LinkLocalSession::setInitialized() {
+ initialized = true;
+ onSessionStarted();
+}
+
+}
diff --git a/Swiften/LinkLocal/LinkLocalSession.h b/Swiften/LinkLocal/LinkLocalSession.h
new file mode 100644
index 0000000..9a7ac13
--- /dev/null
+++ b/Swiften/LinkLocal/LinkLocalSession.h
@@ -0,0 +1,82 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+#include <boost/signal.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include "Swiften/JID/JID.h"
+#include "Swiften/Elements/Element.h"
+#include "Swiften/Network/Connection.h"
+#include "Swiften/StreamStack/ConnectionLayer.h"
+
+namespace Swift {
+ class ProtocolHeader;
+ class StreamStack;
+ class JID;
+ class Stanza;
+ class ByteArray;
+ class PayloadParserFactoryCollection;
+ class PayloadSerializerCollection;
+ class XMPPLayer;
+
+ class LinkLocalSession :
+ public boost::enable_shared_from_this<LinkLocalSession> {
+ public:
+ LinkLocalSession(
+ const JID& localJID,
+ boost::shared_ptr<Connection> connection,
+ PayloadParserFactoryCollection* payloadParserFactories,
+ PayloadSerializerCollection* payloadSerializers);
+ virtual ~LinkLocalSession();
+
+ void finishSession();
+
+ // TODO: Make non-virtual when OutgoingSession is fixed
+ virtual void sendStanza(boost::shared_ptr<Stanza>);
+
+ virtual const JID& getRemoteJID() const = 0;
+
+ virtual void start() = 0;
+
+ boost::signal<void (boost::shared_ptr<Stanza>)> onStanzaReceived;
+ boost::signal<void ()> onSessionFinished;
+ boost::signal<void ()> onSessionStarted;
+ boost::signal<void (const ByteArray&)> onDataWritten;
+ boost::signal<void (const ByteArray&)> onDataRead;
+
+ protected:
+ void initializeStreamStack();
+
+ const JID& getLocalJID() const {
+ return localJID;
+ }
+
+ boost::shared_ptr<XMPPLayer> getXMPPLayer() const {
+ return xmppLayer;
+ }
+
+ // TODO: Remove later
+ void setConnection(boost::shared_ptr<Connection> c) {
+ connection = c;
+ }
+
+ virtual void handleElement(boost::shared_ptr<Element>) = 0;
+ virtual void handleStreamStart(const ProtocolHeader&) = 0;
+
+ void setInitialized();
+ bool isInitialized() const { return initialized; }
+
+ private:
+ void handleDisconnected(const boost::optional<Connection::Error>& error);
+
+ private:
+ JID localJID;
+ PayloadParserFactoryCollection* payloadParserFactories;
+ PayloadSerializerCollection* payloadSerializers;
+ boost::shared_ptr<Connection> connection;
+ boost::shared_ptr<XMPPLayer> xmppLayer;
+ boost::shared_ptr<ConnectionLayer> connectionLayer;
+ StreamStack* streamStack;
+ bool initialized;
+ };
+}
diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc
index 683447c..1d29844 100644
--- a/Swiften/LinkLocal/Makefile.inc
+++ b/Swiften/LinkLocal/Makefile.inc
@@ -1,7 +1,10 @@
SWIFTEN_SOURCES += \
Swiften/LinkLocal/DNSSDService.cpp \
Swiften/LinkLocal/LinkLocalRoster.cpp \
- Swiften/LinkLocal/LinkLocalServiceInfo.cpp
+ Swiften/LinkLocal/LinkLocalServiceInfo.cpp \
+ Swiften/LinkLocal/IncomingLinkLocalSession.cpp \
+ Swiften/LinkLocal/OutgoingLinkLocalSession.cpp \
+ Swiften/LinkLocal/LinkLocalSession.cpp
ifeq ($(MACOSX),1)
diff --git a/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp b/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp
new file mode 100644
index 0000000..57f3154
--- /dev/null
+++ b/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp
@@ -0,0 +1,74 @@
+#include "Swiften/LinkLocal/OutgoingLinkLocalSession.h"
+
+#include <boost/bind.hpp>
+
+#include "Swiften/Elements/ProtocolHeader.h"
+#include "Swiften/Network/Connection.h"
+#include "Swiften/StreamStack/StreamStack.h"
+#include "Swiften/LinkLocal/DNSSDService.h"
+#include "Swiften/StreamStack/ConnectionLayer.h"
+#include "Swiften/StreamStack/XMPPLayer.h"
+#include "Swiften/Elements/StreamFeatures.h"
+#include "Swiften/Elements/IQ.h"
+#include "Swiften/SASL/PLAINMessage.h"
+
+namespace Swift {
+
+OutgoingLinkLocalSession::OutgoingLinkLocalSession(
+ const JID& localJID,
+ const JID& remoteJID,
+ const String& hostname,
+ boost::shared_ptr<DNSSDService> resolver,
+ PayloadParserFactoryCollection* payloadParserFactories,
+ PayloadSerializerCollection* payloadSerializers,
+ ConnectionFactory* connectionFactory) :
+ LinkLocalSession(
+ localJID,
+ boost::shared_ptr<Connection>(),
+ payloadParserFactories,
+ payloadSerializers),
+ resolving_(false),
+ remoteJID_(remoteJID),
+ hostname_(hostname),
+ resolver_(resolver),
+ connectionFactory_(connectionFactory) {
+}
+
+void OutgoingLinkLocalSession::start() {
+ resolving_ = true;
+ //resolver_->onHostnameResolved.connect(boost::bind(&OutgoingLinkLocalSession::handleHostnameResolved, this, _1, _2));
+}
+
+#if 0
+void OutgoingLinkLocalSession::handleHostnameResolved(const String& hostname, const HostAddress&) {
+ if (resolving_) {
+ if (hostname == hostname_) {
+ boost::shared_ptr<Connection> connection = connectionFactory_->createConnection();
+ connection->onConnected.connect(boost::bind(&Session::handleConnected, shared_from_this()));
+ connection->onDisconnected.connect(boost::bind(&Session::handleDisconnected, shared_from_this(), _1));
+ connection_->connect(jid_.getDomain());
+ resolving_ = false;
+ boost::
+ }
+ }
+}
+#endif
+
+void OutgoingLinkLocalSession::handleStreamStart(const ProtocolHeader&) {
+ ProtocolHeader header;
+ header.setFrom(getLocalJID());
+ getXMPPLayer()->writeHeader(header);
+ setInitialized();
+}
+
+void OutgoingLinkLocalSession::handleElement(boost::shared_ptr<Element> element) {
+ if (isInitialized()) {
+ boost::shared_ptr<Stanza> stanza = boost::dynamic_pointer_cast<Stanza>(element);
+ if (stanza) {
+ onStanzaReceived(stanza);
+ }
+ }
+}
+
+
+}
diff --git a/Swiften/LinkLocal/OutgoingLinkLocalSession.h b/Swiften/LinkLocal/OutgoingLinkLocalSession.h
new file mode 100644
index 0000000..ae1e86b
--- /dev/null
+++ b/Swiften/LinkLocal/OutgoingLinkLocalSession.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+#include <boost/signal.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include "Swiften/LinkLocal/LinkLocalSession.h"
+#include "Swiften/JID/JID.h"
+
+namespace Swift {
+ class ConnectionFactory;
+ class HostAddress;
+ class String;
+ class Element;
+ class PayloadParserFactoryCollection;
+ class PayloadSerializerCollection;
+ class DNSSDService;
+
+ class OutgoingLinkLocalSession : public LinkLocalSession, public boost::enable_shared_from_this<OutgoingLinkLocalSession> {
+ public:
+ OutgoingLinkLocalSession(
+ const JID& localJID,
+ const JID& remoteJID,
+ const String& hostname,
+ boost::shared_ptr<DNSSDService> resolver,
+ PayloadParserFactoryCollection* payloadParserFactories,
+ PayloadSerializerCollection* payloadSerializers,
+ ConnectionFactory* connectionFactory);
+
+ const JID& getRemoteJID() const {
+ return remoteJID_;
+ }
+
+ void start();
+
+ private:
+ void handleElement(boost::shared_ptr<Element>);
+ void handleStreamStart(const ProtocolHeader&);
+ //void handleHostnameResolved(const String& hostname, const HostAddress& address);
+
+ private:
+ bool resolving_;
+ JID remoteJID_;
+ String hostname_;
+ boost::shared_ptr<DNSSDService> resolver_;
+ ConnectionFactory* connectionFactory_;
+ };
+}