diff options
author | Luca Muscariello <lumuscar+fdio@cisco.com> | 2019-03-23 14:13:53 +0100 |
---|---|---|
committer | Angelo Mantellini <manangel@cisco.com> | 2019-03-24 14:11:17 +0100 |
commit | eb323e056e747d71867cf965434811c1de925de2 (patch) | |
tree | 23a6096823d795efe448559cf0409a18ab47932d /hicn-light/src/hicn/api/api.h | |
parent | 43562f9f02d35e5d540ab4028a0326c0c7cd4898 (diff) |
[HICN-141] Definition of a C API for hicn-light
Change-Id: Id861f0abe58b1e3c9ba8cc76701da0f9c6801748
Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com>
Signed-off-by: Angelo Mantellini <manangel@cisco.com>
Diffstat (limited to 'hicn-light/src/hicn/api/api.h')
-rw-r--r-- | hicn-light/src/hicn/api/api.h | 580 |
1 files changed, 580 insertions, 0 deletions
diff --git a/hicn-light/src/hicn/api/api.h b/hicn-light/src/hicn/api/api.h new file mode 100644 index 000000000..e2358167c --- /dev/null +++ b/hicn-light/src/hicn/api/api.h @@ -0,0 +1,580 @@ +/* + * Copyright (c) 2017-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. + */ + +/** + * \file api.h + * \brief hICN control library API + */ + +#ifndef HICNTRL_API +#define HICNTRL_API + +#include <stdbool.h> +#include <stdint.h> + +#include <hicn/api/face.h> + +/** + * This allows to selectively define convenience types to avoid any collision + * when using the library in conjunction with other frameworks including similar + * defines + */ +#ifdef _HICNTRL_NO_DEFS +#define _HICNTRL_NO_DEF_TYPES +#define _HICNTRL_NO_DEF_IPADDR +#define _HICNTRL_NO_DEF_UNIONCAST +#endif + +#ifndef _HICNTRL_NO_DEF_TYPES +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +#endif /* _HICNTRL_NO_DEF_TYPES */ + +#ifndef _HICNTRL_NO_DEF_IPADDR +#include <hicn/api/ip_address.h> +#endif /* _HICNTRL_NO_DEF_IPADDR */ + +#ifndef _HICNTRL_NO_DEF_UNIONCAST +/* Helper for avoiding warnings about type-punning */ +#define UNION_CAST(x, destType) \ + (((union { \ + __typeof__(x) a; \ + destType b; \ + })x) \ + .b) +#endif /* _HICNTRL_NO_DEF_UNIONCAST */ + +/****************************************************************************** + * Message helper types and aliases + ******************************************************************************/ + +#define foreach_command \ + _(UNDEFINED) \ + _(CREATE) \ + _(DELETE) \ + _(LIST) \ + _(SET) \ + _(N) + +typedef enum { +#define _(x) ACTION_##x, + foreach_command +#undef _ +} hc_action_t; + +/** + * \brief hICN control message header + */ +typedef struct hc_msg_s hc_msg_t; + +/****************************************************************************** + * Control Data + ******************************************************************************/ + +struct hc_data_s; +typedef int (*data_callback_t)(struct hc_data_s *, void *); + +/** + * \brief Holds the results of an hICN control request + */ +typedef struct hc_data_s { + size_t size; + size_t max_size_log; + size_t in_element_size; + size_t out_element_size; + u8 command_id; /**< Expected message type (should give element size) */ + u8 *buffer; + bool complete; + + /* Callbacks */ + data_callback_t + complete_cb; // XXX int (*complete_cb)(struct hc_data_s * data); + void *complete_cb_data; +} hc_data_t; + +/** + * Create a structure holding the results of an hICN control request. + * \result The newly create data structure. + */ +hc_data_t *hc_data_create(size_t in_element_size, size_t out_element_size); + +/** + * Free a structure holding the results of an hICN control request. + * \param [in] data - The data structure to free. + */ +void hc_data_free(hc_data_t *data); + +/** + * \brief Adds many new results at the end of the data structure, eventually + * allocating buffer space for it. + * \param [in] data - The data structure to which to add elements. + * \param [in] elements - The array of elements to add. + * \param [in] count - The number of elements to add. + * \return Error code + * + * NOTE: The size of the element should match the one declared at structure + * initialization. + */ +int hc_data_push_many(hc_data_t *data, const void *elements, size_t count); + +/** + * \brief Adds a new result at the end of the data structure, eventually + * allocating buffer space for it. + * \param [in] data - The data structure to which to add an element. + * \param [in] element - The element to add + * \return Error code + * + * NOTE: The size of the element should match the one declared at structure + * initialization. + */ +int hc_data_push(hc_data_t *data, const void *element); + +/** + * \brief Configure a callback (along with private data) to be called upon + * completion of a request + * \param [in] data - hICN control data + * \param [in] cb - Callback function + * \param [in] cb_data - Callback private data + */ +int hc_data_set_callback(hc_data_t *data, data_callback_t cb, void *cb_data); + +/** + * \brief Mark the data structure as complete. + * \param [in] data - The data structure to which to add an element. + * \return The error code resulting from callback execution if any. 0 is + * returned if the callback executed successfully, or if no callback were + * defined. + */ +int hc_data_set_complete(hc_data_t *data); + +/** + * \brief Reset the data structure holding control data + * \param [in] data - hICN control data + * \return Error code + */ +int hc_data_reset(hc_data_t *data); + +/** + * \brief Find en element in the data structure + * \param [in] data - The data structure in which to find + * \param [in] element - The element to find + * \param [in] cmp - The element compare function + * \param [out] found - A pointer to the element, or NULL if not found. + * \return Error code + */ +int hc_data_find(hc_data_t *data, const void *element, cmp_t cmp, void **found); + +/****************************************************************************** + * Control socket + ******************************************************************************/ + +/* This should be at least equal to the maximum packet size */ +#define RECV_BUFLEN 8192 + +/** + * \brief Holds the state of an hICN control socket + */ +typedef struct { + char *url; + int fd; + u32 seq; + + /* Partial receive buffer */ + u8 buf[RECV_BUFLEN]; + size_t roff; /**< Read offset */ + size_t woff; /**< Write offset */ + + /* + * Because received messages are potentially unbounded in size, we might not + * guarantee that we can store a full packet before processing it. We must + * implement a very simple state machine remembering the current parsing + * status in order to partially process the packet. + */ + size_t remaining; + u32 send_id; + u32 send_seq; + u32 recv_seq; +} hc_sock_t; + +/** + * \brief Create an hICN control socket using the specified URL. + * \param [in] url - The URL to connect to. + * \return an hICN control socket + */ +hc_sock_t *hc_sock_create_url(const char *url); + +/** + * \brief Create an hICN control socket using the default connection type. + * \return an hICN control socket + */ +hc_sock_t *hc_sock_create(void); + +/** + * \brief Frees an hICN control socket + */ +void hc_sock_free(hc_sock_t *s); + +/** + * \brief Sets the socket as non-blocking + * \return Error code + */ +int hc_sock_set_nonblocking(hc_sock_t *s); + +/** + * \brief Connect the socket + * \return Error code + */ +int hc_sock_connect(hc_sock_t *s); + +/** + * \brief Return the offset and size of available buffer space + * \param [in] sock - hICN control socket + * \param [out] buffer - Offset in buffer + * \param [out] size - Remaining size + * \return Error code + */ +int hc_sock_get_available(hc_sock_t *s, u8 **buffer, size_t *size); + +/** + * \brief Write/read iexchance on the control socket (internal helper function) + * \param [in] sock - hICN control socket + * \param [in] msg - Message to send + * \param [in] msglen - Length of the message to send + * \return Error code + */ +int hc_sock_send(hc_sock_t *s, hc_msg_t *msg, size_t msglen); + +/** + * \brief Helper for reading socket contents + * \param [in] sock - hICN control socket + * \param [in] data - Result data buffer + * \param [in] parse - Parse function to convert remote types into lib native + * types, or NULL not to perform any translation. + * \return Error code + */ +int hc_sock_recv(hc_sock_t *s, hc_data_t *data); + +/** + * \brief Processing data received by socket + * \param [in] sock - hICN control socket + * \param [in] data - Result data buffer + * \param [in] parse - Parse function to convert remote types into lib native + * types, or NULL not to perform any translation. + * \return Error code + */ +int hc_sock_process(hc_sock_t *s, hc_data_t *data, + int (*parse)(const u8 *src, u8 *dst)); + +/** + * \brief Reset the state of the sock (eg. to handle a reconnecton) + * \param [in] sock - hICN control socket + * \return Error code + */ +int hc_sock_reset(hc_sock_t *s); + +/****************************************************************************** + * Command-specific structures and functions + ******************************************************************************/ + +/* + * The following definitions are organized by sections each dealing with a + * specific object being manipulated. All follow a similar structure. + * + * TYPE DEFINITIONS AND ALIASES + * + * We redefine command struct: + * - for uniformization + * - to use enum instead of type specifiers more appropriate for packet format + * - to use more flexible types such as for manipulating IP addresses + * - host endianness + * - more intuitive field name, ordering, consistency, and hierarchy removal + * - to have command types in between add/list/... commands + * + * COMMAND IMPLEMENTATION + * + * All commands return information in a common format + * + * TODO describe + explain for commands with only return code. + * + * RETURN DATA FIXME + * + * \param [out] pdata - Pointer to the structure storing the results of the call + * (NULL if no data has been received). If the pointer is NULL, no result will + * be stored and only the error code will be exposed to the caller. It is + * expected that the caller frees this structure using hc_data_free() after + * usage. + * \see hc_data_free. + * + * PARSING + * + * While this is not made mandatory by the library, the returned data can be + * converted to the library's own data structures as described before. + * + * ITERATORS + * + * Macros are defined to facilitate iteration on the returned data structures. + */ + +#ifndef SPACES +#define SPACES(x) x +#endif +#ifndef SPACE +#define SPACE SPACES(1) +#endif +#ifndef NULLTERM +#define NULLTERM 1 +#endif + +#define NAME_LEN 16 /* NULL-terminated right ? */ +#define MAXSZ_HC_NAME_ NAME_LEN +#define MAXSZ_HC_NAME MAXSZ_HC_NAME_ + NULLTERM + +#define MAXSZ_HC_ID_ 10 /* Number of digits for MAX_INT */ +#define MAXSZ_HC_ID MAXSZ_HC_ID_ + NULLTERM + +#define MAXSZ_HC_PROTO_ 8 /* inetX:// */ +#define MAXSZ_HC_PROTO MAXSZ_HC_PROTO_ + NULLTERM + +#define MAXSZ_HC_URL4_ MAXSZ_HC_PROTO_ + MAXSZ_IP4_ADDRESS_ + MAXSZ_PORT_ +#define MAXSZ_HC_URL6_ MAXSZ_HC_PROTO_ + MAXSZ_IP6_ADDRESS_ + MAXSZ_PORT_ +#define MAXSZ_HC_URL_ MAXSZ_HC_URL6_ +#define MAXSZ_HC_URL4 MAXSZ_HC_URL4_ + NULLTERM +#define MAXSZ_HC_URL6 MAXSZ_HC_URL6_ + NULLTERM +#define MAXSZ_HC_URL MAXSZ_HC_URL_ + NULLTERM + +size_t hc_url_snprintf(char *s, size_t size, int family, + ip_address_t *ip_address, u16 port); + +#define foreach_type(TYPE, VAR, data) \ + for (TYPE *VAR = (TYPE *)data->buffer; \ + VAR < (TYPE *)(data->buffer + data->size * data->out_element_size); \ + VAR++) + +/** + * New type is defined to reconciliate different enum for add and list. + * Also, values not implemented have been removed for clarity. + */ +#define foreach_connection_type \ + _(UNDEFINED) \ + _(TCP) \ + _(UDP) \ + _(HICN) \ + _(N) + +typedef enum { +#define _(x) CONNECTION_TYPE_##x, + foreach_connection_type +#undef _ +} hc_connection_type_t; + +#define MAXSZ_HC_CONNECTION_TYPE_ 9 +#define MAXSZ_HC_CONNECTION_TYPE MAXSZ_HC_CONNECTION_TYPE_ + NULLTERM + +extern const char *connection_type_str[]; + +hc_connection_type_t connection_type_from_str(const char *str); + +#define foreach_connection_state \ + _(UNDEFINED) \ + _(UP) \ + _(DOWN) \ + _(N) + +typedef enum { +#define _(x) CONNECTION_STATE_##x, + foreach_connection_state +#undef _ +} hc_connection_state_t; + +#define MAXSZ_HC_CONNECTION_STATE_ 9 +#define MAXSZ_HC_CONNECTION_STATE MAXSZ_HC_CONNECTION_STATE_ + NULLTERM + +extern const char *connection_state_str[]; + +typedef int (*HC_PARSE)(const u8 *, u8 *); + +/*----------------------------------------------------------------------------* + * Listeners + *----------------------------------------------------------------------------*/ + +typedef struct { + char name[NAME_LEN]; /* K.w */ // XXX clarify what used for + u32 conn_id; /* Kr. */ + hc_connection_type_t type; /* .rw */ + int family; /* .rw */ + ip_address_t local_addr; /* .rw */ + u16 local_port; /* .rw */ +} hc_listener_t; + +int hc_parse_listener(void *in, hc_listener_t *listener); + +int hc_listener_create(hc_sock_t *s, hc_listener_t *listener); +// XXX int hc_listener_delete(hc_sock_t * s, hc_listener_t * listener); +int hc_listener_list(hc_sock_t *s, hc_data_t **pdata); + +#define foreach_listener(VAR, data) foreach_type(hc_listener_t, VAR, data) + +#define MAXSZ_HC_LISTENER_ MAXSZ_HC_URL_ + SPACE + MAXSZ_HC_CONNECTION_TYPE_ +#define MAXSZ_HC_LISTENER MAXSZ_HC_LISTENER_ + NULLTERM + +int hc_listener_cmp(const hc_listener_t *l1, const hc_listener_t *l2); + +size_t hc_listener_snprintf(char *s, size_t size, hc_listener_t *listener); + +/*----------------------------------------------------------------------------* + * Connections + *----------------------------------------------------------------------------*/ + +typedef struct { + u32 id; /* Kr. */ + char name[NAME_LEN]; /* K.w */ + hc_connection_type_t type; /* .rw */ + int family; /* .rw */ + ip_address_t local_addr; /* .rw */ + u16 local_port; /* .rw */ + ip_address_t remote_addr; /* .rw */ + u16 remote_port; /* .rw */ +#ifdef WITH_POLICY + face_state_t desired_state; /* .rw */ + face_tags_t tags; /* .rw */ +#endif /* WITH_POLICY */ + hc_connection_state_t state; /* .r. */ +} hc_connection_t; + +int hc_parse_connection(void *in, hc_connection_t *connection); + +int hc_connection_create(hc_sock_t *s, hc_connection_t *connection); +int hc_connection_delete(hc_sock_t *s, hc_connection_t *connection); +/* +int hc_connection_remove_by_id(hc_sock_t * s, char * name); +int hc_connection_remove_by_name(hc_sock_t * s, char * name); +*/ +#ifdef WITH_POLICY +int hc_connection_set_state(hc_sock_t *s, const char *conn_id_or_name, + face_state_t state); +#endif /* WITH_POLICY */ +int hc_connection_list(hc_sock_t *s, hc_data_t **pdata); + +#define foreach_connection(VAR, data) foreach_type(hc_connection_t, VAR, data) + +#define MAXSZ_HC_CONNECTION_ \ + MAXSZ_HC_CONNECTION_STATE_ + 2 * MAXSZ_HC_URL_ + MAXSZ_HC_CONNECTION_TYPE_ + \ + SPACES(3) +#define MAXSZ_HC_CONNECTION MAXSZ_HC_CONNECTION_ + NULLTERM + +size_t hc_connection_snprintf(char *s, size_t size, + hc_connection_t *connection); + +/*----------------------------------------------------------------------------* + * Routes + *----------------------------------------------------------------------------*/ + +typedef struct { + u8 conn_id; /* Kr. */ + char conn_name[NAME_LEN]; /* K.w */ + int family; /* Krw */ + ip_address_t remote_addr; /* krw */ + u8 len; /* krw */ + u16 cost; /* .rw */ +} hc_route_t; + +int hc_parse_route(void *in, hc_route_t *route); + +int hc_route_create(hc_sock_t *s, hc_route_t *route); +int hc_route_delete(hc_sock_t *s, hc_route_t *route); +int hc_route_list(hc_sock_t *s, hc_data_t **pdata); + +#define foreach_route(VAR, data) foreach_type(hc_route_t, VAR, data) + +#define MAXSZ_HC_ROUTE_ 0 +#define MAXSZ_HC_ROUTE MAXSZ_HC_ROUTE_ + NULLTERM + +size_t hc_route_snprintf(char *s, size_t size, hc_route_t *route); + +/*----------------------------------------------------------------------------* + * Faces + * + * A face is an abstraction introduced by the control library to abstract the + * forwarder implementation details. It encompasses connections and listeners + * and ensures the right dependencies are enforced, eg that we always have a + * listener when a connection is created. + * + *----------------------------------------------------------------------------*/ + +typedef struct { + u32 id; + char name[NAME_LEN]; + face_t face; // or embed ? + // face_id_t parent; /* Pointer from connection to listener */ +} hc_face_t; + +int hc_face_create(hc_sock_t *s, hc_face_t *face); +int hc_face_delete(hc_sock_t *s, hc_face_t *face); +int hc_face_list(hc_sock_t *s, hc_data_t **pdata); + +#define foreach_face(VAR, data) foreach_type(hc_face_t, VAR, data) + +#define MAXSZ_HC_FACE_ 0 +#define MAXSZ_HC_FACE MAXSZ_HC_FACE_ + NULLTERM + +size_t hc_face_snprintf(char *s, size_t size, hc_face_t *face); + +/*----------------------------------------------------------------------------* + * Cache + *----------------------------------------------------------------------------*/ + +int hc_cache_set_store(hc_sock_t *s, int enabled); +int hc_cache_set_serve(hc_sock_t *s, int enabled); + +/*----------------------------------------------------------------------------* + * Punting + *----------------------------------------------------------------------------*/ + +int hc_punting_create(hc_sock_t *s /* XXX */); + +/*----------------------------------------------------------------------------* + * Strategy + *----------------------------------------------------------------------------*/ + +// per prefix +int hc_strategy_set(hc_sock_t *s /* XXX */); + +/*----------------------------------------------------------------------------* + * FIB + *----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------* + * PIT + *----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------* + * WLDR + *----------------------------------------------------------------------------*/ + +// per connection +int hc_wldr_set(hc_sock_t *s /* XXX */); + +/*----------------------------------------------------------------------------* + * MAP-Me + *----------------------------------------------------------------------------*/ + +int hc_mapme_set(hc_sock_t *s, int enabled); +int hc_mapme_set_discovery(hc_sock_t *s, int enabled); +int hc_mapme_set_timescale(hc_sock_t *s, double timescale); +int hc_mapme_set_retx(hc_sock_t *s, double timescale); + +#endif /* HICNTRL_API */ |