LCOV - code coverage report
Current view: top level - plugins/http - http_buffer.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 2 72 2.8 %
Date: 2023-07-05 22:20:52 Functions: 2 13 15.4 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2022 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : 
      16             : #include <http/http_buffer.h>
      17             : #include <http/http.h>
      18             : 
      19             : static http_buffer_vft_t buf_vfts[HTTP_BUFFER_PTR + 1];
      20             : 
      21             : #define HTTP_BUFFER_REGISTER_VFT(type, vft)                                   \
      22             :   static void __attribute__ ((constructor)) http_buf_init_##type (void)       \
      23             :   {                                                                           \
      24             :     buf_vfts[type] = vft;                                                     \
      25             :   }
      26             : 
      27             : typedef struct http_buffer_fifo_
      28             : {
      29             :   svm_fifo_t *src;
      30             :   svm_fifo_seg_t *segs;
      31             :   u64 len;
      32             :   u64 offset;
      33             : } http_buffer_fifo_t;
      34             : 
      35             : STATIC_ASSERT (sizeof (http_buffer_fifo_t) <= HTTP_BUFFER_DATA_SZ, "buf data");
      36             : 
      37             : static void
      38           0 : buf_fifo_init (http_buffer_t *hb, void *data, u64 len)
      39             : {
      40           0 :   svm_fifo_t *f = (svm_fifo_t *) data;
      41             :   http_buffer_fifo_t *bf;
      42             : 
      43           0 :   bf = (http_buffer_fifo_t *) &hb->data;
      44             : 
      45           0 :   bf->len = len;
      46           0 :   bf->offset = 0;
      47           0 :   bf->src = f;
      48           0 :   bf->segs = 0;
      49           0 : }
      50             : 
      51             : static void
      52           0 : buf_fifo_free (http_buffer_t *hb)
      53             : {
      54           0 :   http_buffer_fifo_t *bf = (http_buffer_fifo_t *) &hb->data;
      55             : 
      56           0 :   bf->src = 0;
      57           0 :   vec_free (bf->segs);
      58           0 : }
      59             : 
      60             : static svm_fifo_seg_t *
      61           0 : buf_fifo_get_segs (http_buffer_t *hb, u32 max_len, u32 *n_segs)
      62             : {
      63           0 :   http_buffer_fifo_t *bf = (http_buffer_fifo_t *) &hb->data;
      64             : 
      65           0 :   u32 _n_segs = 5;
      66             :   int len;
      67             : 
      68           0 :   max_len = clib_min (bf->len - bf->offset, (u64) max_len);
      69             : 
      70           0 :   vec_validate (bf->segs, _n_segs);
      71             : 
      72           0 :   len = svm_fifo_segments (bf->src, 0, bf->segs, &_n_segs, max_len);
      73           0 :   if (len < 0)
      74           0 :     return 0;
      75             : 
      76           0 :   *n_segs = _n_segs;
      77             : 
      78             :   HTTP_DBG (1, "available to send %u n_segs %u", len, *n_segs);
      79             : 
      80           0 :   return bf->segs;
      81             : }
      82             : 
      83             : static u32
      84           0 : buf_fifo_drain (http_buffer_t *hb, u32 len)
      85             : {
      86           0 :   http_buffer_fifo_t *bf = (http_buffer_fifo_t *) &hb->data;
      87             : 
      88           0 :   bf->offset += len;
      89           0 :   svm_fifo_dequeue_drop (bf->src, len);
      90             :   HTTP_DBG (1, "drained %u len %u offset %u", len, bf->len, bf->offset);
      91             : 
      92           0 :   return len;
      93             : }
      94             : 
      95             : static u8
      96           0 : buf_fifo_is_drained (http_buffer_t *hb)
      97             : {
      98           0 :   http_buffer_fifo_t *bf = (http_buffer_fifo_t *) &hb->data;
      99             : 
     100           0 :   ASSERT (bf->offset <= bf->len);
     101           0 :   return (bf->offset == bf->len);
     102             : }
     103             : 
     104             : const static http_buffer_vft_t buf_fifo_vft = {
     105             :   .init = buf_fifo_init,
     106             :   .free = buf_fifo_free,
     107             :   .get_segs = buf_fifo_get_segs,
     108             :   .drain = buf_fifo_drain,
     109             :   .is_drained = buf_fifo_is_drained,
     110             : };
     111             : 
     112         559 : HTTP_BUFFER_REGISTER_VFT (HTTP_BUFFER_FIFO, buf_fifo_vft);
     113             : 
     114             : typedef struct http_buffer_ptr_
     115             : {
     116             :   svm_fifo_seg_t *segs;
     117             :   svm_fifo_t *f;
     118             : } http_buffer_ptr_t;
     119             : 
     120             : STATIC_ASSERT (sizeof (http_buffer_ptr_t) <= HTTP_BUFFER_DATA_SZ, "buf data");
     121             : 
     122             : static void
     123           0 : buf_ptr_init (http_buffer_t *hb, void *data, u64 len)
     124             : {
     125           0 :   svm_fifo_t *f = (svm_fifo_t *) data;
     126             :   http_buffer_ptr_t *bf;
     127             :   uword ptr;
     128             :   int rv;
     129             : 
     130           0 :   bf = (http_buffer_ptr_t *) &hb->data;
     131             : 
     132             :   /* Peek the pointer, do not drain the fifo until done with transfer */
     133           0 :   rv = svm_fifo_peek (f, 0, sizeof (ptr), (u8 *) &ptr);
     134           0 :   ASSERT (rv == sizeof (ptr));
     135             : 
     136           0 :   bf->f = f;
     137           0 :   bf->segs = 0;
     138           0 :   vec_validate (bf->segs, 1);
     139             : 
     140           0 :   bf->segs[0].data = uword_to_pointer (ptr, u8 *);
     141           0 :   bf->segs[0].len = len;
     142             : 
     143           0 :   bf->segs[1] = bf->segs[0];
     144           0 : }
     145             : 
     146             : static void
     147           0 : buf_ptr_free (http_buffer_t *hb)
     148             : {
     149           0 :   http_buffer_ptr_t *bf = (http_buffer_ptr_t *) &hb->data;
     150             : 
     151           0 :   bf->f = 0;
     152           0 :   vec_free (bf->segs);
     153           0 : }
     154             : 
     155             : static svm_fifo_seg_t *
     156           0 : buf_ptr_get_segs (http_buffer_t *hb, u32 max_len, u32 *n_segs)
     157             : {
     158           0 :   http_buffer_ptr_t *bf = (http_buffer_ptr_t *) &hb->data;
     159             : 
     160           0 :   *n_segs = 1;
     161           0 :   bf->segs[1].len = clib_min (bf->segs[0].len, max_len);
     162             : 
     163           0 :   return &bf->segs[1];
     164             : }
     165             : 
     166             : static u32
     167           0 : buf_ptr_drain (http_buffer_t *hb, u32 len)
     168             : {
     169           0 :   http_buffer_ptr_t *bf = (http_buffer_ptr_t *) &hb->data;
     170             : 
     171           0 :   ASSERT (bf->segs[0].len >= len);
     172             : 
     173           0 :   bf->segs[1].data += len;
     174           0 :   bf->segs[0].len -= len;
     175             : 
     176             :   HTTP_DBG (1, "drained %u left %u", len, bf->segs[1].len);
     177             : 
     178           0 :   if (!bf->segs[0].len)
     179             :     {
     180           0 :       svm_fifo_dequeue_drop (bf->f, sizeof (uword));
     181           0 :       return sizeof (uword);
     182             :     }
     183             : 
     184           0 :   return 0;
     185             : }
     186             : 
     187             : static u8
     188           0 : buf_ptr_is_drained (http_buffer_t *hb)
     189             : {
     190           0 :   http_buffer_ptr_t *bf = (http_buffer_ptr_t *) &hb->data;
     191             : 
     192           0 :   return (bf->segs[0].len == 0);
     193             : }
     194             : 
     195             : const static http_buffer_vft_t buf_ptr_vft = {
     196             :   .init = buf_ptr_init,
     197             :   .free = buf_ptr_free,
     198             :   .get_segs = buf_ptr_get_segs,
     199             :   .drain = buf_ptr_drain,
     200             :   .is_drained = buf_ptr_is_drained,
     201             : };
     202             : 
     203         559 : HTTP_BUFFER_REGISTER_VFT (HTTP_BUFFER_PTR, buf_ptr_vft);
     204             : 
     205             : void
     206           0 : http_buffer_init (http_buffer_t *hb, http_buffer_type_t type, svm_fifo_t *f,
     207             :                   u64 data_len)
     208             : {
     209           0 :   hb->vft = &buf_vfts[type];
     210           0 :   hb->vft->init (hb, f, data_len);
     211           0 : }
     212             : 
     213             : /*
     214             :  * fd.io coding-style-patch-verification: ON
     215             :  *
     216             :  * Local Variables:
     217             :  * eval: (c-set-style "gnu")
     218             :  * End:
     219             :  */

Generated by: LCOV version 1.14