HostManager.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.furthurnet.furi |
![]() |
![]() |
Furthurnet |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* FURI - A distributed peer-to-peer file sharing system.
* Copyright (C) 2000-2003 William W. Wong, Furthur Network
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.furthurnet.furi;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Hashtable;
import java.util.NoSuchElementException;
import java.util.Vector;
import org.furthurnet.datastructures.supporting.BandwidthUser;
import org.furthurnet.datastructures.supporting.SpeedCalculator;
import org.furthurnet.datastructures.supporting.SpeedManager;
public class HostManager
{
private Vector mHosts;
private Vector mConnectedHosts;
private IHostChanged mHostChangedListener = null;
private DataChanger mHostCountChangedListener = new DataChanger();
private DataChanger mStatusChangedListener = new DataChanger();
private int mStatHosts = 0;
private int mStatFiles = 0;
private long mStatSize = 0;
private String mStatSizeStr = "0";
private int mStatTakenCount = 0;
private int mStatMsgCount = 0;
private int mStatDropCount = 0;
private int mStatUploadCount = 0;
private int mStatDownloadCount = 0;
private Vector mHostsCaught = new Vector();
private Hashtable mHostsCaughtUnique = new Hashtable();
private boolean mHostsCaughtChanged = false;
private long mLastSaved = System.currentTimeMillis();
private long mRateTime0 = System.currentTimeMillis();
private int mRateBytes = 0;
private int mOldRate = 0;
private String[] starterHosts;
private boolean noMoreStats = false;
private int caughtHostIndex = 0;
public SpeedMonitor upstreamMonitor = new SpeedMonitor(BandwidthUser.UPSTREAM);
public SpeedMonitor downstreamMonitor = new SpeedMonitor(BandwidthUser.DOWNSTREAM);
HostManager() {
mHosts = new Vector();
mConnectedHosts = new Vector();
newRateSamplePeriod();
SpeedManager.addBandwidthUser(upstreamMonitor);
SpeedManager.addBandwidthUser(downstreamMonitor);
}
public void setNoMoreStats(boolean noMoreStats) {
this.noMoreStats = noMoreStats;
}
public boolean isNoMoreStats() {
return noMoreStats;
}
public void bootNetwork() {
Vector bootHosts = getBootHosts();
for (int cv = 0; cv < bootHosts.size(); cv++) {
Host host = new Host(this);
host.setType(Host.sTypeOutgoing);
host.setHostAddr((String)bootHosts.get(cv));
mHosts.addElement(host);
BootNetReadWorker bnrw = new BootNetReadWorker(host);
bnrw.run();
if (mHostsCaught.size() >= 1)
{
break;
}
}
// load default hosts
addStarterCacheProxy();
// load any cached host
loadHosts();
}
private String[] getHosts(File file) {
String[] hosts = null;
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(file));
Vector hostVector = new Vector();
String line = in.readLine();
while (line != null) {
// Skip comments
if (line.charAt(0) != (char)'#')
hostVector.add(line);
line = in.readLine();
}
in.close();
in = null;
hosts = new String[hostVector.size()];
for (int i = 0; i < hostVector.size(); i++)
hosts[i] = (String)hostVector.elementAt(i);
}
catch (IOException e) {
if (in != null) {
try {
in.close();
}
catch (IOException ex) {}
}
hosts = new String[0];
}
return hosts;
}
public void loadHosts() {
String[] hosts = getHosts(ServiceManager.getHostsFile());
for (int cv = 0; cv < hosts.length; cv++) {
if (validateHost(hosts[cv])){
addHostCaughtForced(hosts[cv],true,true);
}
}
// addStarterCacheProxy();
}
private Vector getBootHosts() {
return ServiceManager.getManager().getMainFrame().getBootHosts();
}
private String[] getStarterHosts() {
if (starterHosts == null || starterHosts.length == 0) {
starterHosts = new String[20];
// starter hosts is searched in reverse order. we want rs20 checked first
// so populate in **normal** fashion
for (int i = 0; i < starterHosts.length; i++) {
starterHosts[i] = "rs" + (i+1) + ".furthurnet.org:4200";
}
}
return starterHosts;
}
private boolean isStarterHost(Host host) {
String hostStr = host.toString();
for (int idx = 0; idx < starterHosts.length; idx++) {
if (hostStr.equalsIgnoreCase(starterHosts[idx]))
return true;
}
return false;
}
private void addStarterCacheProxy() {
String[] list = getStarterHosts();
for (int i = 0; i < list.length; i++) {
if (validateHost(list[i])){
addHostCaughtForced(list[i], false,true);
}
}
}
void removeStartHosts() {
String[] list = getStarterHosts();
for (int i = 0; i < list.length; i++) {
removeHostCaught(list[i]);
}
}
public Vector getHosts() {
return mHosts;
}
public synchronized void connectAllOutgoingHosts() {
for (int i = 0; i < mHosts.size(); i++) {
connectHost(i);
}
}
public synchronized void connectHost(int index) {
if (index >= mHosts.size())
return;
Host host = (Host)mHosts.elementAt(index);
if (host.getType() != Host.sTypeOutgoing)
return;
if (host.getSock() != null) {
int status = host.getStatus();
if (status == Host.sStatusError ||
status == Host.sStatusNotConnected ||
status == Host.sStatusTimeout ||
status == Host.sStatusDropped) {
disconnectHost(index);
}
else {
if (host.getAttemptReconnect()) {
try {
throw new Exception("Attempting reconnect on already connected host");
}
catch (Exception e) {
e.printStackTrace();
}
}
return;
}
}
new ReadWorker(host, 0);
}
public synchronized void disconnectHost(int index) {
if (index >= mHosts.size())
return;
Host host = (Host)mHosts.elementAt(index);
host.closeConnection();
}
public synchronized void disconnectFirstConnectedHost() {
if (mConnectedHosts.size() == 0)
return;
Host host = (Host)mConnectedHosts.elementAt(0);
host.closeConnection();
}
public synchronized void disconnectAll() {
for (int i = 0; i < mHosts.size(); i++) {
disconnectHost(i);
}
}
public synchronized void timeoutOutgoingHosts() {
for (int i = 0; i < mHosts.size(); i++) {
Host host = (Host)mHosts.elementAt(i);
if (host.isConnectingTimeout()) {
host.setStatus(Host.sStatusTimeout, "");
}
}
}
public synchronized int addOutgoingHost(String hostAddrStr) {
//
// Make sure it's a valid host
//
if (!validateHost(hostAddrStr)){
return - 1;
}
// Check for duplicate.
for (int i = 0; i < mHosts.size(); i++) {
Host host = (Host)mHosts.elementAt(i);
if (host.getType() == Host.sTypeOutgoing &&
host.getHostAddr().equals(hostAddrStr)) {
return -1;
}
}
int index = mHosts.size();
Host host = new Host(this);
host.setType(Host.sTypeOutgoing);
host.setHostAddr(hostAddrStr);
mHosts.addElement(host);
// Insert in the front so that will use it first in restart.
addHostCaughtForced(hostAddrStr,false,true);
try {
saveHosts();
}
catch (IOException e) {
System.out.println(e);
}
return index;
}
private boolean validateHost (String hostAddrStr) {
boolean retVal = true;
String ip;
int port;
if (hostAddrStr.indexOf(":") > 0) {
ip = hostAddrStr.substring(0, hostAddrStr.indexOf(":"));
port = Integer.parseInt(hostAddrStr.substring(hostAddrStr.indexOf(":") + 1));
if (port < 1) {
retVal = false;
}
if (isHostInvalid(ip)) {
retVal = false;
}
}
else {
// No port number, fuhgettaboutit.
retVal = false;
}
return retVal;
}
public synchronized void addIncomingHost(Host host) {
mHosts.addElement(host);
getHostChangedListener().hostChanged();
}
public synchronized void removeHost(int index) {
if (index >= mHosts.size())
return;
Host host = (Host)mHosts.elementAt(index);
host.closeConnection();
removeFromPushRoutingTable(null, index);
mHosts.removeElementAt(index);
}
private synchronized void removeFromPushRoutingTable(Host host, int index) {
if (host == null)
host = (Host)mHosts.elementAt(index);
ServiceManager.getMsgManager().removeFromPushRoutingTable(host);
}
public synchronized void removeAll() {
while (mHosts.size() > 0) {
removeHost(0);
}
}
public int getConnectedHostCount() {
return mConnectedHosts.size();
}
public synchronized int cleanupAndGetLiveHostCount() {
int count = 0;
int size = mHosts.size();
for (int i = 0; i < size; i++) {
Host host = (Host)mHosts.elementAt(i);
int status = host.getStatus();
if (status == Host.sStatusConnected ||
status == Host.sStatusConnecting ||
status == Host.sStatusAccepting) {
count++;
}
else {
if (ServiceManager.getCfg().mAutoCleanup &&
host.isErrorStatusExpired()) {
if (willAttemptReconnect(host)) {
host.incReconnectAttempts();
connectHost(i);
count++;
}
else {
removeHost(i);
size--;
i--;
}
}
}
}
return count;
}
public boolean willAttemptReconnect(Host host) {
if (host.getAttemptReconnect() && !isStarterHost(host) &&
host.getType() == Host.sTypeOutgoing) {
return true;
}
return false;
}
public synchronized Host getConnectedHost(int i) {
return (Host)mConnectedHosts.elementAt(i);
}
public synchronized void addConnectedHost(Host host) {
mConnectedHosts.addElement(host);
setHostCaughtConnectionFailed(host.getHostAddr(), false);
mHostCountChangedListener.dataChanged(mConnectedHosts);
mStatusChangedListener.dataChanged(null);
}
public synchronized void removeConnectedHost(Host host) {
removeFromPushRoutingTable(host, -1);
mConnectedHosts.removeElement(host);
mHostCountChangedListener.dataChanged(mConnectedHosts);
mStatusChangedListener.dataChanged(null);
}
// Forward broadcast messages to neighbors.
public synchronized void forwardMsg(IMsg msg, Host fromHost) {
if (decTTL(msg)) {
// fromHost.log("TTL expired " + msg);
return;
}
SendManager sendMgr = ServiceManager.getSendManager();
Host remoteHost;
for (int i = 0; i < mConnectedHosts.size(); i++) {
if ((remoteHost = (Host)mConnectedHosts.elementAt(i)) == fromHost) {
continue;
}
if (remoteHost.sendQueueInRed() || remoteHost.latencyInRed()) {
// Neighbor is too slow. Deprecate the neighbor.
// Don't send broadcast message to neighbor.
continue;
}
// Note that the msg is shared among all sending hosts.
sendMgr.queueMsgToSend(remoteHost, msg, false);
}
}
public synchronized void sendMsgToHosts(IMsg msg) {
SendManager sendMgr = ServiceManager.getSendManager();
for (int i = 0; i < mConnectedHosts.size(); i++) {
// Note that the msg is shared among all sending hosts.
if (msg.getHeader().getFunction() == MsgHeader.sQuery) {
sendMgr.queueMsgToSend((Host)mConnectedHosts.elementAt(i), msg, true);
}
else
sendMgr.queueMsgToSend((Host)mConnectedHosts.elementAt(i), msg, false);
}
}
public boolean decTTL(IMsg msg) {
MsgHeader header = msg.getHeader();
int ttl = header.getTTL() - 1;
if (ttl <= 0) {
// Expired
return true;
}
if (ttl > ServiceManager.getCfg().mNetMaxTTL) {
ttl = ServiceManager.getCfg().mNetMaxTTL;
}
header.setTTL(ttl);
header.setHopsTaken(header.getHopsTaken() + 1);
return false;
}
public synchronized void pingNeighbors() {
for (int i = 0; i < mConnectedHosts.size(); i++) {
((Host)mConnectedHosts.elementAt(i)).pingHost();
}
}
// CHECK ME
public synchronized void checkConnections() {
for (int i = 0; i < mConnectedHosts.size(); i++) {
Host host = (Host)mConnectedHosts.elementAt(i);
if (host.tooManyDropPackets()) {
host.setStatus(Host.sStatusDropped, "Too many dropped packets");
host.closeConnection();
continue;
}
if (host.deprecatedTooLong()) {
host.setStatus(Host.sStatusDropped, "Deprecated too long");
host.closeConnection();
continue;
}
/*
if (host.tooMuchLatency()) {
host.closeConnection();
continue;
}
if (host.sendQueueTooLong()) {
host.closeConnection();
continue;
}
*/
}
}
public synchronized void saveHosts() throws IOException {
File file = ServiceManager.getHostsFile();
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
for (int i = 0; i < mHostsCaught.size(); i++) {
String host = (String)mHostsCaught.elementAt(i);
bw.write(host);
bw.newLine();
}
bw.close();
mHostsCaughtChanged = false;
mLastSaved = System.currentTimeMillis();
}
public synchronized void autoSaveHosts() {
if (mHostsCaughtChanged) {
// Wait for at least 30 seconds before saving.
if ((System.currentTimeMillis() - mLastSaved) > 30000) {
try {
saveHosts();
}
catch (Exception e) {
System.out.println(e);
}
}
}
}
public void setHostChangedListener(IHostChanged listener) {
mHostChangedListener = listener;
}
public void addHostCountChangedListener(IDataChangedListener listener) {
mHostCountChangedListener.addListener(listener);
}
public void addStatusChangedListener(IDataChangedListener listener) {
mStatusChangedListener.addListener(listener);
}
public IHostChanged getHostChangedListener() {
return mHostChangedListener;
}
public int getStatHosts() {
return mStatHosts;
}
public void setStatHosts(int val) {
mStatHosts = val;
}
public synchronized void incStatHosts(int amount) {
mStatHosts += amount;
}
public int getStatFiles() {
return mStatFiles;
}
public void setStatFiles(int val) {
mStatFiles = val;
}
public synchronized void incStatFiles(int amount) {
if (amount < 0)
return;
mStatFiles += amount;
}
public long getStatSize() {
return mStatSize;
}
public void setStatSize(long val) {
mStatSize = val;
updateStatSizeStr();
}
public synchronized void incStatSize(long amount) {
// Sounds bogos. Ignore
if (amount < 0)
return;
mStatSize += amount;
updateStatSizeStr();
}
public String getStatSizeStr() {
return mStatSizeStr;
}
private void updateStatSizeStr() {
mStatSizeStr = StrUtil.formatSizeBytes(mStatSize << 10);
}
public int getStatTakenCount() {
return mStatTakenCount;
}
public void setStatTakenCount(int val) {
mStatTakenCount = val;
}
public synchronized void incStatTakenCount(int amount) {
mStatTakenCount += amount;
}
public int getStatMsgCount() {
return mStatMsgCount;
}
public void setStatMsgCount(int val) {
mStatMsgCount = val;
}
public synchronized void incStatMsgCount(int amount) {
mStatMsgCount += amount;
}
public int getStatDropCount() {
return mStatDropCount;
}
public void setStatDropCount(int val) {
mStatDropCount = val;
}
public synchronized void incStatDropCount(int amount) {
mStatDropCount += amount;
}
public int getStatUploadCount() {
return mStatUploadCount;
}
public void setStatUploadCount(int val) {
mStatUploadCount = val;
}
public synchronized void incStatUploadCount(int amount) {
mStatUploadCount += amount;
}
public int getStatDownloadCount() {
return mStatDownloadCount;
}
public void setStatDownloadCount(int val) {
mStatDownloadCount = val;
mStatusChangedListener.dataChanged(null);
}
public synchronized void incStatDownloadCount(int amount) {
mStatDownloadCount += amount;
mStatusChangedListener.dataChanged(null);
}
public void resetStat() {
mStatHosts = 0;
mStatFiles = 0;
mStatSize = 0;
mStatSizeStr = "0";
mStatTakenCount = 0;
mStatMsgCount = 0;
mStatDropCount = 0;
mStatUploadCount = 0;
mStatDownloadCount = 0;
newRateSamplePeriod();
}
public void incBytesCount(int count) {
mRateBytes += count;
totalBytes += count;
}
private double totalBytes;
private long startTime = System.currentTimeMillis();
public double getTotalBytes() {
//System.out.println("total =" +totalBytes);
return (totalBytes/1024) / ((System.currentTimeMillis() - startTime)/1000);
}
public final int getRate() {
if (mRateBytes == 0) {
// No date in new sampling period. Use old rate for continuation.
return mOldRate;
}
return mRateBytes * 1000 / (int)(System.currentTimeMillis() - mRateTime0 + 1);
}
public void newRateSamplePeriod() {
mOldRate = getRate();
mRateBytes = 0;
mRateTime0 = System.currentTimeMillis();
}
public Vector getHostsCaught() {
return mHostsCaught;
}
public int incCaughtHostIndex() {
return caughtHostIndex++;
}
public void setCaughtHostIndex(int index) {
caughtHostIndex = index;
}
/*
public synchronized void insertHostCaught(String host)
{
if (mHostsCaughtUnique.get(host) == null)
{
mHostsCaught.insertElementAt(host, 0);
mHostsCaughtUnique.put(host, Boolean.valueOf(false));
}
}
*/
protected synchronized boolean isBootHost(String host) {
Vector bootHosts = getBootHosts();
int size = bootHosts.size();
for (int cv = 0; cv < size; cv++) {
if (((String)(bootHosts.elementAt(cv))).equalsIgnoreCase(host))
return true;
}
return false;
}
public synchronized boolean addHostCaught(String host) {
boolean retVal = false;
if (validateHost(host)){
if (mHostsCaught.size() > ServiceManager.getCfg().mNetMaxHostToCatch)
{
String host2 = (String)mHostsCaught.get(mHostsCaught.size()-1);
removeHostCaught(host2);
}
addHostCaughtForced(host,false,true);
retVal = true;
}
return retVal;
}
public synchronized void addHostCaughtForced(String host, boolean end) {
addHostCaughtForced( host, end, false);
}
private synchronized void addHostCaughtForced(String host, boolean end, boolean validated) {
if (validated || validateHost(host)){
if (mHostsCaughtUnique.get(host) == null) {
if (end)
mHostsCaught.add(host);
else
mHostsCaught.add(0,host);
mHostsCaughtUnique.put(host, Boolean.valueOf(false));
}
}
}
public synchronized void removeHostCaught(String hostStr) {
Host host = null;
for (int idx = 0; idx < mHosts.size(); idx++) {
Host tmp = (Host)mHosts.elementAt(idx);
if (hostStr.equals(tmp.getHostAddr()))
host = tmp;
}
if (host != null) {
removeFromPushRoutingTable(host, -1);
}
mHostsCaught.removeElement(hostStr);
mHostsCaughtUnique.remove(hostStr);
}
public synchronized boolean addAndSaveHostCaught(String host) {
if (addHostCaught(host) == false){
return false;
}
mHostsCaughtChanged = true;
return true;
}
public void setHostCaughtConnectionFailed(String host, boolean failed) {
//mHostsCaughtUnique.put(host, new Boolean(failed));
removeHostCaught(host);
}
public synchronized void resetHostsCaught() {
mHostsCaught.removeAllElements();
mHostsCaughtUnique.clear();
//addStarterCacheProxy();
}
public int throttleControl(int currSleep, int maxSleep, int currRate, int maxRate) {
if (currRate > maxRate) {
// Sleep more to slow down reading in new message.
currSleep = currSleep * 2;
if (currSleep > maxSleep)
currSleep = maxSleep;
}
else if (currRate < maxRate) {
// Sleep less to speed up reading in new message.
currSleep = (int)((float)currSleep * 2 / 3);
if (currSleep == 0)
currSleep = 1; // avoid 0; otherwise multiplication won't work.
}
try {
Thread.sleep(currSleep);
}
catch (Exception e) {}
return currSleep;
}
public boolean isHostConnected(Host host)
{
for (int idx = 0; idx < mConnectedHosts.size(); idx++) {
if (host == (Host)mConnectedHosts.elementAt(idx)) {
return true;
}
}
return false;
}
public boolean isHostIgnored(String ip) {
return isIpInHosts(ip, ServiceManager.getCfg().mNetIgnoredHosts);
}
public boolean isHostInvalid(String ip) {
return isIpInHosts(ip, ServiceManager.getCfg().mNetInvalidHosts);
}
public boolean isHostFiltered(String ip) {
return (ServiceManager.getCfg().mApplyFilterdHosts &&
isIpInHosts(ip, ServiceManager.getCfg().mFilteredSearchHosts));
}
public boolean isIpInHosts(String ip, Vector hosts) {
int size = hosts.size();
String[] parts;
int j;
try {
parts = Cfg.ip2parts(ip);
}
catch (NoSuchElementException nse) {
// Must have been a hostname, not an IP address...
return false;
}
for (int i = 0; i < size; i++) {
String[] partmask = (String[])hosts.elementAt(i);
for (j = 0; j < 4; j++) {
if (partmask[j].equals("*"))
continue;
if (!partmask[j].equals(parts[j]))
break;
}
if (j == 4)
return true;
}
return false;
}
public class SpeedMonitor implements BandwidthUser {
private int type;
private SpeedCalculator calc;
public SpeedMonitor(int _type) {
type = _type;
calc = new SpeedCalculator();
}
public int getBandwidthType() {
return type;
}
public double getActualSpeed() {
return calc.getSpeed();
}
public void addBytes(int bytes) {
calc.addBytes(bytes);
}
}
}
The table below shows all metrics for HostManager.java.




