/* Checks whether the received packet contains a handshake * packet with sequence higher that the previously received. * It must be called only when an actual packet has been * received. * * Returns: 0 if expected, negative value otherwise. */ static int is_next_hpacket_expected(gnutls_session_t session) { int ret; /* htype is arbitrary */ ret = _gnutls_recv_in_buffers(session, GNUTLS_HANDSHAKE, GNUTLS_HANDSHAKE_FINISHED, 0); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_parse_record_buffered_msgs(session); if (ret < 0) return gnutls_assert_val(ret); if (session->internals.handshake_recv_buffer_size > 0) return 0; else return gnutls_assert_val(GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET); }
/* This is a receive function for the gnutls handshake * protocol. Makes sure that we have received all data. */ ssize_t _gnutls_handshake_io_recv_int(gnutls_session_t session, gnutls_handshake_description_t htype, handshake_buffer_st * hsk, unsigned int optional) { int ret; unsigned int tleft = 0; int retries = 7; ret = get_last_packet(session, htype, hsk, optional); if (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE && ret != GNUTLS_E_INT_CHECK_AGAIN) { return gnutls_assert_val(ret); } /* try using the already existing records before * trying to receive. */ ret = _gnutls_parse_record_buffered_msgs(session); if (ret == 0) { ret = get_last_packet(session, htype, hsk, optional); } if (IS_DTLS(session)) { if (ret >= 0) return ret; } else { if ((ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE && ret < 0) || ret >= 0) return gnutls_assert_val(ret); } if (htype != (gnutls_handshake_description_t) -1) { ret = handshake_remaining_time(session); if (ret < 0) return gnutls_assert_val(ret); tleft = ret; } do { /* if we don't have a complete message waiting for us, try * receiving more */ ret = _gnutls_recv_in_buffers(session, GNUTLS_HANDSHAKE, htype, tleft); if (ret < 0) return gnutls_assert_val_fatal(ret); ret = _gnutls_parse_record_buffered_msgs(session); if (ret == 0) { ret = get_last_packet(session, htype, hsk, optional); } /* we put an upper limit (retries) to the number of partial handshake * messages in a record packet. */ } while(IS_DTLS(session) && ret == GNUTLS_E_INT_CHECK_AGAIN && retries-- > 0); if (unlikely(IS_DTLS(session) && ret == GNUTLS_E_INT_CHECK_AGAIN)) { ret = gnutls_assert_val(GNUTLS_E_TOO_MANY_HANDSHAKE_PACKETS); } return ret; }