| 4584 | } |
| 4585 | |
| 4586 | static win_rendezvous_status_t win_endpoint_refresh_rendezvous( |
| 4587 | const cbm_daemon_ipc_endpoint_t *endpoint) { |
| 4588 | if (!endpoint || !endpoint->user_sid || endpoint->user_sid_length == 0) { |
| 4589 | return WIN_RENDEZVOUS_ERROR; |
| 4590 | } |
| 4591 | cbm_private_lock_directory_t *directory = NULL; |
| 4592 | cbm_private_file_lock_t *record_lock = NULL; |
| 4593 | cbm_private_file_lock_status_t directory_status = |
| 4594 | cbm_daemon_ipc_private_lock_directory_new(endpoint, &directory); |
| 4595 | if (directory_status != CBM_PRIVATE_FILE_LOCK_OK) { |
| 4596 | win_endpoint_generation_invalidate(endpoint); |
| 4597 | return WIN_RENDEZVOUS_ERROR; |
| 4598 | } |
| 4599 | cbm_private_file_lock_status_t lock_status = cbm_private_file_lock_try_acquire( |
| 4600 | directory, CBM_DAEMON_IPC_WINDOWS_RENDEZVOUS_FILE, CBM_PRIVATE_FILE_LOCK_SH, &record_lock); |
| 4601 | if (lock_status != CBM_PRIVATE_FILE_LOCK_OK) { |
| 4602 | win_private_lock_release_complete(&record_lock); |
| 4603 | cbm_private_lock_directory_close(directory); |
| 4604 | win_endpoint_generation_invalidate(endpoint); |
| 4605 | return lock_status == CBM_PRIVATE_FILE_LOCK_BUSY ? WIN_RENDEZVOUS_BUSY |
| 4606 | : WIN_RENDEZVOUS_ERROR; |
| 4607 | } |
| 4608 | |
| 4609 | uint8_t record[CBM_DAEMON_IPC_WINDOWS_RENDEZVOUS_RECORD_SIZE]; |
| 4610 | size_t record_length = 0; |
| 4611 | cbm_private_file_lock_status_t read_status = |
| 4612 | cbm_private_file_lock_payload_read(record_lock, record, sizeof(record), &record_length); |
| 4613 | uint8_t nonce[CBM_DAEMON_IPC_WINDOWS_NONCE_SIZE]; |
| 4614 | char address[CBM_DAEMON_IPC_WINDOWS_NAME_CAP]; |
| 4615 | bool decoded = |
| 4616 | read_status == CBM_PRIVATE_FILE_LOCK_OK && |
| 4617 | cbm_daemon_ipc_windows_rendezvous_record_decode(record, record_length, nonce, address); |
| 4618 | char expected[CBM_DAEMON_IPC_WINDOWS_NAME_CAP]; |
| 4619 | bool bound = |
| 4620 | decoded && |
| 4621 | cbm_daemon_ipc_windows_generation_address(endpoint->user_sid, endpoint->user_sid_length, |
| 4622 | endpoint->instance_key, nonce, expected) && |
| 4623 | strcmp(expected, address) == 0; |
| 4624 | win_rendezvous_status_t result; |
| 4625 | if (read_status != CBM_PRIVATE_FILE_LOCK_OK) { |
| 4626 | win_endpoint_generation_invalidate(endpoint); |
| 4627 | result = WIN_RENDEZVOUS_ERROR; |
| 4628 | } else if (record_length == 0) { |
| 4629 | win_endpoint_generation_invalidate(endpoint); |
| 4630 | result = WIN_RENDEZVOUS_ABSENT; |
| 4631 | } else if (!bound) { |
| 4632 | win_endpoint_generation_invalidate(endpoint); |
| 4633 | result = WIN_RENDEZVOUS_CORRUPT; |
| 4634 | } else if (!win_endpoint_generation_install(endpoint, address)) { |
| 4635 | win_endpoint_generation_invalidate(endpoint); |
| 4636 | result = WIN_RENDEZVOUS_ERROR; |
| 4637 | } else { |
| 4638 | result = WIN_RENDEZVOUS_VALID; |
| 4639 | } |
| 4640 | /* Keep the record lock through the in-memory snapshot update. Otherwise |
| 4641 | * a reader of generation N could install/invalidate after a startup owner |
| 4642 | * has published generation N+1, regressing this endpoint to stale state. */ |
| 4643 | win_private_lock_release_complete(&record_lock); |
no test coverage detected