Пример #1
0
  /** Sends a GET_MBR_REQ to *all* GossipRouters, merges responses. */
  private List _getMembers(String group) {
    List ret = new LinkedList();
    Socket sock = null;
    SocketAddress destAddr;
    DataOutputStream out = null;
    DataInputStream in = null;
    IpAddress entry;
    GossipData gossip_req, gossip_rsp;
    Address mbr;

    for (int i = 0; i < gossip_servers.size(); i++) {
      entry = (IpAddress) gossip_servers.elementAt(i);
      if (entry.getIpAddress() == null || entry.getPort() == 0) {
        if (log.isErrorEnabled()) log.error("entry.host or entry.port is null");
        continue;
      }

      try {
        // sock=new Socket(entry.getIpAddress(), entry.getPort());
        sock = new Socket();
        destAddr = new InetSocketAddress(entry.getIpAddress(), entry.getPort());
        sock.connect(destAddr, SOCKET_TIMEOUT);
        out = new DataOutputStream(sock.getOutputStream());

        gossip_req = new GossipData(GossipRouter.GOSSIP_GET, group, null, null);
        // must send GossipData as fast as possible, otherwise the
        // request might be rejected
        gossip_req.writeTo(out);
        out.flush();

        in = new DataInputStream(sock.getInputStream());
        gossip_rsp = new GossipData();
        gossip_rsp.readFrom(in);
        if (gossip_rsp.mbrs != null) { // merge with ret
          for (Iterator it = gossip_rsp.mbrs.iterator(); it.hasNext(); ) {
            mbr = (Address) it.next();
            if (!ret.contains(mbr)) ret.add(mbr);
          }
        }
      } catch (Exception ex) {
        if (log.isErrorEnabled()) log.error("exception connecting to host " + entry);
      } finally {
        Util.close(out);
        Util.close(in);
        if (sock != null) {
          try {
            sock.close();
          } catch (IOException e) {
          }
        }
      }
    }

    return ret;
  }
