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