Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(connlib): report resource status to client #4931

Merged
merged 19 commits into from May 15, 2024

Conversation

conectado
Copy link
Collaborator

@conectado conectado commented May 9, 2024

This PR introduces site's Status. That's used to report to the client the status, either, unknown, online or offline, mostly as a hint to users as what's wrong with a connection.

This are the criteria for an online or offline resource

  • If all sites related to a resource are offline the resource is considered offline, since there's no gateway that can respond to that resource's connection
  • If any site is online the resource is online, since that same peer can be used to reach that resource
  • Any other case is unknown

Right now resources are single site so it doesn't matter too much but tracking online/offline per-site instead of per-gateway or resource seems like the better long-term solution.

The way to "find out" the site's status is:

  • If a response to a connection details is offline, all sites related to that resource must be offline otherwise there would've been a gateway in the response
  • At the point we connect to a gateway, the site that corresponds to that gateway must be online
  • When a connection to a peer stops it's considered unknown again

Fixes #4738

Copy link

vercel bot commented May 9, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
firezone ⬜️ Ignored (Inspect) Visit Preview May 14, 2024 11:48pm

@github-actions github-actions bot added the kind/feature New feature or request label May 9, 2024
Copy link

github-actions bot commented May 9, 2024

Terraform Cloud Plan Output

Plan: 15 to add, 15 to change, 15 to destroy.

Terraform Cloud Plan

Copy link

github-actions bot commented May 9, 2024

Performance Test Results

TCP

Test Name Received/s Sent/s Retransmits
direct-tcp-client2server 235.0 MiB (-3%) 236.1 MiB (-3%) 392 (+22%)
direct-tcp-server2client 247.1 MiB (+2%) 249.0 MiB (+2%) 98 (+1%)
relayed-tcp-client2server 227.9 MiB (-0%) 228.8 MiB (-1%) 253 (+13%)
relayed-tcp-server2client 196.0 MiB (-17%) 196.9 MiB (-17%) 427 (-13%)

UDP

Test Name Total/s Jitter Lost
direct-udp-client2server 500.0 MiB (-0%) 0.04ms (+76%) 45.03% (+10%)
direct-udp-server2client 500.0 MiB (-0%) 0.02ms (-69%) 21.21% (+8%)
relayed-udp-client2server 499.9 MiB (-0%) 0.03ms (+10%) 55.55% (+1%)
relayed-udp-server2client 500.0 MiB (+0%) 0.03ms (+68%) 40.18% (-5%)

@conectado conectado force-pushed the feat/pass-resource-status-to-client branch from cc817de to 1ddd420 Compare May 10, 2024 04:49
@conectado conectado marked this pull request as ready for review May 14, 2024 01:58
Copy link
Member

@jamilbk jamilbk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't comment on the Rust stuff but the rest LGTM. Do we currently send the Site name in the on_update_resources list as well? If so I can start working on displaying that, along with the Resource offline/online status in #3514

}
}

/// What the GUI clients should paste to the clipboard, e.g. `https://github.com/firezone`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a quick note -- this will be updated to use the address_description in #3514

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 this is just copy-pasted though

Copy link
Member

@thomaseizinger thomaseizinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great PR description, thank you for the summary. Left some comments!

rust/connlib/clients/shared/src/eventloop.rs Outdated Show resolved Hide resolved
rust/connlib/clients/shared/src/messages.rs Outdated Show resolved Hide resolved
rust/connlib/shared/src/callbacks.rs Outdated Show resolved Hide resolved
rust/connlib/shared/src/callbacks.rs Show resolved Hide resolved
rust/connlib/shared/src/proptest.rs Outdated Show resolved Hide resolved
rust/connlib/tunnel/src/client.rs Outdated Show resolved Hide resolved
}
}

