Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: QUIC datagram #214

Merged
merged 4 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 2 additions & 65 deletions c_src/quicer_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ limitations under the License.
-------------------------------------------------------------------*/
#include "quicer_connection.h"
#include "quicer_ctx.h"
#include "quicer_dgram.h"
#include "quicer_tls.h"
#include <assert.h>
#include <openssl/pem.h>
Expand All @@ -26,15 +27,6 @@ EncodeHexBuffer(uint8_t *Buffer, uint8_t BufferLen, char *HexString);

extern inline const char *QuicStatusToString(QUIC_STATUS Status);

static void handle_dgram_state_event(QuicerConnCTX *c_ctx,
QUIC_CONNECTION_EVENT *Event);

static void handle_dgram_send_state_event(QuicerConnCTX *c_ctx,
QUIC_CONNECTION_EVENT *Event);

static void handle_dgram_recv_event(QuicerConnCTX *c_ctx,
QUIC_CONNECTION_EVENT *Event);

static QUIC_STATUS
handle_connection_event_connected(QuicerConnCTX *c_ctx,
QUIC_CONNECTION_EVENT *Event);
Expand Down Expand Up @@ -1039,60 +1031,6 @@ async_handshake_1(ErlNifEnv *env,
return res;
}

void
handle_dgram_state_event(QuicerConnCTX *c_ctx, QUIC_CONNECTION_EVENT *Event)
{
if (Event->DATAGRAM_STATE_CHANGED.SendEnabled == 1)
{
ErlNifEnv *env = c_ctx->env;
int max_len = Event->DATAGRAM_STATE_CHANGED.MaxSendLength;
enif_send(NULL,
&(c_ctx->owner->Pid),
NULL,
enif_make_tuple3(env,
ATOM_QUIC,
ATOM_DGRAM_MAX_LEN,
enif_make_int(env, max_len)));
}
}

void
handle_dgram_send_state_event(QuicerConnCTX *c_ctx,
QUIC_CONNECTION_EVENT *Event)
{
ErlNifEnv *env = c_ctx->env;
if (Event->DATAGRAM_SEND_STATE_CHANGED.State == QUIC_DATAGRAM_SEND_SENT)
{
QuicerDgramSendCTX *dgram_send_ctx
= (QuicerDgramSendCTX *)(Event->DATAGRAM_SEND_STATE_CHANGED
.ClientContext);
enif_send(NULL,
&dgram_send_ctx->caller,
NULL,
enif_make_tuple3(env,
ATOM_QUIC,
ATOM_SEND_DGRAM_COMPLETE,
enif_make_resource(env, c_ctx)));
destroy_dgram_send_ctx(dgram_send_ctx);
}
}

void
handle_dgram_recv_event(QuicerConnCTX *c_ctx, QUIC_CONNECTION_EVENT *Event)
{
ErlNifEnv *env = c_ctx->env;
ErlNifBinary bin;
ERL_NIF_TERM report;
enif_alloc_binary(Event->DATAGRAM_RECEIVED.Buffer->Length, &bin);
CxPlatCopyMemory(bin.data,
Event->DATAGRAM_RECEIVED.Buffer->Buffer,
Event->DATAGRAM_RECEIVED.Buffer->Length);
bin.size = Event->DATAGRAM_RECEIVED.Buffer->Length;
report = enif_make_tuple3(
env, ATOM_QUIC, ATOM_DGRAM, enif_make_binary(env, &bin));
enif_send(NULL, &(c_ctx->owner->Pid), NULL, report);
}

