Skip to content
Browse files

Support for listenting on a specific IP address.

Due to security considerations, it is often practically infeasible to deploy an
application that listens on IP addresses by default. This branch includes
changes which allow the user to explicitly specify an IP address when
publishing actors or groups.
  • Loading branch information...
1 parent 190b0b4 commit 2c84f9354ff3204a49c6d61a7e3210f69df24638 @mavam mavam committed
View
4 cppa/cppa.hpp
@@ -751,9 +751,11 @@ inline void await_all_others_done() {
* The connection is automatically closed if the lifetime of @p whom ends.
* @param whom Actor that should be published at @p port.
* @param port Unused TCP port.
+ * @param addr The IP address to listen to, or @p INADDR_ANY if @p addr is
+ * @p nullptr.
* @throws bind_failure
*/
-void publish(actor_ptr whom, std::uint16_t port);
+void publish(actor_ptr whom, std::uint16_t port, const char* addr = nullptr);
/**
* @brief Publishes @p whom using @p acceptor to handle incoming connections.
View
3 cppa/detail/ipv4_acceptor.hpp
@@ -42,7 +42,8 @@ class ipv4_acceptor : public util::acceptor {
public:
- static std::unique_ptr<util::acceptor> create(std::uint16_t port);
+ static std::unique_ptr<util::acceptor> create(std::uint16_t port,
+ const char* addr);
~ipv4_acceptor();
View
5 cppa/group.hpp
@@ -195,11 +195,12 @@ class group : public channel {
typedef intrusive_ptr<group> group_ptr;
/**
- * @brief Makes *all* local groups accessible via network on @p port.
+ * @brief Makes *all* local groups accessible via network on address @p addr
+ * and @p port.
* @throws bind_failure
* @throws network_error
*/
-void publish_local_groups_at(std::uint16_t port);
+void publish_local_groups_at(std::uint16_t port, const char* addr = nullptr);
} // namespace cppa
View
2 examples/group_server.cpp
@@ -49,7 +49,7 @@ int main(int argc, char** argv) {
return 2;
}
if (!args_valid) return 1;
- publish_local_groups_at(port);
+ publish_local_groups_at(port, "127.0.0.1");
cout << "type 'quit' to shutdown the server" << endl;
string line;
while (getline(cin, line)) {
View
4 src/group.cpp
@@ -107,10 +107,10 @@ struct group_nameserver : event_based_actor {
}
};
-void publish_local_groups_at(std::uint16_t port) {
+void publish_local_groups_at(std::uint16_t port, const char* addr) {
auto gn = spawn_hidden<group_nameserver>();
try {
- publish(gn, port);
+ publish(gn, port, addr);
}
catch (std::exception&) {
gn->enqueue(nullptr, make_any_tuple(atom("SHUTDOWN")));
View
12 src/ipv4_acceptor.cpp
@@ -42,6 +42,7 @@
#else
# include <netdb.h>
# include <unistd.h>
+# include <arpa/inet.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
@@ -97,7 +98,8 @@ bool accept_impl(util::io_stream_ptr_pair& result, native_socket_type fd, bool n
ipv4_acceptor::ipv4_acceptor(native_socket_type fd, bool nonblocking)
: m_fd(fd), m_is_nonblocking(nonblocking) { }
-std::unique_ptr<util::acceptor> ipv4_acceptor::create(std::uint16_t port) {
+std::unique_ptr<util::acceptor> ipv4_acceptor::create(std::uint16_t port,
+ const char* addr) {
native_socket_type sockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == invalid_socket) {
@@ -112,7 +114,13 @@ std::unique_ptr<util::acceptor> ipv4_acceptor::create(std::uint16_t port) {
struct sockaddr_in serv_addr;
memset((char*) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = INADDR_ANY;
+ if (! addr) {
+ serv_addr.sin_addr.s_addr = INADDR_ANY;
+ }
+ else if (inet_pton(AF_INET, addr, &serv_addr.sin_addr) <= 0) {
+ throw network_error("invalid IPv4 address");
+ }
+
serv_addr.sin_port = htons(port);
if (bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) {
throw bind_failure(errno);
View
4 src/unicast_network.cpp
@@ -89,8 +89,8 @@ actor_ptr remote_actor(util::io_stream_ptr_pair peer) {
pinfptr->node_id());
}
-void publish(actor_ptr whom, std::uint16_t port) {
- if (whom) publish(whom, detail::ipv4_acceptor::create(port));
+void publish(actor_ptr whom, std::uint16_t port, const char* addr) {
+ if (whom) publish(whom, detail::ipv4_acceptor::create(port, addr));
}
actor_ptr remote_actor(const char* host, std::uint16_t port) {
View
2 unit_testing/test__remote_actor.cpp
@@ -236,7 +236,7 @@ int main(int argc, char** argv) {
bool success = false;
do {
try {
- publish(self, port);
+ publish(self, port, "127.0.0.1");
success = true;
}
catch (bind_failure&) {

0 comments on commit 2c84f93

Please sign in to comment.
Something went wrong with that request. Please try again.