Skip to main content
  • Home
  • login
  • Browse the archive

    swh mirror partner logo
swh logo
SoftwareHeritage
Software
Heritage
Mirror
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

Revision c94d13a06965d4a3d9abf15d3cf5dc90c9d7c49c authored by Adam (ThinLinc team) on 29 July 2024, 11:54:46 UTC, committed by Tomas Mraz on 02 September 2024, 08:24:58 UTC
Detect MinGW 32 bit for NO_INTERLOCKEDOR64
Builds using 32 bit MinGW will fail, due to the same reasoning described in commit 2d46a44ff24173d2cf5ea2196360cb79470d49c7.

CLA: trivial

Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25025)
1 parent d5b3c0e
  • Files
  • Changes
  • 4b510de
  • /
  • ssl
  • /
  • quic
  • /
  • quic_fifd.c
Raw File
Cook and download a directory from the Software Heritage Vault

You have requested the cooking of the directory with identifier None into a standard tar.gz archive.

Are you sure you want to continue ?

Download a directory from the Software Heritage Vault

You have requested the download of the directory with identifier None as a standard tar.gz archive.

Are you sure you want to continue ?

Cook and download a revision from the Software Heritage Vault

You have requested the cooking of the history heading to revision with identifier swh:1:rev:c94d13a06965d4a3d9abf15d3cf5dc90c9d7c49c into a bare git archive.

Are you sure you want to continue ?

Download a revision from the Software Heritage Vault

You have requested the download of the history heading to revision with identifier swh:1:rev:c94d13a06965d4a3d9abf15d3cf5dc90c9d7c49c as a bare git archive.

Are you sure you want to continue ?

Invalid Email !

The provided email is not well-formed.

Download link has expired

The requested archive is no longer available for download from the Software Heritage Vault.

Do you want to cook it again ?

Permalinks

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • revision
  • content
revision badge
swh:1:rev:c94d13a06965d4a3d9abf15d3cf5dc90c9d7c49c
content badge Iframe embedding
swh:1:cnt:1d1bcc11ce633c3fb9d1ae24423003c86603b716
quic_fifd.c
/*
 * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include "internal/quic_fifd.h"
#include "internal/quic_wire.h"
#include "internal/qlog_event_helpers.h"

DEFINE_LIST_OF(tx_history, OSSL_ACKM_TX_PKT);

int ossl_quic_fifd_init(QUIC_FIFD *fifd,
                        QUIC_CFQ *cfq,
                        OSSL_ACKM *ackm,
                        QUIC_TXPIM *txpim,
                        /* stream_id is UINT64_MAX for the crypto stream */
                        QUIC_SSTREAM *(*get_sstream_by_id)(uint64_t stream_id,
                                                           uint32_t pn_space,
                                                           void *arg),
                        void *get_sstream_by_id_arg,
                        /* stream_id is UINT64_MAX if not applicable */
                        void (*regen_frame)(uint64_t frame_type,
                                            uint64_t stream_id,
                                            QUIC_TXPIM_PKT *pkt,
                                            void *arg),
                        void *regen_frame_arg,
                        void (*confirm_frame)(uint64_t frame_type,
                                              uint64_t stream_id,
                                              QUIC_TXPIM_PKT *pkt,
                                              void *arg),
                        void *confirm_frame_arg,
                        void (*sstream_updated)(uint64_t stream_id,
                                                void *arg),
                        void *sstream_updated_arg,
                        QLOG *(*get_qlog_cb)(void *arg),
                        void *get_qlog_cb_arg)
{
    if (cfq == NULL || ackm == NULL || txpim == NULL
        || get_sstream_by_id == NULL || regen_frame == NULL)
        return 0;

    fifd->cfq                   = cfq;
    fifd->ackm                  = ackm;
    fifd->txpim                 = txpim;
    fifd->get_sstream_by_id     = get_sstream_by_id;
    fifd->get_sstream_by_id_arg = get_sstream_by_id_arg;
    fifd->regen_frame           = regen_frame;
    fifd->regen_frame_arg       = regen_frame_arg;
    fifd->confirm_frame         = confirm_frame;
    fifd->confirm_frame_arg     = confirm_frame_arg;
    fifd->sstream_updated       = sstream_updated;
    fifd->sstream_updated_arg   = sstream_updated_arg;
    fifd->get_qlog_cb           = get_qlog_cb;
    fifd->get_qlog_cb_arg       = get_qlog_cb_arg;
    return 1;
}

void ossl_quic_fifd_cleanup(QUIC_FIFD *fifd)
{
    /* No-op. */
}

