⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 endpointrouter.java

📁 jxme的一些相关程序,主要是手机上程序开发以及手机和计算机通信的一些程序资料,程序编译需要Ant支持
💻 JAVA
📖 第 1 页 / 共 5 页
字号:

    private synchronized void waitABit() {

        // We'll still wake if something interresting happens.
        try {
            wait(500);
        } catch (Exception e) {
            if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getAddress got an exception " + e + " while waiting");
        }
    }

    /**
     * Give a peer id, return an address to reach that peer.
     * The address may be for a directly reachable peer, or
     * for the first gateway along a route to reach the peer.
     * If we do not have a route to the peer, we will use the
     * Peer Routing Protocol to try to discover one.  We will
     * wait up to a minute for a route to be discovered.
     */
    public EndpointAddress getAddress(String pId) {

        // Compacting the cache first is a good idea if we want to
        // get the best route. Note that compactCaches() can be expensive,
        // but:
        //        - it is saving time and network bandwith ahead of time
        //        - the proces of compacting happens only if there has been
        //          a change in the caches.
        //
        // So, all together, this seems to be a good optimization.
        //
        if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getAddress for ");
        if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("      peer= " + pId);

        Route route = null;
        int count = 0;

        while (true) {

            // Then check if by anychance we can talk to it directly.
            learnLocalRoute(pId);

            // So, is there a local route ?
            if (isLocalRoute(pId)) {
                if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Found local address: " + pId + " -> " +
                         getLocalRoute(pId).toString());
                return getLocalRoute(pId);
            }

            // Otherwise, look for a long route.
            route = getRoute(pId);
            EndpointAddress addr = null;

            if (route != null) {

                try {
                    addr = getLocalRoute(route.router);
		    if (addr != null) {
			if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Found remote address: " + pId +
                             " -> " + addr.toString());
		    } else {
			if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("Found an not reachable route");
		    }
		    return addr;
                } catch (Exception e) {
                    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getAddress for " + pId);
                    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("     failed with " + e);
                    return null;
                }
            }


            // Trying to recover a route
            if (count == 0) {
                // this is the first time in the loop.
                findRoute(pId);
            }

            // Give up after at most 1 minute
            if (++count > 120) {
                if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getAddress is giving up for " + pId);
                break;
            }

            // Just wait a bit
            waitABit();

        }
        return null;
    }

    /**
     * Given a list of addresses, find the fastest reachable address.
     *
     * The address returned must be pingable.<BR>
     * We prefer an address whose protocol is, in order:<BR>
     * <ol>
     * <li>connected and fast.
     * <li>connected and slow.
     * <li>unconnected and fast.
     * <li>unconnected and slow
     * </ol>
     *
     * @param addrs A list of addresses to evaulate reachability.
     */
    public EndpointAddress getBestLocalRoute(Enumeration addrs) {

        //todo: Evaluate why peer is an arg.  Remove it if not needed.
        if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getBestLocalRoute:");

        EndpointProtocol proto = null;
        EndpointAddress addr = null;
        EndpointAddress bestAddr = null;
        String protoName = null;
        boolean direct = false;
        boolean fast = false;

        while (addrs.hasMoreElements()) {
            try {
                addr = (EndpointAddress) addrs.nextElement();

                protoName = addr.getProtocolName();

                // Ignore ourselves
                if (protoName.equals(getProtocolName())) continue;

                proto = endpoint.getEndpointProtocolByName(protoName);
                if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getBestLocalRoute trying: " + addr.toString()
                          + " on protocol " + proto.getProtocolName());
                if (proto == null) {
                    continue;
                }

		if (!proto.allowRouting()) {
		    // This protocol should not be used for routing.
		    continue;
		}


                if (!proto.ping(addr)) {
                    // This protocol cannot reach the target addr
                    continue;
                }

                if (bestAddr == null) {
                    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Found: " + addr.toString());
                    bestAddr = addr;
                }

                if (proto.isConnectionOriented()) {
                    if (direct) {
                        // There is already a protocol supporting
                        // a direct connection to the target addr.
                        if (isFast (proto)) {
                            return addr;
                        }
                        continue;
                    } else {
                        direct = true;
                        if (isFast (proto)) {
                            return addr;
                        } else {
                            bestAddr = addr;
                            continue;
                        }
                    }
                } else {
                    if (direct) {
                        continue;
                    } else {
                        bestAddr = addr;
                        continue;
                    }
                }
            } catch (Exception e) {
                // That address is somehow broken.
                // Cache that result for a while (5 minutes).
                triedAndFailed.put(addr,
                                   new Long(System.currentTimeMillis()));
                continue;
            }
        }

        return bestAddr;
    }

    boolean isFast (EndpointProtocol p) {
	String name = p.getProtocolName ();

    //PDA requirement 18.02.2002
    // beepcore protocol is not present on a PDA for the time being
	// return name.equals ("tcp") || name.equals ("beep");
    //PDA requirement 18.02.2002
	return name.equals ("tcp");
    }

    /**
     * Returns true if the target address is reachable. Otherwise
     * returns false.
     */
    public boolean ping (EndpointAddress addr) {

        try {
            return (getAddress(addr.getProtocolName() + "://"
                               + addr.getProtocolAddress()) != null);
        } catch (Exception e) {
            return false;
        }
    }

    public synchronized boolean isLocalRoute(String pId) {

        if (directRoutes.containsKey(pId)) {
            return true;
        }
        return false;
    }

    public synchronized EndpointAddress getLocalRoute(String pId) {
        return (EndpointAddress)directRoutes.get(pId);
    }

    // Adds a new local route only if it is new. Takes care
    // of deleting a remote route etc. Returns true if the route was added.
    private synchronized void learnLocalRouteSync(String pId,
                                                  EndpointAddress addr) {


        if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("learnLocalRoute:");
        if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("   peerId = " + pId);

        try {
            directRoutes.put(pId, addr.clone());
        } catch (Exception e) {
            return; // Failed. Keep things as they were.
        }

        try {
            // If we had a long route, remove it
            routedRoutes.remove(pId);
        } catch(Exception e2) {
            // Fine.
        }

        notifyAll(); // Tell all those that may be waiting for a route
        return;
    }

    // Adds a new local route only if it is new. Takes care
    // of deleting a remote route, etc.
    public void learnLocalRoute(String pId) {

        // Here we're not synchronized, so this is a hint.
        // If later we decide to add this address and it has been already by
        // another thread it will not do any damage. But we're about to do a big
        // task possibly, so we want to make sure it's not for nothing.
        // That's why this test is important here, and not in the synchronized
        // method.

        if (directRoutes.containsKey(pId)) return; // nothing new.

        // We presume that we are able to directly talk to this peer and we weren't
        // before. This has do be checked.
	EndpointAddress addr = checkPeer (pId);
	if (addr == null) {
	    // No local route
	    return;
	}

        learnLocalRouteSync(pId, addr);
    }

    public synchronized void removeLocalRoute(String pId) {

        try {
            directRoutes.remove(pId);
        } catch (Exception e) {
        }
    }

    // We could be given the address and remove it from our hash table, but unfortunately
    // our hashtable is in the other direction and so it is much less expensive to
    // start from the destination peer and find-out if the bad direct route is to that peer
    // or to the first hop on a long route.
    private void brokenRoute(String peer) {
        if (isLocalRoute(peer)) {
            removeLocalRoute(peer);
            return;
        }

        // Otherwise, look for a long route.
        Route route = getRoute(peer);
        if (route != null) {
            removeLocalRoute(route.router);
            removeRoute(peer);
        }
    }

    public synchronized boolean isRoute(String pId) {
        return routedRoutes.get(pId) != null;
    }

    public synchronized Route getRoute(String pId) {
        return (Route) routedRoutes.get(pId);
    }

    // Check if a route is valid.
    // Currentely, only loops are detected.
    private boolean checkRoute (Route r) {

	if (r == null) {
	    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("route is null");
	    return false;
	}

	if ((r.gateways == null) || (r.gateways.size() == 0)) {
	    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("route is empty");
	    return false;
	}

	if (r.gateways.contains (localPeerAddr)) {
	    // The route does contain this local peer. Using this route
	    // would create a loop. Discard.
	    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("route contains this peer - loopback");
	    return false;
	}

	// Now check for any other potential loops.
	Vector peers = new Vector();
	for (int i=0; i < r.gateways.size(); ++i) {
	    try {
		if (peers.contains ((String) r.gateways.elementAt (i))) {
		    // This is a loop.
		    return false;
		} else {
            //PDA requirement 18.02.2002
            // Vector.add -> Vector.addElement
            // peers.add (r.gateways.elementAt(i));
		    peers.addElement (r.gateways.elementAt(i));
		}
	    } catch (Exception ez1) {
		// Not much we can do here
		if (LOG.isEnabledFor(Priority.WARN)) LOG.warn ("Exception while processing route checking: " + ez1);
		return false;
	    }
	}
	// Seems to be a potential good route.
	if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("route is ok");
	return true;
    }

    // Adds a new long route provided there not a direct one already.
    // Replaces any longer route.
    // return true if the route was truely new.
    private synchronized boolean setRoute(Route r) {

        if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("setRoute:");
	if (r == null) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -