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