Beispiel #1
0
  /**
   * Invoked upon receiving a MERGE event from the MERGE layer. Starts the merge protocol. See
   * description of protocol in DESIGN.
   *
   * @param views A List of <em>different</em> views detected by the merge protocol
   */
  public void merge(Map<Address, View> views) {
    if (isMergeInProgress()) {
      if (log.isTraceEnabled())
        log.trace(gms.local_addr + ": merge is already running (merge_id=" + merge_id + ")");
      return;
    }

    // we need the merge *coordinators* not merge participants because not everyone can lead a merge
    // !
    Collection<Address> coords = Util.determineMergeCoords(views);
    Collection<Address> merge_participants = Util.determineMergeParticipants(views);
    Membership tmp =
        new Membership(coords); // establish a deterministic order, so that coords can elect leader
    tmp.sort();
    Address merge_leader = tmp.elementAt(0);
    if (log.isDebugEnabled()) log.debug("determining merge leader from " + merge_participants);
    if (merge_leader.equals(gms.local_addr)) {
      if (log.isDebugEnabled())
        log.debug(
            "I ("
                + gms.local_addr
                + ") will be the leader. Starting the merge task for "
                + merge_participants);
      merge_task.start(views);
    } else {
      if (log.isDebugEnabled())
        log.debug(
            "I ("
                + gms.local_addr
                + ") am not the merge leader, "
                + "waiting for merge leader ("
                + merge_leader
                + ") to initiate merge");
    }
  }
  /** Execute when new member join or leave Group */
  public void viewAccepted(View v) {
    memberSize = v.size();
    if (mainFrame != null) setTitle();
    members.clear();
    members.addAll(v.getMembers());

    if (v instanceof MergeView) {
      System.out.println("** " + v);

      // This is a simple merge function, which fetches the state from the coordinator
      // on a merge and overwrites all of its own state
      if (useState && !members.isEmpty()) {
        Address coord = members.get(0);
        Address local_addr = channel.getAddress();
        if (local_addr != null && !local_addr.equals(coord)) {
          try {

            // make a copy of our state first
            Map<Point, Color> copy = null;
            if (send_own_state_on_merge) {
              synchronized (drawPanel.state) {
                copy = new LinkedHashMap<Point, Color>(drawPanel.state);
              }
            }
            System.out.println("fetching state from " + coord);
            channel.getState(coord, 5000);
            if (copy != null)
              sendOwnState(copy); // multicast my own state so everybody else has it too
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    } else System.out.println("** View=" + v);
  }
Beispiel #3
0
  public Object down(Message msg) {
    Address dest = msg.getDest();
    boolean multicast = dest == null;

    if (msg.getSrc() == null) msg.setSrc(localAddress());

    if (discard_all) {
      if (dest == null || dest.equals(localAddress())) loopback(msg);
      return null;
    }

    if (!multicast && drop_down_unicasts > 0) {
      drop_down_unicasts = Math.max(0, drop_down_unicasts - 1);
      return null;
    }

    if (multicast && drop_down_multicasts > 0) {
      drop_down_multicasts = Math.max(0, drop_down_multicasts - 1);
      return null;
    }

    if (down > 0) {
      double r = Math.random();
      if (r < down) {
        if (excludeItself && dest != null && dest.equals(localAddress())) {
          if (log.isTraceEnabled()) log.trace("excluding itself");
        } else {
          log.trace("dropping message");
          num_down++;
          return null;
        }
      }
    }
    return down_prot.down(msg);
  }
Beispiel #4
0
  /**
   * Send all fragments as separate messages (with same ID !). Example:
   *
   * <pre>
   * Given the generated ID is 2344, number of fragments=3, message {dst,src,buf}
   * would be fragmented into:
   *
   * [2344,3,0]{dst,src,buf1},
   * [2344,3,1]{dst,src,buf2} and
   * [2344,3,2]{dst,src,buf3}
   * </pre>
   */
  private void fragment(Message msg) {
    try {
      byte[] buffer = msg.getRawBuffer();
      List<Range> fragments = Util.computeFragOffsets(msg.getOffset(), msg.getLength(), frag_size);
      int num_frags = fragments.size();
      num_sent_frags.addAndGet(num_frags);

      if (log.isTraceEnabled()) {
        Address dest = msg.getDest();
        StringBuilder sb = new StringBuilder("fragmenting packet to ");
        sb.append((dest != null ? dest.toString() : "<all members>"))
            .append(" (size=")
            .append(buffer.length);
        sb.append(") into ")
            .append(num_frags)
            .append(" fragment(s) [frag_size=")
            .append(frag_size)
            .append(']');
        log.trace(sb.toString());
      }

      long frag_id = getNextId(); // used as a seqno
      for (int i = 0; i < fragments.size(); i++) {
        Range r = fragments.get(i);
        // don't copy the buffer, only src, dest and headers. Only copy the headers one time !
        Message frag_msg = msg.copy(false, i == 0);
        frag_msg.setBuffer(buffer, (int) r.low, (int) r.high);
        FragHeader hdr = new FragHeader(frag_id, i, num_frags);
        frag_msg.putHeader(this.id, hdr);
        down_prot.down(new Event(Event.MSG, frag_msg));
      }
    } catch (Exception e) {
      if (log.isErrorEnabled()) log.error("fragmentation failure", e);
    }
  }
Beispiel #5
0
  /** Checks if a message should be passed up, or not */
  protected boolean shouldDropUpMessage(
      @SuppressWarnings("UnusedParameters") Message msg, Address sender) {
    if (discard_all && !sender.equals(localAddress())) return true;

    if (ignoredMembers.contains(sender)) {
      if (log.isTraceEnabled()) log.trace(localAddress + ": dropping message from " + sender);
      num_up++;
      return true;
    }

    if (up > 0) {
      double r = Math.random();
      if (r < up) {
        if (excludeItself && sender.equals(localAddress())) {
          if (log.isTraceEnabled()) log.trace("excluding myself");
        } else {
          if (log.isTraceEnabled()) log.trace(localAddress + ": dropping message from " + sender);
          num_up++;
          return true;
        }
      }
    }

    return false;
  }
Beispiel #6
0
  public void sendGetMembersRequest(String cluster_name, Promise promise, boolean return_views_only)
      throws Exception {
    PhysicalAddress physical_addr =
        (PhysicalAddress) down_prot.down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr));
    PingData data =
        new PingData(local_addr, null, false, UUID.get(local_addr), Arrays.asList(physical_addr));
    PingHeader hdr = new PingHeader(PingHeader.GET_MBRS_REQ, data, cluster_name);
    hdr.return_view_only = return_views_only;

    Set<PhysicalAddress> combined_target_members = new HashSet<PhysicalAddress>(initial_hosts);
    combined_target_members.addAll(dynamic_hosts);

    for (final Address addr : combined_target_members) {
      if (addr.equals(physical_addr)) continue;
      final Message msg = new Message(addr, null, null);
      msg.setFlag(Message.OOB);
      msg.putHeader(this.id, hdr);
      if (log.isTraceEnabled())
        log.trace("[FIND_INITIAL_MBRS] sending PING request to " + msg.getDest());
      timer.execute(
          new Runnable() {
            public void run() {
              try {
                down_prot.down(new Event(Event.MSG, msg));
              } catch (Exception ex) {
                if (log.isErrorEnabled())
                  log.error("failed sending discovery request to " + addr + ": " + ex);
              }
            }
          });
    }
  }
Beispiel #7
0
 protected void deliver(Message msg, Event evt, SequencerHeader hdr) {
   Address sender = msg.getSrc();
   if (sender == null) {
     if (log.isErrorEnabled())
       log.error(local_addr + ": sender is null, cannot deliver " + "::" + hdr.getSeqno());
     return;
   }
   long msg_seqno = hdr.getSeqno();
   if (sender.equals(local_addr)) {
     forward_table.remove(msg_seqno);
     if (hdr.flush_ack) {
       ack_promise.setResult(msg_seqno);
       if (ack_mode && !flushing && threshold > 0 && ++num_acks >= threshold) {
         ack_mode = false;
         num_acks = 0;
       }
     }
   }
   if (!canDeliver(sender, msg_seqno)) {
     if (log.isWarnEnabled())
       log.warn(local_addr + ": dropped duplicate message " + sender + "::" + msg_seqno);
     return;
   }
   if (log.isTraceEnabled()) log.trace(local_addr + ": delivering " + sender + "::" + msg_seqno);
   up_prot.up(evt);
   delivered_bcasts++;
 }
Beispiel #8
0
 /** Checks whether the potential_new_coord would be the new coordinator (2nd in line) */
 protected boolean wouldBeNewCoordinator(Address potential_new_coord) {
   if (potential_new_coord == null) return false;
   synchronized (members) {
     if (members.size() < 2) return false;
     Address new_coord = members.elementAt(1); // member at 2nd place
     return new_coord != null && new_coord.equals(potential_new_coord);
   }
 }
Beispiel #9
0
 protected void handleView(View view) {
   view_size = view.size();
   Address tmp = Util.pickNext(view.getMembers(), local_addr);
   if (tmp != null && !tmp.equals(local_addr)) {
     next = tmp;
     if (log.isDebugEnabled()) log.debug("next=" + next);
   }
 }
Beispiel #10
0
  // If we're becoming coordinator, we need to handle TMP_VIEW as
  // an immediate change of view. See JGRP-1452.
  private void handleTmpView(View v) {
    List<Address> mbrs = v.getMembers();
    if (mbrs.isEmpty()) return;

    Address new_coord = mbrs.get(0);
    if (!new_coord.equals(coord) && local_addr != null && local_addr.equals(new_coord))
      handleViewChange(v);
  }
Beispiel #11
0
  void handleMessage(Message msg) {
    Event evt;
    UdpHeader hdr;

    // discard my own multicast loopback copy
    if (loopback) {
      Address dst = msg.getDest();
      Address src = msg.getSrc();

      if (dst != null && dst.isMulticastAddress() && src != null && local_addr.equals(src)) {
        if (Trace.debug) {
          Trace.info("UDP.handleMessage()", "discarded own loopback multicast packet");
        }
        return;
      }
    }

    evt = new Event(Event.MSG, msg);
    if (Trace.debug) {
      Trace.info("UDP.handleMessage()", "message is " + msg + ", headers are " + msg.getHeaders());

      /* Because Protocol.up() is never called by this bottommost layer, we call up() directly in the observer.
       * This allows e.g. PerfObserver to get the time of reception of a message */
    }
    if (observer != null) {
      observer.up(evt, up_queue.size());
    }
    hdr = (UdpHeader) msg.removeHeader(name);
    if (hdr != null) {

      /* Discard all messages destined for a channel with a different name */
      String ch_name = null;

      if (hdr.group_addr != null) {
        ch_name = hdr.group_addr;

        // Discard if message's group name is not the same as our group name unless the
        // message is a diagnosis message (special group name DIAG_GROUP)
      }
      if (ch_name != null
          && group_addr != null
          && !group_addr.equals(ch_name)
          && !ch_name.equals(Util.DIAG_GROUP)) {
        if (Trace.trace) {
          Trace.warn(
              "UDP.handleMessage()",
              "discarded message from different group ("
                  + ch_name
                  + "). Sender was "
                  + msg.getSrc());
        }
        return;
      }
    } else {
      Trace.error("UDP.handleMessage()", "message does not have a UDP header");
    }
    passUp(evt);
  }
Beispiel #12
0
  public Object down(Event evt) {
    switch (evt.getType()) {
      case Event.TMP_VIEW:
      case Event.VIEW_CHANGE:
        handleViewChange((View) evt.getArg());
        break;

      case Event.GET_STATE:
        Address target;
        StateTransferInfo info = (StateTransferInfo) evt.getArg();
        if (info.target == null) {
          target = determineCoordinator();
        } else {
          target = info.target;
          if (target.equals(local_addr)) {
            log.error("%s: cannot fetch state from myself", local_addr);
            target = null;
          }
        }
        if (target == null) {
          log.debug("%s: first member (no state)", local_addr);
          up_prot.up(new Event(Event.GET_STATE_OK, new StateTransferInfo()));
        } else {
          Message state_req =
              new Message(target)
                  .putHeader(this.id, new StateHeader(StateHeader.STATE_REQ))
                  .setFlag(Message.Flag.DONT_BUNDLE, Message.Flag.OOB, Message.Flag.SKIP_BARRIER);
          log.debug("%s: asking %s for state", local_addr, target);

          // suspend sending and handling of message garbage collection gossip messages,
          // fixes bugs #943480 and #938584). Wake up when state has been received
          /*if(log.isDebugEnabled())
              log.debug("passing down a SUSPEND_STABLE event");
          down_prot.down(new Event(Event.SUSPEND_STABLE, new Long(info.timeout)));*/
          waiting_for_state_response = true;
          start = System.currentTimeMillis();
          down_prot.down(new Event(Event.MSG, state_req));
        }
        return null; // don't pass down any further !

      case Event.CONFIG:
        Map<String, Object> config = (Map<String, Object>) evt.getArg();
        if (config != null && config.containsKey("flush_supported")) {
          flushProtocolInStack = true;
        }
        break;

      case Event.SET_LOCAL_ADDRESS:
        local_addr = (Address) evt.getArg();
        break;
    }

    return down_prot.down(evt); // pass on to the layer below us
  }
Beispiel #13
0
 public void connect() {
   try {
     channel.connect("TOTAL_TOKEN_DEMO_GROUP");
   } catch (ChannelException e) {
     e.printStackTrace();
   }
   receiverThread = new ReceiverThread();
   receiverThread.start();
   Address a = channel.getAddress();
   if (a != null) setTitle(a.toString());
   else setTitle("Not connected");
   control.connected();
 }
Beispiel #14
0
  public void sendDiscoveryRequest(String cluster_name, Promise promise, ViewId view_id)
      throws Exception {
    PingData data = null;
    PhysicalAddress physical_addr =
        (PhysicalAddress) down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr));

    if (view_id == null) {
      List<PhysicalAddress> physical_addrs = Arrays.asList(physical_addr);
      data = new PingData(local_addr, null, false, UUID.get(local_addr), physical_addrs);
    }

    PingHeader hdr = new PingHeader(PingHeader.GET_MBRS_REQ, data, cluster_name);
    hdr.view_id = view_id;

    Collection<PhysicalAddress> cluster_members = fetchClusterMembers(cluster_name);
    if (cluster_members == null) {
      Message msg = new Message(null); // multicast msg
      msg.setFlag(Message.OOB);
      msg.putHeader(getId(), hdr);
      sendMcastDiscoveryRequest(msg);
    } else {
      if (cluster_members.isEmpty()) { // if we don't find any members, return immediately
        if (promise != null) promise.setResult(null);
      } else {
        for (final Address addr : cluster_members) {
          if (addr.equals(physical_addr)) // no need to send the request to myself
          continue;
          final Message msg = new Message(addr, null, null);
          msg.setFlag(Message.OOB);
          msg.putHeader(this.id, hdr);
          if (log.isTraceEnabled())
            log.trace("[FIND_INITIAL_MBRS] sending discovery request to " + msg.getDest());
          if (!sendDiscoveryRequestsInParallel()) {
            down_prot.down(new Event(Event.MSG, msg));
          } else {
            timer.execute(
                new Runnable() {
                  public void run() {
                    try {
                      down_prot.down(new Event(Event.MSG, msg));
                    } catch (Exception ex) {
                      if (log.isErrorEnabled())
                        log.error("failed sending discovery request to " + addr + ": " + ex);
                    }
                  }
                });
          }
        }
      }
    }
  }
