win_socket.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. /*
  2. * Copyright (C) 2021 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "platform_api_vmcore.h"
  6. #include "platform_api_extension.h"
  7. #include "platform_wasi_types.h"
  8. #include "win_util.h"
  9. /* link with Ws2_32.lib */
  10. #pragma comment(lib, "ws2_32.lib")
  11. static bool is_winsock_inited = false;
  12. #define CHECK_VALID_SOCKET_HANDLE(win_handle) \
  13. do { \
  14. if ((win_handle) == NULL) { \
  15. errno = EBADF; \
  16. return BHT_ERROR; \
  17. } \
  18. if ((win_handle)->type != windows_handle_type_socket) { \
  19. errno = ENOTSOCK; \
  20. return BHT_ERROR; \
  21. } \
  22. if ((win_handle)->raw.socket == INVALID_SOCKET) { \
  23. errno = EBADF; \
  24. return BHT_ERROR; \
  25. } \
  26. } while (0)
  27. int
  28. init_winsock()
  29. {
  30. #if WASM_ENABLE_HOST_SOCKET_INIT == 0
  31. WSADATA wsaData;
  32. if (!is_winsock_inited) {
  33. if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
  34. os_printf("winsock init failed");
  35. return BHT_ERROR;
  36. }
  37. is_winsock_inited = true;
  38. }
  39. #endif
  40. return BHT_OK;
  41. }
  42. void
  43. deinit_winsock()
  44. {
  45. #if WASM_ENABLE_HOST_SOCKET_INIT == 0
  46. if (is_winsock_inited) {
  47. WSACleanup();
  48. }
  49. #endif
  50. }
  51. int
  52. os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
  53. {
  54. int af;
  55. if (!sock) {
  56. return BHT_ERROR;
  57. }
  58. *(sock) = BH_MALLOC(sizeof(windows_handle));
  59. if ((*sock) == NULL) {
  60. errno = ENOMEM;
  61. return BHT_ERROR;
  62. }
  63. (*sock)->type = windows_handle_type_socket;
  64. (*sock)->access_mode = windows_access_mode_read | windows_access_mode_write;
  65. (*sock)->fdflags = 0;
  66. if (is_ipv4) {
  67. af = AF_INET;
  68. }
  69. else {
  70. errno = ENOSYS;
  71. return BHT_ERROR;
  72. }
  73. if (is_tcp) {
  74. (*sock)->raw.socket = socket(af, SOCK_STREAM, IPPROTO_TCP);
  75. }
  76. else {
  77. (*sock)->raw.socket = socket(af, SOCK_DGRAM, 0);
  78. }
  79. if ((*sock)->raw.socket == INVALID_SOCKET) {
  80. BH_FREE(*sock);
  81. return BHT_ERROR;
  82. }
  83. return BHT_OK;
  84. }
  85. int
  86. os_socket_bind(bh_socket_t socket, const char *host, int *port)
  87. {
  88. CHECK_VALID_SOCKET_HANDLE(socket);
  89. struct sockaddr_in addr;
  90. int socklen, ret;
  91. assert(host);
  92. assert(port);
  93. addr.sin_addr.s_addr = inet_addr(host);
  94. addr.sin_port = htons(*port);
  95. addr.sin_family = AF_INET;
  96. ret = bind(socket->raw.socket, (struct sockaddr *)&addr, sizeof(addr));
  97. if (ret < 0) {
  98. goto fail;
  99. }
  100. socklen = sizeof(addr);
  101. if (getsockname(socket->raw.socket, (void *)&addr, &socklen) == -1) {
  102. os_printf("getsockname failed with error %d\n", WSAGetLastError());
  103. goto fail;
  104. }
  105. *port = ntohs(addr.sin_port);
  106. return BHT_OK;
  107. fail:
  108. return BHT_ERROR;
  109. }
  110. int
  111. os_socket_settimeout(bh_socket_t socket, uint64 timeout_us)
  112. {
  113. CHECK_VALID_SOCKET_HANDLE(socket);
  114. DWORD tv = (DWORD)(timeout_us / 1000UL);
  115. if (setsockopt(socket->raw.socket, SOL_SOCKET, SO_RCVTIMEO,
  116. (const char *)&tv, sizeof(tv))
  117. != 0) {
  118. return BHT_ERROR;
  119. }
  120. return BHT_OK;
  121. }
  122. int
  123. os_socket_listen(bh_socket_t socket, int max_client)
  124. {
  125. CHECK_VALID_SOCKET_HANDLE(socket);
  126. if (listen(socket->raw.socket, max_client) != 0) {
  127. os_printf("socket listen failed with error %d\n", WSAGetLastError());
  128. return BHT_ERROR;
  129. }
  130. return BHT_OK;
  131. }
  132. int
  133. os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
  134. unsigned int *addrlen)
  135. {
  136. CHECK_VALID_SOCKET_HANDLE(server_sock);
  137. struct sockaddr addr_tmp;
  138. unsigned int len = sizeof(struct sockaddr);
  139. *sock = BH_MALLOC(sizeof(windows_handle));
  140. if (*sock == NULL) {
  141. errno = ENOMEM;
  142. return BHT_ERROR;
  143. }
  144. (*sock)->type = windows_handle_type_socket;
  145. (*sock)->access_mode = windows_access_mode_read | windows_access_mode_write;
  146. (*sock)->fdflags = 0;
  147. (*sock)->raw.socket = accept(server_sock->raw.socket,
  148. (struct sockaddr *)&addr_tmp, (int *)&len);
  149. if ((*sock)->raw.socket == INVALID_SOCKET) {
  150. BH_FREE(*sock);
  151. os_printf("socket accept failed with error %d\n", WSAGetLastError());
  152. return BHT_ERROR;
  153. }
  154. return BHT_OK;
  155. }
  156. int
  157. os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
  158. {
  159. CHECK_VALID_SOCKET_HANDLE(socket);
  160. return recv(socket->raw.socket, buf, len, 0);
  161. }
  162. int
  163. os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
  164. bh_sockaddr_t *src_addr)
  165. {
  166. CHECK_VALID_SOCKET_HANDLE(socket);
  167. errno = ENOSYS;
  168. return BHT_ERROR;
  169. }
  170. int
  171. os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
  172. {
  173. CHECK_VALID_SOCKET_HANDLE(socket);
  174. return send(socket->raw.socket, buf, len, 0);
  175. }
  176. int
  177. os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
  178. int flags, const bh_sockaddr_t *dest_addr)
  179. {
  180. CHECK_VALID_SOCKET_HANDLE(socket);
  181. errno = ENOSYS;
  182. return BHT_ERROR;
  183. }
  184. int
  185. os_socket_close(bh_socket_t socket)
  186. {
  187. CHECK_VALID_SOCKET_HANDLE(socket);
  188. closesocket(socket->raw.socket);
  189. BH_FREE(socket);
  190. return BHT_OK;
  191. }
  192. __wasi_errno_t
  193. os_socket_shutdown(bh_socket_t socket)
  194. {
  195. CHECK_VALID_SOCKET_HANDLE(socket);
  196. if (shutdown(socket->raw.socket, SD_BOTH) != 0) {
  197. return convert_winsock_error_code(WSAGetLastError());
  198. }
  199. return __WASI_ESUCCESS;
  200. }
  201. int
  202. os_socket_inet_network(bool is_ipv4, const char *cp, bh_ip_addr_buffer_t *out)
  203. {
  204. if (!cp)
  205. return BHT_ERROR;
  206. if (is_ipv4) {
  207. if (inet_pton(AF_INET, cp, &out->ipv4) != 1) {
  208. return BHT_ERROR;
  209. }
  210. /* Note: ntohl(INADDR_NONE) == INADDR_NONE */
  211. out->ipv4 = ntohl(out->ipv4);
  212. }
  213. else {
  214. if (inet_pton(AF_INET6, cp, out->ipv6) != 1) {
  215. return BHT_ERROR;
  216. }
  217. for (int i = 0; i < 8; i++) {
  218. out->ipv6[i] = ntohs(out->ipv6[i]);
  219. }
  220. }
  221. return BHT_OK;
  222. }
  223. int
  224. os_socket_connect(bh_socket_t socket, const char *addr, int port)
  225. {
  226. CHECK_VALID_SOCKET_HANDLE(socket);
  227. errno = ENOSYS;
  228. return BHT_ERROR;
  229. }
  230. int
  231. os_socket_addr_resolve(const char *host, const char *service,
  232. uint8_t *hint_is_tcp, uint8_t *hint_is_ipv4,
  233. bh_addr_info_t *addr_info, size_t addr_info_size,
  234. size_t *max_info_size)
  235. {
  236. errno = ENOSYS;
  237. return BHT_ERROR;
  238. }
  239. int
  240. os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
  241. {
  242. CHECK_VALID_SOCKET_HANDLE(socket);
  243. errno = ENOSYS;
  244. return BHT_ERROR;
  245. }
  246. int
  247. os_socket_set_send_timeout(bh_socket_t socket, uint64 timeout_us)
  248. {
  249. CHECK_VALID_SOCKET_HANDLE(socket);
  250. errno = ENOSYS;
  251. return BHT_ERROR;
  252. }
  253. int
  254. os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us)
  255. {
  256. CHECK_VALID_SOCKET_HANDLE(socket);
  257. errno = ENOSYS;
  258. return BHT_ERROR;
  259. }
  260. int
  261. os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us)
  262. {
  263. CHECK_VALID_SOCKET_HANDLE(socket);
  264. errno = ENOSYS;
  265. return BHT_ERROR;
  266. }
  267. int
  268. os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us)
  269. {
  270. CHECK_VALID_SOCKET_HANDLE(socket);
  271. errno = ENOSYS;
  272. return BHT_ERROR;
  273. }
  274. int
  275. os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr)
  276. {
  277. CHECK_VALID_SOCKET_HANDLE(socket);
  278. errno = ENOSYS;
  279. return BHT_ERROR;
  280. }
  281. int
  282. os_socket_set_send_buf_size(bh_socket_t socket, size_t bufsiz)
  283. {
  284. CHECK_VALID_SOCKET_HANDLE(socket);
  285. errno = ENOSYS;
  286. return BHT_ERROR;
  287. }
  288. int
  289. os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz)
  290. {
  291. CHECK_VALID_SOCKET_HANDLE(socket);
  292. errno = ENOSYS;
  293. return BHT_ERROR;
  294. }
  295. int
  296. os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz)
  297. {
  298. CHECK_VALID_SOCKET_HANDLE(socket);
  299. errno = ENOSYS;
  300. return BHT_ERROR;
  301. }
  302. int
  303. os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz)
  304. {
  305. CHECK_VALID_SOCKET_HANDLE(socket);
  306. errno = ENOSYS;
  307. return BHT_ERROR;
  308. }
  309. int
  310. os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled)
  311. {
  312. CHECK_VALID_SOCKET_HANDLE(socket);
  313. errno = ENOSYS;
  314. return BHT_ERROR;
  315. }
  316. int
  317. os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled)
  318. {
  319. CHECK_VALID_SOCKET_HANDLE(socket);
  320. errno = ENOSYS;
  321. return BHT_ERROR;
  322. }
  323. int
  324. os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled)
  325. {
  326. CHECK_VALID_SOCKET_HANDLE(socket);
  327. errno = ENOSYS;
  328. return BHT_ERROR;
  329. }
  330. int
  331. os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled)
  332. {
  333. CHECK_VALID_SOCKET_HANDLE(socket);
  334. errno = ENOSYS;
  335. return BHT_ERROR;
  336. }
  337. int
  338. os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled)
  339. {
  340. CHECK_VALID_SOCKET_HANDLE(socket);
  341. errno = ENOSYS;
  342. return BHT_ERROR;
  343. }
  344. int
  345. os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled)
  346. {
  347. CHECK_VALID_SOCKET_HANDLE(socket);
  348. errno = ENOSYS;
  349. return BHT_ERROR;
  350. }
  351. int
  352. os_socket_set_linger(bh_socket_t socket, bool is_enabled, int linger_s)
  353. {
  354. CHECK_VALID_SOCKET_HANDLE(socket);
  355. errno = ENOSYS;
  356. return BHT_ERROR;
  357. }
  358. int
  359. os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
  360. {
  361. CHECK_VALID_SOCKET_HANDLE(socket);
  362. errno = ENOSYS;
  363. return BHT_ERROR;
  364. }
  365. int
  366. os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled)
  367. {
  368. CHECK_VALID_SOCKET_HANDLE(socket);
  369. errno = ENOSYS;
  370. return BHT_ERROR;
  371. }
  372. int
  373. os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled)
  374. {
  375. CHECK_VALID_SOCKET_HANDLE(socket);
  376. errno = ENOSYS;
  377. return BHT_ERROR;
  378. }
  379. int
  380. os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled)
  381. {
  382. CHECK_VALID_SOCKET_HANDLE(socket);
  383. errno = ENOSYS;
  384. return BHT_ERROR;
  385. }
  386. int
  387. os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled)
  388. {
  389. CHECK_VALID_SOCKET_HANDLE(socket);
  390. errno = ENOSYS;
  391. return BHT_ERROR;
  392. }
  393. int
  394. os_socket_set_tcp_keep_idle(bh_socket_t socket, uint32 time_s)
  395. {
  396. CHECK_VALID_SOCKET_HANDLE(socket);
  397. errno = ENOSYS;
  398. return BHT_ERROR;
  399. }
  400. int
  401. os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32 *time_s)
  402. {
  403. CHECK_VALID_SOCKET_HANDLE(socket);
  404. errno = ENOSYS;
  405. return BHT_ERROR;
  406. }
  407. int
  408. os_socket_set_tcp_keep_intvl(bh_socket_t socket, uint32 time_s)
  409. {
  410. CHECK_VALID_SOCKET_HANDLE(socket);
  411. errno = ENOSYS;
  412. return BHT_ERROR;
  413. }
  414. int
  415. os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32 *time_s)
  416. {
  417. CHECK_VALID_SOCKET_HANDLE(socket);
  418. errno = ENOSYS;
  419. return BHT_ERROR;
  420. }
  421. int
  422. os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled)
  423. {
  424. CHECK_VALID_SOCKET_HANDLE(socket);
  425. errno = ENOSYS;
  426. return BHT_ERROR;
  427. }
  428. int
  429. os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
  430. {
  431. CHECK_VALID_SOCKET_HANDLE(socket);
  432. errno = ENOSYS;
  433. return BHT_ERROR;
  434. }
  435. int
  436. os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled)
  437. {
  438. CHECK_VALID_SOCKET_HANDLE(socket);
  439. errno = ENOSYS;
  440. return BHT_ERROR;
  441. }
  442. int
  443. os_socket_get_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool *is_enabled)
  444. {
  445. CHECK_VALID_SOCKET_HANDLE(socket);
  446. errno = ENOSYS;
  447. return BHT_ERROR;
  448. }
  449. int
  450. os_socket_set_ip_add_membership(bh_socket_t socket,
  451. bh_ip_addr_buffer_t *imr_multiaddr,
  452. uint32_t imr_interface, bool is_ipv6)
  453. {
  454. CHECK_VALID_SOCKET_HANDLE(socket);
  455. errno = ENOSYS;
  456. return BHT_ERROR;
  457. }
  458. int
  459. os_socket_set_ip_drop_membership(bh_socket_t socket,
  460. bh_ip_addr_buffer_t *imr_multiaddr,
  461. uint32_t imr_interface, bool is_ipv6)
  462. {
  463. CHECK_VALID_SOCKET_HANDLE(socket);
  464. errno = ENOSYS;
  465. return BHT_ERROR;
  466. }
  467. int
  468. os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
  469. {
  470. CHECK_VALID_SOCKET_HANDLE(socket);
  471. errno = ENOSYS;
  472. return BHT_ERROR;
  473. }
  474. int
  475. os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s)
  476. {
  477. CHECK_VALID_SOCKET_HANDLE(socket);
  478. errno = ENOSYS;
  479. return BHT_ERROR;
  480. }
  481. int
  482. os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
  483. {
  484. CHECK_VALID_SOCKET_HANDLE(socket);
  485. errno = ENOSYS;
  486. return BHT_ERROR;
  487. }
  488. int
  489. os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
  490. {
  491. CHECK_VALID_SOCKET_HANDLE(socket);
  492. errno = ENOSYS;
  493. return BHT_ERROR;
  494. }
  495. int
  496. os_socket_set_ipv6_only(bh_socket_t socket, bool option)
  497. {
  498. CHECK_VALID_SOCKET_HANDLE(socket);
  499. errno = ENOSYS;
  500. return BHT_ERROR;
  501. }
  502. int
  503. os_socket_get_ipv6_only(bh_socket_t socket, bool *option)
  504. {
  505. CHECK_VALID_SOCKET_HANDLE(socket);
  506. errno = ENOSYS;
  507. return BHT_ERROR;
  508. }
  509. int
  510. os_socket_set_broadcast(bh_socket_t socket, bool is_enabled)
  511. {
  512. CHECK_VALID_SOCKET_HANDLE(socket);
  513. errno = ENOSYS;
  514. return BHT_ERROR;
  515. }
  516. int
  517. os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled)
  518. {
  519. CHECK_VALID_SOCKET_HANDLE(socket);
  520. errno = ENOSYS;
  521. return BHT_ERROR;
  522. }