Projet

Général

Profil

Projet agregation v2 » Historique » Version 22

Laurent GUERBY, 01/05/2012 17:06

1 14 Laurent GUERBY
{{>toc}}
2 14 Laurent GUERBY
3 1 Laurent GUERBY
h1. Projet agregation v2
4 1 Laurent GUERBY
5 12 Laurent GUERBY
* [[Projet agregation]]
6 12 Laurent GUERBY
* uTP (uTorrent transport protocol) is a transport protocol which uses one-way delay measurements for its congestion controller. http://www.rasterbar.com/products/libtorrent/utp.html
7 13 Laurent GUERBY
* Low Extra Delay Background Transport (LEDBAT) https://datatracker.ietf.org/doc/draft-ietf-ledbat-congestion/
8 20 Laurent GUERBY
* QoS tail drop vs by IP http://lists.tetalab.org/pipermail/tetaneutral/2011-April/000129.html
9 1 Laurent GUERBY
10 1 Laurent GUERBY
h2. Divers
11 1 Laurent GUERBY
12 1 Laurent GUERBY
* 1 Mbit/s = 83 frames de 1500 byte/sec = 1 frame de 1500 byte toutes les 12 ms
13 1 Laurent GUERBY
* l'augmentation de latence sur la ligne permet la detection de la saturation des buffer
14 1 Laurent GUERBY
* on peut mesurer les variations de latence en regardant les variations de difference de timestamp destination moins source
15 8 Laurent GUERBY
* sur 1 Mbit/s si 20 utilisateurs envoient des paquets de 1500 byte ca fait 4 frame de 1500 byte/sec par utilisateur soit une latence de 250ms (~ 50 kbit/s par utilisateur)
16 2 Laurent GUERBY
17 6 Laurent GUERBY
h2. Resolution de time.time()
18 1 Laurent GUERBY
19 4 Laurent GUERBY
* http://stackoverflow.com/questions/1938048/high-precision-clock-in-python
20 2 Laurent GUERBY
21 4 Laurent GUERBY
<pre>
22 2 Laurent GUERBY
guerby@pc2:~/work/tetaneutral.net/python/pa2$ cat ttime.py 
23 2 Laurent GUERBY
import time
24 2 Laurent GUERBY
25 2 Laurent GUERBY
N=1000
26 2 Laurent GUERBY
l=[]
27 2 Laurent GUERBY
for i in xrange(N):
28 2 Laurent GUERBY
    t1=time.time()
29 2 Laurent GUERBY
    t2=time.time()
30 2 Laurent GUERBY
    dt=t2-t1
31 2 Laurent GUERBY
    l.append(dt)
32 2 Laurent GUERBY
33 2 Laurent GUERBY
l.sort()
34 2 Laurent GUERBY
print l[0],l[-1],l[N/2],l[9*N/10]
35 2 Laurent GUERBY
guerby@pc2:~/work/tetaneutral.net/python/pa2$ python ttime.py 
36 2 Laurent GUERBY
9.53674316406e-07 3.00407409668e-05 1.90734863281e-06 2.14576721191e-06
37 2 Laurent GUERBY
guerby@pc2:~/work/tetaneutral.net/python/pa2$ python ttime.py 
38 2 Laurent GUERBY
9.53674316406e-07 1.19209289551e-05 1.90734863281e-06 2.14576721191e-06
39 2 Laurent GUERBY
guerby@pc2:~/work/tetaneutral.net/python/pa2$ python ttime.py 
40 2 Laurent GUERBY
9.53674316406e-07 0.000508069992065 1.90734863281e-06 2.14576721191e-06
41 2 Laurent GUERBY
</pre>
42 2 Laurent GUERBY
43 2 Laurent GUERBY
=> autour de 2 microsecondes en pratique
44 3 Laurent GUERBY
45 6 Laurent GUERBY
h2. Résolution de select en python
46 3 Laurent GUERBY
47 4 Laurent GUERBY
<pre>
48 3 Laurent GUERBY
guerby@pc2:~/work/tetaneutral.net/python/pa2$ cat tselect.py 
49 3 Laurent GUERBY
import time
50 3 Laurent GUERBY
import select
51 3 Laurent GUERBY
from socket import *
52 3 Laurent GUERBY
from select import select
53 3 Laurent GUERBY
54 3 Laurent GUERBY
55 3 Laurent GUERBY
56 3 Laurent GUERBY
s1 = socket(AF_INET, SOCK_DGRAM)
57 3 Laurent GUERBY
s2 = socket(AF_INET, SOCK_DGRAM)
58 3 Laurent GUERBY
59 3 Laurent GUERBY
N=1000
60 3 Laurent GUERBY
l=[]
61 3 Laurent GUERBY
for i in xrange(N):
62 3 Laurent GUERBY
    t1=time.time()
63 3 Laurent GUERBY
    r = select([s1,s2],[],[],1.0e-9)
64 3 Laurent GUERBY
    t2=time.time()
65 3 Laurent GUERBY
    dt=t2-t1
66 3 Laurent GUERBY
    l.append(dt)
67 3 Laurent GUERBY
68 3 Laurent GUERBY
l.sort()
69 1 Laurent GUERBY
print l[0],l[-1],l[N/2],l[9*N/10]
70 3 Laurent GUERBY
guerby@pc2:~/work/tetaneutral.net/python/pa2$ python tselect.py 
71 3 Laurent GUERBY
9.77516174316e-06 0.000253915786743 1.09672546387e-05 1.12056732178e-05
72 3 Laurent GUERBY
guerby@pc2:~/work/tetaneutral.net/python/pa2$ python tselect.py 
73 3 Laurent GUERBY
9.77516174316e-06 5.41210174561e-05 1.09672546387e-05 1.12056732178e-05
74 4 Laurent GUERBY
</pre>
75 3 Laurent GUERBY
76 1 Laurent GUERBY
=> 12 microsecondes
77 1 Laurent GUERBY
=> 18 microsecondes avec 5 socket vs 2 donc compter + 2 micro/socket
78 6 Laurent GUERBY
79 6 Laurent GUERBY
h2. Generer un payload random
80 6 Laurent GUERBY
81 6 Laurent GUERBY
* http://docs.python.org/library/random.html
82 6 Laurent GUERBY
* http://docs.python.org/library/struct.html
83 6 Laurent GUERBY
84 6 Laurent GUERBY
<pre>
85 6 Laurent GUERBY
import random
86 6 Laurent GUERBY
import struct
87 6 Laurent GUERBY
88 6 Laurent GUERBY
89 6 Laurent GUERBY
N=256*256*256*256-1
90 6 Laurent GUERBY
S=160000
91 6 Laurent GUERBY
random.seed(0)
92 6 Laurent GUERBY
s="".join([struct.pack("I",random.randint(0,N)) for i in xrange(S/4)])
93 6 Laurent GUERBY
print S,len(s)
94 6 Laurent GUERBY
</pre>
95 6 Laurent GUERBY
96 9 Laurent GUERBY
h2. Premiere mesure de controle de latence : debit
97 6 Laurent GUERBY
98 6 Laurent GUERBY
* sur une ligne ADSL capable de 11 Mbit/s soutenu TCP
99 6 Laurent GUERBY
* du serveur (gw) vers le client (stg) on envoie un paquet UDP de 1200 byte toutes les 1200/D secondes avec un numero de sequence, un timestamp serveur en microseconde et un payload random
100 6 Laurent GUERBY
* sur le client on note le timestamp client en microseconde, le numero de sequence et le timestamp server du paquet
101 6 Laurent GUERBY
* une fois le test fini (1000 paquets) on calcule paquet par paquet la difference timestamp client moins timestamp server
102 7 Laurent GUERBY
* on calcul le min de ces differences sur tous les paquets
103 7 Laurent GUERBY
* on graphe chaque difference moins le min des difference = la deviation par rapport a la normale en microseconde
104 6 Laurent GUERBY
105 6 Laurent GUERBY
Avec D = 10 Mbit/s = en dessous de la capacité de la ligne ça donne :
106 6 Laurent GUERBY
107 6 Laurent GUERBY
!10-1200.png!
108 6 Laurent GUERBY
109 6 Laurent GUERBY
Avec D = 15 Mbit/s = au dessus de la capacité de la ligne ça donne :
110 1 Laurent GUERBY
111 1 Laurent GUERBY
!15-1200.png!
112 6 Laurent GUERBY
113 7 Laurent GUERBY
On voit sur les deux graphes des petits pics qui correspondent aux moments ou le modem ADSL pedale un peu pour envoyer.
114 7 Laurent GUERBY
115 1 Laurent GUERBY
On voit donc dans le deuxieme cas le buffer du modem se remplir au fur et a mesure de l'envoi des paquets => c'est parfaitement observable donc maitrisable.
116 6 Laurent GUERBY
117 7 Laurent GUERBY
Le but de l'algorithme de controle est de baisser le debit cible quand on voit la mesure de controle deriver pour la ramener proche d'un niveau normal.
118 7 Laurent GUERBY
119 1 Laurent GUERBY
Note : a cause d'un drift possible d'horloge entre le client et le serveur le niveau normal de la mesure doit etre calculé sur les N derniers paquets / minutes.
120 9 Laurent GUERBY
121 9 Laurent GUERBY
h2. Deuxieme mesure : paquet par seconde
122 9 Laurent GUERBY
123 9 Laurent GUERBY
Cette fois ci a debit fixé a 10 Mbit/s soit en dessous de la capacité de la ligne on fait varier la taille du paquet donc le nombre de paquet par seconde (pps)
124 9 Laurent GUERBY
125 9 Laurent GUERBY
* Taille 200 = 5485 pps 8.7 Mbit/s sur theo a 6250 pps
126 9 Laurent GUERBY
!10-200.png!
127 9 Laurent GUERBY
128 9 Laurent GUERBY
* Taille 350 = 3552 pps 9.9 Mbit/s sur theo a 3570 pps
129 9 Laurent GUERBY
!10-350.png!
130 9 Laurent GUERBY
131 9 Laurent GUERBY
* Taille 400 = 3126 pps 10 Mbit/s sur theo a 3125 pps
132 9 Laurent GUERBY
!10-400.png!
133 9 Laurent GUERBY
134 9 Laurent GUERBY
On voit donc qu'il y a aussi une limite de traitement en pps sur le modem qui peut entrainer du buffer bloat
135 10 Laurent GUERBY
136 11 Laurent GUERBY
A noter que si on rajoute les 20 bytes de header IP et 8 byte de header UDP dans le compteur de débit on sature plutot vers 6500 pps pour 10 Mbit/s, soit 190 byte/packet, payload de 190-20-8=162 byte
137 10 Laurent GUERBY
138 11 Laurent GUERBY
Script de test utilisé : attachment:iperf-20120304.py
139 14 Laurent GUERBY
140 14 Laurent GUERBY
h2. tuntap
141 14 Laurent GUERBY
142 22 Laurent GUERBY
http://en.wikipedia.org/wiki/IEEE_802.3
143 22 Laurent GUERBY
144 14 Laurent GUERBY
http://backreference.org/2010/03/26/tuntap-interface-tutorial/
145 14 Laurent GUERBY
146 14 Laurent GUERBY
* http://www.mjmwired.net/kernel/Documentation/networking/tuntap.txt#102
147 14 Laurent GUERBY
<pre>
148 14 Laurent GUERBY
3.2 Frame format:
149 14 Laurent GUERBY
	  If flag IFF_NO_PI is not set each frame format is: 
