commit: r235 - trunk/daemon

[email protected]
Newsgroups gmane.network.spread.cvs
Message-ID <[email protected]>
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  <[email protected]>
+ 
+ 	* spread.c (main): Only print Alarms of SPLOG_INFO or higher priority by default.
+ 
+Sun Mar 20 12:12:53 2005  Jonathan Stanton  <[email protected]>
+ 
+ 	* 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  <[email protected]>
 
 	* 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);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.