Compare commits

..

12 Commits

Author SHA1 Message Date
n07070
9d7ccf09dc Ajout du rapport et rendu final. 2020-05-12 17:31:59 +02:00
n07070
f5ab2ba488 Merge branch 'master' of gaufre.informatique.univ-paris-diderot.fr:perdriau/dazibao 2020-05-12 16:49:59 +02:00
n07070
ead5ba5f25 Rajout d'une partie sur la réception des paquets 2020-05-12 16:49:24 +02:00
GONZALEZ ARENAS felipe
a0c70cf65d détails sécurité 2020-05-12 16:37:37 +02:00
n07070
81555b4c6a Corrections finales 2020-05-12 15:23:19 +02:00
n07070
de00cca6c7 Updated Rapport & README 2020-05-12 13:56:13 +02:00
n07070
7f6f1938a6 smol 2020-05-10 17:30:21 +02:00
GONZALEZ ARENAS felipe
880e719ff4 rapport - hash / aggregation tlv / fautes d'ortographe 2020-05-08 16:58:06 +02:00
GONZALEZ ARENAS felipe
28102c9b0b Update README.md 2020-05-08 16:24:30 +02:00
PERDRIAU nelson
6036eab1a3 Merge branch 'fix-add-peer' into 'master'
Fix add peer

See merge request perdriau/dazibao!22
2020-05-06 17:01:01 +02:00
n07070
2b0756a921 Update 2020-05-06 16:49:09 +02:00
n07070
bda5108589 Fixed adding a peer a bootstrap 2020-05-06 16:08:46 +02:00
6 changed files with 76 additions and 80 deletions

View File

