socket_posix.cc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. // Copyright 2014 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/socket_posix.h"
  5. #include <errno.h>
  6. #include <netinet/in.h>
  7. #include <sys/socket.h>
  8. #include <memory>
  9. #include <utility>
  10. #include "base/bind.h"
  11. #include "base/callback_helpers.h"
  12. #include "base/files/file_util.h"
  13. #include "base/logging.h"
  14. #include "base/posix/eintr_wrapper.h"
  15. #include "base/task/current_thread.h"
  16. #include "base/trace_event/trace_event.h"
  17. #include "build/build_config.h"
  18. #include "net/base/io_buffer.h"
  19. #include "net/base/ip_endpoint.h"
  20. #include "net/base/net_errors.h"
  21. #include "net/base/sockaddr_storage.h"
  22. #include "net/base/trace_constants.h"
  23. #include "net/traffic_annotation/network_traffic_annotation.h"
  24. #if BUILDFLAG(IS_FUCHSIA)
  25. #include <poll.h>
  26. #include <sys/ioctl.h>
  27. #endif // BUILDFLAG(IS_FUCHSIA)
  28. namespace net {
  29. namespace {
  30. int MapAcceptError(int os_error) {
  31. switch (os_error) {
  32. // If the client aborts the connection before the server calls accept,
  33. // POSIX specifies accept should fail with ECONNABORTED. The server can
  34. // ignore the error and just call accept again, so we map the error to
  35. // ERR_IO_PENDING. See UNIX Network Programming, Vol. 1, 3rd Ed., Sec.
  36. // 5.11, "Connection Abort before accept Returns".
  37. case ECONNABORTED:
  38. return ERR_IO_PENDING;
  39. default:
  40. return MapSystemError(os_error);
  41. }
  42. }
  43. int MapConnectError(int os_error) {
  44. switch (os_error) {
  45. case EINPROGRESS:
  46. return ERR_IO_PENDING;
  47. case EACCES:
  48. return ERR_NETWORK_ACCESS_DENIED;
  49. case ETIMEDOUT:
  50. return ERR_CONNECTION_TIMED_OUT;
  51. default: {
  52. int net_error = MapSystemError(os_error);
  53. if (net_error == ERR_FAILED)
  54. return ERR_CONNECTION_FAILED; // More specific than ERR_FAILED.
  55. return net_error;
  56. }
  57. }
  58. }
  59. } // namespace
  60. SocketPosix::SocketPosix()
  61. : socket_fd_(kInvalidSocket),
  62. accept_socket_watcher_(FROM_HERE),
  63. read_socket_watcher_(FROM_HERE),
  64. write_socket_watcher_(FROM_HERE) {}
  65. SocketPosix::~SocketPosix() {
  66. Close();
  67. }
  68. int SocketPosix::Open(int address_family) {
  69. DCHECK(thread_checker_.CalledOnValidThread());
  70. DCHECK_EQ(kInvalidSocket, socket_fd_);
  71. DCHECK(address_family == AF_INET ||
  72. address_family == AF_INET6 ||
  73. address_family == AF_UNIX);
  74. socket_fd_ = CreatePlatformSocket(
  75. address_family,
  76. SOCK_STREAM,
  77. address_family == AF_UNIX ? 0 : IPPROTO_TCP);
  78. if (socket_fd_ < 0) {
  79. PLOG(ERROR) << "CreatePlatformSocket() failed";
  80. return MapSystemError(errno);
  81. }
  82. if (!base::SetNonBlocking(socket_fd_)) {
  83. int rv = MapSystemError(errno);
  84. Close();
  85. return rv;
  86. }
  87. return OK;
  88. }
  89. int SocketPosix::AdoptConnectedSocket(SocketDescriptor socket,
  90. const SockaddrStorage& address) {
  91. int rv = AdoptUnconnectedSocket(socket);
  92. if (rv != OK)
  93. return rv;
  94. SetPeerAddress(address);
  95. return OK;
  96. }
  97. int SocketPosix::AdoptUnconnectedSocket(SocketDescriptor socket) {
  98. DCHECK(thread_checker_.CalledOnValidThread());
  99. DCHECK_EQ(kInvalidSocket, socket_fd_);
  100. socket_fd_ = socket;
  101. if (!base::SetNonBlocking(socket_fd_)) {
  102. int rv = MapSystemError(errno);
  103. Close();
  104. return rv;
  105. }
  106. return OK;
  107. }
  108. SocketDescriptor SocketPosix::ReleaseConnectedSocket() {
  109. // It's not safe to release a socket with a pending write.
  110. DCHECK(!write_buf_);
  111. StopWatchingAndCleanUp(false /* close_socket */);
  112. SocketDescriptor socket_fd = socket_fd_;
  113. socket_fd_ = kInvalidSocket;
  114. return socket_fd;
  115. }
  116. int SocketPosix::Bind(const SockaddrStorage& address) {
  117. DCHECK(thread_checker_.CalledOnValidThread());
  118. DCHECK_NE(kInvalidSocket, socket_fd_);
  119. int rv = bind(socket_fd_, address.addr, address.addr_len);
  120. if (rv < 0) {
  121. PLOG(ERROR) << "bind() failed";
  122. return MapSystemError(errno);
  123. }
  124. return OK;
  125. }
  126. int SocketPosix::Listen(int backlog) {
  127. DCHECK(thread_checker_.CalledOnValidThread());
  128. DCHECK_NE(kInvalidSocket, socket_fd_);
  129. DCHECK_LT(0, backlog);
  130. int rv = listen(socket_fd_, backlog);
  131. if (rv < 0) {
  132. PLOG(ERROR) << "listen() failed";
  133. return MapSystemError(errno);
  134. }
  135. return OK;
  136. }
  137. int SocketPosix::Accept(std::unique_ptr<SocketPosix>* socket,
  138. CompletionOnceCallback callback) {
  139. DCHECK(thread_checker_.CalledOnValidThread());
  140. DCHECK_NE(kInvalidSocket, socket_fd_);
  141. DCHECK(accept_callback_.is_null());
  142. DCHECK(socket);
  143. DCHECK(!callback.is_null());
  144. int rv = DoAccept(socket);
  145. if (rv != ERR_IO_PENDING)
  146. return rv;
  147. if (!base::CurrentIOThread::Get()->WatchFileDescriptor(
  148. socket_fd_, true, base::MessagePumpForIO::WATCH_READ,
  149. &accept_socket_watcher_, this)) {
  150. PLOG(ERROR) << "WatchFileDescriptor failed on accept";
  151. return MapSystemError(errno);
  152. }
  153. accept_socket_ = socket;
  154. accept_callback_ = std::move(callback);
  155. return ERR_IO_PENDING;
  156. }
  157. int SocketPosix::Connect(const SockaddrStorage& address,
  158. CompletionOnceCallback callback) {
  159. DCHECK(thread_checker_.CalledOnValidThread());
  160. DCHECK_NE(kInvalidSocket, socket_fd_);
  161. DCHECK(!waiting_connect_);
  162. DCHECK(!callback.is_null());
  163. SetPeerAddress(address);
  164. int rv = DoConnect();
  165. if (rv != ERR_IO_PENDING)
  166. return rv;
  167. if (!base::CurrentIOThread::Get()->WatchFileDescriptor(
  168. socket_fd_, true, base::MessagePumpForIO::WATCH_WRITE,
  169. &write_socket_watcher_, this)) {
  170. PLOG(ERROR) << "WatchFileDescriptor failed on connect";
  171. return MapSystemError(errno);
  172. }
  173. // There is a race-condition in the above code if the kernel receive a RST
  174. // packet for the "connect" call before the registration of the socket file
  175. // descriptor to the message loop pump. On most platform it is benign as the
  176. // message loop pump is awakened for that socket in an error state, but on
  177. // iOS this does not happens. Check the status of the socket at this point
  178. // and if in error, consider the connection as failed.
  179. int os_error = 0;
  180. socklen_t len = sizeof(os_error);
  181. if (getsockopt(socket_fd_, SOL_SOCKET, SO_ERROR, &os_error, &len) == 0) {
  182. // TCPSocketPosix expects errno to be set.
  183. errno = os_error;
  184. }
  185. rv = MapConnectError(errno);
  186. if (rv != OK && rv != ERR_IO_PENDING) {
  187. write_socket_watcher_.StopWatchingFileDescriptor();
  188. return rv;
  189. }
  190. write_callback_ = std::move(callback);
  191. waiting_connect_ = true;
  192. return ERR_IO_PENDING;
  193. }
  194. bool SocketPosix::IsConnected() const {
  195. DCHECK(thread_checker_.CalledOnValidThread());
  196. if (socket_fd_ == kInvalidSocket || waiting_connect_)
  197. return false;
  198. // Checks if connection is alive.
  199. char c;
  200. int rv = HANDLE_EINTR(recv(socket_fd_, &c, 1, MSG_PEEK));
  201. if (rv == 0)
  202. return false;
  203. if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK)
  204. return false;
  205. return true;
  206. }
  207. bool SocketPosix::IsConnectedAndIdle() const {
  208. DCHECK(thread_checker_.CalledOnValidThread());
  209. if (socket_fd_ == kInvalidSocket || waiting_connect_)
  210. return false;
  211. // Check if connection is alive and we haven't received any data
  212. // unexpectedly.
  213. char c;
  214. int rv = HANDLE_EINTR(recv(socket_fd_, &c, 1, MSG_PEEK));
  215. if (rv >= 0)
  216. return false;
  217. if (errno != EAGAIN && errno != EWOULDBLOCK)
  218. return false;
  219. return true;
  220. }
  221. int SocketPosix::Read(IOBuffer* buf,
  222. int buf_len,
  223. CompletionOnceCallback callback) {
  224. // Use base::Unretained() is safe here because OnFileCanReadWithoutBlocking()
  225. // won't be called if |this| is gone.
  226. int rv = ReadIfReady(
  227. buf, buf_len,
  228. base::BindOnce(&SocketPosix::RetryRead, base::Unretained(this)));
  229. if (rv == ERR_IO_PENDING) {
  230. read_buf_ = buf;
  231. read_buf_len_ = buf_len;
  232. read_callback_ = std::move(callback);
  233. }
  234. return rv;
  235. }
  236. int SocketPosix::ReadIfReady(IOBuffer* buf,
  237. int buf_len,
  238. CompletionOnceCallback callback) {
  239. DCHECK(thread_checker_.CalledOnValidThread());
  240. DCHECK_NE(kInvalidSocket, socket_fd_);
  241. DCHECK(!waiting_connect_);
  242. CHECK(read_if_ready_callback_.is_null());
  243. DCHECK(!callback.is_null());
  244. DCHECK_LT(0, buf_len);
  245. int rv = DoRead(buf, buf_len);
  246. if (rv != ERR_IO_PENDING)
  247. return rv;
  248. if (!base::CurrentIOThread::Get()->WatchFileDescriptor(
  249. socket_fd_, true, base::MessagePumpForIO::WATCH_READ,
  250. &read_socket_watcher_, this)) {
  251. PLOG(ERROR) << "WatchFileDescriptor failed on read";
  252. return MapSystemError(errno);
  253. }
  254. read_if_ready_callback_ = std::move(callback);
  255. return ERR_IO_PENDING;
  256. }
  257. int SocketPosix::CancelReadIfReady() {
  258. DCHECK(read_if_ready_callback_);
  259. bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
  260. DCHECK(ok);
  261. read_if_ready_callback_.Reset();
  262. return net::OK;
  263. }
  264. int SocketPosix::Write(
  265. IOBuffer* buf,
  266. int buf_len,
  267. CompletionOnceCallback callback,
  268. const NetworkTrafficAnnotationTag& /* traffic_annotation */) {
  269. DCHECK(thread_checker_.CalledOnValidThread());
  270. DCHECK_NE(kInvalidSocket, socket_fd_);
  271. DCHECK(!waiting_connect_);
  272. CHECK(write_callback_.is_null());
  273. // Synchronous operation not supported
  274. DCHECK(!callback.is_null());
  275. DCHECK_LT(0, buf_len);
  276. int rv = DoWrite(buf, buf_len);
  277. if (rv == ERR_IO_PENDING)
  278. rv = WaitForWrite(buf, buf_len, std::move(callback));
  279. return rv;
  280. }
  281. int SocketPosix::WaitForWrite(IOBuffer* buf,
  282. int buf_len,
  283. CompletionOnceCallback callback) {
  284. DCHECK(thread_checker_.CalledOnValidThread());
  285. DCHECK_NE(kInvalidSocket, socket_fd_);
  286. DCHECK(write_callback_.is_null());
  287. // Synchronous operation not supported
  288. DCHECK(!callback.is_null());
  289. DCHECK_LT(0, buf_len);
  290. if (!base::CurrentIOThread::Get()->WatchFileDescriptor(
  291. socket_fd_, true, base::MessagePumpForIO::WATCH_WRITE,
  292. &write_socket_watcher_, this)) {
  293. PLOG(ERROR) << "WatchFileDescriptor failed on write";
  294. return MapSystemError(errno);
  295. }
  296. write_buf_ = buf;
  297. write_buf_len_ = buf_len;
  298. write_callback_ = std::move(callback);
  299. return ERR_IO_PENDING;
  300. }
  301. int SocketPosix::GetLocalAddress(SockaddrStorage* address) const {
  302. DCHECK(thread_checker_.CalledOnValidThread());
  303. DCHECK(address);
  304. if (getsockname(socket_fd_, address->addr, &address->addr_len) < 0)
  305. return MapSystemError(errno);
  306. return OK;
  307. }
  308. int SocketPosix::GetPeerAddress(SockaddrStorage* address) const {
  309. DCHECK(thread_checker_.CalledOnValidThread());
  310. DCHECK(address);
  311. if (!HasPeerAddress())
  312. return ERR_SOCKET_NOT_CONNECTED;
  313. *address = *peer_address_;
  314. return OK;
  315. }
  316. void SocketPosix::SetPeerAddress(const SockaddrStorage& address) {
  317. DCHECK(thread_checker_.CalledOnValidThread());
  318. // |peer_address_| will be non-nullptr if Connect() has been called. Unless
  319. // Close() is called to reset the internal state, a second call to Connect()
  320. // is not allowed.
  321. // Please note that we don't allow a second Connect() even if the previous
  322. // Connect() has failed. Connecting the same |socket_| again after a
  323. // connection attempt failed results in unspecified behavior according to
  324. // POSIX.
  325. DCHECK(!peer_address_);
  326. peer_address_ = std::make_unique<SockaddrStorage>(address);
  327. }
  328. bool SocketPosix::HasPeerAddress() const {
  329. DCHECK(thread_checker_.CalledOnValidThread());
  330. return peer_address_ != nullptr;
  331. }
  332. void SocketPosix::Close() {
  333. DCHECK(thread_checker_.CalledOnValidThread());
  334. StopWatchingAndCleanUp(true /* close_socket */);
  335. }
  336. void SocketPosix::DetachFromThread() {
  337. thread_checker_.DetachFromThread();
  338. }
  339. void SocketPosix::OnFileCanReadWithoutBlocking(int fd) {
  340. TRACE_EVENT0(NetTracingCategory(),
  341. "SocketPosix::OnFileCanReadWithoutBlocking");
  342. if (!accept_callback_.is_null()) {
  343. AcceptCompleted();
  344. } else {
  345. DCHECK(!read_if_ready_callback_.is_null());
  346. ReadCompleted();
  347. }
  348. }
  349. void SocketPosix::OnFileCanWriteWithoutBlocking(int fd) {
  350. DCHECK(!write_callback_.is_null());
  351. if (waiting_connect_) {
  352. ConnectCompleted();
  353. } else {
  354. WriteCompleted();
  355. }
  356. }
  357. int SocketPosix::DoAccept(std::unique_ptr<SocketPosix>* socket) {
  358. SockaddrStorage new_peer_address;
  359. int new_socket = HANDLE_EINTR(accept(socket_fd_,
  360. new_peer_address.addr,
  361. &new_peer_address.addr_len));
  362. if (new_socket < 0)
  363. return MapAcceptError(errno);
  364. auto accepted_socket = std::make_unique<SocketPosix>();
  365. int rv = accepted_socket->AdoptConnectedSocket(new_socket, new_peer_address);
  366. if (rv != OK)
  367. return rv;
  368. *socket = std::move(accepted_socket);
  369. return OK;
  370. }
  371. void SocketPosix::AcceptCompleted() {
  372. DCHECK(accept_socket_);
  373. int rv = DoAccept(accept_socket_);
  374. if (rv == ERR_IO_PENDING)
  375. return;
  376. bool ok = accept_socket_watcher_.StopWatchingFileDescriptor();
  377. DCHECK(ok);
  378. accept_socket_ = nullptr;
  379. std::move(accept_callback_).Run(rv);
  380. }
  381. int SocketPosix::DoConnect() {
  382. int rv = HANDLE_EINTR(connect(socket_fd_,
  383. peer_address_->addr,
  384. peer_address_->addr_len));
  385. DCHECK_GE(0, rv);
  386. return rv == 0 ? OK : MapConnectError(errno);
  387. }
  388. void SocketPosix::ConnectCompleted() {
  389. // Get the error that connect() completed with.
  390. int os_error = 0;
  391. socklen_t len = sizeof(os_error);
  392. if (getsockopt(socket_fd_, SOL_SOCKET, SO_ERROR, &os_error, &len) == 0) {
  393. // TCPSocketPosix expects errno to be set.
  394. errno = os_error;
  395. }
  396. int rv = MapConnectError(errno);
  397. if (rv == ERR_IO_PENDING)
  398. return;
  399. bool ok = write_socket_watcher_.StopWatchingFileDescriptor();
  400. DCHECK(ok);
  401. waiting_connect_ = false;
  402. std::move(write_callback_).Run(rv);
  403. }
  404. int SocketPosix::DoRead(IOBuffer* buf, int buf_len) {
  405. int rv = HANDLE_EINTR(read(socket_fd_, buf->data(), buf_len));
  406. return rv >= 0 ? rv : MapSystemError(errno);
  407. }
  408. void SocketPosix::RetryRead(int rv) {
  409. DCHECK(read_callback_);
  410. DCHECK(read_buf_);
  411. DCHECK_LT(0, read_buf_len_);
  412. if (rv == OK) {
  413. rv = ReadIfReady(
  414. read_buf_.get(), read_buf_len_,
  415. base::BindOnce(&SocketPosix::RetryRead, base::Unretained(this)));
  416. if (rv == ERR_IO_PENDING)
  417. return;
  418. }
  419. read_buf_ = nullptr;
  420. read_buf_len_ = 0;
  421. std::move(read_callback_).Run(rv);
  422. }
  423. void SocketPosix::ReadCompleted() {
  424. DCHECK(read_if_ready_callback_);
  425. bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
  426. DCHECK(ok);
  427. std::move(read_if_ready_callback_).Run(OK);
  428. }
  429. int SocketPosix::DoWrite(IOBuffer* buf, int buf_len) {
  430. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
  431. // Disable SIGPIPE for this write. Although Chromium globally disables
  432. // SIGPIPE, the net stack may be used in other consumers which do not do
  433. // this. MSG_NOSIGNAL is a Linux-only API. On OS X, this is a setsockopt on
  434. // socket creation.
  435. int rv = HANDLE_EINTR(send(socket_fd_, buf->data(), buf_len, MSG_NOSIGNAL));
  436. #else
  437. int rv = HANDLE_EINTR(write(socket_fd_, buf->data(), buf_len));
  438. #endif
  439. return rv >= 0 ? rv : MapSystemError(errno);
  440. }
  441. void SocketPosix::WriteCompleted() {
  442. int rv = DoWrite(write_buf_.get(), write_buf_len_);
  443. if (rv == ERR_IO_PENDING)
  444. return;
  445. bool ok = write_socket_watcher_.StopWatchingFileDescriptor();
  446. DCHECK(ok);
  447. write_buf_.reset();
  448. write_buf_len_ = 0;
  449. std::move(write_callback_).Run(rv);
  450. }
  451. void SocketPosix::StopWatchingAndCleanUp(bool close_socket) {
  452. bool ok = accept_socket_watcher_.StopWatchingFileDescriptor();
  453. DCHECK(ok);
  454. ok = read_socket_watcher_.StopWatchingFileDescriptor();
  455. DCHECK(ok);
  456. ok = write_socket_watcher_.StopWatchingFileDescriptor();
  457. DCHECK(ok);
  458. // These needs to be done after the StopWatchingFileDescriptor() calls, but
  459. // before deleting the write buffer.
  460. if (close_socket) {
  461. if (socket_fd_ != kInvalidSocket) {
  462. if (IGNORE_EINTR(close(socket_fd_)) < 0)
  463. DPLOG(ERROR) << "close() failed";
  464. socket_fd_ = kInvalidSocket;
  465. }
  466. }
  467. if (!accept_callback_.is_null()) {
  468. accept_socket_ = nullptr;
  469. accept_callback_.Reset();
  470. }
  471. if (!read_callback_.is_null()) {
  472. read_buf_.reset();
  473. read_buf_len_ = 0;
  474. read_callback_.Reset();
  475. }
  476. read_if_ready_callback_.Reset();
  477. if (!write_callback_.is_null()) {
  478. write_buf_.reset();
  479. write_buf_len_ = 0;
  480. write_callback_.Reset();
  481. }
  482. waiting_connect_ = false;
  483. peer_address_.reset();
  484. }
  485. } // namespace net