Support SO_PASSCRED
Co-authored-by: Jianfeng Jiang <jiangjianfeng.jjf@antgroup.com>
This commit is contained in:
parent
deb60415a6
commit
ab897ccd2f
|
|
@ -21,6 +21,7 @@ impl_socket_options!(
|
|||
pub struct Priority(i32);
|
||||
pub struct Linger(LingerOption);
|
||||
pub struct KeepAlive(bool);
|
||||
pub struct PassCred(bool);
|
||||
pub struct PeerCred(CUserCred);
|
||||
pub struct AcceptConn(bool);
|
||||
pub struct SendBufForce(u32);
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ use crate::{
|
|||
match_sock_option_mut, match_sock_option_ref,
|
||||
net::socket::{
|
||||
options::{
|
||||
AcceptConn, KeepAlive, Linger, PeerCred, PeerGroups, Priority, RecvBuf, RecvBufForce,
|
||||
ReuseAddr, ReusePort, SendBuf, SendBufForce, SocketOption,
|
||||
AcceptConn, KeepAlive, Linger, PassCred, PeerCred, PeerGroups, Priority, RecvBuf,
|
||||
RecvBufForce, ReuseAddr, ReusePort, SendBuf, SendBufForce, SocketOption,
|
||||
},
|
||||
unix::{CUserCred, UNIX_STREAM_DEFAULT_BUF_SIZE},
|
||||
},
|
||||
|
|
@ -30,6 +30,7 @@ pub struct SocketOptionSet {
|
|||
recv_buf: u32,
|
||||
linger: LingerOption,
|
||||
keep_alive: bool,
|
||||
pass_cred: bool,
|
||||
priority: i32,
|
||||
}
|
||||
|
||||
|
|
@ -42,14 +43,15 @@ impl Default for SocketOptionSet {
|
|||
recv_buf: MIN_RECVBUF,
|
||||
linger: LingerOption::default(),
|
||||
keep_alive: false,
|
||||
pass_cred: false,
|
||||
priority: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SocketOptionSet {
|
||||
/// Return the default socket level options for tcp socket.
|
||||
pub fn new_tcp() -> Self {
|
||||
/// Returns the default socket level options for tcp socket.
|
||||
pub(in crate::net) fn new_tcp() -> Self {
|
||||
Self {
|
||||
send_buf: TCP_SEND_BUF_LEN as u32,
|
||||
recv_buf: TCP_RECV_BUF_LEN as u32,
|
||||
|
|
@ -57,8 +59,8 @@ impl SocketOptionSet {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the default socket level options for udp socket.
|
||||
pub fn new_udp() -> Self {
|
||||
/// Returns the default socket level options for udp socket.
|
||||
pub(in crate::net) fn new_udp() -> Self {
|
||||
Self {
|
||||
send_buf: UDP_SEND_PAYLOAD_LEN as u32,
|
||||
recv_buf: UDP_RECV_PAYLOAD_LEN as u32,
|
||||
|
|
@ -114,6 +116,12 @@ impl SocketOptionSet {
|
|||
let keep_alive = self.keep_alive();
|
||||
socket_keepalive.set(keep_alive);
|
||||
},
|
||||
socket_pass_cred: PassCred => {
|
||||
// This option only affects UNIX sockets. However, it also works well with other
|
||||
// sockets for setting and getting.
|
||||
let pass_cred = self.pass_cred();
|
||||
socket_pass_cred.set(pass_cred);
|
||||
},
|
||||
socket_peer_cred: PeerCred => {
|
||||
let peer_cred = CUserCred::new_unknown();
|
||||
socket_peer_cred.set(peer_cred);
|
||||
|
|
@ -185,6 +193,12 @@ impl SocketOptionSet {
|
|||
self.set_keep_alive(*keep_alive);
|
||||
return Ok(socket.set_keep_alive(*keep_alive));
|
||||
},
|
||||
socket_pass_cred: PassCred => {
|
||||
// This option only affects UNIX sockets. However, it also works well with other
|
||||
// sockets for setting and getting.
|
||||
let pass_cred = socket_pass_cred.get().unwrap();
|
||||
self.set_pass_cred(*pass_cred);
|
||||
},
|
||||
socket_sendbuf_force: SendBufForce => {
|
||||
check_current_privileged()?;
|
||||
let send_buf = socket_sendbuf_force.get().unwrap();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use super::RawSocketOption;
|
|||
use crate::{
|
||||
current_userspace, impl_raw_sock_option_get_only, impl_raw_socket_option,
|
||||
net::socket::options::{
|
||||
AcceptConn, Error, KeepAlive, Linger, PeerCred, PeerGroups, Priority, RecvBuf,
|
||||
AcceptConn, Error, KeepAlive, Linger, PassCred, PeerCred, PeerGroups, Priority, RecvBuf,
|
||||
RecvBufForce, ReuseAddr, ReusePort, SendBuf, SendBufForce, SocketOption,
|
||||
},
|
||||
prelude::*,
|
||||
|
|
@ -57,6 +57,7 @@ pub fn new_socket_option(name: i32) -> Result<Box<dyn RawSocketOption>> {
|
|||
CSocketOptionName::REUSEPORT => Ok(Box::new(ReusePort::new())),
|
||||
CSocketOptionName::PRIORITY => Ok(Box::new(Priority::new())),
|
||||
CSocketOptionName::LINGER => Ok(Box::new(Linger::new())),
|
||||
CSocketOptionName::PASSCRED => Ok(Box::new(PassCred::new())),
|
||||
CSocketOptionName::KEEPALIVE => Ok(Box::new(KeepAlive::new())),
|
||||
CSocketOptionName::PEERCRED => Ok(Box::new(PeerCred::new())),
|
||||
CSocketOptionName::ACCPETCONN => Ok(Box::new(AcceptConn::new())),
|
||||
|
|
@ -75,6 +76,7 @@ impl_raw_socket_option!(ReusePort);
|
|||
impl_raw_socket_option!(Priority);
|
||||
impl_raw_socket_option!(Linger);
|
||||
impl_raw_socket_option!(KeepAlive);
|
||||
impl_raw_socket_option!(PassCred);
|
||||
impl_raw_sock_option_get_only!(PeerCred);
|
||||
impl_raw_sock_option_get_only!(AcceptConn);
|
||||
impl_raw_socket_option!(SendBufForce);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
* UNIX stream socket-related socket options.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
|
@ -83,6 +82,37 @@ FN_TEST(acceptconn)
|
|||
}
|
||||
END_TEST()
|
||||
|
||||
FN_TEST(pass_cred)
|
||||
{
|
||||
int val = 0;
|
||||
socklen_t len = sizeof(val);
|
||||
|
||||
TEST_RES(getsockopt(sk_tcp, SOL_SOCKET, SO_PASSCRED, &val, &len),
|
||||
len == 4 && val == 0);
|
||||
TEST_RES(getsockopt(sk_unbound, SOL_SOCKET, SO_PASSCRED, &val, &len),
|
||||
len == 4 && val == 0);
|
||||
TEST_RES(getsockopt(sk_listen, SOL_SOCKET, SO_PASSCRED, &val, &len),
|
||||
len == 4 && val == 0);
|
||||
TEST_RES(getsockopt(sk_connected, SOL_SOCKET, SO_PASSCRED, &val, &len),
|
||||
len == 4 && val == 0);
|
||||
|
||||
val = 100;
|
||||
TEST_SUCC(setsockopt(sk_tcp, SOL_SOCKET, SO_PASSCRED, &val, len));
|
||||
TEST_SUCC(setsockopt(sk_unbound, SOL_SOCKET, SO_PASSCRED, &val, len));
|
||||
TEST_SUCC(setsockopt(sk_listen, SOL_SOCKET, SO_PASSCRED, &val, len));
|
||||
TEST_SUCC(setsockopt(sk_connected, SOL_SOCKET, SO_PASSCRED, &val, len));
|
||||
|
||||
TEST_RES(getsockopt(sk_tcp, SOL_SOCKET, SO_PASSCRED, &val, &len),
|
||||
len == 4 && val == 1);
|
||||
TEST_RES(getsockopt(sk_unbound, SOL_SOCKET, SO_PASSCRED, &val, &len),
|
||||
len == 4 && val == 1);
|
||||
TEST_RES(getsockopt(sk_listen, SOL_SOCKET, SO_PASSCRED, &val, &len),
|
||||
len == 4 && val == 1);
|
||||
TEST_RES(getsockopt(sk_connected, SOL_SOCKET, SO_PASSCRED, &val, &len),
|
||||
len == 4 && val == 1);
|
||||
}
|
||||
END_TEST()
|
||||
|
||||
FN_TEST(peer_cred)
|
||||
{
|
||||
struct cred {
|
||||
|
|
@ -94,7 +124,7 @@ FN_TEST(peer_cred)
|
|||
struct cred ucred = {};
|
||||
socklen_t len = sizeof(ucred);
|
||||
|
||||
TEST_ERRNO(setsockopt(sk_unbound, SOL_SOCKET, SO_PEERCRED, &ucred, len),
|
||||
TEST_ERRNO(setsockopt(sk_tcp, SOL_SOCKET, SO_PEERCRED, &ucred, len),
|
||||
ENOPROTOOPT);
|
||||
TEST_RES(getsockopt(sk_tcp, SOL_SOCKET, SO_PEERCRED, &ucred, &len),
|
||||
ucred.pid == 0 && ucred.uid == -1 && ucred.gid == -1);
|
||||
|
|
@ -228,4 +258,4 @@ FN_SETUP(cleanup)
|
|||
CHECK(close(sk_tcp));
|
||||
CHECK(unlink(addr.sun_path));
|
||||
}
|
||||
END_SETUP()
|
||||
END_SETUP()
|
||||
|
|
|
|||
Loading…
Reference in New Issue