Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions libcc2rs/src/libc_shims/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,3 +378,104 @@ impl Sockaddr {
out_len.write(ss.len());
}
}

pub fn setsockopt_refcount(fd: i32, level: i32, optname: i32, optval: crate::AnyPtr) -> i32 {
let res = match (level, optname) {
(::libc::IPPROTO_TCP, ::libc::TCP_NODELAY) => {
let v = optval.reinterpret_cast::<i32>().read() != 0;
crate::FdRegistry::with_fd(fd, |borrowed| {
nix::sys::socket::setsockopt(&borrowed, nix::sys::socket::sockopt::TcpNoDelay, &v)
})
}
(::libc::SOL_SOCKET, ::libc::SO_KEEPALIVE) => {
let v = optval.reinterpret_cast::<i32>().read() != 0;
crate::FdRegistry::with_fd(fd, |borrowed| {
nix::sys::socket::setsockopt(&borrowed, nix::sys::socket::sockopt::KeepAlive, &v)
})
}
(::libc::IPPROTO_TCP, ::libc::TCP_KEEPINTVL) => {
let v = optval.reinterpret_cast::<u32>().read();
crate::FdRegistry::with_fd(fd, |borrowed| {
nix::sys::socket::setsockopt(
&borrowed,
nix::sys::socket::sockopt::TcpKeepInterval,
&v,
)
})
}
(::libc::IPPROTO_TCP, ::libc::TCP_KEEPCNT) => {
let v = optval.reinterpret_cast::<u32>().read();
crate::FdRegistry::with_fd(fd, |borrowed| {
nix::sys::socket::setsockopt(&borrowed, nix::sys::socket::sockopt::TcpKeepCount, &v)
})
}
#[cfg(target_os = "linux")]
(::libc::IPPROTO_IP, ::libc::IP_TOS) => {
let v = optval.reinterpret_cast::<i32>().read();
crate::FdRegistry::with_fd(fd, |borrowed| {
nix::sys::socket::setsockopt(&borrowed, nix::sys::socket::sockopt::Ipv4Tos, &v)
})
}
#[cfg(target_os = "linux")]
(::libc::IPPROTO_IPV6, ::libc::IPV6_TCLASS) => {
let v = optval.reinterpret_cast::<i32>().read();
crate::FdRegistry::with_fd(fd, |borrowed| {
nix::sys::socket::setsockopt(&borrowed, nix::sys::socket::sockopt::Ipv6TClass, &v)
})
}
#[cfg(target_os = "linux")]
(::libc::IPPROTO_TCP, ::libc::TCP_KEEPIDLE) => {
let v = optval.reinterpret_cast::<u32>().read();
crate::FdRegistry::with_fd(fd, |borrowed| {
nix::sys::socket::setsockopt(&borrowed, nix::sys::socket::sockopt::TcpKeepIdle, &v)
})
}
#[cfg(target_os = "linux")]
(::libc::SOL_SOCKET, ::libc::SO_BINDTODEVICE) => {
let v = ::std::ffi::OsString::from(optval.reinterpret_cast::<u8>().to_rust_string());
crate::FdRegistry::with_fd(fd, |borrowed| {
nix::sys::socket::setsockopt(&borrowed, nix::sys::socket::sockopt::BindToDevice, &v)
})
}
#[cfg(target_os = "linux")]
(::libc::IPPROTO_IP, ::libc::IP_BIND_ADDRESS_NO_PORT) => {
let v = optval.reinterpret_cast::<i32>().read() != 0;
crate::FdRegistry::with_fd(fd, |borrowed| {
nix::sys::socket::setsockopt(
&borrowed,
nix::sys::socket::sockopt::IpBindAddressNoPort,
&v,
)
})
}
#[cfg(target_os = "linux")]
(::libc::IPPROTO_TCP, ::libc::TCP_FASTOPEN_CONNECT) => {
let v = optval.reinterpret_cast::<i32>().read() != 0;
crate::FdRegistry::with_fd(fd, |borrowed| {
nix::sys::socket::setsockopt(
&borrowed,
nix::sys::socket::sockopt::TcpFastOpenConnect,
&v,
)
})
}
#[cfg(target_os = "linux")]
(::libc::SOL_SOCKET, ::libc::SO_PRIORITY) => {
let v = optval.reinterpret_cast::<i32>().read();
crate::FdRegistry::with_fd(fd, |borrowed| {
nix::sys::socket::setsockopt(&borrowed, nix::sys::socket::sockopt::Priority, &v)
})
}
(l, o) => panic!(
"setsockopt: unsupported option (level={}, optname={})",
l, o
),
};
match res {
Ok(()) => 0,
Err(e) => {
crate::cpp2rust_errno().write(e as i32);
-1
}
}
}
5 changes: 5 additions & 0 deletions rules/ip/src.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <netinet/in.h>
#include <netinet/tcp.h>

typedef struct sockaddr_in t1;
typedef struct in_addr t2;
Expand Down Expand Up @@ -26,3 +27,7 @@ int f5() {
return IPPROTO_MPTCP;
}
#endif

int f6() {
return TCP_NODELAY;
}
4 changes: 4 additions & 0 deletions rules/ip/tgt_unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ unsafe fn f4() -> i32 {
unsafe fn f5() -> i32 {
libc::IPPROTO_MPTCP
}

unsafe fn f6() -> i32 {
libc::TCP_NODELAY
}
12 changes: 12 additions & 0 deletions rules/socket/src.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,15 @@ int f20() {
int f21() {
return AF_INET6;
}

int f22() {
return SOL_SOCKET;
}

int f23() {
return SO_KEEPALIVE;
}

int f24() {
return SO_ERROR;
}
32 changes: 32 additions & 0 deletions rules/socket/tgt_refcount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,35 @@ fn f17(a0: i32, a1: i32) -> i32 {
}
}
}

fn f7(a0: i32, a1: i32, a2: i32, a3: AnyPtr, a4: u32) -> i32 {
let __a0 = a0;
let __a1 = a1;
let __a2 = a2;
let __a3 = a3;
libcc2rs::setsockopt_refcount(__a0, __a1, __a2, __a3)
}

