/** * Workaround for the problem encountered in certains JDKs that a thread listening on a socket * cannot be interrupted. Therefore we just send a dummy datagram packet so that the thread 'wakes * up' and realizes it has to terminate. Should be removed when all JDKs support * Thread.interrupt() on reads. Uses sock t send dummy packet, so this socket has to be still * alive. * * @param dest The destination host. Will be local host if null * @param port The destination port */ void sendDummyPacket(InetAddress dest, int port) { DatagramPacket packet; byte[] buf = {0}; if (dest == null) { try { dest = InetAddress.getLocalHost(); } catch (Exception e) { } } if (Trace.debug) { Trace.info("UDP.sendDummyPacket()", "sending packet to " + dest + ":" + port); } if (sock == null || dest == null) { Trace.warn( "UDP.sendDummyPacket()", "sock was null or dest was null, cannot send dummy packet"); return; } packet = new DatagramPacket(buf, buf.length, dest, port); try { sock.send(packet); } catch (Throwable e) { Trace.error( "UDP.sendDummyPacket()", "exception sending dummy packet to " + dest + ":" + port + ": " + e); } }
public void run() { Event evt; while (evt_thread != null && event_queue != null) { try { evt = (Event) event_queue.remove(); switch (evt.getType()) { case Event.SUSPECT: impl.suspect((Address) evt.getArg()); break; case Event.MERGE: impl.merge((Vector) evt.getArg()); break; default: Trace.error( "GMS.run()", "event handler thread encountered event of type " + Event.type2String(evt.getType()) + ": not handled by me !"); break; } } catch (QueueClosedException closed) { break; } catch (Exception ex) { Trace.warn("GMS.run()", "exception=" + ex); } } }
/** * Processes a packet read from either the multicast or unicast socket. Needs to be synchronized * because mcast or unicast socket reads can be concurrent */ void handleIncomingUdpPacket(byte[] data) { ByteArrayInputStream inp_stream; ObjectInputStream inp; Message msg = null; List l; // used if bundling is enabled try { // skip the first n bytes (default: 4), this is the version info inp_stream = new ByteArrayInputStream(data, VERSION_LENGTH, data.length - VERSION_LENGTH); inp = new ObjectInputStream(inp_stream); if (enable_bundling) { l = new List(); l.readExternal(inp); for (Enumeration en = l.elements(); en.hasMoreElements(); ) { msg = (Message) en.nextElement(); try { handleMessage(msg); } catch (Throwable t) { Trace.error("UDP.handleIncomingUdpPacket()", "failure: " + t.toString()); } } } else { msg = new Message(); msg.readExternal(inp); handleMessage(msg); } } catch (Throwable e) { Trace.error("UDP.handleIncomingUdpPacket()", "exception=" + Trace.getStackTrace(e)); } }
void setBufferSizes() { if (sock != null) { try { sock.setSendBufferSize(ucast_send_buf_size); } catch (Throwable ex) { Trace.warn("UDP.setBufferSizes()", "failed setting ucast_send_buf_size in sock: " + ex); } try { sock.setReceiveBufferSize(ucast_recv_buf_size); } catch (Throwable ex) { Trace.warn("UDP.setBufferSizes()", "failed setting ucast_recv_buf_size in sock: " + ex); } } if (mcast_sock != null) { try { mcast_sock.setSendBufferSize(mcast_send_buf_size); } catch (Throwable ex) { Trace.warn( "UDP.setBufferSizes()", "failed setting mcast_send_buf_size in mcast_sock: " + ex); } try { mcast_sock.setReceiveBufferSize(mcast_recv_buf_size); } catch (Throwable ex) { Trace.warn( "UDP.setBufferSizes()", "failed setting mcast_recv_buf_size in mcast_sock: " + ex); } } }
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); }
/** Send a message to the address specified in msg.dest */ private void sendUnicastMessage(Message msg) { IpAddress dest; Message copy; Object hdr; Event evt; dest = (IpAddress) msg.getDest(); // guaranteed not to be null if (!(dest instanceof IpAddress)) { Trace.error("TCP.sendUnicastMessage()", "destination address is not of type IpAddress !"); return; } setSourceAddress(msg); /* Don't send if destination is local address. Instead, switch dst and src and put in up_queue */ if (loopback && local_addr != null && dest != null && dest.equals(local_addr)) { copy = msg.copy(); hdr = copy.getHeader(getName()); if (hdr != null && hdr instanceof TcpHeader) copy.removeHeader(getName()); copy.setSrc(local_addr); copy.setDest(local_addr); 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()); passUp(evt); return; } if (Trace.trace) Trace.info( "TCP.sendUnicastMessage()", "dest=" + msg.getDest() + ", hdrs:\n" + msg.printObjectHeaders()); try { if (skip_suspected_members) { if (suspected_mbrs.contains(dest)) { if (Trace.trace) Trace.info( "TCP.sendUnicastMessage()", "will not send unicast message to " + dest + " as it is currently suspected"); return; } } ct.send(msg); } catch (SocketException e) { if (members.contains(dest)) { if (!suspected_mbrs.contains(dest)) { suspected_mbrs.add(dest); passUp(new Event(Event.SUSPECT, dest)); } } } }
/** * Compute a new view, given the current view, the new members and the suspected/left members. Run * view update protocol to install a new view in all members (this involves casting the new view * to all members). The targets for FLUSH and VIEW mcasts are computed as follows: * * <p> * * <pre> * existing leaving suspected joining * <p/> * 1. FLUSH y y n n * 2. new_view y n n y * 3. tmp_view y y n y * (view_dest) * </pre> * * <p> * * <ol> * <li>The FLUSH is only sent to the existing and leaving members (they are the only ones that * might have old messages not yet seen by the group. The suspected members would not answer * anyway (because they have failed) and the joining members have certainly no old messages. * <li>The new view to be installed includes the existing members plus the joining ones and * excludes the leaving and suspected members. * <li>A temporary view is sent down the stack as an <em>event</em>. This allows the bottom * layer (e.g. UDP or TCP) to determine the members to which to send a multicast message. * Compared to the new view, leaving members are <em>included</em> since they have are * waiting for a view in which they are not members any longer before they leave. So, if we * did not set a temporary view, joining members would not receive the view (signalling that * they have been joined successfully). The temporary view is essentially the current view * plus the joining members (old members are still part of the current view). * </ol> */ public void castViewChange(Vector new_mbrs, Vector old_mbrs, Vector suspected_mbrs) { View new_view, tmp_view; ViewId new_vid; Vector flush_dest = computeFlushDestination(suspected_mbrs); // members to which FLUSH/VIEW is sent Vector view_dest = computeViewDestination(new_mbrs, old_mbrs, suspected_mbrs); // dest for view change // next view: current mbrs + new_mbrs - old_mbrs - suspected_mbrs new_view = getNextView(new_mbrs, old_mbrs, suspected_mbrs); new_vid = new_view.getVid(); if (Trace.trace) Trace.info( "GMS.castViewChange()", "flush_dest: " + flush_dest + "\n\tview_dest: " + view_dest + "\n\tnew_view: " + new_view + "\n"); flush(flush_dest, suspected_mbrs); /* VIEW protocol. Send to current mbrs + new_mbrs + old_mbrs - suspected_mbrs. Since suspected members were removed from view_dest during the previous FLUSH round(s), we only need to add the new members. Send TMP_VIEW event down, this allows FLUSH/NAKACK to set membership correctly */ view_dest = computeViewDestination(new_mbrs, old_mbrs, suspected_mbrs); tmp_view = new View(null, view_dest); Event view_event = new Event(Event.TMP_VIEW, tmp_view); // so the VIEW msg is sent to the correct mbrs passDown(view_event); // needed e.g. by failure detector or UDP if (Trace.trace) Trace.info("GMS.castViewChange()", "mcasting view {" + new_vid + ", " + view_dest + "}"); passDown(new Event(Event.SWITCH_NAK_ACK)); // use ACK scheme for view bcast Object[] args = new Object[] {new_vid, new_view.getMembers() /* these are the mbrs in the new view */}; MethodCall call = new MethodCall( "handleViewChange", args, new String[] {ViewId.class.getName(), Vector.class.getName()}); callRemoteMethods( view_dest, // send to all members in 'view_dest' call, GroupRequest.GET_ALL, view_change_timeout); if (Trace.trace) Trace.info("GMS.castViewChange()", "mcasting view completed"); passDown(new Event(Event.SWITCH_NAK)); // back to normal NAKs ... }
/** 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); }
void handleDiagnosticProbe(InetAddress sender, int port) { try { byte[] diag_rsp = getDiagResponse().getBytes(); DatagramPacket rsp = new DatagramPacket(diag_rsp, 0, diag_rsp.length, sender, port); if (Trace.trace) { Trace.info( "UDP.handleDiagnosticProbe()", "sending diag response to " + sender + ":" + port); } sock.send(rsp); } catch (Throwable t) { Trace.error( "UDP.handleDiagnosticProbe()", "failed sending diag rsp to " + sender + ":" + port + ", exception=" + t); } }
public void stop() { if (Trace.trace) { Trace.info("UDP.stop()", "closing sockets and stopping threads"); } stopThreads(); // will close sockets, closeSockets() is not really needed anymore, but... closeSockets(); // ... we'll leave it in there for now (doesn't do anything if already closed) }
public void setImpl(GmsImpl new_impl) { synchronized (impl_mutex) { impl = new_impl; if (Trace.trace) Trace.info("GMS.setImpl()", "changed role to " + new_impl.getClass().getName()); } }
/** * <b>Callback</b>. Called by superclass when event may be handled. * * <p><b>Do not use <code>PassDown</code> in this method as the event is passed down by default by * the superclass after this method returns !</b> * * @return boolean Defaults to true. If false, event will not be passed down the stack. */ public boolean handleDownEvent(Event evt) { switch (evt.getType()) { case Event.CONNECT: passDown(evt); try { group_addr = (String) evt.getArg(); } catch (ClassCastException cce) { Trace.error( "GMS.handleDownEvent(CONNECT)", "group address must " + "be a string (group name) to make sense"); } impl.join(local_addr); passUp(new Event(Event.CONNECT_OK)); startEventHandlerThread(); return false; // don't pass down: was already passed down case Event.DISCONNECT: impl.leave((Address) evt.getArg()); passUp(new Event(Event.DISCONNECT_OK)); stopEventHandlerThread(); initState(); return true; // pass down } return impl.handleDownEvent(evt); }
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(); } }
/** * Creates the unicast and multicast sockets and starts the unicast and multicast receiver threads */ public void start() throws Exception { if (Trace.trace) { Trace.info("UDP.start()", "creating sockets and starting threads"); } createSockets(); passUp(new Event(Event.SET_LOCAL_ADDRESS, local_addr)); startThreads(); }
/** * @param ri * @param cet * @param b_addr * @param s_port * @throws Exception * @return ConnectionTable Sub classes overrides this method to initialize a different version of * ConnectionTable. */ protected ConnectionTable getConnectionTable(long ri, long cet, InetAddress b_addr, int s_port) throws Exception { ConnectionTable cTable = null; if (ri == 0 && cet == 0) { cTable = new ConnectionTable(this, b_addr, start_port); } else { if (ri == 0) { ri = 5000; Trace.warn("TCP.start()", "reaper_interval was 0, set it to " + ri); } if (cet == 0) { cet = 1000 * 60 * 5; Trace.warn("TCP.start()", "conn_expire_time was 0, set it to " + cet); } cTable = new ConnectionTable(this, b_addr, s_port, ri, cet); } return cTable; }
public View handleMerge(ViewId other_vid, Vector other_members) { synchronized (impl_mutex) { if (Trace.trace) { View v = impl.handleMerge(other_vid, other_members); Trace.info("GMS.handleMerge()", "returning view: " + v); return v; } return impl.handleMerge(other_vid, other_members); } }
public void run() { Message msg; while (outgoing_queue != null && outgoing_packet_handler != null) { try { msg = (Message) outgoing_queue.remove(); handleMessage(msg); } catch (QueueClosedException closed_ex) { if (Trace.trace) { Trace.info("UDP.OutgoingPacketHandler.run()", "packet_handler thread terminating"); } break; } catch (Throwable t) { Trace.error( "UDP.OutgoingPacketHandler.run()", "exception sending packet: " + Util.printStackTrace(t)); } msg = null; // let's give the poor garbage collector a hand... } }
void closeSocket() { if (sock != null) { // by sending a dummy packet, the thread will terminate (if it was flagged as stopped before) sendDummyPacket(sock.getLocalAddress(), sock.getLocalPort()); sock.close(); sock = null; if (Trace.trace) { Trace.info("UDP.closeSocket()", "socket closed"); } } }
/** ConnectionTable.Receiver interface */ public void receive(Message msg) { TcpHeader hdr = null; Event evt = new Event(Event.MSG, msg); /* 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.trace) Trace.info("TCP.receive()", "received msg " + msg); // if(Trace.trace) // Trace.info("TCP.receive()", "src=" + msg.getSrc() + ", hdrs:\n" + msg.printObjectHeaders()); hdr = (TcpHeader) msg.removeHeader(getName()); 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; // below lines were commented as patch sent by Roland Kurmann (bela March 20 2003) // if(group_addr == null) { // if(Trace.trace) Trace.warn("TCP.receive()", "group address in header was // null, discarded"); // return; // } // 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.equals(ch_name) && !ch_name.equals(Util.DIAG_GROUP)) { Trace.warn( "TCP.receive()", "discarded message from different group (" + ch_name + "). Sender was " + msg.getSrc()); return; } } passUp(evt); }
/** Starts the unicast and multicast receiver threads */ void startThreads() throws Exception { if (ucast_receiver == null) { // start the listener thread of the ucast_recv_sock ucast_receiver = new UcastReceiver(); ucast_receiver.start(); if (Trace.trace) { Trace.info("UDP.startThreads()", "created unicast receiver thread"); } } if (ip_mcast) { if (mcast_receiver != null) { if (mcast_receiver.isAlive()) { if (Trace.trace) { Trace.info( "UDP.createThreads()", "did not create new multicastreceiver thread as existing " + "multicast receiver thread is still running"); } } else { mcast_receiver = null; // will be created just below... } } if (mcast_receiver == null) { mcast_receiver = new Thread(this, "UDP mcast receiver"); mcast_receiver.setPriority(Thread.MAX_PRIORITY); // needed ???? mcast_receiver.setDaemon(true); mcast_receiver.start(); } } if (use_outgoing_packet_handler) { outgoing_packet_handler.start(); } if (use_incoming_packet_handler) { incoming_packet_handler.start(); } }
public void start() throws Exception { super.start(); if (checkForViewEnforcer(up_prot) == false) { Trace.warn( "GMS.start()", "I need protocol layer " + "VIEW_ENFORCER above me to discard messages sent to me while I'm " + "not yet a group member ! Otherwise, these messages will be delivered " + "to the application without checking...\n"); } if (_corr != null) _corr.setDeadlockDetection(true); else throw new Exception("GMS.start(): cannot set deadlock detection in corr, as it is null !"); }
void sendMultipleUdpMessages(Message msg, Vector dests) { Address dest; for (int i = 0; i < dests.size(); i++) { dest = (Address) dests.elementAt(i); msg.setDest(dest); try { sendUdpMessage(msg); } catch (Exception e) { Trace.debug("UDP.sendMultipleUdpMessages()", "exception=" + e); } } }
/** * handle the UP event. * * @param evt - the event being send from the stack */ public void up(Event evt) { passUp(evt); switch (evt.getType()) { case Event.CONFIG: passUp(evt); if (Trace.trace) { Trace.info("UDP.up()", "received CONFIG event: " + evt.getArg()); } handleConfigEvent((HashMap) evt.getArg()); return; } passUp(evt); }
public void run() { byte[] data; while (incoming_queue != null && incoming_packet_handler != null) { try { data = (byte[]) incoming_queue.remove(); } catch (QueueClosedException closed_ex) { if (Trace.trace) { Trace.info("UDP.IncomingPacketHandler.run()", "packet_handler thread terminating"); } break; } handleIncomingUdpPacket(data); data = null; // let's give the poor garbage collector a hand... } }
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; } }
protected void handleMessage(Message msg) throws Exception { Address dest = msg.getDest(); long len; List tmp; len = msg.size(); // todo: use msg.getLength() instead of msg.getSize() if (len > max_bundle_size) { throw new Exception( "UDP.BundlingOutgoingPacketHandler.handleMessage(): " + "message size (" + len + ") is greater than UDP fragmentation size. " + "Set the fragmentation/bundle size in FRAG and UDP correctly"); } if (total_bytes + len >= max_bundle_size) { if (Trace.trace) { Trace.info( "UDP.BundlingOutgoingPacketHandler.handleMessage()", "sending " + total_bytes + " bytes"); } bundleAndSend(); // send all pending message and clear table total_bytes = 0; } synchronized (msgs) { tmp = (List) msgs.get(dest); if (tmp == null) { tmp = new List(); msgs.put(dest, tmp); } tmp.add(msg); total_bytes += len; } if (!timer_running) { // first message to be bundled startTimer(); } }
void handleDownEvent(Event evt) { switch (evt.getType()) { case Event.TMP_VIEW: case Event.VIEW_CHANGE: synchronized (members) { members.removeAllElements(); Vector tmpvec = ((View) evt.getArg()).getMembers(); for (int i = 0; i < tmpvec.size(); i++) { members.addElement(tmpvec.elementAt(i)); } } break; case Event.GET_LOCAL_ADDRESS: // return local address -> Event(SET_LOCAL_ADDRESS, local) passUp(new Event(Event.SET_LOCAL_ADDRESS, local_addr)); break; case Event.CONNECT: group_addr = (String) evt.getArg(); udp_hdr = new UdpHeader(group_addr); // removed March 18 2003 (bela), not needed (handled by GMS) // changed July 2 2003 (bela): we discard CONNECT_OK at the GMS level anyway, this might // be needed if we run without GMS though passUp(new Event(Event.CONNECT_OK)); break; case Event.DISCONNECT: passUp(new Event(Event.DISCONNECT_OK)); break; case Event.CONFIG: if (Trace.trace) { Trace.info("UDP.down()", "received CONFIG event: " + evt.getArg()); } handleConfigEvent((HashMap) evt.getArg()); break; } }
/** Sent to destination(s) using the ConnectionTable class. */ public void down(Event evt) { Message msg; Object dest_addr; if (evt.getType() != Event.MSG) { handleDownEvent(evt); return; } msg = (Message) evt.getArg(); if (group_addr != null) { // added patch sent by Roland Kurmann (bela March 20 2003) /* Add header (includes channel name) */ msg.putHeader(getName(), new TcpHeader(group_addr)); } dest_addr = msg.getDest(); /* Because we don't call Protocol.passDown(), we notify the observer directly (e.g. PerfObserver). This way, we still have performance numbers for TCP */ if (observer != null) observer.passDown(evt); if (dest_addr == null) { // broadcast (to all members) if (group_addr == null) { Trace.warn( "TCP.down()", "dest address of message is null, and " + "sending to default address fails as group_addr is null, too !" + " Discarding message."); return; } else { sendMulticastMessage(msg); // send to current membership } } else { sendUnicastMessage(msg); // send to a single member } }
private void handleDownEvent(Event evt) { switch (evt.getType()) { case Event.TMP_VIEW: case Event.VIEW_CHANGE: suspected_mbrs.removeAll(); synchronized (members) { members.clear(); members.addAll(((View) evt.getArg()).getMembers()); } break; case Event.GET_LOCAL_ADDRESS: // return local address -> Event(SET_LOCAL_ADDRESS, local) passUp(new Event(Event.SET_LOCAL_ADDRESS, local_addr)); break; case Event.CONNECT: group_addr = (String) evt.getArg(); // removed March 18 2003 (bela), not needed (handled by GMS) // Can't remove it; otherwise TCPGOSSIP breaks (bela May 8 2003) ! passUp(new Event(Event.CONNECT_OK)); break; case Event.DISCONNECT: passUp(new Event(Event.DISCONNECT_OK)); break; case Event.CONFIG: if (Trace.trace) Trace.info("UDP.down()", "received CONFIG event: " + evt.getArg()); handleConfigEvent((HashMap) evt.getArg()); break; case Event.ACK: passUp(new Event(Event.ACK_OK)); break; } }
/** * 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()); } }