Skip to content

Commit 20a6b47

Browse files
authored
Merge pull request #267 from quanweiZhou/fix-parse-vsock-address
vsock: parse cid from vsock
2 parents 7943e3e + 02e02b5 commit 20a6b47

File tree

4 files changed

+59
-24
lines changed

4 files changed

+59
-24
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ windows-sys = {version = "0.48", features = [ "Win32_Foundation", "Win32_Storage
3030
tokio-vsock = { version = "0.4.0", optional = true }
3131

3232
[build-dependencies]
33+
# lock home to avoid conflict with latest version
34+
home = "=0.5.9"
3335
protobuf-codegen = "3.1.0"
3436

3537
[features]

compiler/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ homepage = "https://github.com/containerd/ttrpc-rust/tree/master/compiler"
1212
readme = "README.md"
1313

1414
[dependencies]
15+
# lock home to avoid conflict with latest version
16+
home = "=0.5.9"
1517
protobuf = "2.27.1"
1618
protobuf-codegen = "2.27.1"
1719
prost = "0.8"

src/common.rs

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,40 @@ fn make_addr(_domain: Domain, sockaddr: &str) -> Result<UnixAddr> {
101101
UnixAddr::new(sockaddr).map_err(err_to_others_err!(e, ""))
102102
}
103103

104-
fn make_socket(addr: (&str, u32)) -> Result<(RawFd, Domain, Box<dyn SockaddrLike>)> {
105-
let (sockaddr, _) = addr;
104+
// addr: cid:port
105+
// return (cid, port)
106+
#[cfg(any(target_os = "linux", target_os = "android"))]
107+
fn parse_vscok(addr: &str) -> Result<(u32, u32)> {
108+
// vsock://cid:port
109+
let sockaddr_port_v: Vec<&str> = addr.split(':').collect();
110+
if sockaddr_port_v.len() != 2 {
111+
return Err(Error::Others(format!(
112+
"sockaddr {addr} is not right for vsock"
113+
)));
114+
}
115+
116+
// for -1 need trace to libc::VMADDR_CID_ANY
117+
let cid: u32 = if sockaddr_port_v[0].trim().eq("-1") {
118+
libc::VMADDR_CID_ANY
119+
} else {
120+
sockaddr_port_v[0].parse().map_err(|e| {
121+
Error::Others(format!(
122+
"failed to parse cid from {:?} error: {:?}",
123+
sockaddr_port_v[0], e
124+
))
125+
})?
126+
};
127+
128+
let port: u32 = sockaddr_port_v[1].parse().map_err(|e| {
129+
Error::Others(format!(
130+
"failed to parse port from {:?} error: {:?}",
131+
sockaddr_port_v[1], e
132+
))
133+
})?;
134+
Ok((cid, port))
135+
}
136+
137+
fn make_socket(sockaddr: &str) -> Result<(RawFd, Domain, Box<dyn SockaddrLike>)> {
106138
let (domain, sockaddrv) = parse_sockaddr(sockaddr)?;
107139

108140
let get_sock_addr = |domain, sockaddr| -> Result<(RawFd, Box<dyn SockaddrLike>)> {
@@ -121,23 +153,14 @@ fn make_socket(addr: (&str, u32)) -> Result<(RawFd, Domain, Box<dyn SockaddrLike
121153
Domain::Unix => get_sock_addr(domain, sockaddrv)?,
122154
#[cfg(any(target_os = "linux", target_os = "android"))]
123155
Domain::Vsock => {
124-
let sockaddr_port_v: Vec<&str> = sockaddrv.split(':').collect();
125-
if sockaddr_port_v.len() != 2 {
126-
return Err(Error::Others(format!(
127-
"sockaddr {sockaddr} is not right for vsock"
128-
)));
129-
}
130-
let port: u32 = sockaddr_port_v[1]
131-
.parse()
132-
.expect("the vsock port is not an number");
156+
let (cid, port) = parse_vscok(sockaddrv)?;
133157
let fd = socket(
134158
AddressFamily::Vsock,
135159
SockType::Stream,
136160
SockFlag::SOCK_CLOEXEC,
137161
None,
138162
)
139163
.map_err(|e| Error::Socket(e.to_string()))?;
140-
let cid = addr.1;
141164
let sockaddr = VsockAddr::new(cid, port);
142165
(fd, Box::new(sockaddr))
143166
}
@@ -146,18 +169,8 @@ fn make_socket(addr: (&str, u32)) -> Result<(RawFd, Domain, Box<dyn SockaddrLike
146169
Ok((fd, domain, sockaddr))
147170
}
148171

149-
// Vsock is not supported on non Linux.
150-
#[cfg(any(target_os = "linux", target_os = "android"))]
151-
use libc::VMADDR_CID_ANY;
152-
#[cfg(not(any(target_os = "linux", target_os = "android")))]
153-
const VMADDR_CID_ANY: u32 = 0;
154-
#[cfg(any(target_os = "linux", target_os = "android"))]
155-
use libc::VMADDR_CID_HOST;
156-
#[cfg(not(any(target_os = "linux", target_os = "android")))]
157-
const VMADDR_CID_HOST: u32 = 0;
158-
159172
pub(crate) fn do_bind(sockaddr: &str) -> Result<(RawFd, Domain)> {
160-
let (fd, domain, sockaddr) = make_socket((sockaddr, VMADDR_CID_ANY))?;
173+
let (fd, domain, sockaddr) = make_socket(sockaddr)?;
161174

162175
setsockopt(fd, sockopt::ReusePort, &true)?;
163176
bind(fd, sockaddr.as_ref()).map_err(err_to_others_err!(e, ""))?;
@@ -167,7 +180,7 @@ pub(crate) fn do_bind(sockaddr: &str) -> Result<(RawFd, Domain)> {
167180

168181
/// Creates a unix socket for client.
169182
pub(crate) unsafe fn client_connect(sockaddr: &str) -> Result<RawFd> {
170-
let (fd, _, sockaddr) = make_socket((sockaddr, VMADDR_CID_HOST))?;
183+
let (fd, _, sockaddr) = make_socket(sockaddr)?;
171184

172185
connect(fd, sockaddr.as_ref())?;
173186

@@ -236,4 +249,20 @@ mod tests {
236249
}
237250
}
238251
}
252+
#[cfg(any(target_os = "linux", target_os = "android"))]
253+
#[test]
254+
fn test_parse_vscok() {
255+
for i in &[
256+
("-1:1024", (libc::VMADDR_CID_ANY, 1024)),
257+
("0:1", (0, 1)),
258+
("1:2", (1, 2)),
259+
("4294967294:3", (4294967294, 3)),
260+
// 4294967295 = 0xFFFFFFFF
261+
("4294967295:4", (libc::VMADDR_CID_ANY, 4)),
262+
] {
263+
let (input, (cid, port)) = (i.0, i.1);
264+
let r = parse_vscok(input);
265+
assert_eq!(r.unwrap(), (cid, port), "parse {:?} failed", i);
266+
}
267+
}
239268
}

ttrpc-codegen/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ readme = "README.md"
1313

1414

1515
[dependencies]
16+
# lock home to avoid conflict with latest version
17+
home = "=0.5.9"
1618
protobuf-support = "3.2.0"
1719
protobuf = { version = "2.27.1" }
1820
protobuf-codegen = "3.2.0"

0 commit comments

Comments
 (0)