/* handle conn connected event and deliver the message to the conn owner
{quic, connected, connection_handle(), #{ is_resumed := boolean()
, alpns = binary() | undefined
Expand Down Expand Up @@ -1412,8 +1350,7 @@ static QUIC_STATUS
handle_connection_event_datagram_state_changed(QuicerConnCTX *c_ctx,
QUIC_CONNECTION_EVENT *Event)
{
assert(QUIC_CONNECTION_EVENT_DATAGRAM_STATE_CHANGED == Event->Type);
handle_dgram_state_event(c_ctx, Event);
handle_dgram_state_changed_event(c_ctx, Event);
return QUIC_STATUS_SUCCESS;
}

Expand Down
116 changes: 116 additions & 0 deletions c_src/quicer_dgram.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ limitations under the License.

#include "quicer_dgram.h"

static ERL_NIF_TERM atom_dgram_send_state(uint16_t state);

ERL_NIF_TERM
send_dgram(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
Expand Down Expand Up @@ -100,3 +102,117 @@ send_dgram(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
return SUCCESS(ETERM_UINT_64(bin->size));
}
}

void
handle_dgram_state_changed_event(QuicerConnCTX *c_ctx,
QUIC_CONNECTION_EVENT *Event)
{
assert(QUIC_CONNECTION_EVENT_DATAGRAM_STATE_CHANGED == Event->Type);
ErlNifEnv *env = c_ctx->env;
uint16_t max_len = Event->DATAGRAM_STATE_CHANGED.MaxSendLength;

ERL_NIF_TERM ConnHandle = enif_make_resource(c_ctx->env, c_ctx);
ERL_NIF_TERM props_name[] = { ATOM_DGRAM_MAX_LEN, ATOM_DGRAM_SEND_ENABLED };
ERL_NIF_TERM props_value[]
= { enif_make_uint(env, max_len),
ATOM_BOOLEAN(Event->DATAGRAM_STATE_CHANGED.SendEnabled) };

ERL_NIF_TERM report = make_event_with_props(c_ctx->env,
ATOM_DGRAM_STATE_CHANGED,
ConnHandle,
props_name,
props_value,
2);

enif_send(NULL, &(c_ctx->owner->Pid), NULL, report);
}

void
handle_dgram_send_state_event(QuicerConnCTX *c_ctx,
QUIC_CONNECTION_EVENT *Event)
{
assert(QUIC_CONNECTION_EVENT_DATAGRAM_SEND_STATE_CHANGED == Event->Type);
// result of previous unreliable datagram send
QUIC_DATAGRAM_SEND_STATE state = Event->DATAGRAM_SEND_STATE_CHANGED.State;
QuicerDgramSendCTX *dgram_send_ctx
= (QuicerDgramSendCTX *)(Event->DATAGRAM_SEND_STATE_CHANGED
.ClientContext);

ERL_NIF_TERM ConnHandle = enif_make_resource(c_ctx->env, c_ctx);
ERL_NIF_TERM props_name[] = { ATOM_STATE };
ERL_NIF_TERM props_value[] = { atom_dgram_send_state(state) };
ERL_NIF_TERM report = make_event_with_props(c_ctx->env,
ATOM_DGRAM_SEND_STATE,
ConnHandle,
props_name,
props_value,
1);
enif_send(NULL, &dgram_send_ctx->caller, NULL, report);

if (QUIC_DATAGRAM_SEND_LOST_DISCARDED == state
|| QUIC_DATAGRAM_SEND_ACKNOWLEDGED == state
|| QUIC_DATAGRAM_SEND_ACKNOWLEDGED_SPURIOUS == state
|| QUIC_DATAGRAM_SEND_CANCELED == state)
{
// Destroy only when in final state
destroy_dgram_send_ctx(dgram_send_ctx);
}
}

void
handle_dgram_recv_event(QuicerConnCTX *c_ctx, QUIC_CONNECTION_EVENT *Event)
{
ErlNifEnv *env = c_ctx->env;
ERL_NIF_TERM bin;
ERL_NIF_TERM report;

size_t len = Event->DATAGRAM_RECEIVED.Buffer->Length;
unsigned char *buff = enif_make_new_binary(env, len, &bin);
if (buff)
{
CxPlatCopyMemory(buff, Event->DATAGRAM_RECEIVED.Buffer->Buffer, len);

ERL_NIF_TERM ConnHandle = enif_make_resource(c_ctx->env, c_ctx);
report = enif_make_tuple4(
env,
ATOM_QUIC,
bin,
ConnHandle,
enif_make_uint(env, Event->DATAGRAM_RECEIVED.Flags));
enif_send(NULL, &c_ctx->owner->Pid, NULL, report);
}
}

ERL_NIF_TERM
atom_dgram_send_state(uint16_t state)
{
ERL_NIF_TERM ret = ATOM_UNDEFINED;
switch (state)
{
case QUIC_DATAGRAM_SEND_UNKNOWN:
ret = ATOM_QUIC_DATAGRAM_SEND_UNKNOWN;
break;
case QUIC_DATAGRAM_SEND_SENT:
ret = ATOM_QUIC_DATAGRAM_SEND_SENT;
break;
case QUIC_DATAGRAM_SEND_LOST_SUSPECT:
ret = ATOM_QUIC_DATAGRAM_SEND_LOST_SUSPECT;
break;
case QUIC_DATAGRAM_SEND_LOST_DISCARDED:
ret = ATOM_QUIC_DATAGRAM_SEND_LOST_DISCARDED;
break;
case QUIC_DATAGRAM_SEND_ACKNOWLEDGED:
ret = ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED;
break;
case QUIC_DATAGRAM_SEND_ACKNOWLEDGED_SPURIOUS:
ret = ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED_SPURIOUS;
break;
case QUIC_DATAGRAM_SEND_CANCELED:
ret = ATOM_QUIC_DATAGRAM_SEND_CANCELED;
break;
default:
ret = ATOM_UNDEFINED;
break;
}
return ret;
}
10 changes: 9 additions & 1 deletion c_src/quicer_dgram.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,12 @@ limitations under the License.

ERL_NIF_TERM send_dgram(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);

#endif // __QUICER_DGRAM_H_
void handle_dgram_send_state_event(QuicerConnCTX *c_ctx,
QUIC_CONNECTION_EVENT *Event);
void handle_dgram_state_changed_event(QuicerConnCTX *c_ctx,
QUIC_CONNECTION_EVENT *Event);

void handle_dgram_recv_event(QuicerConnCTX *c_ctx,
QUIC_CONNECTION_EVENT *Event);

#endif // __QUICER_DGRAM_H_
14 changes: 14 additions & 0 deletions c_src/quicer_eterms.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,11 +304,14 @@ extern ERL_NIF_TERM ATOM_STREAMS_AVAILABLE;
extern ERL_NIF_TERM ATOM_PEER_NEEDS_STREAMS;
extern ERL_NIF_TERM ATOM_START_COMPLETE;
extern ERL_NIF_TERM ATOM_SEND_COMPLETE;
extern ERL_NIF_TERM ATOM_DGRAM_SEND_STATE;
extern ERL_NIF_TERM ATOM_SEND_DGRAM_COMPLETE;
extern ERL_NIF_TERM ATOM_EINVAL;
extern ERL_NIF_TERM ATOM_QUIC;
extern ERL_NIF_TERM ATOM_DGRAM;
extern ERL_NIF_TERM ATOM_DGRAM_STATE_CHANGED;
extern ERL_NIF_TERM ATOM_DGRAM_MAX_LEN;
extern ERL_NIF_TERM ATOM_DGRAM_SEND_ENABLED;
extern ERL_NIF_TERM ATOM_PASSIVE;
extern ERL_NIF_TERM ATOM_QUIC_EVENT_MASK;
extern ERL_NIF_TERM ATOM_NST_RECEIVED;
Expand Down Expand Up @@ -362,6 +365,7 @@ extern ERL_NIF_TERM ATOM_IS_ORPHAN;
extern ERL_NIF_TERM ATOM_BIDI_STREAMS;
extern ERL_NIF_TERM ATOM_UNIDI_STREAMS;
extern ERL_NIF_TERM ATOM_STATUS;
extern ERL_NIF_TERM ATOM_STATE;
extern ERL_NIF_TERM ATOM_STREAM_ID;
extern ERL_NIF_TERM ATOM_IS_PEER_ACCEPTED;
extern ERL_NIF_TERM ATOM_IS_CONN_SHUTDOWN;
Expand All @@ -376,6 +380,16 @@ extern ERL_NIF_TERM ATOM_CLIENT_ALPNS;
extern ERL_NIF_TERM ATOM_CRYPTO_BUFFER;

extern ERL_NIF_TERM ATOM_UNDEFINED;

// Datagram Send State
extern ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_UNKNOWN;
extern ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_SENT;
extern ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_LOST_SUSPECT;
extern ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_LOST_DISCARDED;
extern ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED;
extern ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED_SPURIOUS;
extern ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_CANCELED;

/*----------------------------------------------------------*/
/* ATOMS ends here */
/*----------------------------------------------------------*/
Expand Down
25 changes: 25 additions & 0 deletions c_src/quicer_nif.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ ERL_NIF_TERM ATOM_STREAMS_AVAILABLE;
ERL_NIF_TERM ATOM_PEER_NEEDS_STREAMS;
ERL_NIF_TERM ATOM_START_COMPLETE;
ERL_NIF_TERM ATOM_SEND_COMPLETE;
ERL_NIF_TERM ATOM_DGRAM_SEND_STATE;
ERL_NIF_TERM ATOM_SEND_DGRAM_COMPLETE;
ERL_NIF_TERM ATOM_EINVAL;
ERL_NIF_TERM ATOM_QUIC;
Expand All @@ -329,7 +330,9 @@ ERL_NIF_TERM ATOM_QUIC_EVENT_MASK;
ERL_NIF_TERM ATOM_NST_RECEIVED;
ERL_NIF_TERM ATOM_NST;
ERL_NIF_TERM ATOM_DGRAM;
ERL_NIF_TERM ATOM_DGRAM_STATE_CHANGED;
ERL_NIF_TERM ATOM_DGRAM_MAX_LEN;
ERL_NIF_TERM ATOM_DGRAM_SEND_ENABLED;
ERL_NIF_TERM ATOM_DEBUG;
ERL_NIF_TERM ATOM_ONCE;
ERL_NIF_TERM ATOM_NEW_CONN;
Expand Down Expand Up @@ -379,6 +382,7 @@ ERL_NIF_TERM ATOM_IS_ORPHAN;
ERL_NIF_TERM ATOM_BIDI_STREAMS;
ERL_NIF_TERM ATOM_UNIDI_STREAMS;
ERL_NIF_TERM ATOM_STATUS;
ERL_NIF_TERM ATOM_STATE;
ERL_NIF_TERM ATOM_STREAM_ID;
ERL_NIF_TERM ATOM_IS_PEER_ACCEPTED;
ERL_NIF_TERM ATOM_IS_CONN_SHUTDOWN;
Expand All @@ -394,6 +398,15 @@ ERL_NIF_TERM ATOM_CLIENT_ALPNS;
ERL_NIF_TERM ATOM_CRYPTO_BUFFER;
ERL_NIF_TERM ATOM_UNDEFINED;

// Datagram Send State
ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_UNKNOWN;
ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_SENT;
ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_LOST_SUSPECT;
ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_LOST_DISCARDED;
ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED;
ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED_SPURIOUS;
ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_CANCELED;

// Mirror 'status' in msquic_linux.h

/*
Expand Down Expand Up @@ -682,6 +695,7 @@ ERL_NIF_TERM ATOM_UNDEFINED;
ATOM(ATOM_PEER_NEEDS_STREAMS, peer_needs_streams); \
ATOM(ATOM_START_COMPLETE, start_completed); \
ATOM(ATOM_SEND_COMPLETE, send_complete); \
ATOM(ATOM_DGRAM_SEND_STATE, dgram_send_state); \
ATOM(ATOM_SEND_DGRAM_COMPLETE, send_dgram_completed); \
ATOM(ATOM_EINVAL, einval); \
ATOM(ATOM_QUIC, quic); \
Expand All @@ -690,7 +704,9 @@ ERL_NIF_TERM ATOM_UNDEFINED;
ATOM(ATOM_NST_RECEIVED, nst_received); \
ATOM(ATOM_NST, nst); \
ATOM(ATOM_DGRAM, dgram); \
ATOM(ATOM_DGRAM_STATE_CHANGED, dgram_state_changed); \
ATOM(ATOM_DGRAM_MAX_LEN, dgram_max_len); \
ATOM(ATOM_DGRAM_SEND_ENABLED, dgram_send_enabled); \
ATOM(ATOM_DEBUG, debug); \
ATOM(ATOM_ONCE, once); \
ATOM(ATOM_NEW_CONN, new_conn); \
Expand Down Expand Up @@ -727,6 +743,7 @@ ERL_NIF_TERM ATOM_UNDEFINED;
ATOM(ATOM_BIDI_STREAMS, bidi_streams); \
ATOM(ATOM_UNIDI_STREAMS, unidi_streams); \
ATOM(ATOM_STATUS, status); \
ATOM(ATOM_STATE, state); \
ATOM(ATOM_STREAM_ID, stream_id); \
ATOM(ATOM_IS_PEER_ACCEPTED, is_peer_accepted); \
ATOM(ATOM_IS_CONN_SHUTDOWN, is_conn_shutdown); \
Expand All @@ -739,6 +756,14 @@ ERL_NIF_TERM ATOM_UNDEFINED;
ATOM(ATOM_SERVER_NAME, server_name); \
ATOM(ATOM_CLIENT_ALPNS, client_alpns); \
ATOM(ATOM_CRYPTO_BUFFER, crypto_buffer); \
ATOM(ATOM_QUIC_DATAGRAM_SEND_UNKNOWN, dgram_send_unknown); \
ATOM(ATOM_QUIC_DATAGRAM_SEND_SENT, dgram_send_sent); \
ATOM(ATOM_QUIC_DATAGRAM_SEND_LOST_SUSPECT, dgram_send_lost_suspect); \
ATOM(ATOM_QUIC_DATAGRAM_SEND_LOST_DISCARDED, dgram_send_lost_discarded); \
ATOM(ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED, dgram_send_acknowledged); \
ATOM(ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED_SPURIOUS, \
dgram_send_acknowledged_spurious); \
ATOM(ATOM_QUIC_DATAGRAM_SEND_CANCELED, dgram_send_canceled); \
ATOM(ATOM_UNDEFINED, undefined);

HQUIC GRegistration = NULL;
Expand Down
Loading