150 14 Laurent GUERBY
	     Flags [2 bytes]
151 14 Laurent GUERBY
	     Proto [2 bytes]
152 14 Laurent GUERBY
	     Raw protocol(IP, IPv6, etc) frame.
153 14 Laurent GUERBY
</pre>
154 14 Laurent GUERBY
155 14 Laurent GUERBY
156 14 Laurent GUERBY
* http://en.wikipedia.org/wiki/Ethernet_frame
157 14 Laurent GUERBY
<pre>
158 14 Laurent GUERBY
Preamble		Start of frame delimiter	MAC destination	MAC source	802.1Q tag (optional)	Ethertype (Ethernet II) or length (IEEE 802.3)	Payload	Frame check sequence (32‑bit CRC)	Interframe gap
159 14 Laurent GUERBY
7 octets of 10101010	1 octet of 10101011	6 octets	6 octets	(4 octets)	2 octets	42–1500 octets	4 octets	12 octets
160 14 Laurent GUERBY
</pre>
161 14 Laurent GUERBY
162 16 Laurent GUERBY
* http://en.wikipedia.org/wiki/Ethernet_II_framing#Ethernet_II
163 17 Laurent GUERBY
* http://en.wikipedia.org/wiki/EtherType
164 17 Laurent GUERBY
For example, an EtherType value of 
165 17 Laurent GUERBY
0x0800 signals that the frame contains an IPv4 datagram. 
166 17 Laurent GUERBY
0x0806 indicates an ARP frame, 
167 17 Laurent GUERBY
0x8100 indicates an IEEE 802.1Q frame
168 17 Laurent GUERBY
0x86DD indicates an IPv6 frame. 
169 17 Laurent GUERBY
0x8035 RARP
170 17 Laurent GUERBY
0x8870	Jumbo Frames
171 17 Laurent GUERBY
0x88A2	ATA over Ethernet
172 17 Laurent GUERBY
0x88CC	LLDP
173 17 Laurent GUERBY
0x9100	Q-in-Q
174 17 Laurent GUERBY
175 16 Laurent GUERBY
176 14 Laurent GUERBY
* http://en.wikipedia.org/wiki/IPv4#Packet_structure
177 14 Laurent GUERBY
version premier 4 bits du premier octet = 4
178 14 Laurent GUERBY
ip source octet 13 a 16
179 14 Laurent GUERBY
ip dest octet 17 a 20
180 14 Laurent GUERBY
181 14 Laurent GUERBY
* http://en.wikipedia.org/wiki/IPv6_packet
182 14 Laurent GUERBY
version premier 4 bits du premier octet = 6
183 14 Laurent GUERBY
ip source octet 9 a 24
184 14 Laurent GUERBY
ip dest octet 25 a 40
185 15 Laurent GUERBY
186 18 Laurent GUERBY
<pre>
187 18 Laurent GUERBY
# envoyer un paquet UDP "AAAA" en python IPv4 et IPv6
188 18 Laurent GUERBY
import socket
189 18 Laurent GUERBY
addr=""
190 18 Laurent GUERBY
buf="AAAA"
191 18 Laurent GUERBY
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
192 18 Laurent GUERBY
peer=("10.40.0.1",32767)
193 18 Laurent GUERBY
s.bind((addr, 0))
194 18 Laurent GUERBY
s.sendto(buf,peer)
195 18 Laurent GUERBY
196 18 Laurent GUERBY
s6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
197 18 Laurent GUERBY
s6.bind((addr, 0))
198 18 Laurent GUERBY
peer6=("2a01:6600:8081:cb01::1",32767)
199 18 Laurent GUERBY
s6.sendto(buf,peer6)
200 18 Laurent GUERBY
</pre>
201 18 Laurent GUERBY
202 18 Laurent GUERBY
Resultats sur tuntap :
203 18 Laurent GUERBY
204 18 Laurent GUERBY
<pre>
205 18 Laurent GUERBY
ipv4
206 19 Laurent GUERBY
depuis 10.40.0.2 MAC f2:b3:28:1c:f4:88 
207 19 Laurent GUERBY
vers 10.40.0.1:32767 MAC 26:af:3e:41:71:be
208 18 Laurent GUERBY
envoi UDP payload "AAAA"
209 18 Laurent GUERBY
210 19 Laurent GUERBY
paquet len = 50
211 18 Laurent GUERBY
000 00  000 00  008 08  000 00  038 26  175 AF  062 3E  065 41  113 71  190 BE  242 F2  179 B3  040 28  028 1C  244 F4  136 88 
212 1 Laurent GUERBY
008 08  000 00  069 45  000 00  000 00  032 20  000 00  000 00  064 40  000 00  064 40  017 11  038 26  123 7B  010 0A  040 28 
213 1 Laurent GUERBY
000 00  002 02  010 0A  040 28  000 00  001 01  203 CB  245 F5  127 7F  255 FF  000 00  012 0C  029 1D  012 0C  065 41  065 41 
214 1 Laurent GUERBY
065 41  065 41 
215 19 Laurent GUERBY
216 19 Laurent GUERBY
ipv4 pareil mais depuis 10.50.0.2 vers 10.50.0.1:32767 avec vlan tag 128
217 19 Laurent GUERBY
paquet len = 54
218 19 Laurent GUERBY
000 00  000 00  129 81  000 00  038 26  175 AF  062 3E  065 41  113 71  190 BE  242 F2  179 B3  040 28  028 1C  244 F4  136 88 
219 19 Laurent GUERBY
129 81  000 00  000 00  128 80  008 08  000 00  069 45  000 00  000 00  032 20  000 00  000 00  064 40  000 00  064 40  017 11 
220 19 Laurent GUERBY
038 26  103 67  010 0A  050 32  000 00  002 02  010 0A  050 32  000 00  001 01  178 B2  222 DE  127 7F  255 FF  000 00  012 0C 
221 19 Laurent GUERBY
054 36  015 0F  065 41  065 41  065 41  065 41 
222 19 Laurent GUERBY
223 18 Laurent GUERBY
224 18 Laurent GUERBY
ipv6 
225 18 Laurent GUERBY
depuis 2a01:6600:8081:cb01::2 MAC  f2:b3:28:1c:f4:88 
226 18 Laurent GUERBY
vers [2a01:6600:8081:cb01::1]:32767 MAC 26:af:3e:41:71:be
227 18 Laurent GUERBY
envoi UDP payload "AAAA" 
228 18 Laurent GUERBY
229 18 Laurent GUERBY
from tap paquet len = 70
230 18 Laurent GUERBY
000 00  000 00  134 86  221 DD  038 26  175 AF  062 3E  065 41  113 71  190 BE  242 F2  179 B3  040 28  028 1C  244 F4  136 88 
231 18 Laurent GUERBY
134 86  221 DD  096 60  000 00  000 00  000 00  000 00  012 0C  017 11  255 FF  042 2A  001 01  102 66  000 00  128 80  129 81 
232 18 Laurent GUERBY
203 CB  001 01  000 00  000 00  000 00  000 00  000 00  000 00  000 00  002 02  042 2A  001 01  102 66  000 00  128 80  129 81 
233 18 Laurent GUERBY
203 CB  001 01  000 00  000 00  000 00  000 00  000 00  000 00  000 00  001 01  193 C1  022 16  127 7F  255 FF  000 00  012 0C 
234 18 Laurent GUERBY
133 85  049 31  065 41  065 41  065 41  065 41 
235 18 Laurent GUERBY
</pre>
236 18 Laurent GUERBY
237 15 Laurent GUERBY
h2. Compression
238 15 Laurent GUERBY
239 15 Laurent GUERBY
http://www.oberhumer.com/opensource/lzo/
240 15 Laurent GUERBY
<pre>
241 15 Laurent GUERBY
Here are some original timings done on an Intel Pentium 133 back in 1997. Multiply by a constant factor for modern machines.
242 15 Laurent GUERBY
243 15 Laurent GUERBY
memcpy(): ~60 MB/sec
244 15 Laurent GUERBY
LZO1X decompression in C: ~16 MB/sec
245 15 Laurent GUERBY
LZO1X decompression in optimized assembler: ~20 MB/sec
246 15 Laurent GUERBY
LZO1X-1 compression: ~5 MB/sec
247 15 Laurent GUERBY
More detailed results can be found in the documentation.
248 15 Laurent GUERBY
</pre>
249 15 Laurent GUERBY
250 15 Laurent GUERBY
https://github.com/jd-boyd/python-lzo
251 15 Laurent GUERBY
252 15 Laurent GUERBY
h2. Allocation équitable de bande passante
253 15 Laurent GUERBY
254 15 Laurent GUERBY
Les outils comme tc http://en.wikipedia.org/wiki/Tc_(Linux) permettent d'allouer equitablement de la bande passante par IP source cf leur usage actuel [[Buffer_Bloat#QoS]].
255 15 Laurent GUERBY
256 15 Laurent GUERBY
Ces outils travaillent au niveau paquet par paquet donc en présence de plusieurs paquets de 1500 bytes provenant de plusieurs utilisateurs la latence pour les petits paquets d'autre utilisateurs va être fortement impactée, par exemple si 15 utilisateurs
257 15 Laurent GUERBY
258 15 Laurent GUERBY
Une solution alternative est de travailler en volume et non plus par paquet : chaque paquet envoyé sur le tunnel va contenir des fragments de paquet de tous les utisateurs au prorata equitable.
259 15 Laurent GUERBY
260 15 Laurent GUERBY
Exemple concret : une ligne ADSL avec 15 utilisateurs, pour arrondir supporte un paquet a 1500 byte a 1 Mbit/s soit un paquet 1500 toute les 12 ms. 14 envoient du TCP a 1500 byte et le dernier fait des ping de 100 byte.
261 15 Laurent GUERBY
* solution par paquet classique : la latence du ping dans le pire des cas est 14*12ms= 168 ms et elle va etre fortement variable suivant le nombre de paquet de 1500 des autres utilisateurs.
262 15 Laurent GUERBY
* solution en volume : la latence du ping est de 12ms constante. Si le paquet ping est entre 100 et 200 alors la latence sera simplement de 2*12ms = 24ms constante aussi.
263 15 Laurent GUERBY
264 21 Laurent GUERBY
h2. Test de re-bind
265 21 Laurent GUERBY
266 21 Laurent GUERBY
En cas de changement d'IP sur la ligne ADSL le NAT des modem / routeurs peut couper une connection UDP établie (visible sur openvpn) la solution est de forcer un changement de port source si la connection apparait comme non fonctionnelle
267 21 Laurent GUERBY
268 21 Laurent GUERBY
<pre>
269 21 Laurent GUERBY
import sys
270 21 Laurent GUERBY
import socket
271 21 Laurent GUERBY
272 21 Laurent GUERBY
mode=sys.argv[1]
273 21 Laurent GUERBY
RBUFL=2000
274 21 Laurent GUERBY
remote_port=6600
275 21 Laurent GUERBY
276 21 Laurent GUERBY
if mode=="client":
277 21 Laurent GUERBY
    remote_addr=sys.argv[2]
