[Spread-cvs] commit: r235 - trunk/daemon

jonathan at spread.org jonathan at spread.org
Mon Jun 13 00:41:16 EDT 2005


Author: jonathan
Date: 2005-06-13 00:41:15 -0400 (Mon, 13 Jun 2005)
New Revision: 235

Modified:
   trunk/daemon/Changelog
   trunk/daemon/conf_body.h
   trunk/daemon/config_parse.y
   trunk/daemon/configuration.c
   trunk/daemon/configuration.h
   trunk/daemon/membership.c
   trunk/daemon/net_types.h
   trunk/daemon/network.c
   trunk/daemon/protocol.c
Log:
Initial version of hash config checks. Each spread configuration generates a unique hash. The hash
code is added to messages sent between daemons and daemons will ignore other daemons who have a 
different configuration hash. This prevents daemons from inter-operating with other daemons who
have different spread.conf files. This is not a new restriction as that never worked correctly, but 
now it is enforced. 


Modified: trunk/daemon/Changelog
===================================================================
--- trunk/daemon/Changelog	2005-06-12 23:18:24 UTC (rev 234)
+++ trunk/daemon/Changelog	2005-06-13 04:41:15 UTC (rev 235)
@@ -18,6 +18,25 @@
 	* sp.c (SP_internal_multicast): Check for short writes on network 
 	socket sends and loop to finish full write. Bug reported by Tudor Dumitras.
 
+Sun Mar 20 17:45:49 2005  Jonathan Stanton  <jonathan at cnds.jhu.edu>
+ 
+ 	* spread.c (main): Only print Alarms of SPLOG_INFO or higher priority by default.
+ 
+Sun Mar 20 12:12:53 2005  Jonathan Stanton  <jonathan at cnds.jhu.edu>
+ 
+ 	* conf_body.h, membership.c, configuration.c, protocol.c, config_parse.y, net_types.h:
+ 	Create string representation of spread.conf segment entries and compute
+ 	32 bit hash of string. Hash is stored in Config structure and is checked
+ 	when membership messages or tokens are received. received hash must equal
+ 	local hash.
+ 
+ 	* configuration.c: remove old parser code that was ifdef 0.
+ 	
+ 	* configuration.h, configuration.c: 
+ 	Split Conf_init into Conf_load_conf_file to begin dynamic conf support.
+ 	
+ 	* membership.c: Print formatted IP addresses in Memb_handle_message alarms.
+ 
 Thu Dec 02 23:50:27 2004   Ryan Caudy  <rcaudy at gmail.com>
 
 	* groups.c (G_build_groups_buf): Fix groups-state-exchange 

Modified: trunk/daemon/conf_body.h
===================================================================
--- trunk/daemon/conf_body.h	2005-06-12 23:18:24 UTC (rev 234)
+++ trunk/daemon/conf_body.h	2005-06-13 04:41:15 UTC (rev 235)
@@ -62,6 +62,10 @@
 ext	proc           	Config_procs[MAX_PROCS_RING];
 ext     int       LinkWeights[MAX_SEGMENTS][MAX_SEGMENTS];
 
+#define MAX_CONF_STRING 20000
+ext     char            ConfStringRep[MAX_CONF_STRING];
+ext     int             ConfStringLen;
+
 /* For network protocols used in Spread 4 */
 #define HOP_PROT        1
 #define RING_PROT       2

Modified: trunk/daemon/config_parse.y
===================================================================
--- trunk/daemon/config_parse.y	2005-06-12 23:18:24 UTC (rev 234)
+++ trunk/daemon/config_parse.y	2005-06-13 04:41:15 UTC (rev 235)
@@ -162,8 +162,100 @@
 	}
 	return( -1 );
 }
