socket_options.cc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // Copyright 2016 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_options.h"
  5. #include <cerrno>
  6. #include "build/build_config.h"
  7. #include "net/base/net_errors.h"
  8. #if BUILDFLAG(IS_WIN)
  9. #include <winsock2.h>
  10. #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  11. #include <netinet/in.h>
  12. #include <netinet/tcp.h>
  13. #include <sys/socket.h>
  14. #endif
  15. namespace net {
  16. int SetTCPNoDelay(SocketDescriptor fd, bool no_delay) {
  17. #if BUILDFLAG(IS_WIN)
  18. BOOL on = no_delay ? TRUE : FALSE;
  19. #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  20. int on = no_delay ? 1 : 0;
  21. #endif
  22. int rv = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
  23. reinterpret_cast<const char*>(&on), sizeof(on));
  24. return rv == -1 ? MapSystemError(errno) : OK;
  25. }
  26. int SetReuseAddr(SocketDescriptor fd, bool reuse) {
  27. // SO_REUSEADDR is useful for server sockets to bind to a recently unbound
  28. // port. When a socket is closed, the end point changes its state to TIME_WAIT
  29. // and wait for 2 MSL (maximum segment lifetime) to ensure the remote peer
  30. // acknowledges its closure. For server sockets, it is usually safe to
  31. // bind to a TIME_WAIT end point immediately, which is a widely adopted
  32. // behavior.
  33. //
  34. // Note that on *nix, SO_REUSEADDR does not enable the socket (which can be
  35. // either TCP or UDP) to bind to an end point that is already bound by another
  36. // socket. To do that one must set SO_REUSEPORT instead. This option is not
  37. // provided on Linux prior to 3.9.
  38. //
  39. // SO_REUSEPORT is provided in MacOS X and iOS.
  40. #if BUILDFLAG(IS_WIN)
  41. BOOL boolean_value = reuse ? TRUE : FALSE;
  42. #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  43. int boolean_value = reuse ? 1 : 0;
  44. #endif
  45. int rv = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
  46. reinterpret_cast<const char*>(&boolean_value),
  47. sizeof(boolean_value));
  48. return rv == -1 ? MapSystemError(errno) : OK;
  49. }
  50. int SetSocketReceiveBufferSize(SocketDescriptor fd, int32_t size) {
  51. int rv = setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
  52. reinterpret_cast<const char*>(&size), sizeof(size));
  53. #if BUILDFLAG(IS_WIN)
  54. int os_error = WSAGetLastError();
  55. #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  56. int os_error = errno;
  57. #endif
  58. int net_error = (rv == -1) ? MapSystemError(os_error) : OK;
  59. DCHECK(!rv) << "Could not set socket receive buffer size: " << net_error;
  60. return net_error;
  61. }
  62. int SetSocketSendBufferSize(SocketDescriptor fd, int32_t size) {
  63. int rv = setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
  64. reinterpret_cast<const char*>(&size), sizeof(size));
  65. #if BUILDFLAG(IS_WIN)
  66. int os_error = WSAGetLastError();
  67. #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  68. int os_error = errno;
  69. #endif
  70. int net_error = (rv == -1) ? MapSystemError(os_error) : OK;
  71. DCHECK(!rv) << "Could not set socket receive buffer size: " << net_error;
  72. return net_error;
  73. }
  74. } // namespace net