static void on_acked(void *arg)
{
    QUIC_TXPIM_PKT *pkt = arg;
    QUIC_FIFD *fifd = pkt->fifd;
    const QUIC_TXPIM_CHUNK *chunks = ossl_quic_txpim_pkt_get_chunks(pkt);
    size_t i, num_chunks = ossl_quic_txpim_pkt_get_num_chunks(pkt);
    QUIC_SSTREAM *sstream;
    QUIC_CFQ_ITEM *cfq_item, *cfq_item_next;

    /* STREAM and CRYPTO stream chunks, FINs and stream FC frames */
    for (i = 0; i < num_chunks; ++i) {
        sstream = fifd->get_sstream_by_id(chunks[i].stream_id,
                                          pkt->ackm_pkt.pkt_space,
                                          fifd->get_sstream_by_id_arg);
        if (sstream == NULL)
            continue;

        if (chunks[i].end >= chunks[i].start)
            /* coverity[check_return]: Best effort - we cannot fail here. */
            ossl_quic_sstream_mark_acked(sstream,
                                         chunks[i].start, chunks[i].end);

        if (chunks[i].has_fin && chunks[i].stream_id != UINT64_MAX)
            ossl_quic_sstream_mark_acked_fin(sstream);

        if (chunks[i].has_stop_sending && chunks[i].stream_id != UINT64_MAX)
            fifd->confirm_frame(OSSL_QUIC_FRAME_TYPE_STOP_SENDING,
                                chunks[i].stream_id, pkt,
                                fifd->confirm_frame_arg);

        if (chunks[i].has_reset_stream && chunks[i].stream_id != UINT64_MAX)
            fifd->confirm_frame(OSSL_QUIC_FRAME_TYPE_RESET_STREAM,
                                chunks[i].stream_id, pkt,
                                fifd->confirm_frame_arg);

        if (ossl_quic_sstream_is_totally_acked(sstream))
            fifd->sstream_updated(chunks[i].stream_id, fifd->sstream_updated_arg);
    }

    /* GCR */
    for (cfq_item = pkt->retx_head; cfq_item != NULL; cfq_item = cfq_item_next) {
        cfq_item_next = cfq_item->pkt_next;
        ossl_quic_cfq_release(fifd->cfq, cfq_item);
    }

    ossl_quic_txpim_pkt_release(fifd->txpim, pkt);
}

static QLOG *fifd_get_qlog(QUIC_FIFD *fifd)
{
    if (fifd->get_qlog_cb == NULL)
        return NULL;

    return fifd->get_qlog_cb(fifd->get_qlog_cb_arg);
}

static void on_lost(void *arg)
{
    QUIC_TXPIM_PKT *pkt = arg;
    QUIC_FIFD *fifd = pkt->fifd;
    const QUIC_TXPIM_CHUNK *chunks = ossl_quic_txpim_pkt_get_chunks(pkt);
    size_t i, num_chunks = ossl_quic_txpim_pkt_get_num_chunks(pkt);
    QUIC_SSTREAM *sstream;
    QUIC_CFQ_ITEM *cfq_item, *cfq_item_next;
    int sstream_updated;

    ossl_qlog_event_recovery_packet_lost(fifd_get_qlog(fifd), pkt);

    /* STREAM and CRYPTO stream chunks, FIN and stream FC frames */
    for (i = 0; i < num_chunks; ++i) {
        sstream = fifd->get_sstream_by_id(chunks[i].stream_id,
                                          pkt->ackm_pkt.pkt_space,
                                          fifd->get_sstream_by_id_arg);
        if (sstream == NULL)
            continue;

        sstream_updated = 0;

        if (chunks[i].end >= chunks[i].start) {
            /*
             * Note: If the stream is being reset, we do not need to retransmit
             * old data as this is pointless. In this case this will be handled
             * by (sstream == NULL) above as the QSM will free the QUIC_SSTREAM
             * and our call to get_sstream_by_id above will return NULL.
             */
            ossl_quic_sstream_mark_lost(sstream,
                                        chunks[i].start, chunks[i].end);
            sstream_updated = 1;
        }

        if (chunks[i].has_fin && chunks[i].stream_id != UINT64_MAX) {
            ossl_quic_sstream_mark_lost_fin(sstream);
            sstream_updated = 1;
        }

        if (chunks[i].has_stop_sending && chunks[i].stream_id != UINT64_MAX)
            fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_STOP_SENDING,
                              chunks[i].stream_id, pkt,
                              fifd->regen_frame_arg);

        if (chunks[i].has_reset_stream && chunks[i].stream_id != UINT64_MAX)
            fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_RESET_STREAM,
                              chunks[i].stream_id, pkt,
                              fifd->regen_frame_arg);

        /*
         * Inform caller that stream needs an FC frame.
         *
         * Note: We could track whether an FC frame was sent originally for the
         * stream to determine if it really needs to be regenerated or not.
         * However, if loss has occurred, it's probably better to ensure the
         * peer has up-to-date flow control data for the stream. Given that
         * these frames are extremely small, we may as well always send it when
         * handling loss.
         */
        fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA,
                          chunks[i].stream_id,
                          pkt,
                          fifd->regen_frame_arg);

        if (sstream_updated && chunks[i].stream_id != UINT64_MAX)
            fifd->sstream_updated(chunks[i].stream_id,
                                  fifd->sstream_updated_arg);
    }

    /* GCR */
    for (cfq_item = pkt->retx_head; cfq_item != NULL; cfq_item = cfq_item_next) {
        cfq_item_next = cfq_item->pkt_next;
        ossl_quic_cfq_mark_lost(fifd->cfq, cfq_item, UINT32_MAX);
    }

    /* Regenerate flag frames */
    if (pkt->had_handshake_done_frame)
        fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE,
                          UINT64_MAX, pkt,
                          fifd->regen_frame_arg);

    if (pkt->had_max_data_frame)
        fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_MAX_DATA,
                          UINT64_MAX, pkt,
                          fifd->regen_frame_arg);

    if (pkt->had_max_streams_bidi_frame)
        fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI,
                          UINT64_MAX, pkt,
                          fifd->regen_frame_arg);

    if (pkt->had_max_streams_uni_frame)
        fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI,
                          UINT64_MAX, pkt,
                          fifd->regen_frame_arg);

    if (pkt->had_ack_frame)
        /*
         * We always use the ACK_WITH_ECN frame type to represent the ACK frame
         * type in our callback; we assume it is the caller's job to decide
         * whether it wants to send ECN data or not.
         */
        fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN,
                          UINT64_MAX, pkt,
                          fifd->regen_frame_arg);

    ossl_quic_txpim_pkt_release(fifd->txpim, pkt);
}

static void on_discarded(void *arg)
{
    QUIC_TXPIM_PKT *pkt = arg;
    QUIC_FIFD *fifd = pkt->fifd;
    QUIC_CFQ_ITEM *cfq_item, *cfq_item_next;

    /*
     * Don't need to do anything to SSTREAMs for STREAM and CRYPTO streams, as
     * we assume caller will clean them up.
     */

    /* GCR */
    for (cfq_item = pkt->retx_head; cfq_item != NULL; cfq_item = cfq_item_next) {
        cfq_item_next = cfq_item->pkt_next;
        ossl_quic_cfq_release(fifd->cfq, cfq_item);
    }

    ossl_quic_txpim_pkt_release(fifd->txpim, pkt);
}

int ossl_quic_fifd_pkt_commit(QUIC_FIFD *fifd, QUIC_TXPIM_PKT *pkt)
{
    QUIC_CFQ_ITEM *cfq_item;
    const QUIC_TXPIM_CHUNK *chunks;
    size_t i, num_chunks;
    QUIC_SSTREAM *sstream;

    pkt->fifd                   = fifd;

    pkt->ackm_pkt.on_lost       = on_lost;
    pkt->ackm_pkt.on_acked      = on_acked;
    pkt->ackm_pkt.on_discarded  = on_discarded;
    pkt->ackm_pkt.cb_arg        = pkt;

    ossl_list_tx_history_init_elem(&pkt->ackm_pkt);
    pkt->ackm_pkt.anext = pkt->ackm_pkt.lnext = NULL;

    /*
     * Mark the CFQ items which have been added to this packet as having been
     * transmitted.
     */
    for (cfq_item = pkt->retx_head;
         cfq_item != NULL;
         cfq_item = cfq_item->pkt_next)
        ossl_quic_cfq_mark_tx(fifd->cfq, cfq_item);

    /*
     * Mark the send stream chunks which have been added to the packet as having
     * been transmitted.
     */
    chunks = ossl_quic_txpim_pkt_get_chunks(pkt);
    num_chunks = ossl_quic_txpim_pkt_get_num_chunks(pkt);
    for (i = 0; i < num_chunks; ++i) {
        sstream = fifd->get_sstream_by_id(chunks[i].stream_id,
                                          pkt->ackm_pkt.pkt_space,
                                          fifd->get_sstream_by_id_arg);
        if (sstream == NULL)
            continue;

        if (chunks[i].end >= chunks[i].start
            && !ossl_quic_sstream_mark_transmitted(sstream,
                                                   chunks[i].start,
                                                   chunks[i].end))
            return 0;

        if (chunks[i].has_fin
            && !ossl_quic_sstream_mark_transmitted_fin(sstream,
                                                       chunks[i].end + 1))
                return 0;
    }

    /* Inform the ACKM. */
    return ossl_ackm_on_tx_packet(fifd->ackm, &pkt->ackm_pkt);
}

void ossl_quic_fifd_set_qlog_cb(QUIC_FIFD *fifd, QLOG *(*get_qlog_cb)(void *arg),
                                void *get_qlog_cb_arg)
{
    fifd->get_qlog_cb       = get_qlog_cb;
    fifd->get_qlog_cb_arg   = get_qlog_cb_arg;
}
The diff you're trying to view is too large. Only the first 1000 changed files have been loaded.
Showing with 0 additions and 0 deletions (0 / 0 diffs computed)
swh spinner

Computing file changes ...

ENEA — Copyright (C), ENEA. License: GNU AGPLv3+.
Legal notes  ::  JavaScript license information ::  Web API

back to top