@ -1,24 +1,22 @@
# 大字报 # 大字报
> Le Maoïsme du XXIème siècle > Un grand bond en avant pour le pair à pair du XXIème siècle
![Étudiants préparant le projet de réseau, 2020](header.jpg) ![Étudiants préparant le projet de réseau, 2020](header.jpg)
**_Étudiants préparant le projet de réseau, 2020_** **_Étudiants préparant le projet de réseau, 2020_** _By 人民画报 - 《人民畫報》1967年, Public Domain, <a href="https://commons.wikimedia.org/w/index.php?curid=66356803">Link</a>_
By 人民画报 - 《人民畫報》1967年, Public Domain, <a href="https://commons.wikimedia.org/w/index.php?curid=66356803">Link</a>
## Abstract ## Abstract
Dazi bao est l'implémentation d'un protocol de commérage, qui permet de publier un message, ce dernier est envoyé de proche en proche à chaque pair du réseau. Dazi bao est l'implémentation d'un protocole de commérage, qui permet de publier un message, ce dernier est envoyé de proche en proche à chaque pair du réseau.
L'utilisation se fait depuis un terminal, en ligne de commande. L'utilisation se fait depuis un terminal, en ligne de commande.
## Structure et déroulement ## Structure et déroulement
Le programme est structuré autour du fichier `node.c`, dans lequel se trouve la fonction main. Cette fonction va se charger d'appeler les fonctions d'initialisation, et de lancer le protocol. La construction des TLV, la production d'un hash et les fonctions de gestion et d'affichage d'erreurs sont dans leurs propre fichier, car ce sont des points qui peuvent être amené à changé lors de l'implémentation d'extensions. Le programme est structuré autour du fichier `node.c`, dans lequel se trouve la fonction `main()`. Cette fonction va se charger d'appeler les fonctions d'initialisation, et de lancer le protocole. La construction des TLV, la production d'un hash et les fonctions de gestion et d'affichage d'erreurs sont dans leurs propres fichiers, car ce sont des points qui peuvent être amenés à changer lors de l'implémentation d'extensions.
Le noeud n'a pas de mémoire, et va donc être intialisé à partir de 0 à chaque lancement. Entre le lancement, et le moment où l'on connaît l'ensemble des messages publiés ( avec le site web comme référence, bien que ça ne soit pas forcément valide), le temps de convergance est en dessous d'une seconde. Le noeud n'a pas de mémoire, et va donc être initialisé à partir de 0 à chaque lancement. Entre le lancement, et le moment où l'on connaît l'ensemble des messages publiés (avec le site web comme référence, bien que ça ne soit pas forcément valide), le temps de convergance est de l'ordre de quelques secondes.
### Structure ### Structure
@ -26,51 +24,61 @@ Le programme se découpe en 2 parties ; l'initialisation, puis la récupération
### Initialisation ### Initialisation
Lorsque l'on éxécute le programme, on donne une URL ainsi qu'un numéro de port. Cette URL va être décodée par `getaddrinfo`, qui va nous donner >1 adresses IP, qui peuvent être en format IPv4 ou IPv6. Pour chaque adresse IP, nous crééons un pair, que l'on va marqué comme permanent. On y associe le numéro de port donné lors du lancement. Nous crééons aussi le socket que l'on utilisera ensuite. Nous le fixons sur le port 1212. Lorsque l'on exécute le programme, on donne une URL ainsi qu'un numéro de port. Cette URL va être décodée par `getaddrinfo`, qui va nous donner >=1 adresses IP. Pour chaque adresse IP, nous créons un pair, que l'on va marquer comme permanent. Si plusieurs adresses IP sont données, mais qu'elles correspondent à un seul pair, nous n'en utilisons qu'une seule, pour évider les congestions et autres erreurs. On y associe le numéro de port donné lors du lancement. Nous créons aussi le socket que l'on utilisera ensuite. Nous le fixons sur le port 1212.
Par soucis de simplicité, et dans l'espoir que IPv4 disparaisse rapidement des internet, nous traitons tout les pairs comme étant en IPv6. Les adresses IPv4 sont _IPv6 mapped_. Une fois le programme lancé, on ne peux plus ajouter de pair permanent, ni les supprimer. On pourrait étendre le programme en permettant d'ajouter les pairs de façon dynamique, en les ajoutant ou supprimant. On pourrait aussi choisir de "bloquer" un pair, mais cela reste impossible en l'étant, voir la note 1. Par soucis de simplicité, et dans l'espoir que IPv4 disparaisse rapidement des internet, nous traitons tout les pairs comme étant en IPv6. Les adresses IPv4 sont _IPv6 mapped_. Une fois le programme lancé, on ne peux plus ajouter de pair permanent, ni les supprimer. On pourrait étendre le programme en permettant d'ajouter les pairs de façon dynamique, en les ajoutant ou supprimant. On pourrait aussi choisir de "bloquer" un pair, mais cela reste impossible en l'état, voir la note 1.
Nous initialisations aussi la liste des messages, en créeant un permier message, vide. Il est vide, pour plusieurs raisons : d'une part, lorsque l'on lance le programme, on peux ne pas avoir envie de publier quoique ce soit, et de juste recevoir les messages. On peux aussi avoir envie d'effacer les messages publiés précédement. Lors de la publication de notre message, il remplacera les messages précédents connu des pairs par une phrase vide, ce qui effacera le message. À noter que, vu qu'il n'existe pas, dans le protocol de base, d'authentification, ça peux aussi être un moyen d'effacer tout les messages du réseau.¹ Nous initialisations aussi la liste des messages, en créant un premier message, vide. Il est vide, pour plusieurs raisons : d'une part, lorsque l'on lance le programme, on peux ne pas avoir envie de publier quoique ce soit, et de juste recevoir les messages. On peux aussi avoir envie d'effacer les messages publiés précédemment. Lors de la publication de notre message, il remplacera les messages précédents connu des pairs par une phrase vide, ce qui effacera le message. À noter que, vu qu'il n'existe pas, dans le protocole de base, d'authentification, ça peux aussi être un moyen d'effacer tout les messages du réseau.¹
La liste de pair et la liste de messages sont des listes chainés simple. Elles sont suffisante, car permettent l'ajout et la suppression. Lors de l'envoie de messages, nous devons parcourir toute la liste des pairs, et lors de la réception ou l'inondation de message, nous devons aussi passer en revue tout les messages. La liste de pairs et la liste de messages sont des listes chainées simples. Elles sont suffisantes, car permettent l'ajout et la suppression. Lors de l'envoi de messages, nous devons parcourir toute la liste de pairs, et lors de la réception ou l'inondation de messages, nous devons aussi passer en revue tous les messages.
Une extension possible serait de stocker le hash de chaque message, afin d'avoir une hash map. On pourrait donc vérifier uniquement le hash, sans avoir besoin de le recalculer. Cela réduirait aussi fortement le temps de mise à jour et d'accès aux messages. Une extension possible serait de stocker le hash de chaque message, afin d'avoir une hash map. On pourrait donc vérifier uniquement le hash, sans avoir besoin de le recalculer. Cela réduirait aussi fortement le temps de mise à jour et d'accès aux messages.
### Déroulement ### Déroulement
Le noeud va ensuite initiliser une structure `pollfd`, un variable de délais, ainsi que deux tableau de char. Ces derniers font 1024 bytes, ce qui est recommandé dans le projet. C'est suffisant, car un paquet ne peux pas faire plus de 1024 bytes, et nous traitons les paquets les uns à la suite des autres. La structure `pollfd` va servir lors de l'appel à la fonction `poll`, qui se charge de surveiller deux descripteurs de fichiers : `stdin`, et le socket définit lors de l'initialisation. Quand des données sont écrites dans ces fichiers, nous effectuons une lecture. Le noeud va ensuite initialiser une structure `pollfd`, une variable de délai, ainsi que deux tableaux de char. Ces derniers font 1024 bytes, ce qui est recommandé dans le projet. C'est suffisant, car un paquet ne peux pas faire plus de 1024 bytes, et nous traitons les paquets les uns à la suite des autres. La structure `pollfd` va servir lors de l'appel à la fonction `poll`, qui se charge de surveiller deux descripteurs de fichiers : `stdin`, et le socket définit lors de l'initialisation. Quand des données sont écrites dans ces fichiers, nous effectuons une lecture.
La lecture de stdin premet de récupérer à la fois des commandes pour la gestion du noeud, ainsi que le message à publier. La lecture du socket nous permet de récupérer les paquets entrant. La lecture de stdin permet de récupérer à la fois des commandes pour la gestion du noeud, ainsi que le message à publier. La lecture du socket nous permet de récupérer les paquets entrants.
La variable de délais est utilisé pour mettre à jour la liste de pair, demander plus de pair le cas échéant, et demander l'état du réseau aux autres pairs. Nous l'initialisation à une valeur inférieure à 20 secondes, car lors du lancement, nous ne connaissons rien du réseau. Pas la peine d'attendre. Une fois la première éxécution passée, nous mettons un délais de vingt à trentes secondes. C'est suffisant, car la publication de nouveaux messages sur le réseau est assez lente. Nous pourrions faire évoluer ce délais en fonction du rythme de publication de nouveaux messages. La variable de délai est utilisée pour mettre à jour la liste de pairs, demander plus de pairs le cas échéant, et demander l'état du réseau aux autres pairs. Nous l'initialisons à une valeur inférieure à 20 secondes, car lors du lancement, nous ne connaissons rien du réseau. Pas la peine d'attendre. Une fois la première exécution passée, nous mettons un délais de vingt à trente secondes. C'est suffisant, car la publication de nouveaux messages sur le réseau est assez lente. Nous pourrions faire évoluer ce délais en fonction du rythme de publication de nouveaux messages.
#### Ajouts de nouveaux messages #### Ajouts de nouveaux messages
L'ajout de nouveaux messages est fait uniquement si on écrit un message non-vide. Dans le cas contraire, on affiche les messages connus. L'ajout de nouveaux messages est fait uniquement si on écrit un message non-vide. Dans le cas contraire, on affiche les messages connus.
On va ensuite appeler la fonction `add_message(char * message, int message_len)`. Elle se charge de vérifier qu'on n'ajoute pas un message vide, puis va chercher le message publié par notre propre identifiant. On mets à jour le numéro de séquence, et l'on copie le nouveau message dans la liste. Afin d'éviter des erreures, on libère l'ancienne allocation, et on alloue une nouvelle mémoire de la taille du nouveau message. On va ensuite appeler la fonction `add_message(char * message, int message_len)`. Elle se charge de vérifier qu'on n'ajoute pas un message vide, puis va chercher le message publié par notre propre identifiant. On met à jour le numéro de séquence, et l'on copie le nouveau message dans la liste. Afin d'éviter des erreurs, on libère l'ancienne allocation, et on alloue une nouvelle mémoire de la taille du nouveau message.
Ce message sera envoyé aux pairs en faisant la demance lors de l'inondation. Ce message sera envoyé aux pairs en faisant la demande lors de l'inondation.
#### Réception des paquets et traitement #### Réception des paquets et traitement
Lors de la réception d'un message, on effectue plusieurs vérifications. La première consiste à vérifier l'entête du paquet. Une fois cette entête validée, on ajoute le pair à la liste des pairs connus. Lors de la réception d'un message, on effectue plusieurs vérifications. La première consiste à vérifier l'entête du paquet. En particulier, il faudra vérifier que le champ body_length du paquet est bien conforme aux spécifications données et correspond bien au nombre d'octets reçus par recvmsg. Une fois cette entête validée, on ajoute le pair à la liste des pairs connus.
On passe ensuite à la validation de chaque TLV. On commence par créer un paquet vide, qui va nous servir lors du renvoie éventuel de paquet vers les pairs. Ensuite, l'un à la suite des autres, nous validons les TLVs. Une fois qu'un TLV est valide, nous le traitons. Si nous avons besoin de renvoyer un paquet, nous allons soit le renvoyer directement, soit agrégé des TLVs dans un paquet, qui se remplira jusqu'a être pleins, suite à quoi il sera envoyé. On passe ensuite à la validation de chaque TLV. On commence par créer un paquet vide, qui va nous servir lors du renvoi éventuel de paquets vers les pairs. Ensuite, l'un à la suite des autres, nous validons les TLVs. Il faudra vérifier que leur longueur n'est pas différente de ce que l'on attend selon leur type, mais aussi il faudra vérifier que la longeur annoncée ne dépasse pas les bornes du paquet à la position courrante.
#### Gestion et génération des hashs. La validation du TLV se fait selon plusieurs critères : est-ce que la taille annoncée correspond bien à la taille que l'on constate, est-ce que le type de TLV existe bien, ou encore est-ce que le TLV doit être traité (dans le cas du padding par exemple).
? Une fois qu'un TLV est valide, nous le traitons. En fonctions des cas, nous allons recalculer les hash, ou mettre à jour des données. Si nous avons besoin de renvoyer un paquet, nous allons soit envoyer un seul TLV dans un paquet dans certains cas spécifiques, soit agréger des TLVs dans un paquet. Celui-ci servira de buffer pour la fonction d'envoi, qui sera appelée lorsque le paquet ne peux plus accueillir de nouveaux TLV, suite à quoi le paquet sera réinitialisé afin de pouvoir le réutiliser pour des futurs envois.
Après avoir traité tous les TLVs reçus, nous enverrons le paquet courant, qui peut encore contenir des TLVs non envoyés.
#### Gestion et génération des hashes.
Nous utilisons la librairie OpenSSL pour générer notre hash SHA256. Dans le cas où nous ne générons que le hash d'un seul noeud, on concatenne les données id, seqno et data (en faisant attention à convertir id et seqno en big endian) dans un même buffer et on le passe à la fonction de hashage.
Dans le cas d'un network hash, on concatènera dans un grand buffer tous les hashes de chaque donnée connue (qui sont ajoutées peu à peu dans une liste chainée de façon à ce qu'elle soit en ordre croissant par rapport à l'id) puis nous passerons ce buffer à la fonction de hashage.
On n'utilisera que les 16 premiers bytes de ces hashes.
## Choix d'implémentation ## Choix d'implémentation
### TLV ### TLV
Les TLVs sont représentés par un type `union TLV`, qui contiens des pointeurs vers le `struct` TLV en lui-même. Les TLVs sont représentés par un type `union TLV`, qui contient des pointeurs vers le `struct` TLV en lui-même, différent pour chaque type de TLV. Afin de garder une facilité d'accès aux TLVs, ils sont tous définis avec comme premier champs, sont type, qui est de même taille pour tout TLV.
### poll() ### poll()
L'utilisation de `poll()` nous permet de réagir à des évènements, et donc de ne pas avoir à attendre inutilement quand rien ne se passe. `poll()` va attendre 10ms sur chaque descripteur de fichier, en bloquant le reste du programme. Si nous recevons un message alors que nous n'observons pas le socket, rien de grave ne se passe ; on attendra un autre message. L'utilisation de `poll()` nous permet de réagir à des évènements, et donc de ne pas avoir à attendre inutilement quand rien ne se passe. `poll()` va attendre 10ms sur chaque descripteur de fichier, en bloquant le reste du programme. Si nous recevons un message alors que nous n'observons pas le socket, rien de grave ne se passe ; on attendra un autre message. De plus, il y a déjà un buffer interne au système.
### Envoie des paquets avec sendmsg ### Envoie des paquets avec sendmsg
@ -82,37 +90,26 @@ Notre programme contient une variable `DEBUG_LEVEL` définie dans `debug.h`, qui
Puis, entre 1 et 9, des message de débug avec plus ou moins de détails sont affichés, ce qui permet d'avoir une idée de la "vie" du pair en temps réel. À partir de 9, l'éxécution se fait étape par étape, en appuyant sur entrée à chaque étape. Puis, entre 1 et 9, des message de débug avec plus ou moins de détails sont affichés, ce qui permet d'avoir une idée de la "vie" du pair en temps réel. À partir de 9, l'éxécution se fait étape par étape, en appuyant sur entrée à chaque étape.
Une attention particulière est porté sur la gestion des erreurs. En effet, notre pair va essayer au maximum de continuer à vivre malgré les bugs possible. Vu qu'il est possible de recevoir tout type de message, nous préférons afficher un message d'erreur ou de débug plutôt que d'arrêter l'éxécution. À noter que le fait de ne pas avoir de pair au début n'est pas une erreure fatale, car il se peut qu'un autre pair communique avec nous, sans que nous ne le connaissions au préalable. Une attention particulière est porté sur la gestion des erreurs. En effet, notre pair va essayer au maximum de continuer à vivre malgré les bugs possible. Vu qu'il est possible de recevoir tout type de message, nous préférons afficher un message d'erreur ou de débug plutôt que d'arrêter l'exécution. À noter que le fait de ne pas avoir de pair au début n'est pas une erreur fatale, car il se peut qu'un autre pair communique avec nous, sans que nous ne le connaissions au préalable.
## Spécificités
?
## Extensions ## Extensions
Nous avons implémenter l'aggrégation de TLV dans un paquet. Nous avons implémenter l'agrégation de TLV dans un paquet.
Nous vérifions la cohérence des _Node State_ ; si on reçoit un node state, on vérifie que son hash est cohérent. Nous vérifions la cohérence des _Node State_ ; si on reçoit un node state, on vérifie que son hash est cohérent.
Si notre pair as plusieurs adresses, nous communiquons sur toutes les adresses qu'il possède. Si notre pair as plusieurs adresses, nous communiquons sur toutes les adresses qu'il possède.
## Tests
Nous avons réalisé de nombreux test, y compris avec d'autres pairs, écrit par des camarades. Cela nous as permis de renforcer la robustesse de notre programme.
## Commentaire Nous nous ajoutions mutuellement comme pair par défault, ou alors nous formions une "chaîne", où l'on ajoute son voisin, et il ajoute un autre voisin.
Ce que l'on as pensé du projet, les éventuelles difficultés ? Nous avons aussi essayé de faire du renvoi de paquet depuis WireShark, afin de tester la réaction de notre pair à la réception de plusieurs paquets identiques, ou de messages tronqués, corrompu, ou malveillants...
## Conclusion Toutefois, la licence AGPL s'applique toujours ; aucune garantie n'est possible...
?
--- ---
[1] Pour cela, il suffit de publier un message vide, tout en se donnant comme numéro d'identification ceux que l'on connait, venant d'autres pairs. [1] Pour cela, il suffit de publier un message vide, tout en se donnant comme numéro d'identification ceux que l'on connait, venant d'autres pairs.
---
Comment est organisé le code ? Diagram UML ? Dépendances ?

