Skip to content

Commit 5c865fc

Browse files
authored
Merge pull request #643 from 7flying/re-run-to0-before-expiration
Add an OV re-registration window option when using DB storage
2 parents 165eb26 + 626488d commit 5c865fc

File tree

7 files changed

+273
-8
lines changed

7 files changed

+273
-8
lines changed

HOWTO.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ owner_addresses:
453453
- dns_name: fdo.example.com
454454
- ip_address: 192.168.122.1
455455
report_to_rendezvous_endpoint_enabled: false
456+
ov_registration_period: 600
457+
ov_re_registration_window: 61
456458
bind: 0.0.0.0:8081
457459
service_info_api_url: "http://localhost:8089/device_info"
458460
service_info_api_authentication: None
@@ -512,6 +514,12 @@ Where:
512514
- `port`: connection port.
513515
- `report_to_rendezvous_endpoint_enabled`: whether reporting to the Rendezvous
514516
Server is enabled or not, boolean.
517+
- `ov_registration_period`: optional value that sets how many seconds OVs are
518+
going to be registered into the Rendezvous server.
519+
- `ov_re_registration_window`: optional value that sets the minimum amount of
520+
seconds left in the `ov_registration_period` for the Owner server to trigger
521+
a re-registration within the Rendezvous server. This option can only be used
522+
with database backends.
515523

516524
### `rendezvous-server.yml`
517525

admin-tool/src/aio/configure.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use std::{collections::BTreeMap, net::IpAddr, path::Path};
77

88
use fdo_store::StoreConfig;
99
use fdo_util::servers::configuration::{
10+
owner_onboarding_server::DEFAULT_REGISTRATION_PERIOD,
11+
owner_onboarding_server::DEFAULT_RE_REGISTRATION_WINDOW,
1012
serviceinfo_api_server::ServiceInfoSettings, AbsolutePathBuf, Bind,
1113
};
1214