+/* convert_segment_to_string()
+ * char * segstr : output string
+ * int strsize : length of output string space
+ * segment *seg : input segment structure
+ * int return : length of string written or -1 if error (like string not have room)
+ * 
+ *
+ * The format of the returned string will be as shown below with each segment appended
+ * to the string. Each use of IPB will be replaced with the broadcast IP address, port
+ * with the port. The optional section is a list of interfaces tagged with D or C
+ * and idnetified by ip address. 
+ *
+ * "Segment IP:port host1name host1ip (ALL/ANY/C/D/M IP)+ host2name host2ip (ALL/ANY/C/D/M IP )+ ..."
+ *
+ */
+static  int    convert_segment_to_string(char *segstr, int strsize, segment *seg)
+{
+    int         i,j;
+    size_t      curlen = 0;
+    char        temp_str[200];
 
+    sprintf(temp_str, "Segment %d.%d.%d.%d:%d ", 
+            (seg->bcast_address & 0xff000000)>>24, 
+            (seg->bcast_address & 0xff0000)>>16, 
+            (seg->bcast_address & 0xff00)>>8, 
+            (seg->bcast_address & 0xff), 
+            seg->port );
 
+    strncat( segstr, temp_str, strsize - curlen);
+    curlen += strlen(temp_str);
+
+    for (i = 0; i < seg->num_procs; i++) {
+        sprintf(temp_str, "%s %d.%d.%d.%d ", 
+                seg->procs[i]->name, 
+                (seg->procs[i]->id & 0xff000000)>>24, 
+                (seg->procs[i]->id & 0xff0000)>>16, 
+                (seg->procs[i]->id & 0xff00)>>8, 
+                (seg->procs[i]->id & 0xff) );
+        strncat( segstr, temp_str, strsize - curlen);
+        curlen += strlen(temp_str);
+
+        /* Now add all interfaces */
+        for ( j=0 ; j < seg->procs[i]->num_if; j++) {
+            /* add addional interface specs to string */
+            if ( seg->procs[i]->ifc[j].type & IFTYPE_ANY )
+            {
+                strncat( segstr, "ANY ", strsize - curlen);
+                curlen += 4;
+            }
+            if ( seg->procs[i]->ifc[j].type & IFTYPE_DAEMON )
+            {
+                strncat( segstr, "D ", strsize - curlen);
+                curlen += 2;
+            }
+            if ( seg->procs[i]->ifc[j].type & IFTYPE_CLIENT )
+            {
+                strncat( segstr, "C ", strsize - curlen);
+                curlen += 2;
+            }
+            if ( seg->procs[i]->ifc[j].type & IFTYPE_MONITOR )
+            {
+                strncat( segstr, "M ", strsize - curlen);
+                curlen += 2;
+            }
+            sprintf(temp_str, "%d.%d.%d.%d ", 
+                (seg->procs[i]->ifc[j].ip & 0xff000000)>>24, 
+                (seg->procs[i]->ifc[j].ip & 0xff0000)>>16, 
+                (seg->procs[i]->ifc[j].ip & 0xff00)>>8, 
+                (seg->procs[i]->ifc[j].ip & 0xff) );
+            strncat( segstr, temp_str, strsize - curlen);
+            curlen += strlen(temp_str);
+        }
+    }
+
+    /* terminate each segment by a newline */
+    strncat( segstr, "\n", strsize - curlen);
+    curlen += 1;
+
+    if (curlen > strsize) {
+        /* ran out of space in string -- should never happen. */
+        Alarmp( SPLOG_ERROR, CONF, "The segment string is too long! %d characters attemped is more then %d characters allowed", curlen, strsize);
+        Alarmp( SPLOG_ERROR, CONF, "The error occured on segment %d.%d.%d.%d. Successful string was: %s\n",
+                (seg->bcast_address & 0xff000000)>>24, 
+                (seg->bcast_address & 0xff0000)>>16, 
+                (seg->bcast_address & 0xff00)>>8, 
+                (seg->bcast_address & 0xff), 
+                segstr);
+        return(-1);
+    }
+
+    Alarmp( SPLOG_DEBUG, CONF, "The segment string is %d characters long:\n%s", curlen, segstr);
+    return(curlen);
+}
+
 #define PROC_NAME_CHECK( stoken ) { \
                                             char strbuf[80]; \
                                             int ret; \
@@ -227,6 +319,7 @@
 			  Config.num_segments = segments;
 			  Num_procs = num_procs;
 			  Alarm(CONF, "Finished configuration file.\n");
+                          Alarmp( SPLOG_INFO, CONF, "The full segment string is %d characters long:\n%s", strlen(ConfStringRep), ConfStringRep);
 			}
 
 
