summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorrcitachi <[email protected]>2023-11-28 13:56:06 +0800
committerGitHub <[email protected]>2023-11-28 13:56:06 +0800
commitc06f4e98fce6c86ef412aa70c1f31c971a9d61a9 (patch)
treec50f5cab5570e7ee1df636f1ecf4b15723de43e9 /components
parent265b79d953ec8e640b1aedb5feaa0c1c77b340ef (diff)
[SAL] Update SAL,Add socketpair sendmsg recvmsg function (#8293)
Diffstat (limited to 'components')
-rw-r--r--components/dfs/dfs_v2/include/dfs_file.h2
-rw-r--r--components/dfs/dfs_v2/src/dfs_file.c2
-rw-r--r--components/libc/posix/io/epoll/epoll.c303
-rw-r--r--components/libc/posix/io/poll/poll.h47
-rw-r--r--components/lwp/lwp_syscall.c225
-rw-r--r--components/net/netdev/include/netdev.h3
-rw-r--r--components/net/netdev/src/netdev.c2
-rw-r--r--components/net/sal/impl/af_inet_lwip.c53
-rw-r--r--components/net/sal/include/sal_low_lvl.h6
-rw-r--r--components/net/sal/include/sal_socket.h94
-rw-r--r--components/net/sal/include/socket/sys_socket/sys/socket.h6
-rw-r--r--components/net/sal/socket/net_sockets.c85
-rw-r--r--components/net/sal/src/sal_socket.c162
13 files changed, 708 insertions, 282 deletions
diff --git a/components/dfs/dfs_v2/include/dfs_file.h b/components/dfs/dfs_v2/include/dfs_file.h
index 4486401333..17027d93b2 100644
--- a/components/dfs/dfs_v2/include/dfs_file.h
+++ b/components/dfs/dfs_v2/include/dfs_file.h
@@ -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);
diff --git a/components/dfs/dfs_v2/src/dfs_file.c b/components/dfs/dfs_v2/src/dfs_file.c
index d2d27010cf..7e7df1738d 100644
--- a/components/dfs/dfs_v2/src/dfs_file.c
+++ b/components/dfs/dfs_v2/src/dfs_file.c
@@ -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;
diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c
index 7c33d775a2..881b9ac027 100644
--- a/components/libc/posix/io/epoll/epoll.c
+++ b/components/libc/posix/io/epoll/epoll.c
@@ -24,8 +24,6 @@
#define EPOLLEXCLUSIVE_BITS (EPOLLINOUT_BITS | EPOLLERR | EPOLLHUP | \
EPOLLET | EPOLLEXCLUSIVE)
-static struct rt_spinlock spinlock;
-
struct rt_eventpoll;
/* Monitor queue */
@@ -36,15 +34,10 @@ struct rt_fd_list
rt_pollreq_t req;
struct rt_eventpoll *ep;
struct rt_wqueue_node wqn;
+ int exclusive;/* If triggered horizontally, a check is made to see if the data has been read, and if there is any data left to read, the readability event is returned in the next epoll_wait */
int fd;
struct rt_fd_list *next;
-};
-
-struct rt_ready_list
-{
- int exclusive;/* If triggered horizontally, a check is made to see if the data has been read, and if there is any data left to read, the readability event is returned in the next epoll_wait */
- struct rt_fd_list *rdl_event; /* rdl: ready list */
- struct rt_ready_list *next;
+ rt_slist_t rdl_node;
};
struct rt_eventpoll
@@ -56,7 +49,8 @@ struct rt_eventpoll
struct rt_fd_list *fdlist; /* Monitor list */
int eventpoll_num; /* Number of ready lists */
rt_pollreq_t req;
- struct rt_ready_list *rdlist; /* ready list */
+ struct rt_spinlock spinlock;
+ rt_slist_t rdl_head;
};
static int epoll_close(struct dfs_file *file);
@@ -80,32 +74,14 @@ static int epoll_close_fdlist(struct rt_fd_list *fdlist)
while (list->next != RT_NULL)
{
fre_node = list->next;
- rt_wqueue_remove(&fre_node->wqn);
- list->next = fre_node->next;
- rt_free(fre_node);
- }
-
- rt_free(fdlist);
- }
-
- return 0;
-}
+ if (fre_node->wqn.wqueue)
+ rt_wqueue_remove(&fre_node->wqn);
-static int epoll_close_rdlist(struct rt_ready_list *rdlist)
-{
- struct rt_ready_list *list, *fre_node;
-
- list = rdlist;
- if (list)
- {
- while (list->next != RT_NULL)
- {
- fre_node = list->next;
list->next = fre_node->next;
rt_free(fre_node);
}
- rt_free(rdlist);
+ rt_free(fdlist);
}
return 0;
@@ -131,11 +107,6 @@ static int epoll_close(struct dfs_file *file)
epoll_close_fdlist(ep->fdlist);
}
- if (ep->rdlist)
- {
- epoll_close_rdlist(ep->rdlist);
- }
-
rt_mutex_release(&ep->lock);
rt_mutex_detach(&ep->lock);
rt_free(ep);
@@ -149,8 +120,6 @@ static int epoll_close(struct dfs_file *file)
static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req)
{
struct rt_eventpoll *ep;
- struct rt_fd_list *fdlist;
- int mask;
int events = 0;
if (file->vnode->data)
@@ -158,101 +127,41 @@ static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req)
ep = file->vnode->data;
ep->req._key = req->_key;
+ rt_mutex_take(&ep->lock, RT_WAITING_FOREVER);
rt_poll_add(&ep->epoll_read, req);
- fdlist = ep->fdlist;
- if (fdlist)
- {
- while (fdlist->next != RT_NULL)
- {
- fdlist = fdlist->next;
- mask = epoll_get_event(fdlist, &fdlist->req);
-
- if (mask & fdlist->revents)
- {
- events |= mask | POLLIN | EPOLLRDNORM;
- break;
- }
- }
- }
- }
-
- return events;
-}
-
-static int epoll_rdlist_add(struct rt_fd_list *fdl, rt_uint32_t revents)
-{
- struct rt_ready_list *rdlist = RT_NULL;
- struct rt_eventpoll *ep;
- int isexist = 0;
- int res = -1;
-
- ep = fdl->ep;
-
- if (revents & ep->req._key)
- {
- rt_wqueue_wakeup(&ep->epoll_read, (void*)POLLIN);
- }
+ rt_spin_lock(&ep->spinlock);
- rt_mutex_take(&ep->lock, RT_WAITING_FOREVER);
+ if (!rt_slist_isempty(&ep->rdl_head))
+ events |= POLLIN | EPOLLRDNORM | POLLOUT;
- if (ep->rdlist == RT_NULL)
- {
- ep->rdlist = (struct rt_ready_list *)rt_malloc(sizeof(struct rt_ready_list));
- if (ep->rdlist == RT_NULL)
- {
- return -1;
- }
- ep->rdlist->next = RT_NULL;
- }
-
- rdlist = ep->rdlist;
- while (rdlist->next != RT_NULL)
- {
- rdlist = rdlist->next;
- if (rdlist->rdl_event->fd == fdl->fd)
- {
- isexist = 1;
- res = 0;
- break;
- }
- }
-
- if (!isexist)
- {
- rdlist = RT_NULL;
- rdlist = (struct rt_ready_list *)rt_malloc(sizeof(struct rt_ready_list));
- if (rdlist != RT_NULL)
- {
- rdlist->rdl_event = fdl;
- rdlist->rdl_event->epev.events = fdl->revents & revents;
- rdlist->next = ep->rdlist->next;
- rdlist->exclusive = 0;
- ep->rdlist->next = rdlist;
- ep->eventpoll_num ++;
- res = 0;
- }
+ rt_spin_unlock(&ep->spinlock);
+ rt_mutex_release(&ep->lock);
}
- ep->tirggered = 1;
-
- rt_mutex_release(&ep->lock);
-
- return res;
+ return events;
}
static int epoll_wqueue_callback(struct rt_wqueue_node *wait, void *key)
{
struct rt_fd_list *fdlist;
+ struct rt_eventpoll *ep;
if (key && !((rt_ubase_t)key & wait->key))
return -1;
fdlist = rt_container_of(wait, struct rt_fd_list, wqn);
- if (fdlist->revents)
+ ep = fdlist->ep;
+ if (ep)
{
- epoll_rdlist_add(fdlist, (rt_ubase_t)key);
+ rt_spin_lock(&ep->spinlock);
+ rt_slist_append(&ep->rdl_head, &fdlist->rdl_node);
+ fdlist->exclusive = 0;
+ ep->tirggered = 1;
+ ep->eventpoll_num ++;
+ rt_wqueue_wakeup(&ep->epoll_read, (void *)POLLIN);
+ rt_spin_unlock(&ep->spinlock);
}
return __wqueue_default_wake(wait, key);
@@ -285,7 +194,17 @@ static void epoll_ctl_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep
if (mask & fdlist->revents)
{
- epoll_rdlist_add(fdlist, mask);
+ if (ep)
+ {
+ rt_mutex_take(&ep->lock, RT_WAITING_FOREVER);
+ rt_spin_lock(&ep->spinlock);
+ rt_slist_append(&ep->rdl_head, &fdlist->rdl_node);
+ fdlist->exclusive = 0;
+ ep->tirggered = 1;
+ ep->eventpoll_num ++;
+ rt_spin_unlock(&ep->spinlock);
+ rt_mutex_release(&ep->lock);
+ }
}
}
@@ -294,11 +213,12 @@ static void epoll_member_init(struct rt_eventpoll *ep)
ep->tirggered = 0;
ep->eventpoll_num = 0;
ep->polling_thread = rt_thread_self();
- ep->rdlist = RT_NULL;
ep->fdlist = RT_NULL;
ep->req._key = 0;
+ rt_slist_init(&(ep->rdl_head));
rt_wqueue_init(&ep->epoll_read);
- rt_spin_lock_init(&spinlock);
+ rt_mutex_init(&ep->lock, EPOLL_MUTEX_NAME, RT_IPC_FLAG_FIFO);
+ rt_spin_lock_init(&ep->spinlock);
}
static int epoll_epf_init(int fd)
@@ -316,8 +236,6 @@ static int epoll_epf_init(int fd)
{
epoll_member_init(ep);
- rt_mutex_init(&ep->lock, EPOLL_MUTEX_NAME, RT_IPC_FLAG_FIFO);
-
#ifdef RT_USING_DFS_V2
df->fops = &epoll_fops;
#endif
@@ -331,8 +249,10 @@ static int epoll_epf_init(int fd)
ep->fdlist->next = RT_NULL;
ep->fdlist->fd = fd;
ep->fdlist->ep = ep;
+ ep->fdlist->exclusive = 0;
dfs_vnode_init(df->vnode, FT_REGULAR, &epoll_fops);
df->vnode->data = ep;
+ rt_slist_init(&ep->fdlist->rdl_node);
}
else
{
@@ -400,26 +320,33 @@ static int epoll_ctl_add(struct dfs_file *df, int fd, struct epoll_event *event)
fdlist = ep->fdlist;
ret = 0;
+ rt_mutex_take(&ep->lock, RT_WAITING_FOREVER);
while (fdlist->next != RT_NULL)
{
if (fdlist->next->fd == fd)
{
+ rt_mutex_release(&ep->lock);
return 0;
}
fdlist = fdlist->next;
}
+ rt_mutex_release(&ep->lock);
fdlist = (struct rt_fd_list *)rt_malloc(sizeof(struct rt_fd_list));
if (fdlist)
{
fdlist->fd = fd;
memcpy(&fdlist->epev.data, &event->data, sizeof(event->data));
- fdlist->epev.events = event->events;
+ fdlist->epev.events = 0;
fdlist->ep = ep;
+ fdlist->exclusive = 0;
fdlist->req._proc = epoll_wqueue_add_callback;
- fdlist->next = ep->fdlist->next;
fdlist->revents = event->events;
+ rt_mutex_take(&ep->lock, RT_WAITING_FOREVER);
+ fdlist->next = ep->fdlist->next;
ep->fdlist->next = fdlist;
+ rt_mutex_release(&ep->lock);
+ rt_slist_init(&fdlist->rdl_node);
epoll_ctl_install(fdlist, ep);
}
@@ -434,53 +361,48 @@ static int epoll_ctl_add(struct dfs_file *df, int fd, struct epoll_event *event)
static int epoll_ctl_del(struct dfs_file *df, int fd)
{
- struct rt_fd_list *fdlist, *fre_fd;
+ struct rt_fd_list *fdlist, *fre_fd, *rdlist;
struct rt_eventpoll *ep = RT_NULL;
- struct rt_ready_list *rdlist, *fre_rdl;
+ rt_slist_t *node = RT_NULL;
rt_err_t ret = -EINVAL;
if (df->vnode->data)
{
ep = df->vnode->data;
- fdlist = ep->fdlist;
- while (fdlist->next != RT_NULL)
+ if (ep)
{
- if (fdlist->next->fd == fd)
+ rt_mutex_take(&ep->lock, RT_WAITING_FOREVER);
+ rt_spin_lock(&ep->spinlock);
+ rt_slist_for_each(node, &ep->rdl_head)
{
- fre_fd = fdlist->next;
- fdlist->next = fdlist->next->next;
- if (fre_fd->epev.events != 0)
- {
- rt_wqueue_remove(&fre_fd->wqn);
- }
- rt_free(fre_fd);
- break;
+ rdlist = rt_slist_entry(node, struct rt_fd_list, rdl_node);
+ if (rdlist->fd == fd)
+ rt_slist_remove(&ep->rdl_head, node);
}
- else
- {
- fdlist = fdlist->next;
- }
- }
+ rt_spin_unlock(&ep->spinlock);
- if (ep->rdlist)
- {
- rdlist = ep->rdlist;
- while (rdlist->next != RT_NULL)
+ fdlist = ep->fdlist;
+ while (fdlist->next != RT_NULL)
{
- if (rdlist->next->rdl_event->fd == fd)
+ if (fdlist->next->fd == fd)
{
- fre_rdl = rdlist->next;
- rdlist->next = rdlist->next->next;
- ep->eventpoll_num --;
- rt_free(fre_rdl);
+ fre_fd = fdlist->next;
+ fdlist->next = fdlist->next->next;
+
+ if (fre_fd->wqn.wqueue)
+ rt_wqueue_remove(&fre_fd->wqn);
+
+ rt_free(fre_fd);
break;
}
else
{
- rdlist = rdlist->next;
+ fdlist = fdlist->next;
}
}
+
+ rt_mutex_release(&ep->lock);
}
ret = 0;
@@ -504,9 +426,13 @@ static int epoll_ctl_mod(struct dfs_file *df, int fd, struct epoll_event *event)
{
if (fdlist->next->fd == fd)
{
+ rt_mutex_take(&ep->lock, RT_WAITING_FOREVER);
memcpy(&fdlist->next->epev.data, &event->data, sizeof(event->data));
fdlist->next->revents = event->events;
- rt_wqueue_remove(&fdlist->next->wqn);
+ if (fdlist->next->wqn.wqueue)
+ rt_wqueue_remove(&fdlist->next->wqn);
+
+ rt_mutex_release(&ep->lock);
epoll_ctl_install(fdlist->next, ep);
break;
}
@@ -538,10 +464,14 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event)
return -1;
}
- if (!(event->events & EPOLLEXCLUSIVE_BITS))
+ if (!(op & EPOLL_CTL_DEL))
{
- rt_set_errno(EINVAL);
- return -1;
+ if (!(event->events & EPOLLEXCLUSIVE_BITS))
+ {
+ rt_set_errno(EINVAL);
+ return -1;
+ }
+ event->events |= EPOLLERR | EPOLLHUP;
}
if (!fd_get(fd))
@@ -555,8 +485,6 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event)
if (epdf->vnode->data)
{
ep = epdf->vnode->data;
- event->events |= EPOLLERR | EPOLLHUP;
- rt_mutex_take(&ep->lock, RT_WAITING_FOREVER);
switch (op)
{
@@ -583,8 +511,6 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event)
{
ep->polling_thread = rt_thread_self();
}
-
- rt_mutex_release(&ep->lock);
}
return ret;
@@ -601,7 +527,7 @@ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec)
timeout = rt_tick_from_millisecond(msec);
- level = rt_spin_lock_irqsave(&spinlock);
+ level = rt_spin_lock_irqsave(&ep->spinlock);
if (timeout != 0 && !ep->tirggered)
{
@@ -615,16 +541,16 @@ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec)
rt_timer_start(&(thread->thread_timer));
}
- rt_spin_unlock_irqrestore(&spinlock, level);
+ rt_spin_unlock_irqrestore(&ep->spinlock, level);
rt_schedule();
- level = rt_spin_lock_irqsave(&spinlock);
+ level = rt_spin_lock_irqsave(&ep->spinlock);
}
}
ret = !ep->tirggered;
- rt_spin_unlock_irqrestore(&spinlock, level);
+ rt_spin_unlock_irqrestore(&ep->spinlock, level);
return ret;
}
@@ -658,7 +584,8 @@ static int epoll_get_event(struct rt_fd_list *fl, rt_pollreq_t *req)
static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int maxevents, int timeout)
{
- struct rt_ready_list *rdlist, *pre_rdlist;
+ struct rt_fd_list *rdlist;
+ rt_slist_t *node = RT_NULL;
int event_num = 0;
int istimeout = 0;
int isn_add = 0;
@@ -668,23 +595,29 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max
while (1)
{
rt_mutex_take(&ep->lock, RT_WAITING_FOREVER);
+ rt_spin_lock(&ep->spinlock);
if (ep->eventpoll_num > 0)
{
- rdlist = ep->rdlist;
- while (rdlist->next != RT_NULL)
+ rt_slist_for_each(node,&ep->rdl_head)
{
+ rdlist = rt_slist_entry(node, struct rt_fd_list, rdl_node);
+
+ rt_spin_unlock(&ep->spinlock);
+
isfree = 0;
isn_add = 0;
- pre_rdlist = rdlist;
- rdlist = rdlist->next;
if (event_num < maxevents)
{
- rt_wqueue_remove(&rdlist->rdl_event->wqn);
- mask = epoll_get_event(rdlist->rdl_event, &rdlist->rdl_event->req);
+ if (rdlist->wqn.wqueue)
+ {
+ rt_wqueue_remove(&rdlist->wqn);
+ }
+
+ mask = epoll_get_event(rdlist, &rdlist->req);
- if (mask & rdlist->rdl_event->revents)
+ if (mask & rdlist->revents)
{
- rdlist->rdl_event->epev.events = mask & rdlist->rdl_event->revents;
+ rdlist->epev.events = mask & rdlist->revents;
}
else
{
@@ -692,54 +625,64 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max
isn_add = 1;
}
- if (rdlist->rdl_event->revents & EPOLLONESHOT)
+ if (rdlist->revents & EPOLLONESHOT)
{
- rdlist->rdl_event->revents = 0;
+ rdlist->revents = 0;
isfree = 1;
- rt_wqueue_remove(&rdlist->rdl_event->wqn);
+ if (rdlist->wqn.wqueue)
+ rt_wqueue_remove(&rdlist->wqn);
}
else
{
- if (rdlist->rdl_event->revents & EPOLLET)
+ if (rdlist->revents & EPOLLET)
{
isfree = 1;
}
else
{
+ rt_spin_lock(&ep->spinlock);
if (rdlist->exclusive != 1)
{
rdlist->exclusive = 1;
}
+ rt_spin_unlock(&ep->spinlock);
}
}
if (!isn_add)
{
- memcpy(&events[event_num], &rdlist->rdl_event->epev, sizeof(rdlist->rdl_event->epev));
+ memcpy(&events[event_num], &rdlist->epev, sizeof(rdlist->epev));
event_num ++;
}
if (isfree)
{
- pre_rdlist->next = rdlist->next;
- rt_free(rdlist);
+ rt_spin_lock(&ep->spinlock);
ep->eventpoll_num --;
- rdlist = pre_rdlist;
+ rt_slist_remove(&ep->rdl_head, &rdlist->rdl_node);
+ rt_spin_unlock(&ep->spinlock);
}
}
else
{
+ rt_spin_lock(&ep->spinlock);
break;
}
+
+ rt_spin_lock(&ep->spinlock);
}
}
+ rt_spin_unlock(&ep->spinlock);
rt_mutex_release(&ep->lock);
if (event_num || istimeout)
{
+ rt_spin_lock(&ep->spinlock);
ep->tirggered = 0;
- break;
+ rt_spin_unlock(&ep->spinlock);
+ if ((timeout >= 0) || (event_num > 0))
+ break;
}
if (epoll_wait_timeout(ep, timeout))
diff --git a/components/libc/posix/io/poll/poll.h b/components/libc/posix/io/poll/poll.h
index 0fccd48b0d..7b710cd14e 100644
--- a/components/libc/posix/io/poll/poll.h
+++ b/components/libc/posix/io/poll/poll.h
@@ -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)
diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c
index 94ba29ddcd..90d116db5c 100644
--- a/components/lwp/lwp_syscall.c
+++ b/components/lwp/lwp_syscall.c
@@ -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)
diff --git a/components/net/netdev/include/netdev.h b/components/net/netdev/include/netdev.h
index ae0e89b65b..5ee7635cd8 100644
--- a/components/net/netdev/include/netdev.h
+++ b/components/net/netdev/include/netdev.h
@@ -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
{
diff --git a/components/net/netdev/src/netdev.c b/components/net/netdev/src/netdev.c
index 569ba27040..50f2d4bc8d 100644
--- a/components/net/netdev/src/netdev.c
+++ b/components/net/netdev/src/netdev.c
@@ -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;
diff --git a/components/net/sal/impl/af_inet_lwip.c b/components/net/sal/impl/af_inet_lwip.c
index fa015fd14e..9183e1a63f 100644
--- a/components/net/sal/impl/af_inet_lwip.c
+++ b/components/net/sal/impl/af_inet_lwip.c
@@ -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 */
diff --git a/components/net/sal/include/sal_low_lvl.h b/components/net/sal/include/sal_low_lvl.h
index 1b1959a3e9..c19c10ffc1 100644
--- a/components/net/sal/include/sal_low_lvl.h
+++ b/components/net/sal/include/sal_low_lvl.h
@@ -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
diff --git a/components/net/sal/include/sal_socket.h b/components/net/sal/include/sal_socket.h
index b77487516f..52767ece67 100644
--- a/components/net/sal/include/sal_socket.h
+++ b/components/net/sal/include/sal_socket.h
@@ -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);
diff --git a/components/net/sal/include/socket/sys_socket/sys/socket.h b/components/net/sal/include/socket/sys_socket/sys/socket.h
index a86240e2ff..adfe51de5d 100644
--- a/components/net/sal/include/socket/sys_socket/sys/socket.h
+++ b/components/net/sal/include/socket/sys_socket/sys/socket.h
@@ -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 */
diff --git a/components/net/sal/socket/net_sockets.c b/components/net/sal/socket/net_sockets.c
index 211876c6c4..28e96b1795 100644
--- a/components/net/sal/socket/net_sockets.c
+++ b/components/net/sal/socket/net_sockets.c
@@ -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);
diff --git a/components/net/sal/src/sal_socket.c b/components/net/sal/src/sal_socket.c
index 225e50ad3b..782710edcf 100644
--- a/components/net/sal/src/sal_socket.c
+++ b/components/net/sal/src/sal_socket.c
@@ -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;
- }
-
- /* 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);
+ struct sal_proto_family *input_pf = RT_NULL, *local_pf = RT_NULL;
+ struct netdev *new_netdev = RT_NULL;
- /* check the network interface protocol family type */
- if (input_pf->family != local_pf->family)
- {
- int new_socket = -1;
+ new_netdev = netdev_get_by_ipaddr(&input_ipaddr);
+ if (new_netdev == RT_NULL)
+ {
+ return -1;
+ }
- /* protocol family is different, close old socket and create new socket by input ip address */
- local_pf->skt_ops->closesocket(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);
- new_socket = input_pf->skt_ops->socket(input_pf->family, sock->type, sock->protocol);
- if (new_socket < 0)
+ /* check the network interface protocol family type */
+ if (input_pf->family != local_pf->family)
{
- return -1;
+ 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;
}
- 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;