summaryrefslogtreecommitdiff
path: root/components/net/sal_socket
diff options
context:
space:
mode:
authorarmink <[email protected]>2019-12-17 20:11:46 +0800
committerarmink <[email protected]>2019-12-17 20:11:46 +0800
commit4875ee8a3ab95c4fbf1e09941d3f44d99a9a632b (patch)
tree15c596c04a842bac747bbcf05a703b8da76f8eac /components/net/sal_socket
parentfa46d6ac861f26b472d62abdf1278c445431ce4c (diff)
Sync from master (75a3f3dd3a930eab1dc58fa0258a9d1605a0ac11)
Diffstat (limited to 'components/net/sal_socket')
-rw-r--r--components/net/sal_socket/impl/af_inet_lwip.c12
-rw-r--r--components/net/sal_socket/include/sal_socket.h20
-rw-r--r--components/net/sal_socket/socket/net_sockets.c4
-rw-r--r--components/net/sal_socket/src/sal_socket.c200
4 files changed, 158 insertions, 78 deletions
diff --git a/components/net/sal_socket/impl/af_inet_lwip.c b/components/net/sal_socket/impl/af_inet_lwip.c
index 95e7633635..56df735ab9 100644
--- a/components/net/sal_socket/impl/af_inet_lwip.c
+++ b/components/net/sal_socket/impl/af_inet_lwip.c
@@ -25,6 +25,12 @@
#include <netdev.h>
+#if (LWIP_VERSION < 0x2000000) && NETDEV_IPV6
+#error "The lwIP version is not support IPV6, please disable netdev IPV6 configuration "
+#elif (LWIP_VERSION > 0x2000000) && (NETDEV_IPV6 != LWIP_IPV6)
+#error "IPV6 configuration error, Please check and synchronize netdev and lwip IPV6 configuration."
+#endif
+
#if LWIP_VERSION < 0x2000000
#define SELWAIT_T int
#else
@@ -267,6 +273,8 @@ static int inet_poll(struct dfs_fd *file, struct rt_pollreq *req)
if (sock->errevent)
{
mask |= POLLERR;
+ /* clean error event */
+ sock->errevent = 0;
}
rt_hw_interrupt_enable(level);
}
@@ -308,7 +316,11 @@ static const struct sal_netdb_ops lwip_netdb_ops =
static const struct sal_proto_family lwip_inet_family =
{
AF_INET,
+#if LWIP_VERSION > 0x2000000
+ AF_INET6,
+#else
AF_INET,
+#endif
&lwip_socket_ops,
&lwip_netdb_ops,
};
diff --git a/components/net/sal_socket/include/sal_socket.h b/components/net/sal_socket/include/sal_socket.h
index d72f1e4c3c..b620bbe23c 100644
--- a/components/net/sal_socket/include/sal_socket.h
+++ b/components/net/sal_socket/include/sal_socket.h
@@ -157,6 +157,7 @@ struct sockaddr
char sa_data[14];
};
+#if NETDEV_IPV4
/* members are in network byte order */
struct sockaddr_in
{
@@ -167,6 +168,19 @@ struct sockaddr_in
#define SIN_ZERO_LEN 8
char sin_zero[SIN_ZERO_LEN];
};
+#endif /* NETDEV_IPV4 */
+
+#if NETDEV_IPV6
+struct sockaddr_in6
+{
+ uint8_t sin6_len; /* length of this structure */
+ sa_family_t sin6_family; /* AF_INET6 */
+ in_port_t sin6_port; /* Transport layer port # */
+ uint32_t sin6_flowinfo; /* IPv6 flow information */
+ struct in6_addr sin6_addr; /* IPv6 address */
+ uint32_t sin6_scope_id; /* Set of interfaces for scope */
+};
+#endif /* NETDEV_IPV6 */
struct sockaddr_storage
{
@@ -174,9 +188,9 @@ struct sockaddr_storage
sa_family_t ss_family;
char s2_data1[2];
uint32_t s2_data2[3];
-#if SAL_IPV6
- u32_t s2_data3[3];
-#endif /* SAL_IPV6 */
+#if NETDEV_IPV6
+ uint32_t s2_data3[3];
+#endif /* NETDEV_IPV6 */
};
int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen);
diff --git a/components/net/sal_socket/socket/net_sockets.c b/components/net/sal_socket/socket/net_sockets.c
index 12024c8173..a53b2f1f9c 100644
--- a/components/net/sal_socket/socket/net_sockets.c
+++ b/components/net/sal_socket/socket/net_sockets.c
@@ -105,9 +105,7 @@ int shutdown(int s, int how)
rt_set_errno(-ENOTSOCK);
error = -1;
}
-
- /* socket has been closed, delete it from file system fd */
- fd_put(d);
+
fd_put(d);
return error;
diff --git a/components/net/sal_socket/src/sal_socket.c b/components/net/sal_socket/src/sal_socket.c
index 8f3149abd5..e5c55f8bf8 100644
--- a/components/net/sal_socket/src/sal_socket.c
+++ b/components/net/sal_socket/src/sal_socket.c
@@ -94,12 +94,12 @@ do {
* SAL (Socket Abstraction Layer) initialize.
*
* @return result 0: initialize success
- * -1: initialize failed
+ * -1: initialize failed
*/
int sal_init(void)
{
int cn;
-
+
if (init_ok)
{
LOG_D("Socket Abstraction Layer is already initialized.");
@@ -115,7 +115,7 @@ int sal_init(void)
LOG_E("No memory for socket table.\n");
return -1;
}
-
+
/* create sal socket lock */
rt_mutex_init(&sal_core_lock, "sal_lock", RT_IPC_FLAG_FIFO);
@@ -131,7 +131,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data)
{
#define SAL_INTERNET_VERSION 0x00
#define SAL_INTERNET_BUFF_LEN 12
-#define SAL_INTERNET_TIMEOUT (2 * RT_TICK_PER_SECOND)
+#define SAL_INTERNET_TIMEOUT (2)
#define SAL_INTERNET_HOST "link.rt-thread.org"
#define SAL_INTERNET_PORT 8101
@@ -148,7 +148,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data)
char send_data[SAL_INTERNET_BUFF_LEN], recv_data = 0;
struct rt_delayed_work *delay_work = (struct rt_delayed_work *)work;
- const char month[][SAL_INTERNET_MONTH_LEN] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
+ const char month[][SAL_INTERNET_MONTH_LEN] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
char date[SAL_INTERNET_DATE_LEN];
int moth_num = 0;
@@ -175,7 +175,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data)
}
skt_ops = pf->skt_ops;
- if((sockfd = skt_ops->socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ if ((sockfd = skt_ops->socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
result = -RT_ERROR;
goto __exit;
@@ -224,7 +224,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data)
send_data[11] = RT_REVISION;
skt_ops->sendto(sockfd, send_data, SAL_INTERNET_BUFF_LEN, 0,
- (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
+ (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
result = skt_ops->recvfrom(sockfd, &recv_data, sizeof(recv_data), 0, (struct sockaddr *)&server_addr, &addr_len);
if (result < 0)
@@ -242,7 +242,7 @@ __exit:
if (result > 0)
{
LOG_D("Set network interface device(%s) internet status up.", netdev->name);
- netdev->flags |= NETDEV_FLAG_INTERNET_UP;
+ netdev->flags |= NETDEV_FLAG_INTERNET_UP;
}
else
{
@@ -277,7 +277,7 @@ int sal_check_netdev_internet_up(struct netdev *netdev)
rt_delayed_work_init(net_work, check_netdev_internet_up_work, (void *)netdev);
rt_work_submit(&(net_work->work), RT_TICK_PER_SECOND);
-
+
return 0;
}
@@ -316,10 +316,7 @@ struct sal_socket *sal_get_socket(int socket)
socket = socket - SAL_SOCKET_OFFSET;
/* check socket structure valid or not */
- if (st->sockets[socket]->magic != SAL_SOCKET_MAGIC)
- {
- return RT_NULL;
- }
+ RT_ASSERT(st->sockets[socket]->magic == SAL_SOCKET_MAGIC);
return st->sockets[socket];
}
@@ -351,6 +348,38 @@ static void sal_unlock(void)
}
/**
+ * This function will clean the netdev.
+ *
+ * @note please don't invoke it on ISR.
+ */
+int sal_netdev_cleanup(struct netdev *netdev)
+{
+ int idx = 0, find_dev;
+
+ do
+ {
+ find_dev = 0;
+ sal_lock();
+ for (idx = 0; idx < socket_table.max_socket; idx++)
+ {
+ if (socket_table.sockets[idx] && socket_table.sockets[idx]->netdev == netdev)
+ {
+ find_dev = 1;
+ break;
+ }
+ }
+ sal_unlock();
+ if (find_dev)
+ {
+ rt_thread_mdelay(100);
+ }
+ }
+ while (find_dev);
+
+ return 0;
+}
+
+/**
* This function will initialize sal socket object and set socket options
*
* @param family protocol family
@@ -397,7 +426,7 @@ static int socket_init(int family, int type, int protocol, struct sal_socket **r
flag = RT_TRUE;
}
}
-
+
if (flag == RT_FALSE)
{
/* get network interface device by protocol family */
@@ -421,8 +450,7 @@ static int socket_alloc(struct sal_socket_table *st, int f_socket)
/* find an empty socket entry */
for (idx = f_socket; idx < (int) st->max_socket; idx++)
{
- if (st->sockets[idx] == RT_NULL ||
- st->sockets[idx]->netdev == RT_NULL)
+ if (st->sockets[idx] == RT_NULL)
{
break;
}
@@ -466,6 +494,15 @@ __result:
return idx;
}
+static void socket_free(struct sal_socket_table *st, int idx)
+{
+ struct sal_socket *sock;
+
+ sock = st->sockets[idx];
+ st->sockets[idx] = RT_NULL;
+ rt_free(sock);
+}
+
static int socket_new(void)
{
struct sal_socket *sock;
@@ -498,18 +535,38 @@ __result:
return idx + SAL_SOCKET_OFFSET;
}
+static void socket_delete(int socket)
+{
+ struct sal_socket *sock;
+ struct sal_socket_table *st = &socket_table;
+ int idx;
+
+ idx = socket - SAL_SOCKET_OFFSET;
+ if (idx < 0 || idx >= (int) st->max_socket)
+ {
+ return;
+ }
+ sal_lock();
+ sock = sal_get_socket(socket);
+ RT_ASSERT(sock != RT_NULL);
+ sock->magic = 0;
+ sock->netdev = RT_NULL;
+ socket_free(st, idx);
+ sal_unlock();
+}
+
int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
{
int new_socket;
struct sal_socket *sock;
- struct sal_proto_family *pf;
+ struct sal_proto_family *pf;
/* get the socket object by socket descriptor */
SAL_SOCKET_OBJ_GET(sock, socket);
/* check the network interface socket operations */
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, accept);
-
+
new_socket = pf->skt_ops->accept((int) sock->user_data, addr, addrlen);
if (new_socket != -1)
{
@@ -519,18 +576,20 @@ int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
/* allocate a new socket structure and registered socket options */
new_sal_socket = socket_new();
- if (new_sal_socket < 0)
+ new_sock = sal_get_socket(new_sal_socket);
+ if (new_sock == RT_NULL)
{
pf->skt_ops->closesocket(new_socket);
return -1;
}
- new_sock = sal_get_socket(new_sal_socket);
retval = socket_init(sock->domain, sock->type, sock->protocol, &new_sock);
if (retval < 0)
{
pf->skt_ops->closesocket(new_socket);
rt_memset(new_sock, 0x00, sizeof(struct sal_socket));
+ /* socket init failed, delete socket */
+ socket_delete(new_sal_socket);
LOG_E("New socket registered failed, return error %d.", retval);
return -1;
}
@@ -549,20 +608,20 @@ static void sal_sockaddr_to_ipaddr(const struct sockaddr *name, ip_addr_t *local
const struct sockaddr_in *svr_addr = (const struct sockaddr_in *) name;
#if NETDEV_IPV4 && NETDEV_IPV6
- (*local_ipaddr).u_addr.ip4.addr = svr_addr->sin_addr.s_addr;
+ local_ipaddr->u_addr.ip4.addr = svr_addr->sin_addr.s_addr;
+ local_ipaddr->type = IPADDR_TYPE_V4;
#elif NETDEV_IPV4
- (*local_ipaddr).addr = svr_addr->sin_addr.s_addr;
+ local_ipaddr->addr = svr_addr->sin_addr.s_addr;
#elif NETDEV_IPV6
- LOG_E("not support IPV6");
-#endif /* SAL_IPV4 && SAL_IPV6*/
-}
+#error "not only support IPV6"
+#endif /* NETDEV_IPV4 && NETDEV_IPV6*/
+}
int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen)
{
struct sal_socket *sock;
struct sal_proto_family *pf;
- struct netdev *new_netdev;
- ip_addr_t local_addr;
+ ip_addr_t input_ipaddr;
RT_ASSERT(name);
@@ -570,44 +629,43 @@ int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen)
SAL_SOCKET_OBJ_GET(sock, socket);
/* bind network interface by ip address */
- sal_sockaddr_to_ipaddr(name, &local_addr);
+ sal_sockaddr_to_ipaddr(name, &input_ipaddr);
/* check input ipaddr is default netdev ipaddr */
- if (local_addr.addr == INADDR_ANY)
+ if (!ip_addr_isany_val(input_ipaddr))
{
- SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, bind);
- return pf->skt_ops->bind((int) sock->user_data, name, namelen);
- }
-
- new_netdev = netdev_get_by_ipaddr(&local_addr);
- if (new_netdev == RT_NULL)
- {
- LOG_E("Not find network interface device ipaddr(%s).", inet_ntoa(local_addr));
- return -1;
- }
+ struct sal_proto_family *input_pf = RT_NULL, *local_pf = RT_NULL;
+ struct netdev *new_netdev = RT_NULL;
- /* change network interface device parameter in sal socket object */
- if (sock->netdev != new_netdev)
- {
- struct sal_proto_family *old_pf, *new_pf;
- int new_socket = 0;
+ new_netdev = netdev_get_by_ipaddr(&input_ipaddr);
+ if (new_netdev == RT_NULL)
+ {
+ return -1;
+ }
- /* close old netdev socket */
- SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, old_pf, closesocket);
- old_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);
- /* open new netdev socket */
- SAL_NETDEV_SOCKETOPS_VALID(new_netdev, new_pf, socket);
- new_socket = new_pf->skt_ops->socket(sock->domain, 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 *) new_socket;
}
- sock->netdev = new_netdev;
- sock->user_data = (void *) new_socket;
}
- /* check the network interface socket opreation */
+ /* check and get protocol families by the network interface device */
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, bind);
return pf->skt_ops->bind((int) sock->user_data, name, namelen);
}
@@ -643,9 +701,6 @@ int sal_shutdown(int socket, int how)
error = -1;
}
- /* free socket */
- rt_free(sock);
- socket_table.sockets[socket] = RT_NULL;
return error;
}
@@ -761,7 +816,7 @@ int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen)
{
return -1;
}
-
+
return ret;
}
#endif
@@ -784,7 +839,7 @@ int sal_listen(int socket, int backlog)
}
int sal_recvfrom(int socket, void *mem, size_t len, int flags,
- struct sockaddr *from, socklen_t *fromlen)
+ struct sockaddr *from, socklen_t *fromlen)
{
struct sal_socket *sock;
struct sal_proto_family *pf;
@@ -801,11 +856,11 @@ int sal_recvfrom(int socket, void *mem, size_t len, int flags,
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, recv))
{
int ret;
-
+
if ((ret = proto_tls->ops->recv(sock->user_data_tls, mem, len)) < 0)
{
return -1;
- }
+ }
return ret;
}
else
@@ -818,7 +873,7 @@ int sal_recvfrom(int socket, void *mem, size_t len, int flags,
}
int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
- const struct sockaddr *to, socklen_t tolen)
+ const struct sockaddr *to, socklen_t tolen)
{
struct sal_socket *sock;
struct sal_proto_family *pf;
@@ -835,11 +890,11 @@ int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, send))
{
int ret;
-
+
if ((ret = proto_tls->ops->send(sock->user_data_tls, dataptr, size)) < 0)
{
return -1;
- }
+ }
return ret;
}
else
@@ -877,6 +932,7 @@ int sal_socket(int domain, int type, int protocol)
if (retval < 0)
{
LOG_E("SAL socket protocol family input failed, return error %d.", retval);
+ socket_delete(socket);
return -1;
}
@@ -892,6 +948,7 @@ int sal_socket(int domain, int type, int protocol)
sock->user_data_tls = proto_tls->ops->socket(socket);
if (sock->user_data_tls == RT_NULL)
{
+ socket_delete(socket);
return -1;
}
}
@@ -934,9 +991,8 @@ int sal_closesocket(int socket)
error = -1;
}
- /* free socket */
- rt_free(sock);
- socket_table.sockets[socket] = RT_NULL;
+ /* delete socket */
+ socket_delete(socket);
return error;
}
@@ -997,7 +1053,7 @@ struct hostent *sal_gethostbyname(const char *name)
}
int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
- size_t buflen, struct hostent **result, int *h_errnop)
+ size_t buflen, struct hostent **result, int *h_errnop)
{
struct netdev *netdev = netdev_default;
struct sal_proto_family *pf;
@@ -1020,9 +1076,9 @@ int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
}
int sal_getaddrinfo(const char *nodename,
- const char *servname,
- const struct addrinfo *hints,
- struct addrinfo **res)
+ const char *servname,
+ const struct addrinfo *hints,
+ struct addrinfo **res)
{
struct netdev *netdev = netdev_default;
struct sal_proto_family *pf;