Socket.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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", 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. default:
  93. kprintf("%s(%u): getsockopt() at SOL_SOCKET with unimplemented option %d\n", option);
  94. return KResult(-ENOPROTOOPT);
  95. }
  96. }
  97. void Socket::load_receive_deadline()
  98. {
  99. kgettimeofday(m_receive_deadline);
  100. m_receive_deadline.tv_sec += m_receive_timeout.tv_sec;
  101. m_receive_deadline.tv_usec += m_receive_timeout.tv_usec;
  102. m_receive_deadline.tv_sec += (m_send_timeout.tv_usec / 1000000) * 1;
  103. m_receive_deadline.tv_usec %= 1000000;
  104. }
  105. void Socket::load_send_deadline()
  106. {
  107. kgettimeofday(m_send_deadline);
  108. m_send_deadline.tv_sec += m_send_timeout.tv_sec;
  109. m_send_deadline.tv_usec += m_send_timeout.tv_usec;
  110. m_send_deadline.tv_sec += (m_send_timeout.tv_usec / 1000000) * 1;
  111. m_send_deadline.tv_usec %= 1000000;
  112. }
  113. static const char* to_string(SocketRole role)
  114. {
  115. switch (role) {
  116. case SocketRole::Listener:
  117. return "Listener";
  118. case SocketRole::Accepted:
  119. return "Accepted";
  120. case SocketRole::Connected:
  121. return "Connected";
  122. default:
  123. return "None";
  124. }
  125. }
  126. String Socket::absolute_path(FileDescriptor& descriptor) const
  127. {
  128. return String::format("socket:%x (role: %s)", this, to_string(descriptor.socket_role()));
  129. }