Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / src / core / ext / transport / chttp2 / transport / frame_goaway.cc
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 #include <grpc/support/port_platform.h>
20
21 #include "src/core/ext/transport/chttp2/transport/frame_goaway.h"
22 #include "src/core/ext/transport/chttp2/transport/internal.h"
23
24 #include <string.h>
25
26 #include <grpc/support/alloc.h>
27 #include <grpc/support/log.h>
28 #include <grpc/support/string_util.h>
29
30 void grpc_chttp2_goaway_parser_init(grpc_chttp2_goaway_parser* p) {
31   p->debug_data = nullptr;
32 }
33
34 void grpc_chttp2_goaway_parser_destroy(grpc_chttp2_goaway_parser* p) {
35   gpr_free(p->debug_data);
36 }
37
38 grpc_error* grpc_chttp2_goaway_parser_begin_frame(grpc_chttp2_goaway_parser* p,
39                                                   uint32_t length,
40                                                   uint8_t flags) {
41   if (length < 8) {
42     char* msg;
43     gpr_asprintf(&msg, "goaway frame too short (%d bytes)", length);
44     grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
45     gpr_free(msg);
46     return err;
47   }
48
49   gpr_free(p->debug_data);
50   p->debug_length = length - 8;
51   p->debug_data = static_cast<char*>(gpr_malloc(p->debug_length));
52   p->debug_pos = 0;
53   p->state = GRPC_CHTTP2_GOAWAY_LSI0;
54   return GRPC_ERROR_NONE;
55 }
56
57 grpc_error* grpc_chttp2_goaway_parser_parse(void* parser,
58                                             grpc_chttp2_transport* t,
59                                             grpc_chttp2_stream* s,
60                                             const grpc_slice& slice,
61                                             int is_last) {
62   const uint8_t* const beg = GRPC_SLICE_START_PTR(slice);
63   const uint8_t* const end = GRPC_SLICE_END_PTR(slice);
64   const uint8_t* cur = beg;
65   grpc_chttp2_goaway_parser* p =
66       static_cast<grpc_chttp2_goaway_parser*>(parser);
67
68   switch (p->state) {
69     case GRPC_CHTTP2_GOAWAY_LSI0:
70       if (cur == end) {
71         p->state = GRPC_CHTTP2_GOAWAY_LSI0;
72         return GRPC_ERROR_NONE;
73       }
74       p->last_stream_id = (static_cast<uint32_t>(*cur)) << 24;
75       ++cur;
76     /* fallthrough */
77     case GRPC_CHTTP2_GOAWAY_LSI1:
78       if (cur == end) {
79         p->state = GRPC_CHTTP2_GOAWAY_LSI1;
80         return GRPC_ERROR_NONE;
81       }
82       p->last_stream_id |= (static_cast<uint32_t>(*cur)) << 16;
83       ++cur;
84     /* fallthrough */
85     case GRPC_CHTTP2_GOAWAY_LSI2:
86       if (cur == end) {
87         p->state = GRPC_CHTTP2_GOAWAY_LSI2;
88         return GRPC_ERROR_NONE;
89       }
90       p->last_stream_id |= (static_cast<uint32_t>(*cur)) << 8;
91       ++cur;
92     /* fallthrough */
93     case GRPC_CHTTP2_GOAWAY_LSI3:
94       if (cur == end) {
95         p->state = GRPC_CHTTP2_GOAWAY_LSI3;
96         return GRPC_ERROR_NONE;
97       }
98       p->last_stream_id |= (static_cast<uint32_t>(*cur));
99       ++cur;
100     /* fallthrough */
101     case GRPC_CHTTP2_GOAWAY_ERR0:
102       if (cur == end) {
103         p->state = GRPC_CHTTP2_GOAWAY_ERR0;
104         return GRPC_ERROR_NONE;
105       }
106       p->error_code = (static_cast<uint32_t>(*cur)) << 24;
107       ++cur;
108     /* fallthrough */
109     case GRPC_CHTTP2_GOAWAY_ERR1:
110       if (cur == end) {
111         p->state = GRPC_CHTTP2_GOAWAY_ERR1;
112         return GRPC_ERROR_NONE;
113       }
114       p->error_code |= (static_cast<uint32_t>(*cur)) << 16;
115       ++cur;
116     /* fallthrough */
117     case GRPC_CHTTP2_GOAWAY_ERR2:
118       if (cur == end) {
119         p->state = GRPC_CHTTP2_GOAWAY_ERR2;
120         return GRPC_ERROR_NONE;
121       }
122       p->error_code |= (static_cast<uint32_t>(*cur)) << 8;
123       ++cur;
124     /* fallthrough */
125     case GRPC_CHTTP2_GOAWAY_ERR3:
126       if (cur == end) {
127         p->state = GRPC_CHTTP2_GOAWAY_ERR3;
128         return GRPC_ERROR_NONE;
129       }
130       p->error_code |= (static_cast<uint32_t>(*cur));
131       ++cur;
132     /* fallthrough */
133     case GRPC_CHTTP2_GOAWAY_DEBUG:
134       if (end != cur)
135         memcpy(p->debug_data + p->debug_pos, cur,
136                static_cast<size_t>(end - cur));
137       GPR_ASSERT((size_t)(end - cur) < UINT32_MAX - p->debug_pos);
138       p->debug_pos += static_cast<uint32_t>(end - cur);
139       p->state = GRPC_CHTTP2_GOAWAY_DEBUG;
140       if (is_last) {
141         grpc_chttp2_add_incoming_goaway(
142             t, p->error_code, p->last_stream_id,
143             grpc_slice_new(p->debug_data, p->debug_length, gpr_free));
144         p->debug_data = nullptr;
145       }
146       return GRPC_ERROR_NONE;
147   }
148   GPR_UNREACHABLE_CODE(
149       return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
150 }
151
152 void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code,
153                                const grpc_slice& debug_data,
154                                grpc_slice_buffer* slice_buffer) {
155   grpc_slice header = GRPC_SLICE_MALLOC(9 + 4 + 4);
156   uint8_t* p = GRPC_SLICE_START_PTR(header);
157   uint32_t frame_length;
158   GPR_ASSERT(GRPC_SLICE_LENGTH(debug_data) < UINT32_MAX - 4 - 4);
159   frame_length = 4 + 4 + static_cast<uint32_t> GRPC_SLICE_LENGTH(debug_data);
160
161   /* frame header: length */
162   *p++ = static_cast<uint8_t>(frame_length >> 16);
163   *p++ = static_cast<uint8_t>(frame_length >> 8);
164   *p++ = static_cast<uint8_t>(frame_length);
165   /* frame header: type */
166   *p++ = GRPC_CHTTP2_FRAME_GOAWAY;
167   /* frame header: flags */
168   *p++ = 0;
169   /* frame header: stream id */
170   *p++ = 0;
171   *p++ = 0;
172   *p++ = 0;
173   *p++ = 0;
174   /* payload: last stream id */
175   *p++ = static_cast<uint8_t>(last_stream_id >> 24);
176   *p++ = static_cast<uint8_t>(last_stream_id >> 16);
177   *p++ = static_cast<uint8_t>(last_stream_id >> 8);
178   *p++ = static_cast<uint8_t>(last_stream_id);
179   /* payload: error code */
180   *p++ = static_cast<uint8_t>(error_code >> 24);
181   *p++ = static_cast<uint8_t>(error_code >> 16);
182   *p++ = static_cast<uint8_t>(error_code >> 8);
183   *p++ = static_cast<uint8_t>(error_code);
184   GPR_ASSERT(p == GRPC_SLICE_END_PTR(header));
185   grpc_slice_buffer_add(slice_buffer, header);
186   grpc_slice_buffer_add(slice_buffer, debug_data);
187 }