sgx_socket.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222
  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. int
  313. setsockopt(int sockfd, int level, int optname, const void *optval,
  314. socklen_t optlen)
  315. {
  316. int ret;
  317. if (ocall_setsockopt(&ret, sockfd, level, optname, (void *)optval, optlen)
  318. != SGX_SUCCESS) {
  319. TRACE_OCALL_FAIL();
  320. return -1;
  321. }
  322. if (ret == -1)
  323. errno = get_errno();
  324. return ret;
  325. }
  326. ssize_t
  327. sendmsg(int sockfd, const struct msghdr *msg, int flags)
  328. {
  329. ssize_t ret;
  330. int i;
  331. char *p;
  332. struct msghdr *msg1;
  333. uint64 total_size = sizeof(struct msghdr) + (uint64)msg->msg_namelen
  334. + (uint64)msg->msg_controllen;
  335. total_size += sizeof(struct iovec) * (msg->msg_iovlen);
  336. for (i = 0; i < msg->msg_iovlen; i++) {
  337. total_size += msg->msg_iov[i].iov_len;
  338. }
  339. if (total_size >= UINT32_MAX)
  340. return -1;
  341. msg1 = BH_MALLOC((uint32)total_size);
  342. if (msg1 == NULL)
  343. return -1;
  344. p = (char *)(uintptr_t)sizeof(struct msghdr);
  345. if (msg->msg_name != NULL) {
  346. msg1->msg_name = p;
  347. memcpy((uintptr_t)p + (char *)msg1, msg->msg_name,
  348. (size_t)msg->msg_namelen);
  349. p += msg->msg_namelen;
  350. }
  351. if (msg->msg_control != NULL) {
  352. msg1->msg_control = p;
  353. memcpy((uintptr_t)p + (char *)msg1, msg->msg_control,
  354. (size_t)msg->msg_control);
  355. p += msg->msg_controllen;
  356. }
  357. if (msg->msg_iov != NULL) {
  358. msg1->msg_iov = (struct iovec *)p;
  359. p += (uintptr_t)(sizeof(struct iovec) * (msg->msg_iovlen));
  360. for (i = 0; i < msg->msg_iovlen; i++) {
  361. msg1->msg_iov[i].iov_base = p;
  362. msg1->msg_iov[i].iov_len = msg->msg_iov[i].iov_len;
  363. memcpy((uintptr_t)p + (char *)msg1, msg->msg_iov[i].iov_base,
  364. (size_t)(msg->msg_iov[i].iov_len));
  365. p += msg->msg_iov[i].iov_len;
  366. }
  367. }
  368. if (ocall_sendmsg(&ret, sockfd, (void *)msg1, (uint32)total_size, flags)
  369. != SGX_SUCCESS) {
  370. TRACE_OCALL_FAIL();
  371. return -1;
  372. }
  373. if (ret == -1)
  374. errno = get_errno();
  375. return ret;
  376. }
  377. ssize_t
  378. recvmsg(int sockfd, struct msghdr *msg, int flags)
  379. {
  380. ssize_t ret;
  381. int i;
  382. char *p;
  383. struct msghdr *msg1;
  384. uint64 total_size = sizeof(struct msghdr) + (uint64)msg->msg_namelen
  385. + (uint64)msg->msg_controllen;
  386. total_size += sizeof(struct iovec) * (msg->msg_iovlen);
  387. for (i = 0; i < msg->msg_iovlen; i++) {
  388. total_size += msg->msg_iov[i].iov_len;
  389. }
  390. if (total_size >= UINT32_MAX)
  391. return -1;
  392. msg1 = BH_MALLOC((uint32)total_size);
  393. if (msg1 == NULL)
  394. return -1;
  395. memset(msg1, 0, total_size);
  396. p = (char *)(uintptr_t)sizeof(struct msghdr);
  397. if (msg->msg_name != NULL) {
  398. msg1->msg_name = p;
  399. p += msg->msg_namelen;
  400. }
  401. if (msg->msg_control != NULL) {
  402. msg1->msg_control = p;
  403. p += msg->msg_controllen;
  404. }
  405. if (msg->msg_iov != NULL) {
  406. msg1->msg_iov = (struct iovec *)p;
  407. p += (uintptr_t)(sizeof(struct iovec) * (msg->msg_iovlen));
  408. for (i = 0; i < msg->msg_iovlen; i++) {
  409. msg1->msg_iov[i].iov_base = p;
  410. msg1->msg_iov[i].iov_len = msg->msg_iov[i].iov_len;
  411. p += msg->msg_iov[i].iov_len;
  412. }
  413. }
  414. if (ocall_recvmsg(&ret, sockfd, (void *)msg1, (uint32)total_size, flags)
  415. != SGX_SUCCESS) {
  416. TRACE_OCALL_FAIL();
  417. return -1;
  418. }
  419. p = (char *)(uintptr_t)(sizeof(struct msghdr));
  420. if (msg1->msg_name != NULL) {
  421. memcpy(msg->msg_name, (uintptr_t)p + (char *)msg1,
  422. (size_t)msg1->msg_namelen);
  423. p += msg1->msg_namelen;
  424. }
  425. if (msg1->msg_control != NULL) {
  426. memcpy(msg->msg_control, (uintptr_t)p + (char *)msg1,
  427. (size_t)msg1->msg_control);
  428. p += msg->msg_controllen;
  429. }
  430. if (msg1->msg_iov != NULL) {
  431. p += (uintptr_t)(sizeof(struct iovec) * (msg1->msg_iovlen));
  432. for (i = 0; i < msg1->msg_iovlen; i++) {
  433. memcpy(msg->msg_iov[i].iov_base, (uintptr_t)p + (char *)msg1,
  434. (size_t)(msg1->msg_iov[i].iov_len));
  435. p += msg1->msg_iov[i].iov_len;
  436. }
  437. }
  438. if (ret == -1)
  439. errno = get_errno();
  440. return ret;
  441. }
  442. int
  443. shutdown(int sockfd, int how)
  444. {
  445. int ret;
  446. if (ocall_shutdown(&ret, sockfd, how) != SGX_SUCCESS) {
  447. TRACE_OCALL_FAIL();
  448. return -1;
  449. }
  450. if (ret == -1)
  451. errno = get_errno();
  452. return ret;
  453. }
  454. int
  455. os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
  456. unsigned int *addrlen)
  457. {
  458. struct sockaddr addr_tmp;
  459. unsigned int len = sizeof(struct sockaddr);
  460. if (ocall_accept(sock, server_sock, &addr_tmp, &len, len) != SGX_SUCCESS) {
  461. TRACE_OCALL_FAIL();
  462. return -1;
  463. }
  464. if (*sock < 0) {
  465. errno = get_errno();
  466. return BHT_ERROR;
  467. }
  468. return BHT_OK;
  469. }
  470. int
  471. os_socket_bind(bh_socket_t socket, const char *host, int *port)
  472. {
  473. struct sockaddr_in addr;
  474. struct linger ling;
  475. unsigned int socklen;
  476. int ret;
  477. assert(host);
  478. assert(port);
  479. ling.l_onoff = 1;
  480. ling.l_linger = 0;
  481. if (ocall_fcntl_long(&ret, socket, F_SETFD, FD_CLOEXEC) != SGX_SUCCESS) {
  482. TRACE_OCALL_FAIL();
  483. return -1;
  484. }
  485. if (ret < 0) {
  486. goto fail;
  487. }
  488. if (ocall_setsockopt(&ret, socket, SOL_SOCKET, SO_LINGER, &ling,
  489. sizeof(ling))
  490. != SGX_SUCCESS) {
  491. TRACE_OCALL_FAIL();
  492. return -1;
  493. }
  494. if (ret < 0) {
  495. goto fail;
  496. }
  497. addr.sin_addr.s_addr = inet_addr(host);
  498. addr.sin_port = htons(*port);
  499. addr.sin_family = AF_INET;
  500. if (ocall_bind(&ret, socket, &addr, sizeof(addr)) != SGX_SUCCESS) {
  501. TRACE_OCALL_FAIL();
  502. return -1;
  503. }
  504. if (ret < 0) {
  505. goto fail;
  506. }
  507. socklen = sizeof(addr);
  508. if (ocall_getsockname(&ret, socket, (void *)&addr, &socklen, socklen)
  509. != SGX_SUCCESS) {
  510. TRACE_OCALL_FAIL();
  511. return -1;
  512. }
  513. if (ret == -1) {
  514. goto fail;
  515. }
  516. *port = ntohs(addr.sin_port);
  517. return BHT_OK;
  518. fail:
  519. errno = get_errno();
  520. return BHT_ERROR;
  521. }
  522. int
  523. os_socket_close(bh_socket_t socket)
  524. {
  525. int ret;
  526. if (ocall_close(&ret, socket) != SGX_SUCCESS) {
  527. TRACE_OCALL_FAIL();
  528. return -1;
  529. }
  530. if (ret == -1)
  531. errno = get_errno();
  532. return ret;
  533. }
  534. int
  535. os_socket_connect(bh_socket_t socket, const char *addr, int port)
  536. {
  537. struct sockaddr_in addr_in = { 0 };
  538. socklen_t addr_len = sizeof(struct sockaddr_in);
  539. int ret = 0;
  540. if ((ret = textual_addr_to_sockaddr(addr, port, &addr_in)) < 0) {
  541. return ret;
  542. }
  543. if (ocall_connect(&ret, socket, &addr_in, addr_len) != SGX_SUCCESS) {
  544. TRACE_OCALL_FAIL();
  545. return -1;
  546. }
  547. if (ret == -1)
  548. errno = get_errno();
  549. return ret;
  550. }
  551. int
  552. os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
  553. {
  554. int af;
  555. if (!sock) {
  556. return BHT_ERROR;
  557. }
  558. if (is_ipv4) {
  559. af = AF_INET;
  560. }
  561. else {
  562. errno = ENOSYS;
  563. return BHT_ERROR;
  564. }
  565. if (is_tcp) {
  566. if (ocall_socket(sock, af, SOCK_STREAM, IPPROTO_TCP) != SGX_SUCCESS) {
  567. TRACE_OCALL_FAIL();
  568. return -1;
  569. }
  570. }
  571. else {
  572. if (ocall_socket(sock, af, SOCK_DGRAM, 0) != SGX_SUCCESS) {
  573. TRACE_OCALL_FAIL();
  574. return -1;
  575. }
  576. }
  577. if (*sock == -1) {
  578. errno = get_errno();
  579. return BHT_ERROR;
  580. }
  581. return BHT_OK;
  582. }
  583. int
  584. os_socket_inet_network(bool is_ipv4, const char *cp, bh_ip_addr_buffer_t *out)
  585. {
  586. if (!cp)
  587. return BHT_ERROR;
  588. if (is_ipv4) {
  589. if (inet_pton(AF_INET, cp, &out->ipv4) != 1) {
  590. return BHT_ERROR;
  591. }
  592. /* Note: ntohl(INADDR_NONE) == INADDR_NONE */
  593. out->ipv4 = ntohl(out->ipv4);
  594. }
  595. else {
  596. if (inet_pton(AF_INET6, cp, out->ipv6) != 1) {
  597. return BHT_ERROR;
  598. }
  599. for (int i = 0; i < 8; i++) {
  600. out->ipv6[i] = ntohs(out->ipv6[i]);
  601. }
  602. }
  603. return BHT_OK;
  604. }
  605. int
  606. os_socket_listen(bh_socket_t socket, int max_client)
  607. {
  608. int ret;
  609. if (ocall_listen(&ret, socket, max_client) != SGX_SUCCESS) {
  610. TRACE_OCALL_FAIL();
  611. return -1;
  612. }
  613. if (ret == -1)
  614. errno = get_errno();
  615. return ret;
  616. }
  617. int
  618. os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
  619. {
  620. int ret;
  621. if (ocall_recv(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
  622. TRACE_OCALL_FAIL();
  623. errno = ENOSYS;
  624. return -1;
  625. }
  626. if (ret == -1)
  627. errno = get_errno();
  628. return ret;
  629. }
  630. int
  631. os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
  632. bh_sockaddr_t *src_addr)
  633. {
  634. struct sockaddr_in addr;
  635. socklen_t addr_len = sizeof(addr);
  636. ssize_t ret;
  637. if (ocall_recvfrom(&ret, socket, buf, len, flags, &addr, &addr_len,
  638. addr_len)
  639. != SGX_SUCCESS) {
  640. TRACE_OCALL_FAIL();
  641. errno = ENOSYS;
  642. return -1;
  643. }
  644. if (ret < 0) {
  645. errno = get_errno();
  646. return ret;
  647. }
  648. if (src_addr && addr_len > 0) {
  649. if (sockaddr_to_bh_sockaddr((struct sockaddr *)&addr, addr_len,
  650. src_addr)
  651. == BHT_ERROR) {
  652. return -1;
  653. }
  654. }
  655. return ret;
  656. }
  657. int
  658. os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
  659. {
  660. int ret;
  661. if (ocall_send(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
  662. TRACE_OCALL_FAIL();
  663. errno = ENOSYS;
  664. return -1;
  665. }
  666. if (ret == -1)
  667. errno = get_errno();
  668. return ret;
  669. }
  670. int
  671. os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
  672. int flags, const bh_sockaddr_t *dest_addr)
  673. {
  674. struct sockaddr_in addr;
  675. socklen_t addr_len;
  676. ssize_t ret;
  677. if (bh_sockaddr_to_sockaddr(dest_addr, (struct sockaddr *)&addr, &addr_len)
  678. == BHT_ERROR) {
  679. return -1;
  680. }
  681. if (ocall_sendto(&ret, socket, buf, len, flags, (struct sockaddr *)&addr,
  682. addr_len)
  683. != SGX_SUCCESS) {
  684. TRACE_OCALL_FAIL();
  685. errno = ENOSYS;
  686. return -1;
  687. }
  688. if (ret == -1) {
  689. errno = get_errno();
  690. }
  691. return ret;
  692. }
  693. int
  694. os_socket_shutdown(bh_socket_t socket)
  695. {
  696. return shutdown(socket, O_RDWR);
  697. }
  698. int
  699. os_socket_addr_resolve(const char *host, const char *service,
  700. uint8_t *hint_is_tcp, uint8_t *hint_is_ipv4,
  701. bh_addr_info_t *addr_info, size_t addr_info_size,
  702. size_t *max_info_size)
  703. {
  704. errno = ENOSYS;
  705. return BHT_ERROR;
  706. }
  707. int
  708. os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
  709. {
  710. struct sockaddr_in addr;
  711. socklen_t addr_len = sizeof(addr);
  712. int ret;
  713. if (ocall_getsockname(&ret, socket, (struct sockaddr *)&addr, &addr_len,
  714. addr_len)
  715. != SGX_SUCCESS) {
  716. TRACE_OCALL_FAIL();
  717. return BHT_ERROR;
  718. }
  719. if (ret != BHT_OK) {
  720. errno = get_errno();
  721. return BHT_ERROR;
  722. }
  723. return sockaddr_to_bh_sockaddr((struct sockaddr *)&addr, addr_len,
  724. sockaddr);
  725. }
  726. int
  727. os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr)
  728. {
  729. struct sockaddr_in addr;
  730. socklen_t addr_len = sizeof(addr);
  731. int ret;
  732. if (ocall_getpeername(&ret, socket, (void *)&addr, &addr_len, addr_len)
  733. != SGX_SUCCESS) {
  734. TRACE_OCALL_FAIL();
  735. return -1;
  736. }
  737. if (ret != BHT_OK) {
  738. errno = get_errno();
  739. return BHT_ERROR;
  740. }
  741. return sockaddr_to_bh_sockaddr((struct sockaddr *)&addr, addr_len,
  742. sockaddr);
  743. }
  744. int
  745. os_socket_set_send_timeout(bh_socket_t socket, uint64 timeout_us)
  746. {
  747. errno = ENOSYS;
  748. return BHT_ERROR;
  749. }
  750. int
  751. os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us)
  752. {
  753. errno = ENOSYS;
  754. return BHT_ERROR;
  755. }
  756. int
  757. os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us)
  758. {
  759. errno = ENOSYS;
  760. return BHT_ERROR;
  761. }
  762. int
  763. os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us)
  764. {
  765. errno = ENOSYS;
  766. return BHT_ERROR;
  767. }
  768. int
  769. os_socket_set_send_buf_size(bh_socket_t socket, size_t bufsiz)
  770. {
  771. errno = ENOSYS;
  772. return BHT_ERROR;
  773. }
  774. int
  775. os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz)
  776. {
  777. errno = ENOSYS;
  778. return BHT_ERROR;
  779. }
  780. int
  781. os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz)
  782. {
  783. errno = ENOSYS;
  784. return BHT_ERROR;
  785. }
  786. int
  787. os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz)
  788. {
  789. errno = ENOSYS;
  790. return BHT_ERROR;
  791. }
  792. int
  793. os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled)
  794. {
  795. return os_socket_setbooloption(socket, SOL_SOCKET, SO_KEEPALIVE,
  796. is_enabled);
  797. }
  798. int
  799. os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled)
  800. {
  801. return os_socket_getbooloption(socket, SOL_SOCKET, SO_KEEPALIVE,
  802. is_enabled);
  803. }
  804. int
  805. os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled)
  806. {
  807. return os_socket_setbooloption(socket, SOL_SOCKET, SO_REUSEADDR,
  808. is_enabled);
  809. }
  810. int
  811. os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled)
  812. {
  813. return os_socket_getbooloption(socket, SOL_SOCKET, SO_REUSEADDR,
  814. is_enabled);
  815. }
  816. int
  817. os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled)
  818. {
  819. return os_socket_setbooloption(socket, SOL_SOCKET, SO_REUSEPORT,
  820. is_enabled);
  821. }
  822. int
  823. os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled)
  824. {
  825. return os_socket_getbooloption(socket, SOL_SOCKET, SO_REUSEPORT,
  826. is_enabled);
  827. }
  828. int
  829. os_socket_set_linger(bh_socket_t socket, bool is_enabled, int linger_s)
  830. {
  831. errno = ENOSYS;
  832. return BHT_ERROR;
  833. }
  834. int
  835. os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
  836. {
  837. errno = ENOSYS;
  838. return BHT_ERROR;
  839. }
  840. int
  841. os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled)
  842. {
  843. return os_socket_setbooloption(socket, IPPROTO_TCP, TCP_NODELAY,
  844. is_enabled);
  845. }
  846. int
  847. os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled)
  848. {
  849. return os_socket_getbooloption(socket, IPPROTO_TCP, TCP_NODELAY,
  850. is_enabled);
  851. }
  852. int
  853. os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled)
  854. {
  855. return os_socket_setbooloption(socket, IPPROTO_TCP, TCP_QUICKACK,
  856. is_enabled);
  857. }
  858. int
  859. os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled)
  860. {
  861. return os_socket_getbooloption(socket, IPPROTO_TCP, TCP_QUICKACK,
  862. is_enabled);
  863. }
  864. int
  865. os_socket_set_tcp_keep_idle(bh_socket_t socket, uint32 time_s)
  866. {
  867. errno = ENOSYS;
  868. return BHT_ERROR;
  869. }
  870. int
  871. os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32 *time_s)
  872. {
  873. errno = ENOSYS;
  874. return BHT_ERROR;
  875. }
  876. int
  877. os_socket_set_tcp_keep_intvl(bh_socket_t socket, uint32 time_s)
  878. {
  879. errno = ENOSYS;
  880. return BHT_ERROR;
  881. }
  882. int
  883. os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32 *time_s)
  884. {
  885. errno = ENOSYS;
  886. return BHT_ERROR;
  887. }
  888. int
  889. os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled)
  890. {
  891. return os_socket_setbooloption(socket, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
  892. is_enabled);
  893. }
  894. int
  895. os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
  896. {
  897. return os_socket_getbooloption(socket, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
  898. is_enabled);
  899. }
  900. int
  901. os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled)
  902. {
  903. if (ipv6) {
  904. return os_socket_setbooloption(socket, IPPROTO_IPV6,
  905. IPV6_MULTICAST_LOOP, is_enabled);
  906. }
  907. else {
  908. return os_socket_setbooloption(socket, IPPROTO_IP, IP_MULTICAST_LOOP,
  909. is_enabled);
  910. }
  911. }
  912. int
  913. os_socket_get_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool *is_enabled)
  914. {
  915. if (ipv6) {
  916. return os_socket_getbooloption(socket, IPPROTO_IPV6,
  917. IPV6_MULTICAST_LOOP, is_enabled);
  918. }
  919. else {
  920. return os_socket_getbooloption(socket, IPPROTO_IP, IP_MULTICAST_LOOP,
  921. is_enabled);
  922. }
  923. }
  924. int
  925. os_socket_set_ip_add_membership(bh_socket_t socket,
  926. bh_ip_addr_buffer_t *imr_multiaddr,
  927. uint32_t imr_interface, bool is_ipv6)
  928. {
  929. errno = ENOSYS;
  930. return BHT_ERROR;
  931. }
  932. int
  933. os_socket_set_ip_drop_membership(bh_socket_t socket,
  934. bh_ip_addr_buffer_t *imr_multiaddr,
  935. uint32_t imr_interface, bool is_ipv6)
  936. {
  937. errno = ENOSYS;
  938. return BHT_ERROR;
  939. }
  940. int
  941. os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
  942. {
  943. errno = ENOSYS;
  944. return BHT_ERROR;
  945. }
  946. int
  947. os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s)
  948. {
  949. errno = ENOSYS;
  950. return BHT_ERROR;
  951. }
  952. int
  953. os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
  954. {
  955. errno = ENOSYS;
  956. return BHT_ERROR;
  957. }
  958. int
  959. os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
  960. {
  961. errno = ENOSYS;
  962. return BHT_ERROR;
  963. }
  964. int
  965. os_socket_set_ipv6_only(bh_socket_t socket, bool is_enabled)
  966. {
  967. return os_socket_setbooloption(socket, IPPROTO_IPV6, IPV6_V6ONLY,
  968. is_enabled);
  969. }
  970. int
  971. os_socket_get_ipv6_only(bh_socket_t socket, bool *is_enabled)
  972. {
  973. return os_socket_getbooloption(socket, IPPROTO_IPV6, IPV6_V6ONLY,
  974. is_enabled);
  975. }
  976. int
  977. os_socket_set_broadcast(bh_socket_t socket, bool is_enabled)
  978. {
  979. return os_socket_setbooloption(socket, SOL_SOCKET, SO_BROADCAST,
  980. is_enabled);
  981. }
  982. int
  983. os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled)
  984. {
  985. return os_socket_getbooloption(socket, SOL_SOCKET, SO_BROADCAST,
  986. is_enabled);
  987. }
  988. #endif