@Test
  public void testBlockUnblockWithPresence() throws Exception {
    JID connJid = JID.jidInstanceNS("[email protected]/test-111");
    JID userJid = JID.jidInstanceNS("[email protected]/res-1");
    XMPPResourceConnection sess = getSession(connJid, userJid);

    String blockJid = "*****@*****.**";
    RosterAbstract roster_util = RosterFactory.getRosterImplementation(true);
    roster_util.addBuddy(sess, JID.jidInstance(blockJid), "Block-1", null, null);
    roster_util.setBuddySubscription(
        sess, RosterAbstract.SubscriptionType.both, JID.jidInstance(blockJid));

    checkPrivacyJidBlocked(sess, blockJid, false);
    List<String> blocked = getBlocked(sess);
    assertTrue(blocked == null || blocked.isEmpty());

    block(sess, blockJid);
    assertEquals(3, results.size());
    privacy.filter(null, sess, null, results);

    assertEquals(3, results.size());
    Packet result = results.poll();
    assertNotNull(result);
    assertEquals(tigase.server.Presence.ELEM_NAME, result.getElemName());
    assertEquals(StanzaType.unavailable, result.getType());
    result = results.poll();
    assertNotNull(result);
    assertEquals(Iq.ELEM_NAME, result.getElemName());
    assertEquals(StanzaType.result, result.getType());
    result = results.poll();
    assertNotNull(result);
    assertEquals(Iq.ELEM_NAME, result.getElemName());
    assertEquals(StanzaType.set, result.getType());

    checkPrivacyJidBlocked(sess, blockJid, true);
    blocked = getBlocked(sess);
    assertTrue(blocked.contains(blockJid));

    unblock(sess, blockJid);
    assertEquals(3, results.size());
    privacy.filter(null, sess, null, results);

    assertEquals(3, results.size());
    result = results.poll();
    assertNotNull(result);
    assertEquals(tigase.server.Presence.ELEM_NAME, result.getElemName());
    assertEquals(StanzaType.probe, result.getType());
    result = results.poll();
    assertNotNull(result);
    assertEquals(Iq.ELEM_NAME, result.getElemName());
    assertEquals(StanzaType.result, result.getType());
    result = results.poll();
    assertNotNull(result);
    assertEquals(Iq.ELEM_NAME, result.getElemName());
    assertEquals(StanzaType.set, result.getType());

    checkPrivacyJidBlocked(sess, blockJid, false);
    blocked = getBlocked(sess);
    assertTrue(blocked == null || blocked.isEmpty());
  }
Esempio n. 2
0
  /**
   * Creates a packet with message stanza.
   *
   * @param from is a <code>JID</code> instance with message source address.
   * @param to is a <code>JID</code> instance with message destination address.
   * @param type is a <code>StanzaType</code> object with the message type.
   * @param body is a <code>String</code> object with message body content.
   * @param subject is a <code>String</code> object with message subject.
   * @param thread is a <code>String</code> object with message thread.
   * @param id is a <code>String</code> object with packet id value. Normally we do not set packet
   *     IDs for messages but in some cases this might be useful.
   * @return a new <code>Packet</code> instance (more specificaly <code>Message</code> instance)
   *     with the message stanza.
   */
  public static Packet getMessage(
      JID from, JID to, StanzaType type, String body, String subject, String thread, String id) {
    Element message = new Element("message", new Element[] {new Element("body", body)}, null, null);

    message.setXMLNS(CLIENT_XMLNS);
    if (from != null) {
      message.addAttribute("from", from.toString());
    }
    if (to != null) {
      message.addAttribute("to", to.toString());
    }
    if (type != null) {
      message.addAttribute("type", type.name());
    }
    if (id != null) {
      message.addAttribute("id", id);
    }
    if (subject != null) {
      message.addChild(new Element("subject", subject));
    }
    if (thread != null) {
      message.addChild(new Element("thread", thread));
    }

    return packetInstance(message, from, to);
  }
