| 786 | } |
| 787 | |
| 788 | static apr_status_t h2_session_shutdown(h2_session *session, int error, |
| 789 | const char *msg, int force_close) |
| 790 | { |
| 791 | apr_status_t status = APR_SUCCESS; |
| 792 | |
| 793 | ap_assert(session); |
| 794 | if (session->local.shutdown) { |
| 795 | return APR_SUCCESS; |
| 796 | } |
| 797 | |
| 798 | if (error && !msg) { |
| 799 | if (APR_STATUS_IS_EPIPE(error)) { |
| 800 | msg = "remote close"; |
| 801 | } |
| 802 | } |
| 803 | |
| 804 | if (error || force_close) { |
| 805 | /* not a graceful shutdown, we want to leave... |
| 806 | * Do not start further streams that are waiting to be scheduled. |
| 807 | * Find out the max stream id that we habe been processed or |
| 808 | * are still actively working on. |
| 809 | * Remove all streams greater than this number without submitting |
| 810 | * a RST_STREAM frame, since that should be clear from the GOAWAY |
| 811 | * we send. */ |
| 812 | session->local.accepted_max = h2_mplx_c1_shutdown(session->mplx); |
| 813 | session->local.error = error; |
| 814 | session->local.error_msg = msg; |
| 815 | } |
| 816 | else { |
| 817 | /* graceful shutdown. we will continue processing all streams |
| 818 | * we have, but no longer accept new ones. Report the max stream |
| 819 | * we have received and discard all new ones. */ |
| 820 | } |
| 821 | |
| 822 | session->local.accepting = 0; |
| 823 | session->local.shutdown = 1; |
| 824 | if (!session->c1->aborted) { |
| 825 | nghttp2_submit_goaway(session->ngh2, NGHTTP2_FLAG_NONE, |
| 826 | session->local.accepted_max, |
| 827 | error, (uint8_t*)msg, msg? strlen(msg):0); |
| 828 | status = nghttp2_session_send(session->ngh2); |
| 829 | if (status == APR_SUCCESS) { |
| 830 | status = h2_c1_io_assure_flushed(&session->io); |
| 831 | } |
| 832 | ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c1, |
| 833 | H2_SSSN_LOG(APLOGNO(03069), session, |
| 834 | "sent GOAWAY, err=%d, msg=%s"), error, msg? msg : ""); |
| 835 | } |
| 836 | h2_session_dispatch_event(session, H2_SESSION_EV_LOCAL_GOAWAY, error, msg); |
| 837 | return status; |
| 838 | } |
| 839 | |
| 840 | static apr_status_t session_cleanup(h2_session *session, const char *trigger) |
| 841 | { |
no test coverage detected