[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