You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

277 lines
6.7 KiB

#!/bin/bash
set -u
PUBLIC_PREFIX=20 # 20, 21, 22...
MCAST_PREFIX_BASE="235"
MCAST_COMMON_ADDR="$MCAST_PREFIX_BASE.0.0.1"
MCAST_BASE_PORT=4000
set +u
[ -z "$USER" ] && export USER=$(id -un)
set -u
error() {
echo ERROR : "allocator : $@ !"
exit 1
}
# Numéro de l'utilisteur sur la machine
# Utilisé par la redirection de port
computeLocalUser() {
set +u
[ -z "$USER" ] && export USER=$(id -un)
set -u
local u=$USER
#[ $# = 2 ] && u=$2
ps --no-headers --sort=start_time -eo user:14,lstart | gawk -v USER=$u -e '
BEGIN {
n=0
}
/[^[:space:]]+ .*/ {
user=$1
#print $0 USER "===" user
if(user == USER) {
print n%32
exit 0
}
if ( ! ( user in users ) ) {
#print "SET USER : user :" $0
users[user]=n
n=n+1
}
}
'
}
# Calcule les paramètres d'un hôte
# $1 : hôte
computeDb() {
local split host network user domain
[ -d $VDN_PATH/allocators/db-$VDN_RESOURCES_ALLOCATOR ] && dir=$VDN_PATH/allocators/db-$VDN_RESOURCES_ALLOCATOR
[ -d /etc/vdn/allocators/db-$VDN_RESOURCES_ALLOCATOR ] && dir=/etc/vdn/allocators/db-$VDN_RESOURCES_ALLOCATOR
ALLOCATOR_DIR=$dir
[ -z "$dir" ] && error "Allocators dir not found!"
split="${1//./ }"
set - $split
set +u
host=$1
network=$2
user=$3
domain=$4
[ -z "$domain" ] && domain=vdn
[ $domain != vdn ] && error "computeDb : bad domain $domain"
set +u
[ -z "$user" -a -n "$GUEST_OWNER" ] && user=$GUEST_OWNER
set -u
[ -z "$user" ] && user=$USER
[ -z "$network" ] && {
[ -z "$NETWORK_DIR" ] &&
error "computeDb : no network and NETWORK_DIR is empty !"
network=$(basename $NETWORK_DIR)
}
[ -z "$host" ] && error "computeDb : host is empty !"
#echo "computeDb : $VDN_NETWORKS_BASE_DIR/$network/$host.conf" >&2
##[ ! -e $VDN_NETWORKS_BASE_DIR/$network/$host.conf ] && \
## error "computeDb : host $host not found in network $network!"
grep -q $network:$host $dir/hosts || {
error "host $host not found in network $network"
}
###
set +u
[ -z "$DB_CURRENT_USER" ] && DB_CURRENT_USER=""
set -u
[ "$user" != "$DB_CURRENT_USER" ] && {
! cat $dir/users | grep -q "^$user$" &&
error "computeDb : user $user not found"
export DB_CURRENT_USER_NUM=$(cat $dir/users | grep -n "^$user$" | cut -d ':' -f 1)
export DB_CURRENT_USER=$user
export DB_CURRENT_LOCAL_USER_NUM=$(computeLocalUser $user $host)
}
[ -z "$DB_CURRENT_LOCAL_USER_NUM" ] && $(computeLocalUser $user $host)
set +u
[ -z "$DB_CURRENT_NETWORK" ] && DB_CURRENT_NETWORK=""
set -u
[ "$network" != "$DB_CURRENT_NETWORK" ] && {
#local netList=$(cd $VDN_NETWORKS_BASE_DIR; find . -maxdepth 1 -type d)
local netList=$(cat $dir/networks)
export DB_CURRENT_NETWORKS_LIST="$netList"
DB_CURRENT_NETWORK_NUM=$(echo "$DB_CURRENT_NETWORKS_LIST" | grep -n "^$network$" | cut -d ':' -f 1)
[ -z "$DB_CURRENT_NETWORK_NUM" ] &&
error "computeDb : DB_CURRENT_NETWORK_NUM empty (not in $VDN_NETWORKS_BASE_DIR ?)"
#local hostsList=$(cd $VDN_NETWORKS_BASE_DIR/$network; find . -maxdepth 1 -type f -name '*.conf' )
local hostsList=$(cat $dir/hosts | grep "^$network:" | cut -d ':' -f 2 )
export DB_CURRENT_HOSTS_LIST="$hostsList"
DB_CURRENT_HOST_NUM=$(echo "$DB_CURRENT_HOSTS_LIST" | grep -n "^$host$" | cut -d ':' -f 1)
[ -z "$DB_CURRENT_HOST_NUM" ] && {
error "computeDb : DB_CURRENT_HOST_NUM empty (not in $VDN_NETWORKS_BASE_DIR/$network/*.conf ?)"
}
DB_CURRENT_NETWORK=$network
DB_CURRENT_HOST=$host
}
cat << EOF > /dev/null
echo "
host:$host
network:$network
user:$user
hostNum:$DB_CURRENT_HOST_NUM
networkNum:$DB_CURRENT_NETWORK_NUM
userNum=$DB_CURRENT_USER_NUM
"
EOF
}
# $1 : host
# $2 : proto (tcp/udp)
# $3 : port à redirigé
# en sortie : affichage d'un port libre
computeRedir() {
local base dst proto=$2
computeDb $1
base=$(( 5000+$DB_CURRENT_LOCAL_USER_NUM*1024 ))
dst=$(( $base + $DB_CURRENT_HOST_NUM*32+($3%16) ))
dst=$(findUnusedPort $proto $dst)
echo $dst
}
# Affiche l'IP PUBLIC de la machine
# L'hôte (ex : tiny.demo.user.vdn)
computePublicIp() {
computeDb $1
grep -q "$DB_CURRENT_NETWORK:$DB_CURRENT_HOST" $ALLOCATOR_DIR/hosts.global || return
#echo $NETWORKS | egrep -q 'NET_0|NET_G' || return
#echo "keys: $DB_CURRENT_USER $DB_CURRENT_NETWORK $DB_CURRENT_HOST"
#echo "keys: userNum networkNum hostNum : $DB_CURRENT_USER_NUM $DB_CURRENT_NETWORK_NUM $DB_CURRENT_HOST_NUM"
# 20.X.Y.Z => 24 bits dispo
# Une adresse IP_PUBLIC par machine
# 13 bits de poids fort pour le numero de l'utilisateur (max 8192)
# 6 bits pour le numéro réseau (max 64 réseaux)
# 5 bits pour le numéro d'hôte (max 32 hôte par réseau)
#
# IP = -------- -------- ---------
# ^ ^^ ^^ ^
# +------------++------++---+
# user net host
local ip=$(( $DB_CURRENT_USER_NUM * 2**11 + $DB_CURRENT_NETWORK_NUM * 2**5 + $DB_CURRENT_HOST_NUM))
ip1=$(( $ip/2**24 ))
ip2=$(( ($ip-$ip1*2**24) / 2**16 ))
ip3=$(( ($ip- $ip1*2**24 - $ip2*2**16) / 2**8 ))
ip4=$(( $ip % 256 ))
echo "$(($PUBLIC_PREFIX+$2)).$ip2.$ip3.$ip4"
}
# $1 :
# $2 : le numéro du lien souhaihé
computeMacAddr() {
computeDb $1
# xx:xx:xx:xx:xx:xx
# 52 ----- -- -- --
# ^ -interface (8 bits, max 256 interface par hôte)
# ^- host (8 bits, max 256 hôtes par réseau)
# ^network (8 bits, max 256 réseaux)
# ^user (16 bits, max 65536 utilisateurs)
local uHigh=$(($DB_CURRENT_USER_NUM /256))
local uLow=$(($DB_CURRENT_USER_NUM %256))
printf "52:%02X:%02X:%02X:%02X:%02X\n" $uHigh $uLow $DB_CURRENT_NETWORK_NUM $DB_CURRENT_HOST_NUM $2
}
# Affiche l'adresse IPv4 multicast du brin ethernet n°$1
# $1 : l'hôte
# $2 : le numéro du lien souhaité
computeEthLink() {
computeDb $1
echo "=== computeEthLink:$2" >&2
echo "DB_CURRENT_USER_NUM:$DB_CURRENT_USER_NUM" >&2
echo "DB_CURRENT_NETWORK_NUM:$DB_CURRENT_NETWORK_NUM" >&2
#echo "DB_CURRENT_HOST_NUM:$DB_CURRENT_HOST_NUM" >&2
# idem que pour l'IP publique sauf :
# - préfixe de l'adresse mcast IPv4
# - le numéro de brin remplace le numéro d'hôte.
# (5bits = 32 brins max par réseau)
# 230.X.Y.Z
# 13 bits de poids fort pour le numero de l'utilisateur (max 8192)
# 6 bits pour le numéro réseau (max 64 réseaux)
# 5 bits pour le numéro de brins (max 32 hôte par réseau)
#
# IP = -------- -------- ---------
# ^ ^^ ^^ ^
# +------------++----++---+
# user net link
local ip=$(( $DB_CURRENT_USER_NUM * 2**11 + $DB_CURRENT_NETWORK_NUM * 2**5))
ip1=$(( $ip/2**24 ))
ip2=$(( ($ip-$ip1*2**24) / 2**16 ))
ip3=$(( ($ip- $ip1*2**24 - $ip2*2**16) / 2**8 ))
ip4=$(( $ip % 256 ))
echo "==> $MCAST_PREFIX_BASE.$ip2.$ip3.$ip4:$MCAST_BASE_PORT" >&2
echo "$MCAST_PREFIX_BASE.$ip2.$ip3.$ip4:$MCAST_BASE_PORT"
}