Просмотр исходного кода

linux-sgx: Implement POSIX calls based on getsockname and set/getbooloption (#1574)

Jämes Ménétrey 3 лет назад
Родитель
Сommit
78c38d088e
2 измененных файлов с 314 добавлено и 58 удалено
  1. 113 58
      core/shared/platform/linux-sgx/sgx_socket.c
  2. 201 0
      core/shared/platform/linux-sgx/sgx_socket.h

+ 113 - 58
core/shared/platform/linux-sgx/sgx_socket.c

@@ -289,6 +289,52 @@ bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr,
     }
 }
 
+static int
+os_socket_setbooloption(bh_socket_t socket, int level, int optname,
+                        bool is_enabled)
+{
+    int option = (int)is_enabled;
+    int ret;
+
+    if (ocall_setsockopt(&ret, socket, level, optname, &option, sizeof(option))
+        != SGX_SUCCESS) {
+        TRACE_OCALL_FAIL();
+        return BHT_ERROR;
+    }
+
+    if (ret != 0) {
+        errno = get_errno();
+        return BHT_ERROR;
+    }
+
+    return BHT_OK;
+}
+
+static int
+os_socket_getbooloption(bh_socket_t socket, int level, int optname,
+                        bool *is_enabled)
+{
+    assert(is_enabled);
+
+    int optval;
+    socklen_t optval_size = sizeof(optval);
+    int ret;
+    if (ocall_getsockopt(&ret, socket, level, optname, &optval, optval_size,
+                         &optval_size)
+        != SGX_SUCCESS) {
+        TRACE_OCALL_FAIL();
+        return BHT_ERROR;
+    }
+
+    if (ret != 0) {
+        errno = get_errno();
+        return BHT_ERROR;
+    }
+
+    *is_enabled = (bool)optval;
+    return BHT_OK;
+}
+
 int
 socket(int domain, int type, int protocol)
 {
@@ -811,9 +857,24 @@ os_socket_addr_resolve(const char *host, const char *service,
 int
 os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
 {
-    errno = ENOSYS;
+    struct sockaddr_in addr;
+    socklen_t addr_len = sizeof(addr);
+    int ret;
 
-    return BHT_ERROR;
+    if (ocall_getsockname(&ret, socket, (struct sockaddr *)&addr, &addr_len,
+                          addr_len)
+        != SGX_SUCCESS) {
+        TRACE_OCALL_FAIL();
+        return BHT_ERROR;
+    }
+
+    if (ret != BHT_OK) {
+        errno = get_errno();
+        return BHT_ERROR;
+    }
+
+    return sockaddr_to_bh_sockaddr((struct sockaddr *)&addr, addr_len,
+                                   sockaddr);
 }
 
 int
@@ -905,49 +966,43 @@ os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz)
 int
 os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_setbooloption(socket, SOL_SOCKET, SO_KEEPALIVE,
+                                   is_enabled);
 }
 
 int
 os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_getbooloption(socket, SOL_SOCKET, SO_KEEPALIVE,
+                                   is_enabled);
 }
 
 int
 os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_setbooloption(socket, SOL_SOCKET, SO_REUSEADDR,
+                                   is_enabled);
 }
 
 int
 os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_getbooloption(socket, SOL_SOCKET, SO_REUSEADDR,
+                                   is_enabled);
 }
 
 int
 os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_setbooloption(socket, SOL_SOCKET, SO_REUSEPORT,
+                                   is_enabled);
 }
 
 int
 os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_getbooloption(socket, SOL_SOCKET, SO_REUSEPORT,
+                                   is_enabled);
 }
 
 int
@@ -969,33 +1024,29 @@ os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
 int
 os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_setbooloption(socket, IPPROTO_TCP, TCP_NODELAY,
+                                   is_enabled);
 }
 
 int
 os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_getbooloption(socket, IPPROTO_TCP, TCP_NODELAY,
+                                   is_enabled);
 }
 
 int
 os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_setbooloption(socket, IPPROTO_TCP, TCP_QUICKACK,
+                                   is_enabled);
 }
 
 int
 os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_getbooloption(socket, IPPROTO_TCP, TCP_QUICKACK,
+                                   is_enabled);
 }
 
 int
@@ -1033,33 +1084,41 @@ os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32 *time_s)
 int
 os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_setbooloption(socket, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
+                                   is_enabled);
 }
 
 int
 os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_getbooloption(socket, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
+                                   is_enabled);
 }
 
 int
 os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    if (ipv6) {
+        return os_socket_setbooloption(socket, IPPROTO_IPV6,
+                                       IPV6_MULTICAST_LOOP, is_enabled);
+    }
+    else {
+        return os_socket_setbooloption(socket, IPPROTO_IP, IP_MULTICAST_LOOP,
+                                       is_enabled);
+    }
 }
 
 int
 os_socket_get_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool *is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    if (ipv6) {
+        return os_socket_getbooloption(socket, IPPROTO_IPV6,
+                                       IPV6_MULTICAST_LOOP, is_enabled);
+    }
+    else {
+        return os_socket_getbooloption(socket, IPPROTO_IP, IP_MULTICAST_LOOP,
+                                       is_enabled);
+    }
 }
 
 int
@@ -1115,35 +1174,31 @@ os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
 }
 
 int
-os_socket_set_ipv6_only(bh_socket_t socket, bool option)
+os_socket_set_ipv6_only(bh_socket_t socket, bool is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_setbooloption(socket, IPPROTO_IPV6, IPV6_V6ONLY,
+                                   is_enabled);
 }
 
 int
-os_socket_get_ipv6_only(bh_socket_t socket, bool *option)
+os_socket_get_ipv6_only(bh_socket_t socket, bool *is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_getbooloption(socket, IPPROTO_IPV6, IPV6_V6ONLY,
+                                   is_enabled);
 }
 
 int
 os_socket_set_broadcast(bh_socket_t socket, bool is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_setbooloption(socket, SOL_SOCKET, SO_BROADCAST,
+                                   is_enabled);
 }
 
 int
 os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled)
 {
-    errno = ENOSYS;
-
-    return BHT_ERROR;
+    return os_socket_getbooloption(socket, SOL_SOCKET, SO_BROADCAST,
+                                   is_enabled);
 }
 
 #endif

+ 201 - 0
core/shared/platform/linux-sgx/sgx_socket.h

