From 292967c02ffc2ff0b53df526af2965a03916290c Mon Sep 17 00:00:00 2001 From: dknn Date: Mon, 16 Jul 2012 14:00:56 +0200 Subject: Better handling of udp bind errors diff --git a/Swiften/Network/BoostUDPSocket.cpp b/Swiften/Network/BoostUDPSocket.cpp index 4405091..0f66b92 100644 --- a/Swiften/Network/BoostUDPSocket.cpp +++ b/Swiften/Network/BoostUDPSocket.cpp @@ -52,16 +52,22 @@ BoostUDPSocket::~BoostUDPSocket() { } -void BoostUDPSocket::bind(const HostAddressPort& addr) +int BoostUDPSocket::bind(const HostAddressPort& addr) { if (!socket_.is_open()) socket_.open(addr.toEndpoint().protocol()); - socket_.bind(addr.toEndpoint()); + + boost::system::error_code errorCode; + socket_.bind(addr.toEndpoint(), errorCode); + if (errorCode) + return 0; + + return socket_.local_endpoint().port(); } -void BoostUDPSocket::bindOnAvailablePort(const HostAddress &addr) +int BoostUDPSocket::bindOnAvailablePort(const HostAddress& addr) { - bind(HostAddressPort(addr, 0)); + return bind(HostAddressPort(addr, 0)); } void BoostUDPSocket::listen() @@ -70,7 +76,7 @@ void BoostUDPSocket::listen() doRead(); } -void BoostUDPSocket::connect(const HostAddressPort &address) +void BoostUDPSocket::connect(const HostAddressPort& address) { // if (!socket_.is_open()) // socket_.open(boost::asio::ip::udp::v4()); diff --git a/Swiften/Network/BoostUDPSocket.h b/Swiften/Network/BoostUDPSocket.h index bb5014e..d1b2e0d 100644 --- a/Swiften/Network/BoostUDPSocket.h +++ b/Swiften/Network/BoostUDPSocket.h @@ -37,8 +37,8 @@ namespace Swift { return ref(new BoostUDPSocket(ioService, eventLoop)); } - virtual void bind(const HostAddressPort& addr); - virtual void bindOnAvailablePort(const HostAddress& addr); + virtual int bind(const HostAddressPort& addr); + virtual int bindOnAvailablePort(const HostAddress& addr); virtual void listen(); virtual void connect(const HostAddressPort& address); virtual void connectToFirstIncoming(); diff --git a/Swiften/Network/UDPSocket.h b/Swiften/Network/UDPSocket.h index 3a239f8..2092c61 100644 --- a/Swiften/Network/UDPSocket.h +++ b/Swiften/Network/UDPSocket.h @@ -20,8 +20,8 @@ namespace Swift { virtual ~UDPSocket() {} - virtual void bind(const HostAddressPort& addr) = 0; - virtual void bindOnAvailablePort(const HostAddress& addr) = 0; + virtual int bind(const HostAddressPort& addr) = 0; + virtual int bindOnAvailablePort(const HostAddress& addr) = 0; virtual void listen() = 0; virtual void connect(const HostAddressPort& address) = 0; virtual void connectToFirstIncoming() = 0; diff --git a/Swiften/ScreenSharing/IncomingScreenSharing.cpp b/Swiften/ScreenSharing/IncomingScreenSharing.cpp index 2ddfab9..3807a0f 100644 --- a/Swiften/ScreenSharing/IncomingScreenSharing.cpp +++ b/Swiften/ScreenSharing/IncomingScreenSharing.cpp @@ -45,7 +45,14 @@ void IncomingScreenSharing::cancel() void IncomingScreenSharing::accept() { JingleRawUDPTransportPayload::ref transport = boost::make_shared(); - addBestCandidate(transport); + if (!addBestCandidate(transport)) { + SWIFT_LOG(error) << "Screen sharing: Unable to listening on any interface" << std::endl; + jingleSession->sendTerminate(JinglePayload::Reason::FailedTransport); + onStateChange(ScreenSharing::Failed); + onFinished(); + return; + } + JingleRTPDescription::ref desc = initialContent->getDescription(); if (!desc->getPayloadTypes().empty()) payloadTypeUsed = desc->getPayloadTypes().front(); diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp index 906bd68..005e204 100644 --- a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp +++ b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp @@ -50,8 +50,6 @@ void OutgoingScreenSharing::cancel() void OutgoingScreenSharing::start(unsigned int width, unsigned int height) { //onStateChange(ScreenSharing::WaitingForStart); - SWIFT_LOG(debug) << "Screen sharing: start" << std::endl; - this->width = width; this->height = height; @@ -60,13 +58,17 @@ void OutgoingScreenSharing::start(unsigned int width, unsigned int height) desc->addPayloadType(payloadTypeUsed); JingleRawUDPTransportPayload::ref transport = boost::make_shared(); - addBestCandidate(transport); - - jingleSession->sendInitiate(contentID, desc, transport); - onStateChange(ScreenSharing::WaitingForAccept); - - serverSocket->onConnected.connect(boost::bind(&OutgoingScreenSharing::handleSocketConnected, this)); - serverSocket->connectToFirstIncoming(); + if (addBestCandidate(transport)) { + SWIFT_LOG(debug) << "Screen sharing: start" << std::endl; + jingleSession->sendInitiate(contentID, desc, transport); + serverSocket->onConnected.connect(boost::bind(&OutgoingScreenSharing::handleSocketConnected, this)); + serverSocket->connectToFirstIncoming(); + onStateChange(ScreenSharing::WaitingForAccept); + } else { + SWIFT_LOG(error) << "Screen sharing: Unable to listening on any interface" << std::endl; + onStateChange(ScreenSharing::Failed); + onFinished(); + } } void OutgoingScreenSharing::addImage(const Image &image) diff --git a/Swiften/ScreenSharing/ScreenSharing.cpp b/Swiften/ScreenSharing/ScreenSharing.cpp index c6c78e0..0a477c2 100644 --- a/Swiften/ScreenSharing/ScreenSharing.cpp +++ b/Swiften/ScreenSharing/ScreenSharing.cpp @@ -50,10 +50,11 @@ bool ScreenSharing::addBestCandidate(boost::shared_ptr interfaces = env.getNetworkInterfaces(); + serverSocket = udpSocketFactory->createUDPSocket(); + // Find the first ip which is not loopback - foreach (const NetworkInterface& interface, interfaces) { + /*foreach (const NetworkInterface& interface, interfaces) { if (!interface.isLoopback() && !interface.getAddresses().empty()) { // exclude loopback - serverSocket = udpSocketFactory->createUDPSocket(); serverSocket->bindOnAvailablePort(interface.getAddresses().front()); candidate.hostAddressPort = serverSocket->getLocalAddress(); @@ -62,19 +63,34 @@ bool ScreenSharing::addBestCandidate(boost::shared_ptrbindOnAvailablePort(addr); + if (!port) + continue; + + candidate.hostAddressPort = serverSocket->getLocalAddress(); + candidate.type = JingleRawUDPTransportPayload::Candidate::Host; + transport->addCandidate(candidate); + + return true; + } + } } // else loopback for self sharing - if (!interfaces.empty() && !interfaces.front().getAddresses().empty()) { - serverSocket = udpSocketFactory->createUDPSocket(); - serverSocket->bindOnAvailablePort(interfaces.front().getAddresses().front()); - - candidate.hostAddressPort = serverSocket->getLocalAddress(); - candidate.type = JingleRawUDPTransportPayload::Candidate::Host; - transport->addCandidate(candidate); - - return true; - } + /*if (!interfaces.empty() && !interfaces.front().getAddresses().empty()) { + int port = serverSocket->bindOnAvailablePort(interfaces.front().getAddresses().front()); + if (port) { + candidate.hostAddressPort = serverSocket->getLocalAddress(); + candidate.type = JingleRawUDPTransportPayload::Candidate::Host; + transport->addCandidate(candidate); + return true; + } + }*/ return false; } -- cgit v0.10.2-6-g49f6