merge
This commit is contained in:
commit
3a6d034a95
14
Notes.md
14
Notes.md
@ -1 +1,15 @@
|
||||
# Notes et recherches sur le projet
|
||||
|
||||
Arithétique et ordres modulo
|
||||
|
||||
s ⊕ n = (s+n) % 2^(16)
|
||||
s ⊕ n = (s + n) and 65535
|
||||
|
||||
s ≼ s ′ lorsque ((s ′ − s) mod 2 16 ) < 32768
|
||||
s ≼ s ′ lorsque ((s ′ − s) and 32768) = 0
|
||||
|
||||
-------
|
||||
|
||||
jch.irif.fr port UDP 1212
|
||||
|
||||
http://jch.irif.fr:8082/
|
||||
|
31
parser.c
31
parser.c
@ -1,31 +0,0 @@
|
||||
#include "parser.h"
|
||||
|
||||
// retourne le type de commande à exécuter
|
||||
cmd_token parse_cmd() {
|
||||
char buf[198], cmd[5], arg[193];
|
||||
cmd_token token;
|
||||
token.type = ERROR;
|
||||
memset(token.arg, 0, 193);
|
||||
|
||||
if(fgets(buf, 198, stdin) == NULL)
|
||||
return token;
|
||||
|
||||
// cmd sera le premier mot rencontré et arg la suite de mots après celui ci, si les deux variables ne sont pas remplies alors il y a une erreur
|
||||
if(sscanf(buf, "%s %[^\t\n]", cmd, arg) != 2)
|
||||
return token;
|
||||
|
||||
if(strcmp("req", cmd) == 0) {
|
||||
if(strcmp("neighbour", arg) == 0)
|
||||
token.type = NEIGHBOUR_REQ;
|
||||
else if(strcmp("network state", arg) == 0)
|
||||
token.type = NETWORK_STATE_REQ;
|
||||
else if(strcmp("node state", arg) == 0)
|
||||
token.type = NODE_STATE_REQ;
|
||||
} else if(strcmp("post", cmd) == 0) {
|
||||
token.type = POST;
|
||||
//arg[192] = 0;
|
||||
strcpy(token.arg, arg);
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
14
parser.h
14
parser.h
@ -1,14 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef enum cmd_type {
|
||||
NEIGHBOUR_REQ, NETWORK_STATE_REQ, NODE_STATE_REQ, POST, ERROR
|
||||
} cmd_type;
|
||||
|
||||
typedef struct cmd_token {
|
||||
cmd_type type;
|
||||
char arg[193];
|
||||
} cmd_token;
|
||||
|
||||
// retourne le type de commande à exécuter
|
||||
cmd_token parse_cmd();
|
94
src/node.c
Normal file
94
src/node.c
Normal file
@ -0,0 +1,94 @@
|
||||
// This is the main file of the Dazibao project. It represents the node, and
|
||||
// handles all of the main logic, including the network connexions.
|
||||
|
||||
|
||||
// Will return a packet when we receive one that's valid.
|
||||
packet listen_for_packets(){
|
||||
|
||||
}
|
||||
|
||||
// We need to make sure the TLV announces a length that will no go onto
|
||||
// another tlv, as we might end up reading bullshit.
|
||||
int validate_tlvs(union tlv tlv_to_validate){
|
||||
|
||||
}
|
||||
|
||||
void work_with_tlvs(struct tlvs_list receivied_tlvs){
|
||||
|
||||
// For every TLV,
|
||||
// We make sure the TLV is legal.
|
||||
if(!validate_tlvs(tlv)){
|
||||
perror(">> Invalid TLV receivied, it will be ignored.");
|
||||
}
|
||||
|
||||
// Switch
|
||||
|
||||
// TLV Network Hash
|
||||
// We calculate a network hash,
|
||||
|
||||
// We compare both,
|
||||
|
||||
// If they differ, we send a TLV Network State Request
|
||||
// back to the sender.
|
||||
|
||||
// TLV Network State Request
|
||||
// We check our neighbourhood, and for each peer, we send back
|
||||
// to the sender a TLV Node Hash
|
||||
|
||||
// TLV Node hash
|
||||
// We get a hash _h_ for the node _l_
|
||||
// If we don't have an entry for _l_, or if we have the same one as the
|
||||
// on we just receivied, we send out a TLV Node State Request back.
|
||||
|
||||
// TLV Node State
|
||||
// We get a hash _h_, sequence number _s_, data _d_ for node _l_.
|
||||
// We compute a network hash,
|
||||
// We compare the hash, if they differ, then with l',s',d' our data and
|
||||
// h' the corresponding hash,
|
||||
// if _l_ is our own node id, then
|
||||
// if s >> s' then we update our sequence number to s ⊕ 1 mod 2^16
|
||||
// If it's another's node id, then
|
||||
// If there is no entry for the sender,
|
||||
// we store the entry in our data table.
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[]) {
|
||||
int continue = 1;
|
||||
|
||||
while(continue){
|
||||
|
||||
// We create the neighbourhood table
|
||||
neighbour_peer neighbour_list[NEIGHBOUR_MAX];
|
||||
// We create the message table
|
||||
|
||||
// We create our own message.
|
||||
|
||||
// Listen for incoming packets
|
||||
listen_for_packets();
|
||||
// For every packet recivied, we fork,
|
||||
// then we make sure it's conform
|
||||
// We then extract the data from it to make it easy to work with
|
||||
check_header();
|
||||
// If the sender is not in the neighbourhood, and we have 15 neighbours, we
|
||||
// ignore the packet. Otherwise, we add him to the neighbourhood, marked as
|
||||
// temporary.
|
||||
update_neighbours();
|
||||
// We then look at the differents TLVs in the packet.
|
||||
work_with_tlvs();
|
||||
|
||||
time_t delay = time(NULL) + 20;
|
||||
while(! (delay < time(NULL)){
|
||||
// Theses functions are there for general book-keeping,and run in there own
|
||||
// thread, being run every 20 seconds.
|
||||
// Every 20 sec, if we have less than 5 neighbours, we ask for more peers
|
||||
// by sending out a TLV neighbour Request at a random peer.
|
||||
t_ask_for_more_peers();
|
||||
// Every 20 sec, we also check for a peer that didn't emit a new message for
|
||||
// the past 70 sec, if he's temporary, we delete him from the neighbourhood.
|
||||
t_update_neighbours();
|
||||
// We send out a TLV Network hash to get an ideal of the network state.
|
||||
t_get_network_state();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
64
src/node.h
Normal file
64
src/node.h
Normal file
@ -0,0 +1,64 @@
|
||||
// Define constants
|
||||
|
||||
#ifndef NODE_H
|
||||
#define NODE_H
|
||||
|
||||
// The node ID
|
||||
#define NODE_ID 203242402519736214145149136169422092269247115186189140178187251487819615911212154252117172522111472481308026129190139512419121015210238252292031613214452118122204415160254
|
||||
|
||||
// The number of neighbours
|
||||
// The neighbour table has 15 entries
|
||||
#define NEIGHBOUR_MAX 15
|
||||
|
||||
/* la table de voisins, qui est indexée par adresses de socket (des paires (IP, Port)),
|
||||
* et dont chaque entrée contient un booléen indiquant si le pair est permanent
|
||||
* (configuré au lancement) ou transitoire, et la date de dernière réception d’un
|
||||
* paquet de la part de ce pair ;
|
||||
*/
|
||||
typedef struct neighbour_peer {
|
||||
struct in6_addr ip;
|
||||
short port;
|
||||
char is_temporary;
|
||||
struct timeval last_seen;
|
||||
} neighbour_peer;
|
||||
|
||||
// The strucuture to hold the messages
|
||||
/* It's a list of triplets, (Li,Si,Di)
|
||||
* Li : The Node ID of the publisher 64 bits
|
||||
* Si : the sequence number 16 bits
|
||||
* Di : the data of the message 192 bytes
|
||||
*/
|
||||
|
||||
typedef struct message {
|
||||
long node_id_publisher;
|
||||
short seqno;
|
||||
char *data;
|
||||
} message;
|
||||
|
||||
// TODO
|
||||
|
||||
// fonctions signatures
|
||||
void listen_for_packets();
|
||||
|
||||
void check_header();
|
||||
|
||||
void update_neighbours();
|
||||
|
||||
void work_with_tlvs();
|
||||
|
||||
int validate_tlvs();
|
||||
|
||||
// threaded functions
|
||||
|
||||
void t_ask_for_more_peers();
|
||||
|
||||
void t_update_neighbours();
|
||||
|
||||
void t_get_network_state();
|
||||
|
||||
// Helper functions
|
||||
char * hash();
|
||||
|
||||
short * get_seq_no(short s, int n);
|
||||
|
||||
#endif
|
@ -10,7 +10,8 @@ cmd_token parse_cmd() {
|
||||
if(fgets(buf, 198, stdin) == NULL)
|
||||
return token;
|
||||
|
||||
// cmd sera le premier mot rencontré et arg la suite de mots après celui ci, si les deux variables ne sont pas remplies alors il y a une erreur
|
||||
// cmd sera le premier mot rencontré et arg la suite de mots après celui ci,
|
||||
// si les deux variables ne sont pas remplies alors il y a une erreur
|
||||
if(sscanf(buf, "%s %[^\t\n]", cmd, arg) != 2)
|
||||
return token;
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
|
||||
typedef enum cmd_type {
|
||||
NEIGHBOUR_REQ, NETWORK_STATE_REQ, NODE_STATE_REQ, POST, ERROR
|
||||
} cmd_type;
|
||||
@ -12,3 +15,5 @@ typedef struct cmd_token {
|
||||
|
||||
// retourne le type de commande à exécuter
|
||||
cmd_token parse_cmd();
|
||||
|
||||
#endif
|
15
src/test.c
15
src/test.c
@ -1,15 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main() {
|
||||
char a[1];
|
||||
a[0] = 0;
|
||||
|
||||
if(fork() == 0) {
|
||||
while(1)
|
||||
printf("%d\n", a[0]);
|
||||
} else {
|
||||
a[1] = 1;
|
||||
}
|
||||
}
|
@ -3,6 +3,9 @@
|
||||
#include <stdlib.h>
|
||||
#include "parser.h"
|
||||
|
||||
#ifndef TLV_H
|
||||
#define TLV_H
|
||||
|
||||
// 8 octets min (struct pointer 4 octets), 1024 octets max
|
||||
typedef struct packet {
|
||||
unsigned char magic; // 95 (si autre, ignorer)
|
||||
@ -80,7 +83,7 @@ typedef struct node_state {
|
||||
typedef struct warning {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
char *message;
|
||||
char message[256];
|
||||
} warning;
|
||||
|
||||
typedef union tlv {
|
||||
@ -111,3 +114,5 @@ int build_node_hash(tlv *tlv, long node_id, short seqno, char *node_hash);
|
||||
int build_node_state_req(tlv *tlv, long node_id);
|
||||
int build_node_state(tlv *tlv, long node_id, short seqno, char *node_hash, char *data);
|
||||
int build_warning(tlv *tlv, char *message);
|
||||
|
||||
#endif
|
||||
|
188
tlv.c
188
tlv.c
@ -1,188 +0,0 @@
|
||||
#include "tlv.h"
|
||||
|
||||
// creer un tlv
|
||||
int build_tlv(tlv *tlv, cmd_token token) {
|
||||
switch(token.type) {
|
||||
case NEIGHBOUR_REQ:
|
||||
// a remplir
|
||||
break;
|
||||
case NETWORK_STATE_REQ:
|
||||
// a remplir
|
||||
break;
|
||||
case NODE_STATE_REQ:
|
||||
// a remplir
|
||||
break;
|
||||
case POST:
|
||||
// a remplir
|
||||
break;
|
||||
case ERROR:
|
||||
printf("Wrong format, use 'req {neighbour | network state | node state}' or 'post {message}'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int build_pad1(tlv *tlv) {
|
||||
pad1 *new = (pad1*) malloc(sizeof(pad1));
|
||||
|
||||
if(new == NULL)
|
||||
return -1;
|
||||
|
||||
new->type = 0;
|
||||
|
||||
tlv->pad1 = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_padn(tlv *tlv, size_t len) {
|
||||
padn *new = (padn*) malloc(sizeof(padn));
|
||||
|
||||
if(new == NULL)
|
||||
return -1;
|
||||
|
||||
new->type = 1;
|
||||
new->length = len;
|
||||
new->mbz = (char*) calloc(sizeof(char), len);
|
||||
|
||||
tlv->padn = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_neighbour_req(tlv *tlv) {
|
||||
neighbour_req *new = (neighbour_req*) malloc(sizeof(neighbour_req));
|
||||
|
||||
if(new == NULL)
|
||||
return -1;
|
||||
|
||||
new->type = 2;
|
||||
new->length = 0;
|
||||
|
||||
tlv->neighbour_req = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_neighbour(tlv *tlv, struct in6_addr ip, short port) {
|
||||
neighbour *new = (neighbour*) malloc(sizeof(neighbour));
|
||||
|
||||
if(new == NULL)
|
||||
return -1;
|
||||
|
||||
new->type = 3;
|
||||
new->length = 18;
|
||||
new->ip = ip;
|
||||
new->port = port;
|
||||
|
||||
tlv->neighbour = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_network_hash(tlv *tlv, char *hash) {
|
||||
network_hash *new = (network_hash*) malloc(sizeof(network_hash));
|
||||
|
||||
if(new == NULL)
|
||||
return -1;
|
||||
|
||||
new->type = 4;
|
||||
new->length = 16;
|
||||
memcpy(new->network_hash, hash, 16);
|
||||
|
||||
tlv->network_hash = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_network_state_req(tlv *tlv) {
|
||||
network_state_req *new = (network_state_req*) malloc(sizeof(network_state_req));
|
||||
|
||||
if(new == NULL)
|
||||
return -1;
|
||||
|
||||
new->type = 5;
|
||||
new->length = 0;
|
||||
|
||||
tlv->network_state_req = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_node_hash(tlv *tlv, long node_id, short seqno, char *hash) {
|
||||
node_hash *new = (node_hash*) malloc(sizeof(node_hash));
|
||||
|
||||
if(new == NULL)
|
||||
return -1;
|
||||
|
||||
new->type = 6;
|
||||
new->length = 26;
|
||||
new->node_id = node_id;
|
||||
new->seqno = seqno;
|
||||
memcpy(new->node_hash, hash, 16);
|
||||
|
||||
tlv->node_hash = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_node_state_req(tlv *tlv, long node_id) {
|
||||
node_state_req *new = (node_state_req*) malloc(sizeof(node_state_req));
|
||||
|
||||
if(new == NULL)
|
||||
return -1;
|
||||
|
||||
new->type = 7;
|
||||
new->length = 8;
|
||||
new->node_id = node_id;
|
||||
|
||||
tlv->node_state_req = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_node_state(tlv *tlv, long node_id, short seqno, char *node_hash, char *data) {
|
||||
node_state *new = (node_state*) malloc(sizeof(node_state));
|
||||
int len = strlen(data);
|
||||
|
||||
if(new == NULL)
|
||||
return -1;
|
||||
|
||||
// en mettant cet octet à 0 on est surs de traiter un champ data de taille 192 max
|
||||
if(len > 192) {
|
||||
data[192] = 0;
|
||||
len = 192;
|
||||
}
|
||||
|
||||
new->type = 8;
|
||||
new->length = 26 + len;
|
||||
new->node_id = node_id;
|
||||
new->seqno = seqno;
|
||||
memcpy(new->node_hash, node_hash, 16);
|
||||
memcpy(new->data, data, len);
|
||||
|
||||
tlv->node_state = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_warning(tlv *tlv, char *message) {
|
||||
warning *new = (warning*) malloc(sizeof(warning));
|
||||
int len = strlen(message);
|
||||
|
||||
if(new == NULL)
|
||||
return -1;
|
||||
|
||||
// en mettant cet octet à 0 on est surs de traiter un champ message de taille 256 max
|
||||
if(len > 256) {
|
||||
message[256] = 0;
|
||||
len = 256;
|
||||
}
|
||||
|
||||
new->type = 9;
|
||||
new->length = len;
|
||||
memcpy(new->message, message, len);
|
||||
|
||||
tlv->warning = new;
|
||||
|
||||
return 0;
|
||||
}
|
113
tlv.h
113
tlv.h
@ -1,113 +0,0 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdlib.h>
|
||||
#include "parser.h"
|
||||
|
||||
// 8 octets min (struct pointer 4 octets), 1024 octets max
|
||||
typedef struct packet {
|
||||
unsigned char magic; // 95 (si autre, ignorer)
|
||||
unsigned char version; // 1 (si autre, ignorer)
|
||||
short length; // 1020 max
|
||||
char *body;
|
||||
} packet;
|
||||
|
||||
// 1 octet
|
||||
typedef struct pad1 {
|
||||
unsigned char type;
|
||||
} pad1;
|
||||
|
||||
// 2 octets min, 258 octets max (unsigned char 0 -> 255)
|
||||
typedef struct padn {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
char mbz[256];
|
||||
} padn;
|
||||
|
||||
// 2 octets
|
||||
typedef struct neighbour_req {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
} neighbour_req;
|
||||
|
||||
// 20 octets
|
||||
typedef struct neighbour {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
struct in6_addr ip;
|
||||
short port;
|
||||
} neighbour;
|
||||
|
||||
// 18 octets
|
||||
typedef struct network_hash {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
char network_hash[16];
|
||||
} network_hash;
|
||||
|
||||
// 2 octets
|
||||
typedef struct network_state_req {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
} network_state_req;
|
||||
|
||||
// 28 octets
|
||||
typedef struct node_hash {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
long node_id;
|
||||
short seqno;
|
||||
char node_hash[16];
|
||||
} node_hash;
|
||||
|
||||
// 10 octets
|
||||
typedef struct node_state_req {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
long node_id;
|
||||
} node_state_req;
|
||||
|
||||
// 28 octets min, 220 octets max (data 0 -> 192)
|
||||
typedef struct node_state {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
long node_id;
|
||||
short seqno;
|
||||
char node_hash[16];
|
||||
char data[192];
|
||||
} node_state;
|
||||
|
||||
// 2 octets min, 258 ocets max (unsigned char 0 -> 255)
|
||||
typedef struct warning {
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
char *message;
|
||||
} warning;
|
||||
|
||||
typedef union tlv {
|
||||
pad1 *pad1;
|
||||
padn *padn;
|
||||
neighbour_req *neighbour_req;
|
||||
neighbour *neighbour;
|
||||
network_hash *network_hash;
|
||||
network_state_req *network_state_req;
|
||||
node_hash *node_hash;
|
||||
node_state_req *node_state_req;
|
||||
node_state *node_state;
|
||||
warning *warning;
|
||||
} tlv;
|
||||
|
||||
|
||||
// creer un tlv
|
||||
int build_tlv(tlv *tlv, cmd_token token);
|
||||
|
||||
// creer un tlv specifique
|
||||
int build_pad1(tlv *tlv);
|
||||
int build_padn(tlv *tlv, size_t len);
|
||||
int build_neighbour_req(tlv *tlv);
|
||||
int build_neighbour(tlv *tlv, struct in6_addr ip, short seqno);
|
||||
int build_network_hash(tlv *tlv, char *network_hash);
|
||||
int build_network_state_req(tlv *tlv);
|
||||
int build_node_hash(tlv *tlv, long node_id, short seqno, char *node_hash);
|
||||
int build_node_state_req(tlv *tlv, long node_id);
|
||||
int build_node_state(tlv *tlv, long node_id, short seqno, char *node_hash, char *data);
|
||||
int build_warning(tlv *tlv, char *message);
|
Loading…
Reference in New Issue
Block a user