sgx_socket.c 26 KB

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