socket.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. #pragma once
  2. #include "init.h"
  3. #include <util/system/yassert.h>
  4. #include <util/system/defaults.h>
  5. #include <util/system/error.h>
  6. #include <util/stream/output.h>
  7. #include <util/stream/input.h>
  8. #include <util/generic/ptr.h>
  9. #include <util/generic/yexception.h>
  10. #include <util/generic/noncopyable.h>
  11. #include <util/datetime/base.h>
  12. #include <cerrno>
  13. #ifndef INET_ADDRSTRLEN
  14. #define INET_ADDRSTRLEN 16
  15. #endif
  16. #if defined(_unix_)
  17. #define get_host_error() h_errno
  18. #elif defined(_win_)
  19. #pragma comment(lib, "Ws2_32.lib")
  20. #if _WIN32_WINNT < 0x0600
  21. struct pollfd {
  22. SOCKET fd;
  23. short events;
  24. short revents;
  25. };
  26. #define POLLIN (1 << 0)
  27. #define POLLRDNORM (1 << 1)
  28. #define POLLRDBAND (1 << 2)
  29. #define POLLPRI (1 << 3)
  30. #define POLLOUT (1 << 4)
  31. #define POLLWRNORM (1 << 5)
  32. #define POLLWRBAND (1 << 6)
  33. #define POLLERR (1 << 7)
  34. #define POLLHUP (1 << 8)
  35. #define POLLNVAL (1 << 9)
  36. const char* inet_ntop(int af, const void* src, char* dst, socklen_t size);
  37. int poll(struct pollfd fds[], nfds_t nfds, int timeout) noexcept;
  38. #else
  39. #define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout)
  40. #endif
  41. int inet_aton(const char* cp, struct in_addr* inp);
  42. #define get_host_error() WSAGetLastError()
  43. #define SHUT_RD SD_RECEIVE
  44. #define SHUT_WR SD_SEND
  45. #define SHUT_RDWR SD_BOTH
  46. #define INFTIM (-1)
  47. #endif
  48. template <class T>
  49. static inline int SetSockOpt(SOCKET s, int level, int optname, T opt) noexcept {
  50. return setsockopt(s, level, optname, (const char*)&opt, sizeof(opt));
  51. }
  52. template <class T>
  53. static inline int GetSockOpt(SOCKET s, int level, int optname, T& opt) noexcept {
  54. socklen_t len = sizeof(opt);
  55. return getsockopt(s, level, optname, (char*)&opt, &len);
  56. }
  57. template <class T>
  58. static inline void CheckedSetSockOpt(SOCKET s, int level, int optname, T opt, const char* err) {
  59. if (SetSockOpt<T>(s, level, optname, opt)) {
  60. ythrow TSystemError() << "setsockopt() failed for " << err;
  61. }
  62. }
  63. template <class T>
  64. static inline void CheckedGetSockOpt(SOCKET s, int level, int optname, T& opt, const char* err) {
  65. if (GetSockOpt<T>(s, level, optname, opt)) {
  66. ythrow TSystemError() << "getsockopt() failed for " << err;
  67. }
  68. }
  69. static inline void FixIPv6ListenSocket(SOCKET s) {
  70. #if defined(IPV6_V6ONLY)
  71. SetSockOpt(s, IPPROTO_IPV6, IPV6_V6ONLY, 1);
  72. #else
  73. (void)s;
  74. #endif
  75. }
  76. namespace NAddr {
  77. class IRemoteAddr;
  78. }
  79. void SetSocketTimeout(SOCKET s, long timeout);
  80. void SetSocketTimeout(SOCKET s, long sec, long msec);
  81. void SetNoDelay(SOCKET s, bool value);
  82. void SetKeepAlive(SOCKET s);
  83. void SetLinger(SOCKET s, bool on, unsigned len);
  84. void SetZeroLinger(SOCKET s);
  85. void SetKeepAlive(SOCKET s, bool value);
  86. void SetCloseOnExec(SOCKET s, bool value);
  87. void SetOutputBuffer(SOCKET s, unsigned value);
  88. void SetInputBuffer(SOCKET s, unsigned value);
  89. void SetReusePort(SOCKET s, bool value);
  90. void ShutDown(SOCKET s, int mode);
  91. bool GetRemoteAddr(SOCKET s, char* str, socklen_t size);
  92. size_t GetMaximumSegmentSize(SOCKET s);
  93. size_t GetMaximumTransferUnit(SOCKET s);
  94. void SetDeferAccept(SOCKET s);
  95. void SetSocketToS(SOCKET s, int tos);
  96. void SetSocketToS(SOCKET s, const NAddr::IRemoteAddr* addr, int tos);
  97. int GetSocketToS(SOCKET s);
  98. int GetSocketToS(SOCKET s, const NAddr::IRemoteAddr* addr);
  99. void SetSocketPriority(SOCKET s, int priority);
  100. void SetTcpFastOpen(SOCKET s, int qlen);
  101. /**
  102. * Deprecated, consider using HasSocketDataToRead instead.
  103. **/
  104. bool IsNotSocketClosedByOtherSide(SOCKET s);
  105. enum class ESocketReadStatus {
  106. HasData,
  107. NoData,
  108. SocketClosed
  109. };
  110. /**
  111. * Useful for keep-alive connections.
  112. **/
  113. ESocketReadStatus HasSocketDataToRead(SOCKET s);
  114. /**
  115. * Determines whether connection on socket is local (same machine) or not.
  116. **/
  117. bool HasLocalAddress(SOCKET socket);
  118. bool IsNonBlock(SOCKET fd);
  119. void SetNonBlock(SOCKET fd, bool nonBlock = true);
  120. struct addrinfo;
  121. class TNetworkResolutionError: public yexception {
  122. public:
  123. // @param error error code (EAI_XXX) returned by getaddrinfo or getnameinfo (not errno)
  124. TNetworkResolutionError(int error);
  125. };
  126. struct TUnixSocketPath {
  127. TString Path;
  128. // Constructor for create unix domain socket path from string with path in filesystem
  129. // TUnixSocketPath("/tmp/unixsocket") -> "/tmp/unixsocket"
  130. explicit TUnixSocketPath(const TString& path)
  131. : Path(path)
  132. {
  133. }
  134. };
  135. class TNetworkAddress {
  136. friend class TSocket;
  137. public:
  138. class TIterator {
  139. public:
  140. inline TIterator(struct addrinfo* begin)
  141. : C_(begin)
  142. {
  143. }
  144. inline void Next() noexcept {
  145. C_ = C_->ai_next;
  146. }
  147. inline TIterator operator++(int) noexcept {
  148. TIterator old(*this);
  149. Next();
  150. return old;
  151. }
  152. inline TIterator& operator++() noexcept {
  153. Next();
  154. return *this;
  155. }
  156. friend inline bool operator==(const TIterator& l, const TIterator& r) noexcept {
  157. return l.C_ == r.C_;
  158. }
  159. friend inline bool operator!=(const TIterator& l, const TIterator& r) noexcept {
  160. return !(l == r);
  161. }
  162. inline struct addrinfo& operator*() const noexcept {
  163. return *C_;
  164. }
  165. inline struct addrinfo* operator->() const noexcept {
  166. return C_;
  167. }
  168. private:
  169. struct addrinfo* C_;
  170. };
  171. TNetworkAddress(ui16 port);
  172. TNetworkAddress(const TString& host, ui16 port);
  173. TNetworkAddress(const TString& host, ui16 port, int flags);
  174. TNetworkAddress(const TUnixSocketPath& unixSocketPath, int flags = 0);
  175. ~TNetworkAddress();
  176. inline TIterator Begin() const noexcept {
  177. return TIterator(Info());
  178. }
  179. inline TIterator End() const noexcept {
  180. return TIterator(nullptr);
  181. }
  182. private:
  183. struct addrinfo* Info() const noexcept;
  184. private:
  185. class TImpl;
  186. TSimpleIntrusivePtr<TImpl> Impl_;
  187. };
  188. class TSocket;
  189. class TSocketHolder: public TMoveOnly {
  190. public:
  191. inline TSocketHolder()
  192. : Fd_(INVALID_SOCKET)
  193. {
  194. }
  195. inline TSocketHolder(SOCKET fd)
  196. : Fd_(fd)
  197. {
  198. }
  199. inline TSocketHolder(TSocketHolder&& other) noexcept {
  200. Fd_ = other.Fd_;
  201. other.Fd_ = INVALID_SOCKET;
  202. }
  203. inline TSocketHolder& operator=(TSocketHolder&& other) noexcept {
  204. Close();
  205. Swap(other);
  206. return *this;
  207. }
  208. inline ~TSocketHolder() {
  209. Close();
  210. }
  211. inline SOCKET Release() noexcept {
  212. SOCKET ret = Fd_;
  213. Fd_ = INVALID_SOCKET;
  214. return ret;
  215. }
  216. void Close() noexcept;
  217. inline void ShutDown(int mode) const {
  218. ::ShutDown(Fd_, mode);
  219. }
  220. inline void Swap(TSocketHolder& r) noexcept {
  221. DoSwap(Fd_, r.Fd_);
  222. }
  223. inline bool Closed() const noexcept {
  224. return Fd_ == INVALID_SOCKET;
  225. }
  226. inline operator SOCKET() const noexcept {
  227. return Fd_;
  228. }
  229. private:
  230. SOCKET Fd_;
  231. // do not allow construction of TSocketHolder from TSocket
  232. TSocketHolder(const TSocket& fd);
  233. };
  234. class TSocket {
  235. public:
  236. using TPart = IOutputStream::TPart;
  237. class TOps {
  238. public:
  239. inline TOps() noexcept = default;
  240. virtual ~TOps() = default;
  241. virtual ssize_t Send(SOCKET fd, const void* data, size_t len) = 0;
  242. virtual ssize_t Recv(SOCKET fd, void* buf, size_t len) = 0;
  243. virtual ssize_t SendV(SOCKET fd, const TPart* parts, size_t count) = 0;
  244. };
  245. TSocket();
  246. TSocket(SOCKET fd);
  247. TSocket(SOCKET fd, TOps* ops);
  248. TSocket(const TNetworkAddress& addr);
  249. TSocket(const TNetworkAddress& addr, const TDuration& timeOut);
  250. TSocket(const TNetworkAddress& addr, const TInstant& deadLine);
  251. ~TSocket();
  252. template <class T>
  253. inline void SetSockOpt(int level, int optname, T opt) {
  254. CheckedSetSockOpt(Fd(), level, optname, opt, "TSocket");
  255. }
  256. inline void SetSocketTimeout(long timeout) {
  257. ::SetSocketTimeout(Fd(), timeout);
  258. }
  259. inline void SetSocketTimeout(long sec, long msec) {
  260. ::SetSocketTimeout(Fd(), sec, msec);
  261. }
  262. inline void SetNoDelay(bool value) {
  263. ::SetNoDelay(Fd(), value);
  264. }
  265. inline void SetLinger(bool on, unsigned len) {
  266. ::SetLinger(Fd(), on, len);
  267. }
  268. inline void SetZeroLinger() {
  269. ::SetZeroLinger(Fd());
  270. }
  271. inline void SetKeepAlive(bool value) {
  272. ::SetKeepAlive(Fd(), value);
  273. }
  274. inline void SetOutputBuffer(unsigned value) {
  275. ::SetOutputBuffer(Fd(), value);
  276. }
  277. inline void SetInputBuffer(unsigned value) {
  278. ::SetInputBuffer(Fd(), value);
  279. }
  280. inline size_t MaximumSegmentSize() const {
  281. return GetMaximumSegmentSize(Fd());
  282. }
  283. inline size_t MaximumTransferUnit() const {
  284. return GetMaximumTransferUnit(Fd());
  285. }
  286. inline void ShutDown(int mode) const {
  287. ::ShutDown(Fd(), mode);
  288. }
  289. void Close();
  290. ssize_t Send(const void* data, size_t len);
  291. ssize_t Recv(void* buf, size_t len);
  292. /*
  293. * scatter/gather io
  294. */
  295. ssize_t SendV(const TPart* parts, size_t count);
  296. inline operator SOCKET() const noexcept {
  297. return Fd();
  298. }
  299. private:
  300. SOCKET Fd() const noexcept;
  301. private:
  302. class TImpl;
  303. TSimpleIntrusivePtr<TImpl> Impl_;
  304. };
  305. class TSocketInput: public IInputStream {
  306. public:
  307. TSocketInput(const TSocket& s) noexcept;
  308. ~TSocketInput() override;
  309. TSocketInput(TSocketInput&&) noexcept = default;
  310. TSocketInput& operator=(TSocketInput&&) noexcept = default;
  311. const TSocket& GetSocket() const noexcept {
  312. return S_;
  313. }
  314. private:
  315. size_t DoRead(void* buf, size_t len) override;
  316. private:
  317. TSocket S_;
  318. };
  319. class TSocketOutput: public IOutputStream {
  320. public:
  321. TSocketOutput(const TSocket& s) noexcept;
  322. ~TSocketOutput() override;
  323. TSocketOutput(TSocketOutput&&) noexcept = default;
  324. TSocketOutput& operator=(TSocketOutput&&) noexcept = default;
  325. const TSocket& GetSocket() const noexcept {
  326. return S_;
  327. }
  328. private:
  329. void DoWrite(const void* buf, size_t len) override;
  330. void DoWriteV(const TPart* parts, size_t count) override;
  331. private:
  332. TSocket S_;
  333. };
  334. //return -(error code) if error occured, or number of ready fds
  335. ssize_t PollD(struct pollfd fds[], nfds_t nfds, const TInstant& deadLine) noexcept;