Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Showing
with 724 additions and 0 deletions
#!/bin/bash
PROG="./receiver-tcp"
FILE="$PROG.c"
PORT=`shuf -i 10000-65000 -n 1`
OUT="/tmp/$$"
mkdir $OUT
IP="::1"
######################################
echo -n "test 01 - program usage: "
echo "usage: $PROG ip_addr port_number" > $OUT/usage
$PROG > $OUT/stdout 2> $OUT/stderr && echo "KO -> exit status $? instead of 1" && exit 1
! cmp -s $OUT/usage $OUT/stderr && echo "KO -> unexpected output on stderr => check file \"$OUT/usage\"" && exit 1
[ -s $OUT/stdout ] && echo "KO -> output detected on stdout" && exit 1
$PROG a > $OUT/stdout 2> $OUT/stderr && echo "KO -> exit status $? instead of 1" && exit 1
! cmp -s $OUT/usage $OUT/stderr && echo "KO -> unexpected output on stderr => check file \"$OUT/usage\"" && exit 1
[ -s $OUT/stdout ] && echo "KO -> output detected on stdout" && exit 1
$PROG a b c > $OUT/stdout 2> $OUT/stderr && echo "KO -> exit status $? instead of 1" && exit 1
! cmp -s $OUT/usage $OUT/stderr && echo "KO -> unexpected output on stderr => check file \"$OUT/usage\"" && exit 1
[ -s $OUT/stdout ] && echo "KO -> output detected on stdout" && exit 1
echo "...............OK"
######################################
echo -n "test 02 - no dynamic memory allocation: "
grep -q "[cm]alloc" $FILE && echo "KO -> dynamic memory allocation is not allowed!" && exit 1
echo "OK"
######################################
echo -n "test 03 - invalid port number: "
$PROG a 65001 > $OUT/stdout 2> $OUT/stderr && echo "KO -> exit status $? instead of 1" && exit 1
! [ -s $OUT/stderr ] && echo "KO -> no output on stderr" && exit 1
[ -s $OUT/stdout ] && echo "KO -> output detected on stdout" && exit 1
$PROG a 9999 > $OUT/stdout 2> $OUT/stderr && echo "KO -> exit status $? instead of 1" && exit 1
! [ -s $OUT/stderr ] && echo "KO -> no output on stderr" && exit 1
[ -s $OUT/stdout ] && echo "KO -> output detected on stdout" && exit 1
echo ".........OK"
######################################
echo -n "test 04 - error on getaddrinfo: "
nc -n fdjkfslkfj 80 > /dev/null 2> $OUT/error
ERROR=$(grep -o '\S*$' $OUT/error)
$PROG fdjkfslkfj $PORT > $OUT/stdout 2> $OUT/stderr && echo "KO -> exit status $?" && exit 1
[ -s $OUT/stdout ] && echo "KO -> output detected on stdout" && exit 1
STUDENT=$(grep -o '\S*$' $OUT/stderr)
[ "$ERROR" != "$STUDENT" ] && echo "KO -> unexpected output on stderr, use gai_strerror whenever getaddrinfo fails" && exit 1
echo "........OK"
######################################
echo -n "test 05 - program exits without error: "
timeout 10 $PROG $IP $PORT > $OUT/stdout 2> $OUT/stderr &
TO=$!
sleep 5
timeout 1 nc -6 $IP $PORT < receiver-tcp &
wait $!
wait $TO
R=$?
[ "$R" == "124" ] && echo "KO -> program times out" && exit 1
[ "$R" != "0" ] && echo "KO -> exit status $R instead of 0" && exit 1
[ -s $OUT/stderr ] && echo "KO -> output detected on stdout" && exit 1
[ -s $OUT/stderr ] && echo "KO -> output detected on stderr" && exit 1
echo ".OK"
######################################
echo -n "test 06 - file copy.tmp exists: "
[ ! -f "copy.tmp" ] && echo "KO -> file does not exist" && exit 1
echo "........OK"
######################################
echo -n "test 07 - files are the same: "
! cmp -s receiver-tcp copy.tmp 2> /dev/null && echo "KO -> files differ" && exit 1
echo "..........OK"
######################################
echo -n "test 08 - check bind failure: "
timeout 5 nc -6l ::1 $PORT &
TO=$!
sleep 1
$PROG $IP $PORT > $OUT/stdout 2> $OUT/stderr && echo "KO -> exit status $? instead of 1" && exit 1
wait $TO
[ -s $OUT/stdout ] && echo "KO -> output detected on stdout" && exit 1
! [ -s $OUT/stderr ] && echo "KO -> no output detected on stderr" && exit 1
echo "..........OK"
######################################
echo -n "test 09 - check open failure: "
chmod 000 copy.tmp
$PROG $IP $PORT > $OUT/stdout 2> $OUT/stderr &
PID=$!
sleep 5
timeout 1 nc -6 $IP $PORT < receiver-tcp
wait $PID
R=$?
[ "$R" != "1" ] && echo "KO -> exit status $R instead of 1" && exit 1
[ -s $OUT/stdout ] && echo "KO -> output detected on stdout" && exit 1
! [ -s $OUT/stderr ] && echo "KO -> no output detected on stderr" && exit 1
chmod 644 copy.tmp
echo "..........OK"
######################################
echo -n "test 10 - memory error: "
P=`which valgrind`
[ -z "$P" ] && echo "KO -> please install valgrind" && exit 1
valgrind --leak-check=full --error-exitcode=100 --log-file=$OUT/valgrind.log $PROG $IP $PORT > /dev/null &
V=$!
sleep 5
cat receiver-tcp | nc -6 -w1 ::1 $PORT
wait $V
[ "$?" == "100" ] && echo "KO -> memory pb please check valgrind.log" && exit 1
echo "................OK"
######################################
rm -r $OUT
\ No newline at end of file
stages:
- build
- test
image: montavont/algodesreseaux
build_11:
stage: build
script:
- cd 11-dialogue-serveurTCP
- scons
artifacts:
paths:
- 11-dialogue-serveurTCP/client-http
# run tests using the binary build before
test_11:
stage: test
needs: [build_11]
script:
- |
echo "starting tests"
cd 11-dialogue-serveurTCP
bash tests.sh
# Algorithmes des réseaux
## Dialogue avec un serveur existant
Complétez le programme `client-http.c` pour dialoguer avec un serveur web et récupérer une page `html` via le protocole `TCP`.
Le programme `client-http` admet en argument le nom du serveur web à contacter (e.g. `google.com`) :
./client-http server_name
Votre programme doit être agnostique de la version du protocole IP utilisée par le serveur et devra permettre des connexions IPv4 ou IPv6.
**Objectifs :** développer un client web simple qui supporte la double pile IPv4/IPv6.
## Marche à suivre
Vous devez dans un premier temps récupérer l'adresse IP du serveur à partir du nom passé en argument du programme via la fonction `getaddrinfo()`. Pour le paramètre `servname` vous pouvez utiliser la chaîne de caractères `http`.
Ensuite, vous pouvez créer un socket de la bonne famille en fonction des informations retournées par `getaddrinfo()` et vous connecter au serveur via le protocole `TCP`.
Le protocole `http` est un protocole en mode texte, c'est-à-dire que les commandes à envoyer sont des chaînes de caractères. La commande `http` à transmettre au serveur sous la forme d'une chaîne de caractères est de la forme :
GET / HTTP/1.1\r\nHost: server_name\r\nConnection:close\r\n\r\n
`server_name` correspond au nom du serveur passé en argument du programme. Il faut donc construire la chaîne de caractères correspondant à la commande puis l'envoyer au serveur et récupérer sa réponse.
Vous afficherez sur la sortie standard la réponse du serveur.
Vous pouvez tester votre programme sur les serveurs suivants :
mai-reseau-get.psi.ad.unistra.fr // Dual stack IPv6 and IPv4 (preference depends on your OS/client)
mai-reseau-get-v4.psi.ad.unistra.fr // IPv4 only
mai-reseau-get-v6.psi.ad.unistra.fr // IPv6 only
## Validation
Votre programme doit obligatoirement passer tous les tests sur gitlab (il suffit de `commit/push` le fichier source pour déclencher le pipeline de compilation et de tests) avant de passer à l'exercice suivant.
sources = Glob ("*.c")
CFLAGS = ["-Wall", "-Wextra", "-Werror", "-g"]
env = Environment (CCFLAGS = CFLAGS)
env.Program (sources)
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#define CHECK(op) do { if ( (op) == -1) { perror (#op); exit (EXIT_FAILURE); } \
} while (0)
#define SIZE 100
void cpy (int src, int dst)
{
char buffer[1024];
// Read from the source descriptor
ssize_t bytesRead;
while ((bytesRead = read(src, buffer, sizeof(buffer))) > 0) {
ssize_t bytesWritten = write(dst, buffer, bytesRead);
if (bytesWritten == -1) {
perror("Error writing to destination descriptor");
exit(EXIT_FAILURE);
}
}
}
int main (int argc, char * argv[])
{
/* test arg number */
if(argc!=2){
fprintf(stderr, "usage: %s server_name\n", argv[0]);
exit(EXIT_FAILURE);
}
/* get the list of struct addrinfo */
struct addrinfo hints,*res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // Supporte IPv4 ou IPv6
hints.ai_socktype = SOCK_STREAM;
int status = getaddrinfo(argv[1], "80", &hints, &res);
if (status != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(EXIT_FAILURE);
}
/* create socket */
int new_socket;
CHECK(new_socket=socket(res->ai_family,res->ai_socktype,res->ai_protocol));
/* connect to the server */
CHECK(connect(new_socket,res->ai_addr,res->ai_addrlen));
/* prepare GET cmd */
char get[SIZE];
snprintf(get, SIZE, "GET / HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", argv[1]);
/* send GET cmd and get the response */
CHECK(send(new_socket,get,strlen(get),0));
char buffer[SIZE]={0};
memset(buffer, 0, sizeof(buffer));
ssize_t n;
while ((n = recv(new_socket, buffer, SIZE - 1, 0)) > 0) {
CHECK(n);
buffer[n] = '\0';
printf("%s", buffer);
}
/* close socket */
close(new_socket);
/* free struct addrinfo list */
freeaddrinfo(res);
return 0;
}
#!/bin/bash
PROG="./client-http"
FILE="$PROG.c"
OUT="/tmp/$$"
mkdir $OUT
URL="mai-reseau-get.psi.ad.unistra.fr"
URL4="mai-reseau-get-v4.psi.ad.unistra.fr"
URL6="mai-reseau-get-v6.psi.ad.unistra.fr"
######################################
echo -n "test 01 - program without arg: "
echo "usage: $PROG server_name" > $OUT/usage
$PROG > $OUT/stdout 2> $OUT/stderr && echo "KO -> exit status $? instead of 1" && exit 1
! cmp -s $OUT/usage $OUT/stderr && echo "KO -> unexpected output on stderr => check file \"$OUT/usage\"" && exit 1
[ -s $OUT/stdout ] && echo "KO -> output detected on stdout" && exit 1
$PROG a b > $OUT/stdout 2> $OUT/stderr && echo "KO -> exit status $? instead of 1" && exit 1
! cmp -s $OUT/usage $OUT/stderr && echo "KO -> unexpected output on stderr => check file \"$OUT/usage\"" && exit 1
[ -s $OUT/stdout ] && echo "KO -> output detected on stdout" && exit 1
echo ".............................OK"
######################################
echo -n "test 02 - no dynamic memory allocation: "
grep -q "[cm]alloc" $FILE && echo "KO -> dynamic memory allocation is not allowed!" && exit 1
echo "....................OK"
######################################
echo -n "test 03 - connection to a non existing server: "
nc fdjkfslkfj 80 > /dev/null 2> $OUT/error
ERROR=$(grep -o '\S*$' $OUT/error)
$PROG fdjkfslkfj > $OUT/stdout 2> $OUT/stderr && echo "KO -> exit status $?" && exit 1
[ -s $OUT/stdout ] && echo "KO -> output detected on stdout" && exit 1
STUDENT=$(grep -o '\S*$' $OUT/stderr)
[ "$ERROR" != "$STUDENT" ] && echo "KO -> unexpected output on stderr, you should use gai_strerror when getaddrinfo fails" && exit 1
echo ".............OK"
######################################
echo -n "test 04 - program exits without error on IPv4 server: "
timeout 5 $PROG $URL4 > $OUT/stdout 2> $OUT/stderr
R=$?
[ "$R" == "124" ] && echo "KO -> program times out" && exit 1
[ "$R" != "0" ] && echo "KO -> exit status $R instead of 0" && exit 1
[ -s $OUT/stderr ] && echo "KO -> output detected on stderr" && exit 1
echo "......OK"
######################################
echo -n "test 05 - get a response from the IPv4 http server: "
! [ -s $OUT/stdout ] && echo "KO -> no output detected on stdout" && exit 1
echo "........OK"
######################################
echo -n "test 06 - IPv4 html response is valid: "
grep -v -e "Date" -e "Last-Modified" $OUT/stdout > $OUT/pg.http
echo -e "GET / HTTP/1.1\r\nHost: $URL4\r\nConnection:close\r\n\r\n" | nc -4 $URL4 80 > $OUT/nc-output
grep -v -e "Date" -e "Last-Modified" $OUT/nc-output > $OUT/legacy.http
! cmp -s $OUT/legacy.http $OUT/pg.http && echo "KO -> files differ" && exit 1
echo ".....................OK"
######################################
echo -n "test 07 - program exits without error on IPv6 server: "
timeout 5 $PROG $URL6 > $OUT/stdout 2> $OUT/stderr
R=$?
cat $OUT/stderr
[ "$R" == "124" ] && echo "KO -> program times out" && exit 1
[ "$R" != "0" ] && echo "KO -> exit status $R instead of 0" && exit 1
[ -s $OUT/stderr ] && echo "KO -> output detected on stderr" && exit 1
echo "......OK"
######################################
echo -n "test 08 - get a response from the IPv6 http server: "
! [ -s $OUT/stdout ] && echo "KO -> no output detected on stdout" && exit 1
echo "........OK"
######################################
echo -n "test 09 - IPv6 html response is valid: "
grep -v -e "Date" -e "Last-Modified" $OUT/stdout > $OUT/pg.http
echo -e "GET / HTTP/1.1\r\nHost: $URL6\r\nConnection:close\r\n\r\n" | nc -6 $URL6 80 > $OUT/output
grep -v -e "Date" -e "Last-Modified" $OUT/output > $OUT/legacy.http
! cmp -s $OUT/legacy.http $OUT/pg.http && echo "KO -> files differ" && exit 1
echo ".....................OK"
######################################
echo -n "test 10 - program exits without error on dual stack server: "
timeout 5 $PROG $URL > $OUT/stdout 2> $OUT/stderr
R=$?
[ "$R" == "124" ] && echo "KO -> program times out" && exit 1
[ "$R" != "0" ] && echo "KO -> exit status $R instead of 0" && exit 1
[ -s $OUT/stderr ] && echo "KO -> output detected on stderr" && exit 1
echo "OK"
######################################
echo -n "test 11 - get a response from the dual stack http server: "
! [ -s $OUT/stdout ] && echo "KO -> no output detected on stdout" && exit 1
echo "..OK"
######################################
echo -n "test 12 - dual stack html response is valid: "
grep -v -e "Date" -e "Last-Modified" $OUT/stdout > $OUT/pg.http
echo -e "GET / HTTP/1.1\r\nHost: $URL\r\nConnection:close\r\n\r\n" | nc -6 $URL 80 > $OUT/output
grep -v -e "Date" -e "Last-Modified" $OUT/output > $OUT/legacy.http
! cmp -s $OUT/legacy.http $OUT/pg.http && echo "KO -> files differ" && exit 1
echo "...............OK"
######################################
echo -n "test 13 - memory error: "
P=`which valgrind`
[ -z "$P" ] && echo "KO -> please install valgrind" && exit 1
valgrind --leak-check=full --error-exitcode=100 --log-file=$OUT/valgrind.log $PROG google.com > /dev/null 2>&1
[ "$?" == "100" ] && echo "KO -> memory pb please check file $OUT/valgrind.log" && exit 1
echo "....................................OK"
rm -r $OUT
stages:
- build
- test
image: montavont/algodesreseaux
build_12:
stage: build
script:
- cd 12-chat
- scons
artifacts:
paths:
- 12-chat/client-chat
# run tests using the binary build before
test_12:
stage: test
needs: [build_12]
script:
- |
echo "starting tests"
cd 12-chat
bash tests.sh
File added
{
"files.associations": {
"netdb.h": "c"
}
}
\ No newline at end of file
# Algorithmes des réseaux
## Chat à deux utilisateurs
Complétez le programme `client-chat.c` pour réaliser un client d'un chat en mode texte pour deux utilisateurs. Le programme devra être double pile, c'est-à-dire être compatible avec des clients `IPv4` et `IPv6`. Le protocole `UDP` sera utilisé au niveau transport.
Le programme `client-chat` admet en argument le numéro de port sur lequel le programme devra écouter (si aucun autre client n'est déjà en écoute) ou le numéro de port sur lequel joindre un client déjà présent :
./client-chat port_number
Les seuls numéros de port valides sont ceux contenus dans l'intervalle `[10000; 65000]`.
Le programme utilise un protocole simpliste en mode texte pour l'ouverture et la fermeture du salon de discussion. Les commandes admises sont : `/HELO` et `/QUIT` comme illusté sur le diagramme état transition sur la figure :
![state chart](protocol.svg)
Pour créer un socket unique compatible `IPv4` et `IPv6`, vous devez créer un socket `AF_INET6` et désactiver l'option `bindv6only` sur ce dernier via la primitive `setsockopt()` :
int value = 0;
CHECK (setsockopt (sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &value, sizeof value));
Dans le cas où aucun client n'est présent, il faut utiliser toutes les adresses de l'hôte lors de l'appel à `bind` via la variable `in6addr_any` :
struct sockaddr *s = (struct sockaddr *) &ss;
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &ss;
in6->sin6_addr = in6addr_any;
Pour écouter simultanément sur plusieurs descripteurs (ici l'entrée standard et le socket), vous devez utiliser la primitive :
int poll (struct pollfd *fds, nfds_t nfds, int timeout);
L'ensemble des descripteurs à surveiller est présent dans une liste de structure `struct pollfd` :
struct pollfd {
int fd; /* descripteur */
short events; /* requested events */
short revents; /* returned events */
};
Le champ `events` est un champ de bit correspondant aux événements à surveiller pour le descripteur `fd`. Le champ `revents` est également un champ de bits, complété par le noyau au retour de `poll()`, qui contient les événements surveillés pour le descripteur `fd` qui se sont réellement produits. Consulter le manuel utilisateur sur `poll()` pour découvrir la liste des événements possibles et plus généralement le fonctionnement de cette primitive.
Tout commit compile automatiquement votre programme et lance les tests dessus. Tous les tests doivent réussir avant de passer à l'exercice suivant.
File added
sources = Glob ("*.c")
CFLAGS = ["-Wall", "-Wextra", "-Werror", "-g"]
env = Environment (CCFLAGS = CFLAGS)
env.Program (sources)
12-chat/Screenshot from 2023-12-29 15-31-26.png

35.2 KiB

This diff is collapsed.
This diff is collapsed.
#!/bin/bash
PROG="./client-chat"
PORT=`shuf -i 10000-65000 -n 1`
PORT_C=`shuf -i 10000-65000 -n 1`
echo -n "test 01 - program without arg: "
$PROG > /dev/null 2>&1 && echo "KO -> exit status $? instead of 1" && exit 1
echo "..................OK"
echo -n "test 02 - program with invalid port number: "
$PROG 65001 > /dev/null 2>&1 && echo "KO -> exit status $? instead of 1" && exit 1
echo ".....OK"
echo -n "test 03 - program accept /HELO and /QUIT cmd: "
timeout 5 $PROG $PORT > /dev/null 2>&1 &
TO=$!
sleep 2
echo -n "/HELO" | nc -6u -w1 localhost $PORT
echo -n "/QUIT" | nc -6u -w1 localhost $PORT
wait $TO
R=$?
[ "$R" == "124" ] && echo "KO -> program times out" && exit 1
[ "$R" != "0" ] && echo "KO -> exit status $R instead of 0" && exit 1
echo "...OK"
echo -n "test 04 - program in client mode: "
echo -n "/QUIT" > cmd.tmp
timeout 5 nc -6ul ::1 $PORT > output &
TO=$!
sleep 2
timeout 3 $PROG $PORT < cmd.tmp
R=$?
[ "$R" == "124" ] && echo "KO -> programs times out" && exit 1
[ "$R" != "0" ] && echo "KO -> exit status $R instead of 0" && exit 1
wait $TO
MES=`cat output`
[ "$MES" != "/HELO/QUIT" ] && echo "KO -> program sent $MES instead /HELO/QUIT" && exit 1
echo "...............OK"
echo -n "test 05 - program accept IPv4 clients: "
timeout 5 $PROG $PORT > output 2> /dev/null &
TO=$!
sleep 2
echo -n "/HELO" | nc -4u -w1 localhost $PORT -p $PORT_C
echo -n "/QUIT" | nc -4u -w1 localhost $PORT -p $PORT_C
wait $TO
R=$?
[ "$R" == "124" ] && echo "KO -> program times out" && exit 1
[ "$R" != "0" ] && echo "KO -> exit status $R instead of 0" && exit 1
rm cmd.tmp
echo "..........OK"
echo -n "test 06 - program prints remote IP and port: "
IP=`cat output | cut -d ' ' -f1`
[ "$IP" != "::ffff:127.0.0.1" ] && echo "KO -> printed IP: $IP | expected: ::ffff:127.0.0.1" && exit 1
PORT_P=`cat output | cut -d ' ' -f2`
[ "$PORT_P" != "$PORT_C" ] && echo "KO -> printed port: $PORT_P | expected: $PORT_C" && exit 1
rm output
echo "....OK"
echo -n "test 07 - memory error: "
P=`which valgrind`
[ -z "$P" ] && echo "KO -> please install valgrind" && exit 1
valgrind --leak-check=full --error-exitcode=100 --log-file=valgrind.log $PROG $PORT > /dev/null &
V=$!
sleep 3
echo -n "/HELO" | nc -4u -w1 localhost $PORT
echo -n "/QUIT" | nc -4u -w1 localhost $PORT
wait $V
[ "$?" == "100" ] && echo "KO -> memory pb please check file valgrind.log" && exit 1
rm valgrind.log
echo "..........................OK"
KOLESNIKOV @ 434a99b4
Subproject commit 434a99b4595bdc3d2f5cbd1ebdf0dd85b80a8753
# Algorithmes des réseaux
Ce dépôt contient une liste d'exercices pratiques pour apprendre à utiliser l'API socket du langage C. Les exercices sont progressifs et doivent être réalisés dans l'ordre.
## Compilation
Un squelette de programme C est fourni pour chaque exercice. Pour le compiler, vous pouvez simplement utiliser l'outil `SCons` qui est un équivalent de `make` :
scons
Pour nettoyer le répertoire courant, il suffit de passer l'option `-c` :
scons -c
## Tests locaux natifs
Un script de tests en `bash` est fourni pour chaque exercice. Après avoir compilé votre programme, vous pouvez le tester via le script :
bash tests.sh
Suivant les exerices, plusieurs tests sont réalisés et un `OK` indique que le test est réussi. Sinon, un court message vous indique la raison de l'échec, vous permettant de corriger les erreurs dans votre programme.
Les scripts de tests sont fournis sans garantie de compatibilité avec votre système.
## Tests locaux sur docker
Vous pouvez tester vos programmes dans une image docker (nécessite d'avoir `docker` installé sur votre système).
L'image `docker` configurée pour les exercices peut être récupérée localement et instanciée dans un conteneur via les commandes :
docker pull montavont/algodesreseaux:2.0
cd chemin/vers/la/copie/locale/du/dépôt/git
docker run --rm -it -v $PWD:/home/alice montavont/algodesreseaux
Pour l'exercice 10, vous aurez besoin d'une connectivité IPv6 globale. Pour activer le support d'IPv6 dans docker, il faut :
1. créer un fichier de configuration dans `/etc/docker/daemon.json` avec le contenu suivant :
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8:dead:beef::/64",
"experimental": true,
"ip6tables": true
}
2. relancer le service docker :
sudo systemctl restart docker
3. lancer le conteneur :
sudo docker run --rm -it -v $PWD:/home/alice montavont/algodesreseaux
## Tests sur gitlab
Les tests peuvent également être directement exécutés par gitlab dans un conteneur docker exécuté sur un runner de gitlab. Tout `commit/push` sur l'un des fichiers source provoque sa compilation et l'exécution du script de tests. Vous pouvez configurer le dépôt gitlab pour être notifié en cas de succès (ou d'échec) des tests.
Sur l'interface de gitlab, il suffit d'aller dans `build/pipeline` pour visualiser le résultat des tests.
## Primitives système
Vous trouverez ci-dessous la signature des primitives système / fonctions de bibliothèque nécessaires à la réalisation des exercices. N'hésitez pas à consulter le manuel utilisateur pour obtenir des explications détaillées.
Attente de connexions :
int accept (int socket, struct sockaddr *restrict address, socklen_t *restrict address_len)
Affectation d'une adresse :
int bind (int socket, const struct sockaddr *address, socklen_t address_len)
Fermeture d'un socket :
int close (int socket)
Tentative de connexion :
int connect (int socket, const struct sockaddr *address, socklen_t address_len)
Configuration de la file d'attente :
int listen (int socket, int backlog)
Lecture sur un socket :
ssize_t recv (int socket, void *buffer, size_t length, int flags)
ssize_t recvfrom (int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len)
Écriture sur un socket :
ssize_t send (int socket, const void *buffer, size_t length, int flags)
ssize_t sendto (int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len)
Création d'un socket :
int socket (int domain, int type, int protocol)
## Fonctions de bibliothèque
Traduit une adresse IP en nom :
int getnameinfo (const struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags)
Traduit un nom en adresses IP :
int getaddrinfo (const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
Libère la mémoire de la liste de `struct addrinfo` allouée par `getaddrinfo` :
void freeaddrinfo (struct addrinfo *ai)
FROM debian:latest
RUN apt-get update && apt-get install -y \
gcc \
valgrind \
netcat-openbsd \
scons \
iproute2 \
curl
RUN useradd --create-home --shell /bin/bash alice
USER alice
WORKDIR /home/alice