void TransportLayerDtls::Handshake() { // Clear the retransmit timer timer_->Cancel(); SECStatus rv = SSL_ForceHandshake(ssl_fd_); if (rv == SECSuccess) { MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "****** SSL handshake completed ******"); if (!cert_ok_) { MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Certificate check never occurred"); TL_SET_STATE(TS_ERROR); return; } if (!CheckAlpn()) { // Despite connecting, the connection doesn't have a valid ALPN label. // Forcibly close the connection so that the peer isn't left hanging // (assuming the close_notify isn't dropped). ssl_fd_ = nullptr; TL_SET_STATE(TS_ERROR); return; } TL_SET_STATE(TS_OPEN); } else { int32_t err = PR_GetError(); switch(err) { case SSL_ERROR_RX_MALFORMED_HANDSHAKE: MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Malformed DTLS message; ignoring"); // If this were TLS (and not DTLS), this would be fatal, but // here we're required to ignore bad messages, so fall through MOZ_FALLTHROUGH; case PR_WOULD_BLOCK_ERROR: MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "Handshake would have blocked"); PRIntervalTime timeout; rv = DTLS_GetHandshakeTimeout(ssl_fd_, &timeout); if (rv == SECSuccess) { uint32_t timeout_ms = PR_IntervalToMilliseconds(timeout); MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Setting DTLS timeout to " << timeout_ms); timer_->SetTarget(target_); timer_->InitWithFuncCallback(TimerCallback, this, timeout_ms, nsITimer::TYPE_ONE_SHOT); } break; default: MOZ_MTLOG(ML_ERROR, LAYER_INFO << "SSL handshake error "<< err); TL_SET_STATE(TS_ERROR); break; } } }
void TransportLayerDtls::Handshake() { SetState(TS_CONNECTING); // Clear the retransmit timer timer_->Cancel(); SECStatus rv = SSL_ForceHandshake(ssl_fd_); if (rv == SECSuccess) { MOZ_MTLOG(PR_LOG_NOTICE, LAYER_INFO << "****** SSL handshake completed ******"); if (!cert_ok_) { MOZ_MTLOG(PR_LOG_ERROR, LAYER_INFO << "Certificate check never occurred"); SetState(TS_ERROR); return; } SetState(TS_OPEN); } else { int32_t err = PR_GetError(); switch(err) { case SSL_ERROR_RX_MALFORMED_HANDSHAKE: if (mode_ != DGRAM) { MOZ_MTLOG(PR_LOG_ERROR, LAYER_INFO << "Malformed TLS message"); SetState(TS_ERROR); } else { MOZ_MTLOG(PR_LOG_ERROR, LAYER_INFO << "Malformed DTLS message; ignoring"); } // Fall through case PR_WOULD_BLOCK_ERROR: MOZ_MTLOG(PR_LOG_NOTICE, LAYER_INFO << "Would have blocked"); if (mode_ == DGRAM) { PRIntervalTime timeout; rv = DTLS_GetHandshakeTimeout(ssl_fd_, &timeout); if (rv == SECSuccess) { uint32_t timeout_ms = PR_IntervalToMilliseconds(timeout); MOZ_MTLOG(PR_LOG_DEBUG, LAYER_INFO << "Setting DTLS timeout to " << timeout_ms); timer_->SetTarget(target_); timer_->InitWithFuncCallback(TimerCallback, this, timeout_ms, nsITimer::TYPE_ONE_SHOT); } } break; default: MOZ_MTLOG(PR_LOG_ERROR, LAYER_INFO << "SSL handshake error "<< err); SetState(TS_ERROR); break; } } }