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