Ejemplo n.º 1
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;
   }
 }
Ejemplo n.º 2
0
  public void run() {
    DatagramPacket packet;
    byte receive_buf[] = new byte[65535];
    int len;
    byte[] tmp, data;

    // moved out of loop to avoid excessive object creations (bela March 8 2001)
    packet = new DatagramPacket(receive_buf, receive_buf.length);

    while (mcast_receiver != null && mcast_sock != null) {
      try {
        packet.setData(receive_buf, 0, receive_buf.length);
        mcast_sock.receive(packet);
        len = packet.getLength();
        data = packet.getData();
        if (len == 1 && data[0] == 0) {
          if (Trace.debug) {
            Trace.info("UDP.run()", "received dummy packet");
          }
          continue;
        }

        if (len == 4) { // received a diagnostics probe
          if (data[0] == 'd' && data[1] == 'i' && data[2] == 'a' && data[3] == 'g') {
            handleDiagnosticProbe(packet.getAddress(), packet.getPort());
            continue;
          }
        }

        if (Trace.debug) {
          Trace.info(
              "UDP.receive()",
              "received (mcast) "
                  + packet.getLength()
                  + " bytes from "
                  + packet.getAddress()
                  + ":"
                  + packet.getPort()
                  + " (size="
                  + len
                  + " bytes)");
        }
        if (len > receive_buf.length) {
          Trace.error(
              "UDP.run()",
              "size of the received packet ("
                  + len
                  + ") is bigger than "
                  + "allocated buffer ("
                  + receive_buf.length
                  + "): will not be able to handle packet. "
                  + "Use the FRAG protocol and make its frag_size lower than "
                  + receive_buf.length);
        }

        if (Version.compareTo(data) == false) {
          Trace.warn(
              "UDP.run()",
              "packet from "
                  + packet.getAddress()
                  + ":"
                  + packet.getPort()
                  + " has different version ("
                  + Version.printVersionId(data, Version.version_id.length)
                  + ") from ours ("
                  + Version.printVersionId(Version.version_id)
                  + "). This may cause problems");
        }

        if (use_incoming_packet_handler) {
          tmp = new byte[len];
          System.arraycopy(data, 0, tmp, 0, len);
          incoming_queue.add(tmp);
        } else {
          handleIncomingUdpPacket(data);
        }
      } catch (SocketException sock_ex) {
        if (Trace.trace) {
          Trace.info("UDP.run()", "multicast socket is closed, exception=" + sock_ex);
        }
        break;
      } catch (InterruptedIOException io_ex) { // thread was interrupted
        ; // go back to top of loop, where we will terminate loop
      } catch (Throwable ex) {
        Trace.error("UDP.run()", "exception=" + ex + ", stack trace=" + Util.printStackTrace(ex));
        Util.sleep(300); // so we don't get into 100% cpu spinning (should NEVER happen !)
      }
    }
    if (Trace.trace) {
      Trace.info("UDP.run()", "multicast thread terminated");
    }
  }
Ejemplo n.º 3
0
  public Object down(Event evt) {
    switch (evt.getType()) {
      case Event.MSG: // Add UnicastHeader, add to AckSenderWindow and pass down
        Message msg = (Message) evt.getArg();
        Address dst = msg.getDest();

        /* only handle unicast messages */
        if (dst == null || msg.isFlagSet(Message.NO_RELIABILITY)) break;

        if (!running) {
          if (log.isTraceEnabled())
            log.trace("discarded message as start() has not yet been called, message: " + msg);
          return null;
        }

        SenderEntry entry = send_table.get(dst);
        if (entry == null) {
          entry = new SenderEntry(getNewConnectionId());
          SenderEntry existing = send_table.putIfAbsent(dst, entry);
          if (existing != null) entry = existing;
          else {
            if (log.isTraceEnabled())
              log.trace(
                  local_addr
                      + ": created connection to "
                      + dst
                      + " (conn_id="
                      + entry.send_conn_id
                      + ")");
            if (cache != null && !members.contains(dst)) cache.add(dst);
          }
        }

        short send_conn_id = entry.send_conn_id;
        long seqno = entry.sent_msgs_seqno.getAndIncrement();
        long sleep = 10;
        while (running) {
          try {
            msg.putHeader(
                this.id,
                Unicast2Header.createDataHeader(seqno, send_conn_id, seqno == DEFAULT_FIRST_SEQNO));
            entry.sent_msgs.add(seqno, msg); // add *including* UnicastHeader, adds to retransmitter
            if (conn_expiry_timeout > 0) entry.update();
            break;
          } catch (Throwable t) {
            if (!running) break;
            if (log.isWarnEnabled()) log.warn("failed sending message", t);
            Util.sleep(sleep);
            sleep = Math.min(5000, sleep * 2);
          }
        }

        if (log.isTraceEnabled()) {
          StringBuilder sb = new StringBuilder();
          sb.append(local_addr)
              .append(" --> DATA(")
              .append(dst)
              .append(": #")
              .append(seqno)
              .append(", conn_id=")
              .append(send_conn_id);
          if (seqno == DEFAULT_FIRST_SEQNO) sb.append(", first");
          sb.append(')');
          log.trace(sb);
        }

        try {
          down_prot.down(evt);
          num_msgs_sent++;
        } catch (Throwable t) {
          log.warn("failed sending the message", t);
        }
        return null; // we already passed the msg down

      case Event.VIEW_CHANGE: // remove connections to peers that are not members anymore !
        View view = (View) evt.getArg();
        List<Address> new_members = view.getMembers();
        Set<Address> non_members = new HashSet<Address>(send_table.keySet());
        non_members.addAll(recv_table.keySet());

        members = new_members;
        non_members.removeAll(new_members);
        if (cache != null) cache.removeAll(new_members);

        if (!non_members.isEmpty()) {
          if (log.isTraceEnabled()) log.trace("removing non members " + non_members);
          for (Address non_mbr : non_members) removeConnection(non_mbr);
        }
        break;

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

    return down_prot.down(evt); // Pass on to the layer below us
  }