drivers: nsos: initial support for getsockopt() and setsockopt()
Add initial support for getsockopt() and setsockopt() on SOL_SOCKET level. Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
This commit is contained in:
parent
29f81872ce
commit
a3f2b5f4b3
4 changed files with 556 additions and 0 deletions
|
|
@ -126,6 +126,10 @@ int nsos_adapt_sendto(int fd, const void *buf, size_t len, int flags,
|
|||
int nsos_adapt_sendmsg(int fd, const struct nsos_mid_msghdr *msg_mid, int flags);
|
||||
int nsos_adapt_recvfrom(int fd, void *buf, size_t len, int flags,
|
||||
struct nsos_mid_sockaddr *addr, size_t *addrlen);
|
||||
int nsos_adapt_getsockopt(int fd, int level, int optname,
|
||||
void *optval, size_t *optlen);
|
||||
int nsos_adapt_setsockopt(int fd, int level, int optname,
|
||||
const void *optval, size_t optlen);
|
||||
|
||||
void nsos_adapt_poll_add(struct nsos_mid_pollfd *pollfd);
|
||||
void nsos_adapt_poll_remove(struct nsos_mid_pollfd *pollfd);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
* Linux (bottom) side of NSOS (Native Simulator Offloaded Sockets).
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
|
|
@ -25,6 +27,7 @@
|
|||
#include "nsos_errno.h"
|
||||
#include "nsos_fcntl.h"
|
||||
#include "nsos_netdb.h"
|
||||
#include "nsos_socket.h"
|
||||
|
||||
#include "board_soc.h"
|
||||
#include "irq_ctrl.h"
|
||||
|
|
@ -511,6 +514,167 @@ int nsos_adapt_recvfrom(int fd, void *buf, size_t len, int flags,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int nsos_adapt_getsockopt_int(int fd, int level, int optname,
|
||||
void *optval, size_t *nsos_mid_optlen)
|
||||
{
|
||||
socklen_t optlen = *nsos_mid_optlen;
|
||||
int ret;
|
||||
|
||||
ret = getsockopt(fd, level, optname, optval, &optlen);
|
||||
if (ret < 0) {
|
||||
return -errno_to_nsos_mid(errno);
|
||||
}
|
||||
|
||||
*nsos_mid_optlen = optlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nsos_adapt_getsockopt(int fd, int nsos_mid_level, int nsos_mid_optname,
|
||||
void *nsos_mid_optval, size_t *nsos_mid_optlen)
|
||||
{
|
||||
switch (nsos_mid_level) {
|
||||
case NSOS_MID_SOL_SOCKET:
|
||||
switch (nsos_mid_optname) {
|
||||
case NSOS_MID_SO_ERROR: {
|
||||
int err;
|
||||
socklen_t optlen = sizeof(err);
|
||||
int ret;
|
||||
|
||||
ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &optlen);
|
||||
if (ret < 0) {
|
||||
return -errno_to_nsos_mid(errno);
|
||||
}
|
||||
|
||||
*(int *)nsos_mid_optval = errno_to_nsos_mid(err);
|
||||
|
||||
return 0;
|
||||
}
|
||||
case NSOS_MID_SO_TYPE: {
|
||||
int type;
|
||||
socklen_t optlen = sizeof(type);
|
||||
int ret;
|
||||
int err;
|
||||
|
||||
ret = getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &optlen);
|
||||
if (ret < 0) {
|
||||
return -errno_to_nsos_mid(errno);
|
||||
}
|
||||
|
||||
err = socket_type_to_nsos_mid(type, nsos_mid_optval);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
case NSOS_MID_SO_PROTOCOL: {
|
||||
int proto;
|
||||
socklen_t optlen = sizeof(proto);
|
||||
int ret;
|
||||
int err;
|
||||
|
||||
ret = getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &proto, &optlen);
|
||||
if (ret < 0) {
|
||||
return -errno_to_nsos_mid(errno);
|
||||
}
|
||||
|
||||
err = socket_proto_to_nsos_mid(proto, nsos_mid_optval);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
case NSOS_MID_SO_DOMAIN: {
|
||||
int family;
|
||||
socklen_t optlen = sizeof(family);
|
||||
int ret;
|
||||
int err;
|
||||
|
||||
ret = getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &family, &optlen);
|
||||
if (ret < 0) {
|
||||
return -errno_to_nsos_mid(errno);
|
||||
}
|
||||
|
||||
err = socket_family_to_nsos_mid(family, nsos_mid_optval);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
case NSOS_MID_SO_RCVBUF:
|
||||
return nsos_adapt_getsockopt_int(fd, SOL_SOCKET, SO_RCVBUF,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
case NSOS_MID_SO_SNDBUF:
|
||||
return nsos_adapt_getsockopt_int(fd, SOL_SOCKET, SO_SNDBUF,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
case NSOS_MID_SO_REUSEADDR:
|
||||
return nsos_adapt_getsockopt_int(fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
case NSOS_MID_SO_REUSEPORT:
|
||||
return nsos_adapt_getsockopt_int(fd, SOL_SOCKET, SO_REUSEPORT,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
case NSOS_MID_SO_LINGER:
|
||||
return nsos_adapt_getsockopt_int(fd, SOL_SOCKET, SO_LINGER,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
case NSOS_MID_SO_KEEPALIVE:
|
||||
return nsos_adapt_getsockopt_int(fd, SOL_SOCKET, SO_KEEPALIVE,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
}
|
||||
}
|
||||
|
||||
return -NSOS_MID_EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int nsos_adapt_setsockopt_int(int fd, int level, int optname,
|
||||
const void *optval, size_t optlen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = setsockopt(fd, level, optname, optval, optlen);
|
||||
if (ret < 0) {
|
||||
return -errno_to_nsos_mid(errno);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nsos_adapt_setsockopt(int fd, int nsos_mid_level, int nsos_mid_optname,
|
||||
const void *nsos_mid_optval, size_t nsos_mid_optlen)
|
||||
{
|
||||
switch (nsos_mid_level) {
|
||||
case NSOS_MID_SOL_SOCKET:
|
||||
switch (nsos_mid_optname) {
|
||||
case NSOS_MID_SO_PRIORITY:
|
||||
return nsos_adapt_setsockopt_int(fd, SOL_SOCKET, SO_PRIORITY,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
|
||||
case NSOS_MID_SO_RCVBUF:
|
||||
return nsos_adapt_setsockopt_int(fd, SOL_SOCKET, SO_RCVBUF,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
case NSOS_MID_SO_SNDBUF:
|
||||
return nsos_adapt_setsockopt_int(fd, SOL_SOCKET, SO_SNDBUF,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
case NSOS_MID_SO_REUSEADDR:
|
||||
return nsos_adapt_setsockopt_int(fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
case NSOS_MID_SO_REUSEPORT:
|
||||
return nsos_adapt_setsockopt_int(fd, SOL_SOCKET, SO_REUSEPORT,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
case NSOS_MID_SO_LINGER:
|
||||
return nsos_adapt_setsockopt_int(fd, SOL_SOCKET, SO_LINGER,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
case NSOS_MID_SO_KEEPALIVE:
|
||||
return nsos_adapt_setsockopt_int(fd, SOL_SOCKET, SO_KEEPALIVE,
|
||||
nsos_mid_optval, nsos_mid_optlen);
|
||||
}
|
||||
}
|
||||
|
||||
return -NSOS_MID_EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#define MAP_POLL_EPOLL(_event_from, _event_to) \
|
||||
if (events_from & (_event_from)) { \
|
||||
events_from &= ~(_event_from); \
|
||||
|
|
|
|||
83
drivers/net/nsos_socket.h
Normal file
83
drivers/net/nsos_socket.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* Copyright (c) 2024 Marcin Niestroj
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __DRIVERS_NET_NSOS_SOCKET_H__
|
||||
#define __DRIVERS_NET_NSOS_SOCKET_H__
|
||||
|
||||
/**
|
||||
* @name Socket level options (NSOS_MID_SOL_SOCKET)
|
||||
* @{
|
||||
*/
|
||||
/** Socket-level option */
|
||||
#define NSOS_MID_SOL_SOCKET 1
|
||||
|
||||
/* Socket options for NSOS_MID_SOL_SOCKET level */
|
||||
|
||||
/** Recording debugging information (ignored, for compatibility) */
|
||||
#define NSOS_MID_SO_DEBUG 1
|
||||
/** address reuse */
|
||||
#define NSOS_MID_SO_REUSEADDR 2
|
||||
/** Type of the socket */
|
||||
#define NSOS_MID_SO_TYPE 3
|
||||
/** Async error */
|
||||
#define NSOS_MID_SO_ERROR 4
|
||||
/** Bypass normal routing and send directly to host (ignored, for compatibility) */
|
||||
#define NSOS_MID_SO_DONTROUTE 5
|
||||
/** Transmission of broadcast messages is supported (ignored, for compatibility) */
|
||||
#define NSOS_MID_SO_BROADCAST 6
|
||||
|
||||
/** Size of socket send buffer */
|
||||
#define NSOS_MID_SO_SNDBUF 7
|
||||
/** Size of socket recv buffer */
|
||||
#define NSOS_MID_SO_RCVBUF 8
|
||||
|
||||
/** Enable sending keep-alive messages on connections */
|
||||
#define NSOS_MID_SO_KEEPALIVE 9
|
||||
/** Place out-of-band data into receive stream (ignored, for compatibility) */
|
||||
#define NSOS_MID_SO_OOBINLINE 10
|
||||
/** Socket priority */
|
||||
#define NSOS_MID_SO_PRIORITY 12
|
||||
/** Socket lingers on close (ignored, for compatibility) */
|
||||
#define NSOS_MID_SO_LINGER 13
|
||||
/** Allow multiple sockets to reuse a single port */
|
||||
#define NSOS_MID_SO_REUSEPORT 15
|
||||
|
||||
/** Receive low watermark (ignored, for compatibility) */
|
||||
#define NSOS_MID_SO_RCVLOWAT 18
|
||||
/** Send low watermark (ignored, for compatibility) */
|
||||
#define NSOS_MID_SO_SNDLOWAT 19
|
||||
|
||||
/**
|
||||
* Receive timeout
|
||||
* Applies to receive functions like recv(), but not to connect()
|
||||
*/
|
||||
#define NSOS_MID_SO_RCVTIMEO 20
|
||||
/** Send timeout */
|
||||
#define NSOS_MID_SO_SNDTIMEO 21
|
||||
|
||||
/** Bind a socket to an interface */
|
||||
#define NSOS_MID_SO_BINDTODEVICE 25
|
||||
|
||||
/** Socket accepts incoming connections (ignored, for compatibility) */
|
||||
#define NSOS_MID_SO_ACCEPTCONN 30
|
||||
|
||||
/** Timestamp TX packets */
|
||||
#define NSOS_MID_SO_TIMESTAMPING 37
|
||||
/** Protocol used with the socket */
|
||||
#define NSOS_MID_SO_PROTOCOL 38
|
||||
|
||||
/** Domain used with SOCKET */
|
||||
#define NSOS_MID_SO_DOMAIN 39
|
||||
|
||||
/** Enable SOCKS5 for Socket */
|
||||
#define NSOS_MID_SO_SOCKS5 60
|
||||
|
||||
/** Socket TX time (when the data should be sent) */
|
||||
#define NSOS_MID_SO_TXTIME 61
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* __DRIVERS_NET_NSOS_SOCKET_H__ */
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#include "nsos_errno.h"
|
||||
#include "nsos_fcntl.h"
|
||||
#include "nsos_netdb.h"
|
||||
#include "nsos_socket.h"
|
||||
|
||||
#include "nsi_host_trampolines.h"
|
||||
|
||||
|
|
@ -795,6 +796,308 @@ static ssize_t nsos_recvmsg(void *obj, struct msghdr *msg, int flags)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int socket_type_from_nsos_mid(int type_mid, int *type)
|
||||
{
|
||||
switch (type_mid) {
|
||||
case NSOS_MID_SOCK_STREAM:
|
||||
*type = SOCK_STREAM;
|
||||
break;
|
||||
case NSOS_MID_SOCK_DGRAM:
|
||||
*type = SOCK_DGRAM;
|
||||
break;
|
||||
case NSOS_MID_SOCK_RAW:
|
||||
*type = SOCK_RAW;
|
||||
break;
|
||||
default:
|
||||
return -NSOS_MID_ESOCKTNOSUPPORT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int socket_proto_from_nsos_mid(int proto_mid, int *proto)
|
||||
{
|
||||
switch (proto_mid) {
|
||||
case NSOS_MID_IPPROTO_IP:
|
||||
*proto = IPPROTO_IP;
|
||||
break;
|
||||
case NSOS_MID_IPPROTO_ICMP:
|
||||
*proto = IPPROTO_ICMP;
|
||||
break;
|
||||
case NSOS_MID_IPPROTO_IGMP:
|
||||
*proto = IPPROTO_IGMP;
|
||||
break;
|
||||
case NSOS_MID_IPPROTO_IPIP:
|
||||
*proto = IPPROTO_IPIP;
|
||||
break;
|
||||
case NSOS_MID_IPPROTO_TCP:
|
||||
*proto = IPPROTO_TCP;
|
||||
break;
|
||||
case NSOS_MID_IPPROTO_UDP:
|
||||
*proto = IPPROTO_UDP;
|
||||
break;
|
||||
case NSOS_MID_IPPROTO_IPV6:
|
||||
*proto = IPPROTO_IPV6;
|
||||
break;
|
||||
case NSOS_MID_IPPROTO_RAW:
|
||||
*proto = IPPROTO_RAW;
|
||||
break;
|
||||
default:
|
||||
return -NSOS_MID_EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int socket_family_from_nsos_mid(int family_mid, int *family)
|
||||
{
|
||||
switch (family_mid) {
|
||||
case NSOS_MID_AF_UNSPEC:
|
||||
*family = AF_UNSPEC;
|
||||
break;
|
||||
case NSOS_MID_AF_INET:
|
||||
*family = AF_INET;
|
||||
break;
|
||||
case NSOS_MID_AF_INET6:
|
||||
*family = AF_INET6;
|
||||
break;
|
||||
default:
|
||||
return -NSOS_MID_EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nsos_getsockopt_int(struct nsos_socket *sock, int nsos_mid_level, int nsos_mid_optname,
|
||||
void *optval, socklen_t *optlen)
|
||||
{
|
||||
size_t nsos_mid_optlen = sizeof(int);
|
||||
int err;
|
||||
|
||||
if (*optlen != sizeof(int)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = nsos_adapt_getsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET,
|
||||
NSOS_MID_SO_KEEPALIVE, optval, &nsos_mid_optlen);
|
||||
if (err) {
|
||||
errno = errno_from_nsos_mid(-err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*optlen = nsos_mid_optlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nsos_getsockopt(void *obj, int level, int optname,
|
||||
void *optval, socklen_t *optlen)
|
||||
{
|
||||
struct nsos_socket *sock = obj;
|
||||
|
||||
switch (level) {
|
||||
case SOL_SOCKET:
|
||||
switch (optname) {
|
||||
case SO_ERROR: {
|
||||
int nsos_mid_err;
|
||||
int err;
|
||||
|
||||
if (*optlen != sizeof(int)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = nsos_adapt_getsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET,
|
||||
NSOS_MID_SO_ERROR, &nsos_mid_err, NULL);
|
||||
if (err) {
|
||||
errno = errno_from_nsos_mid(-err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*(int *)optval = errno_from_nsos_mid(nsos_mid_err);
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SO_TYPE: {
|
||||
int nsos_mid_type;
|
||||
int err;
|
||||
|
||||
if (*optlen != sizeof(nsos_mid_type)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = nsos_adapt_getsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET,
|
||||
NSOS_MID_SO_TYPE, &nsos_mid_type, NULL);
|
||||
if (err) {
|
||||
errno = errno_from_nsos_mid(-err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = socket_type_from_nsos_mid(nsos_mid_type, optval);
|
||||
if (err) {
|
||||
errno = errno_from_nsos_mid(-err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SO_PROTOCOL: {
|
||||
int nsos_mid_proto;
|
||||
int err;
|
||||
|
||||
if (*optlen != sizeof(nsos_mid_proto)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = nsos_adapt_getsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET,
|
||||
NSOS_MID_SO_PROTOCOL, &nsos_mid_proto, NULL);
|
||||
if (err) {
|
||||
errno = errno_from_nsos_mid(-err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = socket_proto_from_nsos_mid(nsos_mid_proto, optval);
|
||||
if (err) {
|
||||
errno = errno_from_nsos_mid(-err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SO_DOMAIN: {
|
||||
int nsos_mid_family;
|
||||
int err;
|
||||
|
||||
if (*optlen != sizeof(nsos_mid_family)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = nsos_adapt_getsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET,
|
||||
NSOS_MID_SO_DOMAIN, &nsos_mid_family, NULL);
|
||||
if (err) {
|
||||
errno = errno_from_nsos_mid(-err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = socket_family_from_nsos_mid(nsos_mid_family, optval);
|
||||
if (err) {
|
||||
errno = errno_from_nsos_mid(-err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SO_RCVBUF:
|
||||
return nsos_getsockopt_int(sock,
|
||||
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_RCVBUF,
|
||||
optval, optlen);
|
||||
case SO_SNDBUF:
|
||||
return nsos_getsockopt_int(sock,
|
||||
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_SNDBUF,
|
||||
optval, optlen);
|
||||
case SO_REUSEADDR:
|
||||
return nsos_getsockopt_int(sock,
|
||||
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_REUSEADDR,
|
||||
optval, optlen);
|
||||
case SO_REUSEPORT:
|
||||
return nsos_getsockopt_int(sock,
|
||||
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_REUSEPORT,
|
||||
optval, optlen);
|
||||
case SO_KEEPALIVE:
|
||||
return nsos_getsockopt_int(sock,
|
||||
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_KEEPALIVE,
|
||||
optval, optlen);
|
||||
}
|
||||
}
|
||||
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int nsos_setsockopt_int(struct nsos_socket *sock, int nsos_mid_level, int nsos_mid_optname,
|
||||
const void *optval, socklen_t optlen)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (optlen != sizeof(int)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = nsos_adapt_setsockopt(sock->pollfd.fd, nsos_mid_level, nsos_mid_optname,
|
||||
optval, optlen);
|
||||
if (err) {
|
||||
errno = errno_from_nsos_mid(-err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nsos_setsockopt(void *obj, int level, int optname,
|
||||
const void *optval, socklen_t optlen)
|
||||
{
|
||||
struct nsos_socket *sock = obj;
|
||||
|
||||
switch (level) {
|
||||
case SOL_SOCKET:
|
||||
switch (optname) {
|
||||
case SO_PRIORITY: {
|
||||
int nsos_mid_priority;
|
||||
int err;
|
||||
|
||||
if (optlen != sizeof(uint8_t)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsos_mid_priority = *(uint8_t *)optval;
|
||||
|
||||
err = nsos_adapt_setsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET,
|
||||
NSOS_MID_SO_PRIORITY, &nsos_mid_priority,
|
||||
sizeof(nsos_mid_priority));
|
||||
if (err) {
|
||||
errno = errno_from_nsos_mid(-err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SO_RCVBUF:
|
||||
return nsos_setsockopt_int(sock,
|
||||
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_RCVBUF,
|
||||
optval, optlen);
|
||||
case SO_SNDBUF:
|
||||
return nsos_setsockopt_int(sock,
|
||||
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_SNDBUF,
|
||||
optval, optlen);
|
||||
case SO_REUSEADDR:
|
||||
return nsos_setsockopt_int(sock,
|
||||
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_REUSEADDR,
|
||||
optval, optlen);
|
||||
case SO_REUSEPORT:
|
||||
return nsos_setsockopt_int(sock,
|
||||
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_REUSEPORT,
|
||||
optval, optlen);
|
||||
case SO_LINGER:
|
||||
return nsos_setsockopt_int(sock,
|
||||
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_LINGER,
|
||||
optval, optlen);
|
||||
case SO_KEEPALIVE:
|
||||
return nsos_setsockopt_int(sock,
|
||||
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_KEEPALIVE,
|
||||
optval, optlen);
|
||||
}
|
||||
}
|
||||
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct socket_op_vtable nsos_socket_fd_op_vtable = {
|
||||
.fd_vtable = {
|
||||
.read = nsos_read,
|
||||
|
|
@ -810,6 +1113,8 @@ static const struct socket_op_vtable nsos_socket_fd_op_vtable = {
|
|||
.sendmsg = nsos_sendmsg,
|
||||
.recvfrom = nsos_recvfrom,
|
||||
.recvmsg = nsos_recvmsg,
|
||||
.getsockopt = nsos_getsockopt,
|
||||
.setsockopt = nsos_setsockopt,
|
||||
};
|
||||
|
||||
static bool nsos_is_supported(int family, int type, int proto)
|
||||
|
|
|
|||
Loading…
Reference in a new issue