summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Stitcher <astitcher@apache.org>2012-11-16 14:27:24 +0000
committerAndrew Stitcher <astitcher@apache.org>2012-11-16 14:27:24 +0000
commit0f2cbbb74a584de138ff753c19012f3e396b1a75 (patch)
treee22e3fb761754a0b1b9bb2e3e3ab8ab7353b3de2
parentbba1059633e1c8af39b20ce785c7a89fdc2785d7 (diff)
downloadqpid-python-0f2cbbb74a584de138ff753c19012f3e396b1a75.tar.gz
QPID-3351: Provide ability to specify the network interfaces
Added to TCP (without specific port capability) git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1410364 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp93
1 files changed, 59 insertions, 34 deletions
diff --git a/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp b/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp
index 69f48228ad..da0bd31caa 100644
--- a/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp
+++ b/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp
@@ -28,6 +28,7 @@
#include "qpid/sys/AsynchIO.h"
#include "qpid/sys/Socket.h"
#include "qpid/sys/SocketAddress.h"
+#include "qpid/sys/SystemInfo.h"
#include "qpid/sys/Poller.h"
#include <boost/bind.hpp>
@@ -47,10 +48,7 @@ class AsynchIOProtocolFactory : public ProtocolFactory {
const bool tcpNoDelay;
public:
- AsynchIOProtocolFactory(const std::string& host, const std::string& port,
- int backlog, bool nodelay,
- Timer& timer, uint32_t maxTime,
- bool shouldListen);
+ AsynchIOProtocolFactory(const qpid::broker::Broker::Options& opts, Timer& timer, bool shouldListen);
void accept(Poller::shared_ptr, ConnectionCodec::Factory*);
void connect(Poller::shared_ptr, const std::string& host, const std::string& port,
ConnectionCodec::Factory*,
@@ -93,14 +91,9 @@ static class TCPIOPlugin : public Plugin {
bool shouldListen = !sslMultiplexEnabled();
ProtocolFactory::shared_ptr protocolt(
- new AsynchIOProtocolFactory(
- "", boost::lexical_cast<std::string>(opts.port),
- opts.connectionBacklog,
- opts.tcpNoDelay,
- broker->getTimer(), opts.maxNegotiateTime,
- shouldListen));
-
- if (shouldListen) {
+ new AsynchIOProtocolFactory(opts, broker->getTimer(),shouldListen));
+
+ if (shouldListen && protocolt->getPort()!=0 ) {
QPID_LOG(notice, "Listening on TCP/TCP6 port " << protocolt->getPort());
}
@@ -109,41 +102,73 @@ static class TCPIOPlugin : public Plugin {
}
} tcpPlugin;
-AsynchIOProtocolFactory::AsynchIOProtocolFactory(const std::string& host, const std::string& port,
- int backlog, bool nodelay,
- Timer& timer, uint32_t maxTime,
- bool shouldListen) :
+namespace {
+ // Expand list of Interfaces and addresses to a list of addresses
+ std::vector<std::string> expandInterfaces(const std::vector<std::string>& interfaces) {
+ std::vector<std::string> addresses;
+ // If there are no specific interfaces listed use a single "" to listen on every interface
+ if (interfaces.empty()) {
+ addresses.push_back("");
+ return addresses;
+ }
+ for (unsigned i = 0; i < interfaces.size(); ++i) {
+ const std::string& interface = interfaces[i];
+ if (!(SystemInfo::getInterfaceAddresses(interface, addresses))) {
+ // We don't have an interface of that name -
+ // Check for IPv6 ('[' ']') brackets and remove them
+ // then pass to be looked up directly
+ if (interface[0]=='[' && interface[interface.size()-1]==']') {
+ addresses.push_back(interface.substr(1, interface.size()-2));
+ } else {
+ addresses.push_back(interface);
+ }
+ }
+ }
+ return addresses;
+ }
+}
+
+AsynchIOProtocolFactory::AsynchIOProtocolFactory(const qpid::broker::Broker::Options& opts, Timer& timer, bool shouldListen) :
brokerTimer(timer),
- maxNegotiateTime(maxTime),
- tcpNoDelay(nodelay)
+ maxNegotiateTime(opts.maxNegotiateTime),
+ tcpNoDelay(opts.tcpNoDelay)
{
if (!shouldListen) {
- listeningPort = boost::lexical_cast<uint16_t>(port);
+ listeningPort = boost::lexical_cast<uint16_t>(opts.port);
return;
}
- SocketAddress sa(host, port);
-
- // We must have at least one resolved address
- QPID_LOG(info, "Listening to: " << sa.asString())
- Socket* s = createSocket();
- uint16_t lport = s->listen(sa, backlog);
- QPID_LOG(debug, "Listened to: " << lport);
- listeners.push_back(s);
+ std::vector<std::string> addresses = expandInterfaces(opts.listenInterfaces);
+ if (addresses.empty()) {
+ // We specified some interfaces, but couldn't find addresses for them
+ QPID_LOG(warning, "TCP/TCP6: No specified network interfaces found: Not Listening");
+ listeningPort = 0;
+ }
- listeningPort = lport;
+ for (unsigned i = 0; i<addresses.size(); ++i) {
+ QPID_LOG(debug, "Using interface: " << addresses[i]);
+ SocketAddress sa(addresses[i], boost::lexical_cast<std::string>(opts.port));
- // Try any other resolved addresses
- while (sa.nextAddress()) {
- // Hack to ensure that all listening connections are on the same port
- sa.setAddrInfoPort(listeningPort);
+ // We must have at least one resolved address
QPID_LOG(info, "Listening to: " << sa.asString())
Socket* s = createSocket();
- uint16_t lport = s->listen(sa, backlog);
+ uint16_t lport = s->listen(sa, opts.connectionBacklog);
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 = createSocket();
+ uint16_t lport = s->listen(sa, opts.connectionBacklog);
+ QPID_LOG(debug, "Listened to: " << lport);
+ listeners.push_back(s);
+ }
+ }
}
void AsynchIOProtocolFactory::established(Poller::shared_ptr poller, const Socket& s,