linux/fs/dlm/midcomms.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/******************************************************************************
   3*******************************************************************************
   4**
   5**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
   6**  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
   7**
   8**
   9*******************************************************************************
  10******************************************************************************/
  11
  12/*
  13 * midcomms.c
  14 *
  15 * This is the appallingly named "mid-level" comms layer.
  16 *
  17 * Its purpose is to take packets from the "real" comms layer,
  18 * split them up into packets and pass them to the interested
  19 * part of the locking mechanism.
  20 *
  21 * It also takes messages from the locking layer, formats them
  22 * into packets and sends them to the comms layer.
  23 */
  24
  25#include "dlm_internal.h"
  26#include "lowcomms.h"
  27#include "config.h"
  28#include "lock.h"
  29#include "midcomms.h"
  30
  31/*
  32 * Called from the low-level comms layer to process a buffer of
  33 * commands.
  34 */
  35
  36int dlm_process_incoming_buffer(int nodeid, unsigned char *buf, int len)
  37{
  38        const unsigned char *ptr = buf;
  39        const struct dlm_header *hd;
  40        uint16_t msglen;
  41        int ret = 0;
  42
  43        while (len >= sizeof(struct dlm_header)) {
  44                hd = (struct dlm_header *)ptr;
  45
  46                /* no message should be more than DEFAULT_BUFFER_SIZE or
  47                 * less than dlm_header size.
  48                 *
  49                 * Some messages does not have a 8 byte length boundary yet
  50                 * which can occur in a unaligned memory access of some dlm
  51                 * messages. However this problem need to be fixed at the
  52                 * sending side, for now it seems nobody run into architecture
  53                 * related issues yet but it slows down some processing.
  54                 * Fixing this issue should be scheduled in future by doing
  55                 * the next major version bump.
  56                 */
  57                msglen = le16_to_cpu(hd->h_length);
  58                if (msglen > DEFAULT_BUFFER_SIZE ||
  59                    msglen < sizeof(struct dlm_header)) {
  60                        log_print("received invalid length header: %u from node %d, will abort message parsing",
  61                                  msglen, nodeid);
  62                        return -EBADMSG;
  63                }
  64
  65                /* caller will take care that leftover
  66                 * will be parsed next call with more data
  67                 */
  68                if (msglen > len)
  69                        break;
  70
  71                switch (hd->h_cmd) {
  72                case DLM_MSG:
  73                        if (msglen < sizeof(struct dlm_message)) {
  74                                log_print("dlm msg too small: %u, will skip this message",
  75                                          msglen);
  76                                goto skip;
  77                        }
  78
  79                        break;
  80                case DLM_RCOM:
  81                        if (msglen < sizeof(struct dlm_rcom)) {
  82                                log_print("dlm rcom msg too small: %u, will skip this message",
  83                                          msglen);
  84                                goto skip;
  85                        }
  86
  87                        break;
  88                default:
  89                        log_print("unsupported h_cmd received: %u, will skip this message",
  90                                  hd->h_cmd);
  91                        goto skip;
  92                }
  93
  94                dlm_receive_buffer((union dlm_packet *)ptr, nodeid);
  95
  96skip:
  97                ret += msglen;
  98                len -= msglen;
  99                ptr += msglen;
 100        }
 101
 102        return ret;
 103}
 104
 105