Beispiel #15
0
 @Override
 public void channelConnected(Channel channel) {
   // Validate view
   String localName = channel.getName();
   Address localAddress = channel.getAddress();
   for (Address address : channel.getView()) {
     String name = channel.getName(address);
     if ((name != null) && name.equals(localName) && !address.equals(localAddress)) {
       channel.close();
       throw JGroupsLogger.ROOT_LOGGER.duplicateNodeName(
           this.factory.getValue().getProtocolStackConfiguration().getEnvironment().getNodeName());
     }
   }
 }
Beispiel #16
0
  /**
   * Send the cookie first, then the our port number. If the cookie doesn't match the receiver's
   * cookie, the receiver will reject the connection and close it.
   */
  protected void sendLocalAddress(Address local_addr) throws Exception {
    try {
      // write the cookie
      out.write(cookie, 0, cookie.length);

      // write the version
      out.writeShort(Version.version);
      out.writeShort(local_addr.size()); // address size
      local_addr.writeTo(out);
      out.flush(); // needed ?
      updateLastAccessed();
    } catch (Exception ex) {
      server.socket_factory.close(this.sock);
      throw ex;
    }
  }
Beispiel #17
0
  /**
   * An event is to be sent down the stack. The layer may want to examine its type and perform some
   * action on it, depending on the event's type. If the event is a message MSG, then the layer may
   * need to add a header to it (or do nothing at all) before sending it down the stack using <code>
   * PassDown</code>. In case of a GET_ADDRESS event (which tries to retrieve the stack's address
   * from one of the bottom layers), the layer may need to send a new response event back up the
   * stack using <code>up_prot.up()</code>. The PING protocol is interested in several different
   * down events, Event.FIND_INITIAL_MBRS - sent by the GMS layer and expecting a GET_MBRS_OK
   * Event.TMP_VIEW and Event.VIEW_CHANGE - a view change event Event.BECOME_SERVER - called after
   * client has joined and is fully working group member Event.CONNECT, Event.DISCONNECT.
   */
  @SuppressWarnings("unchecked")
  public Object down(Event evt) {

    switch (evt.getType()) {
      case Event.FIND_INITIAL_MBRS: // sent by GMS layer
      case Event.FIND_ALL_VIEWS:
        // sends the GET_MBRS_REQ to all members, waits 'timeout' ms or until 'num_initial_members'
        // have been retrieved
        long start = System.currentTimeMillis();
        boolean find_all_views = evt.getType() == Event.FIND_ALL_VIEWS;
        Promise<JoinRsp> promise = (Promise<JoinRsp>) evt.getArg();
        List<PingData> rsps = find_all_views ? findAllViews(promise) : findInitialMembers(promise);
        long diff = System.currentTimeMillis() - start;
        if (log.isTraceEnabled())
          log.trace("discovery took " + diff + " ms: responses: " + Util.printPingData(rsps));
        return rsps;

      case Event.TMP_VIEW:
      case Event.VIEW_CHANGE:
        List<Address> tmp;
        view = (View) evt.getArg();
        if ((tmp = view.getMembers()) != null) {
          synchronized (members) {
            members.clear();
            members.addAll(tmp);
          }
        }
        current_coord = !members.isEmpty() ? members.get(0) : null;
        is_coord = current_coord != null && local_addr != null && current_coord.equals(local_addr);

        return down_prot.down(evt);

      case Event.BECOME_SERVER: // called after client has joined and is fully working group member
        down_prot.down(evt);
        is_server = true;
        return null;

      case Event.SET_LOCAL_ADDRESS:
        local_addr = (Address) evt.getArg();
        return down_prot.down(evt);

      case Event.CONNECT:
      case Event.CONNECT_WITH_STATE_TRANSFER:
      case Event.CONNECT_USE_FLUSH:
      case Event.CONNECT_WITH_STATE_TRANSFER_USE_FLUSH:
        is_leaving = false;
        group_addr = (String) evt.getArg();
        Object ret = down_prot.down(evt);
        handleConnect();
        return ret;

      case Event.DISCONNECT:
        is_leaving = true;
        handleDisconnect();
        return down_prot.down(evt);

      default:
        return down_prot.down(evt); // Pass on to the layer below us
    }
  }