Esempio n. 3
0
  protected Packet createMessage(
      BareJID roomJID,
      JID senderJID,
      String msgSenderNickname,
      String originalMessage,
      String body,
      String msgSenderJid,
      boolean addRealJids,
      Date msgTimestamp)
      throws TigaseStringprepException {

    Packet message = null;

    if (originalMessage != null) {
      DomBuilderHandler domHandler = new DomBuilderHandler();
      parser.parse(domHandler, originalMessage.toCharArray(), 0, originalMessage.length());
      Queue<Element> queue = domHandler.getParsedElements();

      Element m = queue.poll();
      if (m != null) {
        m.setAttribute("type", "groupchat");
        m.setAttribute("from", JID.jidInstance(roomJID, msgSenderNickname).toString());
        m.setAttribute("to", senderJID.toString());

        message = Packet.packetInstance(m);
        message.setXMLNS(Packet.CLIENT_XMLNS);
      }
    }

    if (message == null) {
      message =
          Packet.packetInstance(
              new Element(
                  "message",
                  new String[] {"type", "from", "to"},
                  new String[] {
                    "groupchat",
                    JID.jidInstance(roomJID, msgSenderNickname).toString(),
                    senderJID.toString()
                  }));
      message.setXMLNS(Packet.CLIENT_XMLNS);
      message.getElement().addChild(new Element("body", body));
    }

    String from = addRealJids ? msgSenderJid : roomJID + "/" + msgSenderNickname;
    Element delay =
        new Element(
            "delay",
            new String[] {"xmlns", "from", "stamp"},
            new String[] {"urn:xmpp:delay", from, DateUtil.formatDatetime(msgTimestamp)});
    Element x =
        new Element(
            "x",
            new String[] {"xmlns", "from", "stamp"},
            new String[] {"jabber:x:delay", from, DateUtil.formatOld(msgTimestamp)});
    message.getElement().addChild(delay);
    message.getElement().addChild(x);

    return message;
  }
Esempio n. 4
0
  private void initDialback(S2SIOService serv, String remote_id) {
    try {
      CID cid = (CID) serv.getSessionData().get("cid");

      String secret = handler.getSecretForDomain(cid.getLocalHost());
      String key =
          Algorithms.generateDialbackKey(
              cid.getLocalHost(), cid.getRemoteHost(), secret, remote_id);

      if (!serv.isHandshakingOnly()) {
        Element elem =
            new Element(
                DB_RESULT_EL_NAME, key, new String[] {XMLNS_DB_ATT}, new String[] {XMLNS_DB_VAL});

        addToResultRequested(serv, cid.getRemoteHost());
        serv.getS2SConnection()
            .addControlPacket(
                Packet.packetInstance(
                    elem,
                    JID.jidInstanceNS(cid.getLocalHost()),
                    JID.jidInstanceNS(cid.getRemoteHost())));
      }
      serv.getS2SConnection().sendAllControlPackets();
    } catch (NotLocalhostException ex) {
      generateStreamError(false, "host-unknown", serv);
    }
  }
Esempio n. 5
0
 private void setJid(String jid) throws TigaseStringprepException {
   if (XMPPStringPrepFactory.STRINGPREP_PROCESSOR.equals(stringpreped)) {
     this.jid = JID.jidInstanceNS(jid);
   } else {
     this.jid = JID.jidInstance(jid);
     modified = true;
   }
   stringpreped = XMPPStringPrepFactory.STRINGPREP_PROCESSOR;
 }
Esempio n. 6
0
 private Queue<Packet> enableMobileV3(XMPPResourceConnection session, JID userJid)
     throws TigaseStringprepException {
   Packet p = Packet.packetInstance("iq", userJid.toString(), userJid.toString(), StanzaType.set);
   p.getElement()
       .addChild(
           new Element(
               "mobile",
               new String[] {"xmlns", "enable"},
               new String[] {"http://tigase.org/protocol/mobile#v3", "true"}));
   ArrayDeque<Packet> results = new ArrayDeque<Packet>();
   mobileV3.process(p, session, null, results, null);
   return results;
 }
  @Test
  public void testBlockUnblock() throws Exception {
    JID connJid = JID.jidInstanceNS("[email protected]/test-111");
    JID userJid = JID.jidInstanceNS("[email protected]/res-1");
    XMPPResourceConnection sess = getSession(connJid, userJid);

    String blockJid = "*****@*****.**";

    checkPrivacyJidBlocked(sess, blockJid, false);
    List<String> blocked = getBlocked(sess);
    assertTrue(blocked == null || blocked.isEmpty());

    block(sess, blockJid);
    assertEquals(2, results.size());
    privacy.filter(null, sess, null, results);

    assertEquals(2, results.size());
    Packet result = results.poll();
    assertNotNull(result);
    assertEquals(Iq.ELEM_NAME, result.getElemName());
    assertEquals(StanzaType.result, result.getType());
    result = results.poll();
    assertNotNull(result);
    assertEquals(Iq.ELEM_NAME, result.getElemName());
    assertEquals(StanzaType.set, result.getType());

    checkPrivacyJidBlocked(sess, blockJid, true);
    blocked = getBlocked(sess);
    assertTrue(blocked.contains(blockJid));

    unblock(sess, blockJid);
    assertEquals(2, results.size());
    privacy.filter(null, sess, null, results);

    assertEquals(2, results.size());
    result = results.poll();
    assertNotNull(result);
    assertEquals(Iq.ELEM_NAME, result.getElemName());
    assertEquals(StanzaType.result, result.getType());
    result = results.poll();
    assertNotNull(result);
    assertEquals(Iq.ELEM_NAME, result.getElemName());
    assertEquals(StanzaType.set, result.getType());

    checkPrivacyJidBlocked(sess, blockJid, false);
    blocked = getBlocked(sess);
    assertTrue(blocked == null || blocked.isEmpty());
  }
Esempio n. 8
0
  public Element getRosterElement() {
    Element elem =
        new Element(
            ELEM_NAME,
            new String[] {JID_ATT, SUBS_ATT, NAME_ATT, STRINGPREP_ATT},
            new String[] {
              jid.toString(), subscription.toString(), XMLUtils.escape(name), "" + stringpreped
            });

    if ((groups != null) && (groups.length > 0)) {
      String grps = "";

      for (String group : groups) {
        grps += XMLUtils.escape(group) + ",";
      }
      grps = grps.substring(0, grps.length() - 1);
      elem.setAttribute(GRP_ATT, grps);
    }
    if (otherData != null) {
      elem.setAttribute(OTHER_ATT, otherData);
    }
    elem.setAttribute(ACTIVITY_ATT, Double.toString(activity));
    elem.setAttribute(WEIGHT_ATT, Double.toString(weight));
    elem.setAttribute(LAST_SEEN_ATT, Long.toString(lastSeen));
    modified = false;

    return elem;
  }
 @Override
 public List<Element> getDiscoItems(String node, JID jid, JID from) {
   if (isAdmin(from)) {
     if (getName().equals(jid.getLocalpart())) {
       return serviceEntity.getDiscoItems(node, jid.toString());
     } else {
       if (node == null) {
         return Arrays.asList(
             serviceEntity.getDiscoItem(null, BareJID.toString(getName(), jid.toString())));
       } else {
         return null;
       }
     }
   }
   return null;
 }
 @Override
 public Element getDiscoInfo(String node, JID jid, JID from) {
   if (jid != null && getName().equals(jid.getLocalpart()) && isAdmin(from)) {
     return serviceEntity.getDiscoInfo(node);
   }
   return null;
 }
