mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 10:58:49 +08:00
net: tcp/udp/icmp/icmpv6 add FIONSPACE support
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
parent
931a64717a
commit
c50d7e174f
16 changed files with 362 additions and 80 deletions
|
@ -27,7 +27,7 @@ NET_CSRCS += icmp_input.c icmp_reply.c
|
|||
|
||||
ifeq ($(CONFIG_NET_ICMP_SOCKET),y)
|
||||
SOCK_CSRCS += icmp_sockif.c icmp_poll.c icmp_conn.c icmp_sendmsg.c
|
||||
SOCK_CSRCS += icmp_recvmsg.c icmp_netpoll.c
|
||||
SOCK_CSRCS += icmp_recvmsg.c icmp_netpoll.c icmp_ioctl.c
|
||||
endif
|
||||
|
||||
# Include ICMP build support
|
||||
|
|
|
@ -380,6 +380,25 @@ int icmp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds);
|
|||
|
||||
void icmp_reply(FAR struct net_driver_s *dev, int type, int code);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmp_ioctl
|
||||
*
|
||||
* Description:
|
||||
* This function performs icmp specific ioctl() operations.
|
||||
*
|
||||
* Parameters:
|
||||
* conn The ICMP connection of interest
|
||||
* cmd The ioctl command
|
||||
* arg The argument of the ioctl cmd
|
||||
* arglen The length of 'arg'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_ICMP_SOCKET
|
||||
int icmp_ioctl(FAR struct socket *psock,
|
||||
int cmd, FAR void *arg, size_t arglen);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
90
net/icmp/icmp_ioctl.c
Normal file
90
net/icmp/icmp_ioctl.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/****************************************************************************
|
||||
* net/icmp/icmp_ioctl.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/mm/iob.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "icmp/icmp.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmp_ioctl
|
||||
*
|
||||
* Description:
|
||||
* This function performs icmp specific ioctl() operations.
|
||||
*
|
||||
* Parameters:
|
||||
* conn The ICMP connection of interest
|
||||
* cmd The ioctl command
|
||||
* arg The argument of the ioctl cmd
|
||||
* arglen The length of 'arg'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int icmp_ioctl(FAR struct socket *psock,
|
||||
int cmd, FAR void *arg, size_t arglen)
|
||||
{
|
||||
FAR struct icmp_conn_s *conn = psock->s_conn;
|
||||
int ret = OK;
|
||||
|
||||
net_lock();
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case FIONREAD:
|
||||
if (iob_peek_queue(&conn->readahead) != NULL)
|
||||
{
|
||||
*(FAR int *)((uintptr_t)arg) =
|
||||
iob_peek_queue(&conn->readahead)->io_pktlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(FAR int *)((uintptr_t)arg) = 0;
|
||||
}
|
||||
break;
|
||||
case FIONSPACE:
|
||||
*(FAR int *)((uintptr_t)arg) = MIN_UDP_MSS;
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -81,7 +81,8 @@ const struct sock_intf_s g_icmp_sockif =
|
|||
icmp_netpoll, /* si_poll */
|
||||
icmp_sendmsg, /* si_sendmsg */
|
||||
icmp_recvmsg, /* si_recvmsg */
|
||||
icmp_close /* si_close */
|
||||
icmp_close, /* si_close */
|
||||
icmp_ioctl /* si_ioctl */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -28,7 +28,7 @@ NET_CSRCS += icmpv6_linkipaddr.c icmpv6_reply.c
|
|||
|
||||
ifeq ($(CONFIG_NET_ICMPv6_SOCKET),y)
|
||||
SOCK_CSRCS += icmpv6_sockif.c icmpv6_conn.c icmpv6_sendmsg.c
|
||||
SOCK_CSRCS += icmpv6_recvmsg.c icmpv6_netpoll.c
|
||||
SOCK_CSRCS += icmpv6_recvmsg.c icmpv6_netpoll.c icmpv6_ioctl.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NET_ICMPv6_NEIGHBOR),y)
|
||||
|
|
|
@ -746,6 +746,25 @@ void icmpv6_linkipaddr(FAR struct net_driver_s *dev, net_ipv6addr_t ipaddr);
|
|||
void icmpv6_reply(FAR struct net_driver_s *dev,
|
||||
int type, int code, int data);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmpv6_ioctl
|
||||
*
|
||||
* Description:
|
||||
* This function performs icmp specific ioctl() operations.
|
||||
*
|
||||
* Parameters:
|
||||
* conn The ICMP connection of interest
|
||||
* cmd The ioctl command
|
||||
* arg The argument of the ioctl cmd
|
||||
* arglen The length of 'arg'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6_SOCKET
|
||||
int icmpv6_ioctl(FAR struct socket *psock,
|
||||
int cmd, FAR void *arg, size_t arglen);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
90
net/icmpv6/icmpv6_ioctl.c
Normal file
90
net/icmpv6/icmpv6_ioctl.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/****************************************************************************
|
||||
* net/icmpv6/icmpv6_ioctl.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/mm/iob.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "icmpv6/icmpv6.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmpv6_ioctl
|
||||
*
|
||||
* Description:
|
||||
* This function performs icmpv6 specific ioctl() operations.
|
||||
*
|
||||
* Parameters:
|
||||
* conn The icmpv6 connection of interest
|
||||
* cmd The ioctl command
|
||||
* arg The argument of the ioctl cmd
|
||||
* arglen The length of 'arg'
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int icmpv6_ioctl(FAR struct socket *psock,
|
||||
int cmd, FAR void *arg, size_t arglen)
|
||||
{
|
||||
FAR struct icmpv6_conn_s *conn = psock->s_conn;
|
||||
int ret = OK;
|
||||
|
||||
net_lock();
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case FIONREAD:
|
||||
if (iob_peek_queue(&conn->readahead) != NULL)
|
||||
{
|
||||
*(FAR int *)((uintptr_t)arg) =
|
||||
iob_peek_queue(&conn->readahead)->io_pktlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(FAR int *)((uintptr_t)arg) = 0;
|
||||
}
|
||||
break;
|
||||
case FIONSPACE:
|
||||
*(FAR int *)((uintptr_t)arg) = MIN_UDP_MSS;
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -81,7 +81,8 @@ const struct sock_intf_s g_icmpv6_sockif =
|
|||
icmpv6_netpoll, /* si_poll */
|
||||
icmpv6_sendmsg, /* si_sendmsg */
|
||||
icmpv6_recvmsg, /* si_recvmsg */
|
||||
icmpv6_close /* si_close */
|
||||
icmpv6_close, /* si_close */
|
||||
icmpv6_ioctl /* si_ioctl */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -1617,6 +1617,24 @@ FAR struct tcp_wrbuffer_s *tcp_wrbuffer_tryalloc(void);
|
|||
void tcp_wrbuffer_release(FAR struct tcp_wrbuffer_s *wrb);
|
||||
#endif /* CONFIG_NET_TCP_WRITE_BUFFERS */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_wrbuffer_inqueue_size
|
||||
*
|
||||
* Description:
|
||||
* Get the in-queued write buffer size from connection
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The TCP connection of interest
|
||||
*
|
||||
* Assumptions:
|
||||
* Called from user logic with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NET_SEND_BUFSIZE > 0
|
||||
uint32_t tcp_wrbuffer_inqueue_size(FAR struct tcp_conn_s *conn);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_wrbuffer_test
|
||||
*
|
||||
|
|
|
@ -74,6 +74,19 @@ int tcp_ioctl(FAR struct tcp_conn_s *conn,
|
|||
*(FAR int *)((uintptr_t)arg) = 0;
|
||||
}
|
||||
break;
|
||||
case FIONSPACE:
|
||||
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
|
||||
# if CONFIG_NET_SEND_BUFSIZE == 0
|
||||
*(FAR int *)((uintptr_t)arg) =
|
||||
iob_navail(true) * CONFIG_IOB_BUFSIZE;
|
||||
# else
|
||||
*(FAR int *)((uintptr_t)arg) =
|
||||
conn->snd_bufs - tcp_wrbuffer_inqueue_size(conn);
|
||||
# endif
|
||||
#else
|
||||
*(FAR int *)((uintptr_t)arg) = MIN_TCP_MSS;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
|
|
|
@ -94,46 +94,6 @@
|
|||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_inqueue_wrb_size
|
||||
*
|
||||
* Description:
|
||||
* Get the in-queued write buffer size from connection
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The TCP connection of interest
|
||||
*
|
||||
* Assumptions:
|
||||
* Called from user logic with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NET_SEND_BUFSIZE > 0
|
||||
static uint32_t tcp_inqueue_wrb_size(FAR struct tcp_conn_s *conn)
|
||||
{
|
||||
FAR struct tcp_wrbuffer_s *wrb;
|
||||
FAR sq_entry_t *entry;
|
||||
uint32_t total = 0;
|
||||
|
||||
if (conn)
|
||||
{
|
||||
for (entry = sq_peek(&conn->unacked_q); entry; entry = sq_next(entry))
|
||||
{
|
||||
wrb = (FAR struct tcp_wrbuffer_s *)entry;
|
||||
total += TCP_WBPKTLEN(wrb);
|
||||
}
|
||||
|
||||
for (entry = sq_peek(&conn->write_q); entry; entry = sq_next(entry))
|
||||
{
|
||||
wrb = (FAR struct tcp_wrbuffer_s *)entry;
|
||||
total += TCP_WBPKTLEN(wrb);
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
#endif /* CONFIG_NET_SEND_BUFSIZE */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: psock_insert_segment
|
||||
*
|
||||
|
@ -1223,7 +1183,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
|||
* wait for the write buffer to be released
|
||||
*/
|
||||
|
||||
while (tcp_inqueue_wrb_size(conn) >= conn->snd_bufs)
|
||||
while (tcp_wrbuffer_inqueue_size(conn) >= conn->snd_bufs)
|
||||
{
|
||||
if (nonblock)
|
||||
{
|
||||
|
|
|
@ -249,6 +249,46 @@ void tcp_wrbuffer_release(FAR struct tcp_wrbuffer_s *wrb)
|
|||
nxsem_post(&g_wrbuffer.sem);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_wrbuffer_inqueue_size
|
||||
*
|
||||
* Description:
|
||||
* Get the in-queued write buffer size from connection
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The TCP connection of interest
|
||||
*
|
||||
* Assumptions:
|
||||
* Called from user logic with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NET_SEND_BUFSIZE > 0
|
||||
uint32_t tcp_wrbuffer_inqueue_size(FAR struct tcp_conn_s *conn)
|
||||
{
|
||||
FAR struct tcp_wrbuffer_s *wrb;
|
||||
FAR sq_entry_t *entry;
|
||||
uint32_t total = 0;
|
||||
|
||||
if (conn)
|
||||
{
|
||||
for (entry = sq_peek(&conn->unacked_q); entry; entry = sq_next(entry))
|
||||
{
|
||||
wrb = (FAR struct tcp_wrbuffer_s *)entry;
|
||||
total += TCP_WBPKTLEN(wrb);
|
||||
}
|
||||
|
||||
for (entry = sq_peek(&conn->write_q); entry; entry = sq_next(entry))
|
||||
{
|
||||
wrb = (FAR struct tcp_wrbuffer_s *)entry;
|
||||
total += TCP_WBPKTLEN(wrb);
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
#endif /* CONFIG_NET_SEND_BUFSIZE */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_wrbuffer_test
|
||||
*
|
||||
|
|
|
@ -510,6 +510,24 @@ FAR struct udp_wrbuffer_s *udp_wrbuffer_tryalloc(void);
|
|||
void udp_wrbuffer_release(FAR struct udp_wrbuffer_s *wrb);
|
||||
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: udp_wrbuffer_inqueue_size
|
||||
*
|
||||
* Description:
|
||||
* Get the in-queued write buffer size from connection
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The UDP connection of interest
|
||||
*
|
||||
* Assumptions:
|
||||
* Called from user logic with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NET_SEND_BUFSIZE > 0
|
||||
uint32_t udp_wrbuffer_inqueue_size(FAR struct udp_conn_s *conn);
|
||||
#endif /* CONFIG_NET_SEND_BUFSIZE */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: udp_wrbuffer_test
|
||||
*
|
||||
|
|
|
@ -76,6 +76,19 @@ int udp_ioctl(FAR struct udp_conn_s *conn,
|
|||
*(FAR int *)((uintptr_t)arg) = 0;
|
||||
}
|
||||
break;
|
||||
case FIONSPACE:
|
||||
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
|
||||
# if CONFIG_NET_SEND_BUFSIZE == 0
|
||||
*(FAR int *)((uintptr_t)arg) =
|
||||
iob_navail(true) * CONFIG_IOB_BUFSIZE;
|
||||
# else
|
||||
*(FAR int *)((uintptr_t)arg) =
|
||||
conn->sndbufs - udp_wrbuffer_inqueue_size(conn);
|
||||
# endif
|
||||
#else
|
||||
*(FAR int *)((uintptr_t)arg) = MIN_UDP_MSS;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
|
|
|
@ -104,40 +104,6 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev,
|
|||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: udp_inqueue_wrb_size
|
||||
*
|
||||
* Description:
|
||||
* Get the in-queued write buffer size from connection
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The UDP connection of interest
|
||||
*
|
||||
* Assumptions:
|
||||
* Called from user logic with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NET_SEND_BUFSIZE > 0
|
||||
static uint32_t udp_inqueue_wrb_size(FAR struct udp_conn_s *conn)
|
||||
{
|
||||
FAR struct udp_wrbuffer_s *wrb;
|
||||
FAR sq_entry_t *entry;
|
||||
uint32_t total = 0;
|
||||
|
||||
if (conn)
|
||||
{
|
||||
for (entry = sq_peek(&conn->write_q); entry; entry = sq_next(entry))
|
||||
{
|
||||
wrb = (FAR struct udp_wrbuffer_s *)entry;
|
||||
total += wrb->wb_iob->io_pktlen;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
#endif /* CONFIG_NET_SEND_BUFSIZE */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sendto_writebuffer_release
|
||||
*
|
||||
|
@ -676,7 +642,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
|
|||
* wait for the write buffer to be released
|
||||
*/
|
||||
|
||||
while (udp_inqueue_wrb_size(conn) + len > conn->sndbufs)
|
||||
while (udp_wrbuffer_inqueue_size(conn) + len > conn->sndbufs)
|
||||
{
|
||||
if (nonblock)
|
||||
{
|
||||
|
|
|
@ -243,6 +243,40 @@ void udp_wrbuffer_release(FAR struct udp_wrbuffer_s *wrb)
|
|||
nxsem_post(&g_wrbuffer.sem);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: udp_wrbuffer_inqueue_size
|
||||
*
|
||||
* Description:
|
||||
* Get the in-queued write buffer size from connection
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The UDP connection of interest
|
||||
*
|
||||
* Assumptions:
|
||||
* Called from user logic with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NET_SEND_BUFSIZE > 0
|
||||
uint32_t udp_wrbuffer_inqueue_size(FAR struct udp_conn_s *conn)
|
||||
{
|
||||
FAR struct udp_wrbuffer_s *wrb;
|
||||
FAR sq_entry_t *entry;
|
||||
uint32_t total = 0;
|
||||
|
||||
if (conn)
|
||||
{
|
||||
for (entry = sq_peek(&conn->write_q); entry; entry = sq_next(entry))
|
||||
{
|
||||
wrb = (FAR struct udp_wrbuffer_s *)entry;
|
||||
total += wrb->wb_iob->io_pktlen;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
#endif /* CONFIG_NET_SEND_BUFSIZE */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: udp_wrbuffer_test
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue