// SPDX-License-Identifier: GPL-2.0-only /****************************************************************************** ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. ** ** ******************************************************************************* ******************************************************************************/ /* * midcomms.c * * This is the appallingly named "mid-level" comms layer. * * Its purpose is to take packets from the "real" comms layer, * split them up into packets and pass them to the interested * part of the locking mechanism. * * It also takes messages from the locking layer, formats them * into packets and sends them to the comms layer. */ #include #include "dlm_internal.h" #include "lowcomms.h" #include "config.h" #include "lock.h" #include "midcomms.h" /* * Called from the low-level comms layer to process a buffer of * commands. */ int dlm_process_incoming_buffer(int nodeid, unsigned char *buf, int len) { const unsigned char *ptr = buf; const struct dlm_header *hd; uint16_t msglen; int ret = 0; while (len >= sizeof(struct dlm_header)) { hd = (struct dlm_header *)ptr; /* no message should be more than this otherwise we * cannot deliver this message to upper layers */ msglen = get_unaligned_le16(&hd->h_length); if (msglen > DEFAULT_BUFFER_SIZE) { log_print("received invalid length header: %u, will abort message parsing", msglen); return -EBADMSG; } /* caller will take care that leftover * will be parsed next call with more data */ if (msglen > len) break; switch (hd->h_cmd) { case DLM_MSG: if (msglen < sizeof(struct dlm_message)) { log_print("dlm msg too small: %u, will skip this message", msglen); goto skip; } break; case DLM_RCOM: if (msglen < sizeof(struct dlm_rcom)) { log_print("dlm rcom msg too small: %u, will skip this message", msglen); goto skip; } break; default: log_print("unsupported h_cmd received: %u, will skip this message", hd->h_cmd); goto skip; } /* for aligned memory access, we just copy current message * to begin of the buffer which contains already parsed buffer * data and should provide align access for upper layers * because the start address of the buffer has a aligned * address. This memmove can be removed when the upperlayer * is capable of unaligned memory access. */ memmove(buf, ptr, msglen); dlm_receive_buffer((union dlm_packet *)buf, nodeid); skip: ret += msglen; len -= msglen; ptr += msglen; } return ret; }