diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2024-08-08 14:34:10 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2024-08-08 14:34:10 -0300 |
| commit | 56f96f0bdc6187ce19064d311c000656ae68008b (patch) | |
| tree | 104a7843861befbd4da34a66f03b85d7b9ea0df9 /libfdcore/p_ce.c | |
| parent | 3e8d3ed13f58af810934de696c34bf5bf16ddcc6 (diff) | |
New upstream version 1.5.0upstream
Diffstat (limited to 'libfdcore/p_ce.c')
| -rw-r--r-- | libfdcore/p_ce.c | 44 |
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; |
