Skip to content

Commit

Permalink
Merge pull request #214 from qzhuyan/dev/william/datagram-updates
Browse files Browse the repository at this point in the history
refactor:  QUIC datagram
  • Loading branch information
qzhuyan authored Sep 8, 2023
2 parents 7892d66 + 4265c04 commit a93004e
Show file tree
Hide file tree
Showing 13 changed files with 232 additions and 85 deletions.
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

0 comments on commit a93004e

Please sign in to comment.