fn f8(a0: i32, a1: i32, a2: i32, a3: AnyPtr, a4: Ptr<u32>) -> i32 {
match (a1, a2) {
(::libc::SOL_SOCKET, ::libc::SO_ERROR) => {
match FdRegistry::with_fd(a0, |__fd| {
nix::sys::socket::getsockopt(&__fd, nix::sys::socket::sockopt::SocketError)
}) {
Ok(__err) => {
a3.reinterpret_cast::<i32>().write(__err);
a4.write(::std::mem::size_of::<i32>() as u32);
0
}
Err(__e) => {
libcc2rs::cpp2rust_errno().write(__e as i32);
-1
}
}
}
(__l, __o) => panic!(
"getsockopt: unsupported option (level={}, optname={})",
__l, __o
),
}
}
12 changes: 12 additions & 0 deletions rules/socket/tgt_unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,15 @@ unsafe fn f20() -> i32 {
unsafe fn f21() -> i32 {
libc::AF_INET6
}

unsafe fn f22() -> i32 {
libc::SOL_SOCKET
}

unsafe fn f23() -> i32 {
libc::SO_KEEPALIVE
}

unsafe fn f24() -> i32 {
libc::SO_ERROR
}
94 changes: 94 additions & 0 deletions tests/unit/out/refcount/sockopt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
extern crate libcc2rs;
use libcc2rs::*;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::io::prelude::*;
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
pub fn main() {
std::process::exit(main_0());
}
fn main_0() -> i32 {
let s: Value<i32> = Rc::new(RefCell::new({
let __family = match libc::AF_INET {
::libc::AF_INET => nix::sys::socket::AddressFamily::Inet,
::libc::AF_INET6 => nix::sys::socket::AddressFamily::Inet6,
::libc::AF_UNIX => nix::sys::socket::AddressFamily::Unix,
__d => panic!("socket: unsupported domain {__d}"),
};
let __flags = nix::sys::socket::SockFlag::from_bits_truncate(libc::SOCK_STREAM);
let __ty = match libc::SOCK_STREAM & !nix::sys::socket::SockFlag::all().bits() {
::libc::SOCK_STREAM => nix::sys::socket::SockType::Stream,
::libc::SOCK_DGRAM => nix::sys::socket::SockType::Datagram,
__t => panic!("socket: unsupported type {__t}"),
};
let __proto = match 0 {
0 => None,
::libc::IPPROTO_TCP => Some(nix::sys::socket::SockProtocol::Tcp),
::libc::IPPROTO_UDP => Some(nix::sys::socket::SockProtocol::Udp),
__p => panic!("socket: unsupported protocol {__p}"),
};
match nix::sys::socket::socket(__family, __ty, __flags, __proto) {
Ok(__ofd) => FdRegistry::register(__ofd),
Err(__e) => {
libcc2rs::cpp2rust_errno().write(__e as i32);
-1
}
}
}));
assert!(((((*s.borrow()) >= 0) as i32) != 0));
let on: Value<i32> = Rc::new(RefCell::new(1));
assert!(
((({
let __a0 = (*s.borrow());
let __a1 = libc::SOL_SOCKET;
let __a2 = libc::SO_KEEPALIVE;
let __a3 = ((on.as_pointer()) as Ptr<i32>).to_any();
libcc2rs::setsockopt_refcount(__a0, __a1, __a2, __a3)
} == 0) as i32)
!= 0)
);
assert!(
((({
let __a0 = (*s.borrow());
let __a1 = libc::IPPROTO_TCP;
let __a2 = libc::TCP_NODELAY;
let __a3 = ((on.as_pointer()) as Ptr<i32>).to_any();
libcc2rs::setsockopt_refcount(__a0, __a1, __a2, __a3)
} == 0) as i32)
!= 0)
);
let err: Value<i32> = Rc::new(RefCell::new(-1_i32));
let len: Value<u32> = Rc::new(RefCell::new((::std::mem::size_of::<i32>() as u32)));
assert!(
(((match (libc::SOL_SOCKET, libc::SO_ERROR) {
(::libc::SOL_SOCKET, ::libc::SO_ERROR) => {
match FdRegistry::with_fd((*s.borrow()), |__fd| {
nix::sys::socket::getsockopt(&__fd, nix::sys::socket::sockopt::SocketError)
}) {
Ok(__err) => {
((err.as_pointer()) as Ptr<i32>)
.to_any()
.reinterpret_cast::<i32>()
.write(__err);
(len.as_pointer()).write(::std::mem::size_of::<i32>() as u32);
0
}
Err(__e) => {
libcc2rs::cpp2rust_errno().write(__e as i32);
-1
}
}
}
(__l, __o) => panic!(
"getsockopt: unsupported option (level={}, optname={})",
__l, __o
),
} == 0) as i32)
!= 0)
);
assert!(((((*err.borrow()) == 0) as i32) != 0));
assert!((((FdRegistry::close((*s.borrow())) == 0) as i32) != 0));
return 0;
}
53 changes: 53 additions & 0 deletions tests/unit/out/unsafe/sockopt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
extern crate libc;
use libc::*;
extern crate libcc2rs;
use libcc2rs::*;
use std::collections::BTreeMap;
use std::io::{Read, Seek, Write};
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
use std::rc::Rc;
pub fn main() {
unsafe {
std::process::exit(main_0() as i32);
}
}
unsafe fn main_0() -> i32 {
let mut s: i32 = libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0);
assert!(((((s) >= (0)) as i32) != 0));
let mut on: i32 = 1;
assert!(
((((libc::setsockopt(
s,
libc::SOL_SOCKET,
libc::SO_KEEPALIVE,
((&mut on as *mut i32) as *const i32 as *const ::libc::c_void),
(::std::mem::size_of::<i32>() as u32)
)) == (0)) as i32)
!= 0)
);
assert!(
((((libc::setsockopt(
s,
libc::IPPROTO_TCP,
libc::TCP_NODELAY,
((&mut on as *mut i32) as *const i32 as *const ::libc::c_void),
(::std::mem::size_of::<i32>() as u32)
)) == (0)) as i32)
!= 0)
);
let mut err: i32 = -1_i32;
let mut len: u32 = (::std::mem::size_of::<i32>() as u32);
assert!(
((((libc::getsockopt(
s,
libc::SOL_SOCKET,
libc::SO_ERROR,
((&mut err as *mut i32) as *mut i32 as *mut ::libc::c_void),
(&mut len as *mut u32)
)) == (0)) as i32)
!= 0)
);
assert!(((((err) == (0)) as i32) != 0));
assert!(((((libc::close(s)) == (0)) as i32) != 0));
return 0;
}
19 changes: 19 additions & 0 deletions tests/unit/sockopt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <assert.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <unistd.h>

int main(void) {
int s = socket(AF_INET, SOCK_STREAM, 0);
assert(s >= 0);
int on = 1;
assert(setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == 0);
assert(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) == 0);
int err = -1;
socklen_t len = sizeof(err);
assert(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) == 0);
assert(err == 0);
assert(close(s) == 0);
return 0;
}
Loading