17b94a
From 4152c77defac24ace3b1b6b9cc81a4f614254e4f Mon Sep 17 00:00:00 2001
17b94a
From: srijan-sivakumar <ssivakum@redhat.com>
17b94a
Date: Sat, 18 Jul 2020 05:59:09 +0530
17b94a
Subject: [PATCH 527/532] Events: Socket creation after getaddrinfo and IPv4
17b94a
 and IPv6 packet capture
17b94a
17b94a
Issue: Currently, the socket creation is done
17b94a
prior to getaddrinfo function being invoked. This
17b94a
can cause mismatch in the protocol and address
17b94a
families of the created socket and the result
17b94a
of the getaddrinfo api. Also, the glustereventsd
17b94a
UDP server by default only captures IPv4 packets
17b94a
hence IPv6 packets are not even captured.
17b94a
17b94a
Code Changes:
17b94a
1. Modified the socket creation in such a way that
17b94a
the parameters taken in are dependent upon the
17b94a
result of the getaddrinfo function.
17b94a
2. Created a subclass for adding address family
17b94a
in glustereventsd.py for both AF_INET and AF_INET6.
17b94a
3. Modified addresses in the eventsapiconf.py.in
17b94a
17b94a
Reasoning behind the approach:
17b94a
1. If we are using getaddrinfo function then
17b94a
socket creation should happen only after we
17b94a
check if we received back valid addresses.
17b94a
Hence socket creation should come after the call
17b94a
to getaddrinfo
17b94a
2. The listening server which pushes the events
17b94a
to the webhook has to listen for both IPv4
17b94a
and IPv6 messages as we would not be sure as to
17b94a
what address family is picked in _gf_event.
17b94a
17b94a
>Fixes: #1377
17b94a
>Change-Id: I568dcd1a977c8832f0fef981e1f81cac7043c760
17b94a
>Signed-off-by: srijan-sivakumar <ssivakum@redhat.com>
17b94a
Upstream patch: https://review.gluster.org/c/glusterfs/+/24722
17b94a
17b94a
BUG: 1814744
17b94a
Change-Id: I568dcd1a977c8832f0fef981e1f81cac7043c760
17b94a
Signed-off-by: srijan-sivakumar <ssivakum@redhat.com>
17b94a
Reviewed-on: https://code.engineering.redhat.com/gerrit/225567
17b94a
Tested-by: RHGS Build Bot <nigelb@redhat.com>
17b94a
Reviewed-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
17b94a
---
17b94a
 events/src/eventsapiconf.py.in |  2 ++
17b94a
 events/src/glustereventsd.py   | 37 ++++++++++++++++++++++++++++++-------
17b94a
 libglusterfs/src/events.c      | 27 +++++++++++++++++++--------
17b94a
 3 files changed, 51 insertions(+), 15 deletions(-)
17b94a
17b94a
diff --git a/events/src/eventsapiconf.py.in b/events/src/eventsapiconf.py.in
17b94a
index 76b5954..700093b 100644
17b94a
--- a/events/src/eventsapiconf.py.in
17b94a
+++ b/events/src/eventsapiconf.py.in
17b94a
@@ -28,6 +28,8 @@ def get_glusterd_workdir():
17b94a
     return glusterd_workdir
17b94a
 
17b94a
 SERVER_ADDRESS = "0.0.0.0"
17b94a
+SERVER_ADDRESSv4 = "0.0.0.0"
17b94a
+SERVER_ADDRESSv6 = "::1"
17b94a
 DEFAULT_CONFIG_FILE = "@SYSCONF_DIR@/glusterfs/eventsconfig.json"
17b94a
 CUSTOM_CONFIG_FILE_TO_SYNC = "/events/config.json"
17b94a
 CUSTOM_CONFIG_FILE = get_glusterd_workdir() + CUSTOM_CONFIG_FILE_TO_SYNC
17b94a
diff --git a/events/src/glustereventsd.py b/events/src/glustereventsd.py
17b94a
index c4c7b65..341a3b6 100644
17b94a
--- a/events/src/glustereventsd.py
17b94a
+++ b/events/src/glustereventsd.py
17b94a
@@ -13,6 +13,7 @@
17b94a
 from __future__ import print_function
17b94a
 import sys
17b94a
 import signal
17b94a
+import threading
17b94a
 try:
17b94a
     import socketserver
17b94a
 except ImportError:
17b94a
@@ -23,10 +24,17 @@ from argparse import ArgumentParser, RawDescriptionHelpFormatter
17b94a
 from eventtypes import all_events
17b94a
 import handlers
17b94a
 import utils
17b94a
-from eventsapiconf import SERVER_ADDRESS, PID_FILE
17b94a
+from eventsapiconf import SERVER_ADDRESSv4, SERVER_ADDRESSv6, PID_FILE
17b94a
 from eventsapiconf import AUTO_BOOL_ATTRIBUTES, AUTO_INT_ATTRIBUTES
17b94a
 from utils import logger, PidFile, PidFileLockFailed, boolify
17b94a
 
17b94a
+# Subclass so that specifically IPv4 packets are captured
17b94a
+class UDPServerv4(socketserver.ThreadingUDPServer):
17b94a
+    address_family = socket.AF_INET
17b94a
+
17b94a
+# Subclass so that specifically IPv6 packets are captured
17b94a
+class UDPServerv6(socketserver.ThreadingUDPServer):
17b94a
+    address_family = socket.AF_INET6
17b94a
 
