Socket.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "util/platform/Socket.h"
  16. #ifdef win32
  17. #include <winsock2.h>
  18. #else
  19. #include <sys/socket.h>
  20. #endif
  21. #include <unistd.h>
  22. #include <fcntl.h>
  23. #ifdef win32
  24. #define SIGNED_IF_WIN32_uint32_t int32_t
  25. #else
  26. #define SIGNED_IF_WIN32_uint32_t uint32_t
  27. #endif
  28. const int Socket_AF_INET = AF_INET;
  29. const int Socket_AF_INET6 = AF_INET6;
  30. const int Socket_SOCK_DGRAM = SOCK_DGRAM;
  31. const int Socket_SOCK_STREAM = SOCK_STREAM;
  32. int Socket_makeNonBlocking(int sock)
  33. {
  34. #ifdef win32
  35. u_long one = 1;
  36. return ioctlsocket(sock, FIONBIO, &one);
  37. #else
  38. int flags;
  39. if ((flags = fcntl(sock, F_GETFL, NULL)) < 0) {
  40. return -1;
  41. }
  42. return (fcntl(sock, F_SETFL, flags | O_NONBLOCK) != -1);
  43. #endif
  44. }
  45. int Socket_makeReusable(int sock)
  46. {
  47. #ifndef win32
  48. int one = 1;
  49. return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
  50. #else
  51. return 0;
  52. #endif
  53. }
  54. int Socket_close(int sock)
  55. {
  56. #ifdef win32
  57. return closesocket(sock);
  58. #else
  59. return close(sock);
  60. #endif
  61. }
  62. int Socket_recv(int sockfd, void* buff, unsigned long bufferSize, int flags)
  63. {
  64. return (int) recv(sockfd, buff, bufferSize, flags);
  65. }
  66. int Socket_recvfrom(int fd,
  67. void* buff,
  68. unsigned long bufferSize,
  69. int flags,
  70. struct Sockaddr_storage* ss)
  71. {
  72. SIGNED_IF_WIN32_uint32_t size = Sockaddr_MAXSIZE;
  73. int ret = recvfrom(fd, buff, bufferSize, flags, (struct sockaddr*)ss->nativeAddr, &size);
  74. if (ret > -1) {
  75. #ifdef Darwin
  76. ((struct sockaddr*)ss->nativeAddr)->sa_len = 0;
  77. #endif
  78. ss->addr.addrLen = size + Sockaddr_OVERHEAD;
  79. }
  80. return ret;
  81. }
  82. static int closeSock(struct Allocator_OnFreeJob* j)
  83. {
  84. Socket_close((int)(uintptr_t)j->userData);
  85. return 0;
  86. }
  87. int Socket_connect(int fd, const struct Sockaddr* sa, struct Allocator* alloc)
  88. {
  89. int out = connect(fd, Sockaddr_asNativeConst(sa), sa->addrLen - Sockaddr_OVERHEAD);
  90. if (out > -1) {
  91. Allocator_onFree(alloc, closeSock, (void*)(intptr_t)out);
  92. }
  93. return out;
  94. }
  95. int Socket_socket(int af, int type, int protocol, struct Allocator* alloc)
  96. {
  97. int out = socket(af, type, protocol);
  98. if (out > -1) {
  99. Allocator_onFree(alloc, closeSock, (void*)(intptr_t)out);
  100. }
  101. return out;
  102. }
  103. int Socket_bind(int fd, const struct Sockaddr* sa)
  104. {
  105. return bind(fd, Sockaddr_asNativeConst(sa), sa->addrLen - Sockaddr_OVERHEAD);
  106. }
  107. int Socket_send(int socket, const void *buffer, unsigned long length, int flags)
  108. {
  109. return (int) send(socket, buffer, length, flags);
  110. }
  111. int Socket_sendto(int fd,
  112. const void* buffer,
  113. unsigned long len,
  114. int flags,
  115. const struct Sockaddr* dest)
  116. {
  117. return (int) sendto(fd,
  118. buffer,
  119. len,
  120. flags,
  121. Sockaddr_asNativeConst(dest),
  122. dest->addrLen - Sockaddr_OVERHEAD);
  123. }
  124. int Socket_accept(int sock, struct Sockaddr_storage* addrOut, struct Allocator* alloc)
  125. {
  126. SIGNED_IF_WIN32_uint32_t len = sizeof(addrOut->nativeAddr);
  127. int fd = accept(sock, (struct sockaddr*) addrOut->nativeAddr, &len);
  128. if (fd > -1) {
  129. addrOut->addr.addrLen = len + Sockaddr_OVERHEAD;
  130. Allocator_onFree(alloc, closeSock, (void*)(intptr_t)fd);
  131. #ifdef Darwin
  132. ((struct sockaddr*)addrOut->nativeAddr)->sa_len = 0;
  133. #endif
  134. }
  135. return fd;
  136. }
  137. int Socket_getsockname(int sockfd, struct Sockaddr_storage* addr)
  138. {
  139. SIGNED_IF_WIN32_uint32_t len = sizeof(addr->nativeAddr);
  140. int ret = getsockname(sockfd, (struct sockaddr*) addr->nativeAddr, &len);
  141. if (!ret) {
  142. addr->addr.addrLen = len + Sockaddr_OVERHEAD;
  143. #ifdef Darwin
  144. ((struct sockaddr*)addr->nativeAddr)->sa_len = 0;
  145. #endif
  146. }
  147. return ret;
  148. }