BIN
RAPPORT.pdf Normal file

Binary file not shown.

View File

@ -18,25 +18,33 @@ _Ce logiciel est développé pour GNU/Linux, et n'a pas de support à l'heure ac
- `gcc` >= 9.3.0 - `gcc` >= 9.3.0
- `libssl-dev` et `libssl`. - `libssl-dev` et `libssl`.
- Lancez la commande `make` - Lancez la commande `make`
- Si aucune erreure n'a lieu, tuto bene. Sinon, ouvrez un rapport de bug sur la page web du projet. - Si aucune erreur n'a lieu, tuto bene. Sinon, ouvrez un rapport de bug sur la page web du projet.
- Optionnel : vous pouvez installer Dazibao de façon permanante en copiant le fichier `dazibao` ainsi crée dans `/usr/bin`. - Optionnel : vous pouvez installer Dazibao de façon permanente en copiant le fichier `dazibao` ainsi crée dans `/usr/bin`.
## Utilisation ## Utilisation
Si vous connaissez l'adresse d'un pair, vous pouvez éxecuter le programme avec la commande `./dazibao <root peer> <port>`, en remplacement `<root peer>` par l'URL où votre pair est disponible, et `<port>` par le port où le pair écoute. Si vous connaissez l'adresse d'un pair, vous pouvez éxecuter le programme avec la commande `./dazibao <root peer> <port>`, en remplaçant `<root peer>` par l'URL où votre pair est disponible, et `<port>` par le port où le pair écoute.
Si vous voulez changer le niveau d'affichage, vous pouvez changer la valeur de la variable `DEBUG_LEVEL`, puis refaire la commande `make`.
Lorsque le niveau est >1, vous êtes en mode débug, et en appuyant sur **P** puis **Entrée**, vous pouvez afficher la liste des pairs connus.
En appuyant juste sur **Entrée** sans rien d'autre, vous pouvez afficher la liste des messages connus, classé par ID du pair.
Vous pouvez aussi lancer votre pair avec la commande `./dazibao <root peer> <port> >> dazibao.log`. Ainsi, vous aurez l'affichage de Dazibao dans le fichier susnommé, que vous pouvez lire avec `tail -f`, dans une autre fenêtre de terminal. De fait, cela rend l'écriture de nouveaux messages beaucoup plus simple.
## Contribution ## Contribution
Sentez vous libre de copier le code, le modifier et de nous renvoyer vos modifications tout en les décrivant avec le plus de détail possible. Vous pouvez ouvrir un _merge request_ depuis la page web du projet. Sentez vous libre de copier le code, le modifier et de nous renvoyer vos modifications tout en les décrivant avec le plus de détails possible. Vous pouvez ouvrir un _merge request_ depuis la page web du projet.
## Notes ## Notes
Ce programme est une projet réalisé lors du deuxième semestre 2020, durant le confinement dû au coronavirus, dans le cadre de la licence d'informatique de Paris-Diderot, dont les consignes sont données dans le fichier [énoncé.pdf](énoncé.pdf). Ce programme est un projet réalisé lors du deuxième semestre 2020, durant le confinement dû au coronavirus, dans le cadre de la licence d'informatique de Paris-Diderot, dont les consignes sont données dans le fichier [énoncé.pdf](énoncé.pdf).
## Licence ## Licence
Dàzì bào - p2p gossip social network. Dàzì bào - p2p gossip social network.
Copyright (C) 2020 Felippe & Nelson P. Copyright (C) 2020 Felipe G.A. & Nelson P.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