@@ -413,6 +506,7 @@
 
 SegmentStruct	:    SEGMENT IPADDR OPENBRACE Segmentparams CLOSEBRACE
                         { int i;
+                          int added_len;
                           SEGMENT_CHECK( segments, inet_ntoa($2.ip.addr) );
 			  Config.segments[segments].num_procs = segment_procs;
 			  Config.segments[segments].port = $2.ip.port;
@@ -433,6 +527,12 @@
 			    alarm_print_proc(&Config_procs[i],
 			    	Config.segments[segments].port);
 			  }
+                          /* generate string representation of segment */
+                          added_len = convert_segment_to_string(&ConfStringRep[ConfStringLen], MAX_CONF_STRING - ConfStringLen, &Config.segments[segments] );
+                          if (added_len == -1 )
+                              yyerror("Failed to update string with segment!\n");
+                          ConfStringLen += added_len;
+
 			  segments++;
 			  segment_procs = 0;
 			}

Modified: trunk/daemon/configuration.c
===================================================================
--- trunk/daemon/configuration.c	2005-06-12 23:18:24 UTC (rev 234)
+++ trunk/daemon/configuration.c	2005-06-13 04:41:15 UTC (rev 235)
@@ -101,26 +101,54 @@
 
 static  int     Link_Protocol;
 
-int		Conf_init( char *file_name, char *my_name )
+/* Hash function for string to 32 bit int */
+static LOC_INLINE int32u conf_hash_string(const void * key, int32u key_len)
 {
+    const char * kit  = (const char*) key;
+    const char * kend = (const char*) key + key_len;
+    int32u    ret  = (int32u) key_len ^ ((int32u) key_len << 8) ^
+        ((int32u) key_len << 16) ^ ((int32u) key_len << 24);
+
+    for (; kit != kend; ++kit) {
+        ret += *kit;
+        ret += (ret << 10);
+        ret ^= (ret >> 6);
+    }
+
+    ret += (ret << 3);
+    ret ^= (ret >> 11);
+    ret += (ret << 15);
+
+    return ret;
+}
+
+
+
+int	Conf_init( char *file_name, char *my_name )
+{
+    int ret;
+
+    ret = Conf_load_conf_file( file_name, my_name);
+
+    return(ret);
+}
+
+
+
+int	Conf_load_conf_file( char *file_name, char *my_name )
+{
         struct hostent  *host_ptr;
 	char	machine_name[256];
 	char	ip[16];
 	int	i,j;
         unsigned int name_len;
         char    configfile_location[MAXPATHLEN];
-#if 0
-        int     s;
-	char	line[132];
-	char	buf[132];
-	int	full;
-	char	optional_id[20];
-	int	iret;
-	char	*ret;
-	int	p;
-	int32	i1,i2,i3,i4;
-#endif
+
 	Num_procs = 0;
+        /* Initialize hash string */
+        ConfStringRep[0] = '\0';
+        ConfStringLen = 0;
+
 	/* init Config, Config_procs from file
 	   init My from host
 	 */
@@ -141,107 +169,7 @@
 			file_name);
 
 	yyparse();
-#if 0
-	do{
-		ret = fgets(line,132,fp);
-		if (ret == NULL) 
-			Alarm( EXIT, "Conf_init: no number of segments \n");
-		full = sscanf( line, "%s", buf );
-	}while( line[0] == '#' || full <= 0 ); 
 
