summaryrefslogtreecommitdiff
path: root/libfdcore/p_ce.c
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2024-08-08 14:34:10 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2024-08-08 14:34:10 -0300
commit56f96f0bdc6187ce19064d311c000656ae68008b (patch)
tree104a7843861befbd4da34a66f03b85d7b9ea0df9 /libfdcore/p_ce.c
parent3e8d3ed13f58af810934de696c34bf5bf16ddcc6 (diff)
New upstream version 1.5.0upstream
Diffstat (limited to 'libfdcore/p_ce.c')
-rw-r--r--libfdcore/p_ce.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/libfdcore/p_ce.c b/libfdcore/p_ce.c
index 1b4cd13..3f3af76 100644
--- a/libfdcore/p_ce.c
+++ b/libfdcore/p_ce.c
@@ -2,7 +2,7 @@
* Software License Agreement (BSD License) *
* Author: Sebastien Decugis <sdecugis@freediameter.net> *
* *
-* Copyright (c) 2015, WIDE Project and NICT *
+* Copyright (c) 2020, WIDE Project and NICT *
* All rights reserved. *
* *
* Redistribution and use of this software in source and binary forms, with or without modification, are *
@@ -704,7 +704,7 @@ int fd_p_ce_handle_newcnx(struct fd_peer * peer, struct cnxctx * initiator)
int fd_p_ce_msgrcv(struct msg ** msg, int req, struct fd_peer * peer)
{
uint32_t rc = 0;
- int st;
+ int st = STATE_NEW;
struct fd_pei pei;
TRACE_ENTRY("%p %p", msg, peer);
@@ -833,6 +833,26 @@ cleanup:
return 0;
}
+/* Check if enough processing peers are connected to allow connections by other peers */
+static int sufficient_processing_peers(void) {
+ int processing_peers_count = 0;
+ struct fd_list * li;
+
+ CHECK_FCT( pthread_rwlock_rdlock(&fd_g_activ_peers_rw) );
+ for (li = fd_g_activ_peers.next; li != &fd_g_activ_peers; li = li->next) {
+ struct fd_peer * p = (struct fd_peer *)li->o;
+
+ TRACE_DEBUG(FULL, "comparing '%s' against processing peers pattern", p->p_hdr.info.pi_diamid);
+ if (regexec(&fd_g_config->cnf_processing_peers_pattern_regex, p->p_hdr.info.pi_diamid, 0, NULL, 0) == 0) {
+ processing_peers_count++;
+ }
+ }
+ CHECK_FCT( pthread_rwlock_unlock(&fd_g_activ_peers_rw) );
+
+ TRACE_DEBUG(FULL, "%d processing peers found", processing_peers_count);
+ return (processing_peers_count >= fd_g_config->cnf_processing_peers_minimum);
+}
+
/* Handle the receiver side to go to OPEN or OPEN_NEW state (any election is resolved) */
int fd_p_ce_process_receiver(struct fd_peer * peer)
{
@@ -883,6 +903,26 @@ int fd_p_ce_process_receiver(struct fd_peer * peer)
CHECK_FCT( res );
}
+ /* Check peer type and if enough processing peers are already connected */
+ if (fd_g_config->cnf_processing_peers_minimum > 0) {
+ if (regexec(&fd_g_config->cnf_processing_peers_pattern_regex, peer->p_hdr.info.pi_diamid, 0, NULL, 0) != 0) {
+ /* peer is not a processing peer */
+ if (!sufficient_processing_peers()) {
+ pei.pei_errcode = "DIAMETER_TOO_BUSY";
+ goto error_abort;
+ }
+ }
+ }
+
+ if (peer->p_flags.pf_responder) {
+ int res = fd_peer_validate( peer );
+ if (res < 0) {
+ TRACE_DEBUG(INFO, "Rejected CER from peer '%s', validation failed (returning DIAMETER_UNKNOWN_PEER).", peer->p_hdr.info.pi_diamid);
+ pei.pei_errcode = "DIAMETER_UNKNOWN_PEER";
+ goto error_abort;
+ }
+ CHECK_FCT( res );
+ }
/* Check if we have common applications */
if ( fd_g_config->cnf_flags.no_fwd && (! peer->p_hdr.info.runtime.pir_relay) ) {
int got_common;