Beispiel #18
0
  private synchronized void handleViewChange(View view, boolean makeServer) {
    if (makeServer) initializeNewSymmetricKey(view instanceof MergeView);

    // if view is a bit broken set me as keyserver
    List<Address> members = view.getMembers();
    if (members == null || members.isEmpty() || members.get(0) == null) {
      becomeKeyServer(local_addr, false);
      return;
    }
    // otherwise get keyserver from view controller
    Address tmpKeyServer = view.getMembers().get(0);

    // I am  keyserver - either first member of group or old key server is no more and
    // I have been voted new controller
    if (makeServer || (tmpKeyServer.equals(local_addr))) becomeKeyServer(tmpKeyServer, makeServer);
    else handleNewKeyServer(tmpKeyServer, view instanceof MergeView);
  }
Beispiel #19
0
 // @see java.lang.Object#hashCode()
 @Override
 public int hashCode() {
   final int prime = 31;
   int result = 1;
   result = prime * result + ((address == null) ? 0 : address.hashCode());
   result = prime * result + (int) (requestId ^ (requestId >>> 32));
   return result;
 }
Beispiel #20
0
  @ManagedOperation(description = "Reads data from local caches and dumps them to a file")
  public void dumpCache(String output_filename) throws Exception {
    Map<Address, PhysicalAddress> cache_contents =
        (Map<Address, PhysicalAddress>)
            down_prot.down(new Event(Event.GET_LOGICAL_PHYSICAL_MAPPINGS, false));

    List<PingData> list = new ArrayList<>(cache_contents.size());
    for (Map.Entry<Address, PhysicalAddress> entry : cache_contents.entrySet()) {
      Address addr = entry.getKey();
      PhysicalAddress phys_addr = entry.getValue();
      PingData data =
          new PingData(addr, true, UUID.get(addr), phys_addr).coord(addr.equals(local_addr));
      list.add(data);
    }
    OutputStream out = new FileOutputStream(output_filename);
    write(list, out);
  }
