From 4e05743909040b51597d78c42eaa0a1e3410b04a Mon Sep 17 00:00:00 2001 From: ariel- Date: Wed, 28 Mar 2018 06:05:10 -0300 Subject: [PATCH] Dep: fix more zmq --- dep/libzmq/CMakeLists.txt | 3 + dep/libzmq/src/ipc_address.cpp | 106 +++++ dep/libzmq/src/ipc_connecter.cpp | 278 ++++++++++++ dep/libzmq/src/ipc_listener.cpp | 427 ++++++++++++++++++ .../scripts/Commands/cs_battlenet_account.cpp | 3 +- 5 files changed, 816 insertions(+), 1 deletion(-) create mode 100644 dep/libzmq/src/ipc_address.cpp create mode 100644 dep/libzmq/src/ipc_connecter.cpp create mode 100644 dep/libzmq/src/ipc_listener.cpp 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);