diff options
| author | Andrew Stitcher <astitcher@apache.org> | 2011-08-12 22:32:05 +0000 |
|---|---|---|
| committer | Andrew Stitcher <astitcher@apache.org> | 2011-08-12 22:32:05 +0000 |
| commit | 5e4e74053e0451f5a103820e99eac00992061b4c (patch) | |
| tree | 17e31c3aa347ecc0cf59001f3c82120481f5f6bd /cpp/src/qpid/sys/TCPIOPlugin.cpp | |
| parent | 6035aef61fe726180a918a57a93d66833eaca96a (diff) | |
| download | qpid-python-5e4e74053e0451f5a103820e99eac00992061b4c.tar.gz | |
QPID-3405: IPv6 support for Unix C++ ports:
- On the Listen side we create separate listening sockets for IPv4 and IPv6
making sure to not allow the IPv6 socket to run dual stack. This makes the
reported IPv4 addresses look "normal" and would allow us to turn control
IPv4/IPv6 listening separately.
- On the connect side we make sure to try all the addresses returned by
getaddrinfo() in order until we either find one that connects or have
tried all of them.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1157272 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/sys/TCPIOPlugin.cpp')
| -rw-r--r-- | cpp/src/qpid/sys/TCPIOPlugin.cpp | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/cpp/src/qpid/sys/TCPIOPlugin.cpp b/cpp/src/qpid/sys/TCPIOPlugin.cpp index 34338ce434..c5cc86c813 100644 --- a/cpp/src/qpid/sys/TCPIOPlugin.cpp +++ b/cpp/src/qpid/sys/TCPIOPlugin.cpp @@ -25,21 +25,22 @@ #include "qpid/Plugin.h" #include "qpid/sys/Socket.h" +#include "qpid/sys/SocketAddress.h" #include "qpid/sys/Poller.h" #include "qpid/broker/Broker.h" #include "qpid/log/Statement.h" #include <boost/bind.hpp> -#include <memory> +#include <boost/ptr_container/ptr_vector.hpp> namespace qpid { namespace sys { class AsynchIOProtocolFactory : public ProtocolFactory { const bool tcpNoDelay; - Socket listener; - const uint16_t listeningPort; - std::auto_ptr<AsynchAcceptor> acceptor; + boost::ptr_vector<Socket> listeners; + boost::ptr_vector<AsynchAcceptor> acceptors; + uint16_t listeningPort; public: AsynchIOProtocolFactory(const std::string& host, const std::string& port, int backlog, bool nodelay); @@ -71,15 +72,38 @@ static class TCPIOPlugin : public Plugin { "", boost::lexical_cast<std::string>(opts.port), opts.connectionBacklog, opts.tcpNoDelay)); - QPID_LOG(notice, "Listening on TCP port " << protocolt->getPort()); + QPID_LOG(notice, "Listening on TCP/TCP6 port " << protocolt->getPort()); broker->registerProtocolFactory("tcp", protocolt); } } } tcpPlugin; AsynchIOProtocolFactory::AsynchIOProtocolFactory(const std::string& host, const std::string& port, int backlog, bool nodelay) : - tcpNoDelay(nodelay), listeningPort(listener.listen(host, port, backlog)) -{} + tcpNoDelay(nodelay) +{ + SocketAddress sa(host, port); + + // We must have at least one resolved address + QPID_LOG(info, "Listening to: " << sa.asString()) + Socket* s = new Socket; + uint16_t lport = s->listen(sa, backlog); + QPID_LOG(debug, "Listened to: " << lport); + listeners.push_back(s); + + listeningPort = lport; + + // Try any other resolved addresses + while (sa.nextAddress()) { + // Hack to ensure that all listening connections are on the same port + sa.setAddrInfoPort(listeningPort); + QPID_LOG(info, "Listening to: " << sa.asString()) + Socket* s = new Socket; + uint16_t lport = s->listen(sa, backlog); + QPID_LOG(debug, "Listened to: " << lport); + listeners.push_back(s); + } + +} void AsynchIOProtocolFactory::established(Poller::shared_ptr poller, const Socket& s, ConnectionCodec::Factory* f, bool isClient) { @@ -111,10 +135,12 @@ uint16_t AsynchIOProtocolFactory::getPort() const { void AsynchIOProtocolFactory::accept(Poller::shared_ptr poller, ConnectionCodec::Factory* fact) { - acceptor.reset( - AsynchAcceptor::create(listener, - boost::bind(&AsynchIOProtocolFactory::established, this, poller, _1, fact, false))); - acceptor->start(poller); + for (unsigned i = 0; i<listeners.size(); ++i) { + acceptors.push_back( + AsynchAcceptor::create(listeners[i], + boost::bind(&AsynchIOProtocolFactory::established, this, poller, _1, fact, false))); + acceptors[i].start(poller); + } } void AsynchIOProtocolFactory::connectFailed( |
