static void Print_help(void) { Alarmp( SPLOG_FATAL, SYSTEM, "Usage: spread\n%s\n%s\n%s\n", "\t[-l y/n] : print log", "\t[-n <proc name>] : force computer name", "\t[-c <file name>] : specify configuration file" ); }
static void Usage(int argc, char *argv[]) { My_name = 0; /* NULL */ Log = 0; strcpy( Config_file, "spread.conf" ); while( --argc > 0 ) { argv++; if( !strncmp( *argv, "-n", 2 ) ) { if (argc < 2) Print_help(); if( strlen( argv[1] ) > MAX_PROC_NAME-1 ) /* -1 for the null */ Alarmp( SPLOG_FATAL, SYSTEM, "Usage: proc name %s too long\n", argv[1] ); memcpy( My_name_buf, argv[1], strlen( argv[1] ) ); My_name = My_name_buf; argc--; argv++; }else if( !strncmp( *argv, "-c", 2 ) ){ if (argc < 2) Print_help(); strcpy( Config_file, argv[1] ); argc--; argv++; }else if( !strncmp( *argv, "-l", 2 ) ){ if (argc < 2) Print_help(); if( !strcmp( argv[1], "y" ) ) Log = 1; else if( !strcmp( argv[1], "n" ) ) Log = 0; else Print_help(); argc--; argv++; }else{ Print_help(); } } }
int main(int argc, char *argv[]) { #ifdef ARCH_PC_WIN95 int ret; #endif #ifndef ARCH_PC_WIN95 struct group *grp; struct passwd *pwd; #endif Alarm_set_types( CONF_SYS ); Alarm_set_priority( SPLOG_INFO ); Alarmp( SPLOG_PRINT, SYSTEM, "/===========================================================================\\\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| The Spread Toolkit. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Copyright (c) 1993-2013 Spread Concepts LLC |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| All rights reserved. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| The Spread toolkit is licensed under the Spread Open-Source License. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| You may only use this software in compliance with the License. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| A copy of the license can be found at http://www.spread.org/license |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| This product uses software developed by Spread Concepts LLC for use |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| in the Spread toolkit. For more information about Spread, |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| see http://www.spread.org |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| This software is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| ANY KIND, either express or implied. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Creators: |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Yair Amir [email protected] |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Michal Miskin-Amir [email protected] |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Jonathan Stanton [email protected] |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| John Schultz [email protected] |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Major Contributors: |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Ryan Caudy [email protected] - contribution to process groups.|\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Claudiu Danilov [email protected] - scalable, wide-area support. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Cristina Nita-Rotaru [email protected] - GC security. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Theo Schlossnagle [email protected] - Perl, autoconf, old skiplist. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Dan Schoenblum [email protected] - Java interface. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Special thanks to the following for discussions and ideas: |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Ken Birman, Danny Dolev, Jacob Green, Mike Goodrich, Ben Laurie, |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| David Shaw, Gene Tsudik, Robbert VanRenesse. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Partial funding provided by the Defense Advanced Research Project Agency |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| (DARPA) and the National Security Agency (NSA) 2000-2004. The Spread |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| toolkit is not necessarily endorsed by DARPA or the NSA. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| For a full list of contributors, see Readme.txt in the distribution. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| WWW: www.spread.org www.spreadconcepts.com |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Contact: [email protected] |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Version %d.%02d.%02d Built %-17s |\n", (int)SP_MAJOR_VERSION, (int)SP_MINOR_VERSION, (int)SP_PATCH_VERSION, Spread_build_date ); Alarmp( SPLOG_PRINT, SYSTEM, "\\===========================================================================/\n"); Usage( argc, argv ); #ifdef ARCH_PC_WIN95 ret = WSAStartup( MAKEWORD(1,1), &WSAData ); if( ret != 0 ) Alarmp( SPLOG_FATAL, NETWORK, "Spread: winsock initialization error %d\n", ret ); #endif /* ARCH_PC_WIN95 */ /* initialize each valid authentication protocol */ null_init(); ip_init(); #ifdef ENABLE_PASSWORD pword_init(); #endif permit_init(); /* Initialize Access Control & Authentication */ Acm_init(); Conf_init( Config_file, My_name ); E_init(); #ifndef ARCH_PC_WIN95 /* Verify that unix socket dir is safe if runing as root user */ if (geteuid() == (uid_t) 0) { struct stat usock_stat; Alarmp( SPLOG_INFO, SECURITY, "Spread is running as root so check file locations\n"); if (stat( SP_UNIX_SOCKET, &usock_stat)) { Alarmp( SPLOG_FATAL, SECURITY, "Spread unable to stat the unix domain socket dir (%s). Please verify the selected directory and restart the daemon\n", SP_UNIX_SOCKET ); exit( 0 ); } if ( (usock_stat.st_mode & S_IWOTH) || !(usock_stat.st_uid == (uid_t) 0) ) Alarmp( SPLOG_WARNING, PRINT, "Spread: SECURITY RISK! running as root, but unix domain socket is not in a root-only writable directory. May risk denial of service or malicious deletion of unexpected file in directory: %s\n", SP_UNIX_SOCKET ); } #endif Sess_init(); Stat_init(); if( Log ) Log_init(); #ifndef ARCH_PC_WIN95 /* Yupp, we're paranoid */ if (geteuid() != (uid_t) 0) { Alarmp( SPLOG_WARNING, SECURITY, "Spread: not running as root, won't chroot\n" ); } else if ( (grp = getgrnam(Conf_get_group())) == NULL || (pwd = getpwnam(Conf_get_user())) == NULL ) { Invalid_privilege_decrease(Conf_get_user(), Conf_get_group()); } else if (chdir(Conf_get_runtime_dir()) < 0 || chroot(Conf_get_runtime_dir()) < 0 ) { Alarmp( SPLOG_FATAL, SECURITY, "Spread: FAILED chroot to '%s'\n", Conf_get_runtime_dir() ); } else if ( setgroups(1, &grp->gr_gid) < 0 || setgid(grp->gr_gid) < 0 || setuid(pwd->pw_uid) < 0) { Invalid_privilege_decrease(Conf_get_user(), Conf_get_group()); } else { Alarmp( SPLOG_INFO, SECURITY, "Spread: setugid and chroot successeful\n" ); } #endif /* ARCH_PC_WIN95 */ E_handle_events(); return 0; }
static void Invalid_privilege_decrease(char *user, char *group) { Alarmp( SPLOG_FATAL, SECURITY, "Spread: FAILED privilege drop to user/group " "'%s/%s' (defined in spread.conf or spread_params.h)\n", user, group ); }
void Prot_handle_token(channel fd, int dummy, void *dummy_p) { int new_ptr; int num_retrans, num_allowed, num_sent; int flow_control; char *new_rtr; ring_rtr *ring_rtr_ptr; int32 rtr_proc_id; int16 rtr_seg_index; int32 val; int retrans_allowed; /* how many of my retrans are allowed on token */ int i, ret; /* int r1,r2;*/ ret = Net_recv_token( fd, &New_token ); /* from another monitor component */ if( ret == 0 ) return; /* delete random r1 = ((-My.id)%17)+3; r2 = get_rand() % (r1+3 ); if ( r2 == 0 ) return; */ Alarm( DEBUG, "Received Token\n"); /* check if it is a regular token */ if( Is_form( Token->type ) ) { Alarm(PROTOCOL, "it is a Form Token.\n"); Memb_handle_token( &New_token ); return; } /* The Veto property for tokens - swallow this token */ if( ! Memb_token_alive() ) { Alarm(PROTOCOL, "Prot_handle_token: Veto Property. Memb not alive.\n"); return; } if( ret != sizeof(token_header) + Token->rtr_len ) { Alarm( PRINT, "Prot_handle_token: recv token len is %d, should be %d\n", ret,sizeof(token_header) + Token->rtr_len ); return; } if( !Same_endian( Token->type ) ) Flip_token_body( New_token.elements[1].buf, Token ); /* Deal with wrapping seq values (2^32) by triggering a membership by dropping the token */ if( (Memb_state() != EVS ) && (Token->seq > MAX_WRAP_SEQUENCE_VALUE ) ) { Alarm( PRINT, "Prot_handle_token: Token Sequence number (%ld) approaching 2^31 so trigger membership to reset it.\n", Token->seq); return; } if( Conf_leader( Memb_active_ptr() ) == My.id ) { if( Get_arq(Token->type) != Get_arq(Last_token->type) ) { Alarm( PROTOCOL, "Prot_handle_token: leader swallowing token %d %d %d\n", Get_arq(Token->type),Get_retrans(Token->type),Get_arq(Last_token->type) ); /* received double token - swallow it */ return; } }else{ if( Get_arq(Token->type) == Get_arq(Last_token->type) ) { if( Get_retrans(Token->type) > Get_retrans(Last_token->type) ) { val = Get_retrans(Token->type); Last_token->type = Set_retrans(Last_token->type,val); /* asked to send token again (almost lost) */ Alarm( PROTOCOL, "Prot_handle_token: not leader, asked to retrans %d %d\n", Get_arq(Token->type), val ); Prot_token_hurry(); }else{ Alarm( PROTOCOL, "Prot_handle_token: not leader, swallow same token %d %d\n", Get_arq(Token->type), Get_retrans(Token->type) ); } return; } else if ( Get_arq(Token->type) != ( ( Get_arq( Last_token->type ) + 1 ) % 0x10 ) ) { Alarm( PROTOCOL, "Prot_handle_token: not leader, swallowing very outdated token: ARQ(%d) RETRANS(%d) vs. Last ARQ(%d)\n", Get_arq(Token->type), Get_retrans(Token->type), Get_arq(Last_token->type) ); return; } else { if ( Get_retrans(Token->type) > 0 ) { GlobalStatus.token_hurry++; } } } if( Highest_seq < Token->seq ) Highest_seq = Token->seq; /* Handle retransmissions */ num_retrans = Answer_retrans( &new_ptr, &rtr_proc_id, &rtr_seg_index ); GlobalStatus.retrans += num_retrans; new_rtr = New_token.elements[1].buf; /* Handle new packets */ flow_control = (int) Token->flow_control; num_allowed = FC_allowed( flow_control, num_retrans ); num_sent = Send_new_packets( num_allowed ); GlobalStatus.packet_sent += num_sent; /* Flow control calculations */ Token->flow_control = Token->flow_control - Last_num_retrans - Last_num_sent + num_retrans + num_sent; Last_num_retrans = num_retrans; Last_num_sent = num_sent; /* Prepare my retransmission requests */ for( i = My_aru+1; i <= Highest_seq; i++ ) { if( ! Packets[i & PACKET_MASK].exist ) break; My_aru++; } GlobalStatus.my_aru = My_aru; if( My_aru < Highest_seq ) { /* Compute how many of my retransmission requests are possible to fit */ retrans_allowed = ( sizeof( token_body ) - new_ptr - sizeof( ring_rtr ) ) / sizeof( int32 ); if( retrans_allowed > 1 ) { ring_rtr_ptr = (ring_rtr *)&new_rtr[new_ptr]; ring_rtr_ptr->memb_id = Memb_id(); ring_rtr_ptr->proc_id = rtr_proc_id; ring_rtr_ptr->seg_index = rtr_seg_index; ring_rtr_ptr->num_seq = 0; new_ptr += sizeof(ring_rtr); for( i=My_aru+1; i <= Highest_seq && retrans_allowed > 0; i++, retrans_allowed-- ) { if( ! Packets[i & PACKET_MASK].exist ) { memcpy( &new_rtr[new_ptr], &i, sizeof(int32) ); new_ptr += sizeof(int32); ring_rtr_ptr->num_seq++; } } } } if( Memb_state() == EVS ) { if( My_aru == Highest_seq ) { My_aru = Last_seq; Memb_commit(); } } Token->rtr_len = new_ptr; New_token.elements[1].len = new_ptr; /* Calculating Token->aru and Set_aru */ if( ( Token->aru == Set_aru ) || ( Token->aru_last_id == My.id ) || ( Token->aru == Token->seq ) ) { Token->aru = My_aru; Token->aru_last_id = My.id; if( My_aru < Highest_seq ) Set_aru = My_aru; else Set_aru = -1; }else if( Token->aru > My_aru ) { Token->aru = My_aru; Token->aru_last_id = My.id; Set_aru = My_aru; }else{ Set_aru = -1; } Token->proc_id = My.id; if( Memb_state() != EVS ) Token->seq = Highest_seq; if( Conf_leader( Memb_active_ptr() ) == My.id ) { val = Get_arq( Token->type ); val = (val + 1)% 0x10; Token->type = Set_arq( Token->type, val ); Token->type = Set_retrans( Token->type, 0 ); } /* Send token */ if( ! ( Conf_leader( Memb_active_ptr() ) == My.id && To_hold_token() ) ) { /* sending token */ Net_send_token( &New_token ); /* ### Bug fix for SGIs */ #ifdef ARCH_SGI_IRIX Net_send_token( &New_token ); #endif /* ARCH_SGI_IRIX */ if( Get_retrans( Token->type ) > 1 ) { /* problems */ Net_send_token( &New_token ); Net_send_token( &New_token ); } } Token_rounds++; if( Conf_leader( Memb_active_ptr() ) == My.id ) E_queue( Prot_token_hurry, 0, NULL, Hurry_timeout ); E_queue( Memb_token_loss, 0, NULL, Token_timeout ); /* calculating Aru */ if( Token->aru > Last_token->aru ) Aru = Last_token->aru; else Aru = Token->aru; if( Highest_seq == Aru ) Token_counter++; else Token_counter = 0; dispose( Last_token ); Last_token = Token; New_token.elements[0].buf = (char *) new(TOKEN_HEAD_OBJ); New_token.elements[1].len = sizeof(token_body); Token = (token_header *)New_token.elements[0].buf; /* Deliver & discard packets */ Discard_packets(); Deliver_agreed_packets(); Deliver_reliable_packets( Highest_seq-num_sent+1, num_sent ); if( Memb_state() == EVS && Token_rounds > MAX_EVS_ROUNDS ) { Alarmp( SPLOG_ERROR, PRINT, "Prot_handle_token: BUG WORKAROUND: Too many rounds in EVS state; swallowing token; state:\n" ); Alarmp( SPLOG_ERROR, PRINT, "\tAru: %d\n", Aru ); Alarmp( SPLOG_ERROR, PRINT, "\tMy_aru: %d\n", My_aru ); Alarmp( SPLOG_ERROR, PRINT, "\tHighest_seq: %d\n", Highest_seq ); Alarmp( SPLOG_ERROR, PRINT, "\tHighest_fifo_seq: %d\n", Highest_fifo_seq ); Alarmp( SPLOG_ERROR, PRINT, "\tLast_discarded: %d\n", Last_discarded ); Alarmp( SPLOG_ERROR, PRINT, "\tLast_delivered: %d\n", Last_delivered ); Alarmp( SPLOG_ERROR, PRINT, "\tLast_seq: %d\n", Last_seq ); Alarmp( SPLOG_ERROR, PRINT, "\tToken_rounds: %d\n", Token_rounds ); Alarmp( SPLOG_ERROR, PRINT, "Last Token:\n" ); Alarmp( SPLOG_ERROR, PRINT, "\ttype: 0x%x\n", Last_token->type ); Alarmp( SPLOG_ERROR, PRINT, "\ttransmiter_id: %d\n", Last_token->transmiter_id ); Alarmp( SPLOG_ERROR, PRINT, "\tseq: %d\n", Last_token->seq ); Alarmp( SPLOG_ERROR, PRINT, "\tproc_id: %d\n", Last_token->proc_id ); Alarmp( SPLOG_ERROR, PRINT, "\taru: %d\n", Last_token->aru ); Alarmp( SPLOG_ERROR, PRINT, "\taru_last_id: %d\n", Last_token->aru_last_id ); Alarmp( SPLOG_ERROR, PRINT, "\tflow_control: %d\n", Last_token->flow_control ); Alarmp( SPLOG_ERROR, PRINT, "\trtr_len: %d\n", Last_token->rtr_len ); Alarmp( SPLOG_ERROR, PRINT, "\tconf_hash: %d\n", Last_token->conf_hash ); Memb_token_loss(); } GlobalStatus.highest_seq = Highest_seq; GlobalStatus.aru = Aru; GlobalStatus.token_rounds = Token_rounds; }
void Discard_packets() { int pack_entry; packet_body *body_ptr; up_queue *up_ptr; int proc_index; int i; if( Aru <= Last_discarded ) return; if( Memb_state() == EVS ) { int found_hole; membership_id reg_memb_id; if( Aru != Last_seq ) return; /* Deliver packets that must be delivered before the transitional signal. * Those up to the Aru for my old ring were delivered in Read_form2(). * So, it remains to deliver all packets up to the first hole or the first * SAFE message. */ Alarmp( SPLOG_INFO, PROTOCOL, "Discard_packets: delivering messages after old ring Aru before transitional\n" ); for( i = Last_discarded+1; i <= Highest_seq; i++ ) { pack_entry = i & PACKET_MASK; if( ! Packets[pack_entry].exist ) Alarmp( SPLOG_FATAL, PROTOCOL, "Discard_packets: (EVS before transitional) packet %d not exist\n", i); if( Packets[pack_entry].exist == 3 ) { Alarmp( SPLOG_INFO, PROTOCOL, "Discard_packets: Found first Hole in %d\n", i); break; } if( Is_safe( Packets[pack_entry].head->type ) ) { Alarmp( SPLOG_INFO, PROTOCOL, "Discard_packets: Found first SAFE message in %d", i); break; } /* should deliver packet or dispose the body if it was delivered already */ if( Packets[pack_entry].exist == 1 ){ Deliver_packet( pack_entry, 0 ); } else { dispose( Packets[pack_entry].body ); } /* dispose packet header in any case */ dispose( Packets[pack_entry].head ); Alarmp( SPLOG_INFO, PROTOCOL, "Discard_packets: delivering %d in EVS\n",i); Packets[pack_entry].exist = 0; Last_discarded = i; } /* calculate and deliver transitional membership */ Alarmp( SPLOG_INFO, PROTOCOL, "Discard_packets: Delivering transitional membership\n" ); Memb_transitional(); Sess_deliver_trans_memb( Trans_membership, Memb_trans_id() ); /* deliver all remaining packets for EVS */ found_hole = 0; for( i = Last_discarded+1; i <= Highest_seq; i++ ) { pack_entry = i & PACKET_MASK; if( ! Packets[pack_entry].exist ) Alarm( EXIT, "Discard_packets: (EVS after transitional) packet %d not exist\n", i); if( Packets[pack_entry].exist == 3 ) { /* * There is a hole! * from here, we need to check if the proc_id of the packet * is in commited membership. */ found_hole = 1; Alarm( PROTOCOL, "Discard_packets: Found a Hole in %d \n",i); }else if( (!found_hole) || (Conf_id_in_conf( &Commit_membership, Packets[pack_entry].head->proc_id ) != -1) ){ /* should deliver packet or dispose the body if it was delivered already */ if( Packets[pack_entry].exist == 1 ){ Deliver_packet( pack_entry, 0 ); }else{ dispose( Packets[pack_entry].body ); } /* dispose packet header in any case */ dispose( Packets[pack_entry].head ); Alarm( PROTOCOL, "Discard_packets: delivering %d in EVS\n",i); }else{ /* should not deliver packet */ dispose( Packets[pack_entry].head ); dispose( Packets[pack_entry].body ); Alarm( PROTOCOL, "Discard_packets: Due to hole, not delivering %d \n",i); } Packets[pack_entry].exist = 0; } /* check up_queue and down_queue */ if( Down_queue_ptr->num_mess > 0 ) { Down_queue_ptr->cur_element = 0; } for( proc_index=0; proc_index < MAX_PROCS_RING; proc_index++ ) { if( Up_queue[proc_index].exist ) { if( proc_index != My_index ) { /* * dispose only packets that are not mine * my packets will stay in Down_queue if the message is not * ready to be delivered (because not fully sent yet) * so we need not to dispose them! */ up_ptr = &Up_queue[proc_index]; for( i=0; i < up_ptr->mess->num_elements; i++ ) { body_ptr = (packet_body *)up_ptr->mess->elements[i].buf; dispose( body_ptr ); } } dispose( Up_queue[proc_index].mess ); Up_queue[proc_index].exist = 0; } } /* calculate and deliver regular membership */ Memb_regular(); Log_membership(); reg_memb_id = Memb_id(); Sess_deliver_reg_memb( Reg_membership, reg_memb_id ); /* If in change conf mode; then if singleton (which should be true) and GOP state then: * Remove partition * Initiate Memb_lookup() to find other daemons */ if( Conf_in_reload_singleton_state() ) { /* GOP state equals value 1, but is private declaration in groups.c */ if ( (GlobalStatus.gstate != 1 ) || ( Conf_num_procs( &Reg_membership ) != 1 ) ) { Alarmp( SPLOG_FATAL, MEMB, "Discard_packets: Failed to reload configuration - gstate: %d and num_procs in membership: %d\n", GlobalStatus.gstate, Conf_num_procs( &Reg_membership) ); } Net_clear_partition(); E_queue( Memb_lookup_new_members, 0, NULL, Zero_timeout); Conf_reload_singleton_state_end(); } /* set variables for next membership */ if ( Conf_debug_initial_sequence() ) { Last_token->aru = INITIAL_SEQUENCE_NEAR_WRAP; Highest_seq = INITIAL_SEQUENCE_NEAR_WRAP; Highest_fifo_seq = INITIAL_SEQUENCE_NEAR_WRAP; My_aru = INITIAL_SEQUENCE_NEAR_WRAP; Aru = INITIAL_SEQUENCE_NEAR_WRAP; Set_aru = INITIAL_SEQUENCE_NEAR_WRAP -1; Last_discarded = INITIAL_SEQUENCE_NEAR_WRAP; Last_delivered = INITIAL_SEQUENCE_NEAR_WRAP; } else { Last_token->aru = 0; Highest_seq = 0; Highest_fifo_seq = 0; My_aru = 0; Aru = 0; Set_aru = -1; Last_discarded = 0; Last_delivered = 0; } GlobalStatus.my_aru = My_aru; Token_counter = 0; }else{ for( i = Last_discarded+1; i <= Aru; i++ ) { pack_entry = i & PACKET_MASK; if( ! Packets[pack_entry].exist ) Alarm( EXIT, "Discard_packets: (NOT EVS) packet %d not exist\n",i); /* should deliver packet or dispose the body if it was delivered already */ if( Packets[pack_entry].exist == 1 ) Deliver_packet( pack_entry, 0 ); else dispose( Packets[pack_entry].body ); /* dispose packet header in any case */ dispose( Packets[pack_entry].head ); Packets[pack_entry].exist = 0; } Alarm( PROTOCOL, "Discard_packets: packets %d-%d were discarded\n", Last_discarded+1, Aru ); Last_discarded = Aru; if( Last_delivered < Last_discarded ) Last_delivered = Last_discarded; } }
int main( int argc, char *argv[] ) { int i; #ifdef _REENTRANT int ret; #endif fclose(stderr); Alarm_set_types( NONE ); Alarmp( SPLOG_PRINT, SYSTEM, "/===========================================================================\\\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| The Spread Toolkit. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Copyright (c) 1993-2014 Spread Concepts LLC |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| All rights reserved. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| The Spread package is licensed under the Spread Open-Source License. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| You may only use this software in compliance with the License. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| A copy of the license can be found at http://www.spread.org/license |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| This product uses software developed by Spread Concepts LLC for use |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| in the Spread toolkit. For more information about Spread, |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| see http://www.spread.org |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| This software is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| ANY KIND, either express or implied. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Creators: |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Yair Amir [email protected] |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Michal Miskin-Amir [email protected] |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Jonathan Stanton [email protected] |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| John Schultz [email protected] |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Contributors: |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Amy Babay [email protected] - accelerated ring protocol. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Ryan Caudy [email protected] - contribution to process groups.|\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Claudiu Danilov [email protected] - scalable, wide-area support. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Cristina Nita-Rotaru [email protected] - GC security. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Theo Schlossnagle [email protected] - Perl, autoconf, old skiplist |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Dan Schoenblum [email protected] - Java Interface Developer. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Special thanks to the following for discussions and ideas: |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Ken Birman, Danny Dolev, Jacob Green, Mike Goodrich, Ben Laurie, |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| David Shaw, Gene Tsudik, Robbert VanRenesse. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Partial funding provided by the Defense Advanced Research Project Agency |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| (DARPA) and the National Security Agency (NSA) 2000-2004. The Spread |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| toolkit is not necessarily endorsed by DARPA or the NSA. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| For a full list of contributors, see Readme.txt in the distribution. |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| WWW: www.spread.org www.spreadconcepts.com |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Contact: [email protected] |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| |\n"); Alarmp( SPLOG_PRINT, SYSTEM, "| Version %d.%02d.%02d Built %-17s |\n", (int)SP_MAJOR_VERSION, (int)SP_MINOR_VERSION, (int)SP_PATCH_VERSION, Spread_build_date ); Alarmp( SPLOG_PRINT, SYSTEM, "\\===========================================================================/\n"); #ifdef ARCH_PC_WIN95 ret = WSAStartup( MAKEWORD(2,0), &WSAData ); if( ret != 0 ) Alarm( EXIT, "sptmonitor: main: winsock initialization error %d\n", ret ); #endif /* ARCH_PC_WIN95 */ Usage( argc, argv ); Alarm_set_interactive(); read_configuration(); initialize_locks(); for( i=0; i < Conf_num_procs( &Cn ); i++ ) Partition[i] = 0; for( i=0; i < Conf_num_procs( &Cn ); i++ ) Status_vector[i] = 0; Pack_scat.elements[0].len = sizeof( packet_header ); Pack_scat.elements[0].buf = (char *)&Pack; Pack.proc_id = My.id; Pack.seq = My_port; Pack.memb_id.proc_id = 15051963; Report_scat.num_elements = 2; Report_scat.elements[0].buf = (char *)&Report_pack; Report_scat.elements[0].len = sizeof(packet_header); Report_scat.elements[1].buf = (char *)&GlobalStatus; Report_scat.elements[1].len = sizeof(status); SendChan = DL_init_channel( SEND_CHANNEL , My_port, 0, 0 ); Report_socket = DL_init_channel( RECV_CHANNEL, My_port, 0, 0 ); E_init(); /* both reentrent and non-reentrant code uses events */ #ifndef _REENTRANT E_attach_fd( 0, READ_FD, User_command, 0, NULL, LOW_PRIORITY ); E_attach_fd( Report_socket, READ_FD, Report_message, 0, NULL, HIGH_PRIORITY ); #endif /* _REENTRANT */ Print_menu(); #ifdef _REENTRANT #ifndef ARCH_PC_WIN95 ret = pthread_create( &Read_thread, NULL, Read_thread_routine, 0 ); ret = pthread_create( &Status_thread, NULL, Status_send_thread_routine, 0 ); ret = pthread_create( &Partition_thread, NULL, Partition_send_thread_routine, 0 ); #else /* ARCH_PC_WIN95 */ Read_thread = CreateThread( NULL, 0, Read_thread_routine, NULL, 0, &ret ); Status_thread = CreateThread( NULL, 0, Status_send_thread_routine, NULL, 0, &ret ); Partition_thread = CreateThread( NULL, 0, Partition_send_thread_routine, NULL, 0, &ret ); #endif /* ARCH_PC_WIN95 */ for(;;) { User_command(); } #else /*! _REENTRANT */ E_handle_events(); #endif /* _REENTRANT */ return 0; }