pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
ipc_common.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2025 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8 */
9
10#include <crm_internal.h>
11
12#include <stdio.h>
13#include <stdint.h> // uint64_t
14#include <sys/types.h>
15
16#include <crm/common/xml.h>
17#include "crmcommon_private.h"
18
19/* The IPC buffer is always 128k. If we are asked to send a message larger
20 * than that size, it will be split into multiple messages that must be
21 * reassembled on the other end.
22 */
23#define BUFFER_SIZE (128*1024) // 128k
24
30unsigned int
35
44bool
46{
47 if (header == NULL) {
48 crm_err("IPC message without header");
49 return false;
50
51 } else if (header->version > PCMK__IPC_VERSION) {
52 crm_err("Filtering incompatible v%d IPC message (only versions <= %d supported)",
53 header->version, PCMK__IPC_VERSION);
54 return false;
55 }
56 return true;
57}
58
59const char *
60pcmk__client_type_str(uint64_t client_type)
61{
62 switch (client_type) {
64 return "IPC";
66 return "TCP";
68 return "TLS";
69 default:
70 return "unknown";
71 }
72}
73
98int
99pcmk__ipc_msg_append(GByteArray **buffer, guint8 *data)
100{
101 pcmk__ipc_header_t *full_header = NULL;
102 pcmk__ipc_header_t *header = (pcmk__ipc_header_t *) (void *) data;
103 const guint8 *payload = (guint8 *) data + sizeof(pcmk__ipc_header_t);
104 int rc = pcmk_rc_ok;
105
106 if (!pcmk__valid_ipc_header(header)) {
107 return EBADMSG;
108 }
109
111 full_header = (pcmk__ipc_header_t *) (void *) (*buffer)->data;
112
113 /* This is the end of a multipart IPC message. Add the payload of the
114 * received data (so, don't include the header) to the partial buffer.
115 * Remember that this needs to include the null terminating character.
116 */
117 CRM_CHECK(buffer != NULL && *buffer != NULL && header->part_id != 0,
118 return EINVAL);
119 CRM_CHECK(full_header->qb.id == header->qb.id, return EBADMSG);
120 g_byte_array_append(*buffer, payload, header->size);
121
122 crm_trace("Received IPC message %" PRId32 " (final part %" PRIu16 ") of %"
123 PRId32 " bytes",
124 header->qb.id, header->part_id, header->qb.size);
125
126 } else if (pcmk_is_set(header->flags, crm_ipc_multipart)) {
127 if (header->part_id == 0) {
128 /* This is the first part of a multipart IPC message. Initialize
129 * the buffer with the entire message, including its header. Do
130 * not include the null terminating character.
131 */
132 CRM_CHECK(buffer != NULL && *buffer == NULL, return EINVAL);
133 *buffer = g_byte_array_new();
134
135 /* Clear any multipart flags from the header of the incoming part
136 * so they'll be clear in the fully reassembled message. This
137 * message is passed to pcmk__client_data2xml, which will extract
138 * the header flags and return them. Those flags can then be used
139 * when constructing a reply, including ACKs. We don't want these
140 * specific incoming flags to influence the reply.
141 */
143
144 g_byte_array_append(*buffer, data,
145 sizeof(pcmk__ipc_header_t) + header->size - 1);
146
147 } else {
148 full_header = (pcmk__ipc_header_t *) (void *) (*buffer)->data;
149
150 /* This is some intermediate part of a multipart message. Add
151 * the payload of the received data (so, don't include the header)
152 * to the partial buffer and return. Do not include the null
153 * terminating character.
154 */
155 CRM_CHECK(buffer != NULL && *buffer != NULL, return EINVAL);
156 CRM_CHECK(full_header->qb.id == header->qb.id, return EBADMSG);
157 g_byte_array_append(*buffer, payload, header->size - 1);
158 }
159
160 crm_trace("Received IPC message %" PRId32 " (part %" PRIu16 ") of %"
161 PRId32 " bytes",
162 header->qb.id, header->part_id, header->qb.size);
163
164 rc = pcmk_rc_ipc_more;
165
166 } else {
167 /* This is a standalone IPC message. For simplicity in the caller,
168 * copy the entire message over into a byte array so it can be handled
169 * the same as a multipart message.
170 */
171 CRM_CHECK(buffer != NULL && *buffer == NULL, return EINVAL);
172 *buffer = g_byte_array_new();
173 g_byte_array_append(*buffer, data,
174 sizeof(pcmk__ipc_header_t) + header->size);
175
176 crm_trace("Received IPC message %" PRId32 " of %" PRId32 " bytes",
177 header->qb.id, header->qb.size);
178 }
179
180 crm_trace("Text = %s", payload);
181 crm_trace("Buffer = %s", (*buffer)->data + sizeof(pcmk__ipc_header_t));
182
183 /* The buffer's header should have a size that matches the full size of
184 * the received message, not just the last chunk of it.
185 */
186 full_header = (pcmk__ipc_header_t *) (void *) (*buffer)->data;
187 full_header->size = (*buffer)->len - sizeof(pcmk__ipc_header_t);
188
189 return rc;
190}
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:80
char data[0]
Definition cpg.c:10
struct pcmk__ipc_header_s pcmk__ipc_header_t
#define PCMK__IPC_VERSION
@ crm_ipc_multipart
This is a multi-part IPC message.
Definition ipc.h:154
@ crm_ipc_multipart_end
This is the end of a multi-part IPC message.
Definition ipc.h:156
int pcmk__ipc_msg_append(GByteArray **buffer, guint8 *data)
Definition ipc_common.c:99
const char * pcmk__client_type_str(uint64_t client_type)
Definition ipc_common.c:60
unsigned int crm_ipc_default_buffer_size(void)
Return pacemaker's IPC buffer size.
Definition ipc_common.c:31
bool pcmk__valid_ipc_header(const pcmk__ipc_header_t *header)
Definition ipc_common.c:45
#define BUFFER_SIZE
Definition ipc_common.c:23
@ pcmk__client_ipc
Client uses plain IPC.
@ pcmk__client_tls
Client uses TCP with TLS.
@ pcmk__client_tcp
Client uses TCP connection.
#define pcmk__clear_ipc_flags(ipc_flags, ipc_name, flags_to_clear)
#define CRM_CHECK(expr, failure_action)
Definition logging.h:213
#define crm_err(fmt, args...)
Definition logging.h:357
#define crm_trace(fmt, args...)
Definition logging.h:370
@ pcmk_rc_ipc_more
Definition results.h:113
@ pcmk_rc_ok
Definition results.h:159
struct qb_ipc_response_header qb
Wrappers for and extensions to libxml2.