Browse Source

Kernel: connect() should fail with EISCONN for already-connected sockets.

Also make sure to reset the socket role if Socket::connect() fails.
Andreas Kling 6 years ago
parent
commit
e48cbf3c8c
2 changed files with 6 additions and 1 deletions
  1. 1 0
      Kernel/FileDescriptor.h
  2. 5 1
      Kernel/Process.cpp

+ 1 - 0
Kernel/FileDescriptor.h

@@ -88,6 +88,7 @@ public:
 
     void set_original_inode(Badge<VFS>, Retained<Inode>&& inode) { m_inode = move(inode); }
 
+    SocketRole socket_role() const { return m_socket_role; }
     void set_socket_role(SocketRole);
 
 private:

+ 5 - 1
Kernel/Process.cpp

@@ -2502,11 +2502,15 @@ int Process::sys$connect(int sockfd, const sockaddr* address, socklen_t address_
         return -EBADF;
     if (!descriptor->is_socket())
         return -ENOTSOCK;
+    if (descriptor->socket_role() == SocketRole::Connected)
+        return -EISCONN;
     auto& socket = *descriptor->socket();
     descriptor->set_socket_role(SocketRole::Connecting);
     auto result = socket.connect(address, address_size);
-    if (result.is_error())
+    if (result.is_error()) {
+        descriptor->set_socket_role(SocketRole::None);
         return result;
+    }
     descriptor->set_socket_role(SocketRole::Connected);
     return 0;
 }