Commit 9cb1fca1 authored by Simon Giesecke's avatar Simon Giesecke

Problem: on a failure to setsockopt SO_BINDTODEVICE, libzmq asserts

Solution: return an error to the user instead
parent ec4ecb01
......@@ -227,20 +227,31 @@ int zmq::set_nosigpipe (fd_t s_)
return 0;
}
void zmq::bind_to_device (fd_t s_, const std::string &bound_device_)
int zmq::bind_to_device (fd_t s_, const std::string &bound_device_)
{
#ifdef ZMQ_HAVE_SO_BINDTODEVICE
int rc = setsockopt (s_, SOL_SOCKET, SO_BINDTODEVICE,
bound_device_.c_str (), bound_device_.length ());
#ifdef ZMQ_HAVE_WINDOWS
wsa_assert (rc != SOCKET_ERROR);
if (rc != SOCKET_ERROR)
return 0;
const int lastError = WSAGetLastError ();
errno = wsa_error_to_errno (lastError);
wsa_assert (lastError != WSAENOTSOCK);
return -1;
#else
errno_assert (rc == 0);
if (rc == 0)
return 0;
errno_assert (errno != ENOTSOCK);
return -1;
#endif
#else
LIBZMQ_UNUSED (s_);
LIBZMQ_UNUSED (bound_device_);
errno = ENOTSUP;
return -1;
#endif
}
......
......@@ -56,7 +56,7 @@ void set_ip_type_of_service (fd_t s_, int iptos_);
int set_nosigpipe (fd_t s_);
// Binds the underlying socket to the given device, eg. VRF or interface
void bind_to_device (fd_t s_, const std::string &bound_device_);
int bind_to_device (fd_t s_, const std::string &bound_device_);
// Initialize network subsystem. May be called multiple times. Each call must be matched by a call to shutdown_network.
bool initialize_network ();
......
......@@ -40,6 +40,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <unistd.h>
#ifdef ZMQ_HAVE_VXWORKS
#include <sockLib.h>
#endif
......@@ -427,7 +428,8 @@ zmq::fd_t zmq::tcp_open_socket (const char *address_,
// Bind the socket to a device if applicable
if (!options_.bound_device.empty ())
bind_to_device (s, options_.bound_device);
if (bind_to_device (s, options_.bound_device) == -1)
goto setsockopt_error;
// Set the socket buffer limits for the underlying socket.
if (options_.sndbuf >= 0)
......@@ -436,4 +438,14 @@ zmq::fd_t zmq::tcp_open_socket (const char *address_,
set_tcp_receive_buffer (s, options_.rcvbuf);
return s;
setsockopt_error:
#ifdef ZMQ_HAVE_WINDOWS
rc = closesocket (s);
wsa_assert (rc != SOCKET_ERROR);
#else
rc = ::close (s);
errno_assert (rc == 0);
#endif
return retired_fd;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment