medium.py 5.86 KB
Newer Older
thomas alfroy's avatar
thomas alfroy committed
1
2
3
4
5
# tagger juste le premier
# Fenetre source -> dest
# 2 modes drop / ecn / mode hybride


thomas alfroy's avatar
thomas alfroy committed
6
7
8
import socket
import select
import sys
thomas alfroy's avatar
thomas alfroy committed
9
import random
10
11
import getopt
import time
thomas alfroy's avatar
thomas alfroy committed
12
13

ECN_ACTIVE = 1
thomas alfroy's avatar
thomas alfroy committed
14
ECN_DISABLED = 0
thomas alfroy's avatar
thomas alfroy committed
15

16
17
18
19
20
TYPE_SYN = 1
TYPE_FIN = 2
TYPE_ACK = 16
TYPE_RST = 4

thomas alfroy's avatar
thomas alfroy committed
21
MAX_PACKETS = 0
thomas alfroy's avatar
thomas alfroy committed
22
23
24
25
26
27
28
29

def help():
    print("Usage : python3 medium.py [option]\n\n" \
        "This program is used to simulate loss of congestion (with the ECN mode). In normal mode, generates 30 percents loss when receiving more than 100 packets within a second. In ECN mode, set the ECN bit for the first packet of a time interval of 1 second when receiving more than 100 packets within a second.\n\n" \
        "\t-v,--verbose\t\tUsed for debug, display the pseudo TCP header for each received packet\n" \
        "\t-s,--second\t\tDisplay the number of received message each second\n" \
        "\t-e,--ecn\t\tActivate the ECN mode\n" \
        "\t-l,--limit [val]\tSet the packet limit rate before loss to the choosen value\n")
thomas alfroy's avatar
thomas alfroy committed
30
31

def parse_type(t):
thomas alfroy's avatar
thomas alfroy committed
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    ok_ = False
    print("Type :", end="")
    if t & TYPE_FIN:
        print(" FIN ", end="")
        ok_ = True
    if t & TYPE_ACK:
        print(" ACK ", end="")
        ok_ = True
    if t & TYPE_SYN:
        print(" SYN ", end="")
        ok_ = True
    if t & TYPE_RST:
        print(" RST ", end="")
        ok_ = True
    if not ok_:
        print("Unrecognized Type : Please check your packet format", end="")
    print("")
thomas alfroy's avatar
thomas alfroy committed
49
50


51
52


thomas alfroy's avatar
thomas alfroy committed
53
def parse_ecn(e):
thomas alfroy's avatar
thomas alfroy committed
54
    if e >= ECN_ACTIVE:
thomas alfroy's avatar
thomas alfroy committed
55
56
57
58
59
60
61
62
63
64
65
66
        print("ECN bit is enabled")
    elif e == ECN_DISABLED:
        print("ECN bit is disable")
    else:
        print("There is an issue with your ECN bit : please check your packet format")


##############################################################
## Packet format : Type, Seq, Ecn, Payload ###################
##############################################################

def parse_new_messages(msg):
67
    print("\nNew source message received")
thomas alfroy's avatar
thomas alfroy committed
68
69
70
    flux = msg[0]
    print("Flux ID : {}".format(flux))
    t = msg[1]
thomas alfroy's avatar
thomas alfroy committed
71
    parse_type(t)
72
    nchars = 1
thomas alfroy's avatar
thomas alfroy committed
73
#   string to int or long. Type depends on nchars
thomas alfroy's avatar
thomas alfroy committed
74
    seq = sum((msg[byte + 2])<<8*(nchars-byte-1) for byte in range(nchars))
thomas alfroy's avatar
thomas alfroy committed
75
    print("SeqNum : {}".format(seq))
76
77
    nchars = 1
#   string to int or long. Type depends on nchars
thomas alfroy's avatar
thomas alfroy committed
78
    ack_seq = sum((msg[byte + 4])<<8*(nchars-byte-1) for byte in range(nchars))
79
    print("Ack seq Num : {}".format(ack_seq))
thomas alfroy's avatar
thomas alfroy committed
80
    #seq = ord(msg[1:4])
thomas alfroy's avatar
thomas alfroy committed
81
    ecn = msg[6]
thomas alfroy's avatar
thomas alfroy committed
82
    parse_ecn(ecn)
thomas alfroy's avatar
thomas alfroy committed
83
84
    win_size = msg[7]
    print("Size of congestion Window : {}".format(win_size))
85
86
87
88


def parse_new_messages_server(msg):
    print("\nNew server message received")
thomas alfroy's avatar
thomas alfroy committed
89
90
91
    flux = msg[0]
    print("Flux ID : {}".format(flux))
    t = msg[1]
92
93
94
    parse_type(t)
    nchars = 1
