| 825 | } |
| 826 | |
| 827 | Http2Error |
| 828 | Http2ConnectionState::rcv_ping_frame(const Http2Frame &frame) |
| 829 | { |
| 830 | uint8_t opaque_data[HTTP2_PING_LEN]; |
| 831 | const Http2StreamId stream_id = frame.header().streamid; |
| 832 | |
| 833 | Http2StreamDebug(this->session, stream_id, "Received PING frame"); |
| 834 | |
| 835 | this->schedule_zombie_event(); |
| 836 | |
| 837 | // If a PING frame is received with a stream identifier field value other |
| 838 | // than 0x0, the recipient MUST respond with a connection error of type |
| 839 | // PROTOCOL_ERROR. |
| 840 | if (stream_id != 0x0) { |
| 841 | return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_PROTOCOL_ERROR, "ping id not 0"); |
| 842 | } |
| 843 | |
| 844 | // Receipt of a PING frame with a length field value other than 8 MUST |
| 845 | // be treated as a connection error (Section 5.4.1) of type FRAME_SIZE_ERROR. |
| 846 | if (frame.header().length != HTTP2_PING_LEN) { |
| 847 | return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_FRAME_SIZE_ERROR, |
| 848 | "ping bad length"); |
| 849 | } |
| 850 | |
| 851 | // Update PING frame count per minute |
| 852 | this->increment_received_ping_frame_count(); |
| 853 | // Close this connection if its ping count received exceeds a limit |
| 854 | if (configured_max_ping_frames_per_minute >= 0 && |
| 855 | this->get_received_ping_frame_count() > static_cast<uint32_t>(configured_max_ping_frames_per_minute)) { |
| 856 | Metrics::Counter::increment(http2_rsb.max_ping_frames_per_minute_exceeded); |
| 857 | Http2StreamDebug(this->session, stream_id, "Observed too frequent PING frames: %u PING frames within a last minute", |
| 858 | this->get_received_ping_frame_count()); |
| 859 | return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_ENHANCE_YOUR_CALM, |
| 860 | "recv ping too frequent PING frame"); |
| 861 | } |
| 862 | |
| 863 | // An endpoint MUST NOT respond to PING frames containing this flag. |
| 864 | if (frame.header().flags & HTTP2_FLAGS_PING_ACK) { |
| 865 | return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_NONE); |
| 866 | } |
| 867 | |
| 868 | frame.reader()->memcpy(opaque_data, HTTP2_PING_LEN, 0); |
| 869 | |
| 870 | // ACK (0x1): An endpoint MUST set this flag in PING responses. |
| 871 | this->send_ping_frame(stream_id, HTTP2_FLAGS_PING_ACK, opaque_data); |
| 872 | |
| 873 | return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_NONE); |
| 874 | } |
| 875 | |
| 876 | Http2Error |
| 877 | Http2ConnectionState::rcv_goaway_frame(const Http2Frame &frame) |
nothing calls this directly
no test coverage detected