Skip to content

Commit

Permalink
dlt_user_shared: Add timeout to writev (#385)
Browse files Browse the repository at this point in the history
This timeout is necessary to prevent
blocking writev indefinitely.
Without the timeout dlt-daemon, may block
indefinitely when an app id is re-used
very frequently.
In that case dlt-daemon won't accept anymore
new connections and further communication
in any way is not possible anymore.

Signed-off-by: Alexander Mohr <[email protected]>
  • Loading branch information
alexmohr authored May 17, 2023
1 parent cfc2c86 commit 6005b92
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ option(WITH_DLT_DAEMON_VSOCK_IPC "Set to ON to enable VSOCK support in daemon"
option(WITH_DLT_LIB_VSOCK_IPC "Set to ON to enable VSOCK support in library (DLT_IPC is not used in library)" OFF)

set(DLT_VSOCK_PORT "13490" CACHE STRING "VSOCK port number for logging traffic.")
set(DLT_WRITEV_TIMEOUT_SEC "1" CACHE STRING "Set sec timeout for writev to prevent blocking indefinitely")
set(DLT_WRITEV_TIMEOUT_USEC "0" CACHE STRING "Set usec timeout for writev to prevent blocking indefinitely")

# RPM settings
set(GENIVI_RPM_RELEASE "1") # ${DLT_REVISION}")
Expand Down Expand Up @@ -135,6 +137,8 @@ include_directories(
)

add_definitions(-D_GNU_SOURCE)
add_definitions(-DDLT_WRITEV_TIMEOUT_SEC=${DLT_WRITEV_TIMEOUT_SEC})
add_definitions(-DDLT_WRITEV_TIMEOUT_USEC=${DLT_WRITEV_TIMEOUT_USEC})

if(NOT DLT_IPC STREQUAL "UNIX_SOCKET" AND NOT DLT_IPC STREQUAL "FIFO")
message(FATAL_ERROR "${DLT_IPC} is not a valid value for DLT_IPC")
Expand Down
2 changes: 1 addition & 1 deletion src/daemon/dlt_daemon_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1622,7 +1622,7 @@ void dlt_daemon_control_callsw_cinjection(int sock,

/* write to FIFO */
DltReturnValue ret =
dlt_user_log_out3(context->user_handle, &(userheader), sizeof(DltUserHeader),
dlt_user_log_out3_with_timeout(context->user_handle, &(userheader), sizeof(DltUserHeader),
&(usercontext), sizeof(DltUserControlMsgInjection),
userbuffer, (size_t) data_length_inject);

Expand Down
4 changes: 2 additions & 2 deletions src/daemon/dlt_daemon_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1380,7 +1380,7 @@ int dlt_daemon_user_send_log_level(DltDaemon *daemon, DltDaemonContext *context,

/* log to FIFO */
errno = 0;
ret = dlt_user_log_out2(context->user_handle,
ret = dlt_user_log_out2_with_timeout(context->user_handle,
&(userheader), sizeof(DltUserHeader),
&(usercontext), sizeof(DltUserControlMsgLogLevel));

Expand Down Expand Up @@ -1416,7 +1416,7 @@ int dlt_daemon_user_send_log_state(DltDaemon *daemon, DltDaemonApplication *app,
logstate.log_state = daemon->connectionState;

/* log to FIFO */
ret = dlt_user_log_out2(app->user_handle,
ret = dlt_user_log_out2_with_timeout(app->user_handle,
&(userheader), sizeof(DltUserHeader),
&(logstate), sizeof(DltUserControlMsgLogState));

Expand Down
47 changes: 46 additions & 1 deletion src/shared/dlt_user_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
#include <errno.h>

#include <sys/uio.h> /* writev() */
#include <sys/time.h> /* timeval */

#include "dlt_user_shared.h"
#include "dlt_user_shared_cfg.h"
Expand Down Expand Up @@ -125,6 +126,28 @@ DltReturnValue dlt_user_log_out2(int handle, void *ptr1, size_t len1, void *ptr2
return DLT_RETURN_OK;
}

DltReturnValue dlt_user_log_out2_with_timeout(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2)
{
if (handle < 0)
/* Invalid handle */
return DLT_RETURN_ERROR;

fd_set fds;
FD_ZERO(&fds);
FD_SET(handle, &fds);

struct timeval tv = { DLT_WRITEV_TIMEOUT_SEC, DLT_WRITEV_TIMEOUT_USEC };
if (select(handle+1, NULL, &fds, NULL, &tv) < 0) {
return DLT_RETURN_ERROR;
}

if (FD_ISSET(handle, &fds)) {
return dlt_user_log_out2(handle, ptr1, len1, ptr2, len2);
} else {
return DLT_RETURN_ERROR;
}
}

DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3)
{
struct iovec iov[3];
Expand Down Expand Up @@ -175,4 +198,26 @@ DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void *ptr2
}

return DLT_RETURN_OK;
}
}

DltReturnValue dlt_user_log_out3_with_timeout(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3)
{
if (handle < 0)
/* Invalid handle */
return DLT_RETURN_ERROR;

fd_set fds;
FD_ZERO(&fds);
FD_SET(handle, &fds);

struct timeval tv = { DLT_WRITEV_TIMEOUT_SEC, DLT_WRITEV_TIMEOUT_USEC };
if (select(handle+1, NULL, &fds, NULL, &tv) < 0) {
return DLT_RETURN_ERROR;
}

if (FD_ISSET(handle, &fds)) {
return dlt_user_log_out3(handle, ptr1, len1, ptr2, len2, ptr3, len3);
} else {
return DLT_RETURN_ERROR;
}
}
25 changes: 25 additions & 0 deletions src/shared/dlt_user_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,17 @@ int dlt_user_check_userheader(DltUserHeader *userheader);
*/
DltReturnValue dlt_user_log_out2(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2);

/**
* Atomic write to file descriptor, using vector of 2 elements with a timeout of 1s
* @param handle file descriptor
* @param ptr1 generic pointer to first segment of data to be written
* @param len1 length of first segment of data to be written
* @param ptr2 generic pointer to second segment of data to be written
* @param len2 length of second segment of data to be written
* @return Value from DltReturnValue enum
*/
DltReturnValue dlt_user_log_out2_with_timeout(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2);

/**
* Atomic write to file descriptor, using vector of 3 elements
* @param handle file descriptor
Expand All @@ -224,4 +235,18 @@ DltReturnValue dlt_user_log_out2(int handle, void *ptr1, size_t len1, void *ptr2
*/
DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3);

/**
* Atomic write to file descriptor, using vector of 3 elements with a timeout of 1s
* @param handle file descriptor
* @param ptr1 generic pointer to first segment of data to be written
* @param len1 length of first segment of data to be written
* @param ptr2 generic pointer to second segment of data to be written
* @param len2 length of second segment of data to be written
* @param ptr3 generic pointer to third segment of data to be written
* @param len3 length of third segment of data to be written
* @return Value from DltReturnValue enum
*/
DltReturnValue dlt_user_log_out3_with_timeout(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3);


#endif /* DLT_USER_SHARED_H */

0 comments on commit 6005b92

Please sign in to comment.