connlib: add arch and kernel version to user agent (#2987)

Fixes #2470, now for linux it looks like:

```
Alpine Linux/3.19.0 (x86_64;5.15.133.1-microsoft-standard-WSL2;) connlib/1.0.0 
```

For macos it looks like:

```
Mac OS/13.4.1 (arm64;22.5.0;) connlib/1.0.0
```

and this is how it looks on android:

```
Android/Unknown 6.1.23-android14-4-00257-g7e35917775b8-ab9964412 connlib/1.0.0
```

note: seems like in android emulator at least we can't get the
architecture so easily
This commit is contained in:
Gabi
2023-12-22 00:03:08 -03:00
committed by GitHub
parent d624031d9f
commit eed9608dd0
2 changed files with 60 additions and 1 deletions

View File

@@ -76,12 +76,70 @@ pub enum Mode {
}
pub fn get_user_agent() -> String {
// Note: we could switch to sys-info and get the hostname
// but we lose the arch
// and neither of the libraries provide the kernel version.
// so I rather keep os_info which seems like the most popular
// and keep implementing things that we are missing on top
let info = os_info::get();
let os_type = info.os_type();
let os_version = info.version();
let additional_info = additional_info();
let lib_version = VERSION;
let lib_name = LIB_NAME;
format!("{os_type}/{os_version} {lib_name}/{lib_version}")
format!("{os_type}/{os_version}{additional_info}{lib_name}/{lib_version}")
}
fn additional_info() -> String {
let info = os_info::get();
match (info.architecture(), kernel_version()) {
(None, None) => " ".to_string(),
(None, Some(k)) => format!(" {k} "),
(Some(a), None) => format!(" {a} "),
(Some(a), Some(k)) => format!(" ({a};{k};) "),
}
}
#[cfg(not(target_family = "unix"))]
fn kernel_version() -> Option<String> {
None
}
#[cfg(target_family = "unix")]
fn kernel_version() -> Option<String> {
#[cfg(any(target_os = "android", target_os = "linux"))]
let mut utsname = libc::utsname {
sysname: [0; 65],
nodename: [0; 65],
release: [0; 65],
version: [0; 65],
machine: [0; 65],
domainname: [0; 65],
};
#[cfg(any(target_os = "macos", target_os = "ios"))]
let mut utsname = libc::utsname {
sysname: [0; 256],
nodename: [0; 256],
release: [0; 256],
version: [0; 256],
machine: [0; 256],
};
// SAFETY: we just allocated the pointer
if unsafe { libc::uname(&mut utsname as *mut _) } != 0 {
return None;
}
let version: Vec<u8> = utsname
.release
.split(|c| *c == 0)
.next()?
.iter()
.map(|x| *x as u8)
.collect();
String::from_utf8(version).ok()
}
#[cfg(not(target_os = "windows"))]

View File

@@ -260,6 +260,7 @@ where
// We should never get a domain_response for a CIDR resource!
return Err(Error::ControlProtocolError);
};
let resource_description =
DnsResource::from_description(&resource_description, domain_response.domain.clone());