| 386 | } |
| 387 | |
| 388 | apr_status_t md_ocsp_get_status(md_ocsp_copy_der *cb, void *userdata, md_ocsp_reg_t *reg, |
| 389 | const char *ext_id, apr_size_t ext_id_len, |
| 390 | apr_pool_t *p, const md_t *md) |
| 391 | { |
| 392 | md_ocsp_status_t *ostat; |
| 393 | const char *name; |
| 394 | apr_status_t rv = APR_SUCCESS; |
| 395 | md_ocsp_id_map_t *id_map; |
| 396 | const char *id; |
| 397 | apr_size_t id_len; |
| 398 | int locked = 0; |
| 399 | |
| 400 | (void)p; |
| 401 | (void)md; |
| 402 | name = md? md->name : MD_OTHER; |
| 403 | md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, reg->p, |
| 404 | "md[%s]: OCSP, get_status", name); |
| 405 | |
| 406 | id_map = apr_hash_get(reg->id_by_external_id, ext_id, (apr_ssize_t)ext_id_len); |
| 407 | id = id_map? id_map->id.data : ext_id; |
| 408 | id_len = id_map? id_map->id.len : ext_id_len; |
| 409 | ostat = apr_hash_get(reg->ostat_by_id, id, (apr_ssize_t)id_len); |
| 410 | if (!ostat) { |
| 411 | rv = APR_ENOENT; |
| 412 | goto cleanup; |
| 413 | } |
| 414 | |
| 415 | /* While the ostat instance itself always exists, the response data it holds |
| 416 | * may vary over time and we need locked access to make a copy. */ |
| 417 | apr_thread_mutex_lock(reg->mutex); |
| 418 | locked = 1; |
| 419 | |
| 420 | if (ostat->resp_der.len <= 0) { |
| 421 | /* No response known, check store for new response. */ |
| 422 | ocsp_status_refresh(ostat, p); |
| 423 | if (ostat->resp_der.len <= 0) { |
| 424 | md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, reg->p, |
| 425 | "md[%s]: OCSP, no response available", name); |
| 426 | cb(NULL, 0, userdata); |
| 427 | goto cleanup; |
| 428 | } |
| 429 | } |
| 430 | /* We have a response */ |
| 431 | if (ostat_should_renew(ostat)) { |
| 432 | /* But it is up for renewal. A watchdog should be busy with |
| 433 | * retrieving a new one. In case of outages, this might take |
| 434 | * a while, however. Pace the frequency of checks with the |
| 435 | * urgency of a new response based on the remaining time. */ |
| 436 | long secs = (long)apr_time_sec(md_timeperiod_remaining(&ostat->resp_valid, apr_time_now())); |
| 437 | apr_time_t waiting_time; |
| 438 | |
| 439 | /* every hour, every minute, every second */ |
| 440 | waiting_time = ((secs >= MD_SECS_PER_DAY)? |
| 441 | apr_time_from_sec(60 * 60) : ((secs >= 60)? |
| 442 | apr_time_from_sec(60) : apr_time_from_sec(1))); |
| 443 | if ((apr_time_now() - ostat->resp_last_check) >= waiting_time) { |
| 444 | ostat->resp_last_check = apr_time_now(); |
| 445 | ocsp_status_refresh(ostat, p); |
no test coverage detected