sgx_socket.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226
  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. #include "libc_errno.h"
  8. #ifndef SGX_DISABLE_WASI
  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