-	sscanf(line,"%d",&Config.num_segments);
-	Alarm( CONF, "Conf_init: %d segments\n", Config.num_segments );
-	for ( s=0; s < Config.num_segments; s++ )
-	{
-		do{
-			ret = fgets(line,132,fp);
-			if (ret == NULL) 
-				Alarm( EXIT, "Conf_init: no segment data line \n");
-			full = sscanf( line, "%s", buf );
-		}while( line[0] == '#' || full <= 0 ); 
-
-		for(i=0; i< 3; i++)
-		{
-			ret = strchr(line, '.' );
-			if ( ret == NULL)
-				Alarm( EXIT, "Conf_init: error in bcast addr\n");
-			*ret = ' ';
-		}
-		iret = sscanf(line,"%d%d%d%d%d%hd",
-			    	&Config.segments[s].num_procs,
-				&i1,&i2,&i3,&i4,
-			    	&Config.segments[s].port);
-		if( iret == 5 ) Config.segments[s].port = 4803;
-		else if( iret < 6 ) 
-			Alarm( EXIT, "Conf_init: not a valid segment line: %s\n",
-					line);
-
-		Alarm( CONF, "Conf_init: segment %d: with %d procs, (%d.%d.%d.%d, %hd)\n",
-			    s, Config.segments[s].num_procs,
-			    i1,i2,i3,i4,
-			    Config.segments[s].port );
-
-		Config.segments[s].bcast_address = 
-			( (i1 << 24 ) | (i2 << 16) | (i3 << 8) | i4 );
-
-		for ( p=0; p < Config.segments[s].num_procs; p++ )
-		{
-		    do{
-			ret = fgets(line,132,fp);
-			if (ret == NULL) 
-				Alarm( EXIT, "Conf_init: no proc line\n");
-			full = sscanf( line, "%s", buf );
-		    }while( line[0] == '#' || full <= 0 ); 
-
-		    /* %19 is MAX_PROC_NAME-1 for the null */
-
-		    iret = sscanf(line,"%19s%s",Config_procs[Num_procs].name,
-					optional_id);
-		    if( iret == 1 )
-		    {
-			host_ptr = gethostbyname(Config_procs[Num_procs].name);
-
-			if ( host_ptr == 0)
-				Alarm( EXIT, "Conf_init: no such host %s\n",
-					Config_procs[Num_procs].name);
-
-        		memcpy(&Config_procs[Num_procs].id, host_ptr->h_addr_list[0], 
-			       sizeof(int32) );
-			Config_procs[Num_procs].id = 
-				htonl( Config_procs[Num_procs].id );
-			i1= ( Config_procs[Num_procs].id & 0xff000000 ) >> 24;
-			i2= ( Config_procs[Num_procs].id & 0x00ff0000 ) >> 16;
-			i3= ( Config_procs[Num_procs].id & 0x0000ff00 ) >>  8;
-			i4= Config_procs[Num_procs].id & 0x000000ff;
-		    }else if( iret == 2 ){
-			for(i=0; i< 3; i++)
-			{
-			    ret = strchr(optional_id, '.' );
-			    if ( ret == NULL)
-			        Alarm( EXIT, 
-	"Conf_init: error in id or not a valid host line: %s\n",line);
-			    *ret = ' ';
-			}
-			sscanf(optional_id,"%d%d%d%d",&i1,&i2,&i3,&i4);
-			Config_procs[Num_procs].id = 
-				( (i1 << 24 ) | (i2 << 16) | (i3 << 8) | i4 );
-		    }else Alarm( EXIT, "Conf_init: not a valid host line: %s\n",
-					line);
-
- 		    Config_procs[Num_procs].port = Config.segments[s].port;
- 		    Config_procs[Num_procs].seg_index = s;
- 		    Config_procs[Num_procs].index_in_seg = p;
-		    Config.segments[s].proc_ids[p] = 
-				Config_procs[Num_procs].id;
-
-		    Alarm( CONF, "Conf_init: \t\t%-20s\t%d.%d.%d.%d\n",
-				Config_procs[Num_procs].name, i1,i2,i3,i4 );
-
-		    Num_procs++;
-		}
-	}
-#endif
-
         fclose(yyin);
 
         /* Test for localhost segemnt defined with other non-localhost segments.
@@ -266,6 +194,13 @@
             }
         }
 
+        /* calculate hash value of configuration. 
+         * This daemon will only work with other daemons who have an identical hash value.
+         */
+        Config.hash_code = conf_hash_string(ConfStringRep, ConfStringLen);
+        Alarmp(SPLOG_DEBUG, CONF, "Hash value for this configuration is: %u\n", Config.hash_code);
+
+        /* Match my IP address to entry in configuration file */
 	if( my_name == NULL ){
 		gethostname(machine_name,sizeof(machine_name)); 
 		host_ptr = gethostbyname(machine_name);

Modified: trunk/daemon/configuration.h
===================================================================
--- trunk/daemon/configuration.h	2005-06-12 23:18:24 UTC (rev 234)
+++ trunk/daemon/configuration.h	2005-06-13 04:41:15 UTC (rev 235)
@@ -74,6 +74,7 @@
 } segment;
 
 typedef struct dummy_configuration{
+        int32u  hash_code;
 	int	num_segments;
 	segment	segments[MAX_SEGMENTS];
 } configuration;
