@@ -3194,6 +3194,56 @@ impl Cage {
31943194 }
31953195 }
31963196
3197+ /// ## ------------------SOCKETPAIR SYSCALL------------------
3198+ /// ### Description
3199+ /// The `socketpair_syscall()` call creates an unnamed pair of connected
3200+ /// sockets in the specified domain, of the specified type, and using
3201+ /// the optionally specified protocol.
3202+ /// The file descriptors used in referencing the new sockets are returned
3203+ /// in sv.sock1 and sv.sock2. The two sockets are indistinguishable.
3204+ /// ### Function Arguments
3205+ /// The `socketpair_syscall()` receives four arguments:
3206+ /// * `domain` - The domain argument specifies a communication domain; this
3207+ /// selects the protocol family which will be used for communication.
3208+ /// Currently supported domains are AF_UNIX, AF_INET and AF_INET6.
3209+ /// * `socktype` - specifies the communication semantics. Currently defined
3210+ /// types are:
3211+ /// 1. SOCK_STREAM Provides sequenced, reliable, two-way,
3212+ /// connection-based byte streams. An out-of-band data
3213+ /// transmission mechanism may be supported.
3214+ /// 2. SOCK_DGRAM Supports datagrams (connectionless,
3215+ /// unreliable messages of a fixed maximum length). The
3216+ /// type argument serves a second purpose: in addition to
3217+ /// specifying a socket type, it may include the bitwise
3218+ /// OR of any of the following values, to modify the
3219+ /// behavior of the socket:
3220+ /// 1. SOCK_NONBLOCK Set the O_NONBLOCK file status flag on
3221+ /// the open file description referred to by the new file
3222+ /// descriptor.
3223+ /// 2. SOCK_CLOEXEC Set the close-on-exec flag on the new
3224+ /// file descriptor.
3225+ /// * `protocol` - The protocol specifies a particular protocol to be used
3226+ /// with the socket. Currently only support the default protocol
3227+ /// (IPPROTO_TCP).
3228+ /// * `sv` - The file descriptors used in referencing the new sockets are
3229+ /// returned in sv.sock1 and sv.sock2. The two sockets are
3230+ /// indistinguishable.
3231+
3232+ /// ### Returns
3233+ /// On success, zero is returned. Otherwise, errors or panics are returned
3234+ /// for different scenarios.
3235+ ///
3236+ /// ### Errors
3237+ /// * EAFNOSUPPORT - The specified address family is not supported on this
3238+ /// machine.
3239+ /// * EOPNOTSUPP - The specified protocol does not support creation of
3240+ /// socket pairs.
3241+ /// * EINVAL - The specified flag is not valid
3242+ /// * ENFILE - no enough file descriptors can be assigned
3243+ ///
3244+ /// ### Panics
3245+ /// No Panic is expected for this syscall.
3246+
31973247 // Because socketpair needs to spawn off a helper thread to connect the two ends
31983248 // of the socket pair, and because that helper thread, along with the main
31993249 // thread, need to access the cage to call methods (syscalls) of it, and because
@@ -3208,14 +3258,22 @@ impl Cage {
32083258 protocol : i32 ,
32093259 sv : & mut interface:: SockPair ,
32103260 ) -> i32 {
3211- let newprotocol = if protocol == 0 { IPPROTO_TCP } else { protocol } ;
3261+ let newprotocol = if protocol == 0 { IPPROTO_TCP } else { protocol } ; // only support protocol of 0 currently
3262+ // BUG: current implementation of socketpair creates two sockets and bind to an
3263+ // unique address.
3264+ // But according to standard, the sockets created from socketpair should not
3265+ // bind to any address
3266+
32123267 // firstly check the parameters
3268+ // socketpair should always be a AF_UNIX TCP socket
32133269 if domain != AF_UNIX {
32143270 return syscall_error (
32153271 Errno :: EOPNOTSUPP ,
32163272 "socketpair" ,
32173273 "Linux socketpair only supports AF_UNIX aka AF_LOCAL domain." ,
32183274 ) ;
3275+ // socket type is stored at the lowest 3 bits
3276+ // so we and it with 0x7 to retrieve it
32193277 } else if socktype & 0x7 != SOCK_STREAM || newprotocol != IPPROTO_TCP {
32203278 return syscall_error (
32213279 Errno :: EOPNOTSUPP ,
@@ -3224,6 +3282,12 @@ impl Cage {
32243282 ) ;
32253283 }
32263284
3285+ // check if socktype contains any invalid flag bits
3286+ if socktype & !( SOCK_NONBLOCK | SOCK_CLOEXEC | 0x7 ) != 0 {
3287+ return syscall_error ( Errno :: EINVAL , "socket" , "Invalid combination of flags" ) ;
3288+ }
3289+
3290+ // get the flags
32273291 let nonblocking = ( socktype & SOCK_NONBLOCK ) != 0 ;
32283292 let cloexec = ( socktype & SOCK_CLOEXEC ) != 0 ;
32293293
@@ -3248,6 +3312,7 @@ impl Cage {
32483312 let sock2fd = this. _socket_inserter ( Socket ( sock2fdobj. clone ( ) ) ) ;
32493313
32503314 // assign local addresses and connect
3315+ // we are not supposed to assign and bind address to socketpair sockets
32513316 let sock1tmp = sock1fdobj. handle . clone ( ) ;
32523317 let sock2tmp = sock2fdobj. handle . clone ( ) ;
32533318 let mut sock1handle = sock1tmp. write ( ) ;
@@ -3275,6 +3340,9 @@ impl Cage {
32753340 sv. sock1 = sock1fd;
32763341 sv. sock2 = sock2fd;
32773342
3343+ // since socket file should not exist in the first place
3344+ // the code below is supposed to be removed as well
3345+
32783346 // we need to increment the refcount of the sockets we created
32793347 // reason: in bind_inner_socket, we added entries to the inode table
32803348 let inode1num = sock1handle. unix_info . as_mut ( ) . unwrap ( ) . inode ;
0 commit comments