Beispiel #21
0
 /** Returns true if local_addr is member of mbrs, else false */
 protected boolean checkSelfInclusion(Vector mbrs) {
   Object mbr;
   if (mbrs == null) return false;
   for (int i = 0; i < mbrs.size(); i++) {
     mbr = mbrs.elementAt(i);
     if (mbr != null && local_addr.equals(mbr)) return true;
   }
   return false;
 }
    /**
     * Send the cookie first, then the our port number. If the cookie doesn't match the receiver's
     * cookie, the receiver will reject the connection and close it.
     *
     * @throws IOException
     */
    private void sendLocalAddress(Address local_addr) throws IOException {
      // write the cookie
      out.write(cookie, 0, cookie.length);

      // write the version
      out.writeShort(Version.version);
      local_addr.writeTo(out);
      out.flush(); // needed ?
      updateLastAccessed();
    }
Beispiel #23
0
 public void suspect(Address mbr) {
   if (mbr.equals(gms.local_addr)) {
     if (log.isWarnEnabled())
       log.warn("I am the coord and I'm suspected -- will probably leave shortly");
     return;
   }
   Collection<Request> suspected = new LinkedHashSet<>(1);
   suspected.add(new Request(Request.SUSPECT, mbr, true));
   handleMembershipChange(suspected);
 }
 /**
  * Acceptor thread. Continuously accept new connections. Create a new thread for each new
  * connection and put it in conns. When the thread should stop, it is interrupted by the thread
  * creator.
  */
 public void run() {
   while (!srv_sock.isClosed() && !Thread.currentThread().isInterrupted()) {
     TCPConnection conn = null;
     Socket client_sock = null;
     try {
       client_sock = srv_sock.accept();
       conn = new TCPConnection(client_sock);
       Address peer_addr = conn.getPeerAddress();
       mapper.getLock().lock();
       try {
         boolean currentConnectionOpen = mapper.hasOpenConnection(peer_addr);
         boolean replaceWithNewConnection = false;
         if (currentConnectionOpen) {
           replaceWithNewConnection = peer_addr.compareTo(local_addr) > 0;
         }
         if (!currentConnectionOpen || replaceWithNewConnection) {
           mapper.removeConnection(peer_addr);
           mapper.addConnection(peer_addr, conn);
           conn.start(mapper.getThreadFactory()); // starts handler thread on this socket
         } else {
           Util.close(conn);
         }
       } finally {
         mapper.getLock().unlock();
       }
     } catch (SocketException se) {
       boolean threadExiting = srv_sock.isClosed() || Thread.currentThread().isInterrupted();
       if (threadExiting) {
         break;
       } else {
         if (log.isWarnEnabled()) log.warn("Could not accept connection from peer ", se);
         Util.close(conn);
         Util.close(client_sock);
       }
     } catch (Exception ex) {
       if (log.isWarnEnabled()) log.warn("Could not read accept connection from peer " + ex);
       Util.close(conn);
       Util.close(client_sock);
     }
   }
   if (log.isTraceEnabled()) log.trace(Thread.currentThread().getName() + " terminated");
 }