@@ -46,6 +48,11 @@ pub(super) struct Configuration {
4648
#[clap(long)]
4749
pub manufacturing_use_secp256r1: bool,
4850

51+
#[clap(long)]
52+
ov_registration_period: Option<u32>,
53+
#[clap(long)]
54+
ov_re_registration_window: Option<u32>,
55+
4956
/// The hostname or IP address that clients should use to connect to the AIO components
5057
/// (if not specified, will be all IP addresses of the system).
5158
/// Note that this is not equal to the listen address, as the AIO components will always
@@ -57,6 +64,7 @@ pub(super) struct Configuration {
5764
// and generate the intermediate data
5865
#[clap(skip)]
5966
pub contact_addresses: Vec<ContactAddress>,
67+
6068
#[clap(skip)]
6169
pub serviceinfo_api_auth_token: String,
6270
#[clap(skip)]
@@ -88,6 +96,9 @@ impl Default for Configuration {
8896
manufacturing_disable_key_storage_tpm: true,
8997
manufacturing_use_secp256r1: false,
9098

99+
ov_registration_period: Some(DEFAULT_REGISTRATION_PERIOD),
100+
ov_re_registration_window: Some(DEFAULT_RE_REGISTRATION_WINDOW),
101+
91102
contact_hostname: None,
92103

93104
contact_addresses: vec![],
@@ -339,6 +350,9 @@ fn generate_configs(aio_dir: &Path, config_args: &Configuration) -> Result<(), E
339350
.generate_owner_addresses()
340351
.context("Error generating owner addresses")?,
341352
report_to_rendezvous_endpoint_enabled: true,
353+
354+
ov_registration_period: config_args.ov_registration_period,
355+
ov_re_registration_window: config_args.ov_re_registration_window,
342356
};
343357
write_config(
344358
aio_dir,

owner-onboarding-server/src/main.rs

Lines changed: 135 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,14 @@ use fdo_data_formats::{
2727
publickey::PublicKey,
2828
types::{Guid, TO2AddressEntry},
2929
};
30-
use fdo_store::{Store, StoreError};
30+
31+
use fdo_store::{Store, StoreConfig, StoreError};
3132
use fdo_util::servers::{
32-
configuration::{owner_onboarding_server::OwnerOnboardingServerSettings, AbsolutePathBuf},
33+
configuration::{
34+
owner_onboarding_server::OwnerOnboardingServerSettings,
35+
owner_onboarding_server::DEFAULT_REGISTRATION_PERIOD,
36+
owner_onboarding_server::DEFAULT_RE_REGISTRATION_WINDOW, AbsolutePathBuf,
37+
},
3338
settings_for, OwnershipVoucherStoreMetadataKey,
3439
};
3540

@@ -63,6 +68,13 @@ pub(crate) struct OwnerServiceUD {
6368
service_info_api_client: fdo_http_wrapper::client::JsonClient,
6469

6570
owner_addresses: Vec<TO2AddressEntry>,
71+
72+
// How much time (s) OVs are going to be registered
73+
ov_registration_period: u32,
74+
// The time window (s) within which the re-registration will start
75+
ov_re_registration_window: u32,
76+
77+
window_check_enabled: bool,
6678
}
6779

6880
pub(crate) type OwnerServiceUDT = Arc<OwnerServiceUD>;
@@ -73,7 +85,14 @@ fn load_private_key(path: &AbsolutePathBuf) -> Result<PKey<Private>> {
7385
}
7486

7587
async fn _handle_report_to_rendezvous(udt: &OwnerServiceUDT, ov: &OwnershipVoucher) -> Result<()> {
76-
match report_ov_to_rendezvous(ov, &udt.owner_addresses, &udt.owner_key).await {
88+
match report_ov_to_rendezvous(
89+
ov,
90+
&udt.owner_addresses,
91+
&udt.owner_key,
92+
udt.ov_registration_period,
93+
)
94+
.await
95+
{
7796
Ok(wait_seconds) => {
7897
udt.ownership_voucher_store
7998
.store_metadata(
@@ -138,10 +157,59 @@ async fn report_to_rendezvous(udt: OwnerServiceUDT) -> Result<()> {
138157
Ok(())
139158
}
140159

160+
async fn check_registration_window(udt: &OwnerServiceUDT) -> Result<()> {
161+
let now_plus_window =
162+
time::OffsetDateTime::now_utc().unix_timestamp() + (udt.ov_re_registration_window as i64);
163+
// these are the ovs whose registration time will end and we need to
164+
// re-register them
165+
let ovs = udt
166+
.ownership_voucher_store
167+
.query_ovs_db_to2_performed_to0_less_than(false, now_plus_window)
168+
.await?;
169+
for ov in ovs {
170+
match report_ov_to_rendezvous(
171+
&ov,
172+
&udt.owner_addresses,
173+
&udt.owner_key,
174+
udt.ov_registration_period,
175+
)
176+
.await
177+
{
178+
Ok(wait_seconds) => {
179+
udt.ownership_voucher_store
180+
.store_metadata(
181+
ov.header().guid(),
182+
&fdo_store::MetadataKey::Local(
183+
OwnershipVoucherStoreMetadataKey::To0AcceptOwnerWaitSeconds,
184+
),
185+
&time::Duration::new(wait_seconds.into(), 0),
186+
)
187+
.await?;
188+
if wait_seconds != udt.ov_registration_period {
189+
log::warn!("OV({}): registered by rendezvous for {wait_seconds}s, as opposed to the requested {}s",
190+
ov.header().guid().to_string(), udt.ov_registration_period);
191+
if udt.ov_re_registration_window >= wait_seconds {
192+
log::warn!("OV({}): re-registration won't be triggered (window: {}s, registration: {}s)",
193+
ov.header().guid().to_string(), udt.ov_re_registration_window, udt.ov_registration_period);
194+
}
195+
}
196+
}
197+
Err(e) => {
198+
log::warn!(
199+
"OV({}): failed to report to rendezvous: {e}",
200+
ov.header().guid().to_string()
201+
);
202+
}
203+
}
204+
}
205+
Ok(())
206+
}
207+
141208
async fn report_ov_to_rendezvous(
142209
ov: &OwnershipVoucher,
143210
owner_addresses: &[TO2AddressEntry],
144211
owner_key: &PKey<Private>,
212+
registration_period: u32,
145213
) -> Result<u32> {
146214
let ov_header = ov.header();
147215
if ov_header.protocol_version() != ProtocolVersion::Version1_1 {
@@ -193,8 +261,7 @@ async fn report_ov_to_rendezvous(
193261
};
194262

195263
// Build to0d and to1d
196-
// TODO(runcom): 600 has to come from configuration
197-
let to0d = TO0Data::new(ov.clone(), 600, hello_ack.nonce3().clone())
264+
let to0d = TO0Data::new(ov.clone(), registration_period, hello_ack.nonce3().clone())
198265
.context("Error creating to0d")?;
199266
let to0d_vec = to0d.serialize_data().context("Error serializing TO0Data")?;
200267
let to0d_hash =
@@ -242,14 +309,21 @@ async fn perform_maintenance(udt: OwnerServiceUDT) -> std::result::Result<(), &'
242309
#[allow(unused_must_use)]
243310
let (ov_res, ses_res, rtr_res) = tokio::join!(ov_maint, ses_maint, rtr_maint);
244311

312+
if udt.window_check_enabled {
313+
let window_res = check_registration_window(&udt.clone()).await;
314+
if let Err(e) = window_res {
315+
log::warn!("Error during re-registration window check: {e:?}");
316+
}
317+
}
318+
245319
if let Err(e) = ov_res {
246-
log::warn!("Error during ownership voucher store maintenance: {:?}", e);
320+
log::warn!("Error during ownership voucher store maintenance: {e:?}");
247321
}
248322
if let Err(e) = ses_res {
249-
log::warn!("Error during session store maintenance: {:?}", e);
323+
log::warn!("Error during session store maintenance: {e:?}");
250324
}
251325
if let Err(e) = rtr_res {
252-
log::warn!("Error during report to rendezvous maintenance: {:?}", e)
326+
log::warn!("Error during report to rendezvous maintenance: {e:?}")
253327
}
254328
}
255329
}
@@ -335,6 +409,43 @@ async fn main() -> Result<()> {
335409
.context("Error converting owner public key to PK")?
336410
};
337411

412+
// Voucher registration times
413+
let ov_registration_period = match settings.ov_registration_period {
414+
Some(value) => {
415+
if value == 0 {
416+
bail!("ov_registration_period cannot be 0");
417+
}
418+
value
419+
}
420+
None => {
421+
log::info!(
422+
"Setting a default ov_registration_period of {DEFAULT_REGISTRATION_PERIOD} seconds"
423+
);
424+
DEFAULT_REGISTRATION_PERIOD
425+
}
426+
};
427+
let ov_re_registration_window = match settings.ov_re_registration_window {
428+
Some(value) => {
429+
if value == 0 {
430+
bail!("ov_re_registration_window cannot be 0");
431+
} else if value as u64 <= MAINTENANCE_INTERVAL {
432+
bail!("this server performs checks every {MAINTENANCE_INTERVAL} seconds, please specify an ov_re_registration_window larger than that value");
433+
}
434+
value
435+
}
436+
None => {
437+
log::info!("Setting a default ov_re_registration_window of {DEFAULT_RE_REGISTRATION_WINDOW} seconds");
438+
DEFAULT_RE_REGISTRATION_WINDOW
439+
}
440+
};
441+
442+
if ov_re_registration_window >= ov_registration_period {
443+
bail!(
444+
"ov_re_registration_window ({ov_re_registration_window}) must be smaller than ov_registration_period ({ov_registration_period})");
445+
} else {
446+
log::info!("Server configured with an OV registration period of {ov_registration_period} seconds, OV re-registration window set to {ov_re_registration_window} seconds")
447+
}
448+
338449
// Initialize stores
339450
let ownership_voucher_store = settings
340451
.ownership_voucher_store_driver
@@ -344,6 +455,16 @@ async fn main() -> Result<()> {
344455
.session_store_driver
345456
.initialize()
346457
.context("Error initializing session store")?;
458+
459+
// the re-registration check is only available with DB store drivers
460+
let window_check_enabled = match settings.ownership_voucher_store_driver {
461+
StoreConfig::Directory { path: _ } => {
462+
log::info!("OV re-registration window check disabled, this feature is only available with DB storage drivers");
463+
false
464+
}
465+
_ => true,
466+
};
467+
347468
let session_store = fdo_http_wrapper::server::SessionStore::new(session_store);
348469

349470
// Generate a new Owner2
@@ -387,6 +508,12 @@ async fn main() -> Result<()> {
387508

388509
// Owner addresses
389510
owner_addresses,
511+
512+
// OV registration times
513+
ov_registration_period,
514+
ov_re_registration_window,
515+
516+
window_check_enabled,
390517
});
391518

392519
// Initialize handlers

0 commit comments

Comments
 (0)