sgx_socket.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227
  1. /*
  2. * Copyright (C) 2019 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. #ifndef SGX_DISABLE_WASI
  8. #include "libc_errno.h"
  9. #define TRACE_OCALL_FAIL() os_printf("ocall %s failed!\n", __FUNCTION__)
  10. /** OCALLs prototypes **/
  11. int
  12. ocall_accept(int *p_ret, int sockfd, void *addr, uint32_t *addrlen,
  13. uint32_t addr_size);
  14. int
  15. ocall_bind(int *p_ret, int sockfd, const void *addr, uint32_t addrlen);
  16. int
  17. ocall_close(int *p_ret, int fd);
  18. int
  19. ocall_connect(int *p_ret, int sockfd, void *addr, uint32_t addrlen);
  20. int
  21. ocall_fcntl_long(int *p_ret, int fd, int cmd, long arg);
  22. int
  23. ocall_getsockname(int *p_ret, int sockfd, void *addr, uint32_t *addrlen,
  24. uint32_t addr_size);
  25. int
  26. ocall_getpeername(int *p_ret, int sockfd, void *addr, uint32_t *addrlen,
  27. uint32_t addr_size);
  28. int
  29. ocall_getsockopt(int *p_ret, int sockfd, int level, int optname, void *val_buf,
  30. unsigned int val_buf_size, void *len_buf);
  31. int
  32. ocall_listen(int *p_ret, int sockfd, int backlog);
  33. int
  34. ocall_recv(int *p_ret, int sockfd, void *buf, size_t len, int flags);
  35. int
  36. ocall_recvfrom(ssize_t *p_ret, int sockfd, void *buf, size_t len, int flags,
  37. void *src_addr, uint32_t *addrlen, uint32_t addr_size);
  38. int
  39. ocall_recvmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
  40. unsigned int msg_buf_size, int flags);
  41. int
  42. ocall_send(int *p_ret, int sockfd, const void *buf, size_t len, int flags);
  43. int
  44. ocall_sendto(ssize_t *p_ret, int sockfd, const void *buf, size_t len, int flags,
  45. void *dest_addr, uint32_t addrlen);
  46. int
  47. ocall_sendmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
  48. unsigned int msg_buf_size, int flags);
  49. int
  50. ocall_setsockopt(int *p_ret, int sockfd, int level, int optname, void *optval,
  51. unsigned int optlen);
  52. int
  53. ocall_shutdown(int *p_ret, int sockfd, int how);
  54. int
  55. ocall_socket(int *p_ret, int domain, int type, int protocol);
  56. /** OCALLs prototypes end **/
  57. /** In-enclave implementation of POSIX functions **/
  58. static bool
  59. is_little_endian()
  60. {
  61. long i = 0x01020304;
  62. unsigned char *c = (unsigned char *)&i;
  63. return (*c == 0x04) ? true : false;
  64. }
  65. static void
  66. swap32(uint8 *pData)
  67. {
  68. uint8 value = *pData;
  69. *pData = *(pData + 3);
  70. *(pData + 3) = value;
  71. value = *(pData + 1);
  72. *(pData + 1) = *(pData + 2);
  73. *(pData + 2) = value;
  74. }
  75. static void
  76. swap16(uint8 *pData)
  77. {
  78. uint8 value = *pData;
  79. *(pData) = *(pData + 1);
  80. *(pData + 1) = value;
  81. }
  82. uint32
  83. htonl(uint32 value)
  84. {
  85. uint32 ret;
  86. if (is_little_endian()) {
  87. ret = value;
  88. swap32((uint8 *)&ret);
  89. return ret;
  90. }
  91. return value;
  92. }
  93. uint32
  94. ntohl(uint32 value)
  95. {
  96. return htonl(value);
  97. }
  98. uint16
  99. htons(uint16 value)
  100. {
  101. uint16 ret;
  102. if (is_little_endian()) {
  103. ret = value;
  104. swap16((uint8 *)&ret);
  105. return ret;
  106. }
  107. return value;
  108. }
  109. static uint16
  110. ntohs(uint16 value)
  111. {
  112. return htons(value);
  113. }
  114. /* Coming from musl, under MIT license */
  115. static int
  116. hexval(unsigned c)
  117. {
  118. if (c - '0' < 10)
  119. return c - '0';
  120. c |= 32;
  121. if (c - 'a' < 6)
  122. return c - 'a' + 10;
  123. return -1;
  124. }
  125. /* Coming from musl, under MIT license */
  126. static int
  127. inet_pton(int af, const char *restrict s, void *restrict a0)
  128. {
  129. uint16_t ip[8];
  130. unsigned char *a = a0;
  131. int i, j, v, d, brk = -1, need_v4 = 0;
  132. if (af == AF_INET) {
  133. for (i = 0; i < 4; i++) {
  134. for (v = j = 0; j < 3 && isdigit(s[j]); j++)
  135. v = 10 * v + s[j] - '0';
  136. if (j == 0 || (j > 1 && s[0] == '0') || v > 255)
  137. return 0;
  138. a[i] = v;
  139. if (s[j] == 0 && i == 3)
  140. return 1;
  141. if (s[j] != '.')
  142. return 0;
  143. s += j + 1;
  144. }
  145. return 0;
  146. }
  147. else if (af != AF_INET6) {
  148. errno = EAFNOSUPPORT;
  149. return -1;
  150. }
  151. if (*s == ':' && *++s != ':')
  152. return 0;
  153. for (i = 0;; i++) {
  154. if (s[0] == ':' && brk < 0) {
  155. brk = i;
  156. ip[i & 7] = 0;
  157. if (!*++s)
  158. break;
  159. if (i == 7)
  160. return 0;
  161. continue;
  162. }
  163. for (v = j = 0; j < 4 && (d = hexval(s[j])) >= 0; j++)
  164. v = 16 * v + d;
  165. if (j == 0)
  166. return 0;
  167. ip[i & 7] = v;
  168. if (!s[j] && (brk >= 0 || i == 7))
  169. break;
  170. if (i == 7)
  171. return 0;
  172. if (s[j] != ':') {
  173. if (s[j] != '.' || (i < 6 && brk < 0))
  174. return 0;
  175. need_v4 = 1;
  176. i++;
  177. break;
  178. }
  179. s += j + 1;
  180. }
  181. if (brk >= 0) {
  182. memmove(ip + brk + 7 - i, ip + brk, 2 * (i + 1 - brk));
  183. for (j = 0; j < 7 - i; j++)
  184. ip[brk + j] = 0;
  185. }
  186. for (j = 0; j < 8; j++) {
  187. *a++ = ip[j] >> 8;
  188. *a++ = ip[j];
  189. }
  190. if (need_v4 && inet_pton(AF_INET, (void *)s, a - 4) <= 0)
  191. return 0;
  192. return 1;
  193. }
  194. static int
  195. inet_addr(const char *p)
  196. {
  197. struct in_addr a;
  198. if (!inet_pton(AF_INET, p, &a))
  199. return -1;
  200. return a.s_addr;
  201. }
  202. /** In-enclave implementation of POSIX functions end **/
  203. static int
  204. textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr_in *out)
  205. {
  206. assert(textual);
  207. out->sin_family = AF_INET;
  208. out->sin_port = htons(port);
  209. out->sin_addr.s_addr = inet_addr(textual);
  210. return BHT_OK;
  211. }
  212. static int
  213. sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr, socklen_t socklen,
  214. bh_sockaddr_t *bh_sockaddr)
  215. {
  216. switch (sockaddr->sa_family) {
  217. case AF_INET:
  218. {
  219. struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr;
  220. assert(socklen >= sizeof(struct sockaddr_in));
  221. bh_sockaddr->port = ntohs(addr->sin_port);
  222. bh_sockaddr->addr_buffer.ipv4 = ntohl(addr->sin_addr.s_addr);
  223. bh_sockaddr->is_ipv4 = true;
  224. return BHT_OK;
  225. }
  226. default:
  227. errno = EAFNOSUPPORT;
  228. return BHT_ERROR;
  229. }
  230. }
  231. static int
  232. bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr,
  233. struct sockaddr *sockaddr, socklen_t *socklen)
  234. {
  235. if (bh_sockaddr->is_ipv4) {
  236. struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr;
  237. addr->sin_port = htons(bh_sockaddr->port);
  238. addr->sin_family = AF_INET;
  239. addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_buffer.ipv4);
  240. *socklen = sizeof(*addr);
  241. return BHT_OK;
  242. }
  243. else {
  244. errno = EAFNOSUPPORT;
  245. return BHT_ERROR;
  246. }
  247. }
  248. static int
  249. os_socket_setbooloption(bh_socket_t socket, int level, int optname,
  250. bool is_enabled)
  251. {
  252. int option = (int)is_enabled;
  253. int ret;
  254. if (ocall_setsockopt(&ret, socket, level, optname, &option, sizeof(option))
  255. != SGX_SUCCESS) {
  256. TRACE_OCALL_FAIL();
  257. return BHT_ERROR;
  258. }
  259. if (ret != 0) {
  260. errno = get_errno();
  261. return BHT_ERROR;
  262. }
  263. return BHT_OK;
  264. }
  265. static int
  266. os_socket_getbooloption(bh_socket_t socket, int level, int optname,
  267. bool *is_enabled)
  268. {
  269. assert(is_enabled);
  270. int optval;
  271. socklen_t optval_size = sizeof(optval);
  272. int ret;
  273. if (ocall_getsockopt(&ret, socket, level, optname, &optval, optval_size,
  274. &optval_size)
  275. != SGX_SUCCESS) {
  276. TRACE_OCALL_FAIL();
  277. return BHT_ERROR;
  278. }
  279. if (ret != 0) {
  280. errno = get_errno();
  281. return BHT_ERROR;
  282. }
  283. *is_enabled = (bool)optval;
  284. return BHT_OK;
  285. }
  286. int
  287. socket(int domain, int type, int protocol)
  288. {
  289. int ret;
  290. if (ocall_socket(&ret, domain, type, protocol) != SGX_SUCCESS) {
  291. TRACE_OCALL_FAIL();
  292. return -1;
  293. }
  294. if (ret == -1)
  295. errno = get_errno();
  296. return ret;
  297. }
  298. int
  299. getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)
  300. {
  301. int ret;
  302. unsigned int val_buf_size = *optlen;
  303. if (ocall_getsockopt(&ret, sockfd, level, optname, optval, val_buf_size,
  304. (void *)optlen)
  305. != SGX_SUCCESS) {
  306. TRACE_OCALL_FAIL();
  307. return -1;
  308. }
  309. if (ret == -1)
  310. errno = get_errno();
  311. return ret;
  312. }
  313. int
  314. setsockopt(int sockfd, int level, int optname, const void *optval,
  315. socklen_t optlen)
  316. {
  317. int ret;
  318. if (ocall_setsockopt(&ret, sockfd, level, optname, (void *)optval, optlen)
  319. != SGX_SUCCESS) {
  320. TRACE_OCALL_FAIL();
  321. return -1;
  322. }
  323. if (ret == -1)
  324. errno = get_errno();
  325. return ret;
  326. }
  327. ssize_t
  328. sendmsg(int sockfd, const struct msghdr *msg, int flags)
  329. {
  330. ssize_t ret;
  331. int i;
  332. char *p;
  333. struct msghdr *msg1;
  334. uint64 total_size = sizeof(struct msghdr) + (uint64)msg->msg_namelen
  335. + (uint64)msg->msg_controllen;
  336. total_size += sizeof(struct iovec) * (msg->msg_iovlen);
  337. for (i = 0; i < msg->msg_iovlen; i++) {
  338. total_size += msg->msg_iov[i].iov_len;
  339. }
  340. if (total_size >= UINT32_MAX)
  341. return -1;
  342. msg1 = BH_MALLOC((uint32)total_size);
  343. if (msg1 == NULL)
  344. return -1;
  345. p = (char *)(uintptr_t)sizeof(struct msghdr);
  346. if (msg->msg_name != NULL) {
  347. msg1->msg_name = p;
  348. memcpy((uintptr_t)p + (char *)msg1, msg->msg_name,
  349. (size_t)msg->msg_namelen);
  350. p += msg->msg_namelen;
  351. }
  352. if (msg->msg_control != NULL) {
  353. msg1->msg_control = p;
  354. memcpy((uintptr_t)p + (char *)msg1, msg->msg_control,
  355. (size_t)msg->msg_control);
  356. p += msg->msg_controllen;
  357. }
  358. if (msg->msg_iov != NULL) {
  359. msg1->msg_iov = (struct iovec *)p;
  360. p += (uintptr_t)(sizeof(struct iovec) * (msg->msg_iovlen));
  361. for (i = 0; i < msg->msg_iovlen; i++) {
  362. msg1->msg_iov[i].iov_base = p;
  363. msg1->msg_iov[i].iov_len = msg->msg_iov[i].iov_len;
  364. memcpy((uintptr_t)p + (char *)msg1, msg->msg_iov[i].iov_base,
  365. (size_t)(msg->msg_iov[i].iov_len));
  366. p += msg->msg_iov[i].iov_len;
  367. }
  368. }
  369. if (ocall_sendmsg(&ret, sockfd, (void *)msg1, (uint32)total_size, flags)
  370. != SGX_SUCCESS) {
  371. TRACE_OCALL_FAIL();
  372. return -1;
  373. }
  374. if (ret == -1)
  375. errno = get_errno();
  376. return ret;
  377. }
  378. ssize_t
  379. recvmsg(int sockfd, struct msghdr *msg, int flags)
  380. {
  381. ssize_t ret;
  382. int i;
  383. char *p;
  384. struct msghdr *msg1;
  385. uint64 total_size = sizeof(struct msghdr) + (uint64)msg->msg_namelen
  386. + (uint64)msg->msg_controllen;
  387. total_size += sizeof(struct iovec) * (msg->msg_iovlen);
  388. for (i = 0; i < msg->msg_iovlen; i++) {
  389. total_size += msg->msg_iov[i].iov_len;
  390. }
  391. if (total_size >= UINT32_MAX)
  392. return -1;
  393. msg1 = BH_MALLOC((uint32)total_size);
  394. if (msg1 == NULL)
  395. return -1;
  396. memset(msg1, 0, total_size);
  397. p = (char *)(uintptr_t)sizeof(struct msghdr);
  398. if (msg->msg_name != NULL) {
  399. msg1->msg_name = p;
  400. p += msg->msg_namelen;
  401. }
  402. if (msg->msg_control != NULL) {
  403. msg1->msg_control = p;
  404. p += msg->msg_controllen;
  405. }
  406. if (msg->msg_iov != NULL) {
  407. msg1->msg_iov = (struct iovec *)p;
  408. p += (uintptr_t)(sizeof(struct iovec) * (msg->msg_iovlen));
  409. for (i = 0; i < msg->msg_iovlen; i++) {
  410. msg1->msg_iov[i].iov_base = p;
  411. msg1->msg_iov[i].iov_len = msg->msg_iov[i].iov_len;
  412. p += msg->msg_iov[i].iov_len;
  413. }
  414. }
  415. if (ocall_recvmsg(&ret, sockfd, (void *)msg1, (uint32)total_size, flags)
  416. != SGX_SUCCESS) {
  417. TRACE_OCALL_FAIL();
  418. return -1;
  419. }
  420. p = (char *)(uintptr_t)(sizeof(struct msghdr));
  421. if (msg1->msg_name != NULL) {
  422. memcpy(msg->msg_name, (uintptr_t)p + (char *)msg1,
  423. (size_t)msg1->msg_namelen);
  424. p += msg1->msg_namelen;
  425. }
  426. if (msg1->msg_control != NULL) {
  427. memcpy(msg->msg_control, (uintptr_t)p + (char *)msg1,
  428. (size_t)msg1->msg_control);
  429. p += msg->msg_controllen;
  430. }
  431. if (msg1->msg_iov != NULL) {
  432. p += (uintptr_t)(sizeof(struct iovec) * (msg1->msg_iovlen));
  433. for (i = 0; i < msg1->msg_iovlen; i++) {
  434. memcpy(msg->msg_iov[i].iov_base, (uintptr_t)p + (char *)msg1,
  435. (size_t)(msg1->msg_iov[i].iov_len));
  436. p += msg1->msg_iov[i].iov_len;
  437. }
  438. }
  439. if (ret == -1)
  440. errno = get_errno();
  441. return ret;
  442. }
  443. int
  444. shutdown(int sockfd, int how)
  445. {
  446. int ret;
  447. if (ocall_shutdown(&ret, sockfd, how) != SGX_SUCCESS) {
  448. TRACE_OCALL_FAIL();
  449. return -1;
  450. }
  451. if (ret == -1)
  452. errno = get_errno();
  453. return ret;
  454. }
  455. int
  456. os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
  457. unsigned int *addrlen)
  458. {
  459. struct sockaddr addr_tmp;
  460. unsigned int len = sizeof(struct sockaddr);
  461. if (ocall_accept(sock, server_sock, &addr_tmp, &len, len) != SGX_SUCCESS) {
  462. TRACE_OCALL_FAIL();
  463. return -1;
  464. }
  465. if (*sock < 0) {
  466. errno = get_errno();
  467. return BHT_ERROR;
  468. }
  469. return BHT_OK;
  470. }
  471. int
  472. os_socket_bind(bh_socket_t socket, const char *host, int *port)
  473. {
  474. struct sockaddr_in addr;
  475. struct linger ling;
  476. unsigned int socklen;
  477. int ret;
  478. assert(host);
  479. assert(port);
  480. ling.l_onoff = 1;
  481. ling.l_linger = 0;
  482. if (ocall_fcntl_long(&ret, socket, F_SETFD, FD_CLOEXEC) != SGX_SUCCESS) {
  483. TRACE_OCALL_FAIL();
  484. return -1;
  485. }
  486. if (ret < 0) {
  487. goto fail;
  488. }
  489. if (ocall_setsockopt(&ret, socket, SOL_SOCKET, SO_LINGER, &ling,
  490. sizeof(ling))
  491. != SGX_SUCCESS) {
  492. TRACE_OCALL_FAIL();
  493. return -1;
  494. }
  495. if (ret < 0) {
  496. goto fail;
  497. }
  498. addr.sin_addr.s_addr = inet_addr(host);
  499. addr.sin_port = htons(*port);
  500. addr.sin_family = AF_INET;
  501. if (ocall_bind(&ret, socket, &addr, sizeof(addr)) != SGX_SUCCESS) {
  502. TRACE_OCALL_FAIL();
  503. return -1;
  504. }
  505. if (ret < 0) {
  506. goto fail;
  507. }
  508. socklen = sizeof(addr);
  509. if (ocall_getsockname(&ret, socket, (void *)&addr, &socklen, socklen)
  510. != SGX_SUCCESS) {
  511. TRACE_OCALL_FAIL();
  512. return -1;
  513. }
  514. if (ret == -1) {
  515. goto fail;
  516. }
  517. *port = ntohs(addr.sin_port);
  518. return BHT_OK;
  519. fail:
  520. errno = get_errno();
  521. return BHT_ERROR;
  522. }
  523. int
  524. os_socket_close(bh_socket_t socket)
  525. {
  526. int ret;
  527. if (ocall_close(&ret, socket) != SGX_SUCCESS) {
  528. TRACE_OCALL_FAIL();
  529. return -1;
  530. }
  531. if (ret == -1)
  532. errno = get_errno();
  533. return ret;
  534. }
  535. int
  536. os_socket_connect(bh_socket_t socket, const char *addr, int port)
  537. {
  538. struct sockaddr_in addr_in = { 0 };
  539. socklen_t addr_len = sizeof(struct sockaddr_in);
  540. int ret = 0;
  541. if ((ret = textual_addr_to_sockaddr(addr, port, &addr_in)) < 0) {
  542. return ret;
  543. }
  544. if (ocall_connect(&ret, socket, &addr_in, addr_len) != SGX_SUCCESS) {
  545. TRACE_OCALL_FAIL();
  546. return -1;
  547. }
  548. if (ret == -1)
  549. errno = get_errno();
  550. return ret;
  551. }
  552. int
  553. os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
  554. {
  555. int af;
  556. if (!sock) {
  557. return BHT_ERROR;
  558. }
  559. if (is_ipv4) {
  560. af = AF_INET;
  561. }
  562. else {
  563. errno = ENOSYS;
  564. return BHT_ERROR;
  565. }
  566. if (is_tcp) {
  567. if (ocall_socket(sock, af, SOCK_STREAM, IPPROTO_TCP) != SGX_SUCCESS) {
  568. TRACE_OCALL_FAIL();
  569. return -1;
  570. }
  571. }
  572. else {
  573. if (ocall_socket(sock, af, SOCK_DGRAM, 0) != SGX_SUCCESS) {
  574. TRACE_OCALL_FAIL();
  575. return -1;
  576. }
  577. }
  578. if (*sock == -1) {
  579. errno = get_errno();
  580. return BHT_ERROR;
  581. }
  582. return BHT_OK;
  583. }
  584. int
  585. os_socket_inet_network(bool is_ipv4, const char *cp, bh_ip_addr_buffer_t *out)
  586. {
  587. if (!cp)
  588. return BHT_ERROR;
  589. if (is_ipv4) {
  590. if (inet_pton(AF_INET, cp, &out->ipv4) != 1) {
  591. return BHT_ERROR;
  592. }
  593. /* Note: ntohl(INADDR_NONE) == INADDR_NONE */
  594. out->ipv4 = ntohl(out->ipv4);
  595. }
  596. else {
  597. if (inet_pton(AF_INET6, cp, out->ipv6) != 1) {
  598. return BHT_ERROR;
  599. }
  600. for (int i = 0; i < 8; i++) {
  601. out->ipv6[i] = ntohs(out->ipv6[i]);
  602. }
  603. }
  604. return BHT_OK;
  605. }
  606. int
  607. os_socket_listen(bh_socket_t socket, int max_client)
  608. {
  609. int ret;
  610. if (ocall_listen(&ret, socket, max_client) != SGX_SUCCESS) {
  611. TRACE_OCALL_FAIL();
  612. return -1;
  613. }
  614. if (ret == -1)
  615. errno = get_errno();
  616. return ret;
  617. }
  618. int
  619. os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
  620. {
  621. int ret;
  622. if (ocall_recv(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
  623. TRACE_OCALL_FAIL();
  624. errno = ENOSYS;
  625. return -1;
  626. }
  627. if (ret == -1)
  628. errno = get_errno();
  629. return ret;
  630. }
  631. int
  632. os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
  633. bh_sockaddr_t *src_addr)
  634. {
  635. struct sockaddr_in addr;
  636. socklen_t addr_len = sizeof(addr);
  637. ssize_t ret;
  638. if (ocall_recvfrom(&ret, socket, buf, len, flags, &addr, &addr_len,
  639. addr_len)
  640. != SGX_SUCCESS) {
  641. TRACE_OCALL_FAIL();
  642. errno = ENOSYS;
  643. return -1;
  644. }
  645. if (ret < 0) {
  646. errno = get_errno();
  647. return ret;
  648. }
  649. if (src_addr && addr_len > 0) {
  650. if (sockaddr_to_bh_sockaddr((struct sockaddr *)&addr, addr_len,
  651. src_addr)
  652. == BHT_ERROR) {
  653. return -1;
  654. }
  655. }
  656. return ret;
  657. }
  658. int
  659. os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
  660. {
  661. int ret;
  662. if (ocall_send(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
  663. TRACE_OCALL_FAIL();
  664. errno = ENOSYS;
  665. return -1;
  666. }
  667. if (ret == -1)
  668. errno = get_errno();
  669. return ret;
  670. }
  671. int
  672. os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
  673. int flags, const bh_sockaddr_t *dest_addr)
  674. {
  675. struct sockaddr_in addr;
  676. socklen_t addr_len;
  677. ssize_t ret;
  678. if (bh_sockaddr_to_sockaddr(dest_addr, (struct sockaddr *)&addr, &addr_len)
  679. == BHT_ERROR) {
  680. return -1;
  681. }
  682. if (ocall_sendto(&ret, socket, buf, len, flags, (struct sockaddr *)&addr,
  683. addr_len)
  684. != SGX_SUCCESS) {
  685. TRACE_OCALL_FAIL();
  686. errno = ENOSYS;
  687. return -1;
  688. }
  689. if (ret == -1) {
  690. errno = get_errno();
  691. }
  692. return ret;
  693. }
  694. __wasi_errno_t
  695. os_socket_shutdown(bh_socket_t socket)
  696. {
  697. if (shutdown(socket, O_RDWR) != 0) {
  698. return convert_errno(errno);
  699. }
  700. return __WASI_ESUCCESS;
  701. }
  702. int
  703. os_socket_addr_resolve(const char *host, const char *service,
  704. uint8_t *hint_is_tcp, uint8_t *hint_is_ipv4,
  705. bh_addr_info_t *addr_info, size_t addr_info_size,
  706. size_t *max_info_size)
  707. {
  708. errno = ENOSYS;
  709. return BHT_ERROR;
  710. }
  711. int
  712. os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
  713. {
  714. struct sockaddr_in addr;
  715. socklen_t addr_len = sizeof(addr);
  716. int ret;
  717. if (ocall_getsockname(&ret, socket, (struct sockaddr *)&addr, &addr_len,
  718. addr_len)
  719. != SGX_SUCCESS) {
  720. TRACE_OCALL_FAIL();
  721. return BHT_ERROR;
  722. }
  723. if (ret != BHT_OK) {
  724. errno = get_errno();
  725. return BHT_ERROR;
  726. }
  727. return sockaddr_to_bh_sockaddr((struct sockaddr *)&addr, addr_len,
  728. sockaddr);
  729. }
  730. int
  731. os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr)
  732. {
  733. struct sockaddr_in addr;
  734. socklen_t addr_len = sizeof(addr);
  735. int ret;
  736. if (ocall_getpeername(&ret, socket, (void *)&addr, &addr_len, addr_len)
  737. != SGX_SUCCESS) {
  738. TRACE_OCALL_FAIL();
  739. return -1;
  740. }
  741. if (ret != BHT_OK) {
  742. errno = get_errno();
  743. return BHT_ERROR;
  744. }
  745. return sockaddr_to_bh_sockaddr((struct sockaddr *)&addr, addr_len,
  746. sockaddr);
  747. }
  748. int
  749. os_socket_set_send_timeout(bh_socket_t socket, uint64 timeout_us)
  750. {
  751. errno = ENOSYS;
  752. return BHT_ERROR;
  753. }
  754. int
  755. os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us)
  756. {
  757. errno = ENOSYS;
  758. return BHT_ERROR;
  759. }
  760. int
  761. os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us)
  762. {
  763. errno = ENOSYS;
  764. return BHT_ERROR;
  765. }
  766. int
  767. os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us)
  768. {
  769. errno = ENOSYS;
  770. return BHT_ERROR;
  771. }
  772. int
  773. os_socket_set_send_buf_size(bh_socket_t socket, size_t bufsiz)
  774. {
  775. errno = ENOSYS;
  776. return BHT_ERROR;
  777. }
  778. int
  779. os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz)
  780. {
  781. errno = ENOSYS;
  782. return BHT_ERROR;
  783. }
  784. int
  785. os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz)
  786. {
  787. errno = ENOSYS;
  788. return BHT_ERROR;
  789. }
  790. int
  791. os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz)
  792. {
  793. errno = ENOSYS;
  794. return BHT_ERROR;
  795. }
  796. int
  797. os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled)
  798. {
  799. return os_socket_setbooloption(socket, SOL_SOCKET, SO_KEEPALIVE,
  800. is_enabled);
  801. }
  802. int
  803. os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled)
  804. {
  805. return os_socket_getbooloption(socket, SOL_SOCKET, SO_KEEPALIVE,
  806. is_enabled);
  807. }
  808. int
  809. os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled)
  810. {
  811. return os_socket_setbooloption(socket, SOL_SOCKET, SO_REUSEADDR,
  812. is_enabled);
  813. }
  814. int
  815. os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled)
  816. {
  817. return os_socket_getbooloption(socket, SOL_SOCKET, SO_REUSEADDR,
  818. is_enabled);
  819. }
  820. int
  821. os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled)
  822. {
  823. return os_socket_setbooloption(socket, SOL_SOCKET, SO_REUSEPORT,
  824. is_enabled);
  825. }
  826. int
  827. os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled)
  828. {
  829. return os_socket_getbooloption(socket, SOL_SOCKET, SO_REUSEPORT,
  830. is_enabled);
  831. }
  832. int
  833. os_socket_set_linger(bh_socket_t socket, bool is_enabled, int linger_s)
  834. {
  835. errno = ENOSYS;
  836. return BHT_ERROR;
  837. }
  838. int
  839. os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
  840. {
  841. errno = ENOSYS;
  842. return BHT_ERROR;
  843. }
  844. int
  845. os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled)
  846. {
  847. return os_socket_setbooloption(socket, IPPROTO_TCP, TCP_NODELAY,
  848. is_enabled);
  849. }
  850. int
  851. os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled)
  852. {
  853. return os_socket_getbooloption(socket, IPPROTO_TCP, TCP_NODELAY,
  854. is_enabled);
  855. }
  856. int
  857. os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled)
  858. {
  859. return os_socket_setbooloption(socket, IPPROTO_TCP, TCP_QUICKACK,
  860. is_enabled);
  861. }
  862. int
  863. os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled)
  864. {
  865. return os_socket_getbooloption(socket, IPPROTO_TCP, TCP_QUICKACK,
  866. is_enabled);
  867. }
  868. int
  869. os_socket_set_tcp_keep_idle(bh_socket_t socket, uint32 time_s)
  870. {
  871. errno = ENOSYS;
  872. return BHT_ERROR;
  873. }
  874. int
  875. os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32 *time_s)
  876. {
  877. errno = ENOSYS;
  878. return BHT_ERROR;
  879. }
  880. int
  881. os_socket_set_tcp_keep_intvl(bh_socket_t socket, uint32 time_s)
  882. {
  883. errno = ENOSYS;
  884. return BHT_ERROR;
  885. }
  886. int
  887. os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32 *time_s)
  888. {
  889. errno = ENOSYS;
  890. return BHT_ERROR;
  891. }
  892. int
  893. os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled)
  894. {
  895. return os_socket_setbooloption(socket, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
  896. is_enabled);
  897. }
  898. int
  899. os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
  900. {
  901. return os_socket_getbooloption(socket, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
  902. is_enabled);
  903. }
  904. int
  905. os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled)
  906. {
  907. if (ipv6) {
  908. return os_socket_setbooloption(socket, IPPROTO_IPV6,
  909. IPV6_MULTICAST_LOOP, is_enabled);
  910. }
  911. else {
  912. return os_socket_setbooloption(socket, IPPROTO_IP, IP_MULTICAST_LOOP,
  913. is_enabled);
  914. }
  915. }
  916. int
  917. os_socket_get_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool *is_enabled)
  918. {
  919. if (ipv6) {
  920. return os_socket_getbooloption(socket, IPPROTO_IPV6,
  921. IPV6_MULTICAST_LOOP, is_enabled);
  922. }
  923. else {
  924. return os_socket_getbooloption(socket, IPPROTO_IP, IP_MULTICAST_LOOP,
  925. is_enabled);
  926. }
  927. }
  928. int
  929. os_socket_set_ip_add_membership(bh_socket_t socket,
  930. bh_ip_addr_buffer_t *imr_multiaddr,
  931. uint32_t imr_interface, bool is_ipv6)
  932. {
  933. errno = ENOSYS;
  934. return BHT_ERROR;
  935. }
  936. int
  937. os_socket_set_ip_drop_membership(bh_socket_t socket,
  938. bh_ip_addr_buffer_t *imr_multiaddr,
  939. uint32_t imr_interface, bool is_ipv6)
  940. {
  941. errno = ENOSYS;
  942. return BHT_ERROR;
  943. }
  944. int
  945. os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
  946. {
  947. errno = ENOSYS;
  948. return BHT_ERROR;
  949. }
  950. int
  951. os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s)
  952. {
  953. errno = ENOSYS;
  954. return BHT_ERROR;
  955. }
  956. int
  957. os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
  958. {
  959. errno = ENOSYS;
  960. return BHT_ERROR;
  961. }
  962. int
  963. os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
  964. {
  965. errno = ENOSYS;
  966. return BHT_ERROR;
  967. }
  968. int
  969. os_socket_set_ipv6_only(bh_socket_t socket, bool is_enabled)
  970. {
  971. return os_socket_setbooloption(socket, IPPROTO_IPV6, IPV6_V6ONLY,
  972. is_enabled);
  973. }
  974. int
  975. os_socket_get_ipv6_only(bh_socket_t socket, bool *is_enabled)
  976. {
  977. return os_socket_getbooloption(socket, IPPROTO_IPV6, IPV6_V6ONLY,
  978. is_enabled);
  979. }
  980. int
  981. os_socket_set_broadcast(bh_socket_t socket, bool is_enabled)
  982. {
  983. return os_socket_setbooloption(socket, SOL_SOCKET, SO_BROADCAST,
  984. is_enabled);
  985. }
  986. int
  987. os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled)
  988. {
  989. return os_socket_getbooloption(socket, SOL_SOCKET, SO_BROADCAST,
  990. is_enabled);
  991. }
  992. #endif