Commit f4559a45 authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

initialized clean Simonstrator-PeerfactSim.KOM-repository to FINALLY get rid...

initialized clean Simonstrator-PeerfactSim.KOM-repository to FINALLY get rid of huge blob objects and ancient history that is not relevant to the simonstrator-branch of PeerfactSim.KOM
parents
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.api.network.NetLayer;
import de.tud.kom.p2psim.impl.util.logging.SimLogger;
/**
*
* @author Gerald Klunker
* @version 0.01, 07/12/12
*/
public class GnpNetBandwidthManagerEvent extends AbstractGnpNetBandwidthManager {
private static Logger log = SimLogger
.getLogger(GnpNetBandwidthManagerEvent.class);
private Set<GnpNetBandwidthAllocation> tempConnections;
private Map<NetLayer, Set<GnpNetBandwidthAllocation>> tempSenderConnections;
private Map<NetLayer, Set<GnpNetBandwidthAllocation>> tempReceiverConnections;
private Set<GnpNetBandwidthAllocation> changedAllocations;
private long step = 0;
public GnpNetBandwidthManagerEvent() {
tempSenderConnections = new HashMap<NetLayer, Set<GnpNetBandwidthAllocation>>(
connectionsSenderToReceiver.size());
tempReceiverConnections = new HashMap<NetLayer, Set<GnpNetBandwidthAllocation>>(
connectionsReceiverToSender.size());
tempConnections = new HashSet<GnpNetBandwidthAllocation>();
changedAllocations = new HashSet<GnpNetBandwidthAllocation>();
}
public void allocateBandwidth() {
changedAllocations.clear();
// Initialize Bids and Allocations
tempSenderConnections.clear();
tempReceiverConnections.clear();
for (NetLayer nl : connectionsSenderToReceiver.keySet()) {
tempSenderConnections.put(nl,
new HashSet<GnpNetBandwidthAllocation>(
connectionsSenderToReceiver.get(nl).size()));
tempSenderConnections
.get(nl)
.addAll(
(Collection<GnpNetBandwidthAllocation>) connectionsSenderToReceiver
.get(nl).values());
tempConnections
.addAll(connectionsSenderToReceiver.get(nl).values());
}
for (NetLayer nl : connectionsReceiverToSender.keySet()) {
tempReceiverConnections.put(nl,
new HashSet<GnpNetBandwidthAllocation>(
connectionsReceiverToSender.get(nl).size()));
tempReceiverConnections.get(nl).addAll(
connectionsReceiverToSender.get(nl).values());
}
for (GnpNetBandwidthAllocation c : tempConnections) {
c.initConnection();
}
Set<NetLayer> senders = tempSenderConnections.keySet();
Set<NetLayer> receivers = tempReceiverConnections.keySet();
HashSet<NetLayer> deleteSenders = new HashSet<NetLayer>();
HashSet<NetLayer> deleteReceivers = new HashSet<NetLayer>();
HashSet<GnpNetBandwidthAllocation> deleteConnections = new HashSet<GnpNetBandwidthAllocation>();
while (!tempConnections.isEmpty()) {
for (NetLayer s : senders) {
Set<GnpNetBandwidthAllocation> temp = new HashSet<GnpNetBandwidthAllocation>();
temp.addAll(tempSenderConnections.get(s));
generateMeanBids(s.getCurrentBandwidth().getUpBW(), temp, true);
}
for (NetLayer r : receivers) {
Set<GnpNetBandwidthAllocation> temp = new HashSet<GnpNetBandwidthAllocation>();
temp.addAll(tempReceiverConnections.get(r));
generateMeanBids(r.getCurrentBandwidth().getDownBW(), temp, false);
}
step++;
/*
* log.debug("Loop " + step +
* " - Remaining Connections / Senders / Receivers: " +
* tempConnections.size() + " / " + senders.size() + " / " +
* receivers.size());
*/
for (NetLayer p : senders) {
if (generateMinimumBids(p, true)) {
deleteSenders.add(p);
}
}
for (NetLayer p : receivers) {
if (generateMinimumBids(p, false))
deleteReceivers.add(p);
}
for (GnpNetBandwidthAllocation c : tempConnections) {
if (assignAllocation((GnpNetBandwidthAllocation) c))
deleteConnections.add((GnpNetBandwidthAllocation) c);
}
senders.removeAll(deleteSenders);
receivers.removeAll(deleteReceivers);
tempConnections.removeAll(deleteConnections);
for (GnpNetBandwidthAllocation c : deleteConnections) {
NetLayer sender = c.getSender();
NetLayer receiver = c.getReceiver();
if (tempSenderConnections.containsKey(sender)) {
tempSenderConnections.get(sender).remove(c);
}
if (tempReceiverConnections.containsKey(receiver)) {
tempReceiverConnections.get(receiver).remove(c);
}
}
deleteSenders.clear();
deleteReceivers.clear();
deleteConnections.clear();
}
step = 0;
tempConnections.clear();
tempSenderConnections.clear();
tempReceiverConnections.clear();
}
/**
* Method shares "bandwidth" to all attached "unsigned" allocations.
* Normally each allocation gets the same part excluding the allocations
* with an upper bound of need bandwidth that is smaller than the mean
* fraction (caused by TCP Throughput).
*
* Example: sender s has an bandwith of 30bytes/second and 3 receivers
* r1-r3. Normally each connection will be assigned with 10 bytes/s
*
* If the throughput of connection s -> r1 is limited to 6 bytes/s => s ->
* r1 : 6 bytes/s s -> r1 : 12 bytes/s s -> r1 : 12 bytes/s
*
* @param bandwidth
* available for bids
* @param unassigned
* Allocations will be empty after run
* @param isSender
* true if allocations relates to one sender, false if
* allocations relates to one reciever
* @return number of smaller opposite bids
*/
private int generateMeanBids(double bandwidth,
Collection<GnpNetBandwidthAllocation> unassigned, boolean isSender) {
if (unassigned.isEmpty())
return 0;
// find connections with an upper bound of throughput that is below fair
// fraction of bandwidth
double minBW = Double.POSITIVE_INFINITY;
double share = bandwidth / unassigned.size();
GnpNetBandwidthAllocation min = null;
for (GnpNetBandwidthAllocation ba : unassigned) {
double bw = 0;
bw = Math.min(share, ba.getBandwidthNeeds());
if (bw < minBW) {
minBW = bw;
min = ba;
}
}
if (minBW < share) {
min.setBid(minBW, false, isSender, step);
unassigned.remove(min);
bandwidth -= minBW;
int counter = generateMeanBids(bandwidth, unassigned, isSender);
if (minBW > min.getPreviousBid(!isSender, step))
return counter + 1;
else
return counter;
} else {
int counter = 0;
for (GnpNetBandwidthAllocation ba : unassigned) {
ba.setBid(share, false, isSender, step);
if (share > ba.getPreviousBid(!isSender, step))
counter++;
}
return counter;
}
}
private boolean generateMinimumBids(NetLayer p, boolean sender) {
// get unassigned connections related to p
Set<GnpNetBandwidthAllocation> connections = (sender) ? tempSenderConnections
.get(p)
: tempReceiverConnections.get(p);
// if one connection left repeat bid and set as minimum
if (connections.size() == 1) {
GnpNetBandwidthAllocation c = connections.iterator().next();
c.setBid(c.getPreviousBid(sender, step), true, sender, step);
return true;
}
// Fair Share bandwidth
double bandwidth = (sender) ? p.getCurrentBandwidth().getUpBW() : p
.getCurrentBandwidth().getDownBW();
Set<GnpNetBandwidthAllocation> temp = new HashSet<GnpNetBandwidthAllocation>();
temp.addAll(connections);
int smallerBids = generateMeanBids(bandwidth, temp, sender);
// no opposite Bid is smaller than own bid
// mark as minimum Bid
if (smallerBids == 0) {
for (GnpNetBandwidthAllocation c : connections)
c.setBid(c.getCurrentBid(sender, step), true, sender, step);
return true;
}
// some opposite Bids are smaller than own bid:
else {
// get Connections with slowest Bids
Set<GnpNetBandwidthAllocation> slowestConnections = new HashSet<GnpNetBandwidthAllocation>();
double slowestBid = Double.MAX_VALUE;
for (GnpNetBandwidthAllocation c : connections) {
double currentBid = c.getPreviousBid(!sender, step);
if (currentBid < slowestBid) {
slowestBid = currentBid;
}
}
for (GnpNetBandwidthAllocation c : connections) {
double currentBid = c.getPreviousBid(!sender, step);
if (currentBid == slowestBid) {
slowestConnections.add(c);
}
}
// double bandwidth = (sender) ? p.getCurrentUploadBandwidth() :
// p.getCurrentDownloadBandwidth();
double min = slowestConnections.iterator().next().getPreviousBid(
!sender, step);
for (GnpNetBandwidthAllocation c : slowestConnections) {
c.setBid(min, true, sender, step);
bandwidth -= min;
}
Set<GnpNetBandwidthAllocation> fasterConnections = new HashSet<GnpNetBandwidthAllocation>();
fasterConnections.addAll(connections);
fasterConnections.removeAll(slowestConnections);
generateMeanBids(bandwidth, fasterConnections, sender);
return false;
}
}
private boolean assignAllocation(GnpNetBandwidthAllocation c) {
double bidSender = c.getCurrentBid(true, step);
double bidReceiver = c.getCurrentBid(false, step);
// System.out.println(bidSender + ":" + c.isBidRepeated(true) + " - " +
// bidReceiver + ":" + c.isBidRepeated(false));
if (bidSender <= bidReceiver && c.isMinBid(true)
&& c.isBidRepeated(true)) {
if (bidSender != c.getAllocatedBandwidth())
changedAllocations.add(c);
c.setAllocatedBandwidth(bidSender);
BandwidthImpl curBWSnd = (BandwidthImpl) c.getSender()
.getCurrentBandwidth();
curBWSnd.setUpBW((long)(curBWSnd.getUpBW() - bidSender));
BandwidthImpl curBWRcv = (BandwidthImpl) c.getReceiver()
.getCurrentBandwidth();
curBWRcv.setDownBW((long)(curBWRcv.getDownBW() - bidSender));
return true;
} else if (bidSender >= bidReceiver && c.isMinBid(false)
&& c.isBidRepeated(false)) {
if (bidReceiver != c.getAllocatedBandwidth())
changedAllocations.add(c);
c.setAllocatedBandwidth(bidReceiver);
BandwidthImpl curBWSnd = (BandwidthImpl) c.getSender()
.getCurrentBandwidth();
curBWSnd.setUpBW((long)(curBWSnd.getUpBW() - bidReceiver));
BandwidthImpl curBWRcv = (BandwidthImpl) c.getReceiver()
.getCurrentBandwidth();
curBWRcv.setDownBW((long)(curBWRcv.getDownBW() - bidReceiver));
return true;
} else {
return false;
}
}
@Override
public BandwidthAllocation getBandwidthAllocationType() {
return AbstractGnpNetBandwidthManager.BandwidthAllocation.EVENT;
}
@Override
public Set<GnpNetBandwidthAllocation> getChangedAllocations() {
return changedAllocations;
}
}
\ No newline at end of file
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.api.network.NetLayer;
import de.tud.kom.p2psim.impl.network.AbstractNetLayer;
public class GnpNetBandwidthManagerPeriodical extends
AbstractGnpNetBandwidthManager {
private HashSet<NetLayer> changedSenders;
private HashSet<NetLayer> changedReceivers;
private Set<GnpNetBandwidthAllocation> changedAllocations; // within last
// realocation
public GnpNetBandwidthManagerPeriodical() {
super();
changedSenders = new HashSet<NetLayer>();
changedReceivers = new HashSet<NetLayer>();
changedAllocations = new HashSet<GnpNetBandwidthAllocation>();
}
@Override
public GnpNetBandwidthAllocation addConnection(AbstractNetLayer sender,
AbstractNetLayer receiver, double bandwidth) {
changedSenders.add(sender);
changedReceivers.add(receiver);
// sender.setCurrentUpBandwidth(sender.getMaxUploadBandwidth());
// receiver.setCurrentDownBandwidth(receiver.getMaxDownloadBandwidth());
GnpNetBandwidthAllocation ba = super.addConnection(sender, receiver,
bandwidth);
return ba;
}
@Override
public GnpNetBandwidthAllocation removeConnection(AbstractNetLayer sender,
AbstractNetLayer receiver, double bandwidth) {
GnpNetBandwidthAllocation ba = super.removeConnection(sender, receiver,
bandwidth);
if (connectionsSenderToReceiver.containsKey(sender))
changedSenders.add(sender);
else
changedSenders.remove(sender);
if (connectionsReceiverToSender.containsKey(receiver))
changedReceivers.add(receiver);
else
changedReceivers.remove(receiver);
return ba;
};
@Override
public void allocateBandwidth() {
HashSet<AbstractNetLayer> chSenders = (HashSet<AbstractNetLayer>) changedSenders
.clone();
HashSet<AbstractNetLayer> chReceivers = (HashSet<AbstractNetLayer>) changedReceivers
.clone();
changedSenders.clear();
changedReceivers.clear();
changedAllocations.clear();
for (AbstractNetLayer host : chSenders) {
host.getCurrentBandwidth().setUpBW(host.getMaxBandwidth().getUpBW());
Set<GnpNetBandwidthAllocation> temp = new HashSet<GnpNetBandwidthAllocation>();
temp.addAll(connectionsSenderToReceiver.get(host).values());
fairShare(temp, true);
}
for (AbstractNetLayer host : chReceivers) {
host.getCurrentBandwidth().setDownBW(host.getMaxBandwidth().getDownBW());
Set<GnpNetBandwidthAllocation> temp = new HashSet<GnpNetBandwidthAllocation>();
temp.addAll(connectionsReceiverToSender.get(host).values());
fairShare(temp, false);
}
}
private void fairShare(Collection<GnpNetBandwidthAllocation> unassigned,
boolean isSender) {
if (unassigned.isEmpty())
return;
double x = Double.POSITIVE_INFINITY;
GnpNetBandwidthAllocation min = null;
for (GnpNetBandwidthAllocation ba : unassigned) {
double bandwidth = 0;
if (isSender)
bandwidth = Math.min(ba.getReceiver()
.getCurrentBandwidth().getDownBW()
+ ba.getAllocatedBandwidth(), ba.getBandwidthNeeds());
else
bandwidth = Math.min(ba.getSender().getCurrentBandwidth().getUpBW()
+ ba.getAllocatedBandwidth(), ba.getBandwidthNeeds());
if (bandwidth < x) {
x = bandwidth;
min = ba;
}
}
double bw = 0;
if (isSender)
bw = min.getSender().getCurrentBandwidth().getUpBW()
/ unassigned.size();
else
bw = min.getReceiver().getCurrentBandwidth().getDownBW()
/ unassigned.size();
if (x < bw) {
if (min.getAllocatedBandwidth() != x) {
changedAllocations.add(min);
min.setAllocatedBandwidth(x);
if (isSender)
changedReceivers.add(min.getReceiver());
else
changedSenders.add(min.getSender());
}
if (isSender) {
BandwidthImpl curbw = (BandwidthImpl) min.getSender()
.getCurrentBandwidth();
curbw.setUpBW((long)(curbw.getUpBW() - min.getAllocatedBandwidth()));
} else {
BandwidthImpl curbw = (BandwidthImpl) min.getReceiver()
.getCurrentBandwidth();
curbw.setDownBW((long)(curbw.getDownBW() - min.getAllocatedBandwidth()));
}
unassigned.remove(min);
fairShare(unassigned, isSender);
} else {
for (GnpNetBandwidthAllocation ba : unassigned) {
if (ba.getAllocatedBandwidth() != bw) {
changedAllocations.add(ba);
ba.setAllocatedBandwidth(bw);
if (isSender)
changedReceivers.add(ba.getReceiver());
else
changedSenders.add(ba.getSender());
}
if (isSender)
ba.getSender().getCurrentBandwidth().setUpBW(0);
else
ba.getReceiver().getCurrentBandwidth().setDownBW(0);
}
}
}
@Override
public BandwidthAllocation getBandwidthAllocationType() {
return AbstractGnpNetBandwidthManager.BandwidthAllocation.PERIODICAL;
}
@Override
public Set<GnpNetBandwidthAllocation> getChangedAllocations() {
return changedAllocations;
}
}
\ No newline at end of file
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp;
import java.util.HashMap;
import java.util.Map;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.api.network.NetMessage;
import de.tud.kom.p2psim.api.network.NetProtocol;
import de.tud.kom.p2psim.api.transport.TransProtocol;
import de.tud.kom.p2psim.impl.network.AbstractNetLayer;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.IPv4NetID;
import de.tud.kom.p2psim.impl.network.gnp.topology.GnpPosition;
import de.tud.kom.p2psim.impl.transport.AbstractTransMessage;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
/**
*
* @author geraldklunker
*
*/
public class GnpNetLayer extends AbstractNetLayer implements EventHandler {
private GeoLocation geoLocation;
private GnpSubnet subnet;
private long nextFreeSendingTime = 0;
private long nextFreeReceiveTime = 0;
private Map<GnpNetLayer, GnpNetBandwidthAllocation> connections = new HashMap<GnpNetLayer, GnpNetBandwidthAllocation>();
private static final int EVENT_RECEIVE = 1;
public GnpNetLayer(SimHost host, GnpSubnet subNet, IPv4NetID netID,
GnpPosition netPosition, GeoLocation geoLoc, BandwidthImpl maxBW) {
super(host, netID, maxBW, netPosition, null);
this.subnet = subNet;
this.geoLocation = geoLoc;
subNet.registerNetLayer(this);
}
public GeoLocation getGeoLocation() {
return geoLocation;
}
/**
*
* @return 2-digit country code
*/
public String getCountryCode() {
return geoLocation.getCountryCode();
}
/**
*
* @return first time sending is possible (line is free)
*/
public long getNextFreeSendingTime() {
return nextFreeSendingTime;
}
/**
*
* @param time
* first time sending is possible (line is free)
*/
public void setNextFreeSendingTime(long time) {
nextFreeSendingTime = time;
}
/**
*
* @param netLayer
* @return
*/
public boolean isConnected(GnpNetLayer netLayer) {
return connections.containsKey(netLayer);
}
/**
*
* @param netLayer
* @param allocation
*/
public void addConnection(GnpNetLayer netLayer,
GnpNetBandwidthAllocation allocation) {
connections.put(netLayer, allocation);
}
/**
*
* @param netLayer
* @return
*/
public GnpNetBandwidthAllocation getConnection(GnpNetLayer netLayer) {
return connections.get(netLayer);
}
/**
*
* @param netLayer
*/
public void removeConnection(GnpNetLayer netLayer) {
connections.remove(netLayer);
}
/**
*
* @param msg
*/
public void addToReceiveQueue(IPv4Message msg) {
long receiveTime = subnet.getLatencyModel().getTransmissionDelay(
msg.getSize(), getMaxBandwidth().getDownBW());
long currenTime = Time.getCurrentTime();
long arrivalTime = nextFreeReceiveTime + receiveTime;
if (arrivalTime <= currenTime) {
nextFreeReceiveTime = currenTime;
receive(msg);
} else {
nextFreeReceiveTime = arrivalTime;
Event.scheduleWithDelay(arrivalTime - Time.getCurrentTime(), this,
msg, EVENT_RECEIVE);
}
}
@Override
public boolean isSupported(TransProtocol transProtocol) {
return (transProtocol.equals(TransProtocol.UDP) || transProtocol
.equals(TransProtocol.TCP));
}
public void send(Message msg, NetID receiver, NetProtocol netProtocol) {
// outer if-else-block is used to avoid sending although the host is
// offline
if (this.isOnline()) {
TransProtocol usedTransProtocol = ((AbstractTransMessage) msg)
.getProtocol();
if (this.isSupported(usedTransProtocol)) {
NetMessage netMsg = new IPv4Message(msg, receiver,
this.getLocalInetAddress());
if (hasAnalyzer) {
netAnalyzerProxy
.netMsgEvent(netMsg, getHost(), Reason.SEND);
}
this.subnet.send(netMsg);
} else
throw new IllegalArgumentException("Transport protocol "
+ usedTransProtocol
+ " not supported by this NetLayer implementation.");
} else {
int assignedMsgId = subnet.determineTransMsgNumber(msg);
log.debug("During send: Assigning MsgId " + assignedMsgId
+ " to dropped message");
((AbstractTransMessage) msg).setCommId(assignedMsgId);
if (hasAnalyzer) {
NetMessage netMsg = new IPv4Message(msg, receiver,
this.getLocalInetAddress());
netAnalyzerProxy.netMsgEvent(netMsg, getHost(), Reason.DROP);
}
}
}
@Override
public String toString() {
return this.getNetID().toString() + " ( "
+ this.getHost().getProperties().getGroupID() + " )";
}
@Override
public void eventOccurred(Object content, int type) {
if (type == EVENT_RECEIVE) {
receive((NetMessage) content);
}
}
public void goOffline() {
super.goOffline();
subnet.goOffline(this);
}
public void cancelTransmission(int commId) {
subnet.cancelTransmission(commId);
}
}
\ No newline at end of file
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.network.BandwidthImpl;
import de.tud.kom.p2psim.impl.network.AbstractNetLayerFactory;
import de.tud.kom.p2psim.impl.network.IPv4NetID;
import de.tud.kom.p2psim.impl.network.gnp.topology.CountryLookup;
import de.tud.kom.p2psim.impl.network.gnp.topology.GnpPosition;
import de.tud.kom.p2psim.impl.network.gnp.topology.PingErLookup;
import de.tud.kom.p2psim.impl.util.logging.SimLogger;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time;
public class GnpNetLayerFactory extends AbstractNetLayerFactory {
private static Logger log = SimLogger.getLogger(GnpNetLayerFactory.class);
private final GnpSubnet subnet;
private HashMap<IPv4NetID, GnpHostInfo> hostPool;
private HashMap<String, ArrayList<IPv4NetID>> namedGroups;
private PingErLookup pingErLookup;
private CountryLookup countryLookup;
public GnpNetLayerFactory() {
super();
subnet = new GnpSubnet();
}
public GnpNetLayer createComponent(Host pureHost) {
SimHost host = (SimHost) pureHost;
GnpNetLayer netLayer = newNetLayer(host, host.getProperties()
.getGroupID());
return netLayer;
}
/**
* random node form group
*
* @param id
* @return
*/
public GnpNetLayer newNetLayer(SimHost host, String id) {
if (this.namedGroups.containsKey(id)
&& !this.namedGroups.get(id).isEmpty()) {
int size = namedGroups.get(id).size();
IPv4NetID netId = namedGroups.get(id).get(
Randoms.getRandom(GnpNetLayerFactory.class).nextInt(size));
namedGroups.get(id).remove(netId);
return newNetLayer(host, netId);
} else {
throw new IllegalStateException(
"No (more) Hosts are assigned to \"" + id + "\"");
}
}
// general method for allocation of bandwidth capacities, which depends on
// the provided class by the setBandwidthDetermination-method
private GnpNetLayer newNetLayer(SimHost host, IPv4NetID netID) {
GnpPosition gnpPos = this.hostPool.get(netID).getGnpPosition();
GeoLocation geoLoc = this.hostPool.get(netID).getGeoLoc();
BandwidthImpl bw = getBandwidth(netID);
GnpNetLayer nw = new GnpNetLayer(host, this.subnet, netID, gnpPos,
geoLoc, bw);
// hostPool.remove(netID); //TODO: Why remove? This information is
// needed if a host is in multiple groups
return nw;
}
public void setGnpFile(String gnpFileName) {
File gnpFile = new File(gnpFileName);
hostPool = new HashMap<IPv4NetID, GnpHostInfo>();
namedGroups = new HashMap<String, ArrayList<IPv4NetID>>();
log.info("Read hosts from file " + gnpFile);
SAXReader reader = new SAXReader(false);
Document configuration = null;
try {
configuration = reader.read(gnpFile);
} catch (DocumentException e) {
e.printStackTrace();
}
Element root = configuration.getRootElement();
assert root.getName().equals("gnp");
for (Object obj : root.elements()) {
Element elem = (Element) obj;
if (elem.getName().equals("GroupLookup")) {
for (Iterator iter = elem.elementIterator("Group"); iter
.hasNext();) {
Element variable = (Element) iter.next();
String id = variable.attributeValue("id");
ArrayList<IPv4NetID> group = new ArrayList<IPv4NetID>();
for (Iterator ipIter = variable.elementIterator("IPs"); ipIter
.hasNext();) {
Element ipElement = (Element) ipIter.next();
String[] ips = ipElement.attributeValue("value").split(
",");
for (int c = 0; c < ips.length; c++)
group.add(new IPv4NetID(Long.parseLong(ips[c])));
}
if (namedGroups.containsKey(id)) {
throw new IllegalStateException(
"Multiple Group Definition in " + gnpFileName
+ " ( Group: " + id + " )");
} else {
namedGroups.put(id, group);
}
}
} else if (elem.getName().equals("Hosts")) {
for (Iterator iter = elem.elementIterator("Host"); iter
.hasNext();) {
Element variable = (Element) iter.next();
// IP-Address
IPv4NetID hostID = new IPv4NetID(Long.parseLong(variable
.attributeValue("ip")));
// GNP-Coordinates
String[] coordinatesS = variable.attributeValue(
"coordinates").split(",");
double[] coordinatesD = new double[coordinatesS.length];
for (int c = 0; c < coordinatesD.length; c++)
coordinatesD[c] = Double.parseDouble(coordinatesS[c]);
GnpPosition gnpPos = new GnpPosition(coordinatesD);
// GeoLocation
String continentalArea = variable
.attributeValue("continentalArea");
String countryCode = variable.attributeValue("countryCode");
String region = variable.attributeValue("region");
String city = variable.attributeValue("city");
String isp = variable.attributeValue("isp");
double longitude = Double.parseDouble(variable
.attributeValue("longitude"));
double latitude = Double.parseDouble(variable
.attributeValue("latitude"));
GeoLocation geoLoc = new GeoLocation(continentalArea,
countryCode, region, city, isp, latitude, longitude);
GnpHostInfo hostInfo = new GnpHostInfo(geoLoc, gnpPos);
hostPool.put(hostID, hostInfo);
}
} else if (elem.getName().equals("PingErLookup")) {
pingErLookup = new PingErLookup();
pingErLookup.loadFromXML(elem);
} else if (elem.getName().equals("CountryLookup")) {
countryLookup = new CountryLookup();
countryLookup.importFromXML(elem);
}
}
}
public void setLatencyModel(GnpLatencyModel model) {
model.init(pingErLookup, countryLookup);
subnet.setLatencyModel(model);
}
public void setBandwidthManager(AbstractGnpNetBandwidthManager bm) {
subnet.setBandwidthManager(bm);
}
public void setPbaPeriod(double seconds) {
subnet.setPbaPeriod(Math.round(seconds * Time.SECOND));
}
private class GnpHostInfo {
private GnpPosition gnpPosition;
private GeoLocation geoLoc;
public GnpHostInfo(GeoLocation geoLoc, GnpPosition gnpPos) {
this.gnpPosition = gnpPos;
this.geoLoc = geoLoc;
}
GnpPosition getGnpPosition() {
return gnpPosition;
}
GeoLocation getGeoLoc() {
return geoLoc;
}
}
}
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import org.apache.log4j.Logger;
import de.tud.kom.p2psim.api.analyzer.MessageAnalyzer.Reason;
import de.tud.kom.p2psim.api.analyzer.NetlayerAnalyzer;
import de.tud.kom.p2psim.api.network.NetLayer;
import de.tud.kom.p2psim.api.network.NetMessage;
import de.tud.kom.p2psim.impl.network.AbstractNetLayer;
import de.tud.kom.p2psim.impl.network.AbstractSubnet;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.IPv4NetID;
import de.tud.kom.p2psim.impl.network.gnp.AbstractGnpNetBandwidthManager.BandwidthAllocation;
import de.tud.kom.p2psim.impl.transport.AbstractTransMessage;
import de.tud.kom.p2psim.impl.transport.TCPMessage;
import de.tud.kom.p2psim.impl.transport.UDPMessage;
import de.tud.kom.p2psim.impl.util.logging.SimLogger;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.AnalyzerNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
/**
*
* @author Gerald Klunker
* @version 0.1, 17.01.2008
*
*/
public class GnpSubnet extends AbstractSubnet implements EventHandler {
private static Logger log = SimLogger.getLogger(GnpSubnet.class);
private static final Byte REALLOCATE_BANDWIDTH_PERIODICAL_EVENT = 0;
private static final Byte REALLOCATE_BANDWIDTH_EVENTBASED_EVENT = 1;
private AbstractGnpNetBandwidthManager bandwidthManager;
private long pbaPeriod = 1 * Time.SECOND;
private long nextPbaTime = 0;
private long nextResheduleTime = -1;
private HashMap<GnpNetBandwidthAllocation, Set<TransferProgress>> currentlyTransferedStreams;
private HashMap<Integer, TransferProgress> currentStreams;
public static Set<TransferProgress> obsoleteEvents;
private GnpLatencyModel netLatencyModel;
private Map<IPv4NetID, GnpNetLayer> layers;
private GeoLocationOracle oracle;
private Random rnd = Randoms.getRandom(GnpSubnet.class);
private final static int EVENT_RECEIVE = 1;
private final static int EVENT_REALLOCATE_BANDWIDTH_PERIODICAL = 2;
private final static int EVENT_REALLOCATE_BANDWIDTH_EVENTBASED = 3;
public GnpSubnet() {
this.layers = new HashMap<IPv4NetID, GnpNetLayer>();
this.netLatencyModel = new GnpLatencyModel();
this.oracle = new GeoLocationOracle(this);
this.oracle.setLatencyModel(netLatencyModel);
this.obsoleteEvents = new HashSet<TransferProgress>(5000000);
this.currentlyTransferedStreams = new HashMap<GnpNetBandwidthAllocation, Set<TransferProgress>>();
this.currentStreams = new HashMap<Integer, TransferProgress>();
}
GnpNetLayer getNetLayer(NetID netId) {
return this.layers.get(netId);
}
public void setLatencyModel(GnpLatencyModel netLatencyModel) {
this.netLatencyModel = netLatencyModel;
this.oracle.setLatencyModel(netLatencyModel);
}
public GnpLatencyModel getLatencyModel() {
return netLatencyModel;
}
public void setBandwidthManager(AbstractGnpNetBandwidthManager bm) {
this.bandwidthManager = bm;
}
public void setPbaPeriod(long timeUnits) {
this.pbaPeriod = timeUnits;
}
/**
* Registers a NetWrapper in the SubNet.
*
* @param wrapper
* The NetWrapper.
*/
@Override
public void registerNetLayer(NetLayer netLayer) {
this.layers
.put((IPv4NetID) netLayer.getNetID(), (GnpNetLayer) netLayer);
}
/**
*
*/
@Override
public void send(NetMessage msg) {
GnpNetLayer sender = this.layers.get(msg.getSender());
GnpNetLayer receiver = this.layers.get(msg.getReceiver());
// sender & receiver are registered in the SubNet
if (sender == null || receiver == null)
throw new IllegalStateException(
"Receiver or Sender is not registered");
if (msg.getPayload() instanceof UDPMessage) {
double packetLossProb = this.netLatencyModel
.getUDPerrorProbability(sender, receiver, (IPv4Message) msg);
if (msg.getSender().equals(msg.getReceiver())) {
log.fatal("Sender and receiver are the same ("
+ msg.getSender() + ") and have a loss prob of "
+ packetLossProb + " for msg "
+ msg.getPayload().getPayload());
}
if (rnd.nextDouble() < packetLossProb) {
// Monitor dropped message. The message loss is assigned to
// the
// sender as the receiver does not know, that it would have
// almost received a message
int assignedMsgId = determineTransMsgNumber(msg);
log.debug("During Drop: Assigning MsgId " + assignedMsgId
+ " to dropped message");
((AbstractTransMessage) msg.getPayload())
.setCommId(assignedMsgId);
try {
Monitor.get(NetlayerAnalyzer.class).netMsgEvent(msg,
sender.getHost(), Reason.DROP);
} catch (AnalyzerNotAvailableException e) {
//
}
log.debug("Packet loss occured while transfer \"" + msg
+ "\" (packetLossProb: " + packetLossProb + ")");
return;
}
}
sendMessage((IPv4Message) msg, sender, receiver);
}
/**
*
* @param msg
* @param sender
* @param receiver
*/
private void sendMessage(IPv4Message msg, GnpNetLayer sender,
GnpNetLayer receiver) {
long currentTime = Time.getCurrentTime();
// In order to enable TransMessageCallbacks at the transport layer on
// every implemented network layer and subnet, AbstractSubnet contains
// a method, which determines the next number for a message at the
// transport layer.
int currentCommId = determineTransMsgNumber(msg);
AbstractTransMessage transMsg = (AbstractTransMessage) msg.getPayload();
transMsg.setCommId(currentCommId);
// Case 1: message only consists of 1 Segment => no bandwidth allocation
if (msg.getNoOfFragments() == 1) {
long propagationTime = netLatencyModel.getPropagationDelay(sender,
receiver);
long transmissionTime = netLatencyModel.getTransmissionDelay(msg
.getSize(), Math.min(sender.getMaxBandwidth().getUpBW(),
receiver.getMaxBandwidth().getDownBW()));
long sendingTime = Math.max(sender.getNextFreeSendingTime(),
currentTime)
+ transmissionTime;
long arrivalTime = sendingTime + propagationTime;
sender.setNextFreeSendingTime(sendingTime);
TransferProgress newTp = new TransferProgress(msg,
Double.POSITIVE_INFINITY, 0, currentTime);
Event.scheduleWithDelay(arrivalTime - Time.getCurrentTime(), this,
newTp, EVENT_RECEIVE);
}
// Case 2: message consists minimum 2 Segments => bandwidth allocation
else {
// Add streams to current transfers
double maximumRequiredBandwidth = sender.getMaxBandwidth().getUpBW();
if (msg.getPayload() instanceof TCPMessage) {
double tcpThroughput = netLatencyModel.getTcpThroughput(sender,
receiver);
maximumRequiredBandwidth = Math.min(maximumRequiredBandwidth,
tcpThroughput);
}
GnpNetBandwidthAllocation ba = bandwidthManager.addConnection(
sender, receiver, maximumRequiredBandwidth);
TransferProgress newTp = new TransferProgress(msg, 0,
msg.getSize(), currentTime);
if (!currentlyTransferedStreams.containsKey(ba))
currentlyTransferedStreams.put(ba,
new HashSet<TransferProgress>());
currentlyTransferedStreams.get(ba).add(newTp);
currentStreams.put(currentCommId, newTp);
// Case 2a: Periodical Bandwidth Allocation
// Schedule the first Periodical Bandwidth Allocation Event
if (bandwidthManager.getBandwidthAllocationType() == BandwidthAllocation.PERIODICAL) {
if (nextPbaTime == 0) {
nextPbaTime = Time.getCurrentTime() + pbaPeriod;
Event.scheduleWithDelay(pbaPeriod, this, null,
EVENT_REALLOCATE_BANDWIDTH_PERIODICAL);
}
}
// Case 2b: Eventbased Bandwidth Allocation
// Schedule an realocation Event after current timeunit
else if (bandwidthManager.getBandwidthAllocationType() == BandwidthAllocation.EVENT) {
if (nextResheduleTime <= currentTime + 1) {
nextResheduleTime = currentTime + 1;
Event.scheduleWithDelay(1, this, null,
EVENT_REALLOCATE_BANDWIDTH_EVENTBASED);
}
}
}
}
/**
*
* @param netLayer
*/
public void goOffline(NetLayer netLayer) {
if (bandwidthManager != null
&& bandwidthManager.getBandwidthAllocationType() == BandwidthAllocation.EVENT) {
for (GnpNetBandwidthAllocation ba : bandwidthManager
.removeConnections((AbstractNetLayer) netLayer)) {
Set<TransferProgress> streams = currentlyTransferedStreams
.remove(ba);
if (streams != null) {
obsoleteEvents.addAll(streams);
currentStreams.values().removeAll(streams);
}
}
// Reschedule messages after current timeunit
long currentTime = Time.getCurrentTime();
if (nextResheduleTime <= currentTime + 1) {
nextResheduleTime = currentTime + 1;
Event.scheduleWithDelay(1, this, null,
EVENT_REALLOCATE_BANDWIDTH_EVENTBASED);
}
} else if (bandwidthManager != null) {
for (GnpNetBandwidthAllocation ba : bandwidthManager
.removeConnections((AbstractNetLayer) netLayer)) {
Set<TransferProgress> streams = currentlyTransferedStreams
.remove(ba);
if (streams != null)
currentStreams.values().removeAll(streams);
}
}
}
/**
*
* @param msg
*/
public void cancelTransmission(int commId) {
if (bandwidthManager != null) {
GnpNetLayer sender = layers.get(currentStreams.get(commId)
.getMessage().getSender());
GnpNetLayer receiver = layers.get(currentStreams.get(commId)
.getMessage().getReceiver());
// remove message from current transfers
double maximumRequiredBandwidth = sender.getMaxBandwidth().getUpBW();
if (currentStreams.get(commId).getMessage().getPayload() instanceof TCPMessage) {
double tcpThroughput = netLatencyModel.getTcpThroughput(sender,
receiver);
maximumRequiredBandwidth = Math.min(maximumRequiredBandwidth,
tcpThroughput);
}
bandwidthManager.removeConnection(sender, receiver,
maximumRequiredBandwidth);
TransferProgress tp = currentStreams.get(commId);
currentStreams.remove(commId);
obsoleteEvents.add(tp);
// Reschedule messages after current timeunit
long currentTime = Time.getCurrentTime();
if (bandwidthManager.getBandwidthAllocationType() == BandwidthAllocation.EVENT
&& nextResheduleTime <= currentTime + 1) {
nextResheduleTime = currentTime + 1;
Event.scheduleWithDelay(1, this, null,
EVENT_REALLOCATE_BANDWIDTH_EVENTBASED);
}
}
}
@Override
public void eventOccurred(Object content, int type) {
long currentTime = Time.getCurrentTime();
if (type == EVENT_REALLOCATE_BANDWIDTH_PERIODICAL) {
nextPbaTime = Time.getCurrentTime() + pbaPeriod;
bandwidthManager.allocateBandwidth();
Set<GnpNetBandwidthAllocation> delete = new HashSet<GnpNetBandwidthAllocation>();
for (GnpNetBandwidthAllocation ba : currentlyTransferedStreams
.keySet()) {
reschedulePeriodical(ba);
if (currentlyTransferedStreams.get(ba).isEmpty()) {
delete.add(ba);
}
}
currentlyTransferedStreams.keySet().removeAll(delete);
// Schedule next Periodic Event
if (currentlyTransferedStreams.size() > 0) {
Event.scheduleWithDelay(pbaPeriod, this, null,
EVENT_REALLOCATE_BANDWIDTH_PERIODICAL);
} else {
nextPbaTime = 0;
}
} else if (type == EVENT_REALLOCATE_BANDWIDTH_EVENTBASED) {
bandwidthManager.allocateBandwidth();
Set<GnpNetBandwidthAllocation> bas = bandwidthManager
.getChangedAllocations();
for (GnpNetBandwidthAllocation ba : bas) {
rescheduleEventBased(ba);
}
} else if (type == EVENT_RECEIVE) {
TransferProgress tp = (TransferProgress) content;
IPv4Message msg = (IPv4Message) tp.getMessage();
GnpNetLayer sender = this.layers.get(msg.getSender());
GnpNetLayer receiver = this.layers.get(msg.getReceiver());
// Case 1: message only consists of 1 Segment => no bandwidth
// allocation
if (msg.getNoOfFragments() == 1) {
receiver.addToReceiveQueue(msg);
}
// Case 2: message consists minimum 2 Segments => bandwidth
// allocation
else {
// Case 2a: Periodical Bandwidth Allocation
// Schedule the first Periodical Bandwidth Allocation Event
if (bandwidthManager.getBandwidthAllocationType() == BandwidthAllocation.PERIODICAL) {
receiver.receive(msg);
}
// Case 2b: Eventbased Bandwidth Allocation
// Schedule an realocation Event after current timeunit
else if (bandwidthManager.getBandwidthAllocationType() == BandwidthAllocation.EVENT) {
// Dropp obsolete Events
if (tp.obsolete || obsoleteEvents.contains(tp)) {
obsoleteEvents.remove(tp);
return;
} else {
receiver.receive(msg);
// Reschedule messages after current timeunit
if (nextResheduleTime <= currentTime + 1) {
nextResheduleTime = currentTime + 1;
Event.scheduleWithDelay(1, this, null,
EVENT_REALLOCATE_BANDWIDTH_EVENTBASED);
}
}
}
// remove message from current transfers
double maximumRequiredBandwidth = sender.getMaxBandwidth()
.getUpBW();
if (msg.getPayload() instanceof TCPMessage) {
double tcpThroughput = netLatencyModel.getTcpThroughput(
sender, receiver);
maximumRequiredBandwidth = Math.min(
maximumRequiredBandwidth, tcpThroughput);
}
GnpNetBandwidthAllocation ba = bandwidthManager
.removeConnection(sender, receiver,
maximumRequiredBandwidth);
if (bandwidthManager.getBandwidthAllocationType() == BandwidthAllocation.EVENT) {
if (currentlyTransferedStreams.get(ba) != null) {
if (currentlyTransferedStreams.get(ba).size() <= 1) {
currentlyTransferedStreams.remove(ba);
} else {
currentlyTransferedStreams.get(ba).remove(tp);
}
}
currentStreams.values().remove(tp);
} else {
if (currentlyTransferedStreams.get(ba) != null
&& currentlyTransferedStreams.get(ba).isEmpty()) {
currentlyTransferedStreams.remove(ba);
}
}
}
}
}
/**
* ToDo
*
* @param ba
*/
private void reschedulePeriodical(GnpNetBandwidthAllocation ba) {
Set<TransferProgress> oldIncomplete = currentlyTransferedStreams
.get(ba);
Set<TransferProgress> newIncomplete = new HashSet<TransferProgress>(
oldIncomplete.size());
GnpNetLayer sender = (GnpNetLayer) ba.getSender();
GnpNetLayer receiver = (GnpNetLayer) ba.getReceiver();
long currentTime = Time.getCurrentTime();
double leftBandwidth = ba.getAllocatedBandwidth();
Set<TransferProgress> temp = new HashSet<TransferProgress>();
temp.addAll(oldIncomplete);
oldIncomplete.removeAll(obsoleteEvents);
obsoleteEvents.removeAll(temp);
int leftStreams = oldIncomplete.size();
for (TransferProgress tp : oldIncomplete) {
double remainingBytes = tp.getRemainingBytes(currentTime);
double bandwidth = leftBandwidth / leftStreams;
if (tp.getMessage().getPayload() instanceof TCPMessage) {
double throughput = netLatencyModel.getTcpThroughput(sender,
receiver);
if (throughput < bandwidth)
bandwidth = throughput;
}
leftBandwidth -= bandwidth;
leftStreams--;
long transmissionTime = this.netLatencyModel.getTransmissionDelay(
remainingBytes, bandwidth);
TransferProgress newTp = new TransferProgress(tp.getMessage(),
bandwidth, remainingBytes, currentTime);
if (currentTime + transmissionTime < nextPbaTime) {
long propagationTime = this.netLatencyModel
.getPropagationDelay(sender, receiver);
long arrivalDelay = transmissionTime
+ propagationTime;
Event.scheduleWithDelay(arrivalDelay, this, newTp,
EVENT_RECEIVE);
} else {
newIncomplete.add(newTp);
int commId = ((AbstractTransMessage) tp.getMessage()
.getPayload()).getCommId();
currentStreams.put(commId, newTp);
}
}
currentlyTransferedStreams.put(ba, newIncomplete);
}
/**
* ToDo
*
* @param ba
*/
private void rescheduleEventBased(GnpNetBandwidthAllocation ba) {
Set<TransferProgress> oldIncomplete = currentlyTransferedStreams
.get(ba);
if (oldIncomplete == null) {
return;
}
Set<TransferProgress> newIncomplete = new HashSet<TransferProgress>(
oldIncomplete.size());
GnpNetLayer sender = (GnpNetLayer) ba.getSender();
GnpNetLayer receiver = (GnpNetLayer) ba.getReceiver();
long currentTime = Time.getCurrentTime();
double leftBandwidth = ba.getAllocatedBandwidth();
// Tesweise auskommentiert. muss aber wieder rein bzw ersetzt werden um
// abgbrochene streams zu entfernen
// oldIncomplete.removeAll(obsoleteEvents);
int leftStreams = oldIncomplete.size();
for (TransferProgress tp : oldIncomplete) {
double remainingBytes = tp.getRemainingBytes(currentTime);
double bandwidth = leftBandwidth / leftStreams;
if (tp.getMessage().getPayload() instanceof TCPMessage) {
double throughput = netLatencyModel.getTcpThroughput(sender,
receiver);
if (throughput < bandwidth)
bandwidth = throughput;
}
leftBandwidth -= bandwidth;
leftStreams--;
long transmissionTime = this.netLatencyModel.getTransmissionDelay(
remainingBytes, bandwidth);
long propagationTime = this.netLatencyModel.getPropagationDelay(
sender, receiver);
long arrivalDelay = transmissionTime + propagationTime;
TransferProgress newTp = new TransferProgress(tp.getMessage(),
bandwidth, remainingBytes, currentTime);
Event.scheduleWithDelay(arrivalDelay, this, newTp, EVENT_RECEIVE);
// newTp.relatedEvent = event;
newIncomplete.add(newTp);
int commId = ((AbstractTransMessage) tp.getMessage().getPayload())
.getCommId();
currentStreams.put(commId, newTp);
newTp.firstSchedule = false;
if (tp.firstSchedule == false) {
tp.obsolete = true;
// tp.relatedEvent.setData(null);
}
}
currentlyTransferedStreams.put(ba, newIncomplete);
// obsoleteEvents.addAll(oldIncomplete);
}
}
\ No newline at end of file
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp;
public class HaversineHelpers {
/** Radius of the earth, in meters, at the equator. */
private static final double GLOBE_RADIUS_EQUATOR = 6378000;
/** Radius of the earth, in meters, at the poles. */
private static final double GLOBE_RADIUS_POLES = 6357000;
public static final double radians(double degrees) {
return degrees * (2 * Math.PI) / 360;
}
public static final double degrees(double radians) {
return radians * 360 / (2 * Math.PI);
}
public static final double square(double d) {
return d * d;
}
/**
* Computes the earth's radius of curvature at a particular latitude,
* assuming that the earth is a squashed sphere with elliptical
* cross-section.
*
* @param lat
* - latitude in radians. This is the angle that a point at this
* latitude makes with the horizontal.
*/
public static final double globeRadiusOfCurvature(double lat) {
double a = GLOBE_RADIUS_EQUATOR; // major axis
double b = GLOBE_RADIUS_POLES; // minor axis
double e = Math.sqrt(1 - square(b / a)); // eccentricity
return a * Math.sqrt(1 - square(e)) / (1 - square(e * Math.sin(lat)));
}
}
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Random;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
/**
* Assigns peers to x,y coordinates accoring to the grey colors of a 8bit
* bitmap. PeerDistributionFromBitmap must be initialized first. Then,
* getNextPeerLocation returns a peers location accoring to the ditribution
* based on the bitmap.
*
* @author Andre Mink, Sebastian Kaune
*/
public class PeerDistributionFromBitmap {
private static PeerDistributionFromBitmap instance;
private int mapWidth;
private int mapHeight;
private boolean initialized;
private ArrayList map;
private Random rnd = Randoms.getRandom(PeerDistributionFromBitmap.class);
public static PeerDistributionFromBitmap getInstance() {
if (instance == null)
instance = new PeerDistributionFromBitmap();
return instance;
}
/**
* Sets the path to the bitmap and the number of peers of this experiment
*
* @param pathToBitmap
* path to the bitmap
* @param numberOfPeers
* number of peers of this experiment
*/
public void initialize(String pathToBitmap, int numberOfPeers) {
BitmapLoader bl = new BitmapLoader(pathToBitmap);
map = bl.assignPeers(numberOfPeers, bl.getDistributionFromBitmap());
mapWidth = bl.width;
mapHeight = bl.height;
initialized = true;
instance = this;
}
/**
* Returns the next x,y coordinate of a peer based on the bitmap
*
* @return the next x,y coordinate of a peer
*/
public Point2D.Double getNextPeerLocation() {
Point p = instance.getNextLocation();
double x = -1;
double y = -1;
while (x < 0.0 || x > mapWidth || y < 0.0 || y > mapHeight) {
x = p.x - rnd.nextDouble() + 0.5;
y = p.y - rnd.nextDouble() + 0.5;
}
return new Point2D.Double(x, y);
}
/**
* Returns the status
*
* @return <code>true</code> if PeerDistributionFromBitmap has been
* initilaized, <code>false</code> otherwise
*/
public boolean isInitialized() {
return initialized;
}
public PeerDistributionFromBitmap() {
this.map = new ArrayList();
this.mapHeight = 0;
this.mapWidth = 0;
this.initialized = false;
}
private Point getNextLocation() {
int i = rnd.nextInt(map.size());
return (Point) map.remove(i);
}
}
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp;
import de.tud.kom.p2psim.api.network.NetMessage;
import de.tudarmstadt.maki.simonstrator.api.Time;
public class TransferProgress {
private NetMessage message;
private double bandwidth; // in Simulator Time Units;
private double remainingBytes;
private long scheduledAt;
public boolean firstSchedule = true;
public boolean obsolete = false;
public TransferProgress(NetMessage msg, double bandwidth,
double remainingBytes, long scheduledAt) {
this.message = msg;
this.bandwidth = bandwidth / Time.SECOND;
this.remainingBytes = remainingBytes;
this.scheduledAt = scheduledAt;
}
public NetMessage getMessage() {
return message;
}
public double getRemainingBytes(long time) {
long interval = time - scheduledAt;
return remainingBytes - (interval * bandwidth);
}
/*
* public long getArrivalTime() { return arrivalTime; }
*/
}
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp.geoip;
/**
* Represents a country.
*
* @author Matt Tucker
*/
public class Country {
private String code;
private String name;
/**
* Creates a new Country.
*
* @param code
* the country code.
* @param name
* the country name.
*/
public Country(String code, String name) {
this.code = code;
this.name = name;
}
/**
* Returns the ISO two-letter country code of this country.
*
* @return the country code.
*/
public String getCode() {
return code;
}
/**
* Returns the name of this country.
*
* @return the country name.
*/
public String getName() {
return name;
}
}
/**
* DatabaseInfo.java
*
* Copyright (C) 2003 MaxMind LLC. All Rights Reserved.
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package de.tud.kom.p2psim.impl.network.gnp.geoip;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Encapsulates metadata about the GeoIP database. The database has a date, is a
* premium or standard version, and is one of the following types:
*
* <ul>
* <li>Country edition -- this is the most common version of the database. It
* includes the name of the country and it's ISO country code given an IP
* address.
* <li>Region edition -- includes the country information as well as what U.S.
* state or Canadian province the IP address is from if the IP address is from
* the U.S. or Canada.
* <li>City edition -- includes country, region, city, postal code, latitude,
* and longitude information.
* <li>Org edition -- includes country and netblock owner.
* <li>ISP edition -- includes country, region, city, postal code, latitude,
* longitude, ISP, and organization information.
* </ul>
*
* @see com.maxmind.geoip.LookupService#getDatabaseInfo()
* @author Matt Tucker
*/
public class DatabaseInfo {
public final static int COUNTRY_EDITION = 1;
public final static int REGION_EDITION_REV0 = 7;
public final static int REGION_EDITION_REV1 = 3;
public final static int CITY_EDITION_REV0 = 6;
public final static int CITY_EDITION_REV1 = 2;
public final static int ORG_EDITION = 5;
public final static int ISP_EDITION = 4;
public final static int PROXY_EDITION = 8;
public final static int ASNUM_EDITION = 9;
public final static int NETSPEED_EDITION = 10;
private static SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
private String info;
/**
* Creates a new DatabaseInfo object given the database info String.
*
* @param info
*/
public DatabaseInfo(String info) {
this.info = info;
}
public int getType() {
if (info == null || info.equals("")) {
return COUNTRY_EDITION;
} else {
// Get the type code from the database info string and then
// subtract 105 from the value to preserve compatability with
// databases from April 2003 and earlier.
return Integer.parseInt(info.substring(4, 7)) - 105;
}
}
/**
* Returns true if the database is the premium version.
*
* @return true if the premium version of the database.
*/
public boolean isPremium() {
return info.indexOf("FREE") < 0;
}
/**
* Returns the date of the database.
*
* @return the date of the database.
*/
public Date getDate() {
for (int i = 0; i < info.length() - 9; i++) {
if (Character.isWhitespace(info.charAt(i))) {
String dateString = info.substring(i + 1, i + 9);
try {
synchronized (formatter) {
return formatter.parse(dateString);
}
} catch (ParseException pe) {
}
break;
}
}
return null;
}
public String toString() {
return info;
}
}
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp.geoip;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
public class IspLookupService {
SortedMap<Long, String> data;
public IspLookupService(String path) {
data = new TreeMap<Long, String>();
try {
readFile(path);
} catch (IOException e) {
e.printStackTrace();
}
}
private void readFile(String path) throws IOException {
FileReader fr = new FileReader(path);
BufferedReader in = new BufferedReader(fr);
String line = null;
while ((line = in.readLine()) != null) {
String[] tmp = line.split(",");
data.put(Long.valueOf(tmp[0]), tmp[2].replace("\"", ""));
data.put(Long.valueOf(tmp[1]), tmp[2].replace("\"", ""));
}
}
public String getISP(long ip) {
Iterator<Entry<Long, String>> it = data.entrySet().iterator();
while (it.hasNext()) {
Entry<Long, String> lowerBound = it.next();
if (ip >= lowerBound.getKey()) {
if (it.hasNext()) {
Entry<Long, String> upperBound = it.next();
if (ip <= upperBound.getKey()
&& upperBound.getValue().equals(
lowerBound.getValue()))
return lowerBound.getValue();
}
}
}
return null;
}
}
/**
* Location.java
*
* Copyright (C) 2004 MaxMind LLC. All Rights Reserved.
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package de.tud.kom.p2psim.impl.network.gnp.geoip;
public class Location {
public String countryCode;
public String countryName;
public String region;
public String city;
public String postalCode;
public float latitude;
public float longitude;
public int dma_code;
public int area_code;
private final static double EARTH_DIAMETER = 2 * 6378.2;
private final static double PI = 3.14159265;
private final static double RAD_CONVERT = PI / 180;
public double distance(Location loc) {
double delta_lat, delta_lon;
double temp;
float lat1 = latitude;
float lon1 = longitude;
float lat2 = loc.latitude;
float lon2 = loc.longitude;
// convert degrees to radians
lat1 *= RAD_CONVERT;
lat2 *= RAD_CONVERT;
// find the deltas
delta_lat = lat2 - lat1;
delta_lon = (lon2 - lon1) * RAD_CONVERT;
// Find the great circle distance
temp = Math.pow(Math.sin(delta_lat / 2), 2) + Math.cos(lat1)
* Math.cos(lat2) * Math.pow(Math.sin(delta_lon / 2), 2);
return EARTH_DIAMETER
* Math.atan2(Math.sqrt(temp), Math.sqrt(1 - temp));
}
}
/**
* LookupService.java
*
* Copyright (C) 2003 MaxMind LLC. All Rights Reserved.
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package de.tud.kom.p2psim.impl.network.gnp.geoip;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.StringTokenizer;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
/**
* Provides a lookup service for information based on an IP address. The
* location of a database file is supplied when creating a lookup service
* instance. The edition of the database determines what information is
* available about an IP address. See the DatabaseInfo class for further
* details.
* <p>
*
* The following code snippet demonstrates looking up the country that an IP
* address is from:
*
* <pre>
* // First, create a LookupService instance with the location of the database.
* LookupService lookupService = new LookupService(&quot;c:\\geoip.dat&quot;);
* // Assume we have a String ipAddress (in dot-decimal form).
* Country country = lookupService.getCountry(ipAddress);
* System.out.println(&quot;The country is: &quot; + country.getName());
* System.out.println(&quot;The country code is: &quot; + country.getCode());
* </pre>
*
* In general, a single LookupService instance should be created and then reused
* repeatedly.
* <p>
*
* <i>Tip:</i> Those deploying the GeoIP API as part of a web application may
* find it difficult to pass in a File to create the lookup service, as the
* location of the database may vary per deployment or may even be part of the
* web-application. In this case, the database should be added to the classpath
* of the web-app. For example, by putting it into the WEB-INF/classes directory
* of the web application. The following code snippet demonstrates how to create
* a LookupService using a database that can be found on the classpath:
*
* <pre>
* String fileName = getClass().getResource(&quot;/GeoIP.dat&quot;).toExternalForm()
* .substring(6);
*
* LookupService lookupService = new LookupService(fileName);
* </pre>
*
* @author Matt Tucker (matt@jivesoftware.com)
*/
public class LookupService {
/**
* Database file.
*/
private RandomAccessFile file = null;
private File databaseFile = null;
/**
* Information about the database.
*/
private DatabaseInfo databaseInfo = null;
/**
* The database type. Default is the country edition.
*/
byte databaseType = DatabaseInfo.COUNTRY_EDITION;
int databaseSegments[];
int recordLength;
String licenseKey;
int dnsService = 0;
int dboptions;
byte dbbuffer[];
byte index_cache[];
long mtime;
private final static int US_OFFSET = 1;
private final static int CANADA_OFFSET = 677;
private final static int WORLD_OFFSET = 1353;
private final static int FIPS_RANGE = 360;
private final static int COUNTRY_BEGIN = 16776960;
private final static int STATE_BEGIN_REV0 = 16700000;
private final static int STATE_BEGIN_REV1 = 16000000;
private final static int STRUCTURE_INFO_MAX_SIZE = 20;
private final static int DATABASE_INFO_MAX_SIZE = 100;
public final static int GEOIP_STANDARD = 0;
public final static int GEOIP_MEMORY_CACHE = 1;
public final static int GEOIP_CHECK_CACHE = 2;
public final static int GEOIP_INDEX_CACHE = 4;
public final static int GEOIP_UNKNOWN_SPEED = 0;
public final static int GEOIP_DIALUP_SPEED = 1;
public final static int GEOIP_CABLEDSL_SPEED = 2;
public final static int GEOIP_CORPORATE_SPEED = 3;
private final static int SEGMENT_RECORD_LENGTH = 3;
private final static int STANDARD_RECORD_LENGTH = 3;
private final static int ORG_RECORD_LENGTH = 4;
private final static int MAX_RECORD_LENGTH = 4;
private final static int MAX_ORG_RECORD_LENGTH = 300;
private final static int FULL_RECORD_LENGTH = 60;
private static final Country UNKNOWN_COUNTRY = new Country("--", "N/A");
private final static HashMap hashmapcountryCodetoindex = new HashMap(512);
private final static HashMap hashmapcountryNametoindex = new HashMap(512);
private final static String[] countryCode = { "--", "AP", "EU", "AD", "AE",
"AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT",
"AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI",
"BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ",
"CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN",
"CO", "CR", "CU", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM",
"DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ",
"FK", "FM", "FO", "FR", "FX", "GA", "GB", "GD", "GE", "GF", "GH",
"GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW",
"GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN",
"IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH",
"KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC",
"LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD",
"MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS",
"MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF",
"NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE",
"PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW",
"PY", "QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE",
"SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST",
"SV", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TM",
"TN", "TO", "TL", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM",
"US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF",
"WS", "YE", "YT", "RS", "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1",
"AX", "GG", "IM", "JE" };
private final static String[] countryName = { "N/A", "Asia/Pacific Region",
"Europe", "Andorra", "United Arab Emirates", "Afghanistan",
"Antigua and Barbuda", "Anguilla", "Albania", "Armenia",
"Netherlands Antilles", "Angola", "Antarctica", "Argentina",
"American Samoa", "Austria", "Australia", "Aruba", "Azerbaijan",
"Bosnia and Herzegovina", "Barbados", "Bangladesh", "Belgium",
"Burkina Faso", "Bulgaria", "Bahrain", "Burundi", "Benin",
"Bermuda", "Brunei Darussalam", "Bolivia", "Brazil", "Bahamas",
"Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize",
"Canada", "Cocos (Keeling) Islands",
"Congo, The Democratic Republic of the",
"Central African Republic", "Congo", "Switzerland",
"Cote D'Ivoire", "Cook Islands", "Chile", "Cameroon", "China",
"Colombia", "Costa Rica", "Cuba", "Cape Verde", "Christmas Island",
"Cyprus", "Czech Republic", "Germany", "Djibouti", "Denmark",
"Dominica", "Dominican Republic", "Algeria", "Ecuador", "Estonia",
"Egypt", "Western Sahara", "Eritrea", "Spain", "Ethiopia",
"Finland", "Fiji", "Falkland Islands (Malvinas)",
"Micronesia, Federated States of", "Faroe Islands", "France",
"France, Metropolitan", "Gabon", "United Kingdom", "Grenada",
"Georgia", "French Guiana", "Ghana", "Gibraltar", "Greenland",
"Gambia", "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece",
"South Georgia and the South Sandwich Islands", "Guatemala",
"Guam", "Guinea-Bissau", "Guyana", "Hong Kong",
"Heard Island and McDonald Islands", "Honduras", "Croatia",
"Haiti", "Hungary", "Indonesia", "Ireland", "Israel", "India",
"British Indian Ocean Territory", "Iraq",
"Iran, Islamic Republic of", "Iceland", "Italy", "Jamaica",
"Jordan", "Japan", "Kenya", "Kyrgyzstan", "Cambodia", "Kiribati",
"Comoros", "Saint Kitts and Nevis",
"Korea, Democratic People's Republic of", "Korea, Republic of",
"Kuwait", "Cayman Islands", "Kazakstan",
"Lao People's Democratic Republic", "Lebanon", "Saint Lucia",
"Liechtenstein", "Sri Lanka", "Liberia", "Lesotho", "Lithuania",
"Luxembourg", "Latvia", "Libyan Arab Jamahiriya", "Morocco",
"Monaco", "Moldova, Republic of", "Madagascar", "Marshall Islands",
"Macedonia", "Mali", "Myanmar", "Mongolia", "Macau",
"Northern Mariana Islands", "Martinique", "Mauritania",
"Montserrat", "Malta", "Mauritius", "Maldives", "Malawi", "Mexico",
"Malaysia", "Mozambique", "Namibia", "New Caledonia", "Niger",
"Norfolk Island", "Nigeria", "Nicaragua", "Netherlands", "Norway",
"Nepal", "Nauru", "Niue", "New Zealand", "Oman", "Panama", "Peru",
"French Polynesia", "Papua New Guinea", "Philippines", "Pakistan",
"Poland", "Saint Pierre and Miquelon", "Pitcairn Islands",
"Puerto Rico", "" + "Palestinian Territory", "Portugal", "Palau",
"Paraguay", "Qatar", "Reunion", "Romania", "Russian Federation",
"Rwanda", "Saudi Arabia", "Solomon Islands", "Seychelles", "Sudan",
"Sweden", "Singapore", "Saint Helena", "Slovenia",
"Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino",
"Senegal", "Somalia", "Suriname", "Sao Tome and Principe",
"El Salvador", "Syrian Arab Republic", "Swaziland",
"Turks and Caicos Islands", "Chad", "French Southern Territories",
"Togo", "Thailand", "Tajikistan", "Tokelau", "Turkmenistan",
"Tunisia", "Tonga", "Timor-Leste", "Turkey", "Trinidad and Tobago",
"Tuvalu", "Taiwan", "Tanzania, United Republic of", "Ukraine",
"Uganda", "United States Minor Outlying Islands", "United States",
"Uruguay", "Uzbekistan", "Holy See (Vatican City State)",
"Saint Vincent and the Grenadines", "Venezuela",
"Virgin Islands, British", "Virgin Islands, U.S.", "Vietnam",
"Vanuatu", "Wallis and Futuna", "Samoa", "Yemen", "Mayotte",
"Serbia", "South Africa", "Zambia", "Montenegro", "Zimbabwe",
"Anonymous Proxy", "Satellite Provider", "Other", "Aland Islands",
"Guernsey", "Isle of Man", "Jersey" };
/**
* Create a new distributed lookup service using the license key
*
* @param databaseFile
* String representation of the database file.
* @param licenseKey
* license key provided by Maxmind to access distributed service
*/
public LookupService(String databaseFile, String licenseKey)
throws IOException {
this(new File(databaseFile));
this.licenseKey = licenseKey;
dnsService = 1;
}
/**
* Create a new distributed lookup service using the license key
*
* @param databaseFile
* the database file.
* @param licenseKey
* license key provided by Maxmind to access distributed service
*/
public LookupService(File databaseFile, String licenseKey)
throws IOException {
this(databaseFile);
this.licenseKey = licenseKey;
dnsService = 1;
}
/**
* Create a new distributed lookup service using the license key
*
* @param options
* Resevered for future use
* @param licenseKey
* license key provided by Maxmind to access distributed service
*/
public LookupService(int options, String licenseKey) throws IOException {
this.licenseKey = licenseKey;
dnsService = 1;
init();
}
/**
* Create a new lookup service using the specified database file.
*
* @param databaseFile
* String representation of the database file.
* @throws java.io.IOException
* if an error occured creating the lookup service from the
* database file.
*/
public LookupService(String databaseFile) throws IOException {
this(new File(databaseFile));
}
/**
* Create a new lookup service using the specified database file.
*
* @param databaseFile
* the database file.
* @throws java.io.IOException
* if an error occured creating the lookup service from the
* database file.
*/
public LookupService(File databaseFile) throws IOException {
this.databaseFile = databaseFile;
this.file = new RandomAccessFile(databaseFile, "r");
init();
}
/**
* Create a new lookup service using the specified database file.
*
* @param databaseFile
* String representation of the database file.
* @param options
* database flags to use when opening the database GEOIP_STANDARD
* read database from disk GEOIP_MEMORY_CACHE cache the database
* in RAM and read it from RAM
* @throws java.io.IOException
* if an error occured creating the lookup service from the
* database file.
*/
public LookupService(String databaseFile, int options) throws IOException {
this(new File(databaseFile), options);
}
/**
* Create a new lookup service using the specified database file.
*
* @param databaseFile
* the database file.
* @param options
* database flags to use when opening the database GEOIP_STANDARD
* read database from disk GEOIP_MEMORY_CACHE cache the database
* in RAM and read it from RAM
* @throws java.io.IOException
* if an error occured creating the lookup service from the
* database file.
*/
public LookupService(File databaseFile, int options) throws IOException {
this.databaseFile = databaseFile;
this.file = new RandomAccessFile(databaseFile, "r");
dboptions = options;
init();
}
/**
* Reads meta-data from the database file.
*
* @throws java.io.IOException
* if an error occurs reading from the database file.
*/
private void init() throws IOException {
int i, j;
byte[] delim = new byte[3];
byte[] buf = new byte[SEGMENT_RECORD_LENGTH];
if (file == null) {
// distributed service only
for (i = 0; i < 233; i++) {
hashmapcountryCodetoindex.put(countryCode[i], new Integer(i));
hashmapcountryNametoindex.put(countryName[i], new Integer(i));
}
return;
}
if ((dboptions & GEOIP_CHECK_CACHE) != 0) {
mtime = databaseFile.lastModified();
}
file.seek(file.length() - 3);
for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) {
file.read(delim);
if (delim[0] == -1 && delim[1] == -1 && delim[2] == -1) {
databaseType = file.readByte();
if (databaseType >= 106) {
// Backward compatibility with databases from April 2003 and
// earlier
databaseType -= 105;
}
// Determine the database type.
if (databaseType == DatabaseInfo.REGION_EDITION_REV0) {
databaseSegments = new int[1];
databaseSegments[0] = STATE_BEGIN_REV0;
recordLength = STANDARD_RECORD_LENGTH;
} else if (databaseType == DatabaseInfo.REGION_EDITION_REV1) {
databaseSegments = new int[1];
databaseSegments[0] = STATE_BEGIN_REV1;
recordLength = STANDARD_RECORD_LENGTH;
} else if (databaseType == DatabaseInfo.CITY_EDITION_REV0
|| databaseType == DatabaseInfo.CITY_EDITION_REV1
|| databaseType == DatabaseInfo.ORG_EDITION
|| databaseType == DatabaseInfo.ISP_EDITION
|| databaseType == DatabaseInfo.ASNUM_EDITION) {
databaseSegments = new int[1];
databaseSegments[0] = 0;
if (databaseType == DatabaseInfo.CITY_EDITION_REV0
|| databaseType == DatabaseInfo.CITY_EDITION_REV1
|| databaseType == DatabaseInfo.ASNUM_EDITION) {
recordLength = STANDARD_RECORD_LENGTH;
} else {
recordLength = ORG_RECORD_LENGTH;
}
file.read(buf);
for (j = 0; j < SEGMENT_RECORD_LENGTH; j++) {
databaseSegments[0] += (unsignedByteToInt(buf[j]) << (j * 8));
}
}
break;
} else {
file.seek(file.getFilePointer() - 4);
}
}
if ((databaseType == DatabaseInfo.COUNTRY_EDITION)
| (databaseType == DatabaseInfo.PROXY_EDITION)
| (databaseType == DatabaseInfo.NETSPEED_EDITION)) {
databaseSegments = new int[1];
databaseSegments[0] = COUNTRY_BEGIN;
recordLength = STANDARD_RECORD_LENGTH;
}
if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
int l = (int) file.length();
dbbuffer = new byte[l];
file.seek(0);
file.read(dbbuffer, 0, l);
databaseInfo = this.getDatabaseInfo();
file.close();
}
if ((dboptions & GEOIP_INDEX_CACHE) != 0) {
int l = databaseSegments[0] * recordLength * 2;
index_cache = new byte[l];
if (index_cache != null) {
file.seek(0);
file.read(index_cache, 0, l);
}
} else {
index_cache = null;
}
}
/**
* Closes the lookup service.
*/
public void close() {
try {
if (file != null) {
file.close();
}
file = null;
} catch (Exception e) {
}
}
/**
* Returns the country the IP address is in.
*
* @param ipAddress
* String version of an IP address, i.e. "127.0.0.1"
* @return the country the IP address is from.
*/
public Country getCountry(String ipAddress) {
InetAddress addr;
try {
addr = InetAddress.getByName(ipAddress);
} catch (UnknownHostException e) {
return UNKNOWN_COUNTRY;
}
return getCountry(bytesToLong(addr.getAddress()));
}
/**
* Returns the country the IP address is in.
*
* @param ipAddress
* the IP address.
* @return the country the IP address is from.
*/
public Country getCountry(InetAddress ipAddress) {
return getCountry(bytesToLong(ipAddress.getAddress()));
}
/**
* Returns the country the IP address is in.
*
* @param ipAddress
* the IP address in long format.
* @return the country the IP address is from.
*/
public Country getCountry(long ipAddress) {
if (file == null && (dboptions & GEOIP_MEMORY_CACHE) == 0) {
throw new IllegalStateException("Database has been closed.");
}
int ret = seekCountry(ipAddress) - COUNTRY_BEGIN;
if (ret == 0) {
return UNKNOWN_COUNTRY;
} else {
return new Country(countryCode[ret], countryName[ret]);
}
}
public int getID(String ipAddress) {
InetAddress addr;
try {
addr = InetAddress.getByName(ipAddress);
} catch (UnknownHostException e) {
return 0;
}
return getID(bytesToLong(addr.getAddress()));
}
public int getID(InetAddress ipAddress) {
return getID(bytesToLong(ipAddress.getAddress()));
}
public int getID(long ipAddress) {
if (file == null && (dboptions & GEOIP_MEMORY_CACHE) == 0) {
throw new IllegalStateException("Database has been closed.");
}
int ret = seekCountry(ipAddress) - databaseSegments[0];
return ret;
}
/**
* Returns information about the database.
*
* @return database info.
*/
public DatabaseInfo getDatabaseInfo() {
if (databaseInfo != null) {
return databaseInfo;
}
try {
// Synchronize since we're accessing the database file.
synchronized (this) {
_check_mtime();
boolean hasStructureInfo = false;
byte[] delim = new byte[3];
// Advance to part of file where database info is stored.
file.seek(file.length() - 3);
for (int i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) {
file.read(delim);
if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) {
hasStructureInfo = true;
break;
}
}
if (hasStructureInfo) {
file.seek(file.getFilePointer() - 3);
} else {
// No structure info, must be pre Sep 2002 database, go back
// to end.
file.seek(file.length() - 3);
}
// Find the database info string.
for (int i = 0; i < DATABASE_INFO_MAX_SIZE; i++) {
file.read(delim);
if (delim[0] == 0 && delim[1] == 0 && delim[2] == 0) {
byte[] dbInfo = new byte[i];
file.read(dbInfo);
// Create the database info object using the string.
this.databaseInfo = new DatabaseInfo(new String(dbInfo));
return databaseInfo;
}
file.seek(file.getFilePointer() - 4);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return new DatabaseInfo("");
}
synchronized void _check_mtime() {
try {
if ((dboptions & GEOIP_CHECK_CACHE) != 0) {
long t = databaseFile.lastModified();
if (t != mtime) {
/* GeoIP Database file updated */
/* refresh filehandle */
file.close();
file = new RandomAccessFile(databaseFile, "r");
init();
}
}
} catch (IOException e) {
System.out.println("file not found");
}
}
// for GeoIP City only
public Location getLocation(InetAddress addr) {
return getLocation(bytesToLong(addr.getAddress()));
}
// for GeoIP City only
public Location getLocation(String str) {
if (dnsService == 0) {
InetAddress addr;
try {
addr = InetAddress.getByName(str);
} catch (UnknownHostException e) {
return null;
}
return getLocation(addr);
} else {
String str2 = getDnsAttributes(str);
return getLocationwithdnsservice(str2);
// TODO if DNS is not available, go to local file as backup
}
}
String getDnsAttributes(String ip) {
try {
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial",
"com.sun.jndi.dns.DnsContextFactory");
// TODO don't specify ws1, instead use ns servers for s.maxmind.com
env.put("java.naming.provider.url", "dns://ws1.maxmind.com/");
DirContext ictx = new InitialDirContext(env);
Attributes attrs = ictx.getAttributes(licenseKey + "." + ip
+ ".s.maxmind.com", new String[] { "txt" });
// System.out.println(attrs.get("txt").get());
String str = attrs.get("txt").get().toString();
return str;
} catch (NamingException e) {
// TODO fix this to handle exceptions
System.out.println("DNS error");
return null;
}
}
public Location getLocationwithdnsservice(String str) {
Location record = new Location();
String key;
String value;
StringTokenizer st = new StringTokenizer(str, ";=\"");
while (st.hasMoreTokens()) {
key = st.nextToken();
if (st.hasMoreTokens()) {
value = st.nextToken();
} else {
value = "";
}
if (key.equals("co")) {
Integer i = (Integer) hashmapcountryCodetoindex.get(value);
record.countryCode = value;
record.countryName = countryName[i.intValue()];
}
if (key.equals("ci")) {
record.city = value;
}
if (key.equals("re")) {
record.region = value;
}
if (key.equals("zi")) {
record.postalCode = value;
}
// TODO, ISP and Organization
// if (key.equals("or")) {
// record.org = value;
// }
// if (key.equals("is")) {
// record.isp = value;
// }
if (key.equals("la")) {
try {
record.latitude = Float.parseFloat(value);
} catch (NumberFormatException e) {
record.latitude = 0;
}
}
if (key.equals("lo")) {
try {
record.longitude = Float.parseFloat(value);
} catch (NumberFormatException e) {
record.latitude = 0;
}
}
if (key.equals("dm")) {
try {
record.dma_code = Integer.parseInt(value);
} catch (NumberFormatException e) {
record.dma_code = 0;
}
}
if (key.equals("ac")) {
try {
record.area_code = Integer.parseInt(value);
} catch (NumberFormatException e) {
record.area_code = 0;
}
}
}
return record;
}
public synchronized Region getRegion(String str) {
InetAddress addr;
try {
addr = InetAddress.getByName(str);
} catch (UnknownHostException e) {
return null;
}
return getRegion(bytesToLong(addr.getAddress()));
}
public synchronized Region getRegion(long ipnum) {
Region record = new Region();
int seek_region = 0;
if (databaseType == DatabaseInfo.REGION_EDITION_REV0) {
seek_region = seekCountry(ipnum) - STATE_BEGIN_REV0;
char ch[] = new char[2];
if (seek_region >= 1000) {
record.countryCode = "US";
record.countryName = "United States";
ch[0] = (char) (((seek_region - 1000) / 26) + 65);
ch[1] = (char) (((seek_region - 1000) % 26) + 65);
record.region = new String(ch);
} else {
record.countryCode = countryCode[seek_region];
record.countryName = countryName[seek_region];
record.region = "";
}
} else if (databaseType == DatabaseInfo.REGION_EDITION_REV1) {
seek_region = seekCountry(ipnum) - STATE_BEGIN_REV1;
char ch[] = new char[2];
if (seek_region < US_OFFSET) {
record.countryCode = "";
record.countryName = "";
record.region = "";
} else if (seek_region < CANADA_OFFSET) {
record.countryCode = "US";
record.countryName = "United States";
ch[0] = (char) (((seek_region - US_OFFSET) / 26) + 65);
ch[1] = (char) (((seek_region - US_OFFSET) % 26) + 65);
record.region = new String(ch);
} else if (seek_region < WORLD_OFFSET) {
record.countryCode = "CA";
record.countryName = "Canada";
ch[0] = (char) (((seek_region - CANADA_OFFSET) / 26) + 65);
ch[1] = (char) (((seek_region - CANADA_OFFSET) % 26) + 65);
record.region = new String(ch);
} else {
record.countryCode = countryCode[(seek_region - WORLD_OFFSET)
/ FIPS_RANGE];
record.countryName = countryName[(seek_region - WORLD_OFFSET)
/ FIPS_RANGE];
record.region = "";
}
}
return record;
}
public synchronized Location getLocation(long ipnum) {
int record_pointer;
byte record_buf[] = new byte[FULL_RECORD_LENGTH];
int record_buf_offset = 0;
Location record = new Location();
int str_length = 0;
int j, seek_country;
double latitude = 0, longitude = 0;
try {
seek_country = seekCountry(ipnum);
if (seek_country == databaseSegments[0]) {
return null;
}
record_pointer = seek_country + (2 * recordLength - 1)
* databaseSegments[0];
if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
// read from memory
for (int i = 0; i < FULL_RECORD_LENGTH; i++) {
record_buf[i] = dbbuffer[i + record_pointer];
}
} else {
// read from disk
file.seek(record_pointer);
file.read(record_buf);
}
// get country
record.countryCode = countryCode[unsignedByteToInt(record_buf[0])];
record.countryName = countryName[unsignedByteToInt(record_buf[0])];
record_buf_offset++;
// get region
while (record_buf[record_buf_offset + str_length] != '\0')
str_length++;
if (str_length > 0) {
record.region = new String(record_buf, record_buf_offset,
str_length);
}
record_buf_offset += str_length + 1;
str_length = 0;
// get city
while (record_buf[record_buf_offset + str_length] != '\0')
str_length++;
if (str_length > 0) {
record.city = new String(record_buf, record_buf_offset,
str_length, "ISO-8859-1");
}
record_buf_offset += str_length + 1;
str_length = 0;
// get postal code
while (record_buf[record_buf_offset + str_length] != '\0')
str_length++;
if (str_length > 0) {
record.postalCode = new String(record_buf, record_buf_offset,
str_length);
}
record_buf_offset += str_length + 1;
// get latitude
for (j = 0; j < 3; j++)
latitude += (unsignedByteToInt(record_buf[record_buf_offset + j]) << (j * 8));
record.latitude = (float) latitude / 10000 - 180;
record_buf_offset += 3;
// get longitude
for (j = 0; j < 3; j++)
longitude += (unsignedByteToInt(record_buf[record_buf_offset
+ j]) << (j * 8));
record.longitude = (float) longitude / 10000 - 180;
record.dma_code = 0;
record.area_code = 0;
if (databaseType == DatabaseInfo.CITY_EDITION_REV1) {
// get DMA code
int dmaarea_combo = 0;
if (record.countryCode == "US") {
record_buf_offset += 3;
for (j = 0; j < 3; j++)
dmaarea_combo += (unsignedByteToInt(record_buf[record_buf_offset
+ j]) << (j * 8));
record.dma_code = dmaarea_combo / 1000;
record.area_code = dmaarea_combo % 1000;
}
}
} catch (IOException e) {
System.err.println("IO Exception while seting up segments");
}
return record;
}
public String getOrg(InetAddress addr) {
return getOrg(bytesToLong(addr.getAddress()));
}
public String getOrg(String str) {
InetAddress addr;
try {
addr = InetAddress.getByName(str);
} catch (UnknownHostException e) {
return null;
}
return getOrg(addr);
}
// GeoIP Organization and ISP Edition methods
public synchronized String getOrg(long ipnum) {
int seek_org;
int record_pointer;
int str_length = 0;
byte[] buf = new byte[MAX_ORG_RECORD_LENGTH];
String org_buf;
try {
seek_org = seekCountry(ipnum);
if (seek_org == databaseSegments[0]) {
return null;
}
record_pointer = seek_org + (2 * recordLength - 1)
* databaseSegments[0];
if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
// read from memory
for (int i = 0; i < FULL_RECORD_LENGTH; i++) {
buf[i] = dbbuffer[i + record_pointer];
}
} else {
// read from disk
file.seek(record_pointer);
file.read(buf);
}
while (buf[str_length] != '\0') {
str_length++;
}
org_buf = new String(buf, 0, str_length, "ISO-8859-1");
return org_buf;
} catch (IOException e) {
System.out.println("IO Exception");
return null;
}
}
/**
* Finds the country index value given an IP address.
*
* @param ipAddress
* the ip address to find in long format.
* @return the country index.
*/
private synchronized int seekCountry(long ipAddress) {
byte[] buf = new byte[2 * MAX_RECORD_LENGTH];
int[] x = new int[2];
int offset = 0;
_check_mtime();
for (int depth = 31; depth >= 0; depth--) {
if ((dboptions & GEOIP_MEMORY_CACHE) == 1) {
// read from memory
for (int i = 0; i < 2 * MAX_RECORD_LENGTH; i++) {
buf[i] = dbbuffer[(2 * recordLength * offset) + i];
}
} else if ((dboptions & GEOIP_INDEX_CACHE) != 0) {
// read from index cache
for (int i = 0; i < 2 * MAX_RECORD_LENGTH; i++) {
buf[i] = index_cache[(2 * recordLength * offset) + i];
}
} else {
// read from disk
try {
file.seek(2 * recordLength * offset);
file.read(buf);
} catch (IOException e) {
System.out.println("IO Exception");
}
}
for (int i = 0; i < 2; i++) {
x[i] = 0;
for (int j = 0; j < recordLength; j++) {
int y = buf[i * recordLength + j];
if (y < 0) {
y += 256;
}
x[i] += (y << (j * 8));
}
}
if ((ipAddress & (1 << depth)) > 0) {
if (x[1] >= databaseSegments[0]) {
return x[1];
}
offset = x[1];
} else {
if (x[0] >= databaseSegments[0]) {
return x[0];
}
offset = x[0];
}
}
// shouldn't reach here
System.err.println("Error seeking country while seeking " + ipAddress);
return 0;
}
/**
* Returns the long version of an IP address given an InetAddress object.
*
* @param address
* the InetAddress.
* @return the long form of the IP address.
*/
private static long bytesToLong(byte[] address) {
long ipnum = 0;
for (int i = 0; i < 4; ++i) {
long y = address[i];
if (y < 0) {
y += 256;
}
ipnum += y << ((3 - i) * 8);
}
return ipnum;
}
private static int unsignedByteToInt(byte b) {
return (int) b & 0xFF;
}
}
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp.geoip;
public class Region {
public String countryCode;
public String countryName;
public String region;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp.geoip;
public class timeZone {
static public String timeZoneByCountryAndRegion(String country,
String region) {
String timezone = null;
if (country == null) {
return null;
}
if (region == null) {
region = "";
}
if (country.equals("US") == true) {
if (region.equals("AL") == true) {
timezone = "America/Chicago";
} else if (region.equals("AK") == true) {
timezone = "America/Anchorage";
} else if (region.equals("AZ") == true) {
timezone = "America/Phoenix";
} else if (region.equals("AR") == true) {
timezone = "America/Chicago";
} else if (region.equals("CA") == true) {
timezone = "America/Los_Angeles";
} else if (region.equals("CO") == true) {
timezone = "America/Denver";
} else if (region.equals("CT") == true) {
timezone = "America/New_York";
} else if (region.equals("DE") == true) {
timezone = "America/New_York";
} else if (region.equals("DC") == true) {
timezone = "America/New_York";
} else if (region.equals("FL") == true) {
timezone = "America/New_York";
} else if (region.equals("GA") == true) {
timezone = "America/New_York";
} else if (region.equals("HI") == true) {
timezone = "Pacific/Honolulu";
} else if (region.equals("ID") == true) {
timezone = "America/Denver";
} else if (region.equals("IL") == true) {
timezone = "America/Chicago";
} else if (region.equals("IN") == true) {
timezone = "America/Indianapolis";
} else if (region.equals("IA") == true) {
timezone = "America/Chicago";
} else if (region.equals("KS") == true) {
timezone = "America/Chicago";
} else if (region.equals("KY") == true) {
timezone = "America/New_York";
} else if (region.equals("LA") == true) {
timezone = "America/Chicago";
} else if (region.equals("ME") == true) {
timezone = "America/New_York";
} else if (region.equals("MD") == true) {
timezone = "America/New_York";
} else if (region.equals("MA") == true) {
timezone = "America/New_York";
} else if (region.equals("MI") == true) {
timezone = "America/New_York";
} else if (region.equals("MN") == true) {
timezone = "America/Chicago";
} else if (region.equals("MS") == true) {
timezone = "America/Chicago";
} else if (region.equals("MO") == true) {
timezone = "America/Chicago";
} else if (region.equals("MT") == true) {
timezone = "America/Denver";
} else if (region.equals("NE") == true) {
timezone = "America/Chicago";
} else if (region.equals("NV") == true) {
timezone = "America/Los_Angeles";
} else if (region.equals("NH") == true) {
timezone = "America/New_York";
} else if (region.equals("NJ") == true) {
timezone = "America/New_York";
} else if (region.equals("NM") == true) {
timezone = "America/Denver";
} else if (region.equals("NY") == true) {
timezone = "America/New_York";
} else if (region.equals("NC") == true) {
timezone = "America/New_York";
} else if (region.equals("ND") == true) {
timezone = "America/Chicago";
} else if (region.equals("OH") == true) {
timezone = "America/New_York";
} else if (region.equals("OK") == true) {
timezone = "America/Chicago";
} else if (region.equals("OR") == true) {
timezone = "America/Los_Angeles";
} else if (region.equals("PA") == true) {
timezone = "America/New_York";
} else if (region.equals("RI") == true) {
timezone = "America/New_York";
} else if (region.equals("SC") == true) {
timezone = "America/New_York";
} else if (region.equals("SD") == true) {
timezone = "America/Chicago";
} else if (region.equals("TN") == true) {
timezone = "America/Chicago";
} else if (region.equals("TX") == true) {
timezone = "America/Chicago";
} else if (region.equals("UT") == true) {
timezone = "America/Denver";
} else if (region.equals("VT") == true) {
timezone = "America/New_York";
} else if (region.equals("VA") == true) {
timezone = "America/New_York";
} else if (region.equals("WA") == true) {
timezone = "America/Los_Angeles";
} else if (region.equals("WV") == true) {
timezone = "America/New_York";
} else if (region.equals("WI") == true) {
timezone = "America/Chicago";
}
} else if (country.equals("CA") == true) {
if (region.equals("AB") == true) {
timezone = "America/Edmonton";
} else if (region.equals("BC") == true) {
timezone = "America/Vancouver";
} else if (region.equals("MB") == true) {
timezone = "America/Winnipeg";
} else if (region.equals("NB") == true) {
timezone = "America/Halifax";
} else if (region.equals("NF") == true) {
timezone = "America/St_Johns";
} else if (region.equals("NT") == true) {
timezone = "America/Yellowknife";
} else if (region.equals("NS") == true) {
timezone = "America/Halifax";
} else if (region.equals("NU") == true) {
timezone = "America/Rankin_Inlet";
} else if (region.equals("ON") == true) {
timezone = "America/Rainy_River";
} else if (region.equals("PE") == true) {
timezone = "America/Halifax";
} else if (region.equals("QC") == true) {
timezone = "America/Montreal";
} else if (region.equals("SK") == true) {
timezone = "America/Regina";
}
} else if (country.equals("AS") == true) {
timezone = "US/Samoa";
} else if (country.equals("CI") == true) {
timezone = "Africa/Abidjan";
} else if (country.equals("GH") == true) {
timezone = "Africa/Accra";
} else if (country.equals("DZ") == true) {
timezone = "Africa/Algiers";
} else if (country.equals("ER") == true) {
timezone = "Africa/Asmera";
} else if (country.equals("ML") == true) {
timezone = "Africa/Bamako";
} else if (country.equals("CF") == true) {
timezone = "Africa/Bangui";
} else if (country.equals("GM") == true) {
timezone = "Africa/Banjul";
} else if (country.equals("GW") == true) {
timezone = "Africa/Bissau";
} else if (country.equals("CG") == true) {
timezone = "Africa/Brazzaville";
} else if (country.equals("BI") == true) {
timezone = "Africa/Bujumbura";
} else if (country.equals("EG") == true) {
timezone = "Africa/Cairo";
} else if (country.equals("MA") == true) {
timezone = "Africa/Casablanca";
} else if (country.equals("GN") == true) {
timezone = "Africa/Conakry";
} else if (country.equals("SN") == true) {
timezone = "Africa/Dakar";
} else if (country.equals("DJ") == true) {
timezone = "Africa/Djibouti";
} else if (country.equals("SL") == true) {
timezone = "Africa/Freetown";
} else if (country.equals("BW") == true) {
timezone = "Africa/Gaborone";
} else if (country.equals("ZW") == true) {
timezone = "Africa/Harare";
} else if (country.equals("ZA") == true) {
timezone = "Africa/Johannesburg";
} else if (country.equals("UG") == true) {
timezone = "Africa/Kampala";
} else if (country.equals("SD") == true) {
timezone = "Africa/Khartoum";
} else if (country.equals("RW") == true) {
timezone = "Africa/Kigali";
} else if (country.equals("NG") == true) {
timezone = "Africa/Lagos";
} else if (country.equals("GA") == true) {
timezone = "Africa/Libreville";
} else if (country.equals("TG") == true) {
timezone = "Africa/Lome";
} else if (country.equals("AO") == true) {
timezone = "Africa/Luanda";
} else if (country.equals("ZM") == true) {
timezone = "Africa/Lusaka";
} else if (country.equals("GQ") == true) {
timezone = "Africa/Malabo";
} else if (country.equals("MZ") == true) {
timezone = "Africa/Maputo";
} else if (country.equals("LS") == true) {
timezone = "Africa/Maseru";
} else if (country.equals("SZ") == true) {
timezone = "Africa/Mbabane";
} else if (country.equals("SO") == true) {
timezone = "Africa/Mogadishu";
} else if (country.equals("LR") == true) {
timezone = "Africa/Monrovia";
} else if (country.equals("KE") == true) {
timezone = "Africa/Nairobi";
} else if (country.equals("TD") == true) {
timezone = "Africa/Ndjamena";
} else if (country.equals("NE") == true) {
timezone = "Africa/Niamey";
} else if (country.equals("MR") == true) {
timezone = "Africa/Nouakchott";
} else if (country.equals("BF") == true) {
timezone = "Africa/Ouagadougou";
} else if (country.equals("ST") == true) {
timezone = "Africa/Sao_Tome";
} else if (country.equals("LY") == true) {
timezone = "Africa/Tripoli";
} else if (country.equals("TN") == true) {
timezone = "Africa/Tunis";
} else if (country.equals("AI") == true) {
timezone = "America/Anguilla";
} else if (country.equals("AG") == true) {
timezone = "America/Antigua";
} else if (country.equals("AW") == true) {
timezone = "America/Aruba";
} else if (country.equals("BB") == true) {
timezone = "America/Barbados";
} else if (country.equals("BZ") == true) {
timezone = "America/Belize";
} else if (country.equals("CO") == true) {
timezone = "America/Bogota";
} else if (country.equals("VE") == true) {
timezone = "America/Caracas";
} else if (country.equals("KY") == true) {
timezone = "America/Cayman";
} else if (country.equals("MX") == true) {
timezone = "America/Chihuahua";
} else if (country.equals("CR") == true) {
timezone = "America/Costa_Rica";
} else if (country.equals("DM") == true) {
timezone = "America/Dominica";
} else if (country.equals("SV") == true) {
timezone = "America/El_Salvador";
} else if (country.equals("GD") == true) {
timezone = "America/Grenada";
} else if (country.equals("FR") == true) {
timezone = "Europe/Paris";
} else if (country.equals("GP") == true) {
timezone = "America/Guadeloupe";
} else if (country.equals("GT") == true) {
timezone = "America/Guatemala";
} else if (country.equals("EC") == true) {
timezone = "America/Guayaquil";
} else if (country.equals("GY") == true) {
timezone = "America/Guyana";
} else if (country.equals("CU") == true) {
timezone = "America/Havana";
} else if (country.equals("JM") == true) {
timezone = "America/Jamaica";
} else if (country.equals("BO") == true) {
timezone = "America/La_Paz";
} else if (country.equals("PE") == true) {
timezone = "America/Lima";
} else if (country.equals("NI") == true) {
timezone = "America/Managua";
} else if (country.equals("MQ") == true) {
timezone = "America/Martinique";
} else if (country.equals("AR") == true) {
timezone = "America/Mendoza";
} else if (country.equals("UY") == true) {
timezone = "America/Montevideo";
} else if (country.equals("MS") == true) {
timezone = "America/Montserrat";
} else if (country.equals("BS") == true) {
timezone = "America/Nassau";
} else if (country.equals("PA") == true) {
timezone = "America/Panama";
} else if (country.equals("SR") == true) {
timezone = "America/Paramaribo";
} else if (country.equals("PR") == true) {
timezone = "America/Puerto_Rico";
} else if (country.equals("KN") == true) {
timezone = "America/St_Kitts";
} else if (country.equals("LC") == true) {
timezone = "America/St_Lucia";
} else if (country.equals("VC") == true) {
timezone = "America/St_Vincent";
} else if (country.equals("HN") == true) {
timezone = "America/Tegucigalpa";
} else if (country.equals("YE") == true) {
timezone = "Asia/Aden";
} else if (country.equals("KZ") == true) {
timezone = "Asia/Almaty";
} else if (country.equals("JO") == true) {
timezone = "Asia/Amman";
} else if (country.equals("TM") == true) {
timezone = "Asia/Ashgabat";
} else if (country.equals("IQ") == true) {
timezone = "Asia/Baghdad";
} else if (country.equals("BH") == true) {
timezone = "Asia/Bahrain";
} else if (country.equals("AZ") == true) {
timezone = "Asia/Baku";
} else if (country.equals("TH") == true) {
timezone = "Asia/Bangkok";
} else if (country.equals("LB") == true) {
timezone = "Asia/Beirut";
} else if (country.equals("KG") == true) {
timezone = "Asia/Bishkek";
} else if (country.equals("BN") == true) {
timezone = "Asia/Brunei";
} else if (country.equals("IN") == true) {
timezone = "Asia/Calcutta";
} else if (country.equals("MN") == true) {
timezone = "Asia/Choibalsan";
} else if (country.equals("CN") == true) {
timezone = "Asia/Chongqing";
} else if (country.equals("LK") == true) {
timezone = "Asia/Colombo";
} else if (country.equals("BD") == true) {
timezone = "Asia/Dhaka";
} else if (country.equals("AE") == true) {
timezone = "Asia/Dubai";
} else if (country.equals("TJ") == true) {
timezone = "Asia/Dushanbe";
} else if (country.equals("HK") == true) {
timezone = "Asia/Hong_Kong";
} else if (country.equals("TR") == true) {
timezone = "Asia/Istanbul";
} else if (country.equals("ID") == true) {
timezone = "Asia/Jakarta";
} else if (country.equals("IL") == true) {
timezone = "Asia/Jerusalem";
} else if (country.equals("AF") == true) {
timezone = "Asia/Kabul";
} else if (country.equals("PK") == true) {
timezone = "Asia/Karachi";
} else if (country.equals("NP") == true) {
timezone = "Asia/Katmandu";
} else if (country.equals("KW") == true) {
timezone = "Asia/Kuwait";
} else if (country.equals("MO") == true) {
timezone = "Asia/Macao";
} else if (country.equals("PH") == true) {
timezone = "Asia/Manila";
} else if (country.equals("OM") == true) {
timezone = "Asia/Muscat";
} else if (country.equals("CY") == true) {
timezone = "Asia/Nicosia";
} else if (country.equals("KP") == true) {
timezone = "Asia/Pyongyang";
} else if (country.equals("QA") == true) {
timezone = "Asia/Qatar";
} else if (country.equals("MM") == true) {
timezone = "Asia/Rangoon";
} else if (country.equals("SA") == true) {
timezone = "Asia/Riyadh";
} else if (country.equals("KR") == true) {
timezone = "Asia/Seoul";
} else if (country.equals("SG") == true) {
timezone = "Asia/Singapore";
} else if (country.equals("TW") == true) {
timezone = "Asia/Taipei";
} else if (country.equals("UZ") == true) {
timezone = "Asia/Tashkent";
} else if (country.equals("GE") == true) {
timezone = "Asia/Tbilisi";
} else if (country.equals("BT") == true) {
timezone = "Asia/Thimphu";
} else if (country.equals("JP") == true) {
timezone = "Asia/Tokyo";
} else if (country.equals("LA") == true) {
timezone = "Asia/Vientiane";
} else if (country.equals("AM") == true) {
timezone = "Asia/Yerevan";
} else if (country.equals("PT") == true) {
timezone = "Atlantic/Azores";
} else if (country.equals("BM") == true) {
timezone = "Atlantic/Bermuda";
} else if (country.equals("CV") == true) {
timezone = "Atlantic/Cape_Verde";
} else if (country.equals("FO") == true) {
timezone = "Atlantic/Faeroe";
} else if (country.equals("IS") == true) {
timezone = "Atlantic/Reykjavik";
} else if (country.equals("GS") == true) {
timezone = "Atlantic/South_Georgia";
} else if (country.equals("SH") == true) {
timezone = "Atlantic/St_Helena";
} else if (country.equals("AU") == true) {
timezone = "Australia/Queensland";
} else if (country.equals("BR") == true) {
timezone = "Brazil/Acre";
} else if (country.equals("CL") == true) {
timezone = "Chile/Continental";
} else if (country.equals("NL") == true) {
timezone = "Europe/Amsterdam";
} else if (country.equals("AD") == true) {
timezone = "Europe/Andorra";
} else if (country.equals("GR") == true) {
timezone = "Europe/Athens";
} else if (country.equals("YU") == true) {
timezone = "Europe/Belgrade";
} else if (country.equals("DE") == true) {
timezone = "Europe/Berlin";
} else if (country.equals("SK") == true) {
timezone = "Europe/Bratislava";
} else if (country.equals("BE") == true) {
timezone = "Europe/Brussels";
} else if (country.equals("RO") == true) {
timezone = "Europe/Bucharest";
} else if (country.equals("HU") == true) {
timezone = "Europe/Budapest";
} else if (country.equals("DK") == true) {
timezone = "Europe/Copenhagen";
} else if (country.equals("IE") == true) {
timezone = "Europe/Dublin";
} else if (country.equals("GI") == true) {
timezone = "Europe/Gibraltar";
} else if (country.equals("FI") == true) {
timezone = "Europe/Helsinki";
} else if (country.equals("UA") == true) {
timezone = "Europe/Kiev";
} else if (country.equals("SI") == true) {
timezone = "Europe/Ljubljana";
} else if (country.equals("GB") == true) {
timezone = "Europe/London";
} else if (country.equals("LU") == true) {
timezone = "Europe/Luxembourg";
} else if (country.equals("ES") == true) {
timezone = "Europe/Madrid";
} else if (country.equals("MT") == true) {
timezone = "Europe/Malta";
} else if (country.equals("BY") == true) {
timezone = "Europe/Minsk";
} else if (country.equals("MC") == true) {
timezone = "Europe/Monaco";
} else if (country.equals("RU") == true) {
timezone = "Europe/Moscow";
} else if (country.equals("NO") == true) {
timezone = "Europe/Oslo";
} else if (country.equals("CZ") == true) {
timezone = "Europe/Prague";
} else if (country.equals("LV") == true) {
timezone = "Europe/Riga";
} else if (country.equals("IT") == true) {
timezone = "Europe/Rome";
} else if (country.equals("SM") == true) {
timezone = "Europe/San_Marino";
} else if (country.equals("BA") == true) {
timezone = "Europe/Sarajevo";
} else if (country.equals("MK") == true) {
timezone = "Europe/Skopje";
} else if (country.equals("BG") == true) {
timezone = "Europe/Sofia";
} else if (country.equals("SE") == true) {
timezone = "Europe/Stockholm";
} else if (country.equals("EE") == true) {
timezone = "Europe/Tallinn";
} else if (country.equals("AL") == true) {
timezone = "Europe/Tirane";
} else if (country.equals("LI") == true) {
timezone = "Europe/Vaduz";
} else if (country.equals("VA") == true) {
timezone = "Europe/Vatican";
} else if (country.equals("AT") == true) {
timezone = "Europe/Vienna";
} else if (country.equals("LT") == true) {
timezone = "Europe/Vilnius";
} else if (country.equals("PL") == true) {
timezone = "Europe/Warsaw";
} else if (country.equals("HR") == true) {
timezone = "Europe/Zagreb";
} else if (country.equals("IR") == true) {
timezone = "Asia/Tehran";
} else if (country.equals("NZ") == true) {
timezone = "Pacific/Auckland";
} else if (country.equals("MG") == true) {
timezone = "Indian/Antananarivo";
} else if (country.equals("CX") == true) {
timezone = "Indian/Christmas";
} else if (country.equals("CC") == true) {
timezone = "Indian/Cocos";
} else if (country.equals("KM") == true) {
timezone = "Indian/Comoro";
} else if (country.equals("MV") == true) {
timezone = "Indian/Maldives";
} else if (country.equals("MU") == true) {
timezone = "Indian/Mauritius";
} else if (country.equals("YT") == true) {
timezone = "Indian/Mayotte";
} else if (country.equals("RE") == true) {
timezone = "Indian/Reunion";
} else if (country.equals("FJ") == true) {
timezone = "Pacific/Fiji";
} else if (country.equals("TV") == true) {
timezone = "Pacific/Funafuti";
} else if (country.equals("GU") == true) {
timezone = "Pacific/Guam";
} else if (country.equals("NR") == true) {
timezone = "Pacific/Nauru";
} else if (country.equals("NU") == true) {
timezone = "Pacific/Niue";
} else if (country.equals("NF") == true) {
timezone = "Pacific/Norfolk";
} else if (country.equals("PW") == true) {
timezone = "Pacific/Palau";
} else if (country.equals("PN") == true) {
timezone = "Pacific/Pitcairn";
} else if (country.equals("CK") == true) {
timezone = "Pacific/Rarotonga";
} else if (country.equals("WS") == true) {
timezone = "Pacific/Samoa";
} else if (country.equals("KI") == true) {
timezone = "Pacific/Tarawa";
} else if (country.equals("TO") == true) {
timezone = "Pacific/Tongatapu";
} else if (country.equals("WF") == true) {
timezone = "Pacific/Wallis";
} else if (country.equals("TZ") == true) {
timezone = "Africa/Dar_es_Salaam";
} else if (country.equals("VN") == true) {
timezone = "Asia/Phnom_Penh";
} else if (country.equals("KH") == true) {
timezone = "Asia/Phnom_Penh";
} else if (country.equals("CM") == true) {
timezone = "Africa/Lagos";
} else if (country.equals("DO") == true) {
timezone = "America/Santo_Domingo";
} else if (country.equals("TL") == true) {
timezone = "Asia/Jakarta";
} else if (country.equals("ET") == true) {
timezone = "Africa/Addis_Ababa";
} else if (country.equals("FX") == true) {
timezone = "Europe/Paris";
} else if (country.equals("GL") == true) {
timezone = "America/Godthab";
} else if (country.equals("HT") == true) {
timezone = "America/Port-au-Prince";
} else if (country.equals("CH") == true) {
timezone = "Europe/Zurich";
} else if (country.equals("") == true) {
timezone = "";
}
return timezone;
}
}
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp.topology;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.tree.DefaultElement;
import de.tud.kom.p2psim.impl.util.logging.SimLogger;
/**
* This class manages the mapping of the 2-digits country code to country and
* region used in the aggregated PingEr reports.
*
* @author Gerald Klunker
* @version 0.1, 09.01.2008
*
*/
public class CountryLookup implements Serializable {
private static final long serialVersionUID = -3994762133062677848L;
private static Logger log = SimLogger.getLogger(CountryLookup.class);
private HashMap<String, String[]> countryLookup = new HashMap<String, String[]>();
private HashMap<String, String> pingErCountryRegions = new HashMap<String, String>();
private String pingErCountryRegionFilename;
// sorted list holding PingEr Data for using in a graphical frontend only
private ArrayList<String> pingErCountry = new ArrayList<String>();
private ArrayList<String> pingErRegion = new ArrayList<String>();
/**
*
* @param 2-digits country code
* @return dedicated GeoIP country name
*/
public String getGeoIpCountryName(String countryCode) {
if (countryLookup.containsKey(countryCode))
return countryLookup.get(countryCode)[0];
else
return null;
}
/**
*
* @param 2-digits country code
* @return dedicated PingEr country name
*/
public String getPingErCountryName(String countryCode) {
if (countryLookup.containsKey(countryCode))
return countryLookup.get(countryCode)[1];
else
return null;
}
/**
*
* @param country
* 2-digits country code or pingEr country name
* @return dedicated PingEr region name
*/
public String getPingErRegionName(String country) {
if (countryLookup.containsKey(country))
return countryLookup.get(country)[2];
else if (pingErCountryRegions.containsKey(country))
return pingErCountryRegions.get(country);
return null;
}
/**
* Adds GeoIP country code and country name.
*
* It will be assign automatically to PingEr Countries, if there are obvious
* consenses.
*
* @param 2-digits country code
* @param dedicated
* country name from GeoIP
*/
public void addCountryFromGeoIP(String countryCode, String country) {
if (!countryLookup.containsKey(countryCode)) {
String[] names = new String[3];
names[0] = country;
if (pingErCountryRegions.containsKey(country)) {
names[1] = country;
names[2] = pingErCountryRegions.get(country);
}
countryLookup.put(countryCode, names);
}
}
/**
* Assign a country code (from GeoIP) to PingER country and/or region name.
* Attention: Nothing happens, if country code was not added before
*
* @param 2-digits country code
* @param dedicated
* country name from PingER
* @param dedicated
* region name from PingER
*/
public void assignCountryCodeToPingErData(String code, String country,
String region) {
if (countryLookup.containsKey(code)) {
String[] names = countryLookup.get(code);
names[1] = country;
names[2] = region;
}
}
/**
* Import all country and region names, that are used by the PingER Project.
* The Country - Region Mapping File can be downloaded form the website of
* the project.
* (http://www-iepm.slac.stanford.edu/pinger/region_country.txt)
*
* GeoIP countries will be assign automatically to PingEr Countries, if
* there are obviouse consensuses.
*
* @param file
*/
public void importPingErCountryRegionFile(File file) {
try {
log.debug("Importing PingER-Country-Region-File: "
+ file.getAbsolutePath());
FileReader inputFilePingER = new FileReader(file);
BufferedReader inputPingER = new BufferedReader(inputFilePingER);
HashMap<String, String> countryToRegion = new HashMap<String, String>();
String line = inputPingER.readLine();
while (line != null) {
String[] parts = line.split(",");
countryToRegion.put(parts[0], parts[1]);
line = inputPingER.readLine();
}
inputPingER.close();
inputFilePingER.close();
Set<String> codes = countryLookup.keySet();
for (String cc : codes) {
String geoIpCountry = getGeoIpCountryName(cc);
if (geoIpCountry != null
&& countryToRegion.containsKey(geoIpCountry)) {
assignCountryCodeToPingErData(cc, geoIpCountry,
countryToRegion.get(geoIpCountry));
}
}
pingErCountryRegions.putAll(countryToRegion);
this.pingErCountryRegionFilename = file.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Import lockup data from an xml-element.
*
* @param element
*/
public void importFromXML(Element element) {
Iterator<Element> iter = element.elementIterator("CountryKey");
while (iter.hasNext()) {
Element variable = iter.next();
String code = variable.attributeValue("code");
String[] names = new String[3];
names[0] = variable.attributeValue("countryGeoIP");
names[1] = variable.attributeValue("countryPingEr");
names[2] = variable.attributeValue("regionPingEr");
countryLookup.put(code, names);
pingErCountryRegions.put(names[1], names[2]);
}
}
/**
* Import lockup data from an xml-file.
*
* @param file
*/
public void importFromXML(File file) {
try {
SAXReader reader = new SAXReader(false);
Document configuration = reader.read(file);
Element root = configuration.getRootElement();
importFromXML(root);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
*
* @return xml-element containing current lookup data
*/
public Element exportToXML() {
DefaultElement country = new DefaultElement("CountryLookup");
Set<String> codeKeys = countryLookup.keySet();
for (String code : codeKeys) {
DefaultElement countryXml = new DefaultElement("CountryKey");
countryXml.addAttribute("code", code);
countryXml.addAttribute("countryGeoIP", getGeoIpCountryName(code));
countryXml
.addAttribute("countryPingEr", getPingErCountryName(code));
countryXml.addAttribute("regionPingEr", getPingErRegionName(code));
country.add(countryXml);
}
return country;
}
/**
*
* @return set of all available country codes added
*/
public Set<String> getCountryCodes() {
return countryLookup.keySet();
}
/**
*
* @return sorted list of all available PingEr country names
*/
public ArrayList<String> getPingErCountrys() {
if (pingErCountry.size() <= 1) {
pingErCountry.clear();
pingErCountry.addAll(pingErCountryRegions.keySet());
pingErCountry.add("");
Collections.sort(pingErCountry);
}
return pingErCountry;
}
/**
*
* @return sorted list of all available PingEr region names
*/
public ArrayList<String> getPingErRegions() {
if (pingErRegion.size() <= 1) {
pingErRegion.clear();
Set<String> region = new HashSet<String>();
region.addAll(pingErCountryRegions.values());
pingErRegion.addAll(region);
pingErRegion.add("");
Collections.sort(pingErRegion);
}
return pingErRegion;
}
/**
* Remove all countries that are not defined in the Set
*
* @param countryCodes
* Set of country codes
*/
public void keepCountries(Set<String> countryCodes) {
countryLookup.keySet().retainAll(countryCodes);
}
/**
*
* @param name
* of country or region
* @return true, if there is a country or region with name exist
*/
public boolean containsPingErCountryOrRegion(String name) {
for (String[] names : countryLookup.values()) {
if (names[1] != null && names[1].equals(name))
return true;
if (names[2] != null && names[2].equals(name))
return true;
}
return false;
}
/**
*
* @return PingER Country - Region Mapping Filename (region_country.txt)
* used for naming
*/
public String getPingErCountryRegionFilename() {
return pingErCountryRegionFilename;
}
}
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp.topology;
import de.tud.kom.p2psim.api.common.Position;
import de.tud.kom.p2psim.impl.topology.PositionVector;
/**
* Implementation of NetPosition for Position and distance measurnment on the
* earth.
*
* @author Gerald Klunker
* @version 0.1, 05.02.2008
*
*/
public class GeographicPosition extends PositionVector {
private double latitude;
private double longitude;
/**
*
* @param longitude
* @param latitude
*/
public GeographicPosition(double longitude, double latitude) {
super(new double[] { longitude, latitude });
this.longitude = longitude;
this.latitude = latitude;
}
/**
* @return geographical distance in km
*/
public double getDistance(Position point) {
double pi = 3.14159265;
double radConverter = pi / 180;
double lat1 = latitude * radConverter;
double lat2 = ((GeographicPosition) point).getLatitude() * radConverter;
double delta_lat = lat2 - lat1;
double delta_lon = (((GeographicPosition) point).getLongitude() - longitude)
* radConverter;
double temp = Math.pow(Math.sin(delta_lat / 2), 2) + Math.cos(lat1)
* Math.cos(lat2) * Math.pow(Math.sin(delta_lon / 2), 2);
return 2 * 6378.2 * Math.atan2(Math.sqrt(temp), Math.sqrt(1 - temp));
}
@Override
public double getAngle(Position target) {
throw new AssertionError(
"getAngle is not defined for this Position-Type");
}
@Override
public int getTransmissionSize() {
return 16; // 2 * double
}
public GeographicPosition clone() {
return new GeographicPosition(longitude, latitude);
}
/**
*
* @return latitude of position
*/
public double getLatitude() {
return latitude;
}
/**
*
* @return longitude of position
*/
public double getLongitude() {
return longitude;
}
}
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp.topology;
/**
* Interface for geolocation services
*
* @author Gerald Klunker
* @version 0.1, 09.01.2008
*
*/
public interface Geolocator {
/**
*
* @param IP
* -address in a readable form like "130.83.47.128"
* @return true, if IP could be located
*/
public boolean search(String ip);
/**
*
* @param 32-bit IP-address
* @return true, if IP could be located
*/
public boolean search(int ip);
/**
*
* @return latitude of last search result, return nan, if ip could not be
* located
*/
public double getLatitude();
/**
*
* @return longitude of last search result, return nan, if ip could not be
* located
*/
public double getLongitude();
/**
*
* @return 2-digit country code of last search result, return null, if ip
* could not be located
*/
public String getCountryCode();
/**
*
* @return country name of last search result , return null, if ip could not
* be located
*/
public String getCountryName();
/**
*
* @return region name of last search result , return null, if ip could not
* be located
*/
public String getRegionName();
/**
*
* @return city name of last search result , return null, if ip could not be
* located
*/
public String getCityName();
}
/*
* Copyright (c) 2005-2011 KOM - Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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 3 of the License, or
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.network.gnp.topology;
import java.io.File;
import java.io.IOException;
import de.tud.kom.p2psim.impl.network.gnp.geoip.Location;
import de.tud.kom.p2psim.impl.network.gnp.geoip.LookupService;
import de.tud.kom.p2psim.impl.network.gnp.geoip.regionName;
/**
* Implementation of the MaxMind GeoIP geolocation service
*
* @author Gerald Klunker
* @version 0.1, 09.01.2008
*
*/
class GeolocatorGeoIP implements Geolocator {
LookupService cl;
Location l1;
/**
* Initialize the GeoIP wrapper class with a binary GeoIP database file.
* There are also free Databases (GPL/LGPL) "GeoLite City"
*
* @param db
*/
public GeolocatorGeoIP(File db) {
super();
try {
cl = new LookupService(db, LookupService.GEOIP_MEMORY_CACHE);
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* (non-Javadoc)
*
* @see
* de.tud.kom.p2psim.impl.network.gnp.topology.Geolocator#getCountryCode()
*/
public String getCountryCode() {
if (l1 == null)
return null;
String cc = l1.countryCode;
if (cc.equals("--") || cc.equals("A1") || cc.equals("A2")
|| cc.equals("01"))
return null;
else
return cc;
}
/*
* (non-Javadoc)
*
* @see
* de.tud.kom.p2psim.impl.network.gnp.topology.Geolocator#getCountryName()
*/
public String getCountryName() {
if (l1 != null)
return l1.countryName;
else
return null;
}
public String getRegionName() {
if (l1 != null) {
String result = regionName.regionNameByCode(l1.countryCode,
l1.region);
if (result != null)
result.replace("ü", "");
return result;
} else
return null;
}
public String getCityName() {
if (l1 != null) {
String result = l1.city;
if (result != null)
result.replace("ü", "");
return result;
} else
return null;
}
/*
* (non-Javadoc)
*
* @see de.tud.kom.p2psim.impl.network.gnp.topology.Geolocator#getLatitude()
*/
public double getLatitude() {
if (l1 != null)
return l1.latitude;
else
return Double.NaN;
}
/*
* (non-Javadoc)
*
* @see
* de.tud.kom.p2psim.impl.network.gnp.topology.Geolocator#getLongitude()
*/
public double getLongitude() {
if (l1 != null)
return l1.longitude;
else
return Double.NaN;
}
/*
* (non-Javadoc)
*
* @see
* de.tud.kom.p2psim.impl.network.gnp.topology.Geolocator#search(java.lang
* .String)
*/
public boolean search(String ip) {
l1 = cl.getLocation(ip);
if (l1 != null)
return true;
else
return false;
}
/*
* (non-Javadoc)
*
* @see
* de.tud.kom.p2psim.impl.network.gnp.topology.Geolocator#search(java.lang
* .Long)
*/
public boolean search(int ip) {
l1 = cl.getLocation(ip);
if (l1 != null)
return true;
else
return false;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment