ks_socket.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148
  1. /*
  2. * Copyright (c) 2018-2023 SignalWire, Inc
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. /* Use select on windows and poll everywhere else.
  23. Select is the devil. Especially if you are doing a lot of small socket connections.
  24. If your FD number is bigger than 1024 you will silently create memory corruption.
  25. If you have build errors on your platform because you don't have poll find a way to detect it and #define KS_USE_SELECT and #undef KS_USE_POLL
  26. All of this will be upgraded to autoheadache eventually.
  27. */
  28. /* TBD for win32 figure out how to tell if you have WSAPoll (vista or higher) and use it when available by #defining KS_USE_WSAPOLL (see below) */
  29. #ifdef _MSC_VER
  30. #ifndef FD_SETSIZE
  31. #define FD_SETSIZE 8192
  32. #endif
  33. //#define KS_USE_SELECT
  34. #else
  35. #define KS_USE_POLL
  36. #endif
  37. #include "libks/ks.h"
  38. #ifndef WIN32
  39. #define closesocket(s) close(s)
  40. #else /* WIN32 */
  41. #pragma warning (disable:6386)
  42. /* These warnings need to be ignored warning in sdk header */
  43. #include <Ws2tcpip.h>
  44. #include <windows.h>
  45. #pragma comment(lib, "Ws2_32.lib")
  46. #ifndef errno
  47. #define errno WSAGetLastError()
  48. #endif
  49. #ifndef EINTR
  50. #define EINTR WSAEINTR
  51. #endif
  52. #pragma warning (default:6386)
  53. #endif /* WIN32 */
  54. #ifndef SOL_IPV6
  55. #define SOL_IPV6 41
  56. #endif
  57. #ifdef KS_USE_POLL
  58. #include <poll.h>
  59. #endif
  60. KS_DECLARE(ks_status_t) ks_socket_option(ks_socket_t socket, int option_name, ks_bool_t enabled)
  61. {
  62. int result = -1;
  63. ks_status_t status = KS_STATUS_FAIL;
  64. #ifdef WIN32
  65. BOOL opt = TRUE;
  66. if (!enabled) opt = FALSE;
  67. #else
  68. int opt = 1;
  69. if (!enabled) opt = 0;
  70. #endif
  71. switch(option_name) {
  72. case SO_REUSEADDR:
  73. case TCP_NODELAY:
  74. case SO_KEEPALIVE:
  75. case SO_LINGER:
  76. #ifdef KS_KEEP_IDLE_INTVL
  77. #ifndef __APPLE__
  78. case TCP_KEEPIDLE:
  79. case TCP_KEEPINTVL:
  80. #endif
  81. #endif /* KS_KEEP_IDLE_INTVL */
  82. #ifdef WIN32
  83. result = setsockopt(socket, SOL_SOCKET, option_name, (char *) &opt, sizeof(opt));
  84. #else
  85. result = setsockopt(socket, SOL_SOCKET, option_name, &opt, sizeof(opt));
  86. #endif
  87. if (!result) status = KS_STATUS_SUCCESS;
  88. break;
  89. case KS_SO_NONBLOCK:
  90. {
  91. #ifdef WIN32
  92. u_long val = (u_long)!!opt;
  93. if (ioctlsocket(socket, FIONBIO, &val) != SOCKET_ERROR) {
  94. status = KS_STATUS_SUCCESS;
  95. }
  96. #else
  97. int flags = fcntl(socket, F_GETFL, 0);
  98. if (opt) {
  99. flags |= O_NONBLOCK;
  100. } else {
  101. flags &= ~O_NONBLOCK;
  102. }
  103. if (fcntl(socket, F_SETFL, flags) != -1) {
  104. status = KS_STATUS_SUCCESS;
  105. }
  106. #endif
  107. }
  108. break;
  109. case IPV6_V6ONLY:
  110. #ifdef WIN32
  111. //#warning make sure windows works like linux for IPV6 to IPV4 automapping stuff
  112. result = setsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, sizeof(opt));
  113. #else
  114. result = setsockopt(socket, SOL_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
  115. #endif
  116. if (!result) status = KS_STATUS_SUCCESS;
  117. break;
  118. default:
  119. break;
  120. }
  121. return status;
  122. }
  123. KS_DECLARE(ks_status_t) ks_socket_sndbuf(ks_socket_t socket, int bufsize)
  124. {
  125. int result;
  126. ks_status_t status = KS_STATUS_FAIL;
  127. #ifdef WIN32
  128. result = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *) &bufsize, sizeof(bufsize));
  129. #else
  130. result = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize));
  131. #endif
  132. if (!result) status = KS_STATUS_SUCCESS;
  133. return status;
  134. }
  135. KS_DECLARE(ks_status_t) ks_socket_rcvbuf(ks_socket_t socket, int bufsize)
  136. {
  137. int result;
  138. ks_status_t status = KS_STATUS_FAIL;
  139. #ifdef WIN32
  140. result = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *) &bufsize, sizeof(bufsize));
  141. #else
  142. result = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize));
  143. #endif
  144. if (!result) status = KS_STATUS_SUCCESS;
  145. return status;
  146. }
  147. static int ks_socket_reuseaddr(ks_socket_t socket)
  148. {
  149. #ifdef WIN32
  150. BOOL reuse_addr = TRUE;
  151. return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse_addr, sizeof(reuse_addr));
  152. #else
  153. int reuse_addr = 1;
  154. return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));
  155. #endif
  156. }
  157. KS_DECLARE(ks_status_t) ks_socket_shutdown(ks_socket_t sock, int how)
  158. {
  159. return shutdown(sock, how) ? KS_STATUS_FAIL : KS_STATUS_SUCCESS;
  160. }
  161. KS_DECLARE(ks_status_t) ks_socket_close(ks_socket_t *sock)
  162. {
  163. ks_assert(sock);
  164. if (*sock != KS_SOCK_INVALID) {
  165. closesocket(*sock);
  166. *sock = KS_SOCK_INVALID;
  167. return KS_STATUS_SUCCESS;
  168. }
  169. return KS_STATUS_FAIL;
  170. }
  171. KS_DECLARE(ks_socket_t) ks_socket_connect(int type, int protocol, ks_sockaddr_t *addr)
  172. {
  173. return ks_socket_connect_ex(type, protocol, addr, 0);
  174. }
  175. KS_DECLARE(ks_socket_t) ks_socket_connect_ex(int type, int protocol, ks_sockaddr_t *addr, uint32_t nb_timeout)
  176. {
  177. ks_socket_t sock = KS_SOCK_INVALID;
  178. int32_t poll_flags = 0;
  179. ks_assert(addr);
  180. ks_assert(addr->family == AF_INET || addr->family == AF_INET6);
  181. if ((sock = socket(addr->family, type, protocol)) == KS_SOCK_INVALID) {
  182. return KS_SOCK_INVALID;
  183. }
  184. if (nb_timeout > 0) {
  185. if (ks_socket_option(sock, KS_SO_NONBLOCK, KS_TRUE) != KS_STATUS_SUCCESS) {
  186. ks_socket_close(&sock);
  187. return KS_SOCK_INVALID;
  188. }
  189. }
  190. if (addr->family == AF_INET) {
  191. if (connect(sock, (struct sockaddr *)&addr->v.v4, sizeof(addr->v.v4))) {
  192. if (!ks_errno_is_blocking(ks_errno())) {
  193. ks_socket_close(&sock);
  194. return KS_SOCK_INVALID;
  195. }
  196. }
  197. }
  198. else {
  199. if (connect(sock, (struct sockaddr *)&addr->v.v6, sizeof(addr->v.v6))) {
  200. if (!ks_errno_is_blocking(ks_errno())) {
  201. ks_socket_close(&sock);
  202. return KS_SOCK_INVALID;
  203. }
  204. }
  205. }
  206. if (nb_timeout > 0) {
  207. poll_flags = ks_wait_sock(sock, nb_timeout, KS_POLL_READ | KS_POLL_WRITE);
  208. if (poll_flags & KS_POLL_ERROR) {
  209. ks_socket_close(&sock);
  210. return KS_SOCK_INVALID;
  211. }
  212. if (!(poll_flags & (KS_POLL_READ | KS_POLL_WRITE))) {
  213. ks_socket_close(&sock);
  214. return KS_SOCK_INVALID;
  215. }
  216. if (ks_socket_option(sock, KS_SO_NONBLOCK, KS_FALSE) != KS_STATUS_SUCCESS) {
  217. ks_socket_close(&sock);
  218. return KS_SOCK_INVALID;
  219. }
  220. }
  221. return sock;
  222. }
  223. KS_DECLARE(ks_status_t) ks_addr_bind(ks_socket_t server_sock, const ks_sockaddr_t *addr)
  224. {
  225. ks_status_t status = KS_STATUS_SUCCESS;
  226. ks_assert(addr);
  227. ks_assert(addr->family == AF_INET || addr->family == AF_INET6);
  228. if (addr->family == AF_INET) {
  229. if (bind(server_sock, (struct sockaddr *) &addr->v.v4, sizeof(addr->v.v4)) < 0) {
  230. status = KS_STATUS_FAIL;
  231. }
  232. } else {
  233. if (bind(server_sock, (struct sockaddr *) &addr->v.v6, sizeof(addr->v.v6)) < 0) {
  234. status = KS_STATUS_FAIL;
  235. }
  236. }
  237. return status;
  238. }
  239. KS_DECLARE(const char *) ks_addr_get_host(ks_sockaddr_t *addr)
  240. {
  241. ks_assert(addr);
  242. ks_assert(addr->family == AF_INET || addr->family == AF_INET6);
  243. if (addr->family == AF_INET) {
  244. inet_ntop(AF_INET, &addr->v.v4.sin_addr, addr->host, sizeof(addr->host));
  245. } else {
  246. inet_ntop(AF_INET6, &addr->v.v6.sin6_addr, addr->host, sizeof(addr->host));
  247. }
  248. return (const char *) addr->host;
  249. }
  250. KS_DECLARE(ks_port_t) ks_addr_get_port(ks_sockaddr_t *addr)
  251. {
  252. ks_assert(addr);
  253. ks_assert(addr->family == AF_INET || addr->family == AF_INET6);
  254. if (addr->family == AF_INET) {
  255. addr->port = ntohs(addr->v.v4.sin_port);
  256. } else {
  257. addr->port = ntohs(addr->v.v6.sin6_port);
  258. }
  259. return addr->port;
  260. }
  261. KS_DECLARE(int) ks_addr_cmp(const ks_sockaddr_t *sa1, const ks_sockaddr_t *sa2)
  262. {
  263. if (!(sa1 && sa2)) {
  264. return 0;
  265. }
  266. if (sa1->family != sa2->family) {
  267. return 0;
  268. }
  269. switch (sa1->family) {
  270. case AF_INET:
  271. return (sa1->v.v4.sin_addr.s_addr == sa2->v.v4.sin_addr.s_addr && sa1->v.v4.sin_port == sa2->v.v4.sin_port);
  272. case AF_INET6:
  273. {
  274. int i;
  275. if (sa1->v.v6.sin6_port != sa2->v.v6.sin6_port) {
  276. return 0;
  277. }
  278. for (i = 0; i < 4; i++) {
  279. if (*((int32_t *) &sa1->v.v6.sin6_addr + i) != *((int32_t *) &sa2->v.v6.sin6_addr + i)) {
  280. return 0;
  281. }
  282. }
  283. return 1;
  284. }
  285. }
  286. return 0;
  287. }
  288. KS_DECLARE(ks_status_t) ks_addr_copy(ks_sockaddr_t *addr, const ks_sockaddr_t *src_addr)
  289. {
  290. ks_status_t status = KS_STATUS_SUCCESS;
  291. ks_assert(addr);
  292. ks_assert(src_addr);
  293. ks_assert(src_addr->family == AF_INET || src_addr->family == AF_INET6);
  294. addr->family = src_addr->family;
  295. if (src_addr->family == AF_INET) {
  296. memcpy(&addr->v.v4, &src_addr->v.v4, sizeof(src_addr->v.v4));
  297. } else {
  298. memcpy(&addr->v.v6, &src_addr->v.v6, sizeof(src_addr->v.v6));
  299. }
  300. ks_addr_get_host(addr);
  301. ks_addr_get_port(addr);
  302. return status;
  303. }
  304. KS_DECLARE(ks_status_t) ks_addr_set(ks_sockaddr_t *addr, const char *host, ks_port_t port, int family)
  305. {
  306. ks_status_t status = KS_STATUS_SUCCESS;
  307. ks_assert(addr);
  308. if (family != PF_INET && family != PF_INET6) family = PF_INET;
  309. if (host && strchr(host, ':')) family = PF_INET6;
  310. memset(addr, 0, sizeof(*addr));
  311. if (family == PF_INET) {
  312. addr->family = AF_INET;
  313. addr->v.v4.sin_family = AF_INET;
  314. addr->v.v4.sin_addr.s_addr = host ? inet_addr(host): htonl(INADDR_ANY);
  315. addr->v.v4.sin_port = htons(port);
  316. } else {
  317. addr->family = AF_INET6;
  318. addr->v.v6.sin6_family = AF_INET6;
  319. addr->v.v6.sin6_port = htons(port);
  320. if (host) {
  321. inet_pton(AF_INET6, host, &(addr->v.v6.sin6_addr));
  322. } else {
  323. addr->v.v6.sin6_addr = in6addr_any;
  324. }
  325. }
  326. ks_addr_get_host(addr);
  327. ks_addr_get_port(addr);
  328. return status;
  329. }
  330. KS_DECLARE(ks_status_t) ks_addr_set_raw(ks_sockaddr_t *addr, const void *data, ks_port_t port, int family)
  331. {
  332. ks_status_t status = KS_STATUS_SUCCESS;
  333. ks_assert(addr);
  334. if (family != PF_INET && family != PF_INET6) family = PF_INET;
  335. memset(addr, 0, sizeof(*addr));
  336. if (family == PF_INET) {
  337. addr->family = AF_INET;
  338. addr->v.v4.sin_family = AF_INET;
  339. memcpy(&(addr->v.v4.sin_addr), data, 4);
  340. addr->v.v4.sin_port = htons(port);
  341. } else {
  342. addr->family = AF_INET6;
  343. addr->v.v6.sin6_family = AF_INET6;
  344. addr->v.v6.sin6_port = htons(port);
  345. memcpy(&(addr->v.v6.sin6_addr), data, 16);
  346. }
  347. ks_addr_get_host(addr);
  348. ks_addr_get_port(addr);
  349. return status;
  350. }
  351. KS_DECLARE(ks_status_t) ks_listen_sock(ks_socket_t server_sock, ks_sockaddr_t *addr, int backlog, ks_listen_callback_t callback, void *user_data)
  352. {
  353. ks_status_t status = KS_STATUS_SUCCESS;
  354. ks_socket_reuseaddr(server_sock);
  355. if (ks_addr_bind(server_sock, addr) != KS_STATUS_SUCCESS) {
  356. status = KS_STATUS_FAIL;
  357. goto end;
  358. }
  359. if (!backlog) backlog = 10000;
  360. if (listen(server_sock, backlog) < 0) {
  361. status = KS_STATUS_FAIL;
  362. goto end;
  363. }
  364. for (;;) {
  365. ks_socket_t client_sock;
  366. ks_sockaddr_t remote_addr = {0};
  367. socklen_t slen = 0;
  368. if (addr->family == PF_INET) {
  369. slen = sizeof(remote_addr.v.v4);
  370. if ((client_sock = accept(server_sock, (struct sockaddr *) &remote_addr.v.v4, &slen)) == KS_SOCK_INVALID) {
  371. status = KS_STATUS_FAIL;
  372. goto end;
  373. }
  374. remote_addr.family = AF_INET;
  375. } else {
  376. slen = sizeof(remote_addr.v.v6);
  377. if ((client_sock = accept(server_sock, (struct sockaddr *) &remote_addr.v.v6, &slen)) == KS_SOCK_INVALID) {
  378. status = KS_STATUS_FAIL;
  379. goto end;
  380. }
  381. remote_addr.family = AF_INET6;
  382. }
  383. ks_addr_get_host(&remote_addr);
  384. ks_addr_get_port(&remote_addr);
  385. callback(server_sock, client_sock, &remote_addr, user_data);
  386. }
  387. end:
  388. if (server_sock != KS_SOCK_INVALID) {
  389. ks_socket_shutdown(server_sock, 2);
  390. ks_socket_close(&server_sock);
  391. server_sock = KS_SOCK_INVALID;
  392. }
  393. return status;
  394. }
  395. KS_DECLARE(ks_status_t) ks_listen(const char *host, ks_port_t port, int family, int backlog, ks_listen_callback_t callback, void *user_data)
  396. {
  397. ks_socket_t server_sock = KS_SOCK_INVALID;
  398. ks_sockaddr_t addr = { 0 };
  399. if (family != PF_INET && family != PF_INET6) family = PF_INET;
  400. if (host && strchr(host, ':')) family = PF_INET6;
  401. if (ks_addr_set(&addr, host, port, family) != KS_STATUS_SUCCESS) {
  402. return KS_STATUS_FAIL;
  403. }
  404. if ((server_sock = socket(family, SOCK_STREAM, IPPROTO_TCP)) == KS_SOCK_INVALID) {
  405. return KS_STATUS_FAIL;
  406. }
  407. return ks_listen_sock(server_sock, &addr, backlog, callback, user_data);
  408. }
  409. KS_DECLARE(int) ks_poll(struct pollfd fds[], uint32_t nfds, int timeout)
  410. {
  411. #ifdef WIN32
  412. int ret = WSAPoll(fds, nfds, timeout);
  413. if (ret == SOCKET_ERROR) {
  414. ret = WSAGetLastError();
  415. }
  416. return ret;
  417. #else
  418. return poll(fds, nfds, timeout);
  419. #endif
  420. }
  421. #ifdef KS_USE_SELECT
  422. #ifdef WIN32
  423. #pragma warning( push )
  424. #pragma warning( disable : 6262 ) /* warning C6262: Function uses '98348' bytes of stack: exceeds /analyze:stacksize'16384'. Consider moving some data to heap */
  425. #endif
  426. KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags)
  427. {
  428. int s = 0, r = 0;
  429. fd_set rfds;
  430. fd_set wfds;
  431. fd_set efds;
  432. struct timeval tv;
  433. if (sock == KS_SOCK_INVALID) {
  434. return KS_POLL_INVALID;
  435. }
  436. FD_ZERO(&rfds);
  437. FD_ZERO(&wfds);
  438. FD_ZERO(&efds);
  439. #ifndef WIN32
  440. /* Wouldn't you rather know?? */
  441. assert(sock <= FD_SETSIZE);
  442. #endif
  443. if ((flags & KS_POLL_READ)) {
  444. #ifdef WIN32
  445. #pragma warning( push )
  446. #pragma warning( disable : 4127 )
  447. #pragma warning( disable : 4548 )
  448. FD_SET(sock, &rfds);
  449. #pragma warning( pop )
  450. #else
  451. FD_SET(sock, &rfds);
  452. #endif
  453. }
  454. if ((flags & KS_POLL_WRITE)) {
  455. #ifdef WIN32
  456. #pragma warning( push )
  457. #pragma warning( disable : 4127 )
  458. #pragma warning( disable : 4548 )
  459. FD_SET(sock, &wfds);
  460. #pragma warning( pop )
  461. #else
  462. FD_SET(sock, &wfds);
  463. #endif
  464. }
  465. if ((flags & KS_POLL_ERROR)) {
  466. #ifdef WIN32
  467. #pragma warning( push )
  468. #pragma warning( disable : 4127 )
  469. #pragma warning( disable : 4548 )
  470. FD_SET(sock, &efds);
  471. #pragma warning( pop )
  472. #else
  473. FD_SET(sock, &efds);
  474. #endif
  475. }
  476. tv.tv_sec = ms / 1000;
  477. tv.tv_usec = (ms % 1000) * ms;
  478. s = select((int)sock + 1, (flags & KS_POLL_READ) ? &rfds : NULL, (flags & KS_POLL_WRITE) ? &wfds : NULL, (flags & KS_POLL_ERROR) ? &efds : NULL, &tv);
  479. if (s < 0) {
  480. r = s;
  481. } else if (s > 0) {
  482. if ((flags & KS_POLL_READ) && FD_ISSET(sock, &rfds)) {
  483. r |= KS_POLL_READ;
  484. }
  485. if ((flags & KS_POLL_WRITE) && FD_ISSET(sock, &wfds)) {
  486. r |= KS_POLL_WRITE;
  487. }
  488. if ((flags & KS_POLL_ERROR) && FD_ISSET(sock, &efds)) {
  489. r |= KS_POLL_ERROR;
  490. }
  491. }
  492. return r;
  493. }
  494. #ifdef WIN32
  495. #pragma warning( pop )
  496. #endif
  497. #endif
  498. #if defined(KS_USE_POLL) || defined(WIN32)
  499. KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags)
  500. {
  501. struct pollfd pfds[2] = { {0} };
  502. int s = 0, r = 0;
  503. if (sock == KS_SOCK_INVALID) {
  504. return KS_POLL_INVALID;
  505. }
  506. pfds[0].fd = sock;
  507. if ((flags & KS_POLL_READ)) {
  508. pfds[0].events |= POLLIN;
  509. }
  510. if ((flags & KS_POLL_WRITE)) {
  511. pfds[0].events |= POLLOUT;
  512. }
  513. if ((flags & KS_POLL_RDNORM)) {
  514. pfds[0].events |= POLLRDNORM;
  515. }
  516. if ((flags & KS_POLL_RDBAND)) {
  517. pfds[0].events |= POLLRDBAND;
  518. }
  519. if ((flags & KS_POLL_PRI)) {
  520. pfds[0].events |= POLLPRI;
  521. }
  522. s = ks_poll(pfds, 1, ms);
  523. if (s < 0) {
  524. r = s;
  525. } else if (s > 0) {
  526. if ((pfds[0].revents & POLLIN)) {
  527. r |= KS_POLL_READ;
  528. }
  529. if ((pfds[0].revents & POLLOUT)) {
  530. r |= KS_POLL_WRITE;
  531. }
  532. if ((pfds[0].revents & POLLERR)) {
  533. r |= KS_POLL_ERROR;
  534. }
  535. if ((pfds[0].revents & POLLHUP)) {
  536. r |= KS_POLL_HUP;
  537. }
  538. if ((pfds[0].revents & POLLRDNORM)) {
  539. r |= KS_POLL_RDNORM;
  540. }
  541. if ((pfds[0].revents & POLLRDBAND)) {
  542. r |= KS_POLL_RDBAND;
  543. }
  544. if ((pfds[0].revents & POLLPRI)) {
  545. r |= KS_POLL_PRI;
  546. }
  547. if ((pfds[0].revents & POLLNVAL)) {
  548. r |= KS_POLL_INVALID;
  549. }
  550. }
  551. return r;
  552. }
  553. #endif
  554. #ifdef HAVE_GETIFADDRS
  555. #include <ifaddrs.h>
  556. static int get_netmask(struct sockaddr_in *me, int *mask)
  557. {
  558. struct ifaddrs *ifaddrs, *i = NULL;
  559. if (!me || getifaddrs(&ifaddrs) < 0) {
  560. return -1;
  561. }
  562. for (i = ifaddrs; i; i = i->ifa_next) {
  563. struct sockaddr_in *s = (struct sockaddr_in *) i->ifa_addr;
  564. struct sockaddr_in *m = (struct sockaddr_in *) i->ifa_netmask;
  565. if (s && m && s->sin_family == AF_INET && s->sin_addr.s_addr == me->sin_addr.s_addr) {
  566. *mask = m->sin_addr.s_addr;
  567. freeifaddrs(ifaddrs);
  568. return 0;
  569. }
  570. }
  571. freeifaddrs(ifaddrs);
  572. return -2;
  573. }
  574. #elif defined(__linux__)
  575. #include <sys/ioctl.h>
  576. #include <net/if.h>
  577. static int get_netmask(struct sockaddr_in *me, int *mask)
  578. {
  579. static struct ifreq ifreqs[20] = { {{{0}}} };
  580. struct ifconf ifconf;
  581. int nifaces, i;
  582. int sock;
  583. int r = -1;
  584. memset(&ifconf, 0, sizeof(ifconf));
  585. ifconf.ifc_buf = (char *) (ifreqs);
  586. ifconf.ifc_len = sizeof(ifreqs);
  587. if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  588. goto end;
  589. }
  590. if (ioctl(sock, SIOCGIFCONF, (char *) &ifconf) < 0) {
  591. goto end;
  592. }
  593. nifaces = ifconf.ifc_len / sizeof(struct ifreq);
  594. for (i = 0; i < nifaces; i++) {
  595. struct sockaddr_in *sin = NULL;
  596. struct in_addr ip;
  597. ioctl(sock, SIOCGIFADDR, &ifreqs[i]);
  598. sin = (struct sockaddr_in *) &ifreqs[i].ifr_addr;
  599. ip = sin->sin_addr;
  600. if (ip.s_addr == me->sin_addr.s_addr) {
  601. ioctl(sock, SIOCGIFNETMASK, &ifreqs[i]);
  602. sin = (struct sockaddr_in *) &ifreqs[i].ifr_addr;
  603. /* mask = sin->sin_addr; */
  604. *mask = sin->sin_addr.s_addr;
  605. r = 0;
  606. break;
  607. }
  608. }
  609. end:
  610. close(sock);
  611. return r;
  612. }
  613. #elif defined(WIN32)
  614. static int get_netmask(struct sockaddr_in *me, int *mask)
  615. {
  616. SOCKET sock = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
  617. INTERFACE_INFO interfaces[20];
  618. unsigned long bytes;
  619. int interface_count, x;
  620. int r = -1;
  621. *mask = 0;
  622. if (sock == SOCKET_ERROR) {
  623. return -1;
  624. }
  625. if (WSAIoctl(sock, SIO_GET_INTERFACE_LIST, 0, 0, &interfaces, sizeof(interfaces), &bytes, 0, 0) == SOCKET_ERROR) {
  626. r = -1;
  627. goto end;
  628. }
  629. interface_count = bytes / sizeof(INTERFACE_INFO);
  630. for (x = 0; x < interface_count; ++x) {
  631. struct sockaddr_in *addr = (struct sockaddr_in *) &(interfaces[x].iiAddress);
  632. if (addr->sin_addr.s_addr == me->sin_addr.s_addr) {
  633. struct sockaddr_in *netmask = (struct sockaddr_in *) &(interfaces[x].iiNetmask);
  634. *mask = netmask->sin_addr.s_addr;
  635. r = 0;
  636. break;
  637. }
  638. }
  639. end:
  640. closesocket(sock);
  641. return r;
  642. }
  643. #else
  644. static int get_netmask(struct sockaddr_in *me, int *mask)
  645. {
  646. return -1;
  647. }
  648. #endif
  649. KS_DECLARE(ks_status_t) ks_ip_route(char *buf, int len, const char *route_ip)
  650. {
  651. int family = AF_INET;
  652. ks_assert(route_ip);
  653. if (strchr(route_ip, ':')) {
  654. family = AF_INET6;
  655. }
  656. return ks_find_local_ip(buf, len, NULL, family, route_ip);
  657. }
  658. KS_DECLARE(ks_status_t) ks_find_local_ip(char *buf, int len, int *mask, int family, const char *route_ip)
  659. {
  660. ks_status_t status = KS_STATUS_FAIL;
  661. char *base = (char *)route_ip;
  662. #ifdef WIN32
  663. SOCKET tmp_socket;
  664. SOCKADDR_STORAGE l_address;
  665. int l_address_len;
  666. struct addrinfo *address_info = NULL;
  667. #else
  668. #ifdef __Darwin__
  669. int ilen;
  670. #else
  671. unsigned int ilen;
  672. #endif
  673. int tmp_socket = -1, on = 1;
  674. char abuf[25] = "";
  675. #endif
  676. if (len < 16) {
  677. return status;
  678. }
  679. switch (family) {
  680. case AF_INET:
  681. ks_copy_string(buf, "127.0.0.1", len);
  682. if (!base) {
  683. base = "82.45.148.209";
  684. }
  685. break;
  686. case AF_INET6:
  687. ks_copy_string(buf, "::1", len);
  688. if (!base) {
  689. base = "2001:503:BA3E::2:30"; /* DNS Root server A */
  690. }
  691. break;
  692. default:
  693. base = "127.0.0.1";
  694. break;
  695. }
  696. #ifdef WIN32
  697. tmp_socket = socket(family, SOCK_DGRAM, 0);
  698. getaddrinfo(base, NULL, NULL, &address_info);
  699. if (!address_info || WSAIoctl(tmp_socket,
  700. SIO_ROUTING_INTERFACE_QUERY,
  701. address_info->ai_addr, (DWORD) address_info->ai_addrlen, &l_address, sizeof(l_address), (LPDWORD) & l_address_len, NULL,
  702. NULL)) {
  703. closesocket(tmp_socket);
  704. if (address_info)
  705. freeaddrinfo(address_info);
  706. return status;
  707. }
  708. closesocket(tmp_socket);
  709. freeaddrinfo(address_info);
  710. if (!getnameinfo((const struct sockaddr *) &l_address, l_address_len, buf, len, NULL, 0, NI_NUMERICHOST)) {
  711. status = KS_STATUS_SUCCESS;
  712. if (mask && family == AF_INET) {
  713. get_netmask((struct sockaddr_in *) &l_address, mask);
  714. }
  715. }
  716. #else
  717. switch (family) {
  718. case AF_INET:
  719. {
  720. struct sockaddr_in iface_out;
  721. struct sockaddr_in remote;
  722. memset(&remote, 0, sizeof(struct sockaddr_in));
  723. remote.sin_family = AF_INET;
  724. remote.sin_addr.s_addr = inet_addr(base);
  725. remote.sin_port = htons(4242);
  726. memset(&iface_out, 0, sizeof(iface_out));
  727. if ( (tmp_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ) {
  728. goto doh;
  729. }
  730. if (setsockopt(tmp_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1) {
  731. goto doh;
  732. }
  733. if (connect(tmp_socket, (struct sockaddr *) &remote, sizeof(struct sockaddr_in)) == -1) {
  734. goto doh;
  735. }
  736. ilen = sizeof(iface_out);
  737. if (getsockname(tmp_socket, (struct sockaddr *) &iface_out, &ilen) == -1) {
  738. goto doh;
  739. }
  740. if (iface_out.sin_addr.s_addr == 0) {
  741. goto doh;
  742. }
  743. getnameinfo((struct sockaddr *) &iface_out, sizeof(iface_out), abuf, sizeof(abuf), NULL, 0, NI_NUMERICHOST);
  744. ks_copy_string(buf, abuf, len);
  745. if (mask && family == AF_INET) {
  746. get_netmask((struct sockaddr_in *) &iface_out, mask);
  747. }
  748. status = KS_STATUS_SUCCESS;
  749. }
  750. break;
  751. case AF_INET6:
  752. {
  753. struct sockaddr_in6 iface_out;
  754. struct sockaddr_in6 remote;
  755. memset(&remote, 0, sizeof(struct sockaddr_in6));
  756. remote.sin6_family = AF_INET6;
  757. inet_pton(AF_INET6, base, &remote.sin6_addr);
  758. remote.sin6_port = htons(4242);
  759. memset(&iface_out, 0, sizeof(iface_out));
  760. if ( (tmp_socket = socket(AF_INET6, SOCK_DGRAM, 0)) == -1 ) {
  761. goto doh;
  762. }
  763. if (connect(tmp_socket, (struct sockaddr *) &remote, sizeof(remote)) == -1) {
  764. goto doh;
  765. }
  766. ilen = sizeof(iface_out);
  767. if (getsockname(tmp_socket, (struct sockaddr *) &iface_out, &ilen) == -1) {
  768. goto doh;
  769. }
  770. inet_ntop(AF_INET6, (const void *) &iface_out.sin6_addr, buf, len - 1);
  771. status = KS_STATUS_SUCCESS;
  772. }
  773. break;
  774. }
  775. doh:
  776. if (tmp_socket > 0) {
  777. close(tmp_socket);
  778. }
  779. #endif
  780. return status;
  781. }
  782. KS_DECLARE(ks_status_t) ks_addr_raw_data(const ks_sockaddr_t *addr, void **data, ks_size_t *datalen)
  783. {
  784. ks_assert(addr->family == AF_INET || addr->family == AF_INET6);
  785. if (addr->family == AF_INET) {
  786. *data = (void *)&addr->v.v4.sin_addr;
  787. *datalen = 4;
  788. } else {
  789. *data = (void *)&addr->v.v6.sin6_addr;
  790. *datalen = 16;
  791. }
  792. return KS_STATUS_SUCCESS;
  793. }
  794. KS_DECLARE(ks_status_t) ks_socket_send(ks_socket_t sock, void *data, ks_size_t *datalen)
  795. {
  796. ks_ssize_t r;
  797. ks_status_t status = KS_STATUS_FAIL;
  798. do {
  799. #ifdef WIN32
  800. r = send(sock, data, (int)*datalen, 0);
  801. #else
  802. r = send(sock, data, *datalen, 0);
  803. #endif
  804. } while (r == -1 && ks_errno_is_interupt(ks_errno()));
  805. if (r > 0) {
  806. *datalen = (ks_size_t) r;
  807. status = KS_STATUS_SUCCESS;
  808. } else if (r == 0) {
  809. status = KS_STATUS_DISCONNECTED;
  810. } else if (ks_errno_is_blocking(ks_errno())) {
  811. status = KS_STATUS_BREAK;
  812. }
  813. return status;
  814. }
  815. KS_DECLARE(ks_status_t) ks_socket_recv(ks_socket_t sock, void *data, ks_size_t *datalen)
  816. {
  817. ks_ssize_t r;
  818. ks_status_t status = KS_STATUS_FAIL;
  819. do {
  820. #ifdef WIN32
  821. r = recv(sock, data, (int)*datalen, 0);
  822. #else
  823. r = recv(sock, data, *datalen, 0);
  824. #endif
  825. } while (r == -1 && ks_errno_is_interupt(ks_errno()));
  826. if (r > 0) {
  827. *datalen = (ks_size_t) r;
  828. status = KS_STATUS_SUCCESS;
  829. } else if (r == 0) {
  830. status = KS_STATUS_DISCONNECTED;
  831. } else if (ks_errno_is_blocking(ks_errno())) {
  832. status = KS_STATUS_BREAK;
  833. }
  834. return status;
  835. }
  836. KS_DECLARE(ks_status_t) ks_socket_sendto(ks_socket_t sock, void *data, ks_size_t *datalen, ks_sockaddr_t *addr)
  837. {
  838. struct sockaddr *sockaddr;
  839. socklen_t socksize = 0;
  840. ks_status_t status = KS_STATUS_FAIL;
  841. ks_ssize_t r;
  842. ks_assert(addr);
  843. ks_assert(addr->family == AF_INET || addr->family == AF_INET6);
  844. if (addr->family == AF_INET) {
  845. sockaddr = (struct sockaddr *) &addr->v.v4;
  846. socksize = sizeof(addr->v.v4);
  847. } else {
  848. sockaddr = (struct sockaddr *) &addr->v.v6;
  849. socksize = sizeof(addr->v.v6);
  850. }
  851. do {
  852. #ifdef WIN32
  853. r = sendto(sock, data, (int)*datalen, 0, sockaddr, socksize);
  854. #else
  855. r = sendto(sock, data, *datalen, 0, sockaddr, socksize);
  856. #endif
  857. } while (r == -1 && ks_errno_is_interupt(ks_errno()));
  858. if (r > 0) {
  859. *datalen = (ks_size_t) r;
  860. status = KS_STATUS_SUCCESS;
  861. } else if (r == 0) {
  862. status = KS_STATUS_DISCONNECTED;
  863. } else if (ks_errno_is_blocking(ks_errno())) {
  864. status = KS_STATUS_BREAK;
  865. }
  866. return status;
  867. }
  868. KS_DECLARE(ks_status_t) ks_socket_recvfrom(ks_socket_t sock, void *data, ks_size_t *datalen, ks_sockaddr_t *addr)
  869. {
  870. struct sockaddr *sockaddr;
  871. ks_status_t status = KS_STATUS_FAIL;
  872. ks_ssize_t r;
  873. socklen_t alen;
  874. ks_assert(addr);
  875. ks_assert(addr->family == AF_INET || addr->family == AF_INET6);
  876. if (addr->family == AF_INET) {
  877. sockaddr = (struct sockaddr *) &addr->v.v4;
  878. alen = sizeof(addr->v.v4);
  879. } else {
  880. sockaddr = (struct sockaddr *) &addr->v.v6;
  881. alen = sizeof(addr->v.v6);
  882. }
  883. do {
  884. #ifdef WIN32
  885. r = recvfrom(sock, data, (int)*datalen, 0, sockaddr, &alen);
  886. #else
  887. r = recvfrom(sock, data, *datalen, 0, sockaddr, &alen);
  888. #endif
  889. } while (r == -1 && ks_errno_is_interupt(ks_errno()));
  890. if (r > 0) {
  891. ks_addr_get_host(addr);
  892. ks_addr_get_port(addr);
  893. *datalen = (ks_size_t) r;
  894. status = KS_STATUS_SUCCESS;
  895. } else if (r == 0) {
  896. status = KS_STATUS_DISCONNECTED;
  897. } else if (ks_errno_is_blocking(ks_errno())) {
  898. status = KS_STATUS_BREAK;
  899. }
  900. return status;
  901. }
  902. KS_DECLARE(ks_status_t) ks_addr_getbyname(const char *name, ks_port_t port, int family, ks_sockaddr_t *result)
  903. {
  904. ks_status_t ret = KS_STATUS_SUCCESS;
  905. struct addrinfo hints;
  906. struct addrinfo *res = NULL;
  907. int eai = 0;
  908. ks_assert(name);
  909. ks_assert(result);
  910. memset((void *)&hints, 0, sizeof(struct addrinfo));
  911. hints.ai_family = family;
  912. eai = getaddrinfo(name, NULL, &hints, &res);
  913. if (eai == EAI_NONAME) ret = KS_STATUS_NOT_FOUND;
  914. else if (eai != 0) ret = KS_STATUS_FAIL;
  915. else {
  916. ks_assert(res);
  917. ks_addr_set_raw(result, &((struct sockaddr_in *)res->ai_addr)->sin_addr, port, res->ai_family);
  918. }
  919. if (res)
  920. freeaddrinfo(res);
  921. return ret;
  922. }