Skip to content
Snippets Groups Projects
Commit 201e51c6 authored by huitema's avatar huitema
Browse files

Starting to build the basic context handling.

parent 6bc0ed15
No related merge requests found
......@@ -4,4 +4,48 @@
* or a combination of source address, source port and partial context value.
* - Has to find the sequence number, based on partial values and windows.
* - For initial packets, has to perform version checks.
*/
\ No newline at end of file
*/
#include <stdint.h>
#include "picoquic.h"
int picoquic_incoming_packet(
uint8_t * bytes,
uint32_t length,
struct soackaddr * addr_from)
{
/* Parse the clear text header */
uint8_t first_byte = bytes[0];
uint64_t cnx_id;
uint32_t pn;
uint32_t vn;
uint32_t offset;
if ((first_byte & 0x80) != 0)
{
/* long packet format */
cnx_id = PICOPARSE_64(&bytes[1]);
pn = PICOPARSE_64(&bytes[9]);
vn = PICOPARSE_64(&bytes[13]);
offset = 17;
/* Get CNX by CNX_ID */
}
else
{
/* short format */
if ((first_byte & 0x40) != 0)
{
cnx_id = PICOPARSE_64(&bytes[1]);
offset = 9;
/* need to identify CNX by CNX_ID */
}
else
{
/* need to identify CNX by socket ID */
offset = 1;
}
/* Get the length of pn from the CNX */
}
}
#include "picoquic.h"
......@@ -115,4 +115,18 @@ void picohash_delete(picohash_table * hash_table, int delete_key_too)
free(hash_table->hash_bin);
free(hash_table);
}
uint64_t picohash_bytes(uint8_t * key, uint32_t length)
{
uint64_t hash = 0xDEADBEEF;
for (uint32_t i = 0; i < length; i++)
{
hash ^= key[i];
hash ^= ((hash << 31) ^ (hash >> 17));
}
return hash;
}
\ No newline at end of file
......@@ -43,6 +43,8 @@ extern "C" {
void picohash_delete(picohash_table * hash_table, int delete_key_too);
uint64_t picohash_bytes(uint8_t * key, uint32_t length);
#ifdef __cplusplus
}
......
File moved
......@@ -2,32 +2,55 @@
#define PICOQUIC_H
#include <stdint.h>
#include <winsock2.h>
#include <Ws2def.h>
#include <WS2tcpip.h>
#include "picohash.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* QUIC context, defining the tables of connections,
* open sockets, etc.
*/
typedef struct _picoquic_quic
{
picohash_table * table_cnx_by_id;
picohash_table * table_cnx_by_net;
} picoquic_quic;
/*
* Connection context, and links between context and addresses
*/
typedef struct _picoquic_cnx
{
picoquic_quic * quic;
struct _picoquic_cnx * next_in_table;
struct _picoquic_cnx_id * first_cnx_id;
struct _picoquic_net_id * first_net_id;
uint64_t last_sequence_sent;
uint64_t last_sequence_received;
} picoquic_cnx;
/*
* Structures used in the hash table of connections
*/
typedef struct _picoquic_cnx_id
{
struct _picoquic_cnx * next_in_bin;
/* QUIC context create and dispose */
picoquic_quic * picoquic_create(uint32_t nb_connections);
void picoquic_free(picoquic_quic * quic);
/* Context retrieval functions */
picoquic_cnx * get_cnx_by_id(picoquic_quic * quic, uint64_t cnx_id);
picoquic_cnx * get_cnx_by_net(picoquic_quic * quic, struct sockaddr* addr);
/* Parsing macros */
#define PICOPARSE_16(b) ((((uint16_t)(b)[0])<<8)|(b)[1])
#define PICOPARSE_32(b) ((((uint32_t)PICOPARSE_16(b))<<16)|PICOPARSE_16((b)+2))
#define PICOPARSE_64(b) ((((uint64_t)PICOPARSE_32(b))<<16)|PICOPARSE_32((b)+4))
} picoquic_cnx_id;
#ifdef __cplusplus
......
......@@ -131,8 +131,9 @@
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ctxhash.c" />
<ClCompile Include="quicctx.c" />
<ClCompile Include="packet.c" />
<ClCompile Include="parse_util.c" />
<ClCompile Include="picohash.c" />
</ItemGroup>
<ItemGroup>
......
......@@ -21,10 +21,13 @@
<ClCompile Include="packet.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ctxhash.c">
<ClCompile Include="picohash.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="picohash.c">
<ClCompile Include="parse_util.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="quicctx.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
......
#include "picoquic.h"
/*
* Structures used in the hash table of connections
*/
typedef struct _picoquic_cnx_id
{
uint64_t cnx_id;
picoquic_cnx * cnx;
struct picoquic_cnx_id * next_cnx_id;
} picoquic_cnx_id;
typedef struct _picoquic_net_id
{
uint64_t cnx_id;
struct sockaddr_storage saddr;
struct picoquic_cnx_id * next_cnx_id;
} picoquic_net_id;
/* Hash and compare for CNX hash tables */
static uint64_t picoquic_cnx_id_hash(void * key)
{
picoquic_cnx_id * cid = (picoquic_cnx_id *)key;
// TODO: should scramble the value for security and DOS protection
return cid->cnx_id;
}
static int picoquic_cnx_id_compare(void * key1, void * key2)
{
picoquic_cnx_id * cid1 = (picoquic_cnx_id *)key1;
picoquic_cnx_id * cid2 = (picoquic_cnx_id *)key2;
return (cid1->cnx_id == cid2->cnx_id) ? 0 : -1;
}
static uint64_t picoquic_net_id_hash(void * key)
{
picoquic_net_id * net = (picoquic_net_id *)key;
return picohash_bytes(&net->saddr, sizeof(net->saddr));
}
static int picoquic_net_id_compare(void * key1, void * key2)
{
picoquic_net_id * net1 = (picoquic_net_id *)key1;
picoquic_net_id * net2 = (picoquic_net_id *)key2;
return memcmp(&net1->saddr, &net2->saddr, sizeof(net1->saddr));
}
/* QUIC context create and dispose */
picoquic_quic * picoquic_create(uint32_t nb_connections)
{
picoquic_quic * quic = (picoquic_quic *)malloc(sizeof(picoquic_quic));
if (quic != NULL)
{
/* TODO: winsock init */
/* TODO: open UDP sockets - maybe */
/* TODO: chain of connections - maybe */
quic->table_cnx_by_id = picohash_create(nb_connections * 4,
picoquic_cnx_id_hash, picoquic_cnx_id_compare);
quic->table_cnx_by_net = picohash_create(nb_connections * 4,
picoquic_net_id_hash, picoquic_net_id_compare);
if (quic->table_cnx_by_id == NULL ||
quic->table_cnx_by_net == NULL)
{
picoquic_free(quic);
quic = NULL;
}
}
return quic;
}
void picoquic_free(picoquic_quic * quic)
{
if (quic != NULL)
{
/* TODO: delete all the connection contexts */
/* TODO: close the network connections */
if (quic->table_cnx_by_id != NULL)
{
picohash_delete(quic->table_cnx_by_id, 1);
}
if (quic->table_cnx_by_net != NULL)
{
picohash_delete(quic->table_cnx_by_net, 1);
}
}
}
/* Context retrieval functions */
picoquic_cnx * get_cnx_by_id(picoquic_quic * quic, uint64_t cnx_id)
{
picoquic_cnx * ret = NULL;
picohash_item * item;
picoquic_cnx_id key = { 0 };
key.cnx_id = cnx_id;
item = picohash_retrieve(quic->table_cnx_by_id, &key);
if (item != NULL)
{
ret = ((picoquic_cnx_id *)item->key)->cnx;
}
return ret;
}
picoquic_cnx * get_cnx_by_net(picoquic_quic * quic, struct sockaddr* addr)
{
picoquic_cnx * ret = NULL;
picohash_item * item;
picoquic_net_id key = { 0 };
if (addr->sa_family == AF_INET)
{
memcpy(&key.saddr, addr, sizeof(struct sockaddr_in));
}
else
{
memcpy(&key.saddr, addr, sizeof(struct sockaddr_in6));
}
item = picohash_retrieve(quic->table_cnx_by_id, &key);
if (item != NULL)
{
ret = ((picoquic_cnx_id *)item->key)->cnx;
}
return ret;
}
#include "../picoquic/picohash.h"
#include <stdlib.h>
#include <malloc.h>
struct hashtestkey
{
......@@ -20,7 +22,7 @@ static int hashtest_compare(void * v1, void *v2)
return (k1->x == k2->x) ? 0 : -1;
}
static picohash_item * hashtest_item(uint64_t x)
static struct hashtestkey * hashtest_item(uint64_t x)
{
struct hashtestkey * p = (struct hashtestkey *) malloc(sizeof(struct hashtestkey));
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment