GnpLatencyModel.java 5.87 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * 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/>.
 *
 */


22
23
package de.tud.kom.p2psim.impl.network.gnp;

24
25
26
27
28
29
30
31
32
33
34
35
import java.util.Random;

import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.api.network.NetLatencyModel;
import de.tud.kom.p2psim.api.network.NetLayer;
import de.tud.kom.p2psim.api.network.NetProtocol;
import de.tud.kom.p2psim.api.transport.TransProtocol;
import de.tud.kom.p2psim.impl.network.IPv4Message;
import de.tud.kom.p2psim.impl.network.gnp.topology.CountryLookup;
import de.tud.kom.p2psim.impl.network.gnp.topology.PingErLookup;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.Time;
36
37
38
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import umontreal.iro.lecuyer.probdist.LognormalDist;

39
public class GnpLatencyModel implements NetLatencyModel {
40

41
42
	private Random rnd = Randoms.getRandom(GnpLatencyModel.class);

43
44
	public static final int MSS = PhyType.ETHERNET.getDefaultMTU()
			- NetProtocol.IPv4.getHeaderSize()
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
			- TransProtocol.TCP.getHeaderSize();

	private static PingErLookup pingErLookup;

	private static CountryLookup countryLookup;

	private boolean usePingErInsteadOfGnp = false;

	private boolean useAnalyticalFunctionInsteadOfGnp = false;

	private boolean usePingErJitter = false;

	private boolean usePingErPacketLoss = false;

	public void init(PingErLookup pingErLookup, CountryLookup countryLookup) {
		GnpLatencyModel.pingErLookup = pingErLookup;
		GnpLatencyModel.countryLookup = countryLookup;
	}

	private double getMinimumRTT(GnpNetLayer sender, GnpNetLayer receiver) {
		String ccSender = sender.getCountryCode();
		String ccReceiver = receiver.getCountryCode();
		double minRtt = 0.0;
		if (usePingErInsteadOfGnp) {
			minRtt = pingErLookup.getMinimumRtt(ccSender, ccReceiver, countryLookup);
		} else if (useAnalyticalFunctionInsteadOfGnp) {
			double distance = GeoLocationOracle.getGeographicalDistance(sender.getNetID(), receiver.getNetID());
			minRtt = 62 + (0.02 * distance);
		} else {
			Location senderPos = sender.getNetPosition();
			Location receiverPos = receiver.getNetPosition();
			minRtt = senderPos.distanceTo(receiverPos);
		}
		return minRtt;
	}

	private double getPacketLossProbability(GnpNetLayer sender, GnpNetLayer receiver) {
		String ccSender = sender.getCountryCode();
		String ccReceiver = receiver.getCountryCode();
		double twoWayLossRate = 0.0;
		double oneWayLossRate = 0.0;
		if (usePingErPacketLoss) {
			twoWayLossRate = pingErLookup.getPacktLossRate(ccSender, ccReceiver, countryLookup);
			twoWayLossRate /= 100;
			oneWayLossRate = 1 - Math.sqrt(1 - twoWayLossRate);
		}
		return oneWayLossRate;

	}

	private double getNextJitter(GnpNetLayer sender, GnpNetLayer receiver) {
		String ccSender = sender.getCountryCode();
		String ccReceiver = receiver.getCountryCode();
		double randomJitter = 0.0;
		if (usePingErJitter) {
			LognormalDist distri = pingErLookup.getJitterDistribution(ccSender, ccReceiver, countryLookup);
			randomJitter = distri.inverseF(rnd.nextDouble());
		}
		return randomJitter;

	}

	private double getAverageJitter(GnpNetLayer sender, GnpNetLayer receiver) {
		String ccSender = sender.getCountryCode();
		String ccReceiver = receiver.getCountryCode();
		double jitter = 0.0;
		if (usePingErJitter) {
			jitter = pingErLookup.getAverageRtt(ccSender, ccReceiver, countryLookup) - pingErLookup.getMinimumRtt(ccSender, ccReceiver, countryLookup);
		}
		return jitter;
	}

	public double getUDPerrorProbability(GnpNetLayer sender, GnpNetLayer receiver, IPv4Message msg) {
		if (msg.getPayload().getSize() > 65507)
			throw new IllegalArgumentException("Message-Size ist too big for a UDP-Datagramm (max 65507 byte)");
		double lp = getPacketLossProbability(sender, receiver);
		double errorProb = 1 - Math.pow(1 - lp, msg.getNoOfFragments());
		return errorProb;
	}

	public double getTcpThroughput(GnpNetLayer sender, GnpNetLayer receiver) {
		double minRtt = getMinimumRTT(sender, receiver);
		double averageJitter = getAverageJitter(sender, receiver);
		double packetLossRate = getPacketLossProbability(sender, receiver);
		double mathisBW = ((MSS * 1000) / (minRtt + averageJitter)) * Math.sqrt(1.5 / packetLossRate);
		return mathisBW;
	}

	public long getTransmissionDelay(double bytes, double bandwidth) {
		double messageTime = bytes / bandwidth;
		long delay = Math.round((messageTime * Time.SECOND));
		return delay;
	}

	public long getPropagationDelay(GnpNetLayer sender, GnpNetLayer receiver) {
		double minRtt = getMinimumRTT(sender, receiver);
		double randomJitter = getNextJitter(sender, receiver);
		double receiveTime = (minRtt + randomJitter) / 2.0;
		long latency = Math.round(receiveTime * Time.MILLISECOND);
		return latency;
	}

	public long getLatency(NetLayer sender, NetLayer receiver) {
		return getPropagationDelay((GnpNetLayer) sender, (GnpNetLayer) receiver);
	}

	public void setUsePingErRttData(boolean pingErRtt) {
		usePingErInsteadOfGnp = pingErRtt;
	}

	public void setUseAnalyticalRtt(boolean analyticalRtt) {
		useAnalyticalFunctionInsteadOfGnp = analyticalRtt;
	}

	public void setUsePingErJitter(boolean pingErRtt) {
		usePingErJitter = pingErRtt;
	}

	public void setUsePingErPacketLoss(boolean pingErPacketLoss) {
		usePingErPacketLoss = pingErPacketLoss;
	}

167
}