mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-05-16 03:27:39 +08:00
[SAL] Update SAL,Add socketpair sendmsg recvmsg function (#8293)
This commit is contained in:
@@ -174,7 +174,7 @@ int dfs_file_isdir(const char *path);
|
||||
int dfs_file_access(const char *path, mode_t mode);
|
||||
int dfs_file_chdir(const char *path);
|
||||
char *dfs_file_getcwd(char *buf, size_t size);
|
||||
|
||||
char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode);
|
||||
#ifdef RT_USING_SMART
|
||||
int dfs_file_mmap2(struct dfs_file *file, struct dfs_mmap2_args *mmap2);
|
||||
|
||||
|
||||
@@ -207,7 +207,7 @@ struct dfs_dentry* dfs_file_follow_link(struct dfs_dentry *dentry)
|
||||
*
|
||||
* @return new path.
|
||||
*/
|
||||
static char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
|
||||
char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
|
||||
{
|
||||
int index = 0;
|
||||
char *path = RT_NULL;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,28 +15,47 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_MUSLLIBC
|
||||
#if !defined(POLLIN) && !defined(POLLOUT)
|
||||
#define POLLIN (0x01)
|
||||
#define POLLRDNORM (0x01)
|
||||
#define POLLRDBAND (0x01)
|
||||
#define POLLPRI (0x01)
|
||||
|
||||
#define POLLOUT (0x02)
|
||||
#define POLLWRNORM (0x02)
|
||||
#define POLLWRBAND (0x02)
|
||||
|
||||
#define POLLERR (0x04)
|
||||
#define POLLHUP (0x08)
|
||||
#define POLLNVAL (0x10)
|
||||
|
||||
#define POLLIN 0x001
|
||||
#define POLLPRI 0x002
|
||||
#define POLLOUT 0x004
|
||||
#define POLLERR 0x008
|
||||
#define POLLHUP 0x010
|
||||
#define POLLNVAL 0x020
|
||||
#define POLLRDNORM 0x040
|
||||
#define POLLRDBAND 0x080
|
||||
#define POLLWRNORM 0x100
|
||||
#define POLLWRBAND 0x200
|
||||
typedef unsigned int nfds_t;
|
||||
|
||||
struct pollfd
|
||||
{
|
||||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
};
|
||||
#endif
|
||||
#else
|
||||
#if !defined(POLLIN) && !defined(POLLOUT)
|
||||
#define POLLIN 0x1
|
||||
#define POLLOUT 0x2
|
||||
#define POLLERR 0x4
|
||||
#define POLLNVAL 0x8
|
||||
/* Below values are unimplemented */
|
||||
#define POLLRDNORM 0x10
|
||||
#define POLLRDBAND 0x20
|
||||
#define POLLPRI 0x40
|
||||
#define POLLWRNORM 0x80
|
||||
#define POLLWRBAND 0x100
|
||||
#define POLLHUP 0x200
|
||||
typedef unsigned int nfds_t;
|
||||
struct pollfd
|
||||
{
|
||||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
};
|
||||
#endif
|
||||
#endif /* !defined(POLLIN) && !defined(POLLOUT) */
|
||||
|
||||
#define POLLMASK_DEFAULT (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
|
||||
|
||||
@@ -3535,6 +3535,150 @@ static int netflags_muslc_2_lwip(int flags)
|
||||
return flgs;
|
||||
}
|
||||
|
||||
#ifdef ARCH_MM_MMU
|
||||
static int copy_msghdr_from_user(struct msghdr *kmsg, struct msghdr *umsg,
|
||||
struct iovec **out_iov, void **out_msg_control)
|
||||
{
|
||||
size_t iovs_size;
|
||||
struct iovec *uiov, *kiov;
|
||||
size_t iovs_buffer_size = 0;
|
||||
void *iovs_buffer;
|
||||
|
||||
if (!lwp_user_accessable(umsg, sizeof(*umsg)))
|
||||
{
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
lwp_get_from_user(kmsg, umsg, sizeof(*kmsg));
|
||||
|
||||
iovs_size = sizeof(*kmsg->msg_iov) * kmsg->msg_iovlen;
|
||||
if (!lwp_user_accessable(kmsg->msg_iov, iovs_size))
|
||||
{
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* user and kernel */
|
||||
kiov = kmem_get(iovs_size * 2);
|
||||
if (!kiov)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
uiov = (void *)kiov + iovs_size;
|
||||
lwp_get_from_user(uiov, kmsg->msg_iov, iovs_size);
|
||||
|
||||
if (out_iov)
|
||||
{
|
||||
*out_iov = uiov;
|
||||
}
|
||||
kmsg->msg_iov = kiov;
|
||||
|
||||
for (int i = 0; i < kmsg->msg_iovlen; ++i)
|
||||
{
|
||||
/*
|
||||
* We MUST check we can copy data to user after socket done in uiov
|
||||
* otherwise we will be lost the messages from the network!
|
||||
*/
|
||||
if (!lwp_user_accessable(uiov->iov_base, uiov->iov_len))
|
||||
{
|
||||
kmem_put(kmsg->msg_iov);
|
||||
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
iovs_buffer_size += uiov->iov_len;
|
||||
kiov->iov_len = uiov->iov_len;
|
||||
|
||||
++kiov;
|
||||
++uiov;
|
||||
}
|
||||
|
||||
/* msg_iov and msg_control */
|
||||
iovs_buffer = kmem_get(iovs_buffer_size + kmsg->msg_controllen);
|
||||
|
||||
if (!iovs_buffer)
|
||||
{
|
||||
kmem_put(kmsg->msg_iov);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
kiov = kmsg->msg_iov;
|
||||
|
||||
for (int i = 0; i < kmsg->msg_iovlen; ++i)
|
||||
{
|
||||
kiov->iov_base = iovs_buffer;
|
||||
iovs_buffer += kiov->iov_len;
|
||||
++kiov;
|
||||
}
|
||||
|
||||
*out_msg_control = kmsg->msg_control;
|
||||
/* msg_control is the end of the iovs_buffer */
|
||||
kmsg->msg_control = iovs_buffer;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* ARCH_MM_MMU */
|
||||
|
||||
sysret_t sys_recvmsg(int socket, struct msghdr *msg, int flags)
|
||||
{
|
||||
int flgs, ret = -1;
|
||||
struct msghdr kmsg;
|
||||
#ifdef ARCH_MM_MMU
|
||||
void *msg_control;
|
||||
struct iovec *uiov, *kiov;
|
||||
#endif
|
||||
|
||||
if (!msg)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
flgs = netflags_muslc_2_lwip(flags);
|
||||
|
||||
#ifdef ARCH_MM_MMU
|
||||
ret = copy_msghdr_from_user(&kmsg, msg, &uiov, &msg_control);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
ret = recvmsg(socket, &kmsg, flgs);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
goto _free_res;
|
||||
}
|
||||
|
||||
kiov = kmsg.msg_iov;
|
||||
|
||||
for (int i = 0; i < kmsg.msg_iovlen; ++i)
|
||||
{
|
||||
lwp_put_to_user(uiov->iov_base, kiov->iov_base, kiov->iov_len);
|
||||
|
||||
++kiov;
|
||||
++uiov;
|
||||
}
|
||||
|
||||
lwp_put_to_user(msg_control, kmsg.msg_control, kmsg.msg_controllen);
|
||||
lwp_put_to_user(&msg->msg_flags, &kmsg.msg_flags, sizeof(kmsg.msg_flags));
|
||||
|
||||
_free_res:
|
||||
kmem_put(kmsg.msg_iov->iov_base);
|
||||
kmem_put(kmsg.msg_iov);
|
||||
}
|
||||
#else
|
||||
rt_memcpy(&kmsg, msg, sizeof(kmsg));
|
||||
|
||||
ret = recvmsg(socket, &kmsg, flgs);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
msg->msg_flags = kmsg.msg_flags;
|
||||
}
|
||||
#endif /* ARCH_MM_MMU */
|
||||
|
||||
return (ret < 0 ? GET_ERRNO() : ret);
|
||||
}
|
||||
|
||||
sysret_t sys_recvfrom(int socket, void *mem, size_t len, int flags,
|
||||
struct musl_sockaddr *from, socklen_t *fromlen)
|
||||
{
|
||||
@@ -3633,6 +3777,57 @@ sysret_t sys_recv(int socket, void *mem, size_t len, int flags)
|
||||
return (ret < 0 ? GET_ERRNO() : ret);
|
||||
}
|
||||
|
||||
sysret_t sys_sendmsg(int socket, const struct msghdr *msg, int flags)
|
||||
{
|
||||
int flgs, ret = -1;
|
||||
struct msghdr kmsg;
|
||||
#ifdef ARCH_MM_MMU
|
||||
void *msg_control;
|
||||
struct iovec *uiov, *kiov;
|
||||
#endif
|
||||
if (!msg)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
flgs = netflags_muslc_2_lwip(flags);
|
||||
|
||||
#ifdef ARCH_MM_MMU
|
||||
ret = copy_msghdr_from_user(&kmsg, (struct msghdr *)msg, &uiov, &msg_control);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
kiov = kmsg.msg_iov;
|
||||
|
||||
for (int i = 0; i < kmsg.msg_iovlen; ++i)
|
||||
{
|
||||
lwp_get_from_user(kiov->iov_base, uiov->iov_base, kiov->iov_len);
|
||||
|
||||
++kiov;
|
||||
++uiov;
|
||||
}
|
||||
|
||||
lwp_get_from_user(kmsg.msg_control, msg_control, kmsg.msg_controllen);
|
||||
|
||||
ret = sendmsg(socket, &kmsg, flgs);
|
||||
|
||||
kmem_put(kmsg.msg_iov->iov_base);
|
||||
kmem_put(kmsg.msg_iov);
|
||||
}
|
||||
#else
|
||||
rt_memcpy(&kmsg, msg, sizeof(kmsg));
|
||||
|
||||
ret = sendmsg(socket, &kmsg, flgs);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
msg->msg_flags = kmsg.msg_flags;
|
||||
}
|
||||
#endif /* ARCH_MM_MMU */
|
||||
|
||||
return (ret < 0 ? GET_ERRNO() : ret);
|
||||
}
|
||||
|
||||
sysret_t sys_sendto(int socket, const void *dataptr, size_t size, int flags,
|
||||
const struct musl_sockaddr *to, socklen_t tolen)
|
||||
{
|
||||
@@ -3757,6 +3952,30 @@ out:
|
||||
return (fd < 0 ? GET_ERRNO() : fd);
|
||||
}
|
||||
|
||||
sysret_t sys_socketpair(int domain, int type, int protocol, int fd[2])
|
||||
{
|
||||
#ifdef RT_USING_SAL
|
||||
int ret = 0;
|
||||
int k_fd[2];
|
||||
|
||||
if (!lwp_user_accessable((void *)fd, sizeof(int [2])))
|
||||
{
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ret = socketpair(domain, type, protocol, k_fd);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
lwp_put_to_user(fd, k_fd, sizeof(int [2]));
|
||||
}
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return -ELIBACC;
|
||||
#endif
|
||||
}
|
||||
|
||||
sysret_t sys_closesocket(int socket)
|
||||
{
|
||||
return closesocket(socket);
|
||||
@@ -6688,8 +6907,8 @@ const static struct rt_syscall_def func_table[] =
|
||||
SYSCALL_NET(SYSCALL_SIGN(sys_getaddrinfo)),
|
||||
SYSCALL_NET(SYSCALL_SIGN(sys_gethostbyname2_r)), /* 85 */
|
||||
|
||||
SYSCALL_SIGN(sys_notimpl), //network,
|
||||
SYSCALL_SIGN(sys_notimpl), //network,
|
||||
SYSCALL_NET(SYSCALL_SIGN(sys_sendmsg)),
|
||||
SYSCALL_NET(SYSCALL_SIGN(sys_recvmsg)),
|
||||
SYSCALL_SIGN(sys_notimpl), //network,
|
||||
SYSCALL_SIGN(sys_notimpl), //network,
|
||||
SYSCALL_SIGN(sys_notimpl), //network, /* 90 */
|
||||
@@ -6826,6 +7045,8 @@ const static struct rt_syscall_def func_table[] =
|
||||
SYSCALL_SIGN(sys_ftruncate),
|
||||
SYSCALL_SIGN(sys_setitimer),
|
||||
SYSCALL_SIGN(sys_utimensat),
|
||||
SYSCALL_SIGN(sys_notimpl),
|
||||
SYSCALL_SIGN(sys_socketpair), /* 205 */
|
||||
};
|
||||
|
||||
const void *lwp_get_sys_api(rt_uint32_t number)
|
||||
|
||||
@@ -111,7 +111,8 @@ struct netdev
|
||||
extern struct netdev *netdev_list;
|
||||
/* The default network interface device */
|
||||
extern struct netdev *netdev_default;
|
||||
|
||||
/* The local virtual network device */
|
||||
extern struct netdev *netdev_lo;
|
||||
/* The network interface device ping response object */
|
||||
struct netdev_ping_resp
|
||||
{
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
struct netdev *netdev_list = RT_NULL;
|
||||
/* The default network interface device */
|
||||
struct netdev *netdev_default = RT_NULL;
|
||||
/* The local virtual network device */
|
||||
struct netdev *netdev_lo = RT_NULL;
|
||||
/* The global network register callback */
|
||||
static netdev_callback_fn g_netdev_register_callback = RT_NULL;
|
||||
static netdev_callback_fn g_netdev_default_change_callback = RT_NULL;
|
||||
|
||||
@@ -293,44 +293,49 @@ static int inet_poll(struct dfs_file *file, struct rt_pollreq *req)
|
||||
|
||||
static const struct sal_socket_ops lwip_socket_ops =
|
||||
{
|
||||
inet_socket,
|
||||
lwip_close,
|
||||
lwip_bind,
|
||||
lwip_listen,
|
||||
lwip_connect,
|
||||
inet_accept,
|
||||
(int (*)(int, const void *, size_t, int, const struct sockaddr *, socklen_t))lwip_sendto,
|
||||
(int (*)(int, void *, size_t, int, struct sockaddr *, socklen_t *))lwip_recvfrom,
|
||||
lwip_getsockopt,
|
||||
.socket = inet_socket,
|
||||
.closesocket = lwip_close,
|
||||
.bind = lwip_bind,
|
||||
.listen = lwip_listen,
|
||||
.connect = lwip_connect,
|
||||
.accept = inet_accept,
|
||||
.sendto = (int (*)(int, const void *, size_t, int, const struct sockaddr *, socklen_t))lwip_sendto,
|
||||
#if LWIP_VERSION >= 0x20102ff
|
||||
.sendmsg = (int (*)(int, const struct msghdr *, int))lwip_sendmsg,
|
||||
.recvmsg = (int (*)(int, struct msghdr *, int))lwip_recvmsg,
|
||||
#endif
|
||||
.recvfrom = (int (*)(int, void *, size_t, int, struct sockaddr *, socklen_t *))lwip_recvfrom,
|
||||
.getsockopt = lwip_getsockopt,
|
||||
//TODO fix on 1.4.1
|
||||
lwip_setsockopt,
|
||||
lwip_shutdown,
|
||||
lwip_getpeername,
|
||||
inet_getsockname,
|
||||
inet_ioctlsocket,
|
||||
.setsockopt = lwip_setsockopt,
|
||||
.shutdown = lwip_shutdown,
|
||||
.getpeername = lwip_getpeername,
|
||||
.getsockname = inet_getsockname,
|
||||
.ioctlsocket = inet_ioctlsocket,
|
||||
.socketpair = RT_NULL,
|
||||
#ifdef SAL_USING_POSIX
|
||||
inet_poll,
|
||||
.poll = inet_poll,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct sal_netdb_ops lwip_netdb_ops =
|
||||
{
|
||||
lwip_gethostbyname,
|
||||
lwip_gethostbyname_r,
|
||||
lwip_getaddrinfo,
|
||||
lwip_freeaddrinfo,
|
||||
.gethostbyname = lwip_gethostbyname,
|
||||
.gethostbyname_r = lwip_gethostbyname_r,
|
||||
.getaddrinfo = lwip_getaddrinfo,
|
||||
.freeaddrinfo = lwip_freeaddrinfo,
|
||||
};
|
||||
|
||||
static const struct sal_proto_family lwip_inet_family =
|
||||
{
|
||||
AF_INET,
|
||||
.family = AF_INET,
|
||||
#if LWIP_VERSION > 0x2000000
|
||||
AF_INET6,
|
||||
.sec_family = AF_INET6,
|
||||
#else
|
||||
AF_INET,
|
||||
.sec_family = AF_INET,
|
||||
#endif
|
||||
&lwip_socket_ops,
|
||||
&lwip_netdb_ops,
|
||||
.skt_ops = &lwip_socket_ops,
|
||||
.netdb_ops = &lwip_netdb_ops,
|
||||
};
|
||||
|
||||
/* Set lwIP network interface device protocol family information */
|
||||
|
||||
@@ -45,6 +45,9 @@ typedef uint32_t socklen_t;
|
||||
#define SAL_SOCKET_OFFSET 0
|
||||
#endif
|
||||
|
||||
struct sockaddr;
|
||||
struct msghdr;
|
||||
struct addrinfo;
|
||||
struct sal_socket
|
||||
{
|
||||
uint32_t magic; /* SAL socket magic word */
|
||||
@@ -72,6 +75,8 @@ struct sal_socket_ops
|
||||
int (*connect) (int s, const struct sockaddr *name, socklen_t namelen);
|
||||
int (*accept) (int s, struct sockaddr *addr, socklen_t *addrlen);
|
||||
int (*sendto) (int s, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen);
|
||||
int (*sendmsg) (int s, const struct msghdr *message, int flags);
|
||||
int (*recvmsg) (int s, struct msghdr *message, int flags);
|
||||
int (*recvfrom) (int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
|
||||
int (*getsockopt) (int s, int level, int optname, void *optval, socklen_t *optlen);
|
||||
int (*setsockopt) (int s, int level, int optname, const void *optval, socklen_t optlen);
|
||||
@@ -79,6 +84,7 @@ struct sal_socket_ops
|
||||
int (*getpeername)(int s, struct sockaddr *name, socklen_t *namelen);
|
||||
int (*getsockname)(int s, struct sockaddr *name, socklen_t *namelen);
|
||||
int (*ioctlsocket)(int s, long cmd, void *arg);
|
||||
int (*socketpair) (int s, int type, int protocol, int *fds);
|
||||
#ifdef SAL_USING_POSIX
|
||||
int (*poll) (struct dfs_file *file, struct rt_pollreq *req);
|
||||
#endif
|
||||
|
||||
@@ -48,6 +48,18 @@ typedef uint16_t in_port_t;
|
||||
#define SO_KEEPALIVE 0x0008 /* keep connections alive */
|
||||
#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
|
||||
|
||||
#define SO_PASSCRED 16
|
||||
#define SO_PEERCRED 17
|
||||
|
||||
#define SO_BINDTODEVICE 25
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_PROTOCOL 38
|
||||
#define SO_DOMAIN 39
|
||||
|
||||
/* Additional options, not kept in so_options */
|
||||
#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */
|
||||
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
|
||||
@@ -103,6 +115,9 @@ typedef uint16_t in_port_t;
|
||||
#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
|
||||
#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */
|
||||
#define MSG_MORE 0x10 /* Sender will send more */
|
||||
/* LWIPPTP_SWREQ_0036 */
|
||||
#define MSG_ERRQUEUE 0x2000 /* Fetch message from error queue */
|
||||
#define MSG_CONFIRM 0x0800 /* Confirm path validity */
|
||||
|
||||
/* Options for level IPPROTO_IP */
|
||||
#define IP_TOS 1
|
||||
@@ -150,6 +165,10 @@ typedef struct ip_mreq
|
||||
#define IPTOS_PREC_PRIORITY 0x20
|
||||
#define IPTOS_PREC_ROUTINE 0x00
|
||||
|
||||
#define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */
|
||||
#define SCM_CREDENTIALS 0x02 /* rw: struct ucred */
|
||||
#define SCM_SECURITY 0x03 /* rw: security label */
|
||||
|
||||
/* Options for shatdown type */
|
||||
#ifndef SHUT_RD
|
||||
#define SHUT_RD 0
|
||||
@@ -167,8 +186,7 @@ struct sockaddr
|
||||
/* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket. */
|
||||
struct sockaddr_un
|
||||
{
|
||||
uint8_t sa_len;
|
||||
sa_family_t sa_family;
|
||||
unsigned short sa_family;
|
||||
char sun_path[108]; /* Path name. */
|
||||
};
|
||||
|
||||
@@ -209,6 +227,75 @@ struct sockaddr_storage
|
||||
#endif /* NETDEV_IPV6 */
|
||||
};
|
||||
|
||||
/* LWIPPTP_SWREQ_0036 */
|
||||
#ifndef __DEFINED_struct_iovec
|
||||
struct iovec
|
||||
{
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* LWIPPTP_SWREQ_0036 */
|
||||
struct msghdr
|
||||
{
|
||||
void *msg_name;
|
||||
socklen_t msg_namelen;
|
||||
struct iovec *msg_iov;
|
||||
int msg_iovlen;
|
||||
void *msg_control;
|
||||
socklen_t msg_controllen;
|
||||
int msg_flags;
|
||||
};
|
||||
|
||||
/* LWIPPTP_SWREQ_0036 */
|
||||
/* RFC 3542, Section 20: Ancillary Data */
|
||||
struct cmsghdr
|
||||
{
|
||||
size_t cmsg_len; /* number of bytes, including header */
|
||||
int cmsg_level; /* originating protocol */
|
||||
int cmsg_type; /* protocol-specific type */
|
||||
};
|
||||
|
||||
/* LWIPPTP_SWREQ_0036 */
|
||||
#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg))
|
||||
|
||||
#define CMSG_ALIGN(len) (((len) + sizeof(long) - 1) & ~(sizeof(long)-1))
|
||||
|
||||
#define CMSG_DATA(cmsg) ((void *)(cmsg) + sizeof(struct cmsghdr))
|
||||
#define CMSG_SPACE(len) (sizeof(struct cmsghdr) + CMSG_ALIGN(len))
|
||||
#define CMSG_LEN(len) (sizeof(struct cmsghdr) + (len))
|
||||
|
||||
#define __CMSG_FIRSTHDR(ctl, len) \
|
||||
((len) >= sizeof(struct cmsghdr) ? (struct cmsghdr *)(ctl) : (struct cmsghdr *)NULL)
|
||||
|
||||
#define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
|
||||
#define CMSG_OK(mhdr, cmsg) \
|
||||
((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \
|
||||
(cmsg)->cmsg_len <= (unsigned long)((mhdr)->msg_controllen - ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
|
||||
|
||||
#define for_each_cmsghdr(cmsg, msg) \
|
||||
for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg))
|
||||
|
||||
static inline struct cmsghdr *__cmsg_nxthdr(void *_ctl, size_t _size, struct cmsghdr *_cmsg)
|
||||
{
|
||||
struct cmsghdr *_ptr;
|
||||
|
||||
_ptr = (struct cmsghdr *)(((unsigned char *)_cmsg) + CMSG_ALIGN(_cmsg->cmsg_len));
|
||||
|
||||
if ((unsigned long)((char *)(_ptr + 1) - (char *)_ctl) > _size)
|
||||
{
|
||||
return (struct cmsghdr *)NULL;
|
||||
}
|
||||
|
||||
return _ptr;
|
||||
}
|
||||
|
||||
static inline struct cmsghdr *cmsg_nxthdr(struct msghdr *_msg, struct cmsghdr *_cmsg)
|
||||
{
|
||||
return __cmsg_nxthdr(_msg->msg_control, _msg->msg_controllen, _cmsg);
|
||||
}
|
||||
|
||||
#define IFNAMSIZ 16
|
||||
struct sal_ifmap
|
||||
{
|
||||
@@ -252,11 +339,14 @@ int sal_getsockopt (int socket, int level, int optname, void *optval, socklen_t
|
||||
int sal_setsockopt (int socket, int level, int optname, const void *optval, socklen_t optlen);
|
||||
int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen);
|
||||
int sal_listen(int socket, int backlog);
|
||||
int sal_sendmsg(int socket, const struct msghdr *message, int flags);
|
||||
int sal_recvmsg(int socket, struct msghdr *message, int flags);
|
||||
int sal_recvfrom(int socket, void *mem, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen);
|
||||
int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen);
|
||||
int sal_socket(int domain, int type, int protocol);
|
||||
int sal_socketpair(int domain, int type, int protocol, int *fds);
|
||||
int sal_closesocket(int socket);
|
||||
int sal_ioctlsocket(int socket, long cmd, void *arg);
|
||||
|
||||
|
||||
@@ -35,12 +35,15 @@ int listen(int s, int backlog);
|
||||
int recv(int s, void *mem, size_t len, int flags);
|
||||
int recvfrom(int s, void *mem, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen);
|
||||
int recvmsg(int s, struct msghdr *message, int flags);
|
||||
int sendmsg(int s, const struct msghdr *message, int flags);
|
||||
int send(int s, const void *dataptr, size_t size, int flags);
|
||||
int sendto(int s, const void *dataptr, size_t size, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen);
|
||||
int socket(int domain, int type, int protocol);
|
||||
int closesocket(int s);
|
||||
int ioctlsocket(int s, long cmd, void *arg);
|
||||
int socketpair(int domain, int type, int protocol, int *fds);
|
||||
#else
|
||||
#define accept(s, addr, addrlen) sal_accept(s, addr, addrlen)
|
||||
#define bind(s, name, namelen) sal_bind(s, name, namelen)
|
||||
@@ -53,9 +56,12 @@ int ioctlsocket(int s, long cmd, void *arg);
|
||||
#define listen(s, backlog) sal_listen(s, backlog)
|
||||
#define recv(s, mem, len, flags) sal_recvfrom(s, mem, len, flags, NULL, NULL)
|
||||
#define recvfrom(s, mem, len, flags, from, fromlen) sal_recvfrom(s, mem, len, flags, from, fromlen)
|
||||
#define recvmsg(s, message, flags) sal_recvmsg(s, message, flags)
|
||||
#define send(s, dataptr, size, flags) sal_sendto(s, dataptr, size, flags, NULL, NULL)
|
||||
#define sendto(s, dataptr, size, flags, to, tolen) sal_sendto(s, dataptr, size, flags, to, tolen)
|
||||
#define sendmsg(s, message, flags) sal_sendmsg(s, message, flags)
|
||||
#define socket(domain, type, protocol) sal_socket(domain, type, protocol)
|
||||
#define socketpair(domain, type, protocol, fds) sal_socketpair(domain, type, protocol, fds)
|
||||
#define closesocket(s) sal_closesocket(s)
|
||||
#define ioctlsocket(s, cmd, arg) sal_ioctlsocket(s, cmd, arg)
|
||||
#endif /* SAL_USING_POSIX */
|
||||
|
||||
@@ -75,17 +75,6 @@ int bind(int s, const struct sockaddr *name, socklen_t namelen)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
|
||||
#ifdef SAL_USING_AF_UNIX
|
||||
struct sockaddr_in server_addr = {0};
|
||||
if (name->sa_family == AF_UNIX)
|
||||
{
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(514);
|
||||
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
return sal_bind(socket, (struct sockaddr *)&server_addr, namelen);
|
||||
}
|
||||
#endif /* SAL_USING_AF_UNIX */
|
||||
|
||||
return sal_bind(socket, name, namelen);
|
||||
}
|
||||
RTM_EXPORT(bind);
|
||||
@@ -159,18 +148,6 @@ RTM_EXPORT(setsockopt);
|
||||
int connect(int s, const struct sockaddr *name, socklen_t namelen)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
|
||||
#ifdef SAL_USING_AF_UNIX
|
||||
struct sockaddr_in server_addr = {0};
|
||||
if (name->sa_family == AF_UNIX)
|
||||
{
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(514);
|
||||
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
return sal_connect(socket, (struct sockaddr *)&server_addr, namelen);
|
||||
}
|
||||
#endif /* SAL_USING_AF_UNIX */
|
||||
|
||||
return sal_connect(socket, name, namelen);
|
||||
}
|
||||
RTM_EXPORT(connect);
|
||||
@@ -191,6 +168,24 @@ int recv(int s, void *mem, size_t len, int flags)
|
||||
}
|
||||
RTM_EXPORT(recv);
|
||||
|
||||
/* LWIPPTP_SWREQ_0036 */
|
||||
int sendmsg(int s, const struct msghdr *message, int flags)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
|
||||
return sal_sendmsg(socket, message, flags);
|
||||
}
|
||||
RTM_EXPORT(sendmsg);
|
||||
|
||||
/* LWIPPTP_SWREQ_0036 */
|
||||
int recvmsg(int s, struct msghdr *message, int flags)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
|
||||
return sal_recvmsg(socket, message, flags);
|
||||
}
|
||||
RTM_EXPORT(recvmsg);
|
||||
|
||||
int recvfrom(int s, void *mem, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen)
|
||||
{
|
||||
@@ -247,13 +242,6 @@ int socket(int domain, int type, int protocol)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SAL_USING_AF_UNIX
|
||||
if (domain == AF_UNIX)
|
||||
{
|
||||
domain = AF_INET;
|
||||
}
|
||||
#endif /* SAL_USING_AF_UNIX */
|
||||
|
||||
/* create socket and then put it to the dfs_file */
|
||||
socket = sal_socket(domain, type, protocol);
|
||||
if (socket >= 0)
|
||||
@@ -319,6 +307,43 @@ int closesocket(int s)
|
||||
}
|
||||
RTM_EXPORT(closesocket);
|
||||
|
||||
|
||||
int socketpair(int domain, int type, int protocol, int *fds)
|
||||
{
|
||||
rt_err_t ret = 0;
|
||||
int sock_fds[2];
|
||||
|
||||
fds[0] = socket(domain, type, protocol);
|
||||
if (fds[0] < 0)
|
||||
{
|
||||
fds[0] = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fds[1] = socket(domain, type, protocol);
|
||||
if (fds[1] < 0)
|
||||
{
|
||||
closesocket(fds[0]);
|
||||
fds[0] = 0;
|
||||
fds[1] = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sock_fds[0] = dfs_net_getsocket(fds[0]);
|
||||
sock_fds[1] = dfs_net_getsocket(fds[1]);
|
||||
|
||||
ret = sal_socketpair(domain, type, protocol, sock_fds);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
closesocket(fds[0]);
|
||||
closesocket(fds[1]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
RTM_EXPORT(socketpair);
|
||||
|
||||
int ioctlsocket(int s, long cmd, void *arg)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sal_socket.h>
|
||||
#include <sal_netdb.h>
|
||||
@@ -442,6 +444,11 @@ static int socket_init(int family, int type, int protocol, struct sal_socket **r
|
||||
struct netdev *netdev = RT_NULL;
|
||||
rt_bool_t flag = RT_FALSE;
|
||||
|
||||
if (family == AF_UNIX)
|
||||
{
|
||||
netdv_def = netdev_lo;
|
||||
}
|
||||
|
||||
if (family < 0 || family > AF_MAX)
|
||||
{
|
||||
return -1;
|
||||
@@ -667,6 +674,7 @@ int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen)
|
||||
{
|
||||
struct sal_socket *sock;
|
||||
struct sal_proto_family *pf;
|
||||
struct sockaddr_un *addr_un = RT_NULL;
|
||||
ip_addr_t input_ipaddr;
|
||||
|
||||
RT_ASSERT(name);
|
||||
@@ -674,43 +682,47 @@ int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen)
|
||||
/* get the socket object by socket descriptor */
|
||||
SAL_SOCKET_OBJ_GET(sock, socket);
|
||||
|
||||
/* bind network interface by ip address */
|
||||
sal_sockaddr_to_ipaddr(name, &input_ipaddr);
|
||||
addr_un = (struct sockaddr_un *)name;
|
||||
|
||||
/* check input ipaddr is default netdev ipaddr */
|
||||
if (!ip_addr_isany_val(input_ipaddr))
|
||||
{
|
||||
struct sal_proto_family *input_pf = RT_NULL, *local_pf = RT_NULL;
|
||||
struct netdev *new_netdev = RT_NULL;
|
||||
if (addr_un->sa_family != AF_UNIX)
|
||||
{
|
||||
/* bind network interface by ip address */
|
||||
sal_sockaddr_to_ipaddr(name, &input_ipaddr);
|
||||
|
||||
new_netdev = netdev_get_by_ipaddr(&input_ipaddr);
|
||||
if (new_netdev == RT_NULL)
|
||||
/* check input ipaddr is default netdev ipaddr */
|
||||
if (!ip_addr_isany_val(input_ipaddr))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
struct sal_proto_family *input_pf = RT_NULL, *local_pf = RT_NULL;
|
||||
struct netdev *new_netdev = RT_NULL;
|
||||
|
||||
/* get input and local ip address proto_family */
|
||||
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, local_pf, bind);
|
||||
SAL_NETDEV_SOCKETOPS_VALID(new_netdev, input_pf, bind);
|
||||
|
||||
/* check the network interface protocol family type */
|
||||
if (input_pf->family != local_pf->family)
|
||||
{
|
||||
int new_socket = -1;
|
||||
|
||||
/* protocol family is different, close old socket and create new socket by input ip address */
|
||||
local_pf->skt_ops->closesocket(socket);
|
||||
|
||||
new_socket = input_pf->skt_ops->socket(input_pf->family, sock->type, sock->protocol);
|
||||
if (new_socket < 0)
|
||||
new_netdev = netdev_get_by_ipaddr(&input_ipaddr);
|
||||
if (new_netdev == RT_NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
sock->netdev = new_netdev;
|
||||
sock->user_data = (void *)(size_t)new_socket;
|
||||
|
||||
/* get input and local ip address proto_family */
|
||||
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, local_pf, bind);
|
||||
SAL_NETDEV_SOCKETOPS_VALID(new_netdev, input_pf, bind);
|
||||
|
||||
/* check the network interface protocol family type */
|
||||
if (input_pf->family != local_pf->family)
|
||||
{
|
||||
int new_socket = -1;
|
||||
|
||||
/* protocol family is different, close old socket and create new socket by input ip address */
|
||||
local_pf->skt_ops->closesocket(socket);
|
||||
|
||||
new_socket = input_pf->skt_ops->socket(input_pf->family, sock->type, sock->protocol);
|
||||
if (new_socket < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
sock->netdev = new_netdev;
|
||||
sock->user_data = (void *)(size_t)new_socket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check and get protocol families by the network interface device */
|
||||
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, bind);
|
||||
return pf->skt_ops->bind((int)(size_t)sock->user_data, name, namelen);
|
||||
@@ -884,6 +896,72 @@ int sal_listen(int socket, int backlog)
|
||||
return pf->skt_ops->listen((int)(size_t)sock->user_data, backlog);
|
||||
}
|
||||
|
||||
int sal_sendmsg(int socket, const struct msghdr *message, int flags)
|
||||
{
|
||||
struct sal_socket *sock;
|
||||
struct sal_proto_family *pf;
|
||||
|
||||
/* get the socket object by socket descriptor */
|
||||
SAL_SOCKET_OBJ_GET(sock, socket);
|
||||
|
||||
/* check the network interface is up status */
|
||||
SAL_NETDEV_IS_UP(sock->netdev);
|
||||
/* check the network interface socket opreation */
|
||||
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, sendmsg);
|
||||
|
||||
#ifdef SAL_USING_TLS
|
||||
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, sendmsg))
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = proto_tls->ops->sendmsg(sock->user_data_tls, message, flags)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pf->skt_ops->sendmsg((int)(size_t)sock->user_data, message, flags);
|
||||
}
|
||||
#else
|
||||
return pf->skt_ops->sendmsg((int)(size_t)sock->user_data, message, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
int sal_recvmsg(int socket, struct msghdr *message, int flags)
|
||||
{
|
||||
struct sal_socket *sock;
|
||||
struct sal_proto_family *pf;
|
||||
|
||||
/* get the socket object by socket descriptor */
|
||||
SAL_SOCKET_OBJ_GET(sock, socket);
|
||||
|
||||
/* check the network interface is up status */
|
||||
SAL_NETDEV_IS_UP(sock->netdev);
|
||||
/* check the network interface socket opreation */
|
||||
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, recvmsg);
|
||||
|
||||
#ifdef SAL_USING_TLS
|
||||
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, recvmsg))
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = proto_tls->ops->recvmsg(sock->user_data_tls, message, flags)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pf->skt_ops->recvmsg((int)(size_t)sock->user_data, message, flags);
|
||||
}
|
||||
#else
|
||||
return pf->skt_ops->recvmsg((int)(size_t)sock->user_data, message, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
int sal_recvfrom(int socket, void *mem, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen)
|
||||
{
|
||||
@@ -1007,6 +1085,36 @@ int sal_socket(int domain, int type, int protocol)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sal_socketpair(int domain, int type, int protocol, int *fds)
|
||||
{
|
||||
int unix_fd[2];
|
||||
struct sal_socket *socka;
|
||||
struct sal_socket *sockb;
|
||||
struct sal_proto_family *pf;
|
||||
|
||||
if (domain == AF_UNIX)
|
||||
{
|
||||
/* get the socket object by socket descriptor */
|
||||
SAL_SOCKET_OBJ_GET(socka, fds[0]);
|
||||
SAL_SOCKET_OBJ_GET(sockb, fds[1]);
|
||||
|
||||
/* valid the network interface socket opreation */
|
||||
SAL_NETDEV_SOCKETOPS_VALID(socka->netdev, pf, socket);
|
||||
|
||||
unix_fd[0] = (int)(size_t)socka->user_data;
|
||||
unix_fd[1] = (int)(size_t)sockb->user_data;
|
||||
|
||||
if (pf->skt_ops->socketpair)
|
||||
{
|
||||
return pf->skt_ops->socketpair(domain, type, protocol, unix_fd);
|
||||
}
|
||||
}
|
||||
|
||||
rt_set_errno(EINVAL);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sal_closesocket(int socket)
|
||||
{
|
||||
struct sal_socket *sock;
|
||||
|
||||
Reference in New Issue
Block a user