code: public Object up(Message msg) {
          // If we have a join or merge request --> authenticate, else pass up
          GMS.GmsHeader gms_hdr=getGMSHeader(msg);
          if(gms_hdr != null && needsAuthentication(gms_hdr)) {
              AuthHeader auth_hdr=msg.getHeader(id);
              if(auth_hdr == null) {
                  sendRejectionMessage(gms_hdr.getType(), msg.src(), "no AUTH header found in message");
                  throw new IllegalStateException(String.format("found %s from %s but no AUTH header", gms_hdr, msg.src()));
              }
              if(!handleAuthHeader(gms_hdr, auth_hdr, msg)) // authentication failed
                  return null;    // don't pass up
          }
          if(!callUpHandlers(msg))
              return null;
  
          return up_prot.up(msg);
      }
docs: An event was received from the layer below. Usually the current layer will want to examine the event type and
  - depending on its type - perform some computation (e.g. removing headers from a MSG event type, or updating
  the internal membership list when receiving a VIEW_CHANGE event).
  Finally the event is either a) discarded, or b) an event is sent down the stack using {@code down_prot.down()}
  or c) the event (or another event) is sent up the stack using {@code up_prot.up()}.