Skip to content

Commit e2a3f0f

Browse files
linux-sgx: Implement socket API getpeername, recvfrom and sendto (#1556)
Implement some of the popular socket APIs left unimplemented for SGX, following the merge of dev/socket.
1 parent 3094b20 commit e2a3f0f

File tree

4 files changed

+159
-11
lines changed

4 files changed

+159
-11
lines changed

core/shared/platform/common/posix/posix_socket.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,12 @@ os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
261261
return ret;
262262
}
263263

264-
if (src_addr) {
265-
sockaddr_to_bh_sockaddr((struct sockaddr *)&sock_addr, socklen,
266-
src_addr);
264+
if (src_addr && socklen > 0) {
265+
if (sockaddr_to_bh_sockaddr((struct sockaddr *)&sock_addr, socklen,
266+
src_addr)
267+
== BHT_ERROR) {
268+
return -1;
269+
}
267270
}
268271

269272
return ret;
@@ -391,8 +394,14 @@ os_socket_addr_resolve(const char *host, const char *service,
391394
continue;
392395
}
393396

394-
sockaddr_to_bh_sockaddr(res->ai_addr, sizeof(struct sockaddr_in),
395-
&addr_info[pos].sockaddr);
397+
ret = sockaddr_to_bh_sockaddr(res->ai_addr,
398+
sizeof(struct sockaddr_in),
399+
&addr_info[pos].sockaddr);
400+
401+
if (ret == BHT_ERROR) {
402+
freeaddrinfo(result);
403+
return BHT_ERROR;
404+
}
396405

397406
addr_info[pos].is_tcp = res->ai_socktype == SOCK_STREAM;
398407
}

core/shared/platform/linux-sgx/sgx_socket.c

Lines changed: 116 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ int
3131
ocall_getsockname(int *p_ret, int sockfd, void *addr, uint32_t *addrlen,
3232
uint32_t addr_size);
3333

34+
int
35+
ocall_getpeername(int *p_ret, int sockfd, void *addr, uint32_t *addrlen,
36+
uint32_t addr_size);
37+
3438
int
3539
ocall_getsockopt(int *p_ret, int sockfd, int level, int optname, void *val_buf,
3640
unsigned int val_buf_size, void *len_buf);
@@ -41,13 +45,21 @@ ocall_listen(int *p_ret, int sockfd, int backlog);
4145
int
4246
ocall_recv(int *p_ret, int sockfd, void *buf, size_t len, int flags);
4347

48+
int
49+
ocall_recvfrom(ssize_t *p_ret, int sockfd, void *buf, size_t len, int flags,
50+
void *src_addr, uint32_t *addrlen, uint32_t addr_size);
51+
4452
int
4553
ocall_recvmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
4654
unsigned int msg_buf_size, int flags);
4755

4856
int
4957
ocall_send(int *p_ret, int sockfd, const void *buf, size_t len, int flags);
5058

59+
int
60+
ocall_sendto(ssize_t *p_ret, int sockfd, const void *buf, size_t len, int flags,
61+
void *dest_addr, uint32_t addrlen);
62+
5163
int
5264
ocall_sendmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
5365
unsigned int msg_buf_size, int flags);
@@ -237,6 +249,46 @@ textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr_in *out)
237249
return BHT_OK;
238250
}
239251

252+
static int
253+
sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr, socklen_t socklen,
254+
bh_sockaddr_t *bh_sockaddr)
255+
{
256+
switch (sockaddr->sa_family) {
257+
case AF_INET:
258+
{
259+
struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr;
260+
261+
assert(socklen >= sizeof(struct sockaddr_in));
262+
263+
bh_sockaddr->port = ntohs(addr->sin_port);
264+
bh_sockaddr->addr_bufer.ipv4 = ntohl(addr->sin_addr.s_addr);
265+
bh_sockaddr->is_ipv4 = true;
266+
return BHT_OK;
267+
}
268+
default:
269+
errno = EAFNOSUPPORT;
270+
return BHT_ERROR;
271+
}
272+
}
273+
274+
static int
275+
bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr,
276+
struct sockaddr *sockaddr, socklen_t *socklen)
277+
{
278+
if (bh_sockaddr->is_ipv4) {
279+
struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr;
280+
addr->sin_port = htons(bh_sockaddr->port);
281+
addr->sin_family = AF_INET;
282+
addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_bufer.ipv4);
283+
*socklen = sizeof(*addr);
284+
return BHT_OK;
285+
}
286+
else {
287+
errno = EAFNOSUPPORT;
288+
return BHT_ERROR;
289+
}
290+
}
291+
240292
int
241293
socket(int domain, int type, int protocol)
242294
{
@@ -651,6 +703,7 @@ os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
651703
int ret;
652704

653705
if (ocall_recv(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
706+
TRACE_OCALL_FAIL();
654707
errno = ENOSYS;
655708
return -1;
656709
}
@@ -665,9 +718,32 @@ int
665718
os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
666719
bh_sockaddr_t *src_addr)
667720
{
668-
errno = ENOSYS;
721+
struct sockaddr_in addr;
722+
socklen_t addr_len = sizeof(addr);
723+
ssize_t ret;
669724

670-
return BHT_ERROR;
725+
if (ocall_recvfrom(&ret, socket, buf, len, flags, &addr, &addr_len,
726+
addr_len)
727+
!= SGX_SUCCESS) {
728+
TRACE_OCALL_FAIL();
729+
errno = ENOSYS;
730+
return -1;
731+
}
732+
733+
if (ret < 0) {
734+
errno = get_errno();
735+
return ret;
736+
}
737+
738+
if (src_addr && addr_len > 0) {
739+
if (sockaddr_to_bh_sockaddr((struct sockaddr *)&addr, addr_len,
740+
src_addr)
741+
== BHT_ERROR) {
742+
return -1;
743+
}
744+
}
745+
746+
return ret;
671747
}
672748

673749
int
@@ -676,6 +752,7 @@ os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
676752
int ret;
677753

678754
if (ocall_send(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
755+
TRACE_OCALL_FAIL();
679756
errno = ENOSYS;
680757
return -1;
681758
}
@@ -690,9 +767,28 @@ int
690767
os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
691768
int flags, const bh_sockaddr_t *dest_addr)
692769
{
693-
errno = ENOSYS;
770+
struct sockaddr_in addr;
771+
socklen_t addr_len;
772+
ssize_t ret;
694773

695-
return BHT_ERROR;
774+
if (bh_sockaddr_to_sockaddr(dest_addr, (struct sockaddr *)&addr, &addr_len)
775+
== BHT_ERROR) {
776+
return -1;
777+
}
778+
779+
if (ocall_sendto(&ret, socket, buf, len, flags, (struct sockaddr *)&addr,
780+
addr_len)
781+
!= SGX_SUCCESS) {
782+
TRACE_OCALL_FAIL();
783+
errno = ENOSYS;
784+
return -1;
785+
}
786+
787+
if (ret == -1) {
788+
errno = get_errno();
789+
}
790+
791+
return ret;
696792
}
697793

698794
int
@@ -723,9 +819,23 @@ os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
723819
int
724820
os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr)
725821
{
726-
errno = ENOSYS;
822+
struct sockaddr_in addr;
823+
socklen_t addr_len = sizeof(addr);
824+
int ret;
727825

728-
return BHT_ERROR;
826+
if (ocall_getpeername(&ret, socket, (void *)&addr, &addr_len, addr_len)
827+
!= SGX_SUCCESS) {
828+
TRACE_OCALL_FAIL();
829+
return -1;
830+
}
831+
832+
if (ret != BHT_OK) {
833+
errno = get_errno();
834+
return BHT_ERROR;
835+
}
836+
837+
return sockaddr_to_bh_sockaddr((struct sockaddr *)&addr, addr_len,
838+
sockaddr);
729839
}
730840

731841
int

core/shared/platform/linux-sgx/sgx_wamr.edl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,24 @@ enclave {
124124
int ocall_connect(int sockfd, [in, size=addrlen]void *addr, uint32_t addrlen);
125125
int ocall_getsockname(int sockfd, [out, size=addr_size]void *addr,
126126
[in, out, size=4]uint32_t *addrlen, uint32_t addr_size);
127+
int ocall_getpeername(int sockfd, [out, size=addr_size]void *addr,
128+
[in, out, size=4]uint32_t *addrlen, uint32_t addr_size);
127129
int ocall_getsockopt(int sockfd, int level, int optname,
128130
[out, size=val_buf_size]void *val_buf,
129131
unsigned int val_buf_size,
130132
[in, out, size=4]void *len_buf);
131133
int ocall_listen(int sockfd, int backlog);
132134
int ocall_recv(int sockfd, [out, size=len]void *buf, size_t len, int flags);
135+
ssize_t ocall_recvfrom(int sockfd, [out, size=len]void *buf, size_t len, int flags,
136+
[out, size=addr_size]void *src_addr,
137+
[in, out, size=4]uint32_t *addrlen, uint32_t addr_size);
133138
ssize_t ocall_recvmsg(int sockfd,
134139
[in, out, size=msg_buf_size]void *msg_buf,
135140
unsigned int msg_buf_size,
136141
int flags);
137142
int ocall_send(int sockfd, [in, size=len]const void *buf, size_t len, int flags);
143+
ssize_t ocall_sendto(int sockfd, [in, size=len]const void *buf, size_t len, int flags,
144+
[in, size=addrlen]void *dest_addr, uint32_t addrlen);
138145
ssize_t ocall_sendmsg(int sockfd,
139146
[in, size=msg_buf_size]void *msg_buf,
140147
unsigned int msg_buf_size,

core/shared/platform/linux-sgx/untrusted/socket.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ ocall_getsockname(int sockfd, void *addr, uint32_t *addrlen, uint32_t addr_size)
9595
return getsockname(sockfd, (struct sockaddr *)addr, addrlen);
9696
}
9797

98+
int
99+
ocall_getpeername(int sockfd, void *addr, uint32_t *addrlen, uint32_t addr_size)
100+
{
101+
return getpeername(sockfd, (struct sockaddr *)addr, addrlen);
102+
}
103+
98104
int
99105
ocall_listen(int sockfd, int backlog)
100106
{
@@ -113,12 +119,28 @@ ocall_recv(int sockfd, void *buf, size_t len, int flags)
113119
return recv(sockfd, buf, len, flags);
114120
}
115121

122+
ssize_t
123+
ocall_recvfrom(int sockfd, void *buf, size_t len, int flags, void *src_addr,
124+
uint32_t *addrlen, uint32_t addr_size)
125+
{
126+
return recvfrom(sockfd, buf, len, flags, (struct sockaddr *)src_addr,
127+
addrlen);
128+
}
129+
116130
int
117131
ocall_send(int sockfd, const void *buf, size_t len, int flags)
118132
{
119133
return send(sockfd, buf, len, flags);
120134
}
121135

136+
ssize_t
137+
ocall_sendto(int sockfd, const void *buf, size_t len, int flags,
138+
void *dest_addr, uint32_t addrlen)
139+
{
140+
return sendto(sockfd, buf, len, flags, (struct sockaddr *)dest_addr,
141+
addrlen);
142+
}
143+
122144
int
123145
ocall_connect(int sockfd, void *addr, uint32_t addrlen)
124146
{

0 commit comments

Comments
 (0)