Fix remote addresses in connected UNIX sockets

This commit is contained in:
Ruihan Li 2024-07-27 09:39:54 +08:00 committed by Tate, Hongliang Tian
parent a3d4748d6b
commit 47857fc10f
3 changed files with 39 additions and 24 deletions

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use super::{connected::Connected, endpoint::Endpoint, listener::push_incoming}; use super::{connected::Connected, listener::push_incoming};
use crate::{ use crate::{
events::{IoEvents, Observer}, events::{IoEvents, Observer},
fs::{ fs::{
@ -45,12 +45,8 @@ impl Init {
} }
pub(super) fn connect(&self, remote_addr: &UnixSocketAddrBound) -> Result<Connected> { pub(super) fn connect(&self, remote_addr: &UnixSocketAddrBound) -> Result<Connected> {
let (this_end, remote_end) = let endpoint = push_incoming(remote_addr, self.addr.clone())?;
Endpoint::new_pair(self.addr.clone(), Some(remote_addr.clone())); Ok(Connected::new(endpoint))
push_incoming(remote_addr, remote_end)?;
Ok(Connected::new(this_end))
} }
pub(super) fn addr(&self) -> Option<&UnixSocketAddrBound> { pub(super) fn addr(&self) -> Option<&UnixSocketAddrBound> {

View File

@ -118,15 +118,19 @@ impl BacklogTable {
.ok_or_else(|| Error::with_message(Errno::EINVAL, "the socket is not listened")) .ok_or_else(|| Error::with_message(Errno::EINVAL, "the socket is not listened"))
} }
fn push_incoming(&self, addr: &UnixSocketAddrBound, endpoint: Endpoint) -> Result<()> { fn push_incoming(
let backlog = self.get_backlog(addr).map_err(|_| { &self,
server_addr: &UnixSocketAddrBound,
client_addr: Option<UnixSocketAddrBound>,
) -> Result<Endpoint> {
let backlog = self.get_backlog(server_addr).map_err(|_| {
Error::with_message( Error::with_message(
Errno::ECONNREFUSED, Errno::ECONNREFUSED,
"no socket is listened at the remote address", "no socket is listened at the remote address",
) )
})?; })?;
backlog.push_incoming(endpoint) backlog.push_incoming(client_addr)
} }
fn remove_backlog(&self, addr: &UnixSocketAddrBound) { fn remove_backlog(&self, addr: &UnixSocketAddrBound) {
@ -160,14 +164,23 @@ impl Backlog {
&self.addr &self.addr
} }
fn push_incoming(&self, endpoint: Endpoint) -> Result<()> { fn push_incoming(&self, client_addr: Option<UnixSocketAddrBound>) -> Result<Endpoint> {
let mut endpoints = self.incoming_endpoints.lock(); let mut endpoints = self.incoming_endpoints.lock();
if endpoints.len() >= self.backlog.load(Ordering::Relaxed) { if endpoints.len() >= self.backlog.load(Ordering::Relaxed) {
return_errno_with_message!(Errno::ECONNREFUSED, "incoming_endpoints is full"); return_errno_with_message!(
Errno::ECONNREFUSED,
"the pending connection queue on the listening socket is full"
);
} }
endpoints.push_back(endpoint);
let (server_endpoint, client_endpoint) =
Endpoint::new_pair(Some(self.addr.clone()), client_addr);
endpoints.push_back(server_endpoint);
self.pollee.add_events(IoEvents::IN); self.pollee.add_events(IoEvents::IN);
Ok(())
Ok(client_endpoint)
} }
fn pop_incoming(&self) -> Result<Endpoint> { fn pop_incoming(&self) -> Result<Endpoint> {
@ -216,6 +229,9 @@ fn unregister_backlog(addr: &UnixSocketAddrBound) {
BACKLOG_TABLE.remove_backlog(addr); BACKLOG_TABLE.remove_backlog(addr);
} }
pub(super) fn push_incoming(remote_addr: &UnixSocketAddrBound, remote_end: Endpoint) -> Result<()> { pub(super) fn push_incoming(
BACKLOG_TABLE.push_incoming(remote_addr, remote_end) server_addr: &UnixSocketAddrBound,
client_addr: Option<UnixSocketAddrBound>,
) -> Result<Endpoint> {
BACKLOG_TABLE.push_incoming(server_addr, client_addr)
} }

View File

@ -83,18 +83,21 @@ static int sk_listen;
static int sk_connected; static int sk_connected;
static int sk_accepted; static int sk_accepted;
#define UNNAMED_ADDR \ #define UNIX_ADDR(path) \
((struct sockaddr_un){ .sun_family = AF_UNIX, .sun_path = "" }) ((struct sockaddr_un){ .sun_family = AF_UNIX, .sun_path = path })
#define UNNAMED_ADDR UNIX_ADDR("")
#define UNNAMED_ADDRLEN PATH_OFFSET #define UNNAMED_ADDRLEN PATH_OFFSET
#define BOUND_ADDR \ #define BOUND_ADDR UNIX_ADDR("//tmp/B0")
((struct sockaddr_un){ .sun_family = AF_UNIX, .sun_path = "//tmp/B0" })
#define BOUND_ADDRLEN (PATH_OFFSET + 9) #define BOUND_ADDRLEN (PATH_OFFSET + 9)
#define LISTEN_ADDR \ #define LISTEN_ADDR UNIX_ADDR("/tmp//L0")
((struct sockaddr_un){ .sun_family = AF_UNIX, .sun_path = "/tmp//L0" })
#define LISTEN_ADDRLEN (PATH_OFFSET + 9) #define LISTEN_ADDRLEN (PATH_OFFSET + 9)
#define LISTEN_ADDR2 UNIX_ADDR("/tmp/L0")
#define LISTEN_ADDRLEN2 (PATH_OFFSET + 8)
FN_SETUP(unbound) FN_SETUP(unbound)
{ {
sk_unbound = CHECK(socket(PF_UNIX, SOCK_STREAM, 0)); sk_unbound = CHECK(socket(PF_UNIX, SOCK_STREAM, 0));
@ -123,8 +126,8 @@ FN_SETUP(connected)
{ {
sk_connected = CHECK(socket(PF_UNIX, SOCK_STREAM, 0)); sk_connected = CHECK(socket(PF_UNIX, SOCK_STREAM, 0));
CHECK(connect(sk_connected, (struct sockaddr *)&LISTEN_ADDR, CHECK(connect(sk_connected, (struct sockaddr *)&LISTEN_ADDR2,
LISTEN_ADDRLEN)); LISTEN_ADDRLEN2));
} }
END_SETUP() END_SETUP()