Esempio n. 11
0
  @Test
  public void testRecipientEnabledFor2Resources2Presences()
      throws TigaseStringprepException, NotAuthorizedException {
    String recipient = "recipient-1@localhost";
    JID recp1 = JID.jidInstanceNS(recipient + "/res1");
    JID recp2 = JID.jidInstanceNS(recipient + "/res2");
    JID connId1 = JID.jidInstanceNS("c2s@localhost/recipient1-res1");
    JID connId2 = JID.jidInstanceNS("c2s@localhost/recipient1-res2");
    XMPPResourceConnection session1 = getSession(connId1, recp1);
    getSession(connId2, recp2);

    enableMobileV3(session1, recp1);

    Packet presence =
        Packet.packetInstance(
            "presence", "sender-1@localhost/res1", recp1.toString(), StanzaType.available);
    presence.setPacketTo(connId1);
    ArrayDeque<Packet> results = new ArrayDeque<Packet>();
    results.offer(presence);
    Packet[] expected = new Packet[0]; // results.toArray(new Packet[0]);
    mobileV3.filter(presence, session1, null, results);
    Packet[] processed = results.toArray(new Packet[0]);
    Assert.assertArrayEquals(expected, processed);

    presence =
        Packet.packetInstance(
            "presence", "sender-1@localhost/res1", recp1.toString(), StanzaType.available);
    presence.setPacketTo(connId1);
    results = new ArrayDeque<Packet>();
    results.offer(presence);
    expected = new Packet[0]; // results.toArray(new Packet[0]);
    mobileV3.filter(presence, session1, null, results);
    processed = results.toArray(new Packet[0]);
    Assert.assertArrayEquals(expected, processed);

    results.clear();
    Packet p =
        Packet.packetInstance(
            "message", "sender-1@localhost/res1", recp1.toString(), StanzaType.chat);
    p.setPacketTo(connId1);
    results.offer(p);
    Packet p1 =
        Packet.packetInstance(
            "presence", "sender-1@localhost/res1", recp1.toString(), StanzaType.error);
    p1.setPacketTo(connId1);
    results.offer(p1);
    expected = new Packet[] {presence, p, p1};
    mobileV3.filter(p, session1, null, results);
    processed = results.toArray(new Packet[0]);
    Assert.assertArrayEquals(expected, processed);
  }
 @Override
 public void nodeConnected(String node) {
   JID nodeJID = JID.jidInstanceNS("vhost-man", node, null);
   log.log(Level.FINEST, "Node connected: " + nodeJID);
   synchronized (connectedNodes) {
     if (!connectedNodes.contains(nodeJID)) {
       connectedNodes.add(nodeJID);
     }
   }
 }
  /**
   * Method is responsible for processing outgoing subscribed and unsubscribed presence (i.e. in the
   * sender session manager).
   *
   * <p>Presence packet is forwarded to the destination with the JID stripped from the resource, a
   * subscription state is being updated and, in case there was a change, a roster push is being
   * sent to all user resources. Also, in case of presence type out_subscribed server send current
   * presence to the user from each of the contact's available resources. For the presence type
   * out_unsubscribed an unavailable presence is sent.
   *
   * @param packet packet is which being processed.
   * @param session user session which keeps all the user session data and also gives an access to
   *     the user's repository data.
   * @param results this a collection with packets which have been generated as input packet
   *     processing results.
   * @param settings this map keeps plugin specific settings loaded from the Tigase server
   *     configuration.
   * @param pres_type specifies type of the presence.
   * @throws NoConnectionIdException
   * @throws NotAuthorizedException
   * @throws TigaseDBException
   */
  protected void processOutSubscribed(
      Packet packet,
      XMPPResourceConnection session,
      Queue<Packet> results,
      Map<String, Object> settings,
      RosterAbstract.PresenceType pres_type)
      throws NotAuthorizedException, TigaseDBException, NoConnectionIdException {

    // According to RFC-3921 I must forward all these kind presence
    // requests, it allows to re-synchronize
    // subscriptions in case of synchronization loss
    forwardPresence(results, packet, session.getJID().copyWithoutResource());

    Element initial_presence = session.getPresence();
    JID buddy = packet.getStanzaTo().copyWithoutResource();
    boolean subscr_changed = roster_util.updateBuddySubscription(session, pres_type, buddy);

    if (autoAuthorize && (pres_type == RosterAbstract.PresenceType.out_subscribed)) {
      roster_util.setBuddySubscription(
          session, RosterAbstract.SubscriptionType.both, buddy.copyWithoutResource());
    }
    if (subscr_changed) {
      roster_util.updateBuddyChange(session, results, roster_util.getBuddyItem(session, buddy));
      if (initial_presence != null) {
        if (pres_type == RosterAbstract.PresenceType.out_subscribed) {

          // The contact's server MUST then also send current presence to the user
          // from each of the contact's available resources.
          List<XMPPResourceConnection> activeSessions = session.getActiveSessions();

          for (XMPPResourceConnection userSessions : activeSessions) {
            Element presence = userSessions.getPresence();

            sendPresence(StanzaType.available, userSessions.getjid(), buddy, results, presence);
          }
          roster_util.setPresenceSent(session, buddy, true);
        } else {
          sendPresence(StanzaType.unavailable, session.getJID(), buddy, results, null);
        }
      } // end of if (subscr_changed)
    }
  }
  /**
   * Method retrieves {@link BoshSession} related to the particular user address
   *
   * @param jid address for which {@link BoshSession} should be returned
   * @return a value of {@link BoshSession}
   */
  protected BoshSession getBoshSession(JID jid) {
    String res = jid.getResource();

    if (res != null) {
      UUID sid = UUID.fromString(res);

      return sessions.get(sid);
    }

    return null;
  }
