diff --git a/src/socks_connecter.cpp b/src/socks_connecter.cpp index 63a750b3..d5aec659 100644 --- a/src/socks_connecter.cpp +++ b/src/socks_connecter.cpp @@ -215,49 +215,26 @@ int zmq::socks_connecter_t::connect_to_proxy () zmq_assert (_s == retired_fd); // Resolve the address - LIBZMQ_DELETE (_proxy_addr->resolved.tcp_addr); - _proxy_addr->resolved.tcp_addr = new (std::nothrow) tcp_address_t (); - alloc_assert (_proxy_addr->resolved.tcp_addr); + if (_addr->resolved.tcp_addr != NULL) { + LIBZMQ_DELETE (_addr->resolved.tcp_addr); + } - int rc = _proxy_addr->resolved.tcp_addr->resolve ( - _proxy_addr->address.c_str (), false, options.ipv6); - if (rc != 0) { - LIBZMQ_DELETE (_proxy_addr->resolved.tcp_addr); + _addr->resolved.tcp_addr = new (std::nothrow) tcp_address_t (); + alloc_assert (_addr->resolved.tcp_addr); + // Automatic fallback to ipv4 is disabled here since this was the existing + // behaviour, however I don't see a real reason for this. Maybe this can + // be changed to true (and then the parameter can be removed entirely). + _s = tcp_open_socket (_addr->address.c_str (), options, false, + _addr->resolved.tcp_addr); + if (_s == retired_fd) { + LIBZMQ_DELETE (_addr->resolved.tcp_addr); return -1; } - zmq_assert (_proxy_addr->resolved.tcp_addr != NULL); - const tcp_address_t *tcp_addr = _proxy_addr->resolved.tcp_addr; + zmq_assert (_addr->resolved.tcp_addr != NULL); - // Create the socket. - _s = open_socket (tcp_addr->family (), SOCK_STREAM, IPPROTO_TCP); - if (_s == retired_fd) - return -1; + const tcp_address_t *const tcp_addr = _addr->resolved.tcp_addr; - // On some systems, IPv4 mapping in IPv6 sockets is disabled by default. - // Switch it on in such cases. - if (tcp_addr->family () == AF_INET6) - enable_ipv4_mapping (_s); - - // Set the IP Type-Of-Service priority for this socket - if (options.tos != 0) - set_ip_type_of_service (_s, options.tos); - - // Bind the socket to a device if applicable - if (!options.bound_device.empty ()) - bind_to_device (_s, options.bound_device); - - // Set the socket to non-blocking mode so that we get async connect(). - unblock_socket (_s); - - // Set the socket buffer limits for the underlying socket. - if (options.sndbuf >= 0) - set_tcp_send_buffer (_s, options.sndbuf); - if (options.rcvbuf >= 0) - set_tcp_receive_buffer (_s, options.rcvbuf); - - // Set the IP Type-Of-Service for the underlying socket - if (options.tos != 0) - set_ip_type_of_service (_s, options.tos); + int rc; // Set a source address for conversations if (tcp_addr->has_src_addr ()) { diff --git a/src/tcp.cpp b/src/tcp.cpp index 597eb7ec..a8dd4873 100644 --- a/src/tcp.cpp +++ b/src/tcp.cpp @@ -385,6 +385,7 @@ void zmq::tcp_tune_loopback_fast_path (const fd_t socket_) zmq::fd_t zmq::tcp_open_socket (const char *address_, const zmq::options_t &options_, + bool fallback_to_ipv4_, zmq::tcp_address_t *out_tcp_addr_) { // Convert the textual address into address structure. @@ -396,8 +397,9 @@ zmq::fd_t zmq::tcp_open_socket (const char *address_, fd_t s = open_socket (out_tcp_addr_->family (), SOCK_STREAM, IPPROTO_TCP); // IPv6 address family not supported, try automatic downgrade to IPv4. - if (s == retired_fd && out_tcp_addr_->family () == AF_INET6 - && errno == EAFNOSUPPORT && options_.ipv6) { + if (s == retired_fd && fallback_to_ipv4_ + && out_tcp_addr_->family () == AF_INET6 && errno == EAFNOSUPPORT + && options_.ipv6) { rc = out_tcp_addr_->resolve (address_, false, false); if (rc != 0) { return retired_fd; diff --git a/src/tcp.hpp b/src/tcp.hpp index b9ed65fa..946dd42a 100644 --- a/src/tcp.hpp +++ b/src/tcp.hpp @@ -79,6 +79,7 @@ void tcp_tune_loopback_fast_path (const fd_t socket_); // errno is set to an error code describing the cause of the error. fd_t tcp_open_socket (const char *address_, const options_t &options_, + bool fallback_to_ipv4_, tcp_address_t *out_tcp_addr_); } diff --git a/src/tcp_connecter.cpp b/src/tcp_connecter.cpp index 2e627d5f..b1d01cad 100644 --- a/src/tcp_connecter.cpp +++ b/src/tcp_connecter.cpp @@ -174,7 +174,7 @@ int zmq::tcp_connecter_t::open () _addr->resolved.tcp_addr = new (std::nothrow) tcp_address_t (); alloc_assert (_addr->resolved.tcp_addr); - _s = tcp_open_socket (_addr->address.c_str (), options, + _s = tcp_open_socket (_addr->address.c_str (), options, true, _addr->resolved.tcp_addr); if (_s == retired_fd) { LIBZMQ_DELETE (_addr->resolved.tcp_addr); diff --git a/src/tcp_listener.cpp b/src/tcp_listener.cpp index 85c4392b..0f4b261b 100644 --- a/src/tcp_listener.cpp +++ b/src/tcp_listener.cpp @@ -103,7 +103,7 @@ zmq::tcp_listener_t::get_socket_name (zmq::fd_t fd_, int zmq::tcp_listener_t::create_socket (const char *addr_) { - _s = tcp_open_socket (addr_, options, &_address); + _s = tcp_open_socket (addr_, options, true, &_address); if (_s == retired_fd) { return -1; }