Beispiel #25
0
 // @see java.lang.Object#equals(java.lang.Object)
 @Override
 public boolean equals(Object obj) {
   if (this == obj) return true;
   if (obj == null) return false;
   if (getClass() != obj.getClass()) return false;
   Owner other = (Owner) obj;
   if (address == null) {
     if (other.address != null) return false;
   } else if (!address.equals(other.address)) return false;
   return requestId == other.requestId;
 }
Beispiel #26
0
  /**
   * Decrements credits bytes from all elements and add new_credits to member (if non null). The
   * lowest credit needs to be greater than min_credits. Needs to be called with lock held
   *
   * @param member The member to which new_credits are added. NOP if null
   * @param new_credits Number of bytes to add to member. NOP if 0.
   */
  protected void decrementAndAdd(Address member, long new_credits) {
    boolean replenish = member != null && new_credits > 0;

    if (accumulated_credits > 0) {
      for (Map.Entry<Address, Long> entry : this.credits.entrySet()) {
        entry.setValue(Math.max(0, entry.getValue().longValue() - accumulated_credits));
        if (replenish) {
          Address tmp = entry.getKey();
          if (tmp.equals(member))
            entry.setValue(Math.min(max_credits, entry.getValue().longValue() + new_credits));
        }
      }
      accumulated_credits = 0;
    } else {
      if (replenish) {
        Long val = this.credits.get(member);
        if (val != null)
          this.credits.put(member, Math.min(max_credits, val.longValue() + new_credits));
      }
    }
  }
