Merge pull request #1981 from Lawlieta/sal
[net][sal] Add SAL component TLS features support
This commit is contained in:
commit
6f97b9ff48
|
@ -21,6 +21,11 @@ config RT_USING_SAL
|
|||
bool "Support AT Commands stack"
|
||||
default y
|
||||
depends on AT_USING_SOCKET
|
||||
|
||||
config SAL_USING_TLS
|
||||
bool "Support MbedTLS protocol"
|
||||
default y
|
||||
depends on PKG_USING_MBEDTLS
|
||||
endmenu
|
||||
|
||||
endif
|
||||
|
|
|
@ -15,10 +15,13 @@ if GetDepend('SAL_USING_LWIP'):
|
|||
|
||||
if GetDepend('SAL_USING_AT'):
|
||||
src += Glob('impl/af_inet_at.c')
|
||||
|
||||
|
||||
if GetDepend('SAL_USING_LWIP') or GetDepend('SAL_USING_AT'):
|
||||
CPPPATH += [cwd + '/impl']
|
||||
|
||||
if GetDepend('SAL_USING_TLS'):
|
||||
src += Glob('impl/proto_mbedtls.c')
|
||||
|
||||
if GetDepend('SAL_USING_POSIX'):
|
||||
CPPPATH += [cwd + '/include/dfs_net']
|
||||
src += Glob('socket/net_sockets.c')
|
||||
|
|
|
@ -62,7 +62,7 @@ static int at_poll(struct dfs_fd *file, struct rt_pollreq *req)
|
|||
}
|
||||
#endif
|
||||
|
||||
static const struct proto_ops at_inet_stream_ops =
|
||||
static const struct sal_socket_ops at_socket_ops =
|
||||
{
|
||||
at_socket,
|
||||
at_closesocket,
|
||||
|
@ -90,25 +90,30 @@ static int at_create(struct sal_socket *socket, int type, int protocol)
|
|||
|
||||
//TODO Check type & protocol
|
||||
|
||||
socket->ops = &at_inet_stream_ops;
|
||||
socket->ops = &at_socket_ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct proto_family at_inet_family_ops = {
|
||||
"at",
|
||||
static struct sal_proto_ops at_proto_ops =
|
||||
{
|
||||
at_gethostbyname,
|
||||
NULL,
|
||||
at_getaddrinfo,
|
||||
at_freeaddrinfo,
|
||||
};
|
||||
|
||||
static const struct sal_proto_family at_inet_family =
|
||||
{
|
||||
AF_AT,
|
||||
AF_INET,
|
||||
at_create,
|
||||
at_gethostbyname,
|
||||
NULL,
|
||||
at_freeaddrinfo,
|
||||
at_getaddrinfo,
|
||||
&at_proto_ops,
|
||||
};
|
||||
|
||||
int at_inet_init(void)
|
||||
{
|
||||
sal_proto_family_register(&at_inet_family_ops);
|
||||
sal_proto_family_register(&at_inet_family);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -259,7 +259,8 @@ static int inet_poll(struct dfs_fd *file, struct rt_pollreq *req)
|
|||
}
|
||||
#endif
|
||||
|
||||
static const struct proto_ops lwip_inet_stream_ops = {
|
||||
static const struct sal_socket_ops lwip_socket_ops =
|
||||
{
|
||||
inet_socket,
|
||||
lwip_close,
|
||||
lwip_bind,
|
||||
|
@ -286,25 +287,30 @@ static int inet_create(struct sal_socket *socket, int type, int protocol)
|
|||
|
||||
//TODO Check type & protocol
|
||||
|
||||
socket->ops = &lwip_inet_stream_ops;
|
||||
socket->ops = &lwip_socket_ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct proto_family lwip_inet_family_ops = {
|
||||
"lwip",
|
||||
static struct sal_proto_ops lwip_proto_ops =
|
||||
{
|
||||
lwip_gethostbyname,
|
||||
lwip_gethostbyname_r,
|
||||
lwip_getaddrinfo,
|
||||
lwip_freeaddrinfo,
|
||||
};
|
||||
|
||||
static const struct sal_proto_family lwip_inet_family =
|
||||
{
|
||||
AF_INET,
|
||||
AF_INET,
|
||||
inet_create,
|
||||
lwip_gethostbyname,
|
||||
lwip_gethostbyname_r,
|
||||
lwip_freeaddrinfo,
|
||||
lwip_getaddrinfo,
|
||||
&lwip_proto_ops,
|
||||
};
|
||||
|
||||
int lwip_inet_init(void)
|
||||
{
|
||||
sal_proto_family_register(&lwip_inet_family_ops);
|
||||
sal_proto_family_register(&lwip_inet_family);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-12 ChenYong First version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef RT_USING_DFS
|
||||
#include <dfs_posix.h>
|
||||
#endif
|
||||
|
||||
#ifdef SAL_USING_TLS
|
||||
#include <sal_tls.h>
|
||||
#endif
|
||||
#include <netdb.h>
|
||||
#include <sal.h>
|
||||
|
||||
#ifdef SAL_USING_TLS
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include <mbedtls/config.h>
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include <tls_certificate.h>
|
||||
#include <tls_client.h>
|
||||
|
||||
#ifndef SAL_MEBDTLS_BUFFER_LEN
|
||||
#define SAL_MEBDTLS_BUFFER_LEN 1024
|
||||
#endif
|
||||
|
||||
static void *mebdtls_socket(int socket)
|
||||
{
|
||||
MbedTLSSession *session = RT_NULL;
|
||||
char *pers = "mbedtls";
|
||||
|
||||
if (socket < 0)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
session = (MbedTLSSession *) tls_calloc(1, sizeof(MbedTLSSession));
|
||||
if (session == RT_NULL)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
session->buffer_len = SAL_MEBDTLS_BUFFER_LEN;
|
||||
session->buffer = tls_calloc(1, session->buffer_len);
|
||||
if (session->buffer == RT_NULL)
|
||||
{
|
||||
tls_free(session);
|
||||
session = RT_NULL;
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
/* initialize TLS Client sesison */
|
||||
if (mbedtls_client_init(session, (void *) pers, rt_strlen(pers)) != RT_EOK)
|
||||
{
|
||||
mbedtls_client_close(session);
|
||||
return RT_NULL;
|
||||
}
|
||||
session->server_fd.fd = socket;
|
||||
|
||||
return (void *)session;
|
||||
}
|
||||
|
||||
int mbedtls_net_send_cb(void *ctx, const unsigned char *buf, size_t len)
|
||||
{
|
||||
struct sal_socket *sock;
|
||||
int socket, ret;
|
||||
|
||||
RT_ASSERT(ctx);
|
||||
RT_ASSERT(buf);
|
||||
|
||||
socket = ((mbedtls_net_context *) ctx)->fd;
|
||||
sock = sal_get_socket(socket);
|
||||
if (sock == RT_NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Register scoket sendto option to TLS send data callback */
|
||||
ret = sock->ops->sendto((int) sock->user_data, (void *)buf, len, 0, RT_NULL, RT_NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
#ifdef RT_USING_DFS
|
||||
if ((fcntl(socket, F_GETFL) & O_NONBLOCK) == O_NONBLOCK)
|
||||
return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
#endif
|
||||
if (errno == ECONNRESET)
|
||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
if ( errno == EINTR)
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
|
||||
return MBEDTLS_ERR_NET_SEND_FAILED ;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_net_recv_cb( void *ctx, unsigned char *buf, size_t len)
|
||||
{
|
||||
struct sal_socket *sock;
|
||||
int socket, ret;
|
||||
|
||||
RT_ASSERT(ctx);
|
||||
RT_ASSERT(buf);
|
||||
|
||||
socket = ((mbedtls_net_context *) ctx)->fd;
|
||||
sock = sal_get_socket(socket);
|
||||
if (sock == RT_NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Register scoket recvfrom option to TLS recv data callback */
|
||||
ret = sock->ops->recvfrom((int) sock->user_data, (void *)buf, len, 0, RT_NULL, RT_NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
#ifdef RT_USING_DFS
|
||||
if ((fcntl(socket, F_GETFL) & O_NONBLOCK) == O_NONBLOCK)
|
||||
return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
#endif
|
||||
if (errno == ECONNRESET)
|
||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
if ( errno == EINTR)
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
|
||||
return MBEDTLS_ERR_NET_RECV_FAILED ;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mbedtls_connect(void *sock)
|
||||
{
|
||||
MbedTLSSession *session = RT_NULL;
|
||||
int ret = 0;
|
||||
|
||||
RT_ASSERT(sock);
|
||||
|
||||
session = (MbedTLSSession *) sock;
|
||||
|
||||
/* Set the SSL Configure infromation */
|
||||
ret = mbedtls_client_context(session);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
/* Set the underlying BIO callbacks for write, read and read-with-timeout. */
|
||||
mbedtls_ssl_set_bio(&session->ssl, &session->server_fd, mbedtls_net_send_cb, mbedtls_net_recv_cb, RT_NULL);
|
||||
|
||||
while ((ret = mbedtls_ssl_handshake(&session->ssl)) != 0)
|
||||
{
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
|
||||
{
|
||||
goto __exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the result of the certificate verification */
|
||||
ret = mbedtls_ssl_get_verify_result(&session->ssl);
|
||||
if (ret != 0)
|
||||
{
|
||||
rt_memset(session->buffer, 0x00, session->buffer_len);
|
||||
mbedtls_x509_crt_verify_info((char *)session->buffer, session->buffer_len, " ! ", ret);
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
__exit:
|
||||
if (session)
|
||||
{
|
||||
mbedtls_client_close(session);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mbedtls_closesocket(void *sock)
|
||||
{
|
||||
struct sal_socket *ssock;
|
||||
int socket;
|
||||
|
||||
if (sock == RT_NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
socket = ((MbedTLSSession *) sock)->server_fd.fd;
|
||||
ssock = sal_get_socket(socket);
|
||||
if (ssock == RT_NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Close TLS client session, and clean user-data in SAL socket */
|
||||
mbedtls_client_close((MbedTLSSession *) sock);
|
||||
ssock->user_data_tls = RT_NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sal_proto_tls_ops mbedtls_proto_ops=
|
||||
{
|
||||
RT_NULL,
|
||||
mebdtls_socket,
|
||||
mbedtls_connect,
|
||||
(int (*)(void *sock, const void *data, size_t size)) mbedtls_client_write,
|
||||
(int (*)(void *sock, void *mem, size_t len)) mbedtls_client_read,
|
||||
mbedtls_closesocket,
|
||||
};
|
||||
|
||||
static const struct sal_proto_tls mbedtls_proto =
|
||||
{
|
||||
"mbedtls",
|
||||
&mbedtls_proto_ops,
|
||||
};
|
||||
|
||||
int sal_mbedtls_proto_init(void)
|
||||
{
|
||||
/* register MbedTLS protocol options to SAL */
|
||||
sal_proto_tls_register(&mbedtls_proto);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_COMPONENT_EXPORT(sal_mbedtls_proto_init);
|
||||
|
||||
#endif /* SAL_USING_TLS */
|
|
@ -25,7 +25,7 @@ extern "C" {
|
|||
typedef uint32_t socklen_t;
|
||||
#endif
|
||||
|
||||
/* sal socket magic word */
|
||||
/* SAL socket magic word */
|
||||
#define SAL_SOCKET_MAGIC 0x5A10
|
||||
|
||||
/* The maximum number of sockets structure */
|
||||
|
@ -38,12 +38,12 @@ typedef uint32_t socklen_t;
|
|||
#define SAL_PROTO_FAMILIES_NUM 4
|
||||
#endif
|
||||
|
||||
/* sal socket offset */
|
||||
/* SAL socket offset */
|
||||
#ifndef SAL_SOCKET_OFFSET
|
||||
#define SAL_SOCKET_OFFSET 0
|
||||
#endif
|
||||
|
||||
struct proto_ops
|
||||
struct sal_socket_ops
|
||||
{
|
||||
int (*socket) (int domain, int type, int protocol);
|
||||
int (*closesocket)(int s);
|
||||
|
@ -64,30 +64,38 @@ struct proto_ops
|
|||
#endif
|
||||
};
|
||||
|
||||
struct sal_proto_ops
|
||||
{
|
||||
struct hostent* (*gethostbyname) (const char *name);
|
||||
int (*gethostbyname_r)(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop);
|
||||
int (*getaddrinfo) (const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res);
|
||||
void (*freeaddrinfo) (struct addrinfo *ai);
|
||||
};
|
||||
|
||||
struct sal_socket
|
||||
{
|
||||
uint32_t magic; /* sal socket magic word */
|
||||
uint32_t magic; /* SAL socket magic word */
|
||||
|
||||
int socket; /* sal socket descriptor */
|
||||
int socket; /* SAL socket descriptor */
|
||||
int domain;
|
||||
int type;
|
||||
int protocol;
|
||||
|
||||
const struct proto_ops *ops; /* socket options */
|
||||
void *user_data; /* specific sal socket data */
|
||||
const struct sal_socket_ops *ops; /* socket options */
|
||||
|
||||
void *user_data; /* user-specific data */
|
||||
#ifdef SAL_USING_TLS
|
||||
void *user_data_tls; /* user-specific TLS data */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct proto_family
|
||||
struct sal_proto_family
|
||||
{
|
||||
char name[RT_NAME_MAX];
|
||||
int family; /* primary protocol families type */
|
||||
int sec_family; /* secondary protocol families type */
|
||||
int (*create)(struct sal_socket *sal_socket, int type, int protocol); /* register socket options */
|
||||
int (*create)(struct sal_socket *sal_socket, int type, int protocol); /* register socket options */
|
||||
|
||||
struct hostent* (*gethostbyname) (const char *name);
|
||||
int (*gethostbyname_r)(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop);
|
||||
void (*freeaddrinfo) (struct addrinfo *ai);
|
||||
int (*getaddrinfo) (const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res);
|
||||
struct sal_proto_ops *ops; /* protocol family options */
|
||||
};
|
||||
|
||||
/* SAL(Socket Abstraction Layer) initialize */
|
||||
|
@ -95,10 +103,11 @@ int sal_init(void);
|
|||
|
||||
struct sal_socket *sal_get_socket(int sock);
|
||||
|
||||
/* protocol family register and unregister operate */
|
||||
int sal_proto_family_register(const struct proto_family *pf);
|
||||
int sal_proto_family_unregister(const struct proto_family *pf);
|
||||
struct proto_family *sal_proto_family_find(const char *name);
|
||||
/* SAL protocol family register and unregister operate */
|
||||
int sal_proto_family_register(const struct sal_proto_family *pf);
|
||||
int sal_proto_family_unregister(int family);
|
||||
rt_bool_t sal_proto_family_is_registered(int family);
|
||||
struct sal_proto_family *sal_proto_family_find(int family);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-10 ChenYong First version
|
||||
*/
|
||||
#ifndef __SAL_TLS_H__
|
||||
#define __SAL_TLS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
/* Protocol level for TLS.
|
||||
* Here, the same socket protocol level for TLS as in Linux was used.
|
||||
*/
|
||||
#define SOL_TLS 282
|
||||
|
||||
/* Socket options for TLS */
|
||||
|
||||
/* Socket option to select TLS credentials to use. */
|
||||
#define TLS_CRET_LIST 1
|
||||
/* Socket option to set select ciphersuites to use. */
|
||||
#define TLS_CIPHERSUITE_LIST 2
|
||||
/* Socket option to set peer verification level for TLS connection. */
|
||||
#define TLS_PEER_VERIFY 3
|
||||
/* Socket option to set role for DTLS connection. */
|
||||
#define TLS_DTLS_ROLE 4
|
||||
|
||||
/* Protocol numbers for TLS protocols */
|
||||
#define PROTOCOL_TLS 256
|
||||
#define PROTOCOL_DTLS 257
|
||||
|
||||
|
||||
struct sal_proto_tls_ops
|
||||
{
|
||||
int (*init)(void);
|
||||
void* (*socket)(int socket);
|
||||
int (*connect)(void *sock);
|
||||
int (*send)(void *sock, const void *data, size_t size);
|
||||
int (*recv)(void *sock, void *mem, size_t len);
|
||||
int (*closesocket)(void *sock);
|
||||
|
||||
int (*set_cret_list)(void *sock, const void *cert, size_t size); /* Set TLS credentials */
|
||||
int (*set_ciphersurite)(void *sock, const void* ciphersurite, size_t size); /* Set select ciphersuites */
|
||||
int (*set_peer_verify)(void *sock, const void* peer_verify, size_t size); /* Set peer verification */
|
||||
int (*set_dtls_role)(void *sock, const void *dtls_role, size_t size); /* Set role for DTLS */
|
||||
};
|
||||
|
||||
struct sal_proto_tls
|
||||
{
|
||||
char name[RT_NAME_MAX]; /* TLS protocol name */
|
||||
const struct sal_proto_tls_ops *ops; /* SAL TLS protocol options */
|
||||
};
|
||||
|
||||
/* SAL TLS protocol register */
|
||||
int sal_proto_tls_register(const struct sal_proto_tls *pt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SAL_TLS_H__ */
|
|
@ -14,6 +14,9 @@
|
|||
|
||||
#include <rtthread.h>
|
||||
#include <sal_socket.h>
|
||||
#ifdef SAL_USING_TLS
|
||||
#include <sal_tls.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-05-23 ChenYong First version
|
||||
* 2018-11-12 ChenYong Add TLS support
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
@ -13,6 +14,9 @@
|
|||
|
||||
#include <sal_socket.h>
|
||||
#include <sal_netdb.h>
|
||||
#ifdef SAL_USING_TLS
|
||||
#include <sal_tls.h>
|
||||
#endif
|
||||
#include <sal.h>
|
||||
|
||||
#define DBG_ENABLE
|
||||
|
@ -30,13 +34,32 @@ struct sal_socket_table
|
|||
struct sal_socket **sockets;
|
||||
};
|
||||
|
||||
#ifdef SAL_USING_TLS
|
||||
/* The global TLS protocol options */
|
||||
static struct sal_proto_tls *proto_tls;
|
||||
#endif
|
||||
|
||||
/* The global array of available protocol families */
|
||||
static struct proto_family proto_families[SAL_PROTO_FAMILIES_NUM];
|
||||
static struct sal_proto_family proto_families[SAL_PROTO_FAMILIES_NUM];
|
||||
/* The global socket table */
|
||||
static struct sal_socket_table socket_table;
|
||||
static struct rt_mutex sal_core_lock;
|
||||
static rt_bool_t init_ok = RT_FALSE;
|
||||
|
||||
#define IS_SOCKET_PROTO_TLS(sock) (((sock)->protocol == PROTOCOL_TLS) || \
|
||||
((sock)->protocol == PROTOCOL_DTLS))
|
||||
#define SAL_SOCKOPS_PROTO_TLS_VALID(sock, name) (proto_tls && (proto_tls->ops->name) && IS_SOCKET_PROTO_TLS(sock))
|
||||
|
||||
#define SAL_SOCKOPT_PROTO_TLS_EXEC(sock, name, optval, optlen) \
|
||||
do \
|
||||
{ \
|
||||
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, name)) \
|
||||
{ \
|
||||
return proto_tls->ops->name((sock)->user_data_tls, (optval), (optlen)); \
|
||||
} \
|
||||
}while(0) \
|
||||
|
||||
|
||||
/**
|
||||
* SAL (Socket Abstraction Layer) initialize.
|
||||
*
|
||||
|
@ -47,7 +70,7 @@ int sal_init(void)
|
|||
{
|
||||
int cn;
|
||||
|
||||
if(init_ok)
|
||||
if (init_ok)
|
||||
{
|
||||
LOG_D("Socket Abstraction Layer is already initialized.");
|
||||
return 0;
|
||||
|
@ -73,15 +96,32 @@ int sal_init(void)
|
|||
}
|
||||
INIT_COMPONENT_EXPORT(sal_init);
|
||||
|
||||
/**
|
||||
* This function will register TLS protocol to the global TLS protocol.
|
||||
*
|
||||
* @param pt TLS protocol object
|
||||
*
|
||||
* @return 0: TLS protocol object register success
|
||||
*/
|
||||
#ifdef SAL_USING_TLS
|
||||
int sal_proto_tls_register(const struct sal_proto_tls *pt)
|
||||
{
|
||||
RT_ASSERT(pt);
|
||||
proto_tls = (struct sal_proto_tls *) pt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will register protocol family to the global array of protocol families.
|
||||
*
|
||||
* @param pf protocol family object
|
||||
*
|
||||
* @return 0 : protocol family object register success
|
||||
* -1 : the global array of available protocol families is full
|
||||
* @return 0: protocol family object register success
|
||||
* -1: the global array of available protocol families is full
|
||||
*/
|
||||
int sal_proto_family_register(const struct proto_family *pf)
|
||||
int sal_proto_family_register(const struct sal_proto_family *pf)
|
||||
{
|
||||
rt_base_t level;
|
||||
int idx;
|
||||
|
@ -92,11 +132,11 @@ int sal_proto_family_register(const struct proto_family *pf)
|
|||
/* check protocol family is already registered */
|
||||
for(idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
|
||||
{
|
||||
if(rt_strcmp(proto_families[idx].name, pf->name) == 0)
|
||||
if (proto_families[idx].family == pf->family && proto_families[idx].create)
|
||||
{
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
LOG_E("%s protocol family is already registered!", pf->name);
|
||||
LOG_E("%s protocol family is already registered!", pf->family);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -105,22 +145,22 @@ int sal_proto_family_register(const struct proto_family *pf)
|
|||
for(idx = 0; idx < SAL_PROTO_FAMILIES_NUM && proto_families[idx].create; idx++);
|
||||
|
||||
/* can't find an empty protocol family entry */
|
||||
if(idx == SAL_PROTO_FAMILIES_NUM)
|
||||
if (idx == SAL_PROTO_FAMILIES_NUM)
|
||||
{
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rt_strncpy(proto_families[idx].name, pf->name, rt_strlen(pf->name));
|
||||
proto_families[idx].family = pf->family;
|
||||
proto_families[idx].sec_family = pf->sec_family;
|
||||
proto_families[idx].create = pf->create;
|
||||
|
||||
proto_families[idx].gethostbyname = pf->gethostbyname;
|
||||
proto_families[idx].gethostbyname_r = pf->gethostbyname_r;
|
||||
proto_families[idx].freeaddrinfo = pf->freeaddrinfo;
|
||||
proto_families[idx].getaddrinfo = pf->getaddrinfo;
|
||||
proto_families[idx].ops = pf->ops;
|
||||
proto_families[idx].ops->gethostbyname = pf->ops->gethostbyname;
|
||||
proto_families[idx].ops->gethostbyname_r = pf->ops->gethostbyname_r;
|
||||
proto_families[idx].ops->freeaddrinfo = pf->ops->freeaddrinfo;
|
||||
proto_families[idx].ops->getaddrinfo = pf->ops->getaddrinfo;
|
||||
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
@ -136,17 +176,17 @@ int sal_proto_family_register(const struct proto_family *pf)
|
|||
* @return >=0 : unregister protocol family index
|
||||
* -1 : unregister failed
|
||||
*/
|
||||
int sal_proto_family_unregister(const struct proto_family *pf)
|
||||
int sal_proto_family_unregister(int family)
|
||||
{
|
||||
int idx = 0;
|
||||
|
||||
RT_ASSERT(pf != RT_NULL);
|
||||
RT_ASSERT(family > 0 && family < AF_MAX);
|
||||
|
||||
for(idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
|
||||
{
|
||||
if(rt_strcmp(proto_families[idx].name, pf->name) == 0)
|
||||
if (proto_families[idx].family == family && proto_families[idx].create)
|
||||
{
|
||||
rt_memset(&proto_families[idx], 0x00, sizeof(struct proto_family));
|
||||
rt_memset(&proto_families[idx], 0x00, sizeof(struct sal_proto_family));
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
@ -156,21 +196,46 @@ int sal_proto_family_unregister(const struct proto_family *pf)
|
|||
}
|
||||
|
||||
/**
|
||||
* This function will get protocol family by name.
|
||||
* This function will judge whether protocol family is registered
|
||||
*
|
||||
* @param name protocol family name
|
||||
* @param family protocol family number
|
||||
*
|
||||
* @return protocol family object
|
||||
* @return 1: protocol family is registered
|
||||
* 0: protocol family is not registered
|
||||
*/
|
||||
struct proto_family *sal_proto_family_find(const char *name)
|
||||
rt_bool_t sal_proto_family_is_registered(int family)
|
||||
{
|
||||
int idx = 0;
|
||||
|
||||
RT_ASSERT(name != RT_NULL);
|
||||
RT_ASSERT(family > 0 && family < AF_MAX);
|
||||
|
||||
for (idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
|
||||
{
|
||||
if (rt_strcmp(proto_families[idx].name, name) == 0)
|
||||
if (proto_families[idx].family == family && proto_families[idx].create)
|
||||
{
|
||||
return RT_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get protocol family object by family number.
|
||||
*
|
||||
* @param family protocol family number
|
||||
*
|
||||
* @return protocol family object
|
||||
*/
|
||||
struct sal_proto_family *sal_proto_family_find(int family)
|
||||
{
|
||||
int idx = 0;
|
||||
|
||||
RT_ASSERT(family > 0 && family < AF_MAX);
|
||||
|
||||
for (idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
|
||||
{
|
||||
if (proto_families[idx].family == family && proto_families[idx].create)
|
||||
{
|
||||
return &proto_families[idx];
|
||||
}
|
||||
|
@ -238,7 +303,7 @@ static void sal_unlock(void)
|
|||
*
|
||||
* @return protocol family structure address
|
||||
*/
|
||||
static struct proto_family *get_proto_family(int family)
|
||||
static struct sal_proto_family *get_proto_family(int family)
|
||||
{
|
||||
int idx;
|
||||
|
||||
|
@ -278,7 +343,7 @@ static struct proto_family *get_proto_family(int family)
|
|||
static int socket_init(int family, int type, int protocol, struct sal_socket **res)
|
||||
{
|
||||
struct sal_socket *sock;
|
||||
struct proto_family *pf;
|
||||
struct sal_proto_family *pf;
|
||||
|
||||
if (family < 0 || family > AF_MAX)
|
||||
{
|
||||
|
@ -383,6 +448,11 @@ static int socket_new(void)
|
|||
sock = st->sockets[idx];
|
||||
sock->socket = idx + SAL_SOCKET_OFFSET;
|
||||
sock->magic = SAL_SOCKET_MAGIC;
|
||||
sock->ops = RT_NULL;
|
||||
sock->user_data = RT_NULL;
|
||||
#ifdef SAL_USING_TLS
|
||||
sock->user_data_tls = RT_NULL;
|
||||
#endif
|
||||
|
||||
__result:
|
||||
sal_unlock();
|
||||
|
@ -474,6 +544,15 @@ int sal_shutdown(int socket, int how)
|
|||
|
||||
if (sock->ops->shutdown((int) sock->user_data, how) == 0)
|
||||
{
|
||||
#ifdef SAL_USING_TLS
|
||||
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, closesocket))
|
||||
{
|
||||
if (proto_tls->ops->closesocket(sock->user_data_tls) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
rt_free(sock);
|
||||
socket_table.sockets[socket] = RT_NULL;
|
||||
return 0;
|
||||
|
@ -551,12 +630,46 @@ int sal_setsockopt(int socket, int level, int optname, const void *optval, sockl
|
|||
return -RT_ENOSYS;
|
||||
}
|
||||
|
||||
#ifdef SAL_USING_TLS
|
||||
if (level == SOL_TLS)
|
||||
{
|
||||
switch (optname)
|
||||
{
|
||||
case TLS_CRET_LIST:
|
||||
SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_cret_list, optval, optlen);
|
||||
break;
|
||||
|
||||
case TLS_CIPHERSUITE_LIST:
|
||||
SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_ciphersurite, optval, optlen);
|
||||
break;
|
||||
|
||||
case TLS_PEER_VERIFY:
|
||||
SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_peer_verify, optval, optlen);
|
||||
break;
|
||||
|
||||
case TLS_DTLS_ROLE:
|
||||
SAL_SOCKOPT_PROTO_TLS_EXEC(sock, set_dtls_role, optval, optlen);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sock->ops->setsockopt((int) sock->user_data, level, optname, optval, optlen);
|
||||
}
|
||||
#else
|
||||
return sock->ops->setsockopt((int) sock->user_data, level, optname, optval, optlen);
|
||||
#endif /* SAL_USING_TLS */
|
||||
}
|
||||
|
||||
int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen)
|
||||
{
|
||||
struct sal_socket *sock;
|
||||
int ret;
|
||||
|
||||
sock = sal_get_socket(socket);
|
||||
if (!sock)
|
||||
|
@ -569,7 +682,20 @@ int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen)
|
|||
return -RT_ENOSYS;
|
||||
}
|
||||
|
||||
return sock->ops->connect((int) sock->user_data, name, namelen);
|
||||
ret = sock->ops->connect((int) sock->user_data, name, namelen);
|
||||
#ifdef SAL_USING_TLS
|
||||
if (ret >= 0 && SAL_SOCKOPS_PROTO_TLS_VALID(sock, connect))
|
||||
{
|
||||
if (proto_tls->ops->connect(sock->user_data_tls) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sal_listen(int socket, int backlog)
|
||||
|
@ -606,7 +732,24 @@ int sal_recvfrom(int socket, void *mem, size_t len, int flags,
|
|||
return -RT_ENOSYS;
|
||||
}
|
||||
|
||||
#ifdef SAL_USING_TLS
|
||||
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
|
||||
{
|
||||
return sock->ops->recvfrom((int) sock->user_data, mem, len, flags, from, fromlen);
|
||||
}
|
||||
#else
|
||||
return sock->ops->recvfrom((int) sock->user_data, mem, len, flags, from, fromlen);
|
||||
#endif
|
||||
}
|
||||
|
||||
int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
|
||||
|
@ -625,7 +768,24 @@ int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
|
|||
return -RT_ENOSYS;
|
||||
}
|
||||
|
||||
#ifdef SAL_USING_TLS
|
||||
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
|
||||
{
|
||||
return sock->ops->sendto((int) sock->user_data, dataptr, size, flags, to, tolen);
|
||||
}
|
||||
#else
|
||||
return sock->ops->sendto((int) sock->user_data, dataptr, size, flags, to, tolen);
|
||||
#endif
|
||||
}
|
||||
|
||||
int sal_socket(int domain, int type, int protocol)
|
||||
|
@ -657,8 +817,17 @@ int sal_socket(int domain, int type, int protocol)
|
|||
proto_socket = sock->ops->socket(domain, type, protocol);
|
||||
if (proto_socket >= 0)
|
||||
{
|
||||
#ifdef SAL_USING_TLS
|
||||
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, socket))
|
||||
{
|
||||
sock->user_data_tls = proto_tls->ops->socket(proto_socket);
|
||||
if (sock->user_data_tls == RT_NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
sock->user_data = (void *) proto_socket;
|
||||
|
||||
return sock->socket;
|
||||
}
|
||||
|
||||
|
@ -682,6 +851,15 @@ int sal_closesocket(int socket)
|
|||
|
||||
if (sock->ops->closesocket((int) sock->user_data) == 0)
|
||||
{
|
||||
#ifdef SAL_USING_TLS
|
||||
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, closesocket))
|
||||
{
|
||||
if (proto_tls->ops->closesocket(sock->user_data_tls) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
rt_free(sock);
|
||||
socket_table.sockets[socket] = RT_NULL;
|
||||
return 0;
|
||||
|
@ -736,9 +914,9 @@ struct hostent *sal_gethostbyname(const char *name)
|
|||
|
||||
for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
|
||||
{
|
||||
if (proto_families[i].gethostbyname)
|
||||
if (proto_families[i].ops && proto_families[i].ops->gethostbyname)
|
||||
{
|
||||
hst = proto_families[i].gethostbyname(name);
|
||||
hst = proto_families[i].ops->gethostbyname(name);
|
||||
if (hst != RT_NULL)
|
||||
{
|
||||
return hst;
|
||||
|
@ -756,9 +934,9 @@ int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
|
|||
|
||||
for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
|
||||
{
|
||||
if (proto_families[i].gethostbyname_r)
|
||||
if (proto_families[i].ops && proto_families[i].ops->gethostbyname_r)
|
||||
{
|
||||
res = proto_families[i].gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
|
||||
res = proto_families[i].ops->gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
|
||||
if (res == 0)
|
||||
{
|
||||
return res;
|
||||
|
@ -769,38 +947,38 @@ int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
|
|||
return -1;
|
||||
}
|
||||
|
||||
int sal_getaddrinfo(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
|
||||
{
|
||||
if (proto_families[i].ops && proto_families[i].ops->getaddrinfo)
|
||||
{
|
||||
ret = proto_families[i].ops->getaddrinfo(nodename, servname, hints, res);
|
||||
if (ret == 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void sal_freeaddrinfo(struct addrinfo *ai)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
|
||||
{
|
||||
if (proto_families[i].freeaddrinfo)
|
||||
if (proto_families[i].ops && proto_families[i].ops->freeaddrinfo)
|
||||
{
|
||||
proto_families[i].freeaddrinfo(ai);
|
||||
proto_families[i].ops->freeaddrinfo(ai);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sal_getaddrinfo(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
|
||||
{
|
||||
if (proto_families[i].getaddrinfo)
|
||||
{
|
||||
ret = proto_families[i].getaddrinfo(nodename, servname, hints, res);
|
||||
if (ret == 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue