LocalSocket.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include <Kernel/LocalSocket.h>
  2. #include <Kernel/UnixTypes.h>
  3. #include <Kernel/Process.h>
  4. #include <Kernel/VirtualFileSystem.h>
  5. #include <LibC/errno_numbers.h>
  6. //#define DEBUG_LOCAL_SOCKET
  7. Retained<LocalSocket> LocalSocket::create(int type)
  8. {
  9. return adopt(*new LocalSocket(type));
  10. }
  11. LocalSocket::LocalSocket(int type)
  12. : Socket(AF_LOCAL, type, 0)
  13. {
  14. #ifdef DEBUG_LOCAL_SOCKET
  15. kprintf("%s(%u) LocalSocket{%p} created with type=%u\n", current->process().name().characters(), current->pid(), this, type);
  16. #endif
  17. }
  18. LocalSocket::~LocalSocket()
  19. {
  20. }
  21. bool LocalSocket::get_address(sockaddr* address, socklen_t* address_size)
  22. {
  23. // FIXME: Look into what fallback behavior we should have here.
  24. if (*address_size != sizeof(sockaddr_un))
  25. return false;
  26. memcpy(address, &m_address, sizeof(sockaddr_un));
  27. *address_size = sizeof(sockaddr_un);
  28. return true;
  29. }
  30. KResult LocalSocket::bind(const sockaddr* address, socklen_t address_size)
  31. {
  32. ASSERT(!is_connected());
  33. if (address_size != sizeof(sockaddr_un))
  34. return KResult(-EINVAL);
  35. if (address->sa_family != AF_LOCAL)
  36. return KResult(-EINVAL);
  37. const sockaddr_un& local_address = *reinterpret_cast<const sockaddr_un*>(address);
  38. char safe_address[sizeof(local_address.sun_path) + 1];
  39. memcpy(safe_address, local_address.sun_path, sizeof(local_address.sun_path));
  40. #ifdef DEBUG_LOCAL_SOCKET
  41. kprintf("%s(%u) LocalSocket{%p} bind(%s)\n", current->process().name().characters(), current->pid(), this, safe_address);
  42. #endif
  43. auto result = VFS::the().open(safe_address, O_CREAT | O_EXCL, S_IFSOCK | 0666, current->process().cwd_inode());
  44. if (result.is_error()) {
  45. if (result.error() == -EEXIST)
  46. return KResult(-EADDRINUSE);
  47. return result.error();
  48. }
  49. m_file = move(result.value());
  50. ASSERT(m_file->inode());
  51. m_file->inode()->bind_socket(*this);
  52. m_address = local_address;
  53. m_bound = true;
  54. return KSuccess;
  55. }
  56. KResult LocalSocket::connect(const sockaddr* address, socklen_t address_size)
  57. {
  58. ASSERT(!m_bound);
  59. if (address_size != sizeof(sockaddr_un))
  60. return KResult(-EINVAL);
  61. if (address->sa_family != AF_LOCAL)
  62. return KResult(-EINVAL);
  63. const sockaddr_un& local_address = *reinterpret_cast<const sockaddr_un*>(address);
  64. char safe_address[sizeof(local_address.sun_path) + 1];
  65. memcpy(safe_address, local_address.sun_path, sizeof(local_address.sun_path));
  66. #ifdef DEBUG_LOCAL_SOCKET
  67. kprintf("%s(%u) LocalSocket{%p} connect(%s)\n", current->process().name().characters(), current->pid(), this, safe_address);
  68. #endif
  69. auto descriptor_or_error = VFS::the().open(safe_address, 0, 0, current->process().cwd_inode());
  70. if (descriptor_or_error.is_error())
  71. return KResult(-ECONNREFUSED);
  72. m_file = move(descriptor_or_error.value());
  73. ASSERT(m_file->inode());
  74. if (!m_file->inode()->socket())
  75. return KResult(-ECONNREFUSED);
  76. m_address = local_address;
  77. auto peer = m_file->inode()->socket();
  78. auto result = peer->queue_connection_from(*this);
  79. if (result.is_error())
  80. return result;
  81. return current->wait_for_connect(*this);
  82. }
  83. void LocalSocket::attach_fd(SocketRole role)
  84. {
  85. if (role == SocketRole::Accepted) {
  86. ++m_accepted_fds_open;
  87. } else if (role == SocketRole::Connected) {
  88. ++m_connected_fds_open;
  89. } else if (role == SocketRole::Connecting) {
  90. ++m_connecting_fds_open;
  91. }
  92. }
  93. void LocalSocket::detach_fd(SocketRole role)
  94. {
  95. if (role == SocketRole::Accepted) {
  96. ASSERT(m_accepted_fds_open);
  97. --m_accepted_fds_open;
  98. } else if (role == SocketRole::Connected) {
  99. ASSERT(m_connected_fds_open);
  100. --m_connected_fds_open;
  101. } else if (role == SocketRole::Connecting) {
  102. ASSERT(m_connecting_fds_open);
  103. --m_connecting_fds_open;
  104. }
  105. }
  106. bool LocalSocket::can_read(SocketRole role) const
  107. {
  108. if (role == SocketRole::Listener)
  109. return can_accept();
  110. if (role == SocketRole::Accepted)
  111. return (!m_connected_fds_open && !m_connecting_fds_open) || !m_for_server.is_empty();
  112. if (role == SocketRole::Connected)
  113. return !m_accepted_fds_open || !m_for_client.is_empty();
  114. ASSERT_NOT_REACHED();
  115. }
  116. ssize_t LocalSocket::read(SocketRole role, byte* buffer, ssize_t size)
  117. {
  118. if (role == SocketRole::Accepted)
  119. return m_for_server.read(buffer, size);
  120. if (role == SocketRole::Connected)
  121. return m_for_client.read(buffer, size);
  122. ASSERT_NOT_REACHED();
  123. }
  124. ssize_t LocalSocket::write(SocketRole role, const byte* data, ssize_t size)
  125. {
  126. if (role == SocketRole::Accepted) {
  127. if (!m_accepted_fds_open)
  128. return -EPIPE;
  129. return m_for_client.write(data, size);
  130. }
  131. if (role == SocketRole::Connected) {
  132. if (!m_connected_fds_open && !m_connecting_fds_open)
  133. return -EPIPE;
  134. return m_for_server.write(data, size);
  135. }
  136. ASSERT_NOT_REACHED();
  137. }
  138. bool LocalSocket::can_write(SocketRole role) const
  139. {
  140. if (role == SocketRole::Accepted)
  141. return (!m_connected_fds_open && !m_connecting_fds_open) || m_for_client.bytes_in_write_buffer() < 4096;
  142. if (role == SocketRole::Connected)
  143. return !m_accepted_fds_open || m_for_server.bytes_in_write_buffer() < 4096;
  144. ASSERT_NOT_REACHED();
  145. }
  146. ssize_t LocalSocket::sendto(const void*, size_t, int, const sockaddr*, socklen_t)
  147. {
  148. ASSERT_NOT_REACHED();
  149. }
  150. ssize_t LocalSocket::recvfrom(void*, size_t, int flags, sockaddr*, socklen_t*)
  151. {
  152. ASSERT_NOT_REACHED();
  153. }