swrap: introduce a socket_wrapper_noop.so and socket_wrapper.h to provide noop stubs
authorStefan Metzmacher <metze@samba.org>
Wed, 24 Feb 2021 11:45:26 +0000 (12:45 +0100)
committerAndreas Schneider <asn@samba.org>
Mon, 15 Mar 2021 07:04:58 +0000 (08:04 +0100)
Applications with the need to call socket_wrapper_enabled() should link
against -lsocket_wrapper_noop in order to resolve the symbol at
link time.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14640

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
CMakeLists.txt
doc/socket_wrapper.1
doc/socket_wrapper.1.adoc
socket_wrapper_noop.pc.cmake [new file with mode: 0644]
src/CMakeLists.txt
src/socket_wrapper.c
src/socket_wrapper.h [new file with mode: 0644]
src/socket_wrapper_noop.c [new file with mode: 0644]
tests/CMakeLists.txt
tests/test_public_functions.c [new file with mode: 0644]

index 13be7fb58b0a755d094017323b48677cd121e2f8..8927ebb56e8d371a03c09f83b0439990246d0b0f 100644 (file)
@@ -71,6 +71,16 @@ install(
     pkgconfig
 )
 
+configure_file(socket_wrapper_noop.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/socket_wrapper_noop.pc @ONLY)
+install(
+  FILES
+    ${CMAKE_CURRENT_BINARY_DIR}/socket_wrapper_noop.pc
+  DESTINATION
+      ${CMAKE_INSTALL_LIBDIR}/pkgconfig
+  COMPONENT
+    pkgconfig
+)
+
 # cmake config files
 configure_file(socket_wrapper-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/socket_wrapper-config-version.cmake @ONLY)
 configure_file(socket_wrapper-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/socket_wrapper-config.cmake @ONLY)
index 0272c63d30d5053eced8cbf6d4cbb32f2675aab2..b6363cd65ac412e0bf2e9cc54e9c001e99aa180e 100644 (file)
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: socket_wrapper
 .\"    Author: Samba Team
-.\" Generator: Asciidoctor 2.0.12
-.\"      Date: 2021-02-02
+.\" Generator: Asciidoctor 2.0.10
+.\"      Date: 2021-02-24
 .\"    Manual: \ \&
 .\"    Source: \ \&
 .\"  Language: English
 .\"
