00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "P_Net.h"
00025 #include "Http2ConnectionState.h"
00026 #include "Http2ClientSession.h"
00027
00028 #define DebugHttp2Ssn(fmt, ...) \
00029 DebugSsn("http2_cs", "[%" PRId64 "] " fmt, this->con_id, __VA_ARGS__)
00030
00031 typedef Http2ErrorCode (*http2_frame_dispatch)(Http2ClientSession&, Http2ConnectionState&, const Http2Frame&);
00032
00033 static Http2ErrorCode
00034 rcv_settings_frame(Http2ClientSession& cs, Http2ConnectionState& cstate, const Http2Frame& frame)
00035 {
00036 Http2SettingsParameter param;
00037 char buf[HTTP2_SETTINGS_PARAMETER_LEN];
00038 unsigned nbytes = 0;
00039 char * end;
00040
00041
00042 if (frame.header().streamid != 0) {
00043 return HTTP2_ERROR_PROTOCOL_ERROR;
00044 }
00045
00046
00047
00048
00049 if (frame.header().flags & HTTP2_FLAGS_SETTINGS_ACK) {
00050 return frame.header().length == 0 ? HTTP2_ERROR_NO_ERROR : HTTP2_ERROR_FRAME_SIZE_ERROR;
00051 }
00052
00053 while (nbytes < frame.header().length) {
00054 end = frame.reader()->memcpy(buf, sizeof(buf), nbytes);
00055 nbytes += (end - buf);
00056
00057 if (!http2_parse_settings_parameter(make_iovec(buf, end - buf), param)) {
00058 return HTTP2_ERROR_PROTOCOL_ERROR;
00059 }
00060
00061 if (!http2_settings_parameter_is_valid(param)) {
00062 return param.id == HTTP2_SETTINGS_INITIAL_WINDOW_SIZE
00063 ? HTTP2_ERROR_FLOW_CONTROL_ERROR : HTTP2_ERROR_PROTOCOL_ERROR;
00064 }
00065
00066 DebugSsn(&cs, "http2_cs", "[%" PRId64 "] setting param=%d value=%u",
00067 cs.connection_id(), param.id, param.value);
00068
00069 cstate.client_settings.set((Http2SettingsIdentifier)param.id, param.value);
00070 }
00071
00072 return HTTP2_ERROR_NO_ERROR;
00073 }
00074
00075 static const int buffer_size_index[HTTP2_FRAME_TYPE_MAX] =
00076 {
00077 -1,
00078 -1,
00079 -1,
00080 -1,
00081 -1,
00082 -1,
00083 -1,
00084 BUFFER_SIZE_INDEX_128,
00085 -1,
00086 -1,
00087 -1,
00088 -1,
00089 };
00090
00091 static const http2_frame_dispatch frame_handlers[HTTP2_FRAME_TYPE_MAX] =
00092 {
00093 NULL,
00094 NULL,
00095 NULL,
00096 NULL,
00097 rcv_settings_frame,
00098 NULL,
00099 NULL,
00100 NULL,
00101 NULL,
00102 NULL,
00103 NULL,
00104 NULL,
00105 };
00106
00107 int
00108 Http2ConnectionState::main_event_handler(int event, void * edata)
00109 {
00110 if (event == HTTP2_SESSION_EVENT_INIT) {
00111 ink_assert(this->ua_session == NULL);
00112 this->ua_session = (Http2ClientSession *)edata;
00113
00114 return 0;
00115 }
00116
00117 if (event == HTTP2_SESSION_EVENT_FINI) {
00118 this->ua_session = NULL;
00119 SET_HANDLER(&Http2ConnectionState::state_closed);
00120 return 0;
00121 }
00122
00123 if (event == HTTP2_SESSION_EVENT_RECV) {
00124 Http2Frame * frame = (Http2Frame *)edata;
00125 Http2ErrorCode error;
00126
00127
00128 ink_assert(frame->header().type < countof(frame_handlers));
00129
00130 if (frame_handlers[frame->header().type]) {
00131 error = frame_handlers[frame->header().type](*this->ua_session, *this, *frame);
00132 } else {
00133 error = HTTP2_ERROR_INTERNAL_ERROR;
00134 }
00135
00136 if (error != HTTP2_ERROR_NO_ERROR) {
00137 Http2Frame frame(HTTP2_FRAME_TYPE_GOAWAY, 0, 0);
00138 Http2Goaway goaway;
00139
00140 goaway.last_streamid = 0;
00141 goaway.error_code = error;
00142
00143 frame.alloc(buffer_size_index[HTTP2_FRAME_TYPE_GOAWAY]);
00144 http2_write_goaway(goaway, frame.write());
00145 frame.finalize(HTTP2_GOAWAY_LEN);
00146
00147 this->ua_session->handleEvent(HTTP2_SESSION_EVENT_XMIT, &frame);
00148 eventProcessor.schedule_imm(this->ua_session, ET_NET, VC_EVENT_ERROR);
00149
00150
00151
00152
00153
00154 SET_HANDLER(&Http2ConnectionState::state_closed);
00155 }
00156
00157 return 0;
00158 }
00159
00160 return 0;
00161 }
00162
00163 int
00164 Http2ConnectionState::state_closed(int , void * )
00165 {
00166 return 0;
00167 }