From 5d504472c63b7acaa7df99ff1097024cf463f1bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sat, 18 Jul 2009 23:06:17 +0200
Subject: Implement outgoing linklocal sessions.


diff --git a/Nim/main.cpp b/Nim/main.cpp
index 15c41c7..7ff4954 100644
--- a/Nim/main.cpp
+++ b/Nim/main.cpp
@@ -175,7 +175,9 @@ class Server {
 					if (linkLocalRoster_->hasItem(toJID)) {
 						boost::shared_ptr<OutgoingLinkLocalSession> outgoingSession(
 								new OutgoingLinkLocalSession(
-									selfJID_, toJID, linkLocalRoster_->getHostname(toJID),
+									selfJID_, toJID, 
+									linkLocalRoster_->getHostname(toJID),
+									linkLocalRoster_->getPort(toJID),
 									dnsSDService_, 
 									&payloadParserFactories_, &payloadSerializers_,
 									&boostConnectionFactory_));
diff --git a/Swiften/LinkLocal/LinkLocalRoster.cpp b/Swiften/LinkLocal/LinkLocalRoster.cpp
index 6809377..ca608a3 100644
--- a/Swiften/LinkLocal/LinkLocalRoster.cpp
+++ b/Swiften/LinkLocal/LinkLocalRoster.cpp
@@ -128,4 +128,13 @@ String LinkLocalRoster::getHostname(const JID& j) const {
 	return "";
 }
 
+int LinkLocalRoster::getPort(const JID& j) const {
+	for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) {
+		if (getJIDForService(i->first) == j) {
+			return i->second.port;
+		}
+	}
+	return 0;
+}
+
 }