17b94a
 class GlusterEventsRequestHandler(socketserver.BaseRequestHandler):
17b94a
 
17b94a
@@ -89,6 +97,10 @@ def signal_handler_sigusr2(sig, frame):
17b94a
     utils.restart_webhook_pool()
17b94a
 
17b94a
 
17b94a
+def UDP_server_thread(sock):
17b94a
+    sock.serve_forever()
17b94a
+
17b94a
+
17b94a
 def init_event_server():
17b94a
     utils.setup_logger()
17b94a
     utils.load_all()
17b94a
@@ -99,15 +111,26 @@ def init_event_server():
17b94a
         sys.stderr.write("Unable to get Port details from Config\n")
17b94a
         sys.exit(1)
17b94a
 
17b94a
-    # Start the Eventing Server, UDP Server
17b94a
+    # Creating the Eventing Server, UDP Server for IPv4 packets
17b94a
+    try:
17b94a
+        serverv4 = UDPServerv4((SERVER_ADDRESSv4, port),
17b94a
+                   GlusterEventsRequestHandler)
17b94a
+    except socket.error as e:
17b94a
+        sys.stderr.write("Failed to start Eventsd for IPv4: {0}\n".format(e))
17b94a
+        sys.exit(1)
17b94a
+    # Creating the Eventing Server, UDP Server for IPv6 packets
17b94a
     try:
17b94a
-        server = socketserver.ThreadingUDPServer(
17b94a
-            (SERVER_ADDRESS, port),
17b94a
-            GlusterEventsRequestHandler)
17b94a
+        serverv6 = UDPServerv6((SERVER_ADDRESSv6, port),
17b94a
+                   GlusterEventsRequestHandler)
17b94a
     except socket.error as e:
17b94a
-        sys.stderr.write("Failed to start Eventsd: {0}\n".format(e))
17b94a
+        sys.stderr.write("Failed to start Eventsd for IPv6: {0}\n".format(e))
17b94a
         sys.exit(1)
17b94a
-    server.serve_forever()
17b94a
+    server_thread1 = threading.Thread(target=UDP_server_thread,
17b94a
+                     args=(serverv4,))
17b94a
+    server_thread2 = threading.Thread(target=UDP_server_thread,
17b94a
+                     args=(serverv6,))
17b94a
+    server_thread1.start()
17b94a
+    server_thread2.start()
17b94a
 
17b94a
 
17b94a
 def get_args():
17b94a
diff --git a/libglusterfs/src/events.c b/libglusterfs/src/events.c
17b94a
index 6d1e383..4d720ca 100644
17b94a
--- a/libglusterfs/src/events.c
17b94a
+++ b/libglusterfs/src/events.c
17b94a
@@ -40,6 +40,7 @@ _gf_event(eventtypes_t event, const char *fmt, ...)
17b94a
     char *host = NULL;
17b94a
     struct addrinfo hints;
17b94a
     struct addrinfo *result = NULL;
17b94a
+    struct addrinfo *iter_result_ptr = NULL;
17b94a
     xlator_t *this = THIS;
17b94a
     char *volfile_server_transport = NULL;
17b94a
 
17b94a
@@ -51,13 +52,6 @@ _gf_event(eventtypes_t event, const char *fmt, ...)
17b94a
         goto out;
17b94a
     }
17b94a
 
17b94a
-    /* Initialize UDP socket */
17b94a
-    sock = socket(AF_INET, SOCK_DGRAM, 0);
17b94a
-    if (sock < 0) {
17b94a
-        ret = EVENT_ERROR_SOCKET;
17b94a
-        goto out;
17b94a
-    }
17b94a
-
17b94a
     if (ctx) {
17b94a
         volfile_server_transport = ctx->cmd_args.volfile_server_transport;
17b94a
     }
17b94a
@@ -66,7 +60,6 @@ _gf_event(eventtypes_t event, const char *fmt, ...)
17b94a
     }
17b94a
 
17b94a
     /* host = NULL returns localhost */
17b94a
-    host = NULL;
17b94a
     if (ctx && ctx->cmd_args.volfile_server &&
17b94a
         (strcmp(volfile_server_transport, "unix"))) {
17b94a
         /* If it is client code then volfile_server is set
17b94a
@@ -84,6 +77,24 @@ _gf_event(eventtypes_t event, const char *fmt, ...)
17b94a
         goto out;
17b94a
     }
17b94a
 
17b94a
+    // iterate over the result and break when socket creation is success.
17b94a
+    for (iter_result_ptr = result; iter_result_ptr != NULL;
17b94a
+         iter_result_ptr = iter_result_ptr->ai_next) {
17b94a
+        sock = socket(iter_result_ptr->ai_family, iter_result_ptr->ai_socktype,
17b94a
+                      iter_result_ptr->ai_protocol);
17b94a
+        if (sock != -1) {
17b94a
+            break;
17b94a
+        }
17b94a
+    }
17b94a
+    /*
17b94a
+     * If none of the addrinfo structures lead to a successful socket
17b94a
+     * creation, socket creation has failed.
17b94a
+     */
17b94a
+    if (sock < 0) {
17b94a
+        ret = EVENT_ERROR_SOCKET;
17b94a
+        goto out;
17b94a
+    }
17b94a
+
17b94a
     va_start(arguments, fmt);
17b94a
     ret = gf_vasprintf(&msg, fmt, arguments);
17b94a
     va_end(arguments);
17b94a
-- 
17b94a
1.8.3.1
17b94a