diff options
author | Remko Tronçon <git@el-tramo.be> | 2009-07-18 19:04:32 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2009-07-18 20:40:56 (GMT) |
commit | 4457bc810a326de8d7895b3f2ff36ade5f1ae1a0 (patch) | |
tree | 1556c4b0190453897d4799d23b05e651b0bb8a32 /Swiften/LinkLocal | |
parent | 4052a822acd9da9dab6a8e2343c6170fb08dd8d6 (diff) | |
download | swift-contrib-4457bc810a326de8d7895b3f2ff36ade5f1ae1a0.zip swift-contrib-4457bc810a326de8d7895b3f2ff36ade5f1ae1a0.tar.bz2 |
Implement incoming linklocal connections.
Diffstat (limited to 'Swiften/LinkLocal')
-rw-r--r-- | Swiften/LinkLocal/AppleDNSSDService.cpp | 4 | ||||
-rw-r--r-- | Swiften/LinkLocal/IncomingLinkLocalSession.cpp | 69 | ||||
-rw-r--r-- | Swiften/LinkLocal/IncomingLinkLocalSession.h | 39 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalRoster.cpp | 21 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalRoster.h | 3 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalSession.cpp | 59 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalSession.h | 82 | ||||
-rw-r--r-- | Swiften/LinkLocal/Makefile.inc | 5 | ||||
-rw-r--r-- | Swiften/LinkLocal/OutgoingLinkLocalSession.cpp | 74 | ||||
-rw-r--r-- | Swiften/LinkLocal/OutgoingLinkLocalSession.h | 48 |
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_; + }; +} |