Skip to content

Commit

Permalink
Add a vsock server/client example of interaction with C lib #27
Browse files Browse the repository at this point in the history
build.rs is added to rust-vsock-payload to set location and name of
the C static library. Method to set these information is added to
vsock readme.md.

In vsock_c_lib/main.c, socket interfaces provided by rust is called
to implement a server and a client.

In main.rs of rust-vsock-payload, these two functions implemented by
C lib is called for a test.

Signed-off-by: Jiaqi Gao <[email protected]>
  • Loading branch information
gaojiaqi7 authored and jyao1 committed Sep 12, 2021
1 parent fd25fcb commit 5cf7e8a
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 5 deletions.
8 changes: 8 additions & 0 deletions rust-vsock-payload/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use std::env;

fn main() {
let out_dir = env::var("RUST_LINK_C_LIB_DIR").unwrap();
let lib_name = env::var("RUST_LINK_C_LIB_NAME").unwrap();
println!("cargo:rustc-link-search=native={}", out_dir);
println!("cargo:rustc-link-lib=static={}", lib_name);
}
6 changes: 6 additions & 0 deletions rust-vsock-payload/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ export RUST_IPL_BIN=$BASE_DIR/target/x86_64-unknown-uefi/release/rust_ipl.efi
export RUST_PAYLOAD_BIN=$BASE_DIR/target/x86_64-unknown-uefi/release/rust-vsock-payload.efi
export RUST_FIRMWARE_BIN=$BASE_DIR/target/x86_64-unknown-uefi/release/final_vsock.bin
```
To link a static C library, set the folder and name of lib to the environment variable:

```bash
export RUST_LINK_C_LIB_DIR=$BASE_DIR/rust-vsock-payload/
export RUST_LINK_C_LIB_NAME=main.a
```

To build default PE format OBJ and link with a static C library:

Expand Down
24 changes: 19 additions & 5 deletions rust-vsock-payload/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ mod vsock_impl;

mod client;
mod server;
mod vsock_lib;

#[link(name = "main")]
extern "C" {
fn server_entry() -> i32;
fn client_entry() -> i32;
}

#[no_mangle]
#[cfg_attr(target_os = "uefi", export_name = "efi_main")]
Expand Down Expand Up @@ -45,17 +52,24 @@ pub extern "win64" fn _start(hob_list: *const u8, _reserved_param: usize) -> ! {

vsock_impl::init_vsock_device();

client::test_client();
server::test_server();
// client::test_client();
let mut result;
unsafe {
result = client_entry();
}
log::debug!("Client example done: {}\n", result);

// server::test_server();
unsafe {
result = server_entry();
}

log::debug!("Example done\n");
log::debug!("Server Example done: {}\n", result);
loop {}
}

#[cfg(target_os = "uefi")]
use core::panic::PanicInfo;

#[cfg(target_os = "uefi")]
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
rust_ipl_log::write_log(
Expand Down
96 changes: 96 additions & 0 deletions rust-vsock-payload/vsock_c_lib/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//
// Copyright (c) 2021 Intel Corporation
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// This example does the same work as rust-vsock-payload/src/server.rs
//

#include <sys/types.h>

typedef unsigned int socklen_t;

struct sockaddr {
unsigned short svm_family;
unsigned short svm_reserved1;
unsigned int svm_port;
unsigned int svm_cid;
unsigned char svm_flags;
unsigned char svm_zero[3];
};

extern int socket (int family, int type, int protocol);
extern int bind (int sockfd, const struct sockaddr *addr,socklen_t addrlen);
extern int listen (int sockfd, int backlog);
extern int accept (int sockfd, struct sockaddr *addr, socklen_t *addrlen);
extern ssize_t recv (int sockfd, void *buf, size_t len, int flags);
extern int connect (int sockfd, const struct sockaddr *addr,socklen_t addrlen);
extern ssize_t send (int sockfd, void *buf, size_t len, int flags);
extern int shutdown (int fd, int how);

#define RECV_BUF_LEN 1024

int server_entry () {
int sockfd;
unsigned char buf[1024];
struct sockaddr bindAddr;
socklen_t bindAddrLen;
struct sockaddr acceptAddr;
socklen_t acceptAddrLen;

bindAddr.svm_port = 1234;
bindAddr.svm_cid = 33;
bindAddrLen = 11;

sockfd = socket (0, 0, 0);

if (bind (sockfd, &bindAddr, bindAddrLen)) {
return -1;
}

if (listen (sockfd, 1)) {
return -1;
}

if (accept (sockfd, &acceptAddr, &acceptAddrLen)) {
return -1;
}

while (1) {
if (!recv (sockfd, buf, 1024, 0)) {
break;
}
}

if (shutdown (sockfd, 0)) {
return -1;
}
return 0;
}



int client_entry () {
int sockfd;
struct sockaddr serverAddr;
socklen_t serverAddrLen;

sockfd = socket (0, 0, 0);

serverAddr.svm_port = 1234;
serverAddr.svm_cid = 2;
serverAddrLen = 11;

if (connect (sockfd, &serverAddr, serverAddrLen)) {
return -1;
}

if (send (sockfd, "hello", 5, 0)) {
return -1;
}

if (shutdown (sockfd, 0)) {
return -1;
}
return 0;
}

0 comments on commit 5cf7e8a

Please sign in to comment.