diff options
Diffstat (limited to 'src/plugins/hs_apps/sapi/quic_echo.h')
-rw-r--r-- | src/plugins/hs_apps/sapi/quic_echo.h | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/src/plugins/hs_apps/sapi/quic_echo.h b/src/plugins/hs_apps/sapi/quic_echo.h new file mode 100644 index 00000000000..aec56d077f0 --- /dev/null +++ b/src/plugins/hs_apps/sapi/quic_echo.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <signal.h> + +#include <vnet/session/application_interface.h> + +#define vl_typedefs /* define message structures */ +#include <vpp/api/vpe_all_api_h.h> +#undef vl_typedefs + +/* declare message handlers for each api */ + +#define vl_endianfun /* define message structures */ +#include <vpp/api/vpe_all_api_h.h> +#undef vl_endianfun + +/* instantiate all the print functions we know about */ +#define vl_print(handle, ...) +#define vl_printfun +#include <vpp/api/vpe_all_api_h.h> +#undef vl_printfun + +#define NITER 4000000 +#define TIMEOUT 10.0 + +#define CHECK(expected, result, _fmt, _args...) \ + if (expected != result) \ + ECHO_FAIL ("expected %d, got %d : " _fmt, expected, result, ##_args); + +#define ECHO_FAIL(_fmt,_args...) \ + { \ + echo_main_t *em = &echo_main; \ + em->has_failed = 1; \ + em->time_to_stop = 1; \ + if (em->log_lvl > 0) \ + clib_warning ("ECHO-ERROR: "_fmt, ##_args); \ + } + +#define ECHO_LOG(lvl, _fmt,_args...) \ + { \ + echo_main_t *em = &echo_main; \ + if (em->log_lvl > lvl) \ + clib_warning (_fmt, ##_args); \ + } + +typedef struct +{ + CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); +#define _(type, name) type name; + foreach_app_session_field +#undef _ + u64 vpp_session_handle; + u64 bytes_sent; + u64 bytes_to_send; + volatile u64 bytes_received; + volatile u64 bytes_to_receive; + f64 start; + u32 listener_index; /* listener index in echo session pool */ + u32 idle_cycles; /* consecutive enq/deq with no data */ + volatile u64 accepted_session_count; /* sessions we accepted */ +} echo_session_t; + +typedef enum +{ + ECHO_NO_DATA_SOURCE, + ECHO_TEST_DATA_SOURCE, + ECHO_RX_DATA_SOURCE, + ECHO_INVALID_DATA_SOURCE +} data_source_t; + +enum echo_close_f_t +{ + ECHO_CLOSE_F_INVALID = 0, + ECHO_CLOSE_F_PASSIVE, /* wait for close msg */ + ECHO_CLOSE_F_ACTIVE, /* send close msg */ + ECHO_CLOSE_F_NONE, /* don't bother sending close msg */ +}; + +enum quic_session_type_t +{ + QUIC_SESSION_TYPE_QUIC, + QUIC_SESSION_TYPE_STREAM, + QUIC_SESSION_TYPE_LISTEN, +}; + +enum quic_session_state_t +{ + QUIC_SESSION_STATE_INITIAL, + QUIC_SESSION_STATE_READY, + QUIC_SESSION_STATE_AWAIT_CLOSING, /* Data transfer is done, wait for close evt */ + QUIC_SESSION_STATE_AWAIT_DATA, /* Peer closed, wait for outstanding data */ + QUIC_SESSION_STATE_CLOSING, /* told vpp to close */ + QUIC_SESSION_STATE_CLOSED, /* closed in vpp */ +}; + +typedef enum +{ + STATE_START, + STATE_ATTACHED, + STATE_LISTEN, + STATE_READY, + STATE_DATA_DONE, + STATE_DISCONNECTED, + STATE_DETACHED +} connection_state_t; + +typedef enum echo_test_evt_ +{ + ECHO_EVT_START = 1, /* app starts */ + ECHO_EVT_FIRST_QCONNECT = (1 << 1), /* First connect Quic session sent */ + ECHO_EVT_LAST_QCONNECTED = (1 << 2), /* All Quic session are connected */ + ECHO_EVT_FIRST_SCONNECT = (1 << 3), /* First connect Stream session sent */ + ECHO_EVT_LAST_SCONNECTED = (1 << 4), /* All Stream session are connected */ + ECHO_EVT_LAST_BYTE = (1 << 5), /* Last byte received */ + ECHO_EVT_EXIT = (1 << 6), /* app exits */ +} echo_test_evt_t; + +typedef struct _quic_echo_cb_vft +{ + void (*quic_connected_cb) (session_connected_msg_t * mp, u32 session_index); + void (*client_stream_connected_cb) (session_connected_msg_t * mp, + u32 session_index); + void (*server_stream_connected_cb) (session_connected_msg_t * mp, + u32 session_index); + void (*quic_accepted_cb) (session_accepted_msg_t * mp, u32 session_index); + void (*client_stream_accepted_cb) (session_accepted_msg_t * mp, + u32 session_index); + void (*server_stream_accepted_cb) (session_accepted_msg_t * mp, + u32 session_index); +} quic_echo_cb_vft_t; + + +typedef enum +{ + RETURN_PACKETS_NOTEST, + RETURN_PACKETS_LOG_WRONG, + RETURN_PACKETS_ASSERT, +} test_return_packets_t; + +typedef struct teardown_stat_ +{ + u32 q; /* quic sessions */ + u32 s; /* stream sessions */ +} teardown_stat_t; + +typedef struct +{ + svm_queue_t *vl_input_queue; /* vpe input queue */ + u32 my_client_index; /* API client handle */ + u8 *uri; /* The URI we're playing with */ + echo_session_t *sessions; /* Session pool */ + svm_msg_q_t *our_event_queue; /* Our event queue */ + clib_time_t clib_time; /* For deadman timers */ + u8 *socket_name; + int i_am_master; + u32 listen_session_index; /* Index of vpp listener session */ + + uword *session_index_by_vpp_handles; /* Hash table : quic_echo s_id -> vpp s_handle */ + clib_spinlock_t sid_vpp_handles_lock; /* Hash table lock */ + + uword *shared_segment_handles; /* Hash table : segment_names -> 1*/ + clib_spinlock_t segment_handles_lock; /* Hash table lock */ + quic_echo_cb_vft_t cb_vft; /* cb vft for QUIC scenarios */ + svm_msg_q_t *rpc_msq_queue; /* MQ between quic_echo threads */ + fifo_segment_main_t segment_main; + + /* State of the connection, shared between msg RX thread and main thread */ + volatile connection_state_t state; + volatile u8 time_to_stop; /* Signal variables */ + u8 has_failed; /* stores the exit code */ + + /** Flag that decides if socket, instead of svm, api is used to connect to + * vpp. If sock api is used, shm binary api is subsequently bootstrapped + * and all other messages are exchanged using shm IPC. */ + u8 use_sock_api; + + u8 *connect_test_data; + u8 test_return_packets; + u64 bytes_to_send; /* target per stream */ + u64 bytes_to_receive; /* target per stream */ + u32 fifo_size; + u32 rx_buf_size; + u32 tx_buf_size; + data_source_t data_source; /* Use no/dummy/mirrored data */ + u8 send_quic_disconnects; /* actively send disconnect */ + u8 send_stream_disconnects; /* actively send disconnect */ + u8 output_json; /* Output stats as JSON */ + u8 log_lvl; /* Verbosity of the logging */ + int max_test_msg; /* Limit the number of incorrect data messages */ + + u8 *appns_id; + u64 appns_flags; + u64 appns_secret; + + pthread_t *data_thread_handles; /* vec of data thread handles */ + pthread_t mq_thread_handle; /* Message queue thread handle */ + u32 *data_thread_args; + + u32 n_clients; /* Target number of QUIC sessions */ + u32 n_stream_clients; /* Target Number of STREAM sessions per QUIC session */ + volatile u32 n_quic_clients_connected; /* Number of connected QUIC sessions */ + volatile u32 n_clients_connected; /* Number of STREAM sessions connected */ + u32 n_rx_threads; /* Number of data threads */ + volatile u32 nxt_available_sidx; /* next unused prealloced session_index */ + + struct { + u64 tx_total; + u64 rx_total; + teardown_stat_t reset_count; /* received reset from vpp */ + teardown_stat_t close_count; /* received close from vpp */ + teardown_stat_t active_count; /* sent close to vpp */ + teardown_stat_t clean_count; /* cleaned up stale session */ + } stats; + + struct /* Event based timing : start & end depend on CLI specified events */ + { + f64 start_time; + f64 end_time; + u8 events_sent; + u8 start_event; + u8 end_event; + } timing; +} echo_main_t; + +typedef void (*echo_rpc_t) (void *arg, u32 opaque); + +typedef struct +{ + void *fp; + void *arg; + u32 opaque; +} echo_rpc_msg_t; |