View File

@ -4,7 +4,7 @@
#include "node.h" #include "node.h"
#define DEBUG_LEVEL 6 #define DEBUG_LEVEL 0
void welcome(); void welcome();

View File

@ -338,7 +338,7 @@ int update_neighbours() {
// from this peer then remove it from the list // from this peer then remove it from the list
time(&curtime); time(&curtime);
if(difftime(peer->last_seen, curtime) >= 70) { if(difftime(curtime, peer->last_seen) >= 70) {
// increase the count of deleted nodes // increase the count of deleted nodes
deleted++; deleted++;
@ -1083,7 +1083,7 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
break; break;
case 9: case 9:
print_debug(">> \aReceived warning !"); print_error(">> \aReceived warning !");
// We received a warning tlv so it's message is printed // We received a warning tlv so it's message is printed
tlv_len = data[pos+1]; tlv_len = data[pos+1];
cur_message = data + pos + 2; cur_message = data + pos + 2;
@ -1395,6 +1395,7 @@ int bootstrap_node(int * sock_fd, char * root_peer_ip, uint16_t root_peer_port){
int rc = getaddrinfo(root_peer_ip, "http", &hints, &res); int rc = getaddrinfo(root_peer_ip, "http", &hints, &res);
if(rc != 0) { if(rc != 0) {
print_error("Failed to resolve hostname, exiting..."); print_error("Failed to resolve hostname, exiting...");
printf(gai_strerror(rc));
exit(1); exit(1);
} }
@ -1404,38 +1405,29 @@ int bootstrap_node(int * sock_fd, char * root_peer_ip, uint16_t root_peer_port){
// For every address given to us by getaddrinfo, we create a new peer. // For every address given to us by getaddrinfo, we create a new peer.
struct addrinfo *p; struct addrinfo *p;
struct neighbour_peer *peer ; struct neighbour_peer *peer ;
p = res;
peer = (neighbour_peer*) malloc(sizeof(neighbour_peer));
memcpy(&peer->ip, &((struct sockaddr_in6 *) p->ai_addr)->sin6_addr, sizeof(struct in6_addr));
peer->port = root_peer_port;
peer->is_temporary = 0;
list * tmp = neighbour_list; // set last_seen time
for(p = res; p != NULL; p = p->ai_next) { peer->last_seen = time(NULL);
peer = (neighbour_peer*) malloc(sizeof(neighbour_peer));
memcpy(&peer->ip, &((struct sockaddr_in6 *) p->ai_addr)->sin6_addr, sizeof(struct in6_addr));
peer->port = root_peer_port;
peer->is_temporary = 0;
// set last_seen time if (DEBUG_LEVEL > 0) {
peer->last_seen = time(NULL); char * buff_str_ip[1024];
char * ip_str = (char * ) inet_ntop(AF_INET6,&peer->ip,(char * restrict) buff_str_ip, 1024);
if (DEBUG_LEVEL > 0) { printf("\x1b[31m[DEBUG]\x1b[0m >> Adding %s @ %i to peer list.\n", ip_str, root_peer_port );
char * buff_str_ip[1024];
char * ip_str = (char * ) inet_ntop(AF_INET6,&peer->ip,(char * restrict) buff_str_ip, 1024);
printf("\x1b[31m[DEBUG]\x1b[0m >> Adding %s @ %i to peer list.\n", ip_str, root_peer_port );
}
// Add new peer to the list.
list *node = (list*) malloc(sizeof(list));
node->data = (void*) peer;
node->next = NULL;
// Goint to the end of the list
while(tmp->next != NULL){
tmp = tmp->next;
}
tmp->next = node;
} }
neighbour_list = tmp;
// Add new peer to the list.
list *node = (list*) malloc(sizeof(list));
node->data = (void*) peer;
node->next = neighbour_list;
neighbour_list = node;
neighbour_list->next = NULL;
print_peers(neighbour_list); print_peers(neighbour_list);

View File

@ -62,8 +62,7 @@ typedef struct list {
// The node ID // The node ID
#define NODE_ID 4209169790617845760 #define NODE_ID 4209169790617845760
// #define NODE_ID 42675882021843277 // #define NODE_ID 13386709784863621846
// #define NODE_ID 1312
// The number of neighbours // The number of neighbours
// The neighbour table has 15 entries // The neighbour table has 15 entries