Fragmented data passed to sendmsg() should be sent as a single datagram in case of datagram sockets (i.e. DTLS connection). Right now that is not happening now, as each fragment is sent separately, which works fine only for stream sockets. There is no mbedTLS API for 'gather' write at this moment. This means that implementing sendmsg() would require allocating contiguous memory area at Zephyr TLS socket level and copying all data fragments before passing to mbedTLS library. While this might be a good option for future, let's just check if data passed to sendmsg() API consists of a single memory region and can be sent using single send request. Return EMSGSIZE error if there are more then one data fragments. Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
80 lines
2.5 KiB
C
80 lines
2.5 KiB
C
/*
|
|
* Copyright (c) 2017 Linaro Limited
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef _SOCKETS_INTERNAL_H_
|
|
#define _SOCKETS_INTERNAL_H_
|
|
|
|
#include <zephyr/sys/fdtable.h>
|
|
|
|
#define SOCK_EOF 1
|
|
#define SOCK_NONBLOCK 2
|
|
#define SOCK_ERROR 4
|
|
|
|
int zsock_close_ctx(struct net_context *ctx);
|
|
int zsock_poll_internal(struct zsock_pollfd *fds, int nfds, k_timeout_t timeout);
|
|
|
|
int zsock_wait_data(struct net_context *ctx, k_timeout_t *timeout);
|
|
|
|
static inline void sock_set_flag(struct net_context *ctx, uintptr_t mask,
|
|
uintptr_t flag)
|
|
{
|
|
uintptr_t val = POINTER_TO_UINT(ctx->socket_data);
|
|
|
|
val = (val & ~mask) | flag;
|
|
(ctx)->socket_data = UINT_TO_POINTER(val);
|
|
}
|
|
|
|
static inline uintptr_t sock_get_flag(struct net_context *ctx, uintptr_t mask)
|
|
{
|
|
return POINTER_TO_UINT(ctx->socket_data) & mask;
|
|
}
|
|
|
|
void net_socket_update_tc_rx_time(struct net_pkt *pkt, uint32_t end_tick);
|
|
|
|
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
|
|
bool net_socket_is_tls(void *obj);
|
|
#else
|
|
static inline bool net_socket_is_tls(void *obj)
|
|
{
|
|
ARG_UNUSED(obj);
|
|
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
#define sock_is_eof(ctx) sock_get_flag(ctx, SOCK_EOF)
|
|
#define sock_set_eof(ctx) sock_set_flag(ctx, SOCK_EOF, SOCK_EOF)
|
|
#define sock_is_nonblock(ctx) sock_get_flag(ctx, SOCK_NONBLOCK)
|
|
#define sock_is_error(ctx) sock_get_flag(ctx, SOCK_ERROR)
|
|
#define sock_set_error(ctx) sock_set_flag(ctx, SOCK_ERROR, SOCK_ERROR)
|
|
|
|
struct socket_op_vtable {
|
|
struct fd_op_vtable fd_vtable;
|
|
int (*shutdown)(void *obj, int how);
|
|
int (*bind)(void *obj, const struct sockaddr *addr, socklen_t addrlen);
|
|
int (*connect)(void *obj, const struct sockaddr *addr,
|
|
socklen_t addrlen);
|
|
int (*listen)(void *obj, int backlog);
|
|
int (*accept)(void *obj, struct sockaddr *addr, socklen_t *addrlen);
|
|
ssize_t (*sendto)(void *obj, const void *buf, size_t len, int flags,
|
|
const struct sockaddr *dest_addr, socklen_t addrlen);
|
|
ssize_t (*recvfrom)(void *obj, void *buf, size_t max_len, int flags,
|
|
struct sockaddr *src_addr, socklen_t *addrlen);
|
|
int (*getsockopt)(void *obj, int level, int optname,
|
|
void *optval, socklen_t *optlen);
|
|
int (*setsockopt)(void *obj, int level, int optname,
|
|
const void *optval, socklen_t optlen);
|
|
ssize_t (*sendmsg)(void *obj, const struct msghdr *msg, int flags);
|
|
int (*getpeername)(void *obj, struct sockaddr *addr,
|
|
socklen_t *addrlen);
|
|
int (*getsockname)(void *obj, struct sockaddr *addr,
|
|
socklen_t *addrlen);
|
|
};
|
|
|
|
size_t msghdr_non_empty_iov_count(const struct msghdr *msg);
|
|
|
|
#endif /* _SOCKETS_INTERNAL_H_ */
|