Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
L
libzmq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
libzmq
Commits
a34adbf4
Commit
a34adbf4
authored
Jul 31, 2017
by
Luca Boccassi
Committed by
GitHub
Jul 31, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2640 from brianbalerno/vrf
Add socket option BINDTODEVICE
parents
4a37ce9a
b963542e
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
189 additions
and
0 deletions
+189
-0
CMakeLists.txt
CMakeLists.txt
+1
-0
acinclude.m4
acinclude.m4
+27
-0
ZMQSourceRunChecks.cmake
builds/cmake/Modules/ZMQSourceRunChecks.cmake
+19
-0
platform.hpp
builds/gyp/platform.hpp
+1
-0
configure.ac
configure.ac
+6
-0
zmq_getsockopt.txt
doc/zmq_getsockopt.txt
+17
-0
zmq_setsockopt.txt
doc/zmq_setsockopt.txt
+18
-0
zmq.h
include/zmq.h
+1
-0
ip.cpp
src/ip.cpp
+13
-0
ip.hpp
src/ip.hpp
+3
-0
options.cpp
src/options.cpp
+31
-0
options.hpp
src/options.hpp
+3
-0
socks_connecter.cpp
src/socks_connecter.cpp
+4
-0
tcp_connecter.cpp
src/tcp_connecter.cpp
+4
-0
tcp_listener.cpp
src/tcp_listener.cpp
+4
-0
udp_engine.cpp
src/udp_engine.cpp
+4
-0
test_setsockopt.cpp
tests/test_setsockopt.cpp
+33
-0
No files found.
CMakeLists.txt
View file @
a34adbf4
...
...
@@ -324,6 +324,7 @@ endif ()
if
(
NOT CMAKE_CROSSCOMPILING
)
zmq_check_sock_cloexec
()
zmq_check_o_cloexec
()
zmq_check_so_bindtodevice
()
zmq_check_so_keepalive
()
zmq_check_tcp_keepcnt
()
zmq_check_tcp_keepidle
()
...
...
acinclude.m4
View file @
a34adbf4
...
...
@@ -682,6 +682,33 @@ int main (int, char **)
)
}])
dnl ################################################################################
dnl # LIBZMQ_CHECK_SO_BINDTODEVICE([action-if-found], [action-if-not-found]) #
dnl # Check if SO_BINDTODEVICE is supported #
dnl ################################################################################
AC_DEFUN([LIBZMQ_CHECK_SO_BINDTODEVICE], [{
AC_CACHE_CHECK([whether SO_BINDTODEVICE is supported], [libzmq_cv_so_bindtodevice],
[AC_TRY_RUN([/* SO_BINDTODEVICE test */
#include <sys/socket.h>
int main (int argc, char *argv [])
{
/* Actually making the setsockopt() call requires CAP_NET_RAW */
#ifndef SO_BINDTODEVICE
return 1;
#else
return 0;
#endif
}
],
[libzmq_cv_so_bindtodevice="yes"],
[libzmq_cv_so_bindtodevice="no"],
[libzmq_cv_so_bindtodevice="not during cross-compile"]
)]
)
AS_IF([test "x$libzmq_cv_so_bindtodevice" = "xyes"], [$1], [$2])
}])
dnl ################################################################################
dnl # LIBZMQ_CHECK_SO_KEEPALIVE([action-if-found], [action-if-not-found]) #
dnl # Check if SO_KEEPALIVE is supported #
...
...
builds/cmake/Modules/ZMQSourceRunChecks.cmake
View file @
a34adbf4
...
...
@@ -48,6 +48,25 @@ int main(int argc, char *argv [])
ZMQ_HAVE_O_CLOEXEC
)
endmacro
()
macro
(
zmq_check_so_bindtodevice
)
message
(
STATUS
"Checking whether SO_BINDTODEVICE is supported"
)
check_c_source_runs
(
"
#include <sys/socket.h>
int main(int argc, char *argv [])
{
/* Actually making the setsockopt() call requires CAP_NET_RAW */
#ifndef SO_BINDTODEVICE
return 1;
#else
return 0;
#endif
}
"
ZMQ_HAVE_SO_BINDTODEVICE
)
endmacro
()
# TCP keep-alives Checks.
macro
(
zmq_check_so_keepalive
)
...
...
builds/gyp/platform.hpp
View file @
a34adbf4
...
...
@@ -62,6 +62,7 @@
# define ZMQ_HAVE_EVENTFD 1
# define ZMQ_HAVE_IFADDRS 1
# define ZMQ_HAVE_SOCK_CLOEXEC 1
# define ZMQ_HAVE_SO_BINDTODEVICE 1
# define ZMQ_HAVE_SO_KEEPALIVE 1
# define ZMQ_HAVE_SO_PEERCRED 1
# define ZMQ_HAVE_TCP_KEEPCNT 1
...
...
configure.ac
View file @
a34adbf4
...
...
@@ -668,6 +668,12 @@ LIBZMQ_CHECK_O_CLOEXEC([
[Whether O_CLOEXEC is defined and functioning.])
])
LIBZMQ_CHECK_SO_BINDTODEVICE([
AC_DEFINE([ZMQ_HAVE_SO_BINDTODEVICE],
[1],
[Whether SO_BINDTODEVICE is supported.])
])
# TCP keep-alives Checks.
LIBZMQ_CHECK_SO_KEEPALIVE([
AC_DEFINE([ZMQ_HAVE_SO_KEEPALIVE],
...
...
doc/zmq_getsockopt.txt
View file @
a34adbf4
...
...
@@ -63,6 +63,23 @@ Default value:: 100
Applicable socket types:: all, only for connection-oriented transports
ZMQ_BINDTODEVICE: Retrieve name of device the socket is bound to
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_BINDTODEVICE' option retrieves the name of the device this socket is
bound to, eg. an interface or VRF. If a socket is bound to an interface, only
packets received from that interface are processed by the socket. If device
is a VRF device, then subsequent binds/connects to that socket use addresses
in the VRF routing table.
NOTE: in DRAFT state, not yet available in stable releases.
[horizontal]
Option value type:: character string
Option value unit:: N/A
Default value:: not set
Applicable socket types:: all, when using TCP or UDP transports.
ZMQ_CONNECT_TIMEOUT: Retrieve connect() timeout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieves how long to wait before timing-out a connect() system call.
...
...
doc/zmq_setsockopt.txt
View file @
a34adbf4
...
...
@@ -70,6 +70,24 @@ Default value:: 100
Applicable socket types:: all, only for connection-oriented transports.
ZMQ_BINDTODEVICE: Set name of device to bind the socket to
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_BINDTODEVICE' option binds this socket to a particular device, eg.
an interface or VRF. If a socket is bound to an interface, only packets
received from that particular interface are processed by the socket. If device
is a VRF device, then subsequent binds/connects to that socket use addresses
in the VRF routing table.
NOTE: requires setting CAP_NET_RAW on the compiled program.
NOTE: in DRAFT state, not yet available in stable releases.
[horizontal]
Option value type:: character string
Option value unit:: N/A
Default value:: not set
Applicable socket types:: all, when using TCP or UDP transports.
ZMQ_CONNECT_RID: Assign the next outbound connection id
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_CONNECT_RID' option sets the peer id of the next host connected
...
...
include/zmq.h
View file @
a34adbf4
...
...
@@ -368,6 +368,7 @@ ZMQ_EXPORT const char *zmq_msg_gets (const zmq_msg_t *msg, const char *property)
#define ZMQ_VMCI_BUFFER_MAX_SIZE 87
#define ZMQ_VMCI_CONNECT_TIMEOUT 88
#define ZMQ_USE_FD 89
#define ZMQ_BINDTODEVICE 90
/* Message options */
#define ZMQ_MORE 1
...
...
src/ip.cpp
View file @
a34adbf4
...
...
@@ -217,3 +217,16 @@ int zmq::set_nosigpipe (fd_t s_)
return
0
;
}
void
zmq
::
bind_to_device
(
fd_t
s_
,
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
);
#else
errno_assert
(
rc
==
0
);
#endif
#endif
}
src/ip.hpp
View file @
a34adbf4
...
...
@@ -56,6 +56,9 @@ namespace zmq
// Return 0 on success, -1 if the connection has been closed by the peer
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_
,
std
::
string
&
bound_device_
);
}
#endif
src/options.cpp
View file @
a34adbf4
...
...
@@ -34,6 +34,16 @@
#include "err.hpp"
#include "macros.hpp"
#ifndef ZMQ_HAVE_WINDOWS
#include <net/if.h>
#endif
#if defined IFNAMSIZ
#define BINDDEVSIZ IFNAMSIZ
#else
#define BINDDEVSIZ 16
#endif
zmq
::
options_t
::
options_t
()
:
sndhwm
(
1000
),
rcvhwm
(
1000
),
...
...
@@ -605,6 +615,19 @@ int zmq::options_t::setsockopt (int option_, const void *optval_,
}
break
;
case
ZMQ_BINDTODEVICE
:
if
(
optval_
==
NULL
&&
optvallen_
==
0
)
{
bound_device
.
clear
();
return
0
;
}
else
if
(
optval_
!=
NULL
&&
optvallen_
>
0
&&
optvallen_
<=
BINDDEVSIZ
)
{
bound_device
=
std
::
string
((
const
char
*
)
optval_
,
optvallen_
);
return
0
;
}
break
;
default
:
#if defined (ZMQ_ACT_MILITANT)
// There are valid scenarios for probing with unknown socket option
...
...
@@ -1021,6 +1044,14 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_)
}
break
;
case
ZMQ_BINDTODEVICE
:
if
(
*
optvallen_
>=
bound_device
.
size
()
+
1
)
{
memcpy
(
optval_
,
bound_device
.
c_str
(),
bound_device
.
size
()
+
1
);
*
optvallen_
=
bound_device
.
size
()
+
1
;
return
0
;
}
break
;
default
:
#if defined (ZMQ_ACT_MILITANT)
malformed
=
false
;
...
...
src/options.hpp
View file @
a34adbf4
...
...
@@ -240,6 +240,9 @@ namespace zmq
// will be used as the File Descriptor instead of allocating a new
// one via the socket () system call.
int
use_fd
;
// Device to bind the underlying socket to, eg. VRF or interface
std
::
string
bound_device
;
};
}
...
...
src/socks_connecter.cpp
View file @
a34adbf4
...
...
@@ -334,6 +334,10 @@ int zmq::socks_connecter_t::connect_to_proxy ()
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
);
...
...
src/tcp_connecter.cpp
View file @
a34adbf4
...
...
@@ -305,6 +305,10 @@ int zmq::tcp_connecter_t::open ()
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
);
...
...
src/tcp_listener.cpp
View file @
a34adbf4
...
...
@@ -212,6 +212,10 @@ int zmq::tcp_listener_t::set_address (const char *addr_)
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 buffer limits for the underlying socket.
if
(
options
.
sndbuf
>=
0
)
set_tcp_send_buffer
(
s
,
options
.
sndbuf
);
...
...
src/udp_engine.cpp
View file @
a34adbf4
...
...
@@ -123,6 +123,10 @@ void zmq::udp_engine_t::plug (io_thread_t* io_thread_, session_base_t *session_)
errno_assert
(
rc
==
0
);
#endif
// Bind the socket to a device if applicable
if
(
!
options
.
bound_device
.
empty
())
bind_to_device
(
fd
,
options
.
bound_device
);
rc
=
bind
(
fd
,
address
->
resolved
.
udp_addr
->
bind_addr
(),
address
->
resolved
.
udp_addr
->
bind_addrlen
());
#ifdef ZMQ_HAVE_WINDOWS
...
...
tests/test_setsockopt.cpp
View file @
a34adbf4
...
...
@@ -110,9 +110,42 @@ void test_setsockopt_use_fd ()
zmq_ctx_term
(
ctx
);
}
#define BOUNDDEVBUFSZ 16
void
test_setsockopt_bindtodevice
()
{
int
rc
;
void
*
ctx
=
zmq_ctx_new
();
void
*
socket
=
zmq_socket
(
ctx
,
ZMQ_PUSH
);
char
devname
[
BOUNDDEVBUFSZ
];
size_t
buflen
=
BOUNDDEVBUFSZ
;
rc
=
zmq_getsockopt
(
socket
,
ZMQ_BINDTODEVICE
,
devname
,
&
buflen
);
assert
(
rc
==
0
);
assert
(
devname
[
0
]
==
'\0'
);
assert
(
buflen
==
1
);
sprintf
(
devname
,
"testdev"
);
buflen
=
strlen
(
devname
);
rc
=
zmq_setsockopt
(
socket
,
ZMQ_BINDTODEVICE
,
devname
,
buflen
);
assert
(
rc
==
0
);
buflen
=
BOUNDDEVBUFSZ
;
memset
(
devname
,
0
,
buflen
);
rc
=
zmq_getsockopt
(
socket
,
ZMQ_BINDTODEVICE
,
devname
,
&
buflen
);
assert
(
rc
==
0
);
assert
(
!
strncmp
(
"testdev"
,
devname
,
buflen
));
zmq_close
(
socket
);
zmq_ctx_term
(
ctx
);
}
int
main
(
void
)
{
test_setsockopt_tcp_recv_buffer
();
test_setsockopt_tcp_send_buffer
();
test_setsockopt_use_fd
();
test_setsockopt_bindtodevice
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment