static public void basic_packet_handling ( AutoBuffer ab ) throws java . io . IOException { // Randomly drop 1/10th of the packets, as-if broken network. Dropped // packets are timeline recorded before dropping - and we still will // respond to timelines and suicide packets. int drop = H2O . OPT_ARGS . random_udp_drop != null && RANDOM_UDP_DROP . nextInt ( 5 ) == 0 ? 2 : 0 ; // Record the last time we heard from any given Node TimeLine . record_recv ( ab , false , drop ) ; ab . _h2o . _last_heard_from = System . currentTimeMillis ( ) ; // Snapshots are handled *IN THIS THREAD*, to prevent more UDP packets from // being handled during the dump. Also works for packets from outside the // Cloud... because we use Timelines to diagnose Paxos failures. int ctrl = ab . getCtrl ( ) ; ab . getPort ( ) ; // skip the port bytes if ( ctrl == UDP . udp . timeline . ordinal ( ) ) { UDP . udp . timeline . _udp . call ( ab ) ; return ; } // Suicide packet? Short-n-sweet... if ( ctrl == UDP . udp . rebooted . ordinal ( ) ) UDPRebooted . checkForSuicide ( ctrl , ab ) ; // Drop the packet. if ( drop != 0 ) return ; // Get the Cloud we are operating under for this packet H2O cloud = H2O . CLOUD ; // Check cloud membership; stale ex-members are "fail-stop" - we mostly // ignore packets from them (except paxos packets). boolean is_member = cloud . contains ( ab . _h2o ) ; // Paxos stateless packets & ACKs just fire immediately in a worker // thread. Dups are handled by these packet handlers directly. No // current membership check required for Paxos packets if ( UDP . udp . UDPS [ ctrl ] . _paxos || is_member ) { H2O . submitTask ( new FJPacket ( ab , ctrl ) ) ; return ; } // Some non-Paxos packet from a non-member. Probably should record & complain. // Filter unknown-packet-reports. In bad situations of poisoned Paxos // voting we can get a LOT of these packets/sec, flooding the console. _unknown_packets_per_sec ++ ; long timediff = ab . _h2o . _last_heard_from - _unknown_packet_time ; if ( timediff > 1000 ) { Log . warn ( "UDP packets from outside the cloud: " + _unknown_packets_per_sec + "/sec, last one from " + ab . _h2o + " @ " + new Date ( ) ) ; _unknown_packets_per_sec = 0 ; _unknown_packet_time = ab . _h2o . _last_heard_from ; } ab . close ( ) ; }
- Timeline record it