tcp_server_socket.cc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/socket/tcp_server_socket.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/bind.h"
  8. #include "base/callback_helpers.h"
  9. #include "base/check.h"
  10. #include "base/notreached.h"
  11. #include "net/base/net_errors.h"
  12. #include "net/socket/socket_descriptor.h"
  13. #include "net/socket/tcp_client_socket.h"
  14. namespace net {
  15. TCPServerSocket::TCPServerSocket(NetLog* net_log, const NetLogSource& source)
  16. : TCPServerSocket(
  17. std::make_unique<TCPSocket>(nullptr /* socket_performance_watcher */,
  18. net_log,
  19. source)) {}
  20. TCPServerSocket::TCPServerSocket(std::unique_ptr<TCPSocket> socket)
  21. : socket_(std::move(socket)) {}
  22. int TCPServerSocket::AdoptSocket(SocketDescriptor socket) {
  23. return socket_->AdoptUnconnectedSocket(socket);
  24. }
  25. TCPServerSocket::~TCPServerSocket() = default;
  26. int TCPServerSocket::Listen(const IPEndPoint& address, int backlog) {
  27. int result = socket_->Open(address.GetFamily());
  28. if (result != OK)
  29. return result;
  30. result = socket_->SetDefaultOptionsForServer();
  31. if (result != OK) {
  32. socket_->Close();
  33. return result;
  34. }
  35. result = socket_->Bind(address);
  36. if (result != OK) {
  37. socket_->Close();
  38. return result;
  39. }
  40. result = socket_->Listen(backlog);
  41. if (result != OK) {
  42. socket_->Close();
  43. return result;
  44. }
  45. return OK;
  46. }
  47. int TCPServerSocket::GetLocalAddress(IPEndPoint* address) const {
  48. return socket_->GetLocalAddress(address);
  49. }
  50. int TCPServerSocket::Accept(std::unique_ptr<StreamSocket>* socket,
  51. CompletionOnceCallback callback) {
  52. return Accept(socket, std::move(callback), nullptr);
  53. }
  54. int TCPServerSocket::Accept(std::unique_ptr<StreamSocket>* socket,
  55. CompletionOnceCallback callback,
  56. IPEndPoint* peer_address) {
  57. DCHECK(socket);
  58. DCHECK(!callback.is_null());
  59. if (pending_accept_) {
  60. NOTREACHED();
  61. return ERR_UNEXPECTED;
  62. }
  63. // It is safe to use base::Unretained(this). |socket_| is owned by this class,
  64. // and the callback won't be run after |socket_| is destroyed.
  65. CompletionOnceCallback accept_callback = base::BindOnce(
  66. &TCPServerSocket::OnAcceptCompleted, base::Unretained(this), socket,
  67. peer_address, std::move(callback));
  68. int result = socket_->Accept(&accepted_socket_, &accepted_address_,
  69. std::move(accept_callback));
  70. if (result != ERR_IO_PENDING) {
  71. // |accept_callback| won't be called so we need to run
  72. // ConvertAcceptedSocket() ourselves in order to do the conversion from
  73. // |accepted_socket_| to |socket|.
  74. result = ConvertAcceptedSocket(result, socket, peer_address);
  75. } else {
  76. pending_accept_ = true;
  77. }
  78. return result;
  79. }
  80. void TCPServerSocket::DetachFromThread() {
  81. socket_->DetachFromThread();
  82. }
  83. int TCPServerSocket::ConvertAcceptedSocket(
  84. int result,
  85. std::unique_ptr<StreamSocket>* output_accepted_socket,
  86. IPEndPoint* output_accepted_address) {
  87. // Make sure the TCPSocket object is destroyed in any case.
  88. std::unique_ptr<TCPSocket> temp_accepted_socket(std::move(accepted_socket_));
  89. if (result != OK)
  90. return result;
  91. if (output_accepted_address)
  92. *output_accepted_address = accepted_address_;
  93. *output_accepted_socket = std::make_unique<TCPClientSocket>(
  94. std::move(temp_accepted_socket), accepted_address_);
  95. return OK;
  96. }
  97. void TCPServerSocket::OnAcceptCompleted(
  98. std::unique_ptr<StreamSocket>* output_accepted_socket,
  99. IPEndPoint* output_accepted_address,
  100. CompletionOnceCallback forward_callback,
  101. int result) {
  102. result = ConvertAcceptedSocket(result, output_accepted_socket,
  103. output_accepted_address);
  104. pending_accept_ = false;
  105. std::move(forward_callback).Run(result);
  106. }
  107. } // namespace net