Beispiel #27
0
 protected Address getReceiver() {
   try {
     List<Address> mbrs = channel.getView().getMembers();
     System.out.println("pick receiver from the following members:");
     int i = 0;
     for (Address mbr : mbrs) {
       if (mbr.equals(channel.getAddress())) System.out.println("[" + i + "]: " + mbr + " (self)");
       else System.out.println("[" + i + "]: " + mbr);
       i++;
     }
     System.out.flush();
     System.in.skip(System.in.available());
     BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
     String tmp = reader.readLine().trim();
     int index = Integer.parseInt(tmp);
     return mbrs.get(index); // index out of bounds caught below
   } catch (Exception e) {
     System.err.println("UnicastTest.getReceiver(): " + e);
     return null;
   }
 }
    /**
     * Reads the peer's address. First a cookie has to be sent which has to match my own cookie,
     * otherwise the connection will be refused
     */
    private Address readPeerAddress(Socket client_sock) throws Exception {
      int timeout = client_sock.getSoTimeout();
      client_sock.setSoTimeout(peer_addr_read_timeout);

      try {
        // read the cookie first
        byte[] input_cookie = new byte[cookie.length];
        in.readFully(input_cookie, 0, input_cookie.length);
        if (!matchCookie(input_cookie))
          throw new SocketException(
              "ConnectionMap.Connection.readPeerAddress(): cookie read by "
                  + getLocalAddress()
                  + " does not match own cookie; terminating connection");
        // then read the version
        short version = in.readShort();

        if (!Version.isBinaryCompatible(version)) {
          if (log.isWarnEnabled())
            log.warn(
                new StringBuilder("packet from ")
                    .append(client_sock.getInetAddress())
                    .append(':')
                    .append(client_sock.getPort())
                    .append(" has different version (")
                    .append(Version.print(version))
                    .append(") from ours (")
                    .append(Version.printVersion())
                    .append("). This may cause problems")
                    .toString());
        }
        Address client_peer_addr = new IpAddress();
        client_peer_addr.readFrom(in);

        updateLastAccessed();
        return client_peer_addr;
      } finally {
        client_sock.setSoTimeout(timeout);
      }
    }