fn resources(&self) -> Vec<ResourceDescription> {
self.resource_ids.values().sorted().cloned().collect_vec()
pub(crate) fn resources(&self) -> Vec<callbacks::ResourceDescription> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this creates a weird coupling to the callbacks. What if we just make this a tuple for now instead of duplicating the type?

Long-term, I'd like connlib to have a proper domain model and not (ab)use the DTO types with the portal. The new ResourceDescription is yet another DTO and not a proper domain model.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use a tuple here, it means having to update all clients as part of this PR since it breaks de-serialization and I don't see much benefit of using a tuple here vs adding a field, which is easier to understand the meaning of specially for the de-serializing code.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the resources function is only used after all for the callbacks.

We could also return a tuple here and create the callbacks::ResourceDescription on the top function but that just seems like a bit more convoluted that simply returning the callbacks::ResourceDescription here.

rust/connlib/tunnel/src/client.rs Outdated Show resolved Hide resolved
rust/connlib/tunnel/src/client.rs Outdated Show resolved Hide resolved
rust/connlib/tunnel/src/client.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@ReactorScram ReactorScram left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks okay other than the changes Thomas and I requested. I skimmed through the tests without looking at them in depth.

rust/connlib/tunnel/src/lib.rs Show resolved Hide resolved
fn on_update_resources(&self, resources: Vec<ResourceDescription>) {
tracing::info!(len = resources.len(), "New resource list");
fn on_update_resources(&self, resources: Vec<callbacks::ResourceDescription>) {
tracing::info!(?resources, "New resource list");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't be logged as INFO because it has domain names and IPs and stuff, right? That's why I only had the length before in some places in the Clients.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should have caught these too. We need to keep logs like this to debug because otherwise it'll just consume too much disk space for all users.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it's a bit too often but I don't think there's any sensitive info here. I think it's safe to log users' resources

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be called pretty often now, so I'll leave at debug with only the length, otherwise I think it will be too spammy.

rust/headless-client/src/lib.rs Outdated Show resolved Hide resolved
rust/headless-client/src/lib.rs Outdated Show resolved Hide resolved
rust/connlib/shared/src/callbacks.rs Show resolved Hide resolved
Comment on lines +74 to +93
pub fn name(&self) -> &str {
match self {
ResourceDescription::Dns(r) => &r.name,
ResourceDescription::Cidr(r) => &r.name,
}
}

pub fn status(&self) -> Status {
match self {
ResourceDescription::Dns(r) => r.status,
ResourceDescription::Cidr(r) => r.status,
}
}

pub fn id(&self) -> ResourceId {
match self {
ResourceDescription::Dns(r) => r.id,
ResourceDescription::Cidr(r) => r.id,
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm we can't flip ResourceDescription into a struct that shares these fields, because it would break compatibility with older code, right? Or if this type of ResourceDescription is only used within the Client, between connlib and the GUI, it could be done?

e.g.

struct ResourceDescription {
    id: ResourceId,
    name: String,
    status: Status,
    other: ResourceType,
}

enum ResourceType {
    Cidr,
    Dns,
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

address is also part of a ResourceDescription and it has a different type depending on whether it's DNS or CIDR

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the other ones look like they have the same type, since there's no into

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, but some clients uses the address, maybe we can convert it to a String but I'm not sure having a single type will simplify things, specially since these are used only for serialization and we don't need to access the fields.

rust/connlib/tunnel/src/client.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@ReactorScram ReactorScram left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@conectado conectado added this pull request to the merge queue May 15, 2024
Merged via the queue into main with commit a7d35cd May 15, 2024
135 checks passed
@conectado conectado deleted the feat/pass-resource-status-to-client branch May 15, 2024 15:53
jamilbk pushed a commit that referenced this pull request May 15, 2024
This PR introduces site's `Status`. That's used to report to the client
the status, either, unknown, online or offline, mostly as a hint to
users as what's wrong with a connection.

This are the criteria for an online or offline resource

* If all sites related to a resource are offline the resource is
considered offline, since there's no gateway that can respond to that
resource's connection
* If any site is online the resource is online, since that same peer can
be used to reach that resource
* Any other case is unknown

Right now resources are single site so it doesn't matter too much but
tracking online/offline per-site instead of per-gateway or resource
seems like the better long-term solution.

The way to "find out" the site's status is:

* If a response to a connection details is offline, all sites related to
that resource must be offline otherwise there would've been a gateway in
the response
* At the point we connect to a gateway, the site that corresponds to
that gateway must be online
* When a connection to a peer stops it's considered unknown again

Fixes #4738
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Report "connected to Peer" status for each Gateway
4 participants