[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