/*
 * Graph representation of a network. This representation is built from
 * a link state database which contains the complete topology and network
 * attributes.
 */

#ifndef _GRAPH_H
#define _GRAPH_H

#include "linklist.h"
#include <linux/ip.h>
#include <linux/timer.h>
#include <linux/spinlock.h>

/* The vertices of the directed graph representing the link-state
   database consisting of routers. A graph edge connects two
   routers when they are attached via a physical point-to-point
   network. An edge connecting a router to a network indicates that
   the router has an interface on the network. 
*/

#ifdef DSR_CRYPT
struct crypt_state {
    time_t expires; /* qos value expiry time */
#define CRYPT_STATE_SENT 1
#define CRYPT_STATE_NOT_SENT 0
    int req_sent; /* 1 if a request is on the way and we don't want to send another request */
    int n_req;
    __u32 nonce;

    /* resend timer/timeout */
    struct timer_list timer;
    unsigned long timeout;
};
#endif


struct node
{
    __u32 id;		/* Link state ID */
    time_t time;        /* last updated (in seconds) */

#ifdef DSR_CRYPT
    unsigned int qos;
    unsigned int trust;
    unsigned int sig_type; /* type of the signature which provided trust */

    struct crypt_state state;
#endif    

    list links;			/* Outgoing links to routers or networks */

    /* The following fields are used by the shortest-path first
       algorithm. */

    /* Each node is also linked according to its distance from the
       source in a priority queue. */
    struct node *next;
    struct node *prev;

    int distance;			/* distance from source node */
    struct node *pred;		/* predecessor of shortest path to
                                   follow to source */
};


struct link
{
    time_t time;        /* last updated (in seconds) */
    unsigned int metric;		/* link metric in host byte order */

    /* target of link */
    struct node *to;
};


/* Directed graph structure */
struct graph
{
    list nodes;			/* of type struct node */
    list links;			/* of type struct link */

    /* For shortest-path first */
    struct pqueue *pq;		/* Priority queue */
    
    int refresh;
    
    spinlock_t lock;
//    rwlock_t lock;
    unsigned long lock_flags;
};

/* -----------------------------------------------------------
 * Prototypes
 * -----------------------------------------------------------
 */

/* Nodes Prototypes */

struct node *node_new (__u32 id);

void node_free (struct node *);
void node_print (struct node *n);
void node_printsimple (struct node *n);

/* Link Prototypes */
struct link *link_new (struct node *from, struct node *to,
		       unsigned int metric);
void link_free (struct link *l);
struct link *link_get_node (struct node *src, struct node *dst);
struct link *link_get_addr (struct node *n, __u32 id);
void link_print (struct link *l);

/* Graph Prototypes */
struct graph *graph_new ();
void graph_free (struct graph *g);
void graph_print (struct graph *g);

void graph_add_node (struct graph *g, struct node *n);
void graph_add_node_nocheck (struct graph *g, struct node *n);
void graph_add_link (struct graph *g, struct link *l);

/* lookup nodes in graph */
struct node *node_get (struct graph *g, __u32 id);

#ifdef NOMORE
void graph_add_graph (struct graph *g1, struct graph *g2);
#endif /* NOMORE */

#endif /* _GRAPH_H */