Esempio n. 15
0
  public Element getRosterItem() {

    // This is actually not a good idea to cache the item element.
    // This causes a huge memory consumption and usually the item
    // is needed only once at the roster retrieving time.
    // if (item == null) {
    Element item = new Element("item");

    item.setAttribute("jid", jid.toString());
    item.addAttributes(subscription.getSubscriptionAttr());
    if (name != null) {
      item.setAttribute("name", XMLUtils.escape(name));
    }
    if (groups != null) {
      for (String gr : groups) {
        Element group = new Element("group");

        group.setCData(XMLUtils.escape(gr));
        item.addChild(group);
      } // end of for ()
    } // end of if-else
    return item;
  }
  protected Map<String, String> preBindSession(Map<String, String> attr) {
    String hostname = attr.get(TO_ATTR);

    Queue<Packet> out_results = new ArrayDeque<Packet>(2);

    BoshSession bs =
        new BoshSession(
            getDefVHostItem().getDomain(),
            JID.jidInstanceNS(routings.computeRouting(hostname)),
            this,
            sendNodeHostname ? getDefHostName().getDomain() : null,
            maxSessionWaitingPackets);

    String jid = attr.get(FROM_ATTR);
    String uuid = UUID.randomUUID().toString();
    JID userId = JID.jidInstanceNS(jid);
    if (null == userId.getResource()) {
      userId = userId.copyWithResourceNS(uuid);
      attr.put(FROM_ATTR, userId.toString());
      bs.setUserJid(jid);
    }
    long rid = (long) (Math.random() * 10000000);

    attr.put(RID_ATTR, Long.toString(rid));

    UUID sid = bs.getSid();
    sessions.put(sid, bs);
    if (log.isLoggable(Level.FINE)) {
      log.log(
          Level.FINE,
          "{0} : {1} ({2})",
          new Object[] {BOSH_OPERATION_TYPE.CREATE, bs.getSid(), "Pre-bind"});
    }

    attr.put(SID_ATTR, sid.toString());

    Packet p = null;
    try {
      Element el = new Element("body");
      el.setAttributes(attr);
      p = Packet.packetInstance(el);
    } catch (TigaseStringprepException ex) {
      Logger.getLogger(BoshConnectionManager.class.getName()).log(Level.SEVERE, null, ex);
    }
    bs.init(
        p,
        null,
        max_wait,
        min_polling,
        max_inactivity,
        concurrent_requests,
        hold_requests,
        max_pause,
        max_batch_size,
        batch_queue_timeout,
        out_results,
        true);
    addOutPackets(out_results, bs);

    attr.put("hostname", getDefHostName().toString());

    return attr;
  }
 // ~--- get methods ----------------------------------------------------------
 private JID getFromAddress(String id) {
   return JID.jidInstanceNS(getName(), getDefHostName().getDomain(), id);
 }
 /**
  * Method description
  *
  * @param jid
  * @return a value of <code>String</code>
  */
 protected String getServiceId(JID jid) {
   return jid.getResource();
 }
  @Override
  public Queue<Packet> processSocketData(XMPPIOService<Object> srv) {
    BoshIOService serv = (BoshIOService) srv;
    Packet p = null;

    while ((p = serv.getReceivedPackets().poll()) != null) {
      Queue<Packet> out_results = new ArrayDeque<Packet>(2);
      BoshSession bs = null;
      String sid_str = null;

      synchronized (sessions) {
        if (log.isLoggable(Level.FINER)) {
          log.log(
              Level.FINER,
              "Processing packet: {0}, type: {1}",
              new Object[] {p.getElemName(), p.getType()});
        }
        if (log.isLoggable(Level.FINEST)) {
          log.log(Level.FINEST, "Processing socket data: {0}", p);
        }
        sid_str = p.getAttributeStaticStr(SID_ATTR);

        UUID sid = null;

        if (sid_str == null) {
          String hostname = p.getAttributeStaticStr(Packet.TO_ATT);

          if ((hostname != null) && isLocalDomain(hostname)) {
            if (!isAllowed(srv, hostname)) {
              if (log.isLoggable(Level.FINE)) {
                log.log(Level.FINE, "Policy violation. Closing connection: {0}", p);
              }
              try {
                serv.sendErrorAndStop(Authorization.NOT_ALLOWED, p, "Policy violation.");
              } catch (IOException e) {
                log.log(
                    Level.WARNING, "Problem sending invalid hostname error for sid =  " + sid, e);
              }
            } else {
              bs =
                  new BoshSession(
                      getDefVHostItem().getDomain(),
                      JID.jidInstanceNS(routings.computeRouting(hostname)),
                      this,
                      sendNodeHostname ? getDefHostName().getDomain() : null,
                      maxSessionWaitingPackets);
              sid = bs.getSid();
              sessions.put(sid, bs);

              if (log.isLoggable(Level.FINE)) {
                log.log(
                    Level.FINE,
                    "{0} : {1} ({2})",
                    new Object[] {BOSH_OPERATION_TYPE.CREATE, sid, "Socket bosh session"});
              }
            }
          } else {
            try {
              serv.sendErrorAndStop(Authorization.NOT_ALLOWED, p, "Invalid hostname.");
            } catch (IOException e) {
              log.log(Level.WARNING, "Problem sending invalid hostname error for sid =  " + sid, e);
            }
          }
        } else {
          try {
            sid = UUID.fromString(sid_str);
            bs = sessions.get(sid);
          } catch (IllegalArgumentException e) {
            log.log(
                Level.WARNING,
                "Problem processing socket data, sid =  "
                    + sid_str
                    + " does not conform to the UUID string representation.",
                e);
          }
        }
      }
      try {
        if (bs != null) {
          synchronized (bs) {
            if (sid_str == null) {
              bs.init(
                  p,
                  serv,
                  max_wait,
                  min_polling,
                  max_inactivity,
                  concurrent_requests,
                  hold_requests,
                  max_pause,
                  max_batch_size,
                  batch_queue_timeout,
                  out_results);
            } else {
              bs.processSocketPacket(p, serv, out_results);
            }
          }
        } else {
          if (log.isLoggable(Level.FINE)) {
            log.log(
                Level.FINE,
                "{0} : {1} ({2})",
                new Object[] {BOSH_OPERATION_TYPE.INVALID_SID, sid_str, "Invalid SID"});
          }
          serv.sendErrorAndStop(Authorization.ITEM_NOT_FOUND, p, "Invalid SID");
        }
        addOutPackets(out_results, bs);
      } catch (IOException e) {
        log.log(Level.WARNING, "Problem processing socket data for sid =  " + sid_str, e);
      }

      // addOutPackets(out_results);
    } // end of while ()

    return null;
  }