Пример #2
0
  /** Send a message to the address specified in dest */
  void sendUdpMessage(Message msg) throws Exception {
    IpAddress dest;
    Message copy;
    Event evt;

    dest = (IpAddress) msg.getDest(); // guaranteed not to be null
    setSourceAddress(msg);

    if (Trace.debug) {
      Trace.debug(
          "UDP.sendUdpMessage()",
          "sending message to "
              + msg.getDest()
              + " (src="
              + msg.getSrc()
              + "), headers are "
              + msg.getHeaders());

      // Don't send if destination is local address. Instead, switch dst and src and put in
      // up_queue.
      // If multicast message, loopback a copy directly to us (but still multicast). Once we receive
      // this,
      // we will discard our own multicast message
    }
    if (loopback && (dest.equals(local_addr) || dest.isMulticastAddress())) {
      copy = msg.copy();
      copy.removeHeader(name);
      copy.setSrc(local_addr);
      copy.setDest(dest);
      evt = new Event(Event.MSG, copy);

      /* 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());
      }
      if (Trace.debug) {
        Trace.info("UDP.sendUdpMessage()", "looped back local message " + copy);
      }
      passUp(evt);
      if (!dest.isMulticastAddress()) {
        return;
      }
    }

    if (use_outgoing_packet_handler) {
      outgoing_queue.add(msg);
      return;
    }

    send(msg);
  }
Пример #3
0
    void bundleAndSend() {
      Map.Entry entry;
      IpAddress dest;
      ObjectOutputStream out;
      InetAddress addr;
      int port;
      byte[] data;
      List l;

      if (Trace.trace) {
        Trace.info(
            "UDP.BundlingOutgoingPacketHandler.bundleAndSend()",
            "\nsending msgs:\n" + dumpMessages(msgs));
      }
      synchronized (msgs) {
        stopTimer();

        if (msgs.size() == 0) {
          return;
        }

        for (Iterator it = msgs.entrySet().iterator(); it.hasNext(); ) {
          entry = (Map.Entry) it.next();
          dest = (IpAddress) entry.getKey();
          addr = dest.getIpAddress();
          port = dest.getPort();
          l = (List) entry.getValue();
          try {
            out_stream.reset();
            // BufferedOutputStream bos=new BufferedOutputStream(out_stream);
            out_stream.write(Version.version_id, 0, Version.version_id.length); // write the version
            // bos.write(Version.version_id, 0, Version.version_id.length); // write the version
            out = new ObjectOutputStream(out_stream);
            // out=new ObjectOutputStream(bos);
            l.writeExternal(out);
            out.close(); // needed if out buffers its output to out_stream
            data = out_stream.toByteArray();
            doSend(data, addr, port);
          } catch (IOException e) {
            Trace.error(
                "UDP.BundlingOutgoingPacketHandle.bundleAndSend()",
                "exception sending msg (to dest=" + dest + "): " + e);
          }
        }
        msgs.clear();
      }
    }
Пример #4
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);
  }
Пример #5
0
 void closeMulticastSocket() {
   if (mcast_sock != null) {
     try {
       if (mcast_addr != null) {
         // by sending a dummy packet the thread will be awakened
         sendDummyPacket(mcast_addr.getIpAddress(), mcast_addr.getPort());
         Util.sleep(300);
         mcast_sock.leaveGroup(mcast_addr.getIpAddress());
       }
       mcast_sock.close(); // this will cause the mcast receiver thread to break out of its loop
       mcast_sock = null;
       if (Trace.trace) {
         Trace.info("UDP.closeMulticastSocket()", "multicast socket closed");
       }
     } catch (IOException ex) {
     }
     mcast_addr = null;
   }
 }
Пример #6
0
  void _unregister(String group, Address mbr) {
    Socket sock = null;
    DataOutputStream out = null;
    IpAddress entry;
    GossipData gossip_req;

    for (int i = 0; i < gossip_servers.size(); i++) {
      entry = (IpAddress) gossip_servers.elementAt(i);
      if (entry.getIpAddress() == null || entry.getPort() == 0) {
        if (log.isErrorEnabled()) log.error("entry.host or entry.port is null");
        continue;
      }
      try {
        if (log.isTraceEnabled())
          log.trace(
              "UNREGISTER("
                  + group
                  + ", "
                  + mbr
                  + ") with GossipRouter at "
                  + entry.getIpAddress()
                  + ':'
                  + entry.getPort());
        sock = new Socket(entry.getIpAddress(), entry.getPort());
        out = new DataOutputStream(sock.getOutputStream());
        gossip_req = new GossipData(GossipRouter.UNREGISTER, group, mbr, null);
        // must send GossipData as fast as possible, otherwise the
        // request might be rejected
        gossip_req.writeTo(out);
        out.flush();
      } catch (Exception ex) {
        if (log.isErrorEnabled()) log.error("exception connecting to host " + entry);
      } finally {
        Util.close(out);
        if (sock != null) {
          try {
            sock.close();
          } catch (IOException e) {
          }
        }
      }
    }
  }
Пример #7
0
  /**
   * Create UDP sender and receiver sockets. Currently there are 2 sockets (sending and receiving).
   * This is due to Linux's non-BSD compatibility in the JDK port (see DESIGN).
   */
  void createSockets() throws Exception {
    InetAddress tmp_addr = null;

    // bind_addr not set, try to assign one by default. This is needed on Windows

    // changed by bela Feb 12 2003: by default multicast sockets will be bound to all network
    // interfaces

    // CHANGED *BACK* by bela March 13 2003: binding to all interfaces did not result in a correct
    // local_addr. As a matter of fact, comparison between e.g. 0.0.0.0:1234 (on hostA) and
    // 0.0.0.0:1.2.3.4 (on hostB) would fail !
    if (bind_addr == null) {
      InetAddress[] interfaces =
          InetAddress.getAllByName(InetAddress.getLocalHost().getHostAddress());
      if (interfaces != null && interfaces.length > 0) bind_addr = interfaces[0];
    }

    if (bind_addr == null) bind_addr = InetAddress.getLocalHost();

    if (bind_addr != null && Trace.trace) {
      Trace.info(
          "UDP.createSockets()",
          "unicast sockets will use interface " + bind_addr.getHostAddress());

      // 2. Create socket for receiving unicast UDP packets. The address and port
      //    of this socket will be our local address (local_addr)

      // 27-6-2003 bgooren, find available port in range (start_port, start_port+port_range)
    }
    int rcv_port = bind_port, max_port = bind_port + port_range;
    while (rcv_port <= max_port) {

      try {
        sock = new DatagramSocket(rcv_port, bind_addr);
        break;
      } catch (SocketException bind_ex) { // Cannot listen on this port
        rcv_port++;
      } catch (SecurityException sec_ex) { // Not allowed to list on this port
        rcv_port++;
      }

      // Cannot listen at all, throw an Exception
      if (rcv_port == max_port + 1) { // +1 due to the increment above
        throw new Exception(
            "UDP.createSockets(): cannot list on any port in range "
                + bind_port
                + "-"
                + (bind_port + port_range));
      }
    }
    // ucast_recv_sock=new DatagramSocket(bind_port, bind_addr);
    if (sock == null) {
      throw new Exception("UDP.createSocket(): sock is null");
    }

    local_addr = new IpAddress(sock.getLocalAddress(), sock.getLocalPort());
    if (additional_data != null) {
      local_addr.setAdditionalData(additional_data);

      // 3. Create socket for receiving IP multicast packets
    }
    if (ip_mcast) {
      mcast_sock = new MulticastSocket(mcast_port);
      mcast_sock.setTimeToLive(ip_ttl);
      if (bind_addr != null) {
        mcast_sock.setInterface(bind_addr);
      }
      tmp_addr = InetAddress.getByName(mcast_addr_name);
      mcast_addr = new IpAddress(tmp_addr, mcast_port);
      mcast_sock.joinGroup(tmp_addr);
    }

    setBufferSizes();

    if (Trace.trace) {
      Trace.info("UDP.createSockets()", "socket information:\n" + dumpSocketInfo());
    }
  }
Пример #8
0
 /** Internal method to serialize and send a message. This method is not reentrant */
 void send(Message msg) throws Exception {
   IpAddress dest = (IpAddress) msg.getDest();
   byte[] buf = messageToBuffer(msg);
   doSend(buf, dest.getIpAddress(), dest.getPort());
 }