-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlink.py
93 lines (76 loc) · 3.87 KB
/
link.py
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
from globals import *
from eventHandler import *
from heapq import heappush
class Link:
def __init__(self, name, rate, delay, buffer, connection1, connection2, h):
self.name = name #string representation
self.rate = rate * 1e6 / 8.0 #convert from Mbps to Bps
self.delay = delay/1000.0 #convert from ms to s
self.bufferSize = buffer * 1000.0 #convert from KB to B
self.c1 = connection1 #pointer to one of the hosts
self.c2 = connection2
self.handler = h #h has the global time
self.c1_ltd = 0.0 #at each this time the link will have...
self.c2_ltd = 0.0 #no packets from that connection...
#ltd = last time to delivery
self.c1.setLink(self) #add this link information to...
self.c2.setLink(self) #each object it connects
self.bufferBytes = 0 #amount of bytes in link buffer
self.queue = [] #packet objects in link's queue/buffer
self.bufferList = []
self.bufferTimestamps = []
self.droppedPackets = []
self.droppedPacketsTimestamps = []
self.droppedPackets.append(0)
self.droppedPacketsTimestamps.append(0)
self.cost = delay
# if (self.c1.initialized == 0):
self.c1.sendDSDV();
# if (self.c2.initialized == 0):
self.c2.sendDSDV();
def recvPacket(self,p):
t = self.handler.getTime() #store current time in t
#self.bufferList.append(self.bufferBytes)
if self.bufferBytes + p.size <= self.bufferSize: #if buffer full, reject packet
if p.immSender == self.c1: #wait until link is clear of
ttd = max(t,self.c2_ltd) + self.delay #the other hosts's packets.
elif p.immSender == self.c2:
ttd = max(t,self.c1_ltd) + self.delay
else:
print 'Error, neither sender',self.c1.name,'nor',self.c2.name,'may send to link',self.name
self.queue.append(p)
self.bufferBytes += p.size
self.bufferList.append(self.bufferBytes)
self.bufferTimestamps.append(globals.time)
heappush(eventQueue, (ttd,self,'send') ) #schedule an event where the packet is tranfered
else:
self.droppedPackets.append(self.droppedPackets[-1] +1)
self.droppedPacketsTimestamps.append(globals.time)
print p.immSender.name,'dropped a packet with ack', p.tcpHeader.acknowledgeNumber, 'and seq ', p.tcpHeader.sequenceNumber,' on link',self.name
def sendPacket(self,p):
self.bufferBytes -= p.size
self.bufferList.append(self.bufferBytes)
self.bufferTimestamps.append(globals.time)
if p.immSender == self.c1:
self.c2.recvPacket(p)
elif p.immSender == self.c2:
self.c1.recvPacket(p)
else:
print 'Error, packet does not match either object'
def getAndUpdateCost(self):
self.cost = (self.bufferBytes / self.rate) + self.delay;
return self.cost;
def doNext(self,action):
if action == 'send':
#print 'popping'
p = self.queue.pop(0)
# if not p.isDistancePacket:
#print p.tcpHeader.acknowledgeNumber, ' ', p.tcpHeader.sequenceNumber
# else:
#print p.DSDV_data
if p.immSender == self.c1:
dest = self.c2
else:
dest = self.c1
if (not p.isDistancePacket):
self.sendPacket(p);