Socket.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include <Kernel/FileSystem/FileDescriptor.h>
  2. #include <Kernel/Net/Socket.h>
  3. #include <Kernel/Net/LocalSocket.h>
  4. #include <Kernel/Net/IPv4Socket.h>
  5. #include <Kernel/UnixTypes.h>
  6. #include <Kernel/Process.h>
  7. #include <LibC/errno_numbers.h>
  8. KResultOr<Retained<Socket>> Socket::create(int domain, int type, int protocol)
  9. {
  10. (void)protocol;
  11. switch (domain) {
  12. case AF_LOCAL:
  13. return LocalSocket::create(type & SOCK_TYPE_MASK);
  14. case AF_INET:
  15. return IPv4Socket::create(type & SOCK_TYPE_MASK, protocol);
  16. default:
  17. return KResult(-EAFNOSUPPORT);
  18. }
  19. }
  20. Socket::Socket(int domain, int type, int protocol)
  21. : m_domain(domain)
  22. , m_type(type)
  23. , m_protocol(protocol)
  24. {
  25. m_origin_pid = current->pid();
  26. }
  27. Socket::~Socket()
  28. {
  29. }
  30. KResult Socket::listen(int backlog)
  31. {
  32. LOCKER(m_lock);
  33. if (m_type != SOCK_STREAM)
  34. return KResult(-EOPNOTSUPP);
  35. m_backlog = backlog;
  36. kprintf("Socket{%p} listening with backlog=%d\n", this, m_backlog);
  37. return KSuccess;
  38. }
  39. RetainPtr<Socket> Socket::accept()
  40. {
  41. LOCKER(m_lock);
  42. if (m_pending.is_empty())
  43. return nullptr;
  44. auto client = m_pending.take_first();
  45. ASSERT(!client->is_connected());
  46. client->m_connected = true;
  47. return client;
  48. }
  49. KResult Socket::queue_connection_from(Socket& peer)
  50. {
  51. LOCKER(m_lock);
  52. if (m_pending.size() >= m_backlog)
  53. return KResult(-ECONNREFUSED);
  54. m_pending.append(peer);
  55. return KSuccess;
  56. }
  57. KResult Socket::setsockopt(int level, int option, const void* value, socklen_t value_size)
  58. {
  59. ASSERT(level == SOL_SOCKET);
  60. switch (option) {
  61. case SO_SNDTIMEO:
  62. if (value_size != sizeof(timeval))
  63. return KResult(-EINVAL);
  64. m_send_timeout = *(const timeval*)value;
  65. return KSuccess;
  66. case SO_RCVTIMEO:
  67. if (value_size != sizeof(timeval))
  68. return KResult(-EINVAL);
  69. m_receive_timeout = *(const timeval*)value;
  70. return KSuccess;
  71. default:
  72. kprintf("%s(%u): setsockopt() at SOL_SOCKET with unimplemented option %d\n", current->process().name().characters(), current->process().pid(), option);
  73. return KResult(-ENOPROTOOPT);
  74. }
  75. }
  76. KResult Socket::getsockopt(int level, int option, void* value, socklen_t* value_size)
  77. {
  78. ASSERT(level == SOL_SOCKET);
  79. switch (option) {
  80. case SO_SNDTIMEO:
  81. if (*value_size < sizeof(timeval))
  82. return KResult(-EINVAL);
  83. *(timeval*)value = m_send_timeout;
  84. *value_size = sizeof(timeval);
  85. return KSuccess;
  86. case SO_RCVTIMEO:
  87. if (*value_size < sizeof(timeval))
  88. return KResult(-EINVAL);
  89. *(timeval*)value = m_receive_timeout;
  90. *value_size = sizeof(timeval);
  91. return KSuccess;
  92. case SO_ERROR:
  93. if (*value_size < sizeof(int))
  94. return KResult(-EINVAL);
  95. kprintf("%s(%u): getsockopt() SO_ERROR: WARNING! I have no idea what the real error is, so I'll just stick my fingers in my ears and pretend there is none! %d\n", current->process().name().characters(), option);
  96. *(int*)value = 0;
  97. *value_size = sizeof(int);
  98. return KSuccess;
  99. default:
  100. kprintf("%s(%u): getsockopt() at SOL_SOCKET with unimplemented option %d\n", current->process().name().characters(), option);
  101. return KResult(-ENOPROTOOPT);
  102. }
  103. }
  104. void Socket::load_receive_deadline()
  105. {
  106. kgettimeofday(m_receive_deadline);
  107. m_receive_deadline.tv_sec += m_receive_timeout.tv_sec;
  108. m_receive_deadline.tv_usec += m_receive_timeout.tv_usec;
  109. m_receive_deadline.tv_sec += (m_send_timeout.tv_usec / 1000000) * 1;
  110. m_receive_deadline.tv_usec %= 1000000;
  111. }
  112. void Socket::load_send_deadline()
  113. {
  114. kgettimeofday(m_send_deadline);
  115. m_send_deadline.tv_sec += m_send_timeout.tv_sec;
  116. m_send_deadline.tv_usec += m_send_timeout.tv_usec;
  117. m_send_deadline.tv_sec += (m_send_timeout.tv_usec / 1000000) * 1;
  118. m_send_deadline.tv_usec %= 1000000;
  119. }
  120. static const char* to_string(SocketRole role)
  121. {
  122. switch (role) {
  123. case SocketRole::Listener:
  124. return "Listener";
  125. case SocketRole::Accepted:
  126. return "Accepted";
  127. case SocketRole::Connected:
  128. return "Connected";
  129. default:
  130. return "None";
  131. }
  132. }
  133. String Socket::absolute_path(const FileDescriptor& descriptor) const
  134. {
  135. return String::format("socket:%x (role: %s)", this, to_string(descriptor.socket_role()));
  136. }