1 /*
2  * The Spread Toolkit.
3  *
4  * The contents of this file are subject to the Spread Open-Source
5  * License, Version 1.0 (the ``License''); you may not use
6  * this file except in compliance with the License.  You may obtain a
7  * copy of the License at:
8  *
9  * http://www.spread.org/license/
10  *
11  * or in the file ``license.txt'' found in this distribution.
12  *
13  * Software distributed under the License is distributed on an AS IS basis,
14  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15  * for the specific language governing rights and limitations under the
16  * License.
17  *
18  * The Creators of Spread are:
19  *  Yair Amir, Michal Miskin-Amir, Jonathan Stanton.
20  *
21  *  Copyright (C) 1993-2004 Spread Concepts LLC <spread@spreadconcepts.com>
22  *
23  *  All Rights Reserved.
24  *
25  * Major Contributor(s):
26  * ---------------
27  *    Cristina Nita-Rotaru crisn@cs.purdue.edu - group communication security.
28  *    Theo Schlossnagle    jesus@omniti.com - Perl, skiplists, autoconf.
29  *    Dan Schoenblum       dansch@cnds.jhu.edu - Java interface.
30  *    John Schultz         jschultz@cnds.jhu.edu - contribution to process group membership.
31  *
32  */
33 
34 
35 #include "flow_control.h"
36 #include "configuration.h"
37 #include "membership.h"
38 #include "prot_body.h"
39 #include "status.h"
40 #include "alarm.h"
41 
42 static	int16	Window;
43 static	int16	Personal_window;
44 static	configuration	Cn;
45 
FC_init()46 void	FC_init( )
47 {
48 	Window = 60;
49 	Personal_window = 15;
50 
51 	Cn = Conf();
52 
53 	GlobalStatus.window = Window;
54 	GlobalStatus.personal_window = Personal_window;
55 }
56 
FC_new_configuration()57 void	FC_new_configuration( )
58 {
59 	Last_num_retrans = 0;
60 	Last_num_sent    = 0;
61 }
62 
FC_allowed(int flow_control,int num_retrans)63 int	FC_allowed( int flow_control, int num_retrans )
64 {
65 	int	allowed;
66 
67 	if( Memb_state() == EVS ) return( 0 );
68 	if( Highest_seq > (Aru + MAX_SEQ_GAP) ) return( 0 );
69 	allowed = Window + Personal_window - flow_control;
70 	if (allowed < 0) allowed = 0;
71 	if (allowed > Window) allowed = Window;
72 	if (allowed > Personal_window) allowed = Personal_window;
73 
74 	return(allowed);
75 }
76 
FC_handle_message(sys_scatter * scat)77 void	FC_handle_message( sys_scatter *scat )
78 {
79 
80 	int16		*cur_fc_buf;
81 	packet_header	*pack_ptr;
82 	proc		dummy_proc;
83 	int		my_index;
84 	int16		temp_window,temp_personal_window;
85 
86 	pack_ptr = (packet_header *)scat->elements[0].buf;
87         if ( ! Conf_get_dangerous_monitor_state() ) {
88                 Alarm( FLOW_CONTROL, "FC_handle_message: Request to change flow control from (%d.%d.%d.%d) denied. Monitor in safe mode\n", IP1(pack_ptr->proc_id), IP2(pack_ptr->proc_id), IP3(pack_ptr->proc_id), IP4(pack_ptr->proc_id) );
89                 return;
90         }
91 
92 	if( ! ( pack_ptr->memb_id.proc_id == 15051963 && Conf_id_in_conf( &Cn, pack_ptr->proc_id ) != -1 ) )
93 	{
94 		Alarm( FLOW_CONTROL,
95 			"FC_handle_message: Illegal monitor request\n");
96 		return;
97 	}
98 	cur_fc_buf = (int16 *)scat->elements[1].buf;
99 
100 	my_index = Conf_proc_by_id( Conf_my().id, &dummy_proc );
101 
102 	if( Same_endian( pack_ptr->type ) ) {
103 		temp_window = cur_fc_buf[Conf_num_procs( &Cn )];
104 		temp_personal_window = cur_fc_buf[my_index];
105 	}else{
106 		temp_window = Flip_int16( cur_fc_buf[Conf_num_procs( &Cn )] );
107 		temp_personal_window = Flip_int16( cur_fc_buf[my_index] );
108 	}
109 	if( temp_window != -1 ) Window = temp_window;
110 	if( temp_personal_window != -1 ) Personal_window = temp_personal_window;
111 	GlobalStatus.window = Window;
112 	GlobalStatus.personal_window = Personal_window;
113 	Alarm( FLOW_CONTROL,
114 		"FC_handle_message: Got monitor mess, Window %d Personal %d\n",
115 			Window, Personal_window );
116 }
117