#   string to int or long. Type depends on nchars
thomas alfroy's avatar
thomas alfroy committed
95
    seq = sum((msg[byte + 2])<<8*(nchars-byte-1) for byte in range(nchars))
96
97
98
    print("SeqNum : {}".format(seq))
    nchars = 1
#   string to int or long. Type depends on nchars
thomas alfroy's avatar
thomas alfroy committed
99
    ack_seq = sum((msg[byte + 4])<<8*(nchars-byte-1) for byte in range(nchars))
100
101
    print("Ack seq Num : {}".format(ack_seq))
    #seq = ord(msg[1:4])
thomas alfroy's avatar
thomas alfroy committed
102
    ecn = msg[6]
103
    parse_ecn(ecn)
thomas alfroy's avatar
thomas alfroy committed
104
    win_size = msg[7]
105
106
107
108
109
    print("Size of new Window : {}".format(win_size))

debug = False
verb = False
second = False
thomas alfroy's avatar
thomas alfroy committed
110
111
112
ecn = False
hybride = False

113

thomas alfroy's avatar
thomas alfroy committed
114
115

options, remainder = getopt.getopt(sys.argv[1:], 'dvsehl:', ['debug', 'verbose', 'second', 'ecn', 'help', 'limit=',])
116
117
118
119
120
121
122
123

for opt, arg in options:
    if opt in ('-d', '--debug'):
        debug = True
    if opt in ('-v', '--verbose'):
        verb = True
    if opt in ('-s', '--second'):
        second = True
thomas alfroy's avatar
thomas alfroy committed
124
125
126
127
128
129
130
131
132
133
    if opt in ('-e','--ecn'):
        ecn = True
    if opt in ('-l','--limit'):
        MAX_PACKETS = arg
    if opt in ('-h', '--help'):
        help()
        exit(0)

    
random.seed(time.time())
thomas alfroy's avatar
thomas alfroy committed
134
135
136
137
138
139
140


sock_sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_recv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

dest_sender = "127.0.0.1"
dest_recv = "127.0.0.1"
141
142
port_sender = 3333
port_recv = 6666
thomas alfroy's avatar
thomas alfroy committed
143

144
145
sock_sender.bind(("127.0.0.1", 4444))
sock_recv.bind(("127.0.0.1", 5555))
thomas alfroy's avatar
thomas alfroy committed
146
147
148
149

input = [ sock_sender, sock_recv , sys.stdin ]

con = True
150
151
act_time = time.time()
nb_packets = 0
thomas alfroy's avatar
thomas alfroy committed
152
tagged = False
thomas alfroy's avatar
thomas alfroy committed
153
154

while con:
thomas alfroy's avatar
thomas alfroy committed
155
156
    if act_time + 1 <= time.time():
        if second :
157
158
159
            print("{} packets received last second".format(nb_packets))
            nb_packets = 0
            act_time = time.time()
thomas alfroy's avatar
thomas alfroy committed
160
        tagged = False
161
162
    
    i_ready, o_ready, e_ready = select.select(input, [], [], 1.0)
thomas alfroy's avatar
thomas alfroy committed
163
164
165

    for s in i_ready:
        if s == sock_sender:
166
167
168
169
            data, addr = sock_sender.recvfrom(64)

            nb_packets += 1
            if nb_packets > MAX_PACKETS:
thomas alfroy's avatar
thomas alfroy committed
170
171
172
173
174
175
176
177
178
179
                if ecn :
                    if not tagged:
                        data_tmp = bytearray(data)
                        data_tmp[5] = ECN_ACTIVE
                        data = bytes(data_tmp)
                        tagged = True
                    sock_sender.sendto(data, (dest_recv, port_recv))
                else:
                    if random.random() <= 0.7:
                        sock_sender.sendto(data, (dest_recv, port_recv))
thomas alfroy's avatar
thomas alfroy committed
180
181
            else:
                sock_sender.sendto(data, (dest_recv, port_recv))
thomas alfroy's avatar
thomas alfroy committed
182
183

            
184
185
186
187
188
189
            
            if debug :
                print("message {} received from sender".format(data))
            if verb :
                parse_new_messages(data)
            
thomas alfroy's avatar
thomas alfroy committed
190
        elif s == sock_recv:
191
            data, addr = sock_recv.recvfrom(64)
thomas alfroy's avatar
thomas alfroy committed
192
            sock_recv.sendto(data, (dest_sender, port_sender))
193
194
195
196
197
            if debug :
                print("message {} received from receiver".format(data))
                #parse_new_messages(data)
            if verb :
                parse_new_messages_server(data)
thomas alfroy's avatar
thomas alfroy committed
198
199
200
201
202
203
204
205
206
207
        elif s == sys.stdin:
            data = sys.stdin.readline()
            data = data.strip()
            if data == "quit":
                con = False
        else:
            print("WTF ?!?")

sock_recv.close()
sock_sender.close()