278 21 Laurent GUERBY
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
279 21 Laurent GUERBY
    s.bind(("", 0))
280 21 Laurent GUERBY
    peer=(remote_addr,remote_port)
281 21 Laurent GUERBY
    s.sendto("TOTO1",peer)
282 21 Laurent GUERBY
    s.close()
283 21 Laurent GUERBY
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
284 21 Laurent GUERBY
    s.bind(("", 0))
285 21 Laurent GUERBY
    s.sendto("TOTO2",peer)
286 21 Laurent GUERBY
else:
287 21 Laurent GUERBY
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
288 21 Laurent GUERBY
    s.bind(("", remote_port))
289 21 Laurent GUERBY
    p,peer=s.recvfrom(RBUFL)
290 21 Laurent GUERBY
    print p,peer
291 21 Laurent GUERBY
    p,peer=s.recvfrom(RBUFL)
292 21 Laurent GUERBY
    print p,peer
293 21 Laurent GUERBY
</pre>
294 21 Laurent GUERBY
295 21 Laurent GUERBY
Test :
296 21 Laurent GUERBY
297 21 Laurent GUERBY
<pre>
298 21 Laurent GUERBY
client$ python tbind.py client testlg1 6600
299 21 Laurent GUERBY
# while on server:
300 21 Laurent GUERBY
server$ python tbind.py server
301 21 Laurent GUERBY
TOTO1 ('192.168.1.18', 47975)
302 21 Laurent GUERBY
TOTO2 ('192.168.1.18', 60607)
303 21 Laurent GUERBY
</pre>
304 21 Laurent GUERBY
=> changement de port effectif
305 15 Laurent GUERBY
306 15 Laurent GUERBY
h2. Attachements