diff --git a/Swiften/LinkLocal/LinkLocalRoster.h b/Swiften/LinkLocal/LinkLocalRoster.h
index bd774f4..c18d8fc 100644
--- a/Swiften/LinkLocal/LinkLocalRoster.h
+++ b/Swiften/LinkLocal/LinkLocalRoster.h
@@ -25,6 +25,7 @@ namespace Swift {
 
 			bool hasItem(const JID&) const;
 			String getHostname(const JID&) const;
+			int getPort(const JID&) const;
 
 		private:
 			RosterItemPayload getRosterItem(const DNSSDService::Service& service, const DNSSDService::ResolveResult& info) const;
diff --git a/Swiften/LinkLocal/LinkLocalSession.cpp b/Swiften/LinkLocal/LinkLocalSession.cpp
index a308686..0f106ae 100644
--- a/Swiften/LinkLocal/LinkLocalSession.cpp
+++ b/Swiften/LinkLocal/LinkLocalSession.cpp
@@ -47,8 +47,13 @@ void LinkLocalSession::sendStanza(boost::shared_ptr<Stanza> stanza) {
 	xmppLayer->writeElement(stanza);
 }
 
-void LinkLocalSession::handleDisconnected(const boost::optional<Connection::Error>&) {
-	onSessionFinished();
+void LinkLocalSession::handleDisconnected(const boost::optional<Connection::Error>& connectionError) {
+	if (connectionError) {
+		onSessionFinished(boost::optional<Error>(ConnectionError));
+	}
+	else {
+		onSessionFinished(boost::optional<Error>());
+	}
 }
 
 void LinkLocalSession::setInitialized() {
diff --git a/Swiften/LinkLocal/LinkLocalSession.h b/Swiften/LinkLocal/LinkLocalSession.h
index 9a7ac13..6629a2a 100644
--- a/Swiften/LinkLocal/LinkLocalSession.h
+++ b/Swiften/LinkLocal/LinkLocalSession.h
@@ -2,6 +2,7 @@
 
 #include <boost/shared_ptr.hpp>
 #include <boost/signal.hpp>
+#include <boost/optional.hpp>
 #include <boost/enable_shared_from_this.hpp>
 
 #include "Swiften/JID/JID.h"
@@ -22,6 +23,8 @@ namespace Swift {
 	class LinkLocalSession : 
 			public boost::enable_shared_from_this<LinkLocalSession> {
 		public:
+			enum Error { ConnectionError, UnknownError };
+
 			LinkLocalSession(
 					const JID& localJID,
 					boost::shared_ptr<Connection> connection,
@@ -39,7 +42,7 @@ namespace Swift {
 			virtual void start() = 0;
 
 			boost::signal<void (boost::shared_ptr<Stanza>)> onStanzaReceived;
-			boost::signal<void ()> onSessionFinished;
+			boost::signal<void (boost::optional<Error>)> onSessionFinished;
 			boost::signal<void ()> onSessionStarted;
 			boost::signal<void (const ByteArray&)> onDataWritten;
 			boost::signal<void (const ByteArray&)> onDataRead;
diff --git a/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp b/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp
index 57f3154..f32bcdd 100644
--- a/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp
+++ b/Swiften/LinkLocal/OutgoingLinkLocalSession.cpp
@@ -1,9 +1,14 @@
+// TODO: Send back errors if we can't make a connection
+
 #include "Swiften/LinkLocal/OutgoingLinkLocalSession.h"
 
 #include <boost/bind.hpp>
 
 #include "Swiften/Elements/ProtocolHeader.h"
 #include "Swiften/Network/Connection.h"
+#include "Swiften/Network/ConnectionFactory.h"
+#include "Swiften/Network/HostAddress.h"
+#include "Swiften/Network/HostAddressPort.h"
 #include "Swiften/StreamStack/StreamStack.h"
 #include "Swiften/LinkLocal/DNSSDService.h"
 #include "Swiften/StreamStack/ConnectionLayer.h"
@@ -18,6 +23,7 @@ OutgoingLinkLocalSession::OutgoingLinkLocalSession(
 		const JID& localJID,
 		const JID& remoteJID,
 		const String& hostname,
+		int port,
 		boost::shared_ptr<DNSSDService> resolver,
 		PayloadParserFactoryCollection* payloadParserFactories, 
 		PayloadSerializerCollection* payloadSerializers,
@@ -30,34 +36,46 @@ OutgoingLinkLocalSession::OutgoingLinkLocalSession(
 			resolving_(false),
 			remoteJID_(remoteJID),
 			hostname_(hostname),
+			port_(port),
 			resolver_(resolver),
 			connectionFactory_(connectionFactory) {
 }
 
 void OutgoingLinkLocalSession::start() {
 	resolving_ = true;
-	//resolver_->onHostnameResolved.connect(boost::bind(&OutgoingLinkLocalSession::handleHostnameResolved, this, _1, _2));
+	resolver_->onHostnameResolved.connect(boost::bind(&OutgoingLinkLocalSession::handleHostnameResolved, boost::dynamic_pointer_cast<OutgoingLinkLocalSession>(shared_from_this()), _1, _2));
+	resolver_->resolveHostname(hostname_);
 }
 
-#if 0
-void OutgoingLinkLocalSession::handleHostnameResolved(const String& hostname, const HostAddress&) {
+void OutgoingLinkLocalSession::handleHostnameResolved(const String& hostname, const boost::optional<HostAddress>& address) {
 	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::
+			if (address) {
+				boost::shared_ptr<Connection> connection = connectionFactory_->createConnection();
+				setConnection(connection);
+				initializeStreamStack();
+				connection->onConnected.connect(boost::bind(&OutgoingLinkLocalSession::handleConnected, boost::dynamic_pointer_cast<OutgoingLinkLocalSession>(shared_from_this())));
+				connection->connect(HostAddressPort(*address, port_));
+			}
+			else {
+				onSessionFinished(boost::optional<Error>(UnknownError));
+			}
 		}
 	}
 }
-#endif
 
-void OutgoingLinkLocalSession::handleStreamStart(const ProtocolHeader&) {
+void OutgoingLinkLocalSession::handleConnected() {
 	ProtocolHeader header;
 	header.setFrom(getLocalJID());
 	getXMPPLayer()->writeHeader(header);
+}
+
+void OutgoingLinkLocalSession::handleStreamStart(const ProtocolHeader&) {
+	foreach(const boost::shared_ptr<Stanza>& stanza, queuedStanzas_) {
+		LinkLocalSession::sendStanza(stanza);
+	}
+	queuedStanzas_.clear();
 	setInitialized();
 }
 
@@ -70,5 +88,14 @@ void OutgoingLinkLocalSession::handleElement(boost::shared_ptr<Element> element)
 	}
 }
 
+void OutgoingLinkLocalSession::sendStanza(boost::shared_ptr<Stanza> stanza) {
+	if (isInitialized()) {
+		LinkLocalSession::sendStanza(stanza);
+	}
+	else {
+		queuedStanzas_.push_back(stanza);
+	}
+}
+
 
 }
diff --git a/Swiften/LinkLocal/OutgoingLinkLocalSession.h b/Swiften/LinkLocal/OutgoingLinkLocalSession.h
index ae1e86b..abbec80 100644
--- a/Swiften/LinkLocal/OutgoingLinkLocalSession.h
+++ b/Swiften/LinkLocal/OutgoingLinkLocalSession.h
@@ -3,6 +3,7 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/signal.hpp>
 #include <boost/enable_shared_from_this.hpp>
+#include <vector>
 
 #include "Swiften/LinkLocal/LinkLocalSession.h"
 #include "Swiften/JID/JID.h"
@@ -16,12 +17,13 @@ namespace Swift {
 	class PayloadSerializerCollection;
 	class DNSSDService;
 
-	class OutgoingLinkLocalSession : public LinkLocalSession, public boost::enable_shared_from_this<OutgoingLinkLocalSession> {
+	class OutgoingLinkLocalSession : public LinkLocalSession {
 		public:
 			OutgoingLinkLocalSession(
 					const JID& localJID,
 					const JID& remoteJID,
 					const String& hostname,
+					int port,
 					boost::shared_ptr<DNSSDService> resolver,
 					PayloadParserFactoryCollection* payloadParserFactories, 
 					PayloadSerializerCollection* payloadSerializers,
@@ -33,16 +35,21 @@ namespace Swift {
 
 			void start();
 
+			void sendStanza(boost::shared_ptr<Stanza> stanza);
+
 		private:
 			void handleElement(boost::shared_ptr<Element>);
 			void handleStreamStart(const ProtocolHeader&);
-			//void handleHostnameResolved(const String& hostname, const HostAddress& address);
+			void handleHostnameResolved(const String& hostname, const boost::optional<HostAddress>& address);
+			void handleConnected();
 
 		private:
 			bool resolving_;
 			JID remoteJID_;
 			String hostname_;
+			int port_;
 			boost::shared_ptr<DNSSDService> resolver_;
+			std::vector<boost::shared_ptr<Stanza> > queuedStanzas_;
 			ConnectionFactory* connectionFactory_;
 	};
 }
-- 
cgit v0.10.2-6-g49f6