-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDVNode.java
More file actions
215 lines (173 loc) · 7.31 KB
/
DVNode.java
File metadata and controls
215 lines (173 loc) · 7.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketTimeoutException;
import java.util.Date;
public class DVNode {
private DVTable table;
private int port;
private DatagramSocket sock;
private int[] neighbors;
private boolean firstShare = false; // has the table been shared yet?
private boolean poison = false;
public DVNode(int port, int[] neighbors, DistanceVector[] initialVectors) {
this.port = port;
this.table = new DVTable(port);
this.neighbors = neighbors;
try {
this.sock = new DatagramSocket(port);
this.sock.setSoTimeout(2000);
} catch (Exception e) {
System.out.println("Error occurred creating socket for Node object.\n" + e);
}
for (DistanceVector v : initialVectors) {
this.table.add(v);
this.table.addLink(v);
}
}
public DVNode(int port, int[] neighbors, DistanceVector[] initialVectors, boolean poison) {
this.port = port;
this.table = new DVTable(port);
this.neighbors = neighbors;
this.poison = poison;
try {
this.sock = new DatagramSocket(port);
this.sock.setSoTimeout(2000);
} catch (Exception e) {
System.out.println("Error occurred creating socket for Node object.\n" + e);
}
for (DistanceVector v : initialVectors) {
this.table.add(v);
this.table.addLink(v);
}
}
private void send(DatagramPacket p) {
Sender sender = new Sender(p);
Thread sendThread = new Thread(sender);
sendThread.start();
}
private void sendSpecial(int destPort, DistanceVector dv) {
DVPacket sDV = new DVPacket(this.port, destPort, dv, true);
DatagramPacket sPack = sDV.packet();
this.send(sPack);
Date date = new Date();
System.out.println("[" + date.getTime() + "] Link value message sent from Node " + port + " to Node " + destPort);
}
// helper method to return highest neighboring port
private int getHighestNeighbor() {
int highest = 0;
for (int neighbor : this.neighbors) {
highest = Math.max(highest, neighbor);
}
return highest;
}
public void linkCostChange(int cost) {
int port = this.getHighestNeighbor();
DistanceVector dv = new DistanceVector(port, cost, port);
this.sendSpecial(this.port, dv);
dv = new DistanceVector(this.port, cost, this.port);
this.sendSpecial(port, dv);
}
// Listen for and handle packet
public void receive() {
byte[] buf = new byte[512];
DatagramPacket rPack = new DatagramPacket(buf, buf.length);
try {
this.sock.receive(rPack);
PacketHandler handler = new PacketHandler(rPack);
Thread handleThread = new Thread(handler);
handleThread.start();
} catch (SocketTimeoutException e) {
;
} catch (IOException e) {
System.out.println("Error receiving packet.\n" + e);
}
}
private class PacketHandler implements Runnable {
DatagramPacket packet;
public PacketHandler(DatagramPacket p) {
this.packet = p;
}
@Override
public void run() {
// parse packet
DVPacket rDVPack = new DVPacket(this.packet);
DistanceVector rDV = rDVPack.getVector();
int sourcePort = rDVPack.getSource();
// Log receipt message
// if this is a triggered link cost change print special status message
// else print normal message
Date date = new Date();
long time = date.getTime();
DistanceVector sDV;
if (rDVPack.getSpecial()) {
System.out.println("[" + date.getTime() + "] Link value message received at Node " + port + " from Node " + sourcePort);
// force table update
sDV = rDV;
table.updateLink(rDV);
System.out.println(table);
broadcastTable();
return;
} else {
// System.out.println("[" + date.getTime() + "] Message received at Node " + port + " from Node " + sourcePort);
// update table normally
sDV = table.updateTable(rDV, sourcePort);
}
// if the initial share has not been made share the whole table, otherwise just sDV
if (!firstShare) {
System.out.println("[" + time + "] Message received at Node " + port + " from Node " + sourcePort);
broadcastTable();
firstShare = true;
} else if (sDV != null) {
System.out.println("[" + time + "] Message received at Node " + port + " from Node " + sourcePort);
// Send to all neighbors
DVPacket sDVPack;
DatagramPacket sPack;
for (int neighbor : neighbors) {
// Check if this message should be altered for poisoned reverse
if (poison && sDV.getNextHop() == neighbor) {
DistanceVector poisonSDV = new DistanceVector(sDV.getPort(), Integer.MAX_VALUE, sDV.getNextHop());
sDVPack = new DVPacket(port, neighbor, poisonSDV);
sPack = sDVPack.packet();
send(sPack);
// Log message send
date = new Date();
System.out.println("[" + date.getTime() + "] Message sent from Node " + port + " to Node " + neighbor + " with distance to " + poisonSDV.getPort() + " as inf");
} else {
sDVPack = new DVPacket(port, neighbor, sDV);
sPack = sDVPack.packet();
// send(sPack);
broadcastTable();/////////////////////////////////////////////////////////////////////////// this is annoying but it makes things work
// Log message send
// date = new Date();
// System.out.println("[" + date.getTime() + "] Message sent from Node " + port + " to Node " + neighbor);
}
}
}
}
}
// Sends table to all neighbors
// Used when this is the last node to be created or for first share
public void broadcastTable() {
for (int neighbor : this.neighbors) {
for (DistanceVector dv : this.table.getNodes()) {
DVPacket sDVPack = new DVPacket(this.port, neighbor, dv);
DatagramPacket sPack = sDVPack.packet();
send(sPack);
}
// Log message send
Date date = new Date();
System.out.println("[" + date.getTime() + "] Broadcast sent from Node " + port + " to Node " + neighbor);
}
this.firstShare = true;
}
public DVTable getTable() {
return this.table;
}
public int[] getNeighbors() {
return this.neighbors;
}
public int getPort() {
return this.port;
}
}