Skip to content

Commit d09c658

Browse files
qianxichen233lind
andauthored
getpeername, getsockname, gethostname and getifaddrs update (#307)
* added tests and comments for getpeername and getsockname * test and comment for getifaddrs and gethostname * try to resolve conflict * resolved some comments * resolved some comments * resolved some comments * minor adjustment * added tests and comments for getpeername and getsockname * test and comment for getifaddrs and gethostname * resolved some comments * resolved some comments * resolved some comments * minor adjustment --------- Co-authored-by: lind <lind@nyu.edu>
1 parent 0276e79 commit d09c658

File tree

2 files changed

+653
-17
lines changed

2 files changed

+653
-17
lines changed

src/safeposix/syscalls/net_calls.rs

Lines changed: 147 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3363,31 +3363,69 @@ impl Cage {
33633363
}
33643364
}
33653365

3366+
/// ## ------------------GETPEERNAME SYSCALL------------------
3367+
/// ### Description
3368+
/// The `getpeername_syscall()` returns the address of the peer connected to
3369+
/// the socket fd, in the buffer pointed to by ret_addr
3370+
///
3371+
/// ### Function Arguments
3372+
/// The `getpeername_syscall()` receives two arguments:
3373+
/// * `fd` - The file descriptor of the socket
3374+
/// * `ret_addr` - A buffer of GenSockaddr type to store the return value
3375+
///
3376+
/// ### Returns
3377+
/// On success, zero is returned. Otherwise, errors or panics are returned
3378+
/// for different scenarios.
3379+
///
3380+
/// ### Errors
3381+
/// * EBADF - The argument fd is not a valid file descriptor.
3382+
/// * ENOTSOCK - The file descriptor sockfd does not refer to a socket.
3383+
/// * ENOTCONN - The socket is not connected.
3384+
///
3385+
/// ### Panics
3386+
/// No Panic is expected from this syscall.
3387+
///
3388+
/// more details at https://man7.org/linux/man-pages/man2/getpeername.2.html
33663389
pub fn getpeername_syscall(&self, fd: i32, ret_addr: &mut interface::GenSockaddr) -> i32 {
3390+
// first let's check the fd range
3391+
if fd < 0 || fd >= MAXFD {
3392+
return syscall_error(
3393+
Errno::EBADF,
3394+
"getpeername",
3395+
"the provided file descriptor is not valid",
3396+
);
3397+
}
3398+
3399+
// get the file descriptor object
33673400
let checkedfd = self.get_filedescriptor(fd).unwrap();
33683401
let unlocked_fd = checkedfd.read();
33693402
if let Some(filedesc_enum) = &*unlocked_fd {
33703403
if let Socket(sockfdobj) = filedesc_enum {
3371-
//if the socket is not connected, then we should return an error
3404+
// get the read lock of sockhandle
33723405
let sock_tmp = sockfdobj.handle.clone();
33733406
let sockhandle = sock_tmp.read();
3407+
// if the socket is not connected, then we should return an error
33743408
if sockhandle.remoteaddr == None {
33753409
return syscall_error(
33763410
Errno::ENOTCONN,
33773411
"getpeername",
33783412
"the socket is not connected",
33793413
);
33803414
}
3415+
// remoteaddr stores the value we want so we just return the remoteaddr stored
3416+
// in sockhandle
33813417
*ret_addr = sockhandle.remoteaddr.unwrap();
33823418
return 0;
33833419
} else {
3420+
// if the fd is not socket object
33843421
return syscall_error(
33853422
Errno::ENOTSOCK,
33863423
"getpeername",
33873424
"the provided file is not a socket",
33883425
);
33893426
}
33903427
} else {
3428+
// if the fd is not valid
33913429
return syscall_error(
33923430
Errno::EBADF,
33933431
"getpeername",
@@ -3396,29 +3434,76 @@ impl Cage {
33963434
}
33973435
}
33983436

3437+
/// ## ------------------GETSOCKNAME SYSCALL------------------
3438+
/// ### Description
3439+
/// The `getsockname_syscall()` returns the current address to which the
3440+
/// socket fd is bound, in the buffer pointed to by ret_addr. If the socket
3441+
/// hasn't bound to any address, it returns an empty address.
3442+
///
3443+
/// ### Function Arguments
3444+
/// The `getsockname_syscall()` receives two arguments:
3445+
/// * `fd` - The file descriptor of the socket
3446+
/// * `ret_addr` - A buffer of GenSockaddr type to store the return value
3447+
///
3448+
/// ### Returns
3449+
/// On success, zero is returned. Otherwise, errors or panics are returned
3450+
/// for different scenarios.
3451+
///
3452+
/// ### Errors
3453+
/// * EBADF - The argument fd is not a valid file descriptor.
3454+
/// * ENOTSOCK - The file descriptor sockfd does not refer to a socket.
3455+
///
3456+
/// ### Panics
3457+
/// No Panic is expected from this syscall.
3458+
///
3459+
/// more details at https://man7.org/linux/man-pages/man2/getsockname.2.html
33993460
pub fn getsockname_syscall(&self, fd: i32, ret_addr: &mut interface::GenSockaddr) -> i32 {
3461+
// first let's check the fd range
3462+
if fd < 0 || fd >= MAXFD {
3463+
return syscall_error(
3464+
Errno::EBADF,
3465+
"getsockname",
3466+
"the provided file descriptor is not valid",
3467+
);
3468+
}
3469+
3470+
// get the file descriptor object
34003471
let checkedfd = self.get_filedescriptor(fd).unwrap();
34013472
let unlocked_fd = checkedfd.read();
34023473
if let Some(filedesc_enum) = &*unlocked_fd {
34033474
if let Socket(sockfdobj) = filedesc_enum {
3475+
// must be a socket file descriptor
3476+
3477+
// get the read lock of socket handler
34043478
let sock_tmp = sockfdobj.handle.clone();
34053479
let sockhandle = sock_tmp.read();
3480+
// each socket type has different structure
3481+
// so we must handle them seperately
34063482
if sockhandle.domain == AF_UNIX {
3483+
// in case of AF_UNIX socket
34073484
if sockhandle.localaddr == None {
3485+
// if hasn't bound to any address,
3486+
// return an empty address
34083487
let null_path: &[u8] = &[];
34093488
*ret_addr = interface::GenSockaddr::Unix(interface::new_sockaddr_unix(
34103489
sockhandle.domain as u16,
34113490
null_path,
34123491
));
34133492
return 0;
34143493
}
3415-
//if the socket is not none, then return the socket
3494+
// if the socket address is not none, then return the socket address
34163495
*ret_addr = sockhandle.localaddr.unwrap();
34173496
return 0;
34183497
} else {
3498+
// in case of AF_INET/AF_INET6
34193499
if sockhandle.localaddr == None {
3420-
//sets the address to 0.0.0.0 if the address is not initialized yet
3421-
//setting the family as well based on the domain
3500+
// if the socket hasn't bound to any address, we'd return an empty address
3501+
// with both ip and port set to 0. But family should be set since it is
3502+
// something that was already specified when the socket was created
3503+
3504+
// for ipv4, set the address to 0.0.0.0 to indicate uninitialized address
3505+
// for ipv6, set the address to 0:0:0:0:0:0:0:0
3506+
// (::) to indicate uninitialized address
34223507
let addr = match sockhandle.domain {
34233508
AF_INET => interface::GenIpaddr::V4(interface::V4Addr::default()),
34243509
AF_INET6 => interface::GenIpaddr::V6(interface::V6Addr::default()),
@@ -3428,20 +3513,24 @@ impl Cage {
34283513
};
34293514
ret_addr.set_addr(addr);
34303515
ret_addr.set_port(0);
3516+
// set the family
34313517
ret_addr.set_family(sockhandle.domain as u16);
34323518
return 0;
34333519
}
3520+
// if the socket address is not none, then return the socket address
34343521
*ret_addr = sockhandle.localaddr.unwrap();
34353522
return 0;
34363523
}
34373524
} else {
3525+
// the fd is not a socket
34383526
return syscall_error(
34393527
Errno::ENOTSOCK,
34403528
"getsockname",
34413529
"the provided file is not a socket",
34423530
);
34433531
}
34443532
} else {
3533+
// invalid fd
34453534
return syscall_error(
34463535
Errno::EBADF,
34473536
"getsockname",
@@ -3450,9 +3539,32 @@ impl Cage {
34503539
}
34513540
}
34523541

3453-
//we only return the default host name because we do not allow for the user to
3454-
// change the host name right now
3542+
/// ## ------------------GETHOSTNAME SYSCALL------------------
3543+
/// ### Description
3544+
/// The `gethostname_syscall()` returns the null-terminated hostname in the
3545+
/// address_ptr, which has length bytes. If the null-terminated
3546+
/// hostname is too large to fit, then the name is truncated, and no error
3547+
/// is returned
3548+
///
3549+
/// ### Function Arguments
3550+
/// The `gethostname_syscall()` receives two arguments:
3551+
/// * `address_ptr` - The buffer to hold the returned host name
3552+
/// * `length` - The length of the buffer
3553+
///
3554+
/// ### Returns
3555+
/// On success, zero is returned. Otherwise, errors or panics are returned
3556+
/// for different scenarios.
3557+
///
3558+
/// ### Errors
3559+
/// * EINVAL - length is negative
3560+
///
3561+
/// ### Panics
3562+
/// No Panic is expected from this syscall.
3563+
///
3564+
/// more details at https://www.man7.org/linux/man-pages/man2/gethostname.2.html
34553565
pub fn gethostname_syscall(&self, address_ptr: *mut u8, length: isize) -> i32 {
3566+
// we only return the default host name (Lind) because we do not allow for the
3567+
// user to change the host name right now
34563568
if length < 0 {
34573569
return syscall_error(
34583570
Errno::EINVAL,
@@ -3461,15 +3573,19 @@ impl Cage {
34613573
);
34623574
}
34633575

3576+
// DEFAULT_HOSTNAME is "Lind"
3577+
// we convert the string to vector with a null terminator
34643578
let mut bytes: Vec<u8> = DEFAULT_HOSTNAME.as_bytes().to_vec();
34653579
bytes.push(0u8); //Adding a null terminator to the end of the string
34663580
let name_length = bytes.len();
34673581

3582+
// take the min between name_length and length from argument
34683583
let mut len = name_length;
34693584
if (length as usize) < len {
34703585
len = length as usize;
34713586
}
34723587

3588+
// fill up the address_ptr
34733589
interface::fill(address_ptr, len, &bytes);
34743590

34753591
return 0;
@@ -4251,9 +4367,32 @@ impl Cage {
42514367
return 0;
42524368
}
42534369

4254-
// all this does is send the net_devs data in a string to libc, where we will
4255-
// later parse and alloc into getifaddrs structs
4370+
/// ## ------------------GETIFADDRS SYSCALL------------------
4371+
/// ### Description
4372+
/// The `getifaddrs_syscall()` function creates a linked list of structures
4373+
/// describing the network interfaces of the local system, and stores the
4374+
/// address of the first item of the list in buf.
4375+
///
4376+
/// ### Function Arguments
4377+
/// The `getifaddrs_syscall()` receives two arguments:
4378+
/// * `buf` - The buffer to hold the returned address
4379+
/// * `count` - The length of the buffer
4380+
///
4381+
/// ### Returns
4382+
/// On success, zero is returned. Otherwise, errors or panics are returned
4383+
/// for different scenarios.
4384+
///
4385+
/// ### Errors
4386+
/// * EOPNOTSUPP - buf length is too small to hold the return value
4387+
///
4388+
/// ### Panics
4389+
/// No Panic is expected from this syscall.
4390+
///
4391+
/// more details at https://www.man7.org/linux/man-pages/man3/getifaddrs.3.html
42564392
pub fn getifaddrs_syscall(&self, buf: *mut u8, count: usize) -> i32 {
4393+
// all this does is returning the net_devs data in a string, where we will later
4394+
// parse and alloc into getifaddrs structs in libc
4395+
42574396
if NET_IFADDRS_STR.len() < count {
42584397
interface::fill(
42594398
buf,

0 commit comments

Comments
 (0)