Пример #1
0
static	void	Read_message()
{

static	char		 mess[MAX_MESSLEN];
	char		 sender[MAX_GROUP_NAME];
	char		 target_groups[MAX_MEMBERS][MAX_GROUP_NAME];
        membership_info  memb_info;
        vs_set_info      vssets[MAX_VSSETS];
        unsigned int     my_vsset_index;
        int              num_vs_sets;
        char             members[MAX_MEMBERS][MAX_GROUP_NAME];
	int		 num_groups;
	int		 service_type;
	int16		 mess_type;
	int		 endian_mismatch;
	int		 i,j;
	int		 ret;

        service_type = 0;

	ret = SP_receive( Mbox, &service_type, sender, 100, &num_groups, target_groups, 
		&mess_type, &endian_mismatch, sizeof(mess), mess );
	printf("\n============================\n");
	if( ret < 0 ) 
	{
                if ( (ret == GROUPS_TOO_SHORT) || (ret == BUFFER_TOO_SHORT) ) {
                        service_type = DROP_RECV;
                        printf("\n========Buffers or Groups too Short=======\n");
                        ret = SP_receive( Mbox, &service_type, sender, MAX_MEMBERS, &num_groups, target_groups, 
                                          &mess_type, &endian_mismatch, sizeof(mess), mess );
                }
        }
        if (ret < 0 )
        {
		if( ! To_exit )
		{
			SP_error( ret );
			printf("\n============================\n");
			printf("\nBye.\n");
		}
		exit( 0 );
	}
	if( Is_regular_mess( service_type ) )
	{
		mess[ret] = 0;
		if     ( Is_unreliable_mess( service_type ) ) printf("received UNRELIABLE ");
		else if( Is_reliable_mess(   service_type ) ) printf("received RELIABLE ");
		else if( Is_fifo_mess(       service_type ) ) printf("received FIFO ");
		else if( Is_causal_mess(     service_type ) ) printf("received CAUSAL ");
		else if( Is_agreed_mess(     service_type ) ) printf("received AGREED ");
		else if( Is_safe_mess(       service_type ) ) printf("received SAFE ");
		printf("message from %s, of type %d, (endian %d) to %d groups \n(%d bytes): %s\n",
			sender, mess_type, endian_mismatch, num_groups, ret, mess );
	}else if( Is_membership_mess( service_type ) )
        {
                ret = SP_get_memb_info( mess, service_type, &memb_info );
                if (ret < 0) {
                        printf("BUG: membership message does not have valid body\n");
                        SP_error( ret );
                        exit( 1 );
                }
		if     ( Is_reg_memb_mess( service_type ) )
		{
			printf("Received REGULAR membership for group %s with %d members, where I am member %d:\n",
				sender, num_groups, mess_type );
			for( i=0; i < num_groups; i++ )
				printf("\t%s\n", &target_groups[i][0] );
			printf("grp id is %d %d %d\n",memb_info.gid.id[0], memb_info.gid.id[1], memb_info.gid.id[2] );

			if( Is_caused_join_mess( service_type ) )
			{
				printf("Due to the JOIN of %s\n", memb_info.changed_member );
			}else if( Is_caused_leave_mess( service_type ) ){
				printf("Due to the LEAVE of %s\n", memb_info.changed_member );
			}else if( Is_caused_disconnect_mess( service_type ) ){
				printf("Due to the DISCONNECT of %s\n", memb_info.changed_member );
			}else if( Is_caused_network_mess( service_type ) ){
				printf("Due to NETWORK change with %u VS sets\n", memb_info.num_vs_sets);
                                num_vs_sets = SP_get_vs_sets_info( mess, &vssets[0], MAX_VSSETS, &my_vsset_index );
                                if (num_vs_sets < 0) {
                                        printf("BUG: membership message has more then %d vs sets. Recompile with larger MAX_VSSETS\n", MAX_VSSETS);
                                        SP_error( num_vs_sets );
                                        exit( 1 );
                                }
                                for( i = 0; i < num_vs_sets; i++ )
                                {
                                        printf("%s VS set %d has %u members:\n",
                                               (i  == my_vsset_index) ?
                                               ("LOCAL") : ("OTHER"), i, vssets[i].num_members );
                                        ret = SP_get_vs_set_members(mess, &vssets[i], members, MAX_MEMBERS);
                                        if (ret < 0) {
                                                printf("VS Set has more then %d members. Recompile with larger MAX_MEMBERS\n", MAX_MEMBERS);
                                                SP_error( ret );
                                                exit( 1 );
                                        }
                                        for( j = 0; j < vssets[i].num_members; j++ )
                                                printf("\t%s\n", members[j] );
                                }
			}
		}else if( Is_transition_mess(   service_type ) ) {
			printf("received TRANSITIONAL membership for group %s\n", sender );
		}else if( Is_caused_leave_mess( service_type ) ){
			printf("received membership message that left group %s\n", sender );
		}else printf("received incorrecty membership message of type 0x%x\n", service_type );
        } else if ( Is_reject_mess( service_type ) )
        {
		printf("REJECTED message from %s, of servicetype 0x%x messtype %d, (endian %d) to %d groups \n(%d bytes): %s\n",
			sender, service_type, mess_type, endian_mismatch, num_groups, ret, mess );
	}else printf("received message of unknown message type 0x%x with ret %d\n", service_type, ret);


	printf("\n");
	printf("User> ");
	fflush(stdout);
}
Пример #2
0
int main(int argc, char **argv) {
  double t;

  exe = *argv;
  usage(argc, argv);

  FL_lib_init();

  if ((err = FL_connect(daemon_name, user_name, 0, &mbox, priv_name)) != ACCEPT_SESSION) {
    fprintf(stderr, "FL_connect failure: ");
    FL_error(err);
    exit(1);
  }  
  if (user_type == DELTA) {
    double *fl_join_times  = (double*) malloc(sizeof(double) * num_joins_leaves);
    double *fl_leave_times = (double*) malloc(sizeof(double) * num_joins_leaves);
    double *fl_cmbo_times  = (double*) malloc(sizeof(double) * num_joins_leaves);

    if (!fl_join_times || !fl_leave_times || !fl_cmbo_times) {
      exit(fprintf(stderr, "Couldn't mallocate tracking arrays!\r\n"));
    }

    for (i = 0; i < num_joins_leaves; ++i) {
      t = get_time_timeofday();

      if ((err = FL_join(mbox, group_name)) < 0) {
	fprintf(stderr, "FL_join failure: ");
	FL_error(err);
	exit(1);
      }	
      do { 
	if ((mess_len = FL_receive(mbox, &service_type, sender, MY_MAX_NUM_GROUPS, 
				   &num_groups, groups, &mess_type, &endian_mismatch, 
				   MY_MAX_MESS_SIZE, mess, &more_messes)) < 0) {
	  fprintf(stderr, "FL_receive failure: ");
	  FL_error(mess_len);
	  exit(1);
	}
      } while (!Is_reg_memb_mess(service_type)); 

      fl_join_times[i] = get_time_timeofday() - t;

      if (should_sleep) {
	/* sleep for 4 times how long the join membership took */
	/* allows membership to stabilize */
	usleep((unsigned long) (4 * fl_join_times[i] * 1000));
      }
      
      /* send a kill message if we are done */
      if (i == num_joins_leaves - 1) {
	if ((mess_len = FL_multicast(mbox, SAFE_MESS, group_name, DIE_MESS, 0, 0)) < 0) {
	  fprintf(stderr, "FL_multicast failure: ");
	  FL_error(err);
	  exit(1);
	}
      }      

      t = get_time_timeofday();
      
      if ((err = FL_leave(mbox, group_name)) < 0) {
	fprintf(stderr, "FL_leave failure: ");
	FL_error(err);
	exit(1); 
      }	
      do {
	if ((mess_len = FL_receive(mbox, &service_type, sender, MY_MAX_NUM_GROUPS, 
				   &num_groups, groups, &mess_type, &endian_mismatch, 
				   MY_MAX_MESS_SIZE, mess, &more_messes)) < 0) {
	  fprintf(stderr, "FL_receive failure: ");
	  FL_error(mess_len);
	  exit(1);
	}
      } while (!Is_self_leave(service_type));

      fl_leave_times[i] = get_time_timeofday() - t;
      fl_cmbo_times[i]  = fl_join_times[i] + fl_leave_times[i];

      if (should_sleep) {
	/* sleep for 4 times how long the join membership took */
	/* allows membership to stabilize */
	usleep((unsigned long) (4 * fl_join_times[i] * 1000));
      }
    }
    /* compute timing statistics */
    comp_stats(&fl_join_stats, fl_join_times, num_joins_leaves);
    comp_stats(&fl_leave_stats, fl_leave_times, num_joins_leaves);
    comp_stats(&fl_cmbo_stats, fl_cmbo_times, num_joins_leaves);

    /* output timing statistics */
    if (pretty_print) { 
      printf("Flush Membership Timings (includes Spread): Group Size: %d, # Joins/Leaves: %d\r\n\r\n", 
	     num_members, num_joins_leaves);

      printf("\tFlush Join: ind. total (90%%): %.6fms, ind. total: %.6fms\r\n", 
	     sp_join_stats.total90, sp_join_stats.total);

      printf("\tFlush Leave: ind. total (90%%): %.6fms, ind. total: %.6fms\r\n", 
	     sp_leave_stats.total90, sp_leave_stats.total);

      printf("\tFlush Join/Leave: ind. total (90%%): %.6fms, ind. total: %.6fms\r\n", 
	     sp_cmbo_stats.total90, sp_cmbo_stats.total);

      printf("\r\n\t\tGroup Size\t# Trials\tQ1\tMEDIAN\tQ3"
	     "\tMIN (5%%)\tMEAN90\tSTDDEV90\tMAX (95%%)"
	     "\tMIN\tMEAN\tSTDDEV\tMAX\r\n");
    }
    printf("\tFL_Join:\t%d\t%d\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\r\n",
	   num_members, num_joins_leaves, fl_join_stats.quart1, fl_join_stats.median,
	   fl_join_stats.quart3, fl_join_stats.min5, fl_join_stats.mean90, 
	   fl_join_stats.stddev90, fl_join_stats.max95, fl_join_stats.min, 
	   fl_join_stats.mean, fl_join_stats.stddev, fl_join_stats.max);

    printf("\tFL_Leave:\t%d\t%d\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\r\n",
	   num_members, num_joins_leaves, fl_leave_stats.quart1, fl_leave_stats.median,
	   fl_leave_stats.quart3, fl_leave_stats.min5, fl_leave_stats.mean90, 
	   fl_leave_stats.stddev90, fl_leave_stats.max95, fl_leave_stats.min, 
	   fl_leave_stats.mean, fl_leave_stats.stddev, fl_leave_stats.max);

    printf("\tFL_Join + FL_Leave\t%d\t%d\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\t%.6f\r\n",
	   num_members, num_joins_leaves, fl_cmbo_stats.quart1, fl_cmbo_stats.median,
	   fl_cmbo_stats.quart3, fl_cmbo_stats.min5, fl_cmbo_stats.mean90, 
	   fl_cmbo_stats.stddev90, fl_cmbo_stats.max95, fl_cmbo_stats.min, 
	   fl_cmbo_stats.mean, fl_cmbo_stats.stddev, fl_cmbo_stats.max);

  } else if (user_type == LOAD_MEMBER) { 
    if ((err = FL_join(mbox, group_name)) < 0) {
      fprintf(stderr, "FL_join failure: ");
      FL_error(err);
      exit(1);
    }      
    while (1) {
      if ((mess_len = FL_receive(mbox, &service_type, sender,
				 MY_MAX_NUM_GROUPS, &num_groups, groups,
				 &mess_type, &endian_mismatch,
				 MY_MAX_MESS_SIZE, mess, &more_messes)) < 0) { 
	fprintf(stderr, "FL_receive failure: ");
	FL_error(mess_len);
	exit(1);
      }
      if (Is_flush_req_mess(service_type)) {
	if ((err = FL_flush(mbox, group_name)) < 0) {
	  fprintf(stderr, "FL_flush failure: ");
	  FL_error(err);
	  exit(1);
	}
      } else if (Is_reg_memb_mess(service_type)) {
	if (Is_caused_leave_mess(service_type)) {
	  if (about_to_die) {
	    break;
	  }
	} else if (!Is_caused_join_mess(service_type)) {
	  exit(fprintf(stderr, "Unexpected membership type: %d\n", service_type));
	}
      } else if (Is_safe_mess(service_type) && mess_type == DIE_MESS) {
	about_to_die = 1;
      }
    }
    printf("Success!\r\n");

  } else { 
    fprintf(stderr, "Unknown user type: %d\n", user_type); 
    exit(printUsage(stderr));
  }
  
  if ((err = FL_disconnect(mbox)) < 0) {
    fprintf(stderr, "FL_disconnect failure: ");
    FL_error(err);
    exit(1);
  }
  return 0;
}
Пример #3
0
static PyObject *
new_membership_msg(int type, PyObject *group, int num_members,
		   char (*members)[MAX_GROUP_NAME], char *buffer, int size)
{
    MembershipMsg *self;
    group_id grp_id;
    membership_info memb_info;
    int32 num_extra_members = 0;
    int i;
    int ret;

    assert(group != NULL);
    self = PyObject_New(MembershipMsg, &MembershipMsg_Type);
    if (self == NULL)
        return NULL;
    self->reason = type & CAUSED_BY_MASK; /* from sp.h defines */
    self->msg_subtype = type & (TRANSITION_MESS | REG_MEMB_MESS);
    Py_INCREF(group);
    self->group = group;
    self->members = NULL;
    self->extra = NULL;
    self->group_id = NULL;
    self->changed_member = NULL;
    self->members = PyTuple_New(num_members);
    if (self->members == NULL) {
        Py_DECREF(self);
        return NULL;
    }
    for (i = 0; i < num_members; ++i) {
        PyObject *s = PyString_FromString(members[i]);
        if (!s) {
            Py_DECREF(self);
            return NULL;
        }
        PyTuple_SET_ITEM(self->members, i, s);
    }


    if ((ret = SP_get_memb_info(buffer, type, &memb_info)) < 0) {
	      PyErr_Format(SpreadError, "error %d on SP_get_memb_info", ret);
        Py_DECREF(self);
        return NULL;
    }


    memcpy(&grp_id, &memb_info.gid, sizeof(group_id));
    self->group_id = new_group_id(grp_id);
    if (self->group_id == NULL) {
        Py_DECREF(self);
        return NULL;
    }


    /* The extra attribute is a tuple initialized for 0 or more items.
     * If the member event is a single member event such as a join, leave or disconnect,
     * the changed member attribute is set from memb_info.changed_member
     * and a single value from vs_set, which is stored inside the message, is added to extra tuple.
     * If the member event is a merge or partition, the list of member names
     * from vs_set is stored in extra.
     */


    if (Is_reg_memb_mess(type) && (Is_caused_join_mess(type) || Is_caused_disconnect_mess(type) || Is_caused_leave_mess(type))) {
        self->changed_member =  PyString_FromString(memb_info.changed_member);
        if (!self->changed_member) {
            Py_DECREF(self);
            return NULL;
        }
    }
    else {
        self->changed_member = Py_BuildValue("");
    }

    num_extra_members = memb_info.my_vs_set.num_members;

    self->extra = PyTuple_New(num_extra_members);
    if (self->extra == NULL) {
        Py_DECREF(self);
        return NULL;
    }

    if (num_extra_members > 0) {

        char (*member_names)[MAX_GROUP_NAME] = (char (*)[MAX_GROUP_NAME]) malloc(num_extra_members * MAX_GROUP_NAME);

        if (member_names == NULL) {
            Py_DECREF(self);
            PyErr_NoMemory();
            return NULL;
        }

        if ((ret = SP_get_vs_set_members(buffer, &memb_info.my_vs_set, member_names, num_extra_members)) < 0) {
	          PyErr_Format(SpreadError, "error %d on SP_get_vs_set_members", ret);
            Py_DECREF(self);
            free(member_names);
            return NULL;
        }

        for (i = 0; i < num_extra_members; i++) {
            PyObject *s;
            s = PyString_FromString(member_names[i]);
            if (!s) {
                Py_DECREF(self);
                free(member_names);
                return NULL;
            }
            PyTuple_SET_ITEM(self->extra, i, s);
        }

        free(member_names);
    }

    return (PyObject *)self;
}
Пример #4
0
int main( int argc, char *argv[] )
{
	int		ret;
	int		service_type, num_groups;
	char		sender[MAX_GROUP_NAME];
	int16		mess_type;
	int		dummy_endian_mismatch;
        int             joined_members;
        int             sender_index;
	int		i,j;

	Usage( argc, argv );

        if (Num_members == 0) {
            /* connecting to the relevant Spread daemon, no need for group info */
            printf("flooder: connecting to %s\n", Spread_name );
            ret = SP_connect( Spread_name, User, 0, 0, &Mbox, Private_group ) ;
        } else {
            /* connecting to the relevant Spread daemon, DO need group info */
            printf("flooder: connecting to %s with group membership\n", Spread_name );
            ret = SP_connect( Spread_name, User, 0, 1, &Mbox, Private_group ) ;
        }
        if(ret < 0) 
	{
		SP_error( ret );
                exit(1) ;
        }
	/* 
	 * Joining the process group.
	 *
	 * Note that this is not necessary in order to multicast the
	 * messages, but only to demonstrate end-to-end behaviour.
	 */
	if( Read_only )
	{
		printf("flooder: Only receiving messages\n");
		SP_join( Mbox, "flooder" );
	}else if( Write_only ) {
		printf("flooder: starting  multicast of %d messages, %d bytes each (self discarding).\n", Num_messages, Num_bytes);
	}else{
		SP_join( Mbox, "flooder" );
		printf("flooder: starting  multicast of %d messages, %d bytes each.\n", Num_messages, Num_bytes);
	}

        /* Wait for all members to join */
        joined_members = 0;
        while( joined_members < Num_members)
        {
            service_type = 0;
            ret = SP_receive( Mbox, &service_type, sender, FLOODER_MAX_GROUPS, &num_groups, ret_groups, 
                              &mess_type, &dummy_endian_mismatch, sizeof(recv_mess), recv_mess );
            if( ret < 0 ) 
            {
                if ( (ret == GROUPS_TOO_SHORT) || (ret == BUFFER_TOO_SHORT) ) {
                    printf("\n========Buffers or Groups too Short=======\n");
                    printf("Should NOT happen in wait for members! Program quitting\n");
                    exit(1);
                }       
            }

            if( Is_regular_mess( service_type ) )
            {
		mess[ret] = 0;
		if     ( Is_unreliable_mess( service_type ) ) printf("received UNRELIABLE ");
		else if( Is_reliable_mess(   service_type ) ) printf("received RELIABLE ");
		else if( Is_fifo_mess(       service_type ) ) printf("received FIFO ");
		else if( Is_causal_mess(     service_type ) ) printf("received CAUSAL ");
		else if( Is_agreed_mess(     service_type ) ) printf("received AGREED ");
		else if( Is_safe_mess(       service_type ) ) printf("received SAFE ");
		printf("message during wait for members, from %s, of type %d, (endian %d) to %d groups \n(%d bytes): %s\n",
			sender, mess_type, dummy_endian_mismatch, num_groups, ret, recv_mess );
            }else if( Is_membership_mess( service_type ) )
            {
		if     ( Is_reg_memb_mess( service_type ) )
		{
			printf("Received REGULAR membership for group %s with %d members, where I am member %d:\n",
				sender, num_groups, mess_type );
			for( i=0; i < num_groups; i++ )
				printf("\t%s\n", &ret_groups[i][0] );
                        /* update count of joined members */
                        joined_members = num_groups;

		}else if( Is_transition_mess(   service_type ) ) {
			printf("received TRANSITIONAL membership for group %s\n", sender );
		}else if( Is_caused_leave_mess( service_type ) ){
			printf("received membership message that left group %s\n", sender );
		}else printf("received incorrecty membership message of type 0x%x\n", service_type );
            } else if ( Is_reject_mess( service_type ) )
            {
		printf("REJECTED message from %s, of servicetype 0x%x messtype %d, (endian %d) to %d groups \n(%d bytes): %s\n",
			sender, service_type, mess_type, dummy_endian_mismatch, num_groups, ret, recv_mess );
            }else printf("received message of unknown message type 0x%x with ret %d\n", service_type, ret);
           
        } /* joined_members < Num_members */

        /* Update My_Counter_index field based on location of my name in last membership message */
        if (Num_members)
        {
            My_Counter_index = mess_type;
            memcpy(&mess[0], &My_Counter_index, sizeof(int));
        }

	for( i=1; i <= Num_messages; i++ )
	{
		/* multicast a message unless Read_only */
		if( !Read_only )
		{
                    if (Num_members) 
                    {
                        ret = SP_multicast( Mbox, FIFO_MESS, "flooder", 0, Num_bytes, mess );
                        Send_Counter++;
                    } else {
                        ret = SP_multicast( Mbox, RELIABLE_MESS, "flooder", 0, Num_bytes, mess );
                    }
		    if( ret != Num_bytes ) 
		    {
			if( ret < 0 )
			{
				SP_error( ret );
				exit(1);
			}
			printf("sent a different message %d -> %d\n", Num_bytes, ret );
		    }
		}

		/* receive a message (Read_only) or one of my messages */
		if( Read_only || ( i > 200 && !Write_only ) )
		{
                    int notdone;

		    do{
                        service_type = 0;

			ret = SP_receive( Mbox, &service_type, sender, FLOODER_MAX_GROUPS, &num_groups, ret_groups, 
					  &mess_type, &dummy_endian_mismatch, sizeof(recv_mess), recv_mess );
                        if( ret < 0 ) 
                        {
                                if ( (ret == GROUPS_TOO_SHORT) || (ret == BUFFER_TOO_SHORT) ) {
                                        service_type = DROP_RECV;
                                        printf("\n========Buffers or Groups too Short=======\n");
                                        ret = SP_receive( Mbox, &service_type, sender, FLOODER_MAX_GROUPS, &num_groups, ret_groups, 
                                                          &mess_type, &dummy_endian_mismatch, sizeof(recv_mess), recv_mess );
                                }
                        }
			if( ret < 0 )
			{
				SP_error( ret );
				exit(1);
			}
                        if (Num_members) {
                            /* update counters of received messages */
                            memcpy(&sender_index, &recv_mess[0], sizeof(int));
                            Recv_Counters[sender_index]++;
                            /* 
                               printf("DEBUG: updated counter %d to value %d\n", sender_index, Recv_Counters[sender_index]);
                            */
                            if (Recv_Counters[sender_index] == (Lowest_Recv_Counter + 1)) {
                                /* Update Lowest_Recv_Counter */
                                Lowest_Recv_Counter = INT_MAX;
                                for (j=0; j < Num_members; j++) {
                                    if (Recv_Counters[j] == 0) continue;
                                    if (Recv_Counters[j] < Lowest_Recv_Counter)
                                        Lowest_Recv_Counter = Recv_Counters[j];
                                }
                                if (Lowest_Recv_Counter == INT_MAX) 
                                    Lowest_Recv_Counter = 0;
                            }
                            /* Read loop is done if we send messages and we have received all 
                             * other senders messages upto 100 less then our current send count 
                             */
                            notdone = ( Lowest_Recv_Counter < (Send_Counter - 200) && !Read_only );
                        } else {
                            notdone = (strcmp( sender, Private_group ) != 0 && !Read_only);
                        }

		    } while( notdone );
		}

		/* report some progress... */
		if( i%1000 == 0 ) printf("flooder: completed %6d messages of %d bytes\n",i, ret);
	}
	printf("flooder: completed multicast of %d messages, %d bytes each.\n", Num_messages, Num_bytes);

	return 0;
}
Пример #5
0
static	void	Read_message()
{

static	char		 mess[SPREAD_MESS_LEN];
        char		 sender[MAX_GROUP_NAME];
        char		 target_groups[MAX_MEMBERS][MAX_GROUP_NAME];
        membership_info  memb_info;
        vs_set_info      vssets[MAX_VSSETS];
        unsigned int     my_vsset_index;
        int              num_vs_sets;
        char             members[MAX_MEMBERS][MAX_GROUP_NAME];
        int		 num_groups;
        int		 service_type;
        int16		 mess_type;
        int		 endian_mismatch;
        int		 i,j;
        int		 ret;

        service_type = 0;

	ret = SP_receive( Mbox, &service_type, sender, 100, &num_groups, target_groups, 
		&mess_type, &endian_mismatch, sizeof(mess), mess );
	if( ret < 0 ) 
	{
                if ( (ret == GROUPS_TOO_SHORT) || (ret == BUFFER_TOO_SHORT) ) {
                        service_type = DROP_RECV;
                        printf("\n========Buffers or Groups too Short=======\n");
                        ret = SP_receive( Mbox, &service_type, sender, MAX_MEMBERS, &num_groups, target_groups, 
                                          &mess_type, &endian_mismatch, sizeof(mess), mess );
                }
        }
        if (ret < 0 )
        {
		if( ! To_exit )
		{
			SP_error( ret );
			printf("\n============================\n");
			printf("\nBye.\n");
		}
		exit( 0 );
	}
	if( Is_regular_mess( service_type ) )
	{
		//printf("message from %s, of type %d, (endian %d) to %d groups \n(%d bytes): %s\n", sender, mess_type, endian_mismatch, num_groups, ret, mess );
	    
            typecheck* type = (typecheck*)mess;
            if (type->type == TYPE_JOIN_CHATROOM) {
                join_chatroom* dat = (join_chatroom*)mess;
                ret = add_user(dat->u_id,dat->sp_id,dat->chatroom);
            }
            else if (type->type == TYPE_LEAVE_CHATROOM) {
                leave_chatroom* dat = (leave_chatroom*)mess;
                rm_user(dat->sp_id);
            }
            else if (type->type == TYPE_SEND_MSG) {
                message* dat = (message*)mess;
                if (strlen(chatroom) == 0)
                    add_room(chatroom);   
                lamport* ts = malloc(sizeof(lamport));
                ts->server_id = dat->timestamp.server_id;
                ts->index = dat->timestamp.index;
                printf("[%d,%d]\n",ts->server_id,ts->index);
                add_message(ts, dat->u_id, dat->chatroom, dat->mess);             
            }
            else if (type->type == TYPE_LIKE_MSG) {
                like* dat = (like*)mess;
                lamport* lts = malloc(sizeof(lamport));
                lamport* mts = malloc(sizeof(lamport));
                lts->server_id = dat->timestamp.server_id;
                lts->index = dat->timestamp.index;
                mts->server_id = dat->timestamp.server_id;
                mts->index = dat->timestamp.index;

                ret = add_like(dat->like_state, lts, dat->u_id, chatroom, mts); 
                printf("~~~~~~~~ %d:[%d,%d | %d,%d] %d %s %s \n",ret, lts->server_id,lts->index,mts->server_id,mts->index,dat->like_state,dat->u_id,chatroom);
            } 
            master_print();

	}else if( Is_membership_mess( service_type ) )
        {
                ret = SP_get_memb_info( mess, service_type, &memb_info );
                if (ret < 0) {
                        printf("BUG: membership message does not have valid body\n");
                        SP_error( ret );
                        exit( 1 );
                }
		if     ( Is_reg_memb_mess( service_type ) )
		{
			printf("Received REGULAR membership for group %s with %d members, where I am member %d:\n",
				sender, num_groups, mess_type );
			for( i=0; i < num_groups; i++ )
				printf("\t%s\n", &target_groups[i][0] );
			printf("grp id is %d %d %d\n",memb_info.gid.id[0], memb_info.gid.id[1], memb_info.gid.id[2] );

			if( Is_caused_join_mess( service_type ) )
			{
				printf("Due to the JOIN of %s\n", memb_info.changed_member );
			}else if( Is_caused_leave_mess( service_type ) ){
				printf("Due to the LEAVE of %s\n", memb_info.changed_member );
			}else if( Is_caused_disconnect_mess( service_type ) ){
				printf("Due to the DISCONNECT of %s\n", memb_info.changed_member );
			}else if( Is_caused_network_mess( service_type ) ){
				printf("Due to NETWORK change with %u VS sets\n", memb_info.num_vs_sets);
                                num_vs_sets = SP_get_vs_sets_info( mess, &vssets[0], MAX_VSSETS, &my_vsset_index );
                                if (num_vs_sets < 0) {
                                        printf("BUG: membership message has more then %d vs sets. Recompile with larger MAX_VSSETS\n", MAX_VSSETS);
                                        SP_error( num_vs_sets );
                                        exit( 1 );
                                }
                                for( i = 0; i < num_vs_sets; i++ )
                                {
                                        printf("%s VS set %d has %u members:\n",
                                               (i  == my_vsset_index) ?
                                               ("LOCAL") : ("OTHER"), i, vssets[i].num_members );
                                        ret = SP_get_vs_set_members(mess, &vssets[i], members, MAX_MEMBERS);
                                        if (ret < 0) {
                                                printf("VS Set has more then %d members. Recompile with larger MAX_MEMBERS\n", MAX_MEMBERS);
                                                SP_error( ret );
                                                exit( 1 );
                                        }
                                        for( j = 0; j < vssets[i].num_members; j++ )
                                                printf("\t%s\n", members[j] );
                                }
			}
		}else if( Is_transition_mess(   service_type ) ) {
			printf("received TRANSITIONAL membership for group %s\n", sender );
		}else if( Is_caused_leave_mess( service_type ) ){
			printf("received membership message that left group %s\n", sender );
		}else printf("received incorrecty membership message of type 0x%x\n", service_type );
        } else if ( Is_reject_mess( service_type ) )
        {
		printf("REJECTED message from %s, of servicetype 0x%x messtype %d, (endian %d) to %d groups \n(%d bytes): %s\n",
			sender, service_type, mess_type, endian_mismatch, num_groups, ret, mess );
	}else printf("received message of unknown message type 0x%x with ret %d\n", service_type, ret);


	printf("\n");
	fflush(stdout);
}
Пример #6
0
int main(int argc, const char *argv[]) {
    char from[MAX_GROUP_NAME];
    char message[MAX_MESSLEN];
    membership_info memb_info;
    int num_groups;
    char target_groups[100][MAX_GROUP_NAME];
    int16 mess_type;
    int endian_mismatch;

    int service_type;
    int loop = 1;
    int rc;
    int ret;
    int i;

    sqlite3 *mydb;
    char *dbName;
    char *zErrMsg;

    connectionStatus status = UNKNOWN;

    char buffer[MAX_GROUP_NAME];
    char sqlBuffer[1024];
    char *member;
    char *host;
    char *tok;
    char ch;
    extern char *optarg;

    char scratch[255];

    global.connected=0;
    global.Group=(char *)NULL;
    global.configFileName=(char *)NULL;
    global.locked = 0;
    global.rawClient =1;
    global.debug = 0;

#ifdef FICL
    global.appDir=(char *)NULL;
#endif

    char *group=(char *)NULL;

    setSymbol("BUILD",__DATE__,LOCK,LOCAL);
    setSymbol("CLIENT","raw",UNLOCK,GLOBAL);
    setSymbol("SPREAD_SERVER","4803",UNLOCK,GLOBAL);
    setSymbol("GROUP","global",UNLOCK,GLOBAL);
    setSymbol("USER","dbCache",LOCK,GLOBAL);
    setSymbol("DEBUG","false",UNLOCK,GLOBAL);
    setSymbol("MODE","local",UNLOCK,GLOBAL);
    setSymbol("START_FILE","./dbCache.rc",UNLOCK,GLOBAL);

    while((ch = getopt(argc, ( char **)argv,"dhc:")) != -1) {
        switch(ch) {
            case 'c':
                setSymbol("START_FILE", optarg,LOCK,GLOBAL);
                break;
            case 'd':
                global.debug=1;
                break;
            case 'h':
                usage();
                exit(0);
                break;
        }
    }

    loadFile(getSymbol("START_FILE"));

    if( global.debug ) {
        setBoolean("DEBUG",1);
    }

    global.debug = getBoolean("DEBUG");

    if(global.debug) {
        dumpGlobals();
        dumpSymbols();
    }

    dbName = getSymbol("DATABASE");

    connectToSpread();

    while(loop) {
        status = UNKNOWN;
        ret = SP_receive(global.Mbox, &service_type, from, 100,
                &num_groups, target_groups,
                &mess_type, &endian_mismatch, sizeof(message), message);

        if (Is_membership_mess (service_type)) {
            ret = SP_get_memb_info(message, service_type, &memb_info);

            if (Is_caused_join_mess(service_type)) {
                status=JOINED;
            } 
            if (Is_caused_leave_mess (service_type)) {
                status = LEFT;
            } 
            if (Is_caused_disconnect_mess (service_type)) {
                status = DISCONNECTED;
            } 
            if (Is_caused_network_mess (service_type)) {
                status = NETWORK;
            }

            rc = sqlite3_open(dbName, &mydb);
            for (i = 0; i < num_groups; i++) {

                if( global.debug) {
                    printf("\t%s\n",(char *) &target_groups[i][0]);
                }

                strcpy(buffer, &target_groups[i][1]);

                member=strtok(buffer,"#");
                host=strtok(NULL,"#");

                if( global.debug) {
                    printf("\t\tMember:%s\n", member);
                    printf("\t\tHost  :%s\n", host);
                }

                statusToText( status, scratch );

                if (JOINED == status ) {
                    sprintf( sqlBuffer,"insert or replace into status  ( member, host, grp, state ) values ( '%s','%s','%s','%s');", member, host,from,scratch);
                }
                if( global.debug) {
                    printf ("%s\n",sqlBuffer);
                }
                rc = sqlite3_exec(mydb, sqlBuffer, 0, 0, &zErrMsg);
            }
            strcpy(buffer, &memb_info.changed_member[1]);
            member=strtok(buffer,"#");
            host=strtok(NULL,"#");

            statusToText( status, scratch );
            sprintf( sqlBuffer, "update status set state='%s' where member = '%s' and host ='%s';",scratch, member,host);

            if( global.debug) {
                printf("CHANGE: %s %s\n",member,host);
                printf("CHANGE: %s\n", scratch);
                printf ("%s\n",sqlBuffer);
            }

            rc = sqlite3_exec(mydb, sqlBuffer, 0, 0, &zErrMsg);

            sqlite3_close(mydb);

        }

    }


    printf("============ After\n");
    dumpGlobals();

    printf("Sender %s\n",from);
    printf("Message >%s<\n",message);

    toSpread(from,"Message recieved\n");

    spreadJoin("TEST");

    sleep(2);

    spreadLeave("TEST");

    sleep(2);

    spreadDisconnect();
}
Пример #7
0
static  void    Read_message()
{

static  char             mess[MAX_MESSLEN];
        char             sender[MAX_GROUP_NAME];
        char             target_groups[MAX_MEMBERS][MAX_GROUP_NAME];
        membership_info  memb_info;
        vs_set_info      vssets[MAX_VSSETS];
        unsigned int     my_vsset_index;
        int              num_vs_sets;
        char             members[MAX_MEMBERS][MAX_GROUP_NAME];
        int              num_groups;
        int              service_type;
        int16            mess_type;
        int              endian_mismatch;
        int              i,j;
        int              ret, success =0;
	char		 server_group[1];
	char		 *uname;

        service_type = 0;

        ret = SP_receive( Mbox, &service_type, sender, 100, &num_groups, target_groups, 
                &mess_type, &endian_mismatch, sizeof(mess), mess );
        if( ret < 0 ) 
        {
                if ( (ret == GROUPS_TOO_SHORT) || (ret == BUFFER_TOO_SHORT) ) {
                        service_type = DROP_RECV;
                        printf("\n========Buffers or Groups too Short=======\n");
                        ret = SP_receive( Mbox, &service_type, sender, MAX_MEMBERS, &num_groups, target_groups, 
                                          &mess_type, &endian_mismatch, sizeof(mess), mess );
                }
        }
if (ret < 0 )
        {
                if( ! To_exit )
                {
                        SP_error( ret );
                        printf("\n============================\n");
                        printf("\nBye.\n");
                }
                exit( 0 );
        }
        if( Is_regular_mess( service_type ) )
        {
                mess[ret] = 0;
                //printf("message from %s, of type %d, (endian %d) to %d groups \n(%d bytes): %s\n",
                //        sender, mess_type, endian_mismatch, num_groups, ret, mess ); 
	 	//printf("private group is %s\n", Private_group);
		if (strncmp(Private_group, sender, strlen(Private_group)) != 0)
		{	
		   recv_server_msg((struct chat_packet *) mess, mess_type);
		}
        }else if( Is_membership_mess( service_type ) )
        {
                ret = SP_get_memb_info( mess, service_type, &memb_info );
                if (ret < 0) {
                        printf("BUG: membership message does not have valid body\n");
                        SP_error( ret );
                        exit( 1 );
                }
	if     ( Is_reg_memb_mess( service_type ) )
                {
                        //printf("Received REGULAR membership for group %s with %d members, where I am member %d:\n",
                        //        sender, num_groups, mess_type );
                        //for( i=0; i < num_groups; i++ )
                        //        printf("\t%s\n", &target_groups[i][0] );
                        //printf("grp id is %d %d %d\n",memb_info.gid.id[0], memb_info.gid.id[1], memb_info.gid.id[2] );
			sprintf(server_group, "c%d", connected);
			if (strncmp(sender, server_group, 2) == 0)
			{
			  //printf("Server connection message\n");
			  for (i=0; i< num_groups; i++)
			  {
			    if (target_groups[i][1] == server_group[1])
			    {
				printf("Successfully connected to server %d\n>", connected);
				success = 1;
				show_menu();
			    }
			  }
			  if (!success)
			  {
				printf("Server unavailable.  Please try again later.\n>");
				connected = 0;
				SP_leave(Mbox, sender);
			  }
			}
			else
			{ /*Membership message from chatroom.  Show users in chat */
			 /*No longer here*/ 
			}
                        if( Is_caused_join_mess( service_type ) )
                        {
                                //printf("Due to the JOIN of %s\n", memb_info.changed_member );
                        }else if( Is_caused_leave_mess( service_type ) ){
                                //printf("Due to the LEAVE of %s\n", memb_info.changed_member );
                        }else if( Is_caused_disconnect_mess( service_type ) ){
                                //printf("Due to the DISCONNECT of %s\n", memb_info.changed_member );
			        if (strncmp(sender, server_group, 2) == 0 && memb_info.changed_member[1] == server_group[1])
				{
				  printf("Disconnected from server %s\n", server_group);
				  SP_leave(Mbox, sender); /*Disconnect us from the server group */
				  if (chatroom != NULL)
				  {
				    sprintf(chatroom, "%s%d",chatroom, connected);
				    SP_leave(Mbox, chatroom);
				    chatroom[0]='\0';
				    chatroom_start = (struct node *)calloc(1,sizeof(struct node));
				  }
				  connected = 0; /*we are no longer connected */
				}
                        }else if( Is_caused_network_mess( service_type ) ){
                                //printf("Due to NETWORK change with %u VS sets\n", memb_info.num_vs_sets);
                                num_vs_sets = SP_get_vs_sets_info( mess, &vssets[0], MAX_VSSETS, &my_vsset_index );
                                if (num_vs_sets < 0) {
                                        printf("BUG: membership message has more then %d vs sets. Recompile with larger MAX_VSSETS\n", MAX_VSSETS);
                                        SP_error( num_vs_sets );
                                        exit( 1 );
                                }
                                for( i = 0; i < num_vs_sets; i++ )
                                {
                                        printf("%s VS set %d has %u members:\n",
                                               (i  == my_vsset_index) ?
                                               ("LOCAL") : ("OTHER"), i, vssets[i].num_members );
                                        ret = SP_get_vs_set_members(mess, &vssets[i], members, MAX_MEMBERS);
                                        if (ret < 0) {
                                                printf("VS Set has more then %d members. Recompile with larger MAX_MEMBERS\n", MAX_MEMBERS);
                                                SP_error( ret );
                                                exit( 1 );
                                        }
                                        for( j = 0; j < (int) vssets[i].num_members; j++ )
                                                printf("\t%s\n", members[j] );
                                }
                        }
		}
                
		else if( Is_transition_mess( service_type ) ) {
                        //printf("received TRANSITIONAL membership for group %s\n", sender );
                }else if ( Is_caused_leave_mess( service_type ) ){
                        //printf("received membership message that left group %s\n", sender );
		} else printf("Incorrect mess type");
		
        }  else if (Is_reject_mess( service_type)) {
		printf("Rejcted");
	}  else printf("Unknown");
        fflush(stdout);
}