Repository: valkey-io/valkey
File: src/cluster_legacy.c (C)

Code before:
        } else {
            clusterSendPublishMessage(node, type, msgblock);
        }
    }
    dictReleaseIterator(di);

    if (nodes_not_supporting_light_header) {
        server.cluster->is_light_hdr_supported = 0;
    } else {
        server.cluster->is_light_hdr_supported = 1;
    }
}

/* Build the message header. hdr must point to a buffer at least
 * sizeof(clusterMsg) in bytes. */
static void clusterBuildMessageHdr(clusterMsg *hdr, int type, size_t msglen) {
    hdr->ver = htons(CLUSTER_PROTO_VER);
    hdr->sig[0] = 'R';
    hdr->sig[1] = 'C';
    hdr->sig[2] = 'm';
    hdr->sig[3] = 'b';
    hdr->type = htons(type);
    hdr->totlen = htonl(msglen);

    if (type == CLUSTERMSG_TYPE_PUBLISH_LIGHT || type == CLUSTERMSG_TYPE_PUBLISHSHARD_LIGHT) {
        clusterMsgLight *hdr_light = (clusterMsgLight *)(void *)hdr;
        hdr_light->notused1 = 0;
        return;
    }

    uint64_t offset;
    clusterNode *primary;

    /* If this node is a primary, we send its slots bitmap and configEpoch.
     * If this node is a replica we send the primary's information instead (the
     * node is flagged as replica so the receiver knows that it is NOT really
     * in charge for this slots. */
    primary = (nodeIsReplica(myself) && myself->replicaof) ? myself->replicaof : myself;

    memcpy(hdr->sender, myself->name, CLUSTER_NAMELEN);

    /* If cluster-announce-ip option is enabled, force the receivers of our
     * packets to use the specified address for this node. Otherwise if the
     * first byte is zero, they'll do auto discovery. */
    memset(hdr->myip, 0, NET_IP_STR_LEN);
    if (server.cluster_announce_ip) {
        valkey_strlcpy(hdr->myip, server.cluster_announce_ip, NET_IP_STR_LEN);
    }

    /* Handle cluster-announce-[tls-|bus-]port. */
    int announced_tcp_port, announced_tls_port, announced_cport;

Review comment (suggestion):
Should it be just 

```suggestion
        clusterMsgLight *hdr_light = (clusterMsgLight *)hdr;
```

Code after:
 *
 * It is guaranteed that this function will never have as a side effect
 * some node->link to be invalidated, so it is safe to call this function
 * from event handlers that will do stuff with node links later. */
void clusterBroadcastMessage(clusterMsgSendBlock *msgblock) {
    dictIterator *di;
    dictEntry *de;

    di = dictGetSafeIterator(server.cluster->nodes);
    while ((de = dictNext(di)) != NULL) {
        clusterNode *node = dictGetVal(de);

        if (node->flags & (CLUSTER_NODE_MYSELF | CLUSTER_NODE_HANDSHAKE)) continue;
        clusterSendMessage(node->link, msgblock);
    }
    dictReleaseIterator(di);
}

static void clusterBuildMessageHdrLight(clusterMsgLight *hdr, int type, size_t msglen) {
    hdr->ver = htons(CLUSTER_PROTO_VER);
    hdr->sig[0] = 'R';
    hdr->sig[1] = 'C';
    hdr->sig[2] = 'm';
    hdr->sig[3] = 'b';
    hdr->type = htons(type);
    hdr->notused1 = 0;
    hdr->notused2 = 0;
    hdr->totlen = htonl(msglen);
}

/* Build the message header. hdr must point to a buffer at least
 * sizeof(clusterMsg) in bytes. */
static void clusterBuildMessageHdr(clusterMsg *hdr, int type, size_t msglen) {
    uint64_t offset;
    clusterNode *primary;

    /* If this node is a primary, we send its slots bitmap and configEpoch.
     * If this node is a replica we send the primary's information instead (the
     * node is flagged as replica so the receiver knows that it is NOT really
     * in charge for this slots. */
    primary = (nodeIsReplica(myself) && myself->replicaof) ? myself->replicaof : myself;

    hdr->ver = htons(CLUSTER_PROTO_VER);
    hdr->sig[0] = 'R';
    hdr->sig[1] = 'C';
    hdr->sig[2] = 'm';
    hdr->sig[3] = 'b';
    hdr->type = htons(type);
    memcpy(hdr->sender, myself->name, CLUSTER_NAMELEN);

    /* If cluster-announce-ip option is enabled, force the receivers of our