diff --git a/dep/libzmq/CMakeLists.txt b/dep/libzmq/CMakeLists.txt
index 05551937dc2..a8fa5764cd2 100644
--- a/dep/libzmq/CMakeLists.txt
+++ b/dep/libzmq/CMakeLists.txt
@@ -14,6 +14,9 @@ set (libzmq_STAT_SRCS
src/io_object.cpp
src/io_thread.cpp
src/ip.cpp
+ src/ipc_address.cpp
+ src/ipc_connecter.cpp
+ src/ipc_listener.cpp
src/lb.cpp
src/kqueue.cpp
src/mailbox.cpp
diff --git a/dep/libzmq/src/ipc_address.cpp b/dep/libzmq/src/ipc_address.cpp
new file mode 100644
index 00000000000..137ee849595
--- /dev/null
+++ b/dep/libzmq/src/ipc_address.cpp
@@ -0,0 +1,106 @@
+/*
+ Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
+
+ This file is part of libzmq, the ZeroMQ core engine in C++.
+
+ libzmq is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ As a special exception, the Contributors give you permission to link
+ this library with independent modules to produce an executable,
+ regardless of the license terms of these independent modules, and to
+ copy and distribute the resulting executable under terms of your choice,
+ provided that you also meet, for each linked independent module, the
+ terms and conditions of the license of that module. An independent
+ module is a module which is not derived from or based on this library.
+ If you modify this library, you must extend this exception to your
+ version of the library.
+
+ libzmq is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+*/
+
+#include "precompiled.hpp"
+#include "ipc_address.hpp"
+
+#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
+
+#include "err.hpp"
+
+#include
+#include
+
+zmq::ipc_address_t::ipc_address_t ()
+{
+ memset (&address, 0, sizeof address);
+}
+
+zmq::ipc_address_t::ipc_address_t (const sockaddr *sa, socklen_t sa_len)
+{
+ zmq_assert (sa && sa_len > 0);
+
+ memset (&address, 0, sizeof address);
+ if (sa->sa_family == AF_UNIX)
+ memcpy(&address, sa, sa_len);
+}
+
+zmq::ipc_address_t::~ipc_address_t ()
+{
+}
+
+int zmq::ipc_address_t::resolve (const char *path_)
+{
+ if (strlen (path_) >= sizeof address.sun_path) {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+ if (path_ [0] == '@' && !path_ [1]) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ address.sun_family = AF_UNIX;
+ strcpy (address.sun_path, path_);
+ /* Abstract sockets start with '\0' */
+ if (path_ [0] == '@')
+ *address.sun_path = '\0';
+ return 0;
+}
+
+int zmq::ipc_address_t::to_string (std::string &addr_)
+{
+ if (address.sun_family != AF_UNIX) {
+ addr_.clear ();
+ return -1;
+ }
+
+ std::stringstream s;
+ s << "ipc://";
+ if (!address.sun_path [0] && address.sun_path [1])
+ s << "@" << address.sun_path + 1;
+ else
+ s << address.sun_path;
+ addr_ = s.str ();
+ return 0;
+}
+
+const sockaddr *zmq::ipc_address_t::addr () const
+{
+ return (sockaddr*) &address;
+}
+
+socklen_t zmq::ipc_address_t::addrlen () const
+{
+ if (!address.sun_path [0] && address.sun_path [1])
+ return (socklen_t) strlen (address.sun_path + 1) + sizeof (sa_family_t) + 1;
+ return (socklen_t) sizeof address;
+}
+
+#endif
diff --git a/dep/libzmq/src/ipc_connecter.cpp b/dep/libzmq/src/ipc_connecter.cpp
new file mode 100644
index 00000000000..48793e8c4a7
--- /dev/null
+++ b/dep/libzmq/src/ipc_connecter.cpp
@@ -0,0 +1,278 @@
+/*
+ Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
+
+ This file is part of libzmq, the ZeroMQ core engine in C++.
+
+ libzmq is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ As a special exception, the Contributors give you permission to link
+ this library with independent modules to produce an executable,
+ regardless of the license terms of these independent modules, and to
+ copy and distribute the resulting executable under terms of your choice,
+ provided that you also meet, for each linked independent module, the
+ terms and conditions of the license of that module. An independent
+ module is a module which is not derived from or based on this library.
+ If you modify this library, you must extend this exception to your
+ version of the library.
+
+ libzmq is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+*/
+
+#include "precompiled.hpp"
+#include "ipc_connecter.hpp"
+
+#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
+
+#include
+#include
+
+#include "stream_engine.hpp"
+#include "io_thread.hpp"
+#include "random.hpp"
+#include "err.hpp"
+#include "ip.hpp"
+#include "address.hpp"
+#include "ipc_address.hpp"
+#include "session_base.hpp"
+
+#include
+#include
+#include
+#include
+
+zmq::ipc_connecter_t::ipc_connecter_t (class io_thread_t *io_thread_,
+ class session_base_t *session_, const options_t &options_,
+ const address_t *addr_, bool delayed_start_) :
+ own_t (io_thread_, options_),
+ io_object_t (io_thread_),
+ addr (addr_),
+ s (retired_fd),
+ handle_valid (false),
+ delayed_start (delayed_start_),
+ timer_started (false),
+ session (session_),
+ current_reconnect_ivl(options.reconnect_ivl)
+{
+ zmq_assert (addr);
+ zmq_assert (addr->protocol == "ipc");
+ addr->to_string (endpoint);
+ socket = session-> get_socket();
+}
+
+zmq::ipc_connecter_t::~ipc_connecter_t ()
+{
+ zmq_assert (!timer_started);
+ zmq_assert (!handle_valid);
+ zmq_assert (s == retired_fd);
+}
+
+void zmq::ipc_connecter_t::process_plug ()
+{
+ if (delayed_start)
+ add_reconnect_timer ();
+ else
+ start_connecting ();
+}
+
+void zmq::ipc_connecter_t::process_term (int linger_)
+{
+ if (timer_started) {
+ cancel_timer (reconnect_timer_id);
+ timer_started = false;
+ }
+
+ if (handle_valid) {
+ rm_fd (handle);
+ handle_valid = false;
+ }
+
+ if (s != retired_fd)
+ close ();
+
+ own_t::process_term (linger_);
+}
+
+void zmq::ipc_connecter_t::in_event ()
+{
+ // We are not polling for incoming data, so we are actually called
+ // because of error here. However, we can get error on out event as well
+ // on some platforms, so we'll simply handle both events in the same way.
+ out_event ();
+}
+
+void zmq::ipc_connecter_t::out_event ()
+{
+ fd_t fd = connect ();
+ rm_fd (handle);
+ handle_valid = false;
+
+ // Handle the error condition by attempt to reconnect.
+ if (fd == retired_fd) {
+ close ();
+ add_reconnect_timer();
+ return;
+ }
+ // Create the engine object for this connection.
+ stream_engine_t *engine = new (std::nothrow)
+ stream_engine_t (fd, options, endpoint);
+ alloc_assert (engine);
+
+ // Attach the engine to the corresponding session object.
+ send_attach (session, engine);
+
+ // Shut the connecter down.
+ terminate ();
+
+ socket->event_connected (endpoint, fd);
+}
+
+void zmq::ipc_connecter_t::timer_event (int id_)
+{
+ zmq_assert (id_ == reconnect_timer_id);
+ timer_started = false;
+ start_connecting ();
+}
+
+void zmq::ipc_connecter_t::start_connecting ()
+{
+ // Open the connecting socket.
+ int rc = open ();
+
+ // Connect may succeed in synchronous manner.
+ if (rc == 0) {
+ handle = add_fd (s);
+ handle_valid = true;
+ out_event ();
+ }
+
+ // Connection establishment may be delayed. Poll for its completion.
+ else
+ if (rc == -1 && errno == EINPROGRESS) {
+ handle = add_fd (s);
+ handle_valid = true;
+ set_pollout (handle);
+ socket->event_connect_delayed (endpoint, zmq_errno());
+ }
+
+ // Handle any other error condition by eventual reconnect.
+ else {
+ if (s != retired_fd)
+ close ();
+ add_reconnect_timer ();
+ }
+}
+
+void zmq::ipc_connecter_t::add_reconnect_timer()
+{
+ int rc_ivl = get_new_reconnect_ivl();
+ add_timer (rc_ivl, reconnect_timer_id);
+ socket->event_connect_retried (endpoint, rc_ivl);
+ timer_started = true;
+}
+
+int zmq::ipc_connecter_t::get_new_reconnect_ivl ()
+{
+ // The new interval is the current interval + random value.
+ int this_interval = current_reconnect_ivl +
+ (generate_random () % options.reconnect_ivl);
+
+ // Only change the current reconnect interval if the maximum reconnect
+ // interval was set and if it's larger than the reconnect interval.
+ if (options.reconnect_ivl_max > 0 &&
+ options.reconnect_ivl_max > options.reconnect_ivl) {
+
+ // Calculate the next interval
+ current_reconnect_ivl = current_reconnect_ivl * 2;
+ if(current_reconnect_ivl >= options.reconnect_ivl_max) {
+ current_reconnect_ivl = options.reconnect_ivl_max;
+ }
+ }
+ return this_interval;
+}
+
+int zmq::ipc_connecter_t::open ()
+{
+ zmq_assert (s == retired_fd);
+
+ // Create the socket.
+ s = open_socket (AF_UNIX, SOCK_STREAM, 0);
+ if (s == -1)
+ return -1;
+
+ // Set the non-blocking flag.
+ unblock_socket (s);
+
+ // Connect to the remote peer.
+ int rc = ::connect (
+ s, addr->resolved.ipc_addr->addr (),
+ addr->resolved.ipc_addr->addrlen ());
+
+ // Connect was successful immediately.
+ if (rc == 0)
+ return 0;
+
+ // Translate other error codes indicating asynchronous connect has been
+ // launched to a uniform EINPROGRESS.
+ if (rc == -1 && errno == EINTR) {
+ errno = EINPROGRESS;
+ return -1;
+ }
+
+ // Forward the error.
+ return -1;
+}
+
+int zmq::ipc_connecter_t::close ()
+{
+ zmq_assert (s != retired_fd);
+ int rc = ::close (s);
+ errno_assert (rc == 0);
+ socket->event_closed (endpoint, s);
+ s = retired_fd;
+ return 0;
+}
+
+zmq::fd_t zmq::ipc_connecter_t::connect ()
+{
+ // Following code should handle both Berkeley-derived socket
+ // implementations and Solaris.
+ int err = 0;
+#if defined ZMQ_HAVE_HPUX
+ int len = sizeof (err);
+#else
+ socklen_t len = sizeof (err);
+#endif
+ int rc = getsockopt (s, SOL_SOCKET, SO_ERROR, (char*) &err, &len);
+ if (rc == -1) {
+ if (errno == ENOPROTOOPT)
+ errno = 0;
+ err = errno;
+ }
+ if (err != 0) {
+
+ // Assert if the error was caused by 0MQ bug.
+ // Networking problems are OK. No need to assert.
+ errno = err;
+ errno_assert (errno == ECONNREFUSED || errno == ECONNRESET ||
+ errno == ETIMEDOUT || errno == EHOSTUNREACH ||
+ errno == ENETUNREACH || errno == ENETDOWN);
+
+ return retired_fd;
+ }
+
+ fd_t result = s;
+ s = retired_fd;
+ return result;
+}
+
+#endif
+
diff --git a/dep/libzmq/src/ipc_listener.cpp b/dep/libzmq/src/ipc_listener.cpp
new file mode 100644
index 00000000000..40e9ecba612
--- /dev/null
+++ b/dep/libzmq/src/ipc_listener.cpp
@@ -0,0 +1,427 @@
+/*
+ Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
+
+ This file is part of libzmq, the ZeroMQ core engine in C++.
+
+ libzmq is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ As a special exception, the Contributors give you permission to link
+ this library with independent modules to produce an executable,
+ regardless of the license terms of these independent modules, and to
+ copy and distribute the resulting executable under terms of your choice,
+ provided that you also meet, for each linked independent module, the
+ terms and conditions of the license of that module. An independent
+ module is a module which is not derived from or based on this library.
+ If you modify this library, you must extend this exception to your
+ version of the library.
+
+ libzmq is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+*/
+
+#include "precompiled.hpp"
+#include "ipc_listener.hpp"
+
+#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
+
+#include
+
+#include
+
+#include "stream_engine.hpp"
+#include "ipc_address.hpp"
+#include "io_thread.hpp"
+#include "session_base.hpp"
+#include "config.hpp"
+#include "err.hpp"
+#include "ip.hpp"
+#include "socket_base.hpp"
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef ZMQ_HAVE_LOCAL_PEERCRED
+# include
+# include
+#endif
+#ifdef ZMQ_HAVE_SO_PEERCRED
+# include
+# include
+# include
+# if defined ZMQ_HAVE_OPENBSD
+# define ucred sockpeercred
+# endif
+#endif
+
+const char *zmq::ipc_listener_t::tmp_env_vars[] = {
+ "TMPDIR",
+ "TEMPDIR",
+ "TMP",
+ 0 // Sentinel
+};
+
+int zmq::ipc_listener_t::create_wildcard_address(std::string& path_,
+ std::string& file_)
+{
+ std::string tmp_path;
+
+ // If TMPDIR, TEMPDIR, or TMP are available and are directories, create
+ // the socket directory there.
+ const char **tmp_env = tmp_env_vars;
+ while ( tmp_path.empty() && *tmp_env != 0 ) {
+ char *tmpdir = getenv(*tmp_env);
+ struct stat statbuf;
+
+ // Confirm it is actually a directory before trying to use
+ if ( tmpdir != 0 && ::stat(tmpdir, &statbuf) == 0 && S_ISDIR(statbuf.st_mode) ) {
+ tmp_path.assign(tmpdir);
+ if ( *(tmp_path.rbegin()) != '/' ) {
+ tmp_path.push_back('/');
+ }
+ }
+
+ // Try the next environment variable
+ ++tmp_env;
+ }
+
+ // Append a directory name
+ tmp_path.append("tmpXXXXXX");
+
+ // We need room for tmp_path + trailing NUL
+ std::vector buffer(tmp_path.length()+1);
+ strcpy (&buffer[0], tmp_path.c_str ());
+
+#ifdef HAVE_MKDTEMP
+ // Create the directory. POSIX requires that mkdtemp() creates the
+ // directory with 0700 permissions, meaning the only possible race
+ // with socket creation could be the same user. However, since
+ // each socket is created in a directory created by mkdtemp(), and
+ // mkdtemp() guarantees a unique directory name, there will be no
+ // collision.
+ if (mkdtemp (&buffer[0]) == 0) {
+ return -1;
+ }
+
+ path_.assign (&buffer[0]);
+ file_.assign (path_ + "/socket");
+#else
+ // Silence -Wunused-parameter. #pragma and __attribute__((unused)) are not
+ // very portable unfortunately...
+ (void) path_;
+ int fd = mkstemp (&buffer[0]);
+ if (fd == -1)
+ return -1;
+ ::close (fd);
+
+ file_.assign (&buffer[0]);
+#endif
+
+ return 0;
+}
+
+zmq::ipc_listener_t::ipc_listener_t (io_thread_t *io_thread_,
+ socket_base_t *socket_, const options_t &options_) :
+ own_t (io_thread_, options_),
+ io_object_t (io_thread_),
+ has_file (false),
+ s (retired_fd),
+ socket (socket_)
+{
+}
+
+zmq::ipc_listener_t::~ipc_listener_t ()
+{
+ zmq_assert (s == retired_fd);
+}
+
+void zmq::ipc_listener_t::process_plug ()
+{
+ // Start polling for incoming connections.
+ handle = add_fd (s);
+ set_pollin (handle);
+}
+
+void zmq::ipc_listener_t::process_term (int linger_)
+{
+ rm_fd (handle);
+ close ();
+ own_t::process_term (linger_);
+}
+
+void zmq::ipc_listener_t::in_event ()
+{
+ fd_t fd = accept ();
+
+ // If connection was reset by the peer in the meantime, just ignore it.
+ // TODO: Handle specific errors like ENFILE/EMFILE etc.
+ if (fd == retired_fd) {
+ socket->event_accept_failed (endpoint, zmq_errno());
+ return;
+ }
+
+ // Create the engine object for this connection.
+ stream_engine_t *engine = new (std::nothrow)
+ stream_engine_t (fd, options, endpoint);
+ alloc_assert (engine);
+
+ // Choose I/O thread to run connecter in. Given that we are already
+ // running in an I/O thread, there must be at least one available.
+ io_thread_t *io_thread = choose_io_thread (options.affinity);
+ zmq_assert (io_thread);
+
+ // Create and launch a session object.
+ session_base_t *session = session_base_t::create (io_thread, false, socket,
+ options, NULL);
+ errno_assert (session);
+ session->inc_seqnum ();
+ launch_child (session);
+ send_attach (session, engine, false);
+ socket->event_accepted (endpoint, fd);
+}
+
+int zmq::ipc_listener_t::get_address (std::string &addr_)
+{
+ struct sockaddr_storage ss;
+#ifdef ZMQ_HAVE_HPUX
+ int sl = sizeof (ss);
+#else
+ socklen_t sl = sizeof (ss);
+#endif
+ int rc = getsockname (s, (sockaddr *) &ss, &sl);
+ if (rc != 0) {
+ addr_.clear ();
+ return rc;
+ }
+
+ ipc_address_t addr ((struct sockaddr *) &ss, sl);
+ return addr.to_string (addr_);
+}
+
+int zmq::ipc_listener_t::set_address (const char *addr_)
+{
+ // Create addr on stack for auto-cleanup
+ std::string addr (addr_);
+
+ // Allow wildcard file
+ if (options.use_fd == -1 && addr [0] == '*') {
+ if ( create_wildcard_address(tmp_socket_dirname, addr) < 0 ) {
+ return -1;
+ }
+ }
+
+ // Get rid of the file associated with the UNIX domain socket that
+ // may have been left behind by the previous run of the application.
+ // MUST NOT unlink if the FD is managed by the user, or it will stop
+ // working after the first client connects. The user will take care of
+ // cleaning up the file after the service is stopped.
+ if (options.use_fd == -1) {
+ ::unlink (addr.c_str());
+ }
+ filename.clear ();
+
+ // Initialise the address structure.
+ ipc_address_t address;
+ int rc = address.resolve (addr.c_str());
+ if (rc != 0) {
+ if ( !tmp_socket_dirname.empty() ) {
+ // We need to preserve errno to return to the user
+ int errno_ = errno;
+ ::rmdir(tmp_socket_dirname.c_str ());
+ tmp_socket_dirname.clear();
+ errno = errno_;
+ }
+ return -1;
+ }
+
+ address.to_string (endpoint);
+
+ if (options.use_fd != -1) {
+ s = options.use_fd;
+ } else {
+ // Create a listening socket.
+ s = open_socket (AF_UNIX, SOCK_STREAM, 0);
+ if (s == -1) {
+ if ( !tmp_socket_dirname.empty() ) {
+ // We need to preserve errno to return to the user
+ int errno_ = errno;
+ ::rmdir(tmp_socket_dirname.c_str ());
+ tmp_socket_dirname.clear();
+ errno = errno_;
+ }
+ return -1;
+ }
+
+ // Bind the socket to the file path.
+ rc = bind (s, address.addr (), address.addrlen ());
+ if (rc != 0)
+ goto error;
+
+ // Listen for incoming connections.
+ rc = listen (s, options.backlog);
+ if (rc != 0)
+ goto error;
+ }
+
+ filename.assign (addr.c_str());
+ has_file = true;
+
+ socket->event_listening (endpoint, s);
+ return 0;
+
+error:
+ int err = errno;
+ close ();
+ errno = err;
+ return -1;
+}
+
+int zmq::ipc_listener_t::close ()
+{
+ zmq_assert (s != retired_fd);
+ int fd_for_event = s;
+ int rc = ::close (s);
+ errno_assert (rc == 0);
+
+ s = retired_fd;
+
+ if (has_file && options.use_fd == -1) {
+ rc = 0;
+
+ if ( rc == 0 && !tmp_socket_dirname.empty() ) {
+ rc = ::rmdir(tmp_socket_dirname.c_str ());
+ tmp_socket_dirname.clear();
+ }
+
+ if (rc != 0) {
+ socket->event_close_failed (endpoint, zmq_errno());
+ return -1;
+ }
+ }
+
+ socket->event_closed (endpoint, fd_for_event);
+ return 0;
+}
+
+#if defined ZMQ_HAVE_SO_PEERCRED
+
+bool zmq::ipc_listener_t::filter (fd_t sock)
+{
+ if (options.ipc_uid_accept_filters.empty () &&
+ options.ipc_pid_accept_filters.empty () &&
+ options.ipc_gid_accept_filters.empty ())
+ return true;
+
+ struct ucred cred;
+ socklen_t size = sizeof (cred);
+
+ if (getsockopt (sock, SOL_SOCKET, SO_PEERCRED, &cred, &size))
+ return false;
+ if (options.ipc_uid_accept_filters.find (cred.uid) != options.ipc_uid_accept_filters.end () ||
+ options.ipc_gid_accept_filters.find (cred.gid) != options.ipc_gid_accept_filters.end () ||
+ options.ipc_pid_accept_filters.find (cred.pid) != options.ipc_pid_accept_filters.end ())
+ return true;
+
+ struct passwd *pw;
+ struct group *gr;
+
+ if (!(pw = getpwuid (cred.uid)))
+ return false;
+ for (options_t::ipc_gid_accept_filters_t::const_iterator it = options.ipc_gid_accept_filters.begin ();
+ it != options.ipc_gid_accept_filters.end (); it++) {
+ if (!(gr = getgrgid (*it)))
+ continue;
+ for (char **mem = gr->gr_mem; *mem; mem++) {
+ if (!strcmp (*mem, pw->pw_name))
+ return true;
+ }
+ }
+ return false;
+}
+
+#elif defined ZMQ_HAVE_LOCAL_PEERCRED
+
+bool zmq::ipc_listener_t::filter (fd_t sock)
+{
+ if (options.ipc_uid_accept_filters.empty () &&
+ options.ipc_gid_accept_filters.empty ())
+ return true;
+
+ struct xucred cred;
+ socklen_t size = sizeof (cred);
+
+ if (getsockopt (sock, 0, LOCAL_PEERCRED, &cred, &size))
+ return false;
+ if (cred.cr_version != XUCRED_VERSION)
+ return false;
+ if (options.ipc_uid_accept_filters.find (cred.cr_uid) != options.ipc_uid_accept_filters.end ())
+ return true;
+ for (int i = 0; i < cred.cr_ngroups; i++) {
+ if (options.ipc_gid_accept_filters.find (cred.cr_groups[i]) != options.ipc_gid_accept_filters.end ())
+ return true;
+ }
+
+ return false;
+}
+
+#endif
+
+zmq::fd_t zmq::ipc_listener_t::accept ()
+{
+ // Accept one connection and deal with different failure modes.
+ // The situation where connection cannot be accepted due to insufficient
+ // resources is considered valid and treated by ignoring the connection.
+ zmq_assert (s != retired_fd);
+#if defined ZMQ_HAVE_SOCK_CLOEXEC && defined HAVE_ACCEPT4
+ fd_t sock = ::accept4 (s, NULL, NULL, SOCK_CLOEXEC);
+#else
+ fd_t sock = ::accept (s, NULL, NULL);
+#endif
+ if (sock == -1) {
+ errno_assert (errno == EAGAIN || errno == EWOULDBLOCK ||
+ errno == EINTR || errno == ECONNABORTED || errno == EPROTO ||
+ errno == ENFILE);
+ return retired_fd;
+ }
+
+#if (!defined ZMQ_HAVE_SOCK_CLOEXEC || !defined HAVE_ACCEPT4) && defined FD_CLOEXEC
+ // Race condition can cause socket not to be closed (if fork happens
+ // between accept and this point).
+ int rc = fcntl (sock, F_SETFD, FD_CLOEXEC);
+ errno_assert (rc != -1);
+#endif
+
+ // IPC accept() filters
+#if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED
+ if (!filter (sock)) {
+ int rc = ::close (sock);
+ errno_assert (rc == 0);
+ return retired_fd;
+ }
+#endif
+
+ if (zmq::set_nosigpipe (sock)) {
+#ifdef ZMQ_HAVE_WINDOWS
+ int rc = closesocket (sock);
+ wsa_assert (rc != SOCKET_ERROR);
+#else
+ int rc = ::close (sock);
+ errno_assert (rc == 0);
+#endif
+ return retired_fd;
+ }
+
+ return sock;
+}
+
+#endif
diff --git a/src/server/scripts/Commands/cs_battlenet_account.cpp b/src/server/scripts/Commands/cs_battlenet_account.cpp
index 87b76c68c58..5b1a25a0b7b 100644
--- a/src/server/scripts/Commands/cs_battlenet_account.cpp
+++ b/src/server/scripts/Commands/cs_battlenet_account.cpp
@@ -20,6 +20,7 @@
#include "BattlenetAccountMgr.h"
#include "Chat.h"
#include "DatabaseEnv.h"
+#include "IpAddress.h"
#include "Language.h"
#include "Log.h"
#include "Player.h"
@@ -128,7 +129,7 @@ public:
if (param == "on")
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY);
- uint32 ip = inet_addr(handler->GetSession()->GetRemoteAddress().c_str());
+ uint32 ip = Trinity::Net::address_to_uint(Trinity::Net::make_address_v4(handler->GetSession()->GetRemoteAddress()));
EndianConvertReverse(ip);
stmt->setUInt32(0, ip);
PreparedQueryResult result = LoginDatabase.Query(stmt);