Beispiel #29
0
  /**
   * Send all fragments as separate messages (with same ID !). Example:
   *
   * <pre>
   * Given the generated ID is 2344, number of fragments=3, message {dst,src,buf}
   * would be fragmented into:
   * <p/>
   * [2344,3,0]{dst,src,buf1},
   * [2344,3,1]{dst,src,buf2} and
   * [2344,3,2]{dst,src,buf3}
   * </pre>
   */
  private void fragment(Message msg, long size) {
    Address dest = msg.getDest(), src = msg.getSrc();
    long frag_id = curr_id.getAndIncrement(); // used as seqnos
    int num_frags;

    try {
      // write message into a byte buffer and fragment it
      ByteArrayDataOutputStream dos = new ByteArrayDataOutputStream((int) (size + 50));
      msg.writeTo(dos);
      byte[] buffer = dos.buffer();
      byte[][] fragments = Util.fragmentBuffer(buffer, frag_size, dos.position());
      num_frags = fragments.length;
      num_sent_frags += num_frags;

      if (log.isTraceEnabled()) {
        StringBuilder sb = new StringBuilder();
        sb.append("fragmenting packet to ")
            .append(dest != null ? dest.toString() : "<all members>")
            .append(" (size=")
            .append(buffer.length)
            .append(") into ")
            .append(num_frags)
            .append(" fragment(s) [frag_size=")
            .append(frag_size)
            .append(']');
        log.trace(sb.toString());
      }

      for (int i = 0; i < num_frags; i++) {
        Message frag_msg = new Message(dest, src, fragments[i]);
        FragHeader hdr = new FragHeader(frag_id, i, num_frags);
        frag_msg.putHeader(this.id, hdr);
        Event evt = new Event(Event.MSG, frag_msg);
        down_prot.down(evt);
      }
    } catch (Exception e) {
      log.error(Util.getMessage("ExceptionOccurredTryingToFragmentMessage"), e);
    }
  }
