Skip to content

Commit

Permalink
Merge branch 'hotfix/44-proper-cla-rate-limiting'
Browse files Browse the repository at this point in the history
See !148
  • Loading branch information
felix-walter committed Dec 20, 2023
2 parents bf97cb0 + c543afd commit 6d6eac0
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 94 deletions.
42 changes: 5 additions & 37 deletions components/cla/posix/cla_bibe.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ struct bibe_contact_parameters {
const char *partner_eid;

bool in_contact;
int connect_attempt;

int socket;
};
Expand Down Expand Up @@ -111,7 +110,6 @@ static void bibe_link_management_task(void *p)
if (param->socket > 0) {
// NOTE the following function releases and re-locks sem
handle_established_connection(param);
param->connect_attempt = 0;
param->socket = -1;
} else {
if (param->cla_sock_addr[0] == '\0') {
Expand All @@ -121,31 +119,17 @@ static void bibe_link_management_task(void *p)
ASSERT(param->socket < 0);
hal_semaphore_release(param->param_semphr);

if (cla_tcp_rate_limit_connection_attempts(
&param->config->base))
break;
const int socket = cla_tcp_connect_to_cla_addr(
param->cla_sock_addr, // only used by us
NULL
);

hal_semaphore_take_blocking(param->param_semphr);
if (socket < 0) {
if (++param->connect_attempt >
CLA_TCP_MAX_RETRY_ATTEMPTS) {
LOG_WARN("BIBE: Final retry failed.");
break;
}
LOGF_INFO(
"BIBE: Delayed retry %d of %d in %d ms",
param->connect_attempt,
CLA_TCP_MAX_RETRY_ATTEMPTS,
CLA_TCP_RETRY_INTERVAL_MS
);
hal_semaphore_release(param->param_semphr);
hal_task_delay(CLA_TCP_RETRY_INTERVAL_MS);
hal_semaphore_take_blocking(
param->param_semphr
);
if (socket < 0)
continue;
}
param->socket = socket;

const struct aap_message register_bibe = {
Expand All @@ -171,22 +155,7 @@ static void bibe_link_management_task(void *p)
if (wsp.errno_) {
LOG_ERRNO("BIBE", "send()", wsp.errno_);
close(param->socket);
if (++param->connect_attempt >
CLA_TCP_MAX_RETRY_ATTEMPTS) {
LOG_WARN("BIBE: Final retry failed.");
break;
}
LOGF_INFO(
"BIBE: Delayed retry %d of %d in %d ms",
param->connect_attempt,
CLA_TCP_MAX_RETRY_ATTEMPTS,
CLA_TCP_RETRY_INTERVAL_MS
);
hal_semaphore_release(param->param_semphr);
hal_task_delay(CLA_TCP_RETRY_INTERVAL_MS);
hal_semaphore_take_blocking(
param->param_semphr
);
param->socket = -1;
continue;
}
LOGF_INFO(
Expand Down Expand Up @@ -236,7 +205,6 @@ static void launch_connection_management_task(
}

contact_params->config = bibe_config;
contact_params->connect_attempt = 0;

char *const cla_sock_addr = cla_get_connect_addr(cla_addr, CLA_NAME);

Expand Down
25 changes: 4 additions & 21 deletions components/cla/posix/cla_mtcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ struct mtcp_contact_parameters {

bool is_outgoing;
bool in_contact;
int connect_attempt;

int socket;
};
Expand Down Expand Up @@ -103,7 +102,6 @@ static void mtcp_link_management_task(void *p)
if (param->socket > 0) {
// NOTE the following function releases and re-locks sem
handle_established_connection(param);
param->connect_attempt = 0;
param->socket = -1;
} else {
if (param->cla_sock_addr[0] == '\0') {
Expand All @@ -113,31 +111,17 @@ static void mtcp_link_management_task(void *p)
ASSERT(param->socket < 0);
hal_semaphore_release(param->param_semphr);

if (cla_tcp_rate_limit_connection_attempts(
&param->config->base))
break;
const int socket = cla_tcp_connect_to_cla_addr(
param->cla_sock_addr, // only used by us
NULL
);

hal_semaphore_take_blocking(param->param_semphr);
if (socket < 0) {
if (++param->connect_attempt >
CLA_TCP_MAX_RETRY_ATTEMPTS) {
LOG_WARN("MTCP: Final retry failed.");
break;
}
LOGF_INFO(
"MTCP: Delayed retry %d of %d in %d ms",
param->connect_attempt,
CLA_TCP_MAX_RETRY_ATTEMPTS,
CLA_TCP_RETRY_INTERVAL_MS
);
hal_semaphore_release(param->param_semphr);
hal_task_delay(CLA_TCP_RETRY_INTERVAL_MS);
hal_semaphore_take_blocking(
param->param_semphr
);
if (socket < 0)
continue;
}
param->socket = socket;
LOGF_INFO(
"MTCP: Connected successfully to \"%s\"",
Expand Down Expand Up @@ -184,7 +168,6 @@ static void launch_connection_management_task(
}

contact_params->config = mtcp_config;
contact_params->connect_attempt = 0;

if (sock < 0) {
contact_params->cla_sock_addr = cla_get_connect_addr(
Expand Down
3 changes: 0 additions & 3 deletions components/cla/posix/cla_smtcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ static void smtcp_link_creation_task(void *param)
smtcp_config,
sizeof(struct mtcp_link)
);

// Should never get here.
abort();
}

static enum ud3tn_result smtcp_launch(struct cla_config *const config)
Expand Down
64 changes: 57 additions & 7 deletions components/cla/posix/cla_tcp_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "platform/hal_io.h"
#include "platform/hal_semaphore.h"
#include "platform/hal_task.h"
#include "platform/hal_time.h"

#include "ud3tn/common.h"
#include "ud3tn/result.h"
Expand Down Expand Up @@ -40,6 +41,8 @@ enum ud3tn_result cla_tcp_config_init(
return UD3TN_FAIL;

config->socket = -1;
config->last_connection_attempt_ms = 0;
config->last_connection_attempt_no = 1;

return UD3TN_OK;
}
Expand Down Expand Up @@ -294,14 +297,14 @@ void cla_tcp_single_connect_task(struct cla_tcp_single_config *config,
config->service
);

if (cla_tcp_rate_limit_connection_attempts(&config->base))
break;
if (cla_tcp_connect(&config->base,
config->node, config->service) != UD3TN_OK) {
LOGF_WARN(
"TCP: CLA \"%s\": Connection failed, will retry in %d ms as long as a contact is ongoing.",
config->base.base.vtable->cla_name_get(),
CLA_TCP_RETRY_INTERVAL_MS
"TCP: CLA \"%s\": Connection failed, will retry as long as a contact is ongoing.",
config->base.base.vtable->cla_name_get()
);
hal_task_delay(CLA_TCP_RETRY_INTERVAL_MS);
} else {
handle_established_connection(config, NULL,
config->base.socket,
Expand Down Expand Up @@ -359,11 +362,58 @@ void cla_tcp_single_link_creation_task(struct cla_tcp_single_config *config,
config->node,
config->service
);
abort();
return;
} else {
cla_tcp_single_listen_task(config, struct_size);
}
cla_tcp_single_listen_task(config, struct_size);
}

LOGF_ERROR(
"TCP: CLA \"%s\" link task terminated.",
config->base.base.vtable->cla_name_get()
);
if (CLA_TCP_ABORT_ON_LINK_TASK_TERMINATION)
abort();
}

int cla_tcp_rate_limit_connection_attempts(struct cla_tcp_config *config)
{
const uint64_t rt_limit_ms = CLA_TCP_RETRY_INTERVAL_MS;
const int rt_max_attempts = CLA_TCP_MAX_RETRY_ATTEMPTS;
const uint64_t now_ms = hal_time_get_timestamp_ms();

if (config->last_connection_attempt_ms + rt_limit_ms > now_ms) {
if (rt_max_attempts <= 0) {
LOGF_WARN(
"TCP: Last connection attempt was less than %llu ms ago, delaying next attempt.",
rt_limit_ms
);
} else {
if (config->last_connection_attempt_no >=
rt_max_attempts) {
LOGF_WARN(
"TCP: Final retry %d of %d failed.",
config->last_connection_attempt_no,
rt_max_attempts
);
return -1;
}
LOGF_WARN(
"TCP: Last connection attempt %d of %d was less than %llu ms ago, delaying next attempt.",
config->last_connection_attempt_no,
rt_max_attempts,
rt_limit_ms
);
config->last_connection_attempt_no++;
}
hal_task_delay(rt_limit_ms);
config->last_connection_attempt_ms = (
hal_time_get_timestamp_ms()
);
} else {
config->last_connection_attempt_ms = now_ms;
config->last_connection_attempt_no = 1;
}
return 0;
}

struct cla_tx_queue cla_tcp_single_get_tx_queue(
Expand Down
1 change: 1 addition & 0 deletions components/cla/posix/cla_tcp_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "cla/posix/cla_tcp_util.h"

#include "platform/hal_io.h"
#include "platform/posix/socket_util.h"

#include "ud3tn/common.h"

Expand Down
24 changes: 4 additions & 20 deletions components/cla/posix/cla_tcpclv3.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ struct tcpclv3_contact_parameters {
char *eid;
char *cla_addr;

int connect_attempt;

int socket;

enum TCPCLV3_STATE state;
Expand Down Expand Up @@ -288,30 +286,18 @@ static void tcpclv3_link_management_task(void *p)

hal_semaphore_release(param->param_semphr);

if (cla_tcp_rate_limit_connection_attempts(
&param->config->base))
break;
const int socket = cla_tcp_connect_to_cla_addr(
param->cla_addr,
"4556"
);

hal_semaphore_take_blocking(param->param_semphr);

if (socket < 0) {
if (++param->connect_attempt >
CLA_TCP_MAX_RETRY_ATTEMPTS) {
LOG_WARN("TCPCLv3: Final retry failed.");
break;
}
LOGF_INFO("TCPCLv3: Delayed retry %d of %d in %d ms",
param->connect_attempt,
CLA_TCP_MAX_RETRY_ATTEMPTS,
CLA_TCP_RETRY_INTERVAL_MS);
hal_semaphore_release(param->param_semphr);
hal_task_delay(CLA_TCP_RETRY_INTERVAL_MS);
hal_semaphore_take_blocking(
param->param_semphr
);
if (socket < 0)
continue;
}
LOGF_INFO("TCPCLv3: Connected successfully to \"%s\"",
param->cla_addr);
param->socket = socket;
Expand All @@ -329,7 +315,6 @@ static void tcpclv3_link_management_task(void *p)
break;
}
param->state = TCPCLV3_CONNECTING;
param->connect_attempt = 0;
} else {
// TCPCLV3_INACTIVE, TCPCLV3_ESTABLISHED
// should never happen as we are not created or wait
Expand Down Expand Up @@ -386,7 +371,6 @@ static void launch_connection_management_task(
}

contact_params->config = tcpclv3_config;
contact_params->connect_attempt = 0;

if (sock < 0) {
ASSERT(eid && cla_addr);
Expand Down
3 changes: 0 additions & 3 deletions components/cla/posix/cla_tcpspp.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,6 @@ static void tcpspp_link_creation_task(void *param)
&tcpspp_config->base,
sizeof(struct cla_tcp_link)
);

// Should never get here.
abort();
}

static enum ud3tn_result tcpspp_launch(struct cla_config *const config)
Expand Down
6 changes: 5 additions & 1 deletion components/platform/posix/socket_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,18 @@ int poll_recv_timeout(const int socket_fd, const int timeout)
LOG_ERRNO("Socket Util", "poll()", err);
return -1;
}
if ((pollfd[0].revents & POLLERR)) {
if (pollfd[0].revents & POLLERR) {
LOG_WARN("Socket Util: Socket error (e.g. TCP RST) detected.");
return -1;
}
if (pollfd[0].revents & POLLHUP) {
LOG_INFO("Socket Util: The peer closed the connection.");
return -1;
}
if (pollfd[0].revents & POLLNVAL) {
LOG_INFO("Socket Util: Connection was not open.");
return -1;
}
if (pollfd[0].revents & POLLIN)
return 1;
return 0;
Expand Down
6 changes: 5 additions & 1 deletion config.mk.example
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,16 @@
# Setting this can help when broken records may be part of the incoming data.
#CPPFLAGS += -DCLA_RX_READ_TIMEOUT=0

# Whether to abort() uD3TN in case a TCP CLA terminates finally.
#CPPFLAGS += -DCLA_TCP_ABORT_ON_LINK_TASK_TERMINATION=0

# Whether to set SO_REUSEPORT on listening TCP sockets. Note that this may have
# security implications and it is Linux-/BSD-specific.
#CPPFLAGS += -DCLA_TCP_ALLOW_REUSE_PORT=0

# Maximum number of attempts to create a connection on contact start.
#CPPFLAGS += -DCLA_TCP_MAX_RETRY_ATTEMPTS=10
# The default value of 0 means infinite.
#CPPFLAGS += -DCLA_TCP_MAX_RETRY_ATTEMPTS=0

# The length of the listen backlog for multi-connection TCP CLAs.
#CPPFLAGS += -DCLA_TCP_MULTI_BACKLOG=64
Expand Down
Loading

0 comments on commit 6d6eac0

Please sign in to comment.