/** 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; }
/** 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 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(); } }
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); }
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; } }
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) { } } } } }
/** * 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()); } }
/** 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()); }