@@ -1829,22 +1829,88 @@ impl Cage {
18291829 return self . recv_common ( fd, buf, buflen, flags, & mut None ) ;
18301830 }
18311831
1832- //we currently ignore backlog
1833- pub fn listen_syscall ( & self , fd : i32 , _backlog : i32 ) -> i32 {
1832+ /// ### Description
1833+ ///
1834+ /// `listen_syscall` listen for connections on a socket
1835+ ///
1836+ /// ### Arguments
1837+ ///
1838+ /// it accepts two parameters:
1839+ /// * `sockfd` - a file descriptor that refers to a socket of type
1840+ /// SOCK_STREAM Note, we do not implement sockets of type SOCK_SEQPACKET
1841+ /// * `backlog` - defines the maximum length to which the queue of pending
1842+ /// connections for sockfd may grow. If a connection request arrives when
1843+ /// the queue is full, the client may receive an error with an indication
1844+ /// of ECONNREFUSED or, if the underlying protocol supports
1845+ /// retransmission, the request may be ignored so that a later reattempt
1846+ /// at connection succeeds.
1847+ ///
1848+ /// ### Returns
1849+ ///
1850+ /// for a successful call, zero is returned. On error, -errno is
1851+ /// returned and errno is set to indicate the error
1852+ ///
1853+ /// ### Errors
1854+ ///
1855+ /// * EADDRINUSE - Another socket is already listening on the same port.
1856+ ///
1857+ /// * EADDRINUSE - (Internet domain sockets) The socket referred to by
1858+ /// sockfd had not previously been bound to an address and, upon
1859+ /// attempting to bind it to an ephemeral port, it was determined that all
1860+ /// port numbers in the ephemeral port range are currently in use. See
1861+ /// the discussion of /proc/sys/net/ipv4/ip_local_port_range in ip(7).
1862+ ///
1863+ /// * EBADF - The argument sockfd is not a valid file descriptor.
1864+ ///
1865+ /// * ENOTSOCK - The file descriptor sockfd does not refer to a socket.
1866+ ///
1867+ /// * EOPNOTSUPP - The socket is not of a type that supports the listen()
1868+ /// operation.
1869+ ///
1870+ /// ### Panics
1871+ ///
1872+ /// * invalid or out-of-bounds file descriptor), calling unwrap() on it will
1873+ /// cause a panic.
1874+ /// * unknown errno value from socket bind sys call from libc in the case
1875+ /// that the socket isn't assigned an address
1876+ /// * unknown errno value from socket listen sys call from libc
1877+ ///
1878+ /// for more detailed description of all the commands and return values, see
1879+ /// [listen(2)](https://linux.die.net/man/2/listen)
1880+ //
1881+ // TODO: We are currently ignoring backlog
1882+ pub fn listen_syscall ( & self , fd : i32 , backlog : i32 ) -> i32 {
1883+ //BUG:s
1884+ //If fd is out of range of [0,MAXFD], process will panic
1885+ //Otherwise, we obtain a write gaurd to the Option<FileDescriptor> object
18341886 let checkedfd = self . get_filedescriptor ( fd) . unwrap ( ) ;
18351887 let mut unlocked_fd = checkedfd. write ( ) ;
18361888 if let Some ( filedesc_enum) = & mut * unlocked_fd {
18371889 match filedesc_enum {
1890+ //If the file descriptor refers to a socket
18381891 Socket ( ref mut sockfdobj) => {
18391892 //get or create the socket and bind it before listening
1893+ //Gain write access to the socket handle
18401894 let sock_tmp = sockfdobj. handle . clone ( ) ;
18411895 let mut sockhandle = sock_tmp. write ( ) ;
18421896
1897+ //If the given socket is already listening, return with
1898+ //success
18431899 match sockhandle. state {
18441900 ConnState :: LISTEN => {
1845- return 0 ; //Already done!
1901+ return 0 ;
18461902 }
18471903
1904+ //Possible connection states in which the socket
1905+ //can not be set to listening mode:
1906+ // * Connected to another socket and can send
1907+ // and receive data
1908+ // * Connected to another socket and can only send
1909+ // data
1910+ // * Connected to another socket and can only receive
1911+ // data
1912+ // * A non-blocking socket is in progress of connecting
1913+ // to another socket
18481914 ConnState :: CONNECTED
18491915 | ConnState :: CONNRDONLY
18501916 | ConnState :: CONNWRONLY
@@ -1856,7 +1922,11 @@ impl Cage {
18561922 ) ;
18571923 }
18581924
1925+ //If the given socket is not connected, it is ready
1926+ //to begin listening
18591927 ConnState :: NOTCONNECTED => {
1928+ //If the given socket is not a TCP socket, then the
1929+ //socket can not listen for connections
18601930 if sockhandle. protocol != IPPROTO_TCP {
18611931 return syscall_error (
18621932 Errno :: EOPNOTSUPP ,
@@ -1865,12 +1935,24 @@ impl Cage {
18651935 ) ;
18661936 }
18671937
1868- // simple if it's a domain socket
1938+ //TODO: Implement backlog for UNIX
1939+ //If the given socket is a Unix socket, lind handles
1940+ //the connection, return with success
18691941 if sockhandle. domain == AF_UNIX {
18701942 sockhandle. state = ConnState :: LISTEN ;
18711943 return 0 ;
18721944 }
18731945
1946+ //If the given socket is not assigned an address,
1947+ //attempt to bind the socket to an address.
1948+ //
1949+ //An implicit bind refers to the automatic binding of a socket to an
1950+ // address and port by the system, without
1951+ // an explicit call to the bind() function by
1952+ // the programmer.
1953+ //
1954+ //If implicit bind fails, return with the errno if known
1955+ //Otherwise, panic!
18741956 if sockhandle. localaddr . is_none ( ) {
18751957 let shd = sockhandle. domain as i32 ;
18761958 let ibindret = self . _implicit_bind ( & mut * sockhandle, shd) ;
@@ -1882,18 +1964,25 @@ impl Cage {
18821964 }
18831965 }
18841966
1885- let ladr = sockhandle. localaddr . unwrap ( ) . clone ( ) ; //must have been populated by implicit bind
1967+ //The socket must have been assigned an address by implicit bind
1968+ let ladr = sockhandle. localaddr . unwrap ( ) . clone ( ) ;
1969+ //Grab a tuple of the address, port, and port type
1970+ //to be inserted into the set of listening ports
18861971 let porttuple = mux_port (
18871972 ladr. addr ( ) . clone ( ) ,
18881973 ladr. port ( ) ,
18891974 sockhandle. domain ,
18901975 TCPPORT ,
18911976 ) ;
18921977
1978+ //Set the socket connection state to listening
1979+ //to readily accept connections
18931980 NET_METADATA . listening_port_set . insert ( porttuple. clone ( ) ) ;
18941981 sockhandle. state = ConnState :: LISTEN ;
18951982
1896- let listenret = sockhandle. innersocket . as_ref ( ) . unwrap ( ) . listen ( 5 ) ; //default backlog in repy for whatever reason, we replicate it
1983+ //Call listen from libc on the socket
1984+ let listenret =
1985+ sockhandle. innersocket . as_ref ( ) . unwrap ( ) . listen ( backlog) ;
18971986 if listenret < 0 {
18981987 let lr = match Errno :: from_discriminant ( interface:: get_errno ( ) ) {
18991988 Ok ( i) => syscall_error (
@@ -1905,30 +1994,42 @@ impl Cage {
19051994 panic ! ( "Unknown errno value from socket listen returned!" )
19061995 }
19071996 } ;
1908- NET_METADATA . listening_port_set . remove ( & mux_port (
1909- ladr. addr ( ) . clone ( ) ,
1910- ladr. port ( ) ,
1911- sockhandle. domain ,
1912- TCPPORT ,
1913- ) ) ;
1997+ //Remove the tuple of the address, port, and
1998+ //port type from the set of listening ports
1999+ //as we are returning from an error
2000+ NET_METADATA . listening_port_set . remove ( & porttuple) ;
2001+
2002+ //Set the socket state to NOTCONNECTED, as
2003+ //the socket is not listening
19142004 sockhandle. state = ConnState :: NOTCONNECTED ;
19152005 return lr;
19162006 } ;
19172007
1918- //set rawfd for select
2008+ // Set the rawfd for select_syscall as we cannot implement the select
2009+ // logics for AF_INET socket right now, so we have to call the select
2010+ // syscall from libc, which takes the rawfd as the argument instead of
2011+ // the fake fd used by lind.
2012+ // The raw fd of the socket is the set to be the same as the fd set by
2013+ // the kernal in the libc connect call
19192014 sockfdobj. rawfd = sockhandle. innersocket . as_ref ( ) . unwrap ( ) . raw_sys_fd ;
19202015
2016+ //If listening socket is not in the table of pending
2017+ //connections, we must insert it as the key with
2018+ //an empty vector as the value
2019+ //We can now track incoming connections
19212020 if !NET_METADATA . pending_conn_table . contains_key ( & porttuple) {
19222021 NET_METADATA
19232022 . pending_conn_table
19242023 . insert ( porttuple. clone ( ) , vec ! [ ] ) ;
19252024 }
19262025
1927- return 0 ;
2026+ return 0 ; //return on success
19282027 }
19292028 }
19302029 }
19312030
2031+ //Otherwise, the file descriptor refers to something other
2032+ //than a socket, return with error
19322033 _ => {
19332034 return syscall_error (
19342035 Errno :: ENOTSOCK ,
@@ -1937,6 +2038,7 @@ impl Cage {
19372038 ) ;
19382039 }
19392040 }
2041+ //Otherwise, file descriptor is invalid, return with error
19402042 } else {
19412043 return syscall_error ( Errno :: EBADF , "listen" , "invalid file descriptor" ) ;
19422044 }
0 commit comments