-.TH "SOCKET_WRAPPER" "1" "2021-02-02" "\ \&" "\ \&"
+.TH "SOCKET_WRAPPER" "1" "2021-02-24" "\ \&" "\ \&"
 .ie \n(.g .ds Aq \(aq
 .el       .ds Aq '
 .ss \n[.ss] 0
@@ -214,54 +214,73 @@ to be usable.
 .sp
 .if n .RS 4
 .nf
-.fam C
 # Open a console and create a directory for the unix sockets.
 $ mktemp \-d
 /tmp/tmp.bQRELqDrhM
-.fam
 .fi
 .if n .RE
 .sp
 .if n .RS 4
 .nf
-.fam C
 # Then start nc to listen for network traffic using the temporary directory.
 $ LD_PRELOAD=libsocket_wrapper.so \(rs
   SOCKET_WRAPPER_DIR=/tmp/tmp.bQRELqDrhM \(rs
   SOCKET_WRAPPER_DEFAULT_IFACE=10 nc \-v \-l 127.0.0.10 7
-.fam
 .fi
 .if n .RE
 .sp
 .if n .RS 4
 .nf
-.fam C
 # (If nc, listens on 0.0.0.0 then listener will be open on 127.0.0.10 because
 #  it is the default interface)
-.fam
 .fi
 .if n .RE
 .sp
 .if n .RS 4
 .nf
-.fam C
 # Now open another console and start \(aqnc\(aq as a client to connect to the server:
 $ LD_PRELOAD=libsocket_wrapper.so \(rs
   SOCKET_WRAPPER_DIR=/tmp/tmp.bQRELqDrhM \(rs
   SOCKET_WRAPPER_DEFAULT_IFACE=100 nc \-v 127.0.0.10 7
-.fam
 .fi
 .if n .RE
 .sp
 .if n .RS 4
 .nf
-.fam C
 # (The client will use the address 127.0.0.100 when connecting to the server)
 # Now you can type \(aqHello!\(aq which will be sent to the server and should appear
 # in the console output of the server.
-.fam
 .fi
 .if n .RE
+.SH "PUBLIC FUNCTIONS"
+.sp
+Socket wrapper advanced helpers.
+.sp
+Applications with the need to alter their behaviour when
+socket wrapper is active, can link use these functions.
+.sp
+By default it\(cqs required for applications to use any of these
+functions as libsocket_wrapper.so is injected at runtime via
+LD_PRELOAD.
+.sp
+Applications using these functions should link against
+libsocket_wrapper_noop.so by using \-lsocket_wrapper_noop,
+or implement their own noop stubs.
+.sp
+#include <socket_wrapper.h>
+.sp
+bool socket_wrapper_enabled(void);
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.  sp -1
+.  IP \(bu 2.3
+.\}
+This returns true when socket wrapper is actively in use.
+.RE
 .SH "RESOURCES"
 .sp
 \fBProject web site:\fP \c
index 9519fd4113e873c9bbe73926698a9a9a6527519d..fd0b74584224113e660b69151a78174565117919 100644 (file)
@@ -133,6 +133,29 @@ EXAMPLE
   # Now you can type 'Hello!' which will be sent to the server and should appear
   # in the console output of the server.
 
+PUBLIC FUNCTIONS
+----------------
+
+Socket wrapper advanced helpers.
+
+Applications with the need to alter their behaviour when
+socket wrapper is active, can link use these functions.
+
+By default it's required for applications to use any of these
+functions as libsocket_wrapper.so is injected at runtime via
+LD_PRELOAD.
+
+Applications using these functions should link against
+libsocket_wrapper_noop.so by using -lsocket_wrapper_noop,
+or implement their own noop stubs.
+
+#include <socket_wrapper.h>
+
+bool socket_wrapper_enabled(void);
+
+- This returns true when socket wrapper is actively in use.
+
+
 RESOURCES
 ---------
 
diff --git a/socket_wrapper_noop.pc.cmake b/socket_wrapper_noop.pc.cmake
new file mode 100644 (file)
index 0000000..5c8ac49
--- /dev/null
@@ -0,0 +1,8 @@
+libdir=@CMAKE_INSTALL_FULL_LIBDIR@
+includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
+
+Name: @PROJECT_NAME@
+Description: The socket_wrapper_noop library
+Version: @PROJECT_VERSION@
+Libs: -L${libdir} -lsocket_wrapper_noop
+Cflags: -I${includedir}
index 73f8cd0836f4bd6f2b8c243cbbd1828fa7de2b45..ac56c8618f6cca1e9da1abd909ede4bcc36f35d7 100644 (file)
@@ -27,3 +27,35 @@ install(TARGETS socket_wrapper
 )
 
 set(SOCKET_WRAPPER_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}socket_wrapper${CMAKE_SHARED_LIBRARY_SUFFIX}" PARENT_SCOPE)
+
+add_library(socket_wrapper_noop SHARED socket_wrapper_noop.c)
+target_include_directories(socket_wrapper_noop
+                           PRIVATE
+                               ${CMAKE_BINARY_DIR})
+target_compile_options(socket_wrapper_noop
+                       PRIVATE
+                          ${DEFAULT_C_COMPILE_FLAGS}
+                          -D_GNU_SOURCE)
+target_link_libraries(socket_wrapper_noop ${SWRAP_REQUIRED_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+set_target_properties(socket_wrapper_noop
+                      PROPERTIES
+                          VERSION ${LIBRARY_VERSION}
+                          SOVERSION ${LIBRARY_SOVERSION})
+if (DEFINED DEFAULT_LINK_FLAGS)
+    set_target_properties(socket_wrapper_noop
+                          PROPERTIES
+                              LINK_FLAGS ${DEFAULT_LINK_FLAGS})
+endif()
+
+install(TARGETS socket_wrapper_noop
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+install(
+    FILES
+        ${CMAKE_CURRENT_SOURCE_DIR}/socket_wrapper.h
+    DESTINATION
+        ${CMAKE_INSTALL_INCLUDEDIR}
+)
index 22e024608fbac2b345a21d6e16b0085bcaf7a71b..63de14885fdd93addfde0fe965d5e772b7c07fe4 100644 (file)
@@ -2,8 +2,8 @@
  * BSD 3-Clause License
  *
  * Copyright (c) 2005-2008, Jelmer Vernooij <jelmer@samba.org>
- * Copyright (c) 2006-2018, Stefan Metzmacher <metze@samba.org>
- * Copyright (c) 2013-2018, Andreas Schneider <asn@samba.org>
+ * Copyright (c) 2006-2021, Stefan Metzmacher <metze@samba.org>
+ * Copyright (c) 2013-2021, Andreas Schneider <asn@samba.org>
  * Copyright (c) 2014-2017, Michael Adam <obnox@samba.org>
  * Copyright (c) 2016-2018, Anoop C S <anoopcs@redhat.com>
  * All rights reserved.
@@ -86,6 +86,8 @@
 #endif
 #include <pthread.h>
 
+#include "socket_wrapper.h"
+
 enum swrap_dbglvl_e {
        SWRAP_LOG_ERROR = 0,
        SWRAP_LOG_WARN,
@@ -392,8 +394,6 @@ static pthread_mutex_t mtu_update_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /* Function prototypes */
 
-bool socket_wrapper_enabled(void);
-
 #if ! defined(HAVE_CONSTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_INIT)
 /* xlC and other oldschool compilers support (only) this */
 #pragma init (swrap_constructor)
diff --git a/src/socket_wrapper.h b/src/socket_wrapper.h
new file mode 100644 (file)
index 0000000..f1a97e8
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2005-2008, Jelmer Vernooij <jelmer@samba.org>
+ * Copyright (c) 2006-2021, Stefan Metzmacher <metze@samba.org>
+ * Copyright (c) 2013-2021, Andreas Schneider <asn@samba.org>
+ * Copyright (c) 2014-2017, Michael Adam <obnox@samba.org>
+ * Copyright (c) 2016-2018, Anoop C S <anoopcs@redhat.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the author nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __SOCKET_WRAPPER_H__
+#define __SOCKET_WRAPPER_H__ 1
+
+#include <stdbool.h>
+
+/*
+   Socket wrapper advanced helpers.
+
+   Applications with the need to alter their behaviour when
+   socket wrapper is active, can link use these functions.
+
+   By default it's required for applications to use any of these
+   functions as libsocket_wrapper.so is injected at runtime via
+   LD_PRELOAD.
+
+   Applications using these functions should link against
+   libsocket_wrapper_noop.so by using -lsocket_wrapper_noop,
+   or implement their own noop stubs.
+*/
+
+/*
+ * This returns true when socket wrapper is actively in use.
+ */
+bool socket_wrapper_enabled(void);
+
+#endif /* __SOCKET_WRAPPER_H__ */
diff --git a/src/socket_wrapper_noop.c b/src/socket_wrapper_noop.c
new file mode 100644 (file)
index 0000000..45aff8f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2005-2008, Jelmer Vernooij <jelmer@samba.org>
+ * Copyright (c) 2006-2021, Stefan Metzmacher <metze@samba.org>
+ * Copyright (c) 2013-2021, Andreas Schneider <asn@samba.org>
+ * Copyright (c) 2014-2017, Michael Adam <obnox@samba.org>
+ * Copyright (c) 2016-2018, Anoop C S <anoopcs@redhat.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the author nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+   Socket wrapper noop library.
+
+   Applications with the need to alter their behaviour when
+   socket wrapper is active, can link to this with -lsocket_wrapper_noop
+   in order to call get the required public functions at link time.
+
+   During runtime these are overloaded with LD_PRELOAD by the real
+   libsocket_wrapper.so.
+*/
+
+#include "config.h"
+#include "stdbool.h"
+#include "socket_wrapper.h"
+
+bool socket_wrapper_enabled(void)
+{
+       return false;
+}
index db36bf35321b96e7b375d3a80890956ed96454f2..2f98af1460163dad8b6da891160b05da7b41c5b8 100644 (file)
@@ -56,6 +56,7 @@ set(SWRAP_TESTS
     test_echo_udp_sendmsg_recvmsg
     test_swrap_unit
     test_max_sockets
+    test_public_functions
     test_close_failure
     test_tcp_socket_overwrite
     ${SWRAP_THREADED_TESTS})
@@ -111,7 +112,7 @@ foreach(_SWRAP_TEST ${SWRAP_TESTS})
     add_cmocka_test(${_SWRAP_TEST}
                     SOURCES ${_SWRAP_TEST}.c
                     COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} -D_GNU_SOURCE
-                    LINK_LIBRARIES ${TORTURE_LIBRARY}
+                    LINK_LIBRARIES ${TORTURE_LIBRARY} socket_wrapper_noop
                     LINK_OPTIONS ${DEFAULT_LINK_FLAGS})
     add_cmocka_test_environment(${_SWRAP_TEST})
 endforeach()
diff --git a/tests/test_public_functions.c b/tests/test_public_functions.c
new file mode 100644 (file)
index 0000000..11d03ef
--- /dev/null
@@ -0,0 +1,78 @@
+#include "torture.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <cmocka.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <socket_wrapper.h>
+
+static int setup_enabled(void **state)
+{
+       torture_setup_socket_dir(state);
+
+       return 0;
+}
+
+static int teardown_enabled(void **state)
+{
+       torture_teardown_socket_dir(state);
+
+       return 0;
+}
+
+static int setup_disabled(void **state)
+{
+       (void) state; /* unused */
+
+       unsetenv("SOCKET_WRAPPER_DIR");
+       unsetenv("SOCKET_WRAPPER_DEFAULT_IFACE");
+       unsetenv("SOCKET_WRAPPER_PCAP_FILE");
+
+       return 0;
+}
+
+static int teardown_disabled(void **state)
+{
+       (void) state; /* unused */
+
+       return 0;
+}
+
+static void test_call_enabled_true(void **state)
+{
+       char *s = getenv("SOCKET_WRAPPER_DIR");
+
+       (void) state; /* unused */
+
+       assert_true(socket_wrapper_enabled());
+       assert_true(s != NULL);
+}
+
+static void test_call_enabled_false(void **state)
+{
+       char *s = getenv("SOCKET_WRAPPER_DIR");
+
+       (void) state; /* unused */
+
+       assert_false(socket_wrapper_enabled());
+       assert_false(s != NULL);
+}
+
+int main(void) {
+       int rc;
+
+       const struct CMUnitTest max_sockets_tests[] = {
+               cmocka_unit_test_setup_teardown(test_call_enabled_true,
+                                               setup_enabled,
+                                               teardown_enabled),
+               cmocka_unit_test_setup_teardown(test_call_enabled_false,
+                                               setup_disabled,
+                                               teardown_disabled),
+       };
+
+       rc = cmocka_run_group_tests(max_sockets_tests, NULL, NULL);
+
+       return rc;
+}