@@ -85,6 +86,7 @@
 } port_reuse;
 
 int		Conf_init( char *file_name, char *my_name );
+int	        Conf_load_conf_file( char *file_name, char *my_name );
 configuration	Conf(void);
 proc		Conf_my(void);
 int		Conf_proc_by_id( int32u id, proc *p );

Modified: trunk/daemon/membership.c
===================================================================
--- trunk/daemon/membership.c	2005-06-12 23:18:24 UTC (rev 234)
+++ trunk/daemon/membership.c	2005-06-13 04:41:15 UTC (rev 235)
@@ -253,21 +253,50 @@
 	packet_header	*pack_ptr;
 
 	pack_ptr = (packet_header *)scat->elements[0].buf;
+
+        /* First reject any message whose daemon has a different configuration */
+        if (pack_ptr->conf_hash != Cn.hash_code) {
+            Alarmp( SPLOG_WARNING, MEMB, "Memb_handle_message: Received message (pkthdr_len = %u) from host %d.%d.%d.%d with different spread configuration file (hash %u != local hash %u)\n", 
+                    scat->elements[0].len,
+                    IP1(pack_ptr->proc_id),
+                    IP2(pack_ptr->proc_id),
+                    IP3(pack_ptr->proc_id),
+                    IP4(pack_ptr->proc_id),
+                    pack_ptr->conf_hash, 
+                    Cn.hash_code);
+            return;
+        }
+
 	if( 	  Is_alive( pack_ptr->type ) )
 	{
 		Alarm( MEMB, "Memb_handle_message: handling alive message\n");
 		Memb_handle_alive( scat );
 
 	}else if( Is_join( pack_ptr->type ) ){
-		Alarm( MEMB, "Memb_handle_message: handling join message from %d, State is %d\n", pack_ptr->proc_id, State);
+		Alarm( MEMB, "Memb_handle_message: handling join message from %d.%d.%d.%d, State is %d\n", 
+                       IP1(pack_ptr->proc_id),
+                       IP2(pack_ptr->proc_id),
+                       IP3(pack_ptr->proc_id),
+                       IP4(pack_ptr->proc_id),
+                       State);
 		Memb_handle_join( scat );
 
 	}else if( Is_refer( pack_ptr->type ) ){
-		Alarm( MEMB, "Memb_handle_message: handling refer message from %d, State is %d\n",pack_ptr->proc_id, State);
+		Alarm( MEMB, "Memb_handle_message: handling refer message from %d.%d.%d.%d, State is %d\n",
+                       IP1(pack_ptr->proc_id),
+                       IP2(pack_ptr->proc_id),
+                       IP3(pack_ptr->proc_id),
+                       IP4(pack_ptr->proc_id),
+                       State);
 		Memb_handle_refer( scat );
 
 	}else if( Is_regular( pack_ptr->type ) ){
-		Alarm( NONE, "Memb_handle_message: handling foreign message from %d, State is %d\n",pack_ptr->proc_id, State);
+		Alarm( NONE, "Memb_handle_message: handling foreign message from %d.%d.%d.%d, State is %d\n",
+                       IP1(pack_ptr->proc_id),
+                       IP2(pack_ptr->proc_id),
+                       IP3(pack_ptr->proc_id),
+                       IP4(pack_ptr->proc_id),
+                       State);
 		Memb_handle_foreign( scat );
 
 	}else{
@@ -282,6 +311,19 @@
 	token_header	*token_ptr;
 
 	token_ptr = (token_header *)scat->elements[0].buf;
+
+        /* First reject any token whose daemon has a different configuration */
+        if (token_ptr->conf_hash != Cn.hash_code) {
+            Alarmp( SPLOG_WARNING, MEMB, "Memb_handle_token: Received token from host %d.%d.%d.%d with different spread configuration file (hash %u != local hash %u)\n", 
+                    IP1(token_ptr->proc_id),
+                    IP2(token_ptr->proc_id),
+                    IP3(token_ptr->proc_id),
+                    IP4(token_ptr->proc_id),
+                    token_ptr->conf_hash, 
+                    Cn.hash_code);
+            return;
+        }
+
 	if( 	  Is_form1( token_ptr->type ) )
 	{
 		Alarm( MEMB, "Memb_handle_token: handling form1 token\n");
@@ -942,6 +984,7 @@
 
 	pack_ptr = (packet_header *)Send_pack.elements[0].buf;
 	pack_ptr->type = ALIVE_TYPE;
+        pack_ptr->conf_hash = Cn.hash_code;
 	pack_ptr->data_len = 
 		2*sizeof(int16) + (F_members.num_members)*sizeof(int32);
 
@@ -962,6 +1005,7 @@
 
 	pack_ptr = (packet_header *)Send_pack.elements[0].buf;
 	pack_ptr->type = JOIN_TYPE;
+        pack_ptr->conf_hash = Cn.hash_code;
 	Send_pack.elements[1].buf = (char *)&F_members;
 	Send_pack.elements[1].len = 
 		2*sizeof(int16) + (F_members.num_members)*sizeof(int32);
@@ -1007,6 +1051,7 @@
 
 	pack_ptr = (packet_header *)Send_pack.elements[0].buf;
 	pack_ptr->type = JOIN_TYPE;
+        pack_ptr->conf_hash = Cn.hash_code;
 	Send_pack.elements[1].buf = (char *)&F_members;
 	Send_pack.elements[1].len = 
 		2*sizeof(int16) + (F_members.num_members)*sizeof(int32);
@@ -1270,6 +1315,7 @@
 	form_token.seq = Highest_seq+3333;
 	form_token.proc_id = My.id;
 	form_token.type = FORM1_TYPE;
+        form_token.conf_hash = Cn.hash_code;
 
 	/* if I am a ring leader - update my F_members */
 	if( F_reps.reps[0].type == RING_REP )

Modified: trunk/daemon/net_types.h
===================================================================
--- trunk/daemon/net_types.h	2005-06-12 23:18:24 UTC (rev 234)
+++ trunk/daemon/net_types.h	2005-06-13 04:41:15 UTC (rev 235)
@@ -111,6 +111,7 @@
 	int32		fifo_seq;
 	int16		packet_index;
 	int16		data_len;
+        int32           conf_hash;
 } packet_header;
 
 typedef	char       packet_body[MAX_PACKET_SIZE-sizeof(packet_header)];
@@ -124,6 +125,7 @@
         int32           aru_last_id;
 	int16		flow_control;
 	int16		rtr_len;
+        int32           conf_hash;
 } token_header;
 
 typedef	char       token_body[MAX_PACKET_SIZE-sizeof(token_header)];

