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 }