LCOV - code coverage report
Current view: top level - src/core/transport/chttp2 - frame_goaway.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 97 102 95.1 %
Date: 2015-10-10 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright 2015, Google Inc.
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions are
       8             :  * met:
       9             :  *
      10             :  *     * Redistributions of source code must retain the above copyright
      11             :  * notice, this list of conditions and the following disclaimer.
      12             :  *     * Redistributions in binary form must reproduce the above
      13             :  * copyright notice, this list of conditions and the following disclaimer
      14             :  * in the documentation and/or other materials provided with the
      15             :  * distribution.
      16             :  *     * Neither the name of Google Inc. nor the names of its
      17             :  * contributors may be used to endorse or promote products derived from
      18             :  * this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      23             :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      24             :  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      25             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      26             :  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      30             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             :  *
      32             :  */
      33             : 
      34             : #include "src/core/transport/chttp2/frame_goaway.h"
      35             : #include "src/core/transport/chttp2/internal.h"
      36             : 
      37             : #include <string.h>
      38             : 
      39             : #include <grpc/support/alloc.h>
      40             : #include <grpc/support/log.h>
      41             : 
      42        4014 : void grpc_chttp2_goaway_parser_init(grpc_chttp2_goaway_parser *p) {
      43        4014 :   p->debug_data = NULL;
      44        4014 : }
      45             : 
      46        4014 : void grpc_chttp2_goaway_parser_destroy(grpc_chttp2_goaway_parser *p) {
      47        4014 :   gpr_free(p->debug_data);
      48        4014 : }
      49             : 
      50         229 : grpc_chttp2_parse_error grpc_chttp2_goaway_parser_begin_frame(
      51             :     grpc_chttp2_goaway_parser *p, gpr_uint32 length, gpr_uint8 flags) {
      52         229 :   if (length < 8) {
      53           0 :     gpr_log(GPR_ERROR, "goaway frame too short (%d bytes)", length);
      54           0 :     return GRPC_CHTTP2_CONNECTION_ERROR;
      55             :   }
      56             : 
      57         229 :   gpr_free(p->debug_data);
      58         229 :   p->debug_length = length - 8;
      59         229 :   p->debug_data = gpr_malloc(p->debug_length);
      60         229 :   p->debug_pos = 0;
      61         229 :   p->state = GRPC_CHTTP2_GOAWAY_LSI0;
      62         229 :   return GRPC_CHTTP2_PARSE_OK;
      63             : }
      64             : 
      65         317 : grpc_chttp2_parse_error grpc_chttp2_goaway_parser_parse(
      66             :     grpc_exec_ctx *exec_ctx, void *parser,
      67             :     grpc_chttp2_transport_parsing *transport_parsing,
      68             :     grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last) {
      69         317 :   gpr_uint8 *const beg = GPR_SLICE_START_PTR(slice);
      70         317 :   gpr_uint8 *const end = GPR_SLICE_END_PTR(slice);
      71         317 :   gpr_uint8 *cur = beg;
      72         317 :   grpc_chttp2_goaway_parser *p = parser;
      73             : 
      74         317 :   switch (p->state) {
      75             :     case GRPC_CHTTP2_GOAWAY_LSI0:
      76         229 :       if (cur == end) {
      77           0 :         p->state = GRPC_CHTTP2_GOAWAY_LSI0;
      78           0 :         return GRPC_CHTTP2_PARSE_OK;
      79             :       }
      80         229 :       p->last_stream_id = ((gpr_uint32)*cur) << 24;
      81         229 :       ++cur;
      82             :     /* fallthrough */
      83             :     case GRPC_CHTTP2_GOAWAY_LSI1:
      84         233 :       if (cur == end) {
      85           4 :         p->state = GRPC_CHTTP2_GOAWAY_LSI1;
      86           4 :         return GRPC_CHTTP2_PARSE_OK;
      87             :       }
      88         229 :       p->last_stream_id |= ((gpr_uint32)*cur) << 16;
      89         229 :       ++cur;
      90             :     /* fallthrough */
      91             :     case GRPC_CHTTP2_GOAWAY_LSI2:
      92         233 :       if (cur == end) {
      93           4 :         p->state = GRPC_CHTTP2_GOAWAY_LSI2;
      94           4 :         return GRPC_CHTTP2_PARSE_OK;
      95             :       }
      96         229 :       p->last_stream_id |= ((gpr_uint32)*cur) << 8;
      97         229 :       ++cur;
      98             :     /* fallthrough */
      99             :     case GRPC_CHTTP2_GOAWAY_LSI3:
     100         233 :       if (cur == end) {
     101           4 :         p->state = GRPC_CHTTP2_GOAWAY_LSI3;
     102           4 :         return GRPC_CHTTP2_PARSE_OK;
     103             :       }
     104         229 :       p->last_stream_id |= ((gpr_uint32)*cur);
     105         229 :       ++cur;
     106             :     /* fallthrough */
     107             :     case GRPC_CHTTP2_GOAWAY_ERR0:
     108         233 :       if (cur == end) {
     109           4 :         p->state = GRPC_CHTTP2_GOAWAY_ERR0;
     110           4 :         return GRPC_CHTTP2_PARSE_OK;
     111             :       }
     112         229 :       p->error_code = ((gpr_uint32)*cur) << 24;
     113         229 :       ++cur;
     114             :     /* fallthrough */
     115             :     case GRPC_CHTTP2_GOAWAY_ERR1:
     116         233 :       if (cur == end) {
     117           4 :         p->state = GRPC_CHTTP2_GOAWAY_ERR1;
     118           4 :         return GRPC_CHTTP2_PARSE_OK;
     119             :       }
     120         229 :       p->error_code |= ((gpr_uint32)*cur) << 16;
     121         229 :       ++cur;
     122             :     /* fallthrough */
     123             :     case GRPC_CHTTP2_GOAWAY_ERR2:
     124         233 :       if (cur == end) {
     125           4 :         p->state = GRPC_CHTTP2_GOAWAY_ERR2;
     126           4 :         return GRPC_CHTTP2_PARSE_OK;
     127             :       }
     128         229 :       p->error_code |= ((gpr_uint32)*cur) << 8;
     129         229 :       ++cur;
     130             :     /* fallthrough */
     131             :     case GRPC_CHTTP2_GOAWAY_ERR3:
     132         233 :       if (cur == end) {
     133           4 :         p->state = GRPC_CHTTP2_GOAWAY_ERR3;
     134           4 :         return GRPC_CHTTP2_PARSE_OK;
     135             :       }
     136         229 :       p->error_code |= ((gpr_uint32)*cur);
     137         229 :       ++cur;
     138             :     /* fallthrough */
     139             :     case GRPC_CHTTP2_GOAWAY_DEBUG:
     140         289 :       memcpy(p->debug_data + p->debug_pos, cur, (size_t)(end - cur));
     141         289 :       GPR_ASSERT((size_t)(end - cur) < GPR_UINT32_MAX - p->debug_pos);
     142         289 :       p->debug_pos += (gpr_uint32)(end - cur);
     143         289 :       p->state = GRPC_CHTTP2_GOAWAY_DEBUG;
     144         289 :       if (is_last) {
     145         229 :         transport_parsing->goaway_received = 1;
     146         229 :         transport_parsing->goaway_last_stream_index = p->last_stream_id;
     147         229 :         gpr_slice_unref(transport_parsing->goaway_text);
     148         229 :         transport_parsing->goaway_error = (grpc_status_code)p->error_code;
     149         229 :         transport_parsing->goaway_text =
     150         229 :             gpr_slice_new(p->debug_data, p->debug_length, gpr_free);
     151         229 :         p->debug_data = NULL;
     152             :       }
     153         289 :       return GRPC_CHTTP2_PARSE_OK;
     154             :   }
     155           0 :   GPR_UNREACHABLE_CODE(return GRPC_CHTTP2_CONNECTION_ERROR);
     156             : }
     157             : 
     158        1772 : void grpc_chttp2_goaway_append(gpr_uint32 last_stream_id, gpr_uint32 error_code,
     159             :                                gpr_slice debug_data,
     160             :                                gpr_slice_buffer *slice_buffer) {
     161        1772 :   gpr_slice header = gpr_slice_malloc(9 + 4 + 4);
     162        1772 :   gpr_uint8 *p = GPR_SLICE_START_PTR(header);
     163             :   gpr_uint32 frame_length;
     164        1772 :   GPR_ASSERT(GPR_SLICE_LENGTH(debug_data) < GPR_UINT32_MAX - 4 - 4);
     165        1772 :   frame_length = 4 + 4 + (gpr_uint32)GPR_SLICE_LENGTH(debug_data);
     166             : 
     167             :   /* frame header: length */
     168        1772 :   *p++ = (gpr_uint8)(frame_length >> 16);
     169        1772 :   *p++ = (gpr_uint8)(frame_length >> 8);
     170        1772 :   *p++ = (gpr_uint8)(frame_length);
     171             :   /* frame header: type */
     172        1772 :   *p++ = GRPC_CHTTP2_FRAME_GOAWAY;
     173             :   /* frame header: flags */
     174        1772 :   *p++ = 0;
     175             :   /* frame header: stream id */
     176        1772 :   *p++ = 0;
     177        1772 :   *p++ = 0;
     178        1772 :   *p++ = 0;
     179        1772 :   *p++ = 0;
     180             :   /* payload: last stream id */
     181        1772 :   *p++ = (gpr_uint8)(last_stream_id >> 24);
     182        1772 :   *p++ = (gpr_uint8)(last_stream_id >> 16);
     183        1772 :   *p++ = (gpr_uint8)(last_stream_id >> 8);
     184        1772 :   *p++ = (gpr_uint8)(last_stream_id);
     185             :   /* payload: error code */
     186        1772 :   *p++ = (gpr_uint8)(error_code >> 24);
     187        1772 :   *p++ = (gpr_uint8)(error_code >> 16);
     188        1772 :   *p++ = (gpr_uint8)(error_code >> 8);
     189        1772 :   *p++ = (gpr_uint8)(error_code);
     190        1772 :   GPR_ASSERT(p == GPR_SLICE_END_PTR(header));
     191        1772 :   gpr_slice_buffer_add(slice_buffer, header);
     192        1772 :   gpr_slice_buffer_add(slice_buffer, debug_data);
     193        1772 : }

Generated by: LCOV version 1.10