[projet-agregation] Prototype multi.py v1
Laurent GUERBY
laurent at guerby.net
Dim 13 Nov 14:54:52 CET 2011
Bonjour,
Comme j'avais besoin de tester rapidement j'ai ecrit un prototype
de 60 lignes en python de tunnel UDP qui dispatche sur plusieurs
connections UDP vers l'IP du serveur remote. La partie creation de
l'interface tunnel n'est pas gérée par le python mais par openvpn.
Le code ne teste rien niveau conditions d'erreur mais devrait survivre a
un changement d'IP client grace au keepalive du client openvpn et au
serveur qui garde trace des plus recentes IP client :
le "del peer_d[peer_l.pop(0)]" vire la plus vieille IP.
L'algorithme de dispatch du prototype est un simple round robin par
paquet. Le prototype sur un LAN arrive facilement a plus de 100 Mbit/s
iperf. Sur une ligne ADSL seule on se retrouve tres proche du debit
maximum.
Je commite dans git des que ma clé sera sur gitolite
(/root/.ssh/authorized_keys ligne guerby).
En esperant que ça clarifie un peu mon courriel precedant.
Sincerement
Laurent
server# openvpn --dev tun --ifconfig 10.1.0.1 10.1.0.2 --auth none --cipher none --port 65404 --local 127.0.0.1
server# python multi.py -s
client# python multi.py -c
client# openvpn --dev tun --ifconfig 10.1.0.2 10.1.0.1 --auth none --cipher none --remote localhost 65404 --keepalive 10 30
$ cat multi.py
#!/usr/bin/env python
# Laurent GUERBY 2011
# Licence: GPL v3 or later
import sys
from socket import *
from select import select
is_server = sys.argv[1]=="-s"
tunnel_port=65404
remote_port=65405
remote_ip="a.b.c.d"
multi_n=4
multi_ip_l=multi_n*["192.168.1.z"]
BUF=20000
rr=0
if is_server:
tunnel_s=socket(AF_INET, SOCK_DGRAM)
tunnel_s.bind((remote_ip,remote_port))
tunnel_peer=("127.0.0.1",tunnel_port)
peer_d={}
peer_l=[]
while True:
data,peer=tunnel_s.recvfrom(BUF)
if peer[0]=="127.0.0.1":
if len(peer_l)>0:
tunnel_s.sendto(data,peer_l[rr])
rr=(rr+1)%len(peer_l)
else:
if not peer_d.has_key(peer):
if len(peer_l)>multi_n:
del peer_d[peer_l.pop(0)]
peer_d[peer]=None
peer_l.append(peer)
tunnel_s.sendto(data,tunnel_peer)
else:
tunnel_s=socket(AF_INET, SOCK_DGRAM)
tunnel_s.bind(("127.0.0.1",tunnel_port))
tunnel_peer=None
peer_l=[]
for i in xrange(multi_n):
peer_s=socket(AF_INET, SOCK_DGRAM)
peer_s.bind((multi_ip_l[i],0))
peer_s.connect((remote_ip,remote_port))
peer_l.append(peer_s)
s_l=[tunnel_s]+peer_l
while True:
read_s,write_s,err_s=select(s_l,[],[])
for s in read_s:
data,peer=s.recvfrom(BUF)
if s==tunnel_s:
tunnel_peer=peer
peer_l[rr].send(data)
rr=(rr+1)%len(peer_l)
else:
if tunnel_peer!=None:
tunnel_s.sendto(data,tunnel_peer)
More information about the projet-agregation
mailing list