private void handleFlushReconcile(Message msg) { Address requester = msg.getSrc(); Tuple<Collection<? extends Address>,Digest> tuple=readParticipantsAndDigest(msg.getRawBuffer(), msg.getOffset(),msg.getLength()); Digest reconcileDigest = tuple.getVal2(); if (log.isDebugEnabled()) log.debug(localAddress + ": received FLUSH_RECONCILE, passing digest to NAKACK " + reconcileDigest); // Let NAKACK reconcile missing messages down_prot.down(new Event(Event.REBROADCAST, reconcileDigest)); if (log.isDebugEnabled()) log.debug(localAddress + ": returned from FLUSH_RECONCILE, " + " sending RECONCILE_OK to " + requester); Message reconcileOk = new Message(requester).setFlag(Message.Flag.OOB, Message.Flag.INTERNAL) .putHeader(this.id,new FlushHeader(FlushHeader.FLUSH_RECONCILE_OK)); down_prot.down(reconcileOk); }
protected void getStateFromApplication(Address requester, Digest digest) { StateTransferInfo rsp=(StateTransferInfo)up_prot.up(new Event(Event.GET_APPLSTATE)); byte[] state=rsp.state; if(stats) { num_state_reqs.increment(); if(state != null) num_bytes_sent.add(state.length); avg_state_size=num_bytes_sent.doubleValue() / num_state_reqs.doubleValue(); } Message state_rsp=new Message(requester, state).putHeader(this.id, new StateHeader(StateHeader.STATE_RSP, digest)); log.trace("%s: sending state to %s (size=%s)", local_addr, state_rsp.getDest(), Util.printBytes(state != null? state.length : 0)); down_prot.down(state_rsp); }
@Override public void enableStats(boolean flag) { super.enableStats(flag); statsCollector.setStatsEnabled(flag); }
/** Returns a given protocol or null if not found */ public <T extends Protocol> T findProtocol(String name) { T tmp=(T)top_prot; String prot_name; while(tmp != null) { prot_name=tmp.getName(); if(Objects.equals(prot_name, name)) return tmp; tmp=tmp.getDownProtocol(); } return null; }
public void insertProtocolInStack(Protocol prot, Protocol neighbor, Position position) { // connect to the protocol layer below and above if(position == Position.BELOW) { prot.setUpProtocol(neighbor); Protocol below=neighbor.getDownProtocol(); prot.setDownProtocol(below); if(below != null) below.setUpProtocol(prot); neighbor.setDownProtocol(prot); } else { // ABOVE is default Protocol above=neighbor.getUpProtocol(); checkAndSwitchTop(neighbor, prot); prot.setUpProtocol(above); if(above != null) above.setDownProtocol(prot); prot.setDownProtocol(neighbor); neighbor.setUpProtocol(prot); } }
/** * Replaces one protocol instance with another. Should be done before the stack is connected * @param existing_prot * @param new_prot */ public void replaceProtocol(Protocol existing_prot, Protocol new_prot) throws Exception { Protocol up_neighbor=existing_prot.getUpProtocol(), down_neighbor=existing_prot.getDownProtocol(); new_prot.setUpProtocol(existing_prot.getUpProtocol()); new_prot.setDownProtocol(existing_prot.getDownProtocol()); up_neighbor.setDownProtocol(new_prot); if(down_neighbor != null) down_neighbor.setUpProtocol(new_prot); existing_prot.setDownProtocol(null); existing_prot.setUpProtocol(null); existing_prot.stop(); existing_prot.destroy(); if(new_prot.getUpProtocol() == this) top_prot=new_prot; callAfterCreationHook(new_prot, afterCreationHook()); new_prot.init(); }
public Object down(Event evt) { switch(evt.getType()) { case Event.VIEW_CHANGE: Object retval=down_prot.down(evt); View view=evt.getArg(); members.addAll(view.getMembers()); bcast_task.adjustSuspectedMembers(members); computePingDest(null); if(view.size() <= 1) stopMonitor(); else if(!isMonitorRunning()) FdHeader hdr=new FdHeader(FdHeader.UNSUSPECT); hdr.mbrs=new ArrayList<>(); hdr.mbrs.add(evt.getArg()); hdr.from=local_addr; Message unsuspect_msg=new Message().setFlag(Message.Flag.INTERNAL).putHeader(id, hdr); log.trace("%s: broadcasting UNSUSPECT message (mbrs=%s)", local_addr, hdr.mbrs); down_prot.down(unsuspect_msg); break; break; return down_prot.down(evt);
@Override public void members(List<PingData> mbrs) { PhysicalAddress own_physical_addr=(PhysicalAddress)down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr)); PingData data=new PingData(local_addr, false, org.jgroups.util.NameCache.get(local_addr), own_physical_addr); PingHeader hdr=new PingHeader(PingHeader.GET_MBRS_REQ).clusterName(cluster_name); Set<PhysicalAddress> physical_addrs=mbrs.stream().filter(ping_data -> ping_data != null && ping_data.getPhysicalAddr() != null) .map(PingData::getPhysicalAddr).collect(Collectors.toSet()); for(PhysicalAddress physical_addr: physical_addrs) { if(physical_addr != null && own_physical_addr.equals(physical_addr)) // no need to send the request to myself continue; // the message needs to be DONT_BUNDLE, see explanation above final Message msg=new Message(physical_addr).setFlag(Message.Flag.INTERNAL, Message.Flag.DONT_BUNDLE, Message.Flag.OOB) .putHeader(this.id, hdr).setBuffer(marshal(data)); log.trace("%s: sending discovery request to %s", local_addr, msg.getDest()); down_prot.down(msg); } }
protected void sendResponse(Address dest, short id) { try { RsvpHeader hdr=new RsvpHeader(RsvpHeader.RSP,id); Message msg=new Message(dest) .putHeader(this.id, hdr) .setFlag(Message.Flag.RSVP, Message.Flag.INTERNAL, Message.Flag.DONT_BUNDLE, Message.Flag.OOB); if(log.isTraceEnabled()) log.trace(local_addr + ": " + hdr.typeToString() + " --> " + dest); down_prot.down(msg); } catch(Throwable t) { log.error(Util.getMessage("FailedSendingResponse"), t); } }
protected void sendCredit(Address dest, long credits) { if(log.isTraceEnabled()) log.trace("sending %d credits to %s", credits, dest); Message msg=new Message(dest, longToBuffer(credits)) .setFlag(Message.Flag.OOB, Message.Flag.INTERNAL, Message.Flag.DONT_BUNDLE) .putHeader(this.id,getReplenishHeader()); down_prot.down(msg); num_credit_responses_sent++; }
protected void send(Address dest, Request req) { Message msg=new Message(dest, Util.streamableToBuffer(req)).putHeader(id, new LockingHeader()); if(bypass_bundling) msg.setFlag(Message.Flag.DONT_BUNDLE); log.trace("%s --> %s: %s", local_addr, dest == null? "ALL" : dest, req); try { down_prot.down(msg); } catch(Exception ex) { log.error("%s: failed sending %s request: %s", local_addr, req.type, ex); } }
/** Sends a retransmit request to the given sender */ protected void retransmit(SeqnoList missing, Address sender) { Message xmit_msg=new Message(sender).setBuffer(Util.streamableToBuffer(missing)) .setFlag(Message.Flag.OOB, Message.Flag.INTERNAL).putHeader(id, UnicastHeader3.createXmitReqHeader()); if(is_trace) log.trace("%s: sending XMIT_REQ (%s) to %s", local_addr, missing, sender); down_prot.down(xmit_msg); xmit_reqs_sent.add(missing.size()); }
/** send client's public key to server and request server's public key */ protected void sendKeyRequest(Address key_server) { if(key_server == null) return; if(last_key_request == 0 || System.currentTimeMillis() - last_key_request > min_time_between_key_requests) last_key_request=System.currentTimeMillis(); else return; if(use_external_key_exchange) { log.debug("%s: asking key exchange protocol to get secret key from %s", local_addr, key_server); down_prot.down(new Event(Event.FETCH_SECRET_KEY, key_server)); return; } log.debug("%s: asking %s for the secret key (my version: %s)", local_addr, key_server, Util.byteArrayToHexString(sym_version)); Message newMsg=new Message(key_server, key_pair.getPublic().getEncoded()).src(local_addr) .putHeader(this.id,new EncryptHeader(EncryptHeader.SECRET_KEY_REQ, null)); down_prot.down(newMsg); }
public Object down(Event evt) { switch(evt.getType()) { case Event.TMP_VIEW: case Event.VIEW_CHANGE: List<Address> new_members=((View)evt.getArg()).getMembers(); synchronized(members) { members.clear(); if(new_members != null && !new_members.isEmpty()) members.addAll(new_members); } return down_prot.down(evt); } return down_prot.down(evt); // Pass on to the layer below us }
protected void handleEvent(Event evt) { switch(evt.getType()) { case Event.VIEW_CHANGE: View old_view=view, new_view=evt.getArg(); this.view=new_view; if(old_view == null) { // first join Util.sleepRandom(0, stagger_timeout); // 1. send my own mapping to all multicastOwnMapping(); // 2. ask the coordinator to send us the cache contents Address coord=new_view.getCoord(); if(Objects.equals(local_addr, coord)) return; Message msg=new Message(coord).setFlag(Message.Flag.OOB).putHeader(id, new Header(Type.CACHE_REQ)); down_prot.down(msg); return; } if(new_view instanceof MergeView) { Util.sleepRandom(0, stagger_timeout); multicastOwnMapping(); } break; case Event.SET_LOCAL_ADDRESS: local_addr=evt.getArg(); break; } }
protected void broadcastUnuspectMessage(Address mbr) { if(mbr == null) return; log.debug("%s: broadcasting unsuspect(%s)", local_addr, mbr); // 1. Send a SUSPECT message right away; the broadcast task will take some time to send it (sleeps first) FdHeader hdr=new FdHeader(FdHeader.UNSUSPECT).mbrs(Collections.singleton(mbr)); Message suspect_msg=new Message().setFlag(Message.Flag.INTERNAL).putHeader(this.id, hdr); down_prot.down(suspect_msg); }
protected void send(Address dest, Buffer buffer) { try { Message rsp_msg=new Message(dest, buffer).putHeader(id, new CounterHeader()); if(bypass_bundling) rsp_msg.setFlag(Message.Flag.DONT_BUNDLE); down_prot.down(rsp_msg); } catch(Exception ex) { log.error(Util.getMessage("FailedSendingMessageTo") + dest + ": " + ex); } }
protected void handleSecretKeyRequest(PublicKey dh_public_key, Address sender) throws Exception { KeyPair kp=key_pair_gen.generateKeyPair(); PrivateKey private_key=kp.getPrivate(); PublicKey public_key_rsp=kp.getPublic(); // sent back as part of the response byte[] version; byte[] encrypted_secret_key; log.debug("%s: received public key %s.. from %s", local_addr, print16(dh_public_key), sender); synchronized(this) { key_agreement.init(private_key); key_agreement.doPhase(dh_public_key, true); // Diffie-Hellman secret session key, to encrypt secret key byte[] secret_session_key=key_agreement.generateSecret(); SecretKey hashed_session_key=hash(secret_session_key); Cipher encrypter=Cipher.getInstance(secret_key_algorithm); encrypter.init(Cipher.ENCRYPT_MODE, hashed_session_key); Tuple<SecretKey,byte[]> tuple=(Tuple<SecretKey,byte[]>)up_prot.up(new Event(Event.GET_SECRET_KEY)); SecretKey secret_key=tuple.getVal1(); version=tuple.getVal2(); encrypted_secret_key=encrypter.doFinal(secret_key.getEncoded()); } log.debug("%s: sending public key rsp %s.. to %s", local_addr, print16(public_key_rsp), sender); // send response to sender with public_key_rsp, encrypted secret key and secret key version Message rsp=new Message(sender) .putHeader(id, DhHeader.createSecretKeyResponse(public_key_rsp.getEncoded(), encrypted_secret_key, version)); down_prot.down(rsp); }
@SuppressWarnings("unchecked") private void onResume(Event evt) { List<Address> members =evt.getArg(); long viewID = currentViewId(); boolean isParticipant = false; synchronized(sharedLock) { isParticipant = flushMembers.contains(localAddress) || (members != null && members.contains(localAddress)); } if (members == null || members.isEmpty()) { Message msg = new Message(null).src(localAddress); // Cannot be OOB since START_FLUSH is not OOB // we have to FIFO order two subsequent flushes if (log.isDebugEnabled()) log.debug(localAddress + ": received RESUME, sending STOP_FLUSH to all"); msg.putHeader(this.id, new FlushHeader(FlushHeader.STOP_FLUSH, viewID)); down_prot.down(msg); } else { for (Address address : members) { Message msg = new Message(address).src(localAddress); // Cannot be OOB since START_FLUSH is not OOB // we have to FIFO order two subsequent flushes if (log.isDebugEnabled()) log.debug(localAddress + ": received RESUME, sending STOP_FLUSH to " + address); msg.putHeader(this.id, new FlushHeader(FlushHeader.STOP_FLUSH, viewID)); down_prot.down(msg); } } if(isParticipant) waitForUnblock(); }
public Object down(Message msg) { if(msg.getSrc() == null) msg.setSrc(local_addr); Buffer serialized_msg=Util.streamableToBuffer(msg); // exclude existing headers, they will be seen again when we unmarshal the message at the receiver Message tmp=msg.copy(false, false).setBuffer(serialized_msg); return down_prot.down(tmp); }