3737//#include "rlm_radius.h"
3838#include "track.h"
3939
40+ extern int fr_schedule_worker_id (void );
41+
4042/*
4143 * Macro to simplify checking packets before calling decode(), so that
4244 * it gets a known valid length and no longer calls fr_radius_ok() itself.
@@ -49,14 +51,13 @@ typedef struct {
4951 rlm_radius_t const * inst ; //!< our instance
5052 fr_event_list_t * el ; //!< Event list.
5153 trunk_t * trunk ; //!< trunk handler
52- fr_bio_fd_config_t * fd_config ; //!< for threads or sockets
54+ fr_bio_fd_config_t fd_config ; //!< for threads or sockets
5355 fr_bio_fd_info_t const * fd_info ; //!< status of the FD.
5456 fr_radius_ctx_t radius_ctx ;
5557} bio_handle_ctx_t ;
5658
5759typedef struct {
58- bio_handle_ctx_t ctx ; //!< for copying to bio_handle_t
59-
60+ bio_handle_ctx_t ctx ; //!< common struct for home servers and BIO handles
6061
6162 struct {
6263 fr_bio_t * fd ; //!< writing
@@ -71,7 +72,7 @@ typedef struct bio_request_s bio_request_t;
7172 *
7273 */
7374typedef struct {
74- bio_handle_ctx_t ctx ; //! from thread or home server
75+ bio_handle_ctx_t ctx ; //!< common struct for home servers and BIO handles
7576
7677 int fd ; //!< File descriptor.
7778
@@ -140,8 +141,6 @@ struct bio_request_s {
140141typedef struct {
141142 bio_handle_ctx_t ctx ; //!< for copying to bio_handle_t
142143
143- fr_bio_fd_config_t fd_config ; //!< fil descriptor configuration
144-
145144 fr_rb_expire_node_t expire ;
146145} home_server_t ;
147146
@@ -747,7 +746,14 @@ static connection_state_t conn_init(void **h_out, connection_t *conn, void *uctx
747746
748747 MEM (h -> tt = radius_track_alloc (h ));
749748
750- h -> bio .fd = fr_bio_fd_alloc (h , h -> ctx .fd_config , 0 );
749+ /*
750+ * Limit the source port to the given range.
751+ */
752+ if (h -> ctx .inst -> src_port_start ) {
753+ DEBUG ("WARNING - src_port_start and src_port_end not currently supported. A random source port will be chosen" );
754+ }
755+
756+ h -> bio .fd = fr_bio_fd_alloc (h , & h -> ctx .fd_config , 0 );
751757 if (!h -> bio .fd ) {
752758 PERROR ("%s - failed opening socket" , h -> ctx .module_name );
753759 fail :
@@ -774,7 +780,7 @@ static connection_state_t conn_init(void **h_out, connection_t *conn, void *uctx
774780 * way we don't need a memory BIO for UDP sockets, but we can still add a verification layer for
775781 * UDP sockets?
776782 */
777- if (h -> ctx .fd_config -> socket_type == SOCK_STREAM ) {
783+ if (h -> ctx .fd_config . socket_type == SOCK_STREAM ) {
778784 h -> bio .mem = fr_bio_mem_alloc (h , 8192 , 0 , h -> bio .fd );
779785 if (!h -> bio .mem ) {
780786 PERROR ("%s - Failed allocating memory buffer - " , h -> ctx .module_name );
@@ -1411,7 +1417,7 @@ static void mod_dup(request_t *request, bio_request_t *u)
14111417
14121418 h = talloc_get_type_abort (u -> treq -> tconn -> conn -> h , bio_handle_t );
14131419
1414- if (h -> ctx .fd_config -> socket_type != SOCK_DGRAM ) {
1420+ if (h -> ctx .fd_config . socket_type != SOCK_DGRAM ) {
14151421 RDEBUG ("Using stream sockets - suppressing retransmission" );
14161422 return ;
14171423 }
@@ -1735,7 +1741,7 @@ static void mod_write(request_t *request, trunk_request_t *treq, bio_handle_t *h
17351741 /*
17361742 * We don't retransmit over TCP.
17371743 */
1738- if (h -> ctx .fd_config -> socket_type != SOCK_DGRAM ) return ;
1744+ if (h -> ctx .fd_config . socket_type != SOCK_DGRAM ) return ;
17391745
17401746 /*
17411747 * If we only send one datagram packet, then don't bother saving it.
@@ -2427,7 +2433,6 @@ static const trunk_io_funcs_t io_funcs = {
24272433 .request_cancel = request_cancel ,
24282434};
24292435
2430-
24312436/** Instantiate thread data for the submodule.
24322437 *
24332438 */
@@ -2438,7 +2443,7 @@ static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
24382443
24392444 thread -> ctx .el = mctx -> el ;
24402445 thread -> ctx .inst = inst ;
2441- thread -> ctx .fd_config = & inst -> fd_config ;
2446+ thread -> ctx .fd_config = inst -> fd_config ;
24422447 thread -> ctx .radius_ctx = inst -> common_ctx ;
24432448
24442449 if ((inst -> mode != RLM_RADIUS_MODE_UNCONNECTED_REPLICATE ) &&
@@ -2449,10 +2454,20 @@ static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
24492454 return 0 ;
24502455 }
24512456
2457+ /*
2458+ * If we have a port range, allocate the source IP based
2459+ * on the range start, plus the thread ID. This means
2460+ * that we can avoid "hunt and peck" attempts to open up
2461+ * the source port.
2462+ */
2463+ if (thread -> ctx .inst -> src_port_start ) {
2464+ thread -> ctx .fd_config .src_port = thread -> ctx .inst -> src_port_start + fr_schedule_worker_id ();
2465+ }
2466+
24522467 /*
24532468 * Allocate the unconnected replication socket.
24542469 */
2455- thread -> bio .fd = fr_bio_fd_alloc (thread , & thread -> ctx .inst -> fd_config , 0 );
2470+ thread -> bio .fd = fr_bio_fd_alloc (thread , & thread -> ctx .fd_config , 0 );
24562471 if (!thread -> bio .fd ) {
24572472 PERROR ("%s - failed opening socket" , inst -> name );
24582473 return CONNECTION_STATE_FAILED ;
@@ -2597,10 +2612,10 @@ static int8_t home_server_cmp(void const *one, void const *two)
25972612 home_server_t const * b = two ;
25982613 int8_t rcode ;
25992614
2600- rcode = fr_ipaddr_cmp (& a -> fd_config .dst_ipaddr , & b -> fd_config .dst_ipaddr );
2615+ rcode = fr_ipaddr_cmp (& a -> ctx . fd_config .dst_ipaddr , & b -> ctx . fd_config .dst_ipaddr );
26012616 if (rcode != 0 ) return rcode ;
26022617
2603- return CMP (a -> fd_config .dst_port , b -> fd_config .dst_port );
2618+ return CMP (a -> ctx . fd_config .dst_port , b -> ctx . fd_config .dst_port );
26042619}
26052620
26062621static xlat_action_t xlat_sendto_resume (TALLOC_CTX * ctx , fr_dcursor_t * out ,
@@ -2665,9 +2680,11 @@ static xlat_action_t xlat_radius_client(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcurso
26652680 }
26662681
26672682 home = fr_rb_find (& thread -> bio .expires .tree , & (home_server_t ) {
2668- .fd_config = (fr_bio_fd_config_t ) {
2669- .dst_ipaddr = ipaddr -> vb_ip ,
2670- .dst_port = port -> vb_uint16 ,
2683+ .ctx = {
2684+ .fd_config = (fr_bio_fd_config_t ) {
2685+ .dst_ipaddr = ipaddr -> vb_ip ,
2686+ .dst_port = port -> vb_uint16 ,
2687+ },
26712688 },
26722689 });
26732690 if (!home ) {
@@ -2681,12 +2698,14 @@ static xlat_action_t xlat_radius_client(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcurso
26812698 },
26822699 };
26832700
2684- home -> fd_config = inst -> fd_config ;
2685- home -> ctx .fd_config = & home -> fd_config ;
2686-
2687- home -> fd_config .type = FR_BIO_FD_CONNECTED ;
2688- home -> fd_config .dst_ipaddr = ipaddr -> vb_ip ;
2689- home -> fd_config .dst_port = port -> vb_uint32 ;
2701+ /*
2702+ * Copy the home server configuration from the root configuration. Then update it with
2703+ * the needs of the home server.
2704+ */
2705+ home -> ctx .fd_config = inst -> fd_config ;
2706+ home -> ctx .fd_config .type = FR_BIO_FD_CONNECTED ;
2707+ home -> ctx .fd_config .dst_ipaddr = ipaddr -> vb_ip ;
2708+ home -> ctx .fd_config .dst_port = port -> vb_uint32 ;
26902709
26912710 home -> ctx .radius_ctx = (fr_radius_ctx_t ) {
26922711 .secret = talloc_strdup (home , secret -> vb_strvalue ),
0 commit comments