Modified: trunk/daemon/network.c
===================================================================
--- trunk/daemon/network.c	2005-06-12 23:18:24 UTC (rev 234)
+++ trunk/daemon/network.c	2005-06-13 04:41:15 UTC (rev 235)
@@ -726,6 +726,7 @@
 	pack_ptr->fifo_seq	  = Flip_int32( pack_ptr->fifo_seq );
 	pack_ptr->packet_index	  = Flip_int16( pack_ptr->packet_index );
 	pack_ptr->data_len	  = Flip_int16( pack_ptr->data_len );
+	pack_ptr->conf_hash	  = Flip_int32( pack_ptr->conf_hash );
 }
 
 void	Flip_token( token_header *token_ptr )
@@ -738,4 +739,5 @@
 	token_ptr->aru_last_id	 = Flip_int32( token_ptr->aru_last_id );
 	token_ptr->flow_control	 = Flip_int16( token_ptr->flow_control );
 	token_ptr->rtr_len	 = Flip_int16( token_ptr->rtr_len );
+        token_ptr->conf_hash     = Flip_int32( token_ptr->conf_hash );
 }

Modified: trunk/daemon/protocol.c
===================================================================
--- trunk/daemon/protocol.c	2005-06-12 23:18:24 UTC (rev 234)
+++ trunk/daemon/protocol.c	2005-06-13 04:41:15 UTC (rev 235)
@@ -137,6 +137,7 @@
 	Last_token->seq = 0;
 	Last_token->aru = 0;
 	Last_token->flow_control = 0;
+        Last_token->conf_hash = 0;
 
 	Hurry_pack.num_elements = 1;
 	Hurry_pack.elements[0].len = sizeof(packet_header);




More information about the Spread-cvs mailing list