Esempio n. 20
0
  @Test
  public void testRecipientEnabledFor2ResourcesMixed()
      throws TigaseStringprepException, NotAuthorizedException {
    String recipient = "recipient-1@localhost";
    JID recp1 = JID.jidInstanceNS(recipient + "/res1");
    JID recp2 = JID.jidInstanceNS(recipient + "/res2");
    JID connId1 = JID.jidInstanceNS("c2s@localhost/recipient1-res1");
    JID connId2 = JID.jidInstanceNS("c2s@localhost/recipient1-res2");
    XMPPResourceConnection session1 = getSession(connId1, recp1);
    getSession(connId2, recp2);

    enableMobileV3(session1, recp1);

    Packet presence =
        Packet.packetInstance(
            "presence", "sender-1@localhost/res1", recp1.toString(), StanzaType.available);
    presence.setPacketTo(connId1);
    ArrayDeque<Packet> results = new ArrayDeque<Packet>();
    results.offer(presence);
    Packet[] expected = new Packet[0]; // results.toArray(new Packet[0]);
    mobileV3.filter(presence, session1, null, results);
    Packet[] processed = results.toArray(new Packet[0]);
    Assert.assertArrayEquals(expected, processed);

    results.clear();
    Packet m1 =
        Packet.packetInstance("message", recp2.toString(), recp1.toString(), StanzaType.chat);
    Element receivedEl =
        new Element("received", new String[] {"xmlns"}, new String[] {"urn:xmpp:carbons:2"});
    Element forwardedEl =
        new Element("forwarded", new String[] {"xmlns"}, new String[] {"urn:xmpp:forward:0"});
    forwardedEl.addChild(
        new Element(
            "message",
            new String[] {"from", "to"},
            new String[] {recp2.toString(), "sender-1@localhost/res1"}));
    receivedEl.addChild(forwardedEl);
    m1.getElement().addChild(receivedEl);
    m1.setPacketTo(connId1);
    results.offer(m1);
    expected = new Packet[0];
    mobileV3.filter(m1, session1, null, results);
    processed = results.toArray(new Packet[0]);
    Assert.assertArrayEquals(expected, processed);

    results.clear();
    presence =
        Packet.packetInstance(
            "presence", "sender-1@localhost/res1", recp1.toString(), StanzaType.available);
    presence.setPacketTo(connId1);
    results.offer(presence);
    expected = new Packet[0]; // results.toArray(new Packet[0]);
    mobileV3.filter(presence, session1, null, results);
    processed = results.toArray(new Packet[0]);
    Assert.assertArrayEquals(expected, processed);

    results.clear();
    Packet p =
        Packet.packetInstance(
            "message", "sender-1@localhost/res1", recp1.toString(), StanzaType.chat);
    p.setPacketTo(connId1);
    results.offer(p);
    Packet p1 =
        Packet.packetInstance(
            "presence", "sender-1@localhost/res1", recp1.toString(), StanzaType.error);
    p1.setPacketTo(connId1);
    results.offer(p1);
    expected = new Packet[] {presence, m1, p, p1};
    mobileV3.filter(p, session1, null, results);
    processed = results.toArray(new Packet[0]);
    Assert.assertArrayEquals(expected, processed);
  }
 @Override
 public void nodeDisconnected(String node) {
   JID nodeJID = JID.jidInstanceNS("vhost-man", node, null);
   log.log(Level.FINEST, "Node disconnected: " + nodeJID);
   connectedNodes.remove(nodeJID);
 }