@@ -12,10 +12,211 @@
 extern "C" {
 #endif
 
+/* For setsockopt(2) */
 #define SOL_SOCKET 1
 
+#define SO_DEBUG 1
+#define SO_REUSEADDR 2
 #define SO_TYPE 3
+#define SO_ERROR 4
+#define SO_DONTROUTE 5
+#define SO_BROADCAST 6
+#define SO_SNDBUF 7
+#define SO_RCVBUF 8
+#define SO_SNDBUFFORCE 32
+#define SO_RCVBUFFORCE 33
+#define SO_KEEPALIVE 9
+#define SO_OOBINLINE 10
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
 #define SO_LINGER 13
+#define SO_BSDCOMPAT 14
+#define SO_REUSEPORT 15
+#define SO_PASSCRED 16
+#define SO_PEERCRED 17
+#define SO_RCVLOWAT 18
+#define SO_SNDLOWAT 19
+#define SO_RCVTIMEO_OLD 20
+#define SO_SNDTIMEO_OLD 21
+
+/* User-settable options (used with setsockopt) */
+#define TCP_NODELAY 1               /* Don't delay send to coalesce packets  */
+#define TCP_MAXSEG 2                /* Set maximum segment size  */
+#define TCP_CORK 3                  /* Control sending of partial frames  */
+#define TCP_KEEPIDLE 4              /* Start keeplives after this period */
+#define TCP_KEEPINTVL 5             /* Interval between keepalives */
+#define TCP_KEEPCNT 6               /* Number of keepalives before death */
+#define TCP_SYNCNT 7                /* Number of SYN retransmits */
+#define TCP_LINGER2 8               /* Life time of orphaned FIN-WAIT-2 state */
+#define TCP_DEFER_ACCEPT 9          /* Wake up listener only when data arrive */
+#define TCP_WINDOW_CLAMP 10         /* Bound advertised window */
+#define TCP_INFO 11                 /* Information about this connection. */
+#define TCP_QUICKACK 12             /* Bock/reenable quick ACKs.  */
+#define TCP_CONGESTION 13           /* Congestion control algorithm.  */
+#define TCP_MD5SIG 14               /* TCP MD5 Signature (RFC2385) */
+#define TCP_COOKIE_TRANSACTIONS 15  /* TCP Cookie Transactions */
+#define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/
+#define TCP_THIN_DUPACK 17          /* Fast retrans. after 1 dupack */
+#define TCP_USER_TIMEOUT 18         /* How long for loss retry before timeout */
+#define TCP_REPAIR 19               /* TCP sock is under repair right now */
+#define TCP_REPAIR_QUEUE 20         /* Set TCP queue to repair */
+#define TCP_QUEUE_SEQ 21            /* Set sequence number of repaired queue. */
+#define TCP_REPAIR_OPTIONS 22       /* Repair TCP connection options */
+#define TCP_FASTOPEN 23             /* Enable FastOpen on listeners */
+#define TCP_TIMESTAMP 24            /* TCP time stamp */
+#define TCP_NOTSENT_LOWAT                                                    \
+    25                       /* Limit number of unsent bytes in write queue. \
+                              */
+#define TCP_CC_INFO 26       /* Get Congestion Control (optional) info.  */
+#define TCP_SAVE_SYN 27      /* Record SYN headers for new connections.  */
+#define TCP_SAVED_SYN 28     /* Get SYN headers recorded for connection.  */
+#define TCP_REPAIR_WINDOW 29 /* Get/set window parameters.  */
+#define TCP_FASTOPEN_CONNECT 30   /* Attempt FastOpen with connect.  */
+#define TCP_ULP 31                /* Attach a ULP to a TCP connection.  */
+#define TCP_MD5SIG_EXT 32         /* TCP MD5 Signature with extensions.  */
+#define TCP_FASTOPEN_KEY 33       /* Set the key for Fast Open (cookie).  */
+#define TCP_FASTOPEN_NO_COOKIE 34 /* Enable TFO without a TFO cookie.  */
+#define TCP_ZEROCOPY_RECEIVE 35
+#define TCP_INQ 36 /* Notify bytes available to read as a cmsg on read.  */
+#define TCP_CM_INQ TCP_INQ
+#define TCP_TX_DELAY 37 /* Delay outgoing packets by XX usec.  */
+
+/* Standard well-defined IP protocols.  */
+#define IPPROTO_IP 0        /* Dummy protocol for TCP.  */
+#define IPPROTO_ICMP 1      /* Internet Control Message Protocol.  */
+#define IPPROTO_IGMP 2      /* Internet Group Management Protocol. */
+#define IPPROTO_IPIP 4      /* IPIP tunnels (older KA9Q tunnels use 94).  */
+#define IPPROTO_TCP 6       /* Transmission Control Protocol.  */
+#define IPPROTO_EGP 8       /* Exterior Gateway Protocol.  */
+#define IPPROTO_PUP 12      /* PUP protocol.  */
+#define IPPROTO_UDP 17      /* User Datagram Protocol.  */
+#define IPPROTO_IDP 22      /* XNS IDP protocol.  */
+#define IPPROTO_TP 29       /* SO Transport Protocol Class 4.  */
+#define IPPROTO_DCCP 33     /* Datagram Congestion Control Protocol.  */
+#define IPPROTO_IPV6 41     /* IPv6 header.  */
+#define IPPROTO_RSVP 46     /* Reservation Protocol.  */
+#define IPPROTO_GRE 47      /* General Routing Encapsulation.  */
+#define IPPROTO_ESP 50      /* encapsulating security payload.  */
+#define IPPROTO_AH 51       /* authentication header.  */
+#define IPPROTO_MTP 92      /* Multicast Transport Protocol.  */
+#define IPPROTO_BEETPH 94   /* IP option pseudo header for BEET.  */
+#define IPPROTO_ENCAP 98    /* Encapsulation Header.  */
+#define IPPROTO_PIM 103     /* Protocol Independent Multicast.  */
+#define IPPROTO_COMP 108    /* Compression Header Protocol.  */
+#define IPPROTO_SCTP 132    /* Stream Control Transmission Protocol.  */
+#define IPPROTO_UDPLITE 136 /* UDP-Lite protocol.  */
+#define IPPROTO_MPLS 137    /* MPLS in IP.  */
+#define IPPROTO_RAW 255     /* Raw IP packets.  */
+
+#define IP_ROUTER_ALERT 5 /* bool */
+#define IP_PKTINFO 8      /* bool */
+#define IP_PKTOPTIONS 9
+#define IP_PMTUDISC 10     /* obsolete name? */
+#define IP_MTU_DISCOVER 10 /* int; see below */
+#define IP_RECVERR 11      /* bool */
+#define IP_RECVTTL 12      /* bool */
+#define IP_RECVTOS 13      /* bool */
+#define IP_MTU 14          /* int */
+#define IP_FREEBIND 15
+#define IP_IPSEC_POLICY 16
+#define IP_XFRM_POLICY 17
+#define IP_PASSSEC 18
+#define IP_TRANSPARENT 19
+#define IP_MULTICAST_ALL 49 /* bool */
+
+/* TProxy original addresses */
+#define IP_ORIGDSTADDR 20
+#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
+#define IP_MINTTL 21
+#define IP_NODEFRAG 22
+#define IP_CHECKSUM 23
+#define IP_BIND_ADDRESS_NO_PORT 24
+#define IP_RECVFRAGSIZE 25
+#define IP_PMTUDISC_DONT 0
+#define IP_PMTUDISC_WANT 1
+#define IP_PMTUDISC_DO 2
+#define IP_PMTUDISC_PROBE 3
+#define IP_PMTUDISC_INTERFACE 4
+#define IP_PMTUDISC_OMIT 5
+#define IP_MULTICAST_IF 32
+#define IP_MULTICAST_TTL 33
+#define IP_MULTICAST_LOOP 34
+#define IP_ADD_MEMBERSHIP 35
+#define IP_DROP_MEMBERSHIP 36
+#define IP_UNBLOCK_SOURCE 37
+#define IP_BLOCK_SOURCE 38
+#define IP_ADD_SOURCE_MEMBERSHIP 39
+#define IP_DROP_SOURCE_MEMBERSHIP 40
+#define IP_MSFILTER 41
+#define IP_MULTICAST_ALL 49
+#define IP_UNICAST_IF 50
+
+#define IPV6_ADDRFORM 1
+#define IPV6_2292PKTINFO 2
+#define IPV6_2292HOPOPTS 3
+#define IPV6_2292DSTOPTS 4
+#define IPV6_2292RTHDR 5
+#define IPV6_2292PKTOPTIONS 6
+#define IPV6_CHECKSUM 7
+#define IPV6_2292HOPLIMIT 8
+
+#define SCM_SRCRT IPV6_RXSRCRT
+
+#define IPV6_NEXTHOP 9
+#define IPV6_AUTHHDR 10
+#define IPV6_UNICAST_HOPS 16
+#define IPV6_MULTICAST_IF 17
+#define IPV6_MULTICAST_HOPS 18
+#define IPV6_MULTICAST_LOOP 19
+#define IPV6_JOIN_GROUP 20
+#define IPV6_LEAVE_GROUP 21
+#define IPV6_ROUTER_ALERT 22
+#define IPV6_MTU_DISCOVER 23
+#define IPV6_MTU 24
+#define IPV6_RECVERR 25
+#define IPV6_V6ONLY 26
+#define IPV6_JOIN_ANYCAST 27
+#define IPV6_LEAVE_ANYCAST 28
+#define IPV6_MULTICAST_ALL 29
+#define IPV6_ROUTER_ALERT_ISOLATE 30
+#define IPV6_IPSEC_POLICY 34
+#define IPV6_XFRM_POLICY 35
+#define IPV6_HDRINCL 36
+
+/* Advanced API (RFC3542) (1).  */
+#define IPV6_RECVPKTINFO 49
+#define IPV6_PKTINFO 50
+#define IPV6_RECVHOPLIMIT 51
+#define IPV6_HOPLIMIT 52
+#define IPV6_RECVHOPOPTS 53
+#define IPV6_HOPOPTS 54
+#define IPV6_RTHDRDSTOPTS 55
+#define IPV6_RECVRTHDR 56
+#define IPV6_RTHDR 57
+#define IPV6_RECVDSTOPTS 58
+#define IPV6_DSTOPTS 59
+#define IPV6_RECVPATHMTU 60
+#define IPV6_PATHMTU 61
+#define IPV6_DONTFRAG 62
+
+/* Advanced API (RFC3542) (2).  */
+#define IPV6_RECVTCLASS 66
+#define IPV6_TCLASS 67
+
+#define IPV6_AUTOFLOWLABEL 70
+
+/* RFC5014.  */
+#define IPV6_ADDR_PREFERENCES 72
+
+/* RFC5082.  */
+#define IPV6_MINHOPCOUNT 73
+
+#define IPV6_ORIGDSTADDR 74
+#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR
+#define IPV6_TRANSPARENT 75
+#define IPV6_UNICAST_IF 76
+#define IPV6_RECVFRAGSIZE 77
+#define IPV6_FREEBIND 78
 
 #define SOCK_STREAM 1
 #define SOCK_DGRAM 2