Beispiel #30
0
 /**
  * Removes all members from a given view which don't have us in their view
  * (https://jira.jboss.org/browse/JGRP-1061). Example:
  *
  * <pre>
  * A: AB
  * B: AB
  * C: ABC
  * </pre>
  *
  * becomes
  *
  * <pre>
  * A: AB
  * B: AB
  * C: C // A and B don't have C in their views
  * </pre>
  *
  * @param map A map of members and their associated views
  */
 public static void sanitizeViews(Map<Address, View> map) {
   if (map == null) return;
   for (Map.Entry<Address, View> entry : map.entrySet()) {
     Address key = entry.getKey();
     Collection<Address> members = new ArrayList<Address>(entry.getValue().getMembers());
     boolean modified = false;
     for (Iterator<Address> it = members.iterator(); it.hasNext(); ) {
       Address val = it.next();
       if (val.equals(key)) // we can always talk to ourself !
       continue;
       View view = map.get(val);
       final Collection<Address> tmp_mbrs = view != null ? view.getMembers() : null;
       if (tmp_mbrs != null && !tmp_mbrs.contains(key)) {
         it.remove();
         modified = true;
       }
     }
     if (modified) {
       View old_view = entry.getValue();
       entry.setValue(new View(old_view.getVid(), members));
     }
   }
 }