eaiovnaovbqoebvqoeavibavo PK|Z`f file.hnu[/* * Copyright (c) 2014 by Farsight Security, Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef FSTRM_FILE_H #define FSTRM_FILE_H /** * \defgroup fstrm_file fstrm_file * * `fstrm_file` contains interfaces for opening \ref fstrm_reader or * \ref fstrm_writer objects that are backed by file I/O. * * @{ */ /** * Initialize an `fstrm_file_options` object, which is needed to configure the * file path to be opened by fstrm_file_reader_init() or * fstrm_file_writer_init(). * * \return * `fstrm_file_options` object. */ struct fstrm_file_options * fstrm_file_options_init(void); /** * Destroy an `fstrm_file_options` object. * * \param fopt * Pointer to `fstrm_file_options` object. */ void fstrm_file_options_destroy(struct fstrm_file_options **fopt); /** * Set the `file_path` option. This is a filesystem path to a regular file to be * opened for reading or writing. * * \param fopt * `fstrm_file_options` object. * \param file_path * The filesystem path for a regular file. */ void fstrm_file_options_set_file_path(struct fstrm_file_options *fopt, const char *file_path); /** * Open a file containing Frame Streams data for reading. * * \param fopt * `fstrm_file_options` object. Must be non-NULL, and have the `file_path` * option set. * \param ropt * `fstrm_reader_options` object. May be NULL, in which case default values * will be used. * * \return * `fstrm_reader` object. * \retval * NULL on failure. */ struct fstrm_reader * fstrm_file_reader_init(const struct fstrm_file_options *fopt, const struct fstrm_reader_options *ropt); /** * Open a file for writing Frame Streams data. The file will be truncated if it * already exists. * * \param fopt * `fstrm_file_options` object. Must be non-NULL, and have the `file_path` * option set. * \param wopt * `fstrm_writer_options` object. May be NULL, in which case default values * will be used. * * \return * `fstrm_writer` object. * \retval * NULL on failure. */ struct fstrm_writer * fstrm_file_writer_init(const struct fstrm_file_options *fopt, const struct fstrm_writer_options *wopt); /**@}*/ #endif /* FSTRM_FILE_H */ PK|Zqn tcp_writer.hnu[/* * Copyright (c) 2014, 2018 by Farsight Security, Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef FSTRM_TCP_WRITER_H #define FSTRM_TCP_WRITER_H /** * \defgroup fstrm_tcp_writer fstrm_tcp_writer * * `fstrm_tcp_writer` is an interface for opening an \ref fstrm_writer object * that is backed by I/O on a TCP socket. * * @{ */ /** * Initialize an `fstrm_tcp_writer_options` object, which is needed to * configure the socket address and socket port to be opened by the writer. * * \return * `fstrm_tcp_writer_options` object. */ struct fstrm_tcp_writer_options * fstrm_tcp_writer_options_init(void); /** * Destroy an `fstrm_tcp_writer_options` object. * * \param twopt * Pointer to `fstrm_tcp_writer_options` object. */ void fstrm_tcp_writer_options_destroy( struct fstrm_tcp_writer_options **twopt); /** * Set the `socket_address` option. This is the IPv4 or IPv6 address in * presentation format to be connected by the TCP socket. * * \param twopt * `fstrm_tcp_writer_options` object. * \param socket_address * The socket address. */ void fstrm_tcp_writer_options_set_socket_address( struct fstrm_tcp_writer_options *twopt, const char *socket_address); /** * Set the `socket_port` option. This is the TCP port number to be connected by * the TCP socket. * * \param twopt * `fstrm_tcp_writer_options` object. * \param socket_port * The TCP socket port number provided as a character string. * (When converted, the maximum allowed unsigned integer is 65535.) */ void fstrm_tcp_writer_options_set_socket_port( struct fstrm_tcp_writer_options *twopt, const char *socket_port); /** * Initialize the `fstrm_writer` object. Note that the TCP socket will not * actually be opened until a subsequent call to fstrm_writer_open(). * * \param twopt * `fstrm_tcp_writer_options` object. Must be non-NULL, and have the * `socket_address` and `socket_port` options set. * \param wopt * `fstrm_writer_options` object. May be NULL, in which chase default * values will be used. * * \return * `fstrm_writer` object. * \retval * NULL on failure. */ struct fstrm_writer * fstrm_tcp_writer_init( const struct fstrm_tcp_writer_options *twopt, const struct fstrm_writer_options *wopt); /**@}*/ #endif /* FSTRM_TCP_WRITER_H */ PK|Z(x<x<iothr.hnu[/* * Copyright (c) 2014 by Farsight Security, Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef FSTRM_IOTHR_H #define FSTRM_IOTHR_H /** * \defgroup fstrm_iothr fstrm_iothr * * The `fstrm_iothr` interface creates a background I/O thread which writes * Frame Streams encapsulated data frames into an output stream specified by an * \ref fstrm_writer object. It exposes non-blocking input queues that can be * used by worker threads to asynchronously write data frames to the output * stream. A deferred deallocation callback is invoked after the I/O thread has * disposed of a queued data frame. * * In order to create an `fstrm_iothr` object, the caller must first configure * and instantiate an `fstrm_writer` object and pass this instance to the * fstrm_iothr_init() function. The `fstrm_iothr` object then takes ownership of * the `fstrm_writer` object. It is responsible for serializing writes and will * take care of destroying the captive `fstrm_writer` object at the same time * the `fstrm_iothr` object is destroyed. The caller should not perform any * operations on the captive `fstrm_writer` object after it has been passed to * `fstrm_iothr_init()`. * * Parameters used to configure the I/O thread are passed through an * `fstrm_iothr_options` object. These options have to be specified in advance * and are mostly performance knobs which have reasonable defaults. * * Once the `fstrm_iothr` object has been created, handles to the input queues * used to submit data frames can be obtained by calling * `fstrm_iothr_get_input_queue()`. This function can be called up to * **num_input_queues** times, and can be safely called concurrently. For * instance, in an application with a fixed number of worker threads, an input * queue can be dedicated to each worker thread by setting the * **num_input_queues** option to the number of worker threads, and then calling * `fstrm_iothr_get_input_queue()` from each worker thread's startup function to * obtain a per-thread input queue. * * @{ */ /** * Initialize an `fstrm_iothr_options` object. This is needed to pass * configuration parameters to fstrm_iothr_init(). * * \return * `fstrm_iothr_options` object. */ struct fstrm_iothr_options * fstrm_iothr_options_init(void); /** * Destroy an `fstrm_iothr_options` object. * * \param opt * Pointer to `fstrm_iothr_options` object. */ void fstrm_iothr_options_destroy(struct fstrm_iothr_options **opt); /** * Set the `buffer_hint` parameter. This is the threshold number of bytes to * accumulate in the output buffer before forcing a buffer flush. * * \param opt * `fstrm_iothr_options` object. * \param buffer_hint * New `buffer_hint` value. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_iothr_options_set_buffer_hint( struct fstrm_iothr_options *opt, unsigned buffer_hint); /** Minimum `buffer_hint` value. */ #define FSTRM_IOTHR_BUFFER_HINT_MIN 1024 /** Default `buffer_hint` value. */ #define FSTRM_IOTHR_BUFFER_HINT_DEFAULT 8192 /** Maximum `buffer_hint` value. */ #define FSTRM_IOTHR_BUFFER_HINT_MAX 65536 /** * Set the `flush_timeout` parameter. This is the number of seconds to allow * unflushed data to remain in the output buffer. * * \param opt * `fstrm_iothr_options` object. * \param flush_timeout * New `flush_timeout` value. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_iothr_options_set_flush_timeout( struct fstrm_iothr_options *opt, unsigned flush_timeout); /** Minimum `flush_timeout` value. */ #define FSTRM_IOTHR_FLUSH_TIMEOUT_MIN 1 /** Default `flush_timeout` value. */ #define FSTRM_IOTHR_FLUSH_TIMEOUT_DEFAULT 1 /** Maximum `flush_timeout` value. */ #define FSTRM_IOTHR_FLUSH_TIMEOUT_MAX 600 /** * Set the `input_queue_size` parameter. This is the number of queue entries to * allocate per each input queue. This option controls the number of outstanding * data frames per input queue that can be outstanding for deferred processing * by the `fstrm_iothr` object and thus affects performance and memory usage. * * This parameter must be a power-of-2. * * \param opt * `fstrm_iothr_options` object. * \param input_queue_size * New `input_queue_size` value. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_iothr_options_set_input_queue_size( struct fstrm_iothr_options *opt, unsigned input_queue_size); /** Minimum `input_queue_size` value. */ #define FSTRM_IOTHR_INPUT_QUEUE_SIZE_MIN 2 /** Default `input_queue_size` value. */ #define FSTRM_IOTHR_INPUT_QUEUE_SIZE_DEFAULT 512 /** Maximum `input_queue_size` value. */ #define FSTRM_IOTHR_INPUT_QUEUE_SIZE_MAX 16384 /** * Set the `num_input_queues` parameter. This is the number of input queues to * create and must match the number of times that fstrm_iothr_get_input_queue() * is called on the corresponding `fstrm_iothr` object. * * \param opt * `fstrm_iothr_options` object. * \param num_input_queues * New `num_input_queues` value. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_iothr_options_set_num_input_queues( struct fstrm_iothr_options *opt, unsigned num_input_queues); /** Minimum `num_input_queues` value. */ #define FSTRM_IOTHR_NUM_INPUT_QUEUES_MIN 1 /** Default `num_input_queues` value. */ #define FSTRM_IOTHR_NUM_INPUT_QUEUES_DEFAULT 1 /** * Set the `output_queue_size` parameter. This is the number of queue entries to * allocate for the output queue. This option controls the maximum number of * data frames that can be accumulated in the output queue before a buffer flush * must occur and thus affects performance and memory usage. * * \param opt * `fstrm_iothr_options` object. * \param output_queue_size * New `output_queue_size` value. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_iothr_options_set_output_queue_size( struct fstrm_iothr_options *opt, unsigned output_queue_size); /** Minimum `output_queue_size` value. */ #define FSTRM_IOTHR_OUTPUT_QUEUE_SIZE_MIN 2 /** Default `output_queue_size` value. */ #define FSTRM_IOTHR_OUTPUT_QUEUE_SIZE_DEFAULT 64 /** Maximum `output_queue_size` value. */ #define FSTRM_IOTHR_OUTPUT_QUEUE_SIZE_MAX IOV_MAX /** * Queue models. * \see fstrm_iothr_options_set_queue_model() */ typedef enum { /** Single Producer, Single Consumer. */ FSTRM_IOTHR_QUEUE_MODEL_SPSC, /** Multiple Producer, Single Consumer. */ FSTRM_IOTHR_QUEUE_MODEL_MPSC, } fstrm_iothr_queue_model; /** * Set the `queue_model` parameter. This controls what queueing semantics to use * for `fstrm_iothr_queue` objects. Single Producer queues * (#FSTRM_IOTHR_QUEUE_MODEL_SPSC) may only have a single thread at a time * calling fstrm_iothr_submit() on a given `fstrm_iothr_queue` object, while * Multiple Producer queues (#FSTRM_IOTHR_QUEUE_MODEL_MPSC) may have multiple * threads concurrently calling fstrm_iothr_submit() on a given * `fstrm_iothr_queue` object. * * \param opt * `fstrm_iothr_options` object. * \param queue_model * New `queue_model` value. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_iothr_options_set_queue_model( struct fstrm_iothr_options *opt, fstrm_iothr_queue_model queue_model); /** Default `queue_model` value. */ #define FSTRM_IOTHR_QUEUE_MODEL_DEFAULT FSTRM_IOTHR_QUEUE_MODEL_SPSC /** * Set the `queue_notify_threshold` parameter. This controls the number of * outstanding queue entries to allow on an input queue before waking the I/O * thread, which will cause the outstanding queue entries to begin draining. * * \param opt * `fstrm_iothr_options` object. * \param queue_notify_threshold * New `queue_notify_threshold` value. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_iothr_options_set_queue_notify_threshold( struct fstrm_iothr_options *opt, unsigned queue_notify_threshold); /** Minimum `queue_notify_threshold` value. */ #define FSTRM_IOTHR_QUEUE_NOTIFY_THRESHOLD_MIN 1 /** Default `queue_notify_threshold` value. */ #define FSTRM_IOTHR_QUEUE_NOTIFY_THRESHOLD_DEFAULT 32 /** * Set the `reopen_interval` parameter. This controls the number of seconds to * wait between attempts to reopen a closed `fstrm_writer` output stream. * * \param opt * `fstrm_iothr_options` object. * \param reopen_interval * New `queue_notify_threshold` value. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_iothr_options_set_reopen_interval( struct fstrm_iothr_options *opt, unsigned reopen_interval); /** Minimum `reopen_interval` value. */ #define FSTRM_IOTHR_REOPEN_INTERVAL_MIN 1 /** Default `reopen_interval` value. */ #define FSTRM_IOTHR_REOPEN_INTERVAL_DEFAULT 5 /** Maximum `reopen_interval` value. */ #define FSTRM_IOTHR_REOPEN_INTERVAL_MAX 600 /** * Initialize an `fstrm_iothr` object. This creates a background I/O thread * which asynchronously writes data frames submitted by other threads which call * fstrm_iothr_submit(). * * \param opt * `fstrm_iothr_options` object. May be NULL, in which case default values * will be used. * * \param writer * Pointer to `fstrm_writer` object. Must be non-NULL. * * \return * `fstrm_iothr` object. * \retval * NULL on failure. */ struct fstrm_iothr * fstrm_iothr_init( const struct fstrm_iothr_options *opt, struct fstrm_writer **writer); /** * Destroy an `fstrm_iothr` object. This signals the background I/O thread to * flush or discard any queued data frames and deallocates any resources used * internally. This function blocks until the I/O thread has terminated. * * \param iothr * Pointer to `fstrm_iothr` object. */ void fstrm_iothr_destroy(struct fstrm_iothr **iothr); /** * Obtain an `fstrm_iothr_queue` object for submitting data frames to the * `fstrm_iothr` object. `fstrm_iothr_queue` objects are child objects of their * parent `fstrm_iothr` object and will be destroyed when fstrm_iothr_destroy() * is called on the parent `fstrm_iothr` object. * * This function is thread-safe and may be called simultaneously from any * thread. For example, in a program which employs a fixed number of worker * threads to handle requests, fstrm_iothr_get_input_queue() may be called from * a thread startup routine without synchronization. * * `fstrm_iothr` objects allocate a fixed total number of `fstrm_iothr_queue` * objects during the call to fstrm_iothr_init(). To adjust this parameter, use * fstrm_iothr_options_set_num_input_queues(). * * This function will fail if it is called more than **num_input_queues** times. * By default, only one input queue is initialized per `fstrm_iothr` object. * * For optimum performance in a threaded program, each worker thread submitting * data frames should have a dedicated `fstrm_iothr_queue` object. This allows * each worker thread to have its own queue which is processed independently by * the I/O thread. If the queue model for the `fstrm_iothr` object is set to * #FSTRM_IOTHR_QUEUE_MODEL_SPSC, this results in contention-free access to the * input queue. * * \param iothr * `fstrm_iothr` object. * * \return * `fstrm_iothr_queue` object. * \retval * NULL on failure. */ struct fstrm_iothr_queue * fstrm_iothr_get_input_queue(struct fstrm_iothr *iothr); /** * Obtain an `fstrm_iothr_queue` object for submitting data frames to the * `fstrm_iothr` object. This function is like fstrm_iothr_get_input_queue() * except it indexes into the `fstrm_iothr_queue`'s array of input queues. * * \param iothr * `fstrm_iothr` object. * \param idx * Index of the `fstrm_iothr_queue` object to retrieve. This value is * limited by the **num_input_queues** option. * * \return * `fstrm_iothr_queue` object. * \retval * NULL on failure. */ struct fstrm_iothr_queue * fstrm_iothr_get_input_queue_idx(struct fstrm_iothr *iothr, size_t idx); /** * Submit a data frame to the background I/O thread. If successfully queued and * the I/O thread has an active output stream opened, the data frame will be * asynchronously written to the output stream. * * When this function returns #fstrm_res_success, responsibility for * deallocating the data frame specified by the `data` parameter passes to the * `fstrm` library. The caller **MUST** ensure that the `data` object remains * valid after fstrm_iothr_submit() returns. The callback function specified by * the `free_func` parameter will be invoked once the data frame is no longer * needed by the `fstrm` library. For example, if the data frame is dynamically * allocated, the data frame may be deallocated in the callback function. * * Note that if this function returns #fstrm_res_failure, the responsibility for * deallocating the data frame remains with the caller. * * As a convenience, if `data` is allocated with the system's `malloc()`, * `fstrm_free_wrapper` may be provided as the `free_func` parameter with the * `free_data` parameter set to `NULL`. This will cause the system's `free()` to * be invoked to deallocate `data`. * * `free_func` may be NULL, in which case no callback function will be invoked * to dispose of `buf`. This behavior may be useful if `data` is a global, * statically allocated object. * * \param iothr * `fstrm_iothr` object. * \param ioq * `fstrm_iothr_queue` object. * \param data * Data frame bytes. * \param len * Number of bytes in `data`. * \param free_func * Callback function to deallocate the data frame. The `data` and * `free_data` parameters passed to this callback will be the same values * originally supplied in the call to fstrm_iothr_submit(). * \param free_data * Parameter to pass to `free_func`. * * \retval #fstrm_res_success * The data frame was successfully queued. * \retval #fstrm_res_again * The queue is full. * \retval #fstrm_res_failure * Permanent failure. */ fstrm_res fstrm_iothr_submit( struct fstrm_iothr *iothr, struct fstrm_iothr_queue *ioq, void *data, size_t len, void (*free_func)(void *buf, void *free_data), void *free_data); /** * Wrapper function for the system's `free()`, suitable for use as the * `free_func` callback for fstrm_iothr_submit(). * * \param data * Object to call `free()` on. * \param free_data * Unused. */ void fstrm_free_wrapper(void *data, void *free_data); /**@}*/ #endif /* FSTRM_IOTHR_H */ PK|ZS S unix_writer.hnu[/* * Copyright (c) 2014 by Farsight Security, Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef FSTRM_UNIX_WRITER_H #define FSTRM_UNIX_WRITER_H /** * \defgroup fstrm_unix_writer fstrm_unix_writer * * `fstrm_unix_writer` is an interface for opening an \ref fstrm_writer object * that is backed by I/O on a stream-oriented (`SOCK_STREAM`) Unix socket. * * @{ */ /** * Initialize an `fstrm_unix_writer_options` object, which is needed to * configure the socket path to be opened by the writer. * * \return * `fstrm_unix_writer_options` object. */ struct fstrm_unix_writer_options * fstrm_unix_writer_options_init(void); /** * Destroy an `fstrm_unix_writer_options` object. * * \param uwopt * Pointer to `fstrm_unix_writer_options` object. */ void fstrm_unix_writer_options_destroy( struct fstrm_unix_writer_options **uwopt); /** * Set the `socket_path` option. This is a filesystem path that will be * connected to as an `AF_UNIX` socket. * * \param uwopt * `fstrm_unix_writer_options` object. * \param socket_path * The filesystem path to the `AF_UNIX` socket. */ void fstrm_unix_writer_options_set_socket_path( struct fstrm_unix_writer_options *uwopt, const char *socket_path); /** * Initialize the `fstrm_writer` object. Note that the `AF_UNIX` socket will not * actually be opened until a subsequent call to fstrm_writer_open(). * * \param uwopt * `fstrm_unix_writer_options` object. Must be non-NULL, and have the * `socket_path` option set. * \param wopt * `fstrm_writer_options` object. May be NULL, in which chase default * values will be used. * * \return * `fstrm_writer` object. * \retval * NULL on failure. */ struct fstrm_writer * fstrm_unix_writer_init( const struct fstrm_unix_writer_options *uwopt, const struct fstrm_writer_options *wopt); /**@}*/ #endif /* FSTRM_UNIX_WRITER_H */ PK|Z[sF(PP control.hnu[/* * Copyright (c) 2014 by Farsight Security, Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef FSTRM_CONTROL_H #define FSTRM_CONTROL_H /** * \defgroup fstrm_control fstrm_control * * `fstrm_control` is an interface for encoding and decoding Frame Streams * control frames. * * Two types of frames are possible in a Frame Streams byte stream: **data * frames** and **control frames**. Both are variable length byte sequences * prefixed by a 32-bit big endian unsigned integer (the **frame length**) * specifying the length of the following byte sequence. If this frame length * value is greater than zero, the **frame length** specifies the **data frame * length**, and a data frame follows it. If the frame length is zero (i.e., it * is the four byte sequence `00 00 00 00`), this is an **escape sequence**, * which means that a control frame follows. The control frame itself is * prefixed by a 32-bit big endian unsigned integer (the **control frame * length**) specifying the length of the following **control frame payload**. * * There are two types of control frames used for uni-directional streams: * `START` and `STOP`. These control frame types bracket the stream of data * frames. `START` indicates the beginning of the stream and communicates * metadata about the stream to follow, and `STOP` indicates the end of the * stream. * * Bi-directional streams make use of three additional control frame types: * `READY`, `ACCEPT`, and `FINISH`. These control frame types are used in a * simple handshake protocol between sender and receiver. * * A uni-directional Frame Streams byte stream normally consists of the * following: * * 1. The `START` control frame. * 2. A sequence of zero or more data frames or control frames that are not of * the control frame types `START`, `STOP`, `ACCEPT`, `READY`, or * `FINISH`. * 3. The `STOP` control frame. * * The `START` and `STOP` control frames are not optional. The `START` control * frame must appear at the beginning of the byte stream, and the `STOP` control * frame must appear at the end of the byte stream. (If the byte stream has an * end.) `START` control frames must not appear anywhere other than at the * beginning of the byte stream, and `STOP` control frames must not appear * anywhere other than at the end of the byte stream. Only one `START` control * frame and only one `STOP` control frame may appear in a Frame Streams byte * stream. * * Control frames may optionally include zero or more **control frame fields**. * There is currently one type of control frame field defined: `CONTENT_TYPE`. * This field specifies a variable length byte sequence describing the encoding * of data frames that appear in the Frame Streams byte stream. This field is * used by cooperating programs to unambiguously identify how to interpret the * data frames in a particular Frame Streams byte stream. For instance, this * field may specify a particular schema to use to interpret the data frames * appearing in the byte stream. Zero, one, or more `CONTENT_TYPE` fields may * appear in `READY` or `ACCEPT` control frames. Zero or one `CONTENT_TYPE` * fields may appear in `START` control frames. No `CONTENT_TYPE` fields may * appear in `STOP` or `FINISH` control frames. * * A uni-directional Frame Streams encoder would normally produce a byte stream * as follows: * * 1. Write the `START` **control frame**. * + At the start of the byte stream, write the four byte **escape * sequence** `00 00 00 00` that precedes control frames. * + Write the **control frame length** as a 32-bit big endian unsigned * integer. * + Write the **control frame payload**. It must be a `START` control * frame. It may optionally specify a `CONTENT_TYPE` field. * 2. Write zero or more **data frames**. * 3. Write the `STOP` **control frame**. * + At the start of the byte stream, write the four byte **escape * sequence** `00 00 00 00` that precedes control frames. * + Write the **control frame length** as a 32-bit big endian unsigned * integer. * + Write the **control frame payload**. It must be a `STOP` control * frame. * * A uni-directional Frame Streams decoder would normally process the byte * stream as follows: * * 1. Read the `START` control frame. * + At the start of the byte stream, read the four byte **escape * sequence** `00 00 00 00` that precedes control frames. * + Read the 32-bit big endian unsigned integer specifying the **control * frame length**. * + Decode the **control frame payload**. It must be a `START` control * frame. It may optionally specify a `CONTENT_TYPE` field. * 2. Repeatedly read data frames or control frames following the `START` * control frame. * + Read the **frame length**, a 32-bit big endian unsigned integer. * + If the **frame length** is zero, a control frame follows: * + Read the 32-bit big endian unsigned integer specifying the * **control frame length**. * + Decode the **control frame payload**. If it is a `STOP` * control frame, the end of the Frame Streams byte stream has * occurred, and no frames follow. Break out of the decoding loop * and halt processing. (`READY`, `ACCEPT`, `START`, and `FINISH` * may not occur here. For forward compatibility, control frames of * types other than the types `READY`, `ACCEPT`, `START`, `STOP`, * and `FINISH` must be ignored here. No control frames specified * in the future may alter the encoding of succeeding frames.) * + If the **frame length** is non-zero, it specifies the number of bytes * in the following **data frame**. Consume these bytes from the byte * stream. * * The functions fstrm_control_encode() and fstrm_control_decode() are provided * to encode and decode control frames. See the detailed descriptions of those * functions for code examples showing their usage. * * @{ */ /** * The maximum length in bytes of an "Accept", "Start", or "Stop" control frame * payload. This excludes the escape sequence and the control frame length. */ #define FSTRM_CONTROL_FRAME_LENGTH_MAX 512 /** * The maximum length in bytes of a "Content Type" control frame field payload. * This excludes the field type and payload length. */ #define FSTRM_CONTROL_FIELD_CONTENT_TYPE_LENGTH_MAX 256 /** * Control frame types. */ typedef enum { /** Control frame type value for "Accept" control frames. */ FSTRM_CONTROL_ACCEPT = 0x01, /** Control frame type value for "Start" control frames. */ FSTRM_CONTROL_START = 0x02, /** Control frame type value for "Stop" control frames. */ FSTRM_CONTROL_STOP = 0x03, /** Control frame type value for "Ready" control frames. */ FSTRM_CONTROL_READY = 0x04, /** Control frame type value for "Finish" control frames. */ FSTRM_CONTROL_FINISH = 0x05, } fstrm_control_type; /** * Control frame field types. These are optional fields that can appear in * control frames. */ typedef enum { /** * Control frame field type value for the "Content Type" control frame * option. */ FSTRM_CONTROL_FIELD_CONTENT_TYPE = 0x01, } fstrm_control_field; /** * Flags for controlling the behavior of the encoding and decoding functions. */ typedef enum { /** * Set to control whether to include the control frame header in * encoding/decoding operations. * * Causes fstrm_control_encode() and fstrm_control_encoded_size() to * include the control frame header containing the escape sequence and * control frame payload length in the encoded output. Otherwise, only * the control frame payload itself is encoded. * * Tells fstrm_control_decode() that the input buffer to be decoded * begins with the control frame header containing the escape sequence * and control frame payload length. (Note that this requires the caller * to peek at the input buffer to calculate the right buffer length.) * Otherwise, the input buffer begins with the control frame payload. */ FSTRM_CONTROL_FLAG_WITH_HEADER = (1 << 0), } fstrm_control_flag; /** * Convert an `fstrm_control_type` enum value to a string representation. * Unknown values are represented as `"FSTRM_CONTROL_UNKNOWN"`. * * \param type The `fstrm_control_type` enum value. * \return The string representation of the enum value. (Always non-NULL.) */ const char * fstrm_control_type_to_str(fstrm_control_type type); /** * Convert an `fstrm_control_field` enum value to a string representation. * Unknown values are represented as `"FSTRM_CONTROL_FIELD_UNKNOWN"`. * * \param f_type The `fstrm_control_field` enum value. * \return The string representation of the enum value. (Always non-NULL.) */ const char * fstrm_control_field_type_to_str(fstrm_control_field f_type); /** * Initialize an `fstrm_control` object. This object represents Frame Streams * control frames and is used for encoding and decoding control frames. * * \return * An `fstrm_control` object. */ struct fstrm_control * fstrm_control_init(void); /** * Destroy an `fstrm_control` object. * * \param[in] c * Pointer to an `fstrm_control` object. */ void fstrm_control_destroy(struct fstrm_control **c); /** * Reinitialize an `fstrm_control` object. This resets the internal state to * default values. * * \param c * `fstrm_control` object. */ void fstrm_control_reset(struct fstrm_control *c); /** * Retrieve the type of the control frame. * * \param c * `fstrm_control` object. * \param[out] type * Type of the control frame. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_control_get_type( const struct fstrm_control *c, fstrm_control_type *type); /** * Set the type of the control frame. * * \param c * `fstrm_control` object. * \param[in] type * Type of the control frame. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_control_set_type( struct fstrm_control *c, fstrm_control_type type); /** * Retrieve the number of "Content Type" fields present in the control frame. * * \param c * `fstrm_control` object. * \param[out] n_content_type * The number of "Content Type" fields. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_control_get_num_field_content_type( const struct fstrm_control *c, size_t *n_content_type); /** * Retrieve a "Content Type" field from the control frame. This function * returns a reference which must not be modified. Control frames may contain * zero, one, or more "Content Type" fields. * * \see fstrm_control_get_num_field_content_type() * * \param c * `fstrm_control` object. * \param[in] idx * The index of the "Content Type" field to retrieve. * \param[out] content_type * Pointer to where the reference to the "Content Type" string will be * stored. Note that this string is not NUL-terminated and may contain * embedded NULs. * \param[out] len_content_type * The number of bytes in `content_type`. * * \retval #fstrm_res_success * The control frame has a "Content Type" field. * \retval #fstrm_res_failure * The control frame does not have a "Content Type" field. */ fstrm_res fstrm_control_get_field_content_type( const struct fstrm_control *c, const size_t idx, const uint8_t **content_type, size_t *len_content_type); /** * Add a "Content Type" field to the control frame. This function makes a copy * of the provided string. This function may be called multiple times, in which * case multiple "Content Type" fields will be added to the control frame. * * The "Content Type" fields are removed on a call to fstrm_control_reset(). * * \param c * `fstrm_control` object. * \param[in] content_type * The "Content Type" string to copy. Note that this string is not * NUL-terminated and may contain embedded NULs. * \param[in] len_content_type * The number of bytes in `content_type`. * * \retval #fstrm_res_success * The "Content Type" field was successfully added. * \retval #fstrm_res_failure * The "Content Type" string is too long. */ fstrm_res fstrm_control_add_field_content_type( struct fstrm_control *c, const uint8_t *content_type, size_t len_content_type); /** * Check if the control frame matches a particular content type value. That is, * the content type given in the `match` and `len_match` parameters is checked * for compatibility with the content types (if any) specified in the control * frame. * * \param c * `fstrm_control` object. * \param match * The "Content Type" string to match. Note that this string is not * NUL-terminated and may contain embedded NULs. May be NULL, in which case * the control frame must not have any content type fields in order to * match. * \param len_match * The number of bytes in `match`. * * \retval #fstrm_res_success * A match was found. * \retval #fstrm_res_failure * A match was not found. */ fstrm_res fstrm_control_match_field_content_type( const struct fstrm_control *c, const uint8_t *match, const size_t len_match); /** * Decode a control frame from a buffer. The buffer starts with either the * escape sequence or the control frame payload depending on whether the * `FSTRM_CONTROL_FLAG_WITH_HEADER` flag is set or not. In either case, the * 'len_control_frame' parameter must be exact. Underflow or overflow is not * permitted. * * The following code example shows a function that decodes a control frame * payload: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ static fstrm_res decode_control_frame(const void *control_frame, size_t len_control_frame) { fstrm_res res; fstrm_control_type c_type; struct fstrm_control *c; uint32_t flags = 0; c = fstrm_control_init(); res = fstrm_control_decode(c, control_frame, len_control_frame, flags); if (res != fstrm_res_success) { puts("fstrm_control_decode() failed."); fstrm_control_destroy(&c); return res; } res = fstrm_control_get_type(c, &c_type); if (res != fstrm_res_success) { puts("fstrm_control_get_type() failed."); fstrm_control_destroy(&c); return res; } printf("The control frame is of type %s (%u).\n", fstrm_control_type_to_str(c_type), c_type); size_t n_content_type; res = fstrm_control_get_num_field_content_type(c, &n_content_type); if (res != fstrm_res_success) { puts("fstrm_control_get_num_field_content_type() failed."); fstrm_control_destroy(&c); return res; } const uint8_t *content_type; size_t len_content_type; for (size_t idx = 0; idx < n_content_type; idx++) { res = fstrm_control_get_field_content_type(c, idx, &content_type, &len_content_type); if (res == fstrm_res_success) { printf("The control frame has a CONTENT_TYPE field of length %zd.\n", len_content_type); } } fstrm_control_destroy(&c); return fstrm_res_success; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * \param c * `fstrm_control` object. Its state will be overwritten. * \param[in] control_frame * Buffer containing the serialized control frame. * \param[in] len_control_frame * The number of bytes in `control_frame`. This parameter must specify the * exact number of bytes in the control frame. * \param flags * Flags controlling the decoding process. See #fstrm_control_flag. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_control_decode( struct fstrm_control *c, const void *control_frame, size_t len_control_frame, const uint32_t flags); /** * Calculate the number of bytes needed to serialize the control frame. * * \param c * `fstrm_control` object. * \param[out] len_control_frame * The number of bytes needed to encode `c`. * \param flags * Flags controlling the encoding process. See #fstrm_control_flag. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_control_encoded_size( const struct fstrm_control *c, size_t *len_control_frame, const uint32_t flags); /** * Encode a control frame into a buffer. Since a Frame Streams control frame is * a variable length byte sequence of up to #FSTRM_CONTROL_FRAME_LENGTH_MAX * bytes, this function can be used in two different ways. The first way is to * call fstrm_control_encoded_size() to obtain the exact number of bytes needed * to encode the frame, and then pass a buffer of this exact size to * fstrm_control_encode(). The following example shows this usage: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ fstrm_res res; struct fstrm_control *c; uint8_t *control_frame; size_t len_control_frame; uint32_t flags = 0; c = fstrm_control_init(); res = fstrm_control_set_type(c, FSTRM_CONTROL_START); if (res != fstrm_res_success) { // Error handling goes here. } // Calculate the number of bytes needed. res = fstrm_control_encoded_size(c, &len_control_frame, flags); if (res != fstrm_res_success) { // Error handling goes here. } // 'len_control_frame' now specifies the number of bytes required for // the control frame. Allocate the needed space. control_frame = malloc(len_control_frame); if (!control_frame) { // Error handling goes here. } // Serialize the control frame into the allocated buffer. res = fstrm_control_encode(c, control_frame, &len_control_frame, 0); if (res != fstrm_res_success) { // Error handling goes here. } // Do something with 'control_frame' and 'len_control_frame'. // Clean up. free(control_frame); fstrm_control_destroy(&c); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * The second way to use fstrm_control_encode() is to allocate a statically * sized buffer of #FSTRM_CONTROL_FRAME_LENGTH_MAX bytes. The exact number of * bytes serialized by the encoder will be returned in the `len_control_frame` * parameter. The following example shows this usage: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ fstrm_res res; struct fstrm_control *c; uint8_t control_frame[FSTRM_CONTROL_FRAME_LENGTH_MAX]; size_t len_control_frame = sizeof(control_frame); c = fstrm_control_init(); res = fstrm_control_set_type(c, FSTRM_CONTROL_START); if (res != fstrm_res_success) { // Error handling. } // Serialize the control frame. res = fstrm_control_encode(c, control_frame, &len_control_frame, 0); if (res != fstrm_res_success) { // Error handling goes here. } // Do something with 'control_frame' and 'len_control_frame'. // Clean up. fstrm_control_destroy(&c); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * \param c * `fstrm_control` object. * \param[out] control_frame * The buffer in which to serialize the control frame. * \param[in,out] len_control_frame * The size in bytes of `control_frame`. On a successful return, contains * the number of bytes actually written into `control_frame`. * \param flags * Flags controlling the encoding process. See #fstrm_control_flag. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_control_encode( const struct fstrm_control *c, void *control_frame, size_t *len_control_frame, const uint32_t flags); /**@}*/ #endif /* FSTRM_CONTROL_H */ PK|Z+0reader.hnu[/* * Copyright (c) 2014 by Farsight Security, Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef FSTRM_READER_H #define FSTRM_READER_H /** * \defgroup fstrm_reader fstrm_reader * * `fstrm_reader` is an interface for reading Frame Streams data from a byte * stream. The underlying byte stream I/O operations are abstracted by the * \ref fstrm_rdwr interface. Thus, the `fstrm_reader` interface can be used to * read Frame Streams data from any source whose read/write operations are * wrapped by an `fstrm_rdwr` object. * * Some basic `fstrm_reader` implementations are already provided in the `fstrm` * library. See fstrm_file_reader_init() to create an `fstrm_reader` object that * reads Frame Streams data from a regular file. * * @{ */ /** * The default `max_frame_size` value. */ #define FSTRM_READER_MAX_FRAME_SIZE_DEFAULT 1048576 /** * Initialize an `fstrm_reader_options` object. * * \return * `fstrm_reader_options` object. */ struct fstrm_reader_options * fstrm_reader_options_init(void); /** * Destroy an `fstrm_reader_options` object. * * \param ropt * Pointer to `fstrm_reader_options` object. */ void fstrm_reader_options_destroy( struct fstrm_reader_options **ropt); /** * Add a "Content Type" value to the set of content types accepted by the * `fstrm_reader`. This function makes a copy of the provided string. This * function may be called multiple times, in which case multiple "Content Type" * values will be accepted by the reader. * * If the reader has no content types set, it will accept any content type. * * \param ropt * `fstrm_reader_options` object. * \param content_type * The "Content Type" string to copy. Note that this string is not * NUL-terminated and may contain embedded NULs. * \param len_content_type * The number of bytes in `content_type`. * * \retval #fstrm_res_success * The "Content Type" field was successfully added. * \retval #fstrm_res_failure * The "Content Type" string is too long. */ fstrm_res fstrm_reader_options_add_content_type( struct fstrm_reader_options *ropt, const void *content_type, size_t len_content_type); /** * Set the maximum frame size that the reader is willing to accept. This * enforces an upper limit on the amount of memory used to buffer incoming data * from the reader's byte stream. * * If this option is not set, it defaults to * #FSTRM_READER_MAX_FRAME_SIZE_DEFAULT. * * \param ropt * `fstrm_reader_options` object. * \param max_frame_size * The maximum frame size value. * * \retval #fstrm_res_success * The `max_frame_size` value was successfully set. * \retval #fstrm_res_failure * The `max_frame_size` value was too large or too small. */ fstrm_res fstrm_reader_options_set_max_frame_size( struct fstrm_reader_options *ropt, size_t max_frame_size); /** * Initialize a new `fstrm_reader` object based on an underlying `fstrm_rdwr` * object and an `fstrm_reader_options` object. * * The underlying `fstrm_rdwr` object MUST have a `read` method. It MAY * optionally have a `write` method, in which case the stream will be treated as * a bi-directional, handshaked stream. Otherwise, if there is no `write` method * the stream will be treated as a uni-directional stream. * * This function is useful for implementing functions that return new types of * `fstrm_reader` objects, such as fstrm_file_reader_init(). * * After a successful call to this function, the ownership of the `fstrm_rdwr` * object passes from the caller to the `fstrm_reader` object. The caller * should perform no further calls on the `fstrm_rdwr` object. The `fstrm_rdwr` * object will be cleaned up on a call to fstrm_reader_destroy(). * * \param ropt * `fstrm_reader_options` object. May be NULL, in which case default values * will be used. * * \param rdwr * Pointer to `fstrm_rdwr` object. Must be non-NULL. The `fstrm_rdwr` * object must have a `read` method, and may optionally have a `write` * method. * * \return * `fstrm_reader` object. * \retval * NULL on failure. */ struct fstrm_reader * fstrm_reader_init( const struct fstrm_reader_options *ropt, struct fstrm_rdwr **rdwr); /** * Destroy an `fstrm_reader` object. This implicitly calls fstrm_reader_close() * if necessary. * * \param r * Pointer to `fstrm_reader` object. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_reader_destroy(struct fstrm_reader **r); /** * Open an `fstrm_reader` object and prepare it to read data. * * This checks that the content type in the byte stream, if specified, matches * one of the content types specified in the `fstrm_reader_options` object used * to initialize the `fstrm_reader` object. * * This function may fail if there was an underlying problem opening the input * stream. * * \param r * `fstrm_reader` object. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_reader_open(struct fstrm_reader *r); /** * Close an `fstrm_reader` object. Once it has been closed, no data frames may * subsequently be read. * * Calling this function is optional; it may be implicitly invoked by a call to * fstrm_reader_destroy(). * * \param r * `fstrm_reader` object. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_reader_close(struct fstrm_reader *r); /** * Read a data frame from an `fstrm_reader` object. This frame is held in an * internal buffer owned by the `fstrm_reader` object and should not be modified * by the caller. The contents of this buffer will be overwritten by a * subsequent call to fstrm_reader_read(). * * This function implicitly calls fstrm_reader_open() if necessary. * * \param r * `fstrm_reader` object. * \param[out] data * Pointer to buffer containing the data frame payload. * \param[out] len_data * The number of bytes available in `data`. * * \retval #fstrm_res_success * A data frame was successfully read. * \retval #fstrm_res_stop * The end of the stream has been reached. * \retval #fstrm_res_failure */ fstrm_res fstrm_reader_read( struct fstrm_reader *r, const uint8_t **data, size_t *len_data); /** * Obtain a pointer to an `fstrm_control` object used during processing. Objects * returned by this function are owned by the `fstrm_reader` object and must not * be modified by the caller. After a call to fstrm_reader_destroy() these * pointers will no longer be valid. * * For example, this function can be used to obtain a pointer to the START * control frame, which can be queried to see which "Content Type" was * negotiated during the opening of the reader. * * This function implicitly calls fstrm_reader_open() if necessary. * * \param r * `fstrm_reader` object. * \param type * Which control frame to return. * \param[out] control * The `fstrm_control` object. * * \retval #fstrm_res_success * If an `fstrm_control` object was returned. * \retval #fstrm_res_failure */ fstrm_res fstrm_reader_get_control( struct fstrm_reader *r, fstrm_control_type type, const struct fstrm_control **control); /**@}*/ #endif /* FSTRM_READER_H */ PK|Zw!!writer.hnu[/* * Copyright (c) 2014, 2018 by Farsight Security, Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef FSTRM_WRITER_H #define FSTRM_WRITER_H /** * \defgroup fstrm_writer fstrm_writer * * `fstrm_writer` is an interface for writing Frame Streams data into a byte * stream. The underlying byte stream I/O operations are abstracted by the * \ref fstrm_rdwr interface. Thus, the `fstrm_writer` interface can be used to * write Frame Streams data to any type of output whose read/write operations * are wrapped by an `fstrm_rdwr` object. * * Some basic `fstrm_writer` implementations are already provided in the `fstrm` * library. See fstrm_file_writer_init() for an implementation that writes to * a regular file, fstrm_tcp_writer_init() for an implementation that writes to * a TCP socket, and fstrm_unix_writer_init() for an implementation that writes * to a Unix socket. * * @{ */ /** * Initialize an `fstrm_writer_options` object. * * \return * `fstrm_writer_options` object. */ struct fstrm_writer_options * fstrm_writer_options_init(void); /** * Destroy an `fstrm_writer_options` object. * * \param wopt * Pointer to `fstrm_writer_options` object. */ void fstrm_writer_options_destroy( struct fstrm_writer_options **wopt); /** * Add a "Content Type" value to the set of content types that can be negotiated * by the writer. This function makes a copy of the provided string. This * function may be called multiple times, in which case multiple "Content Type" * values will be accepted by the reader. * * For uni-directional streams like regular files, the negotiated content type * will simply be the first content type provided to this function. For * bi-directional streams like sockets, a handshake occurs and the remote end * determines which content type should be sent. In the latter case, after the * writer has been successfully opened with a call to fstrm_writer_open(), the * fstrm_writer_get_control() function should be called with `type` set to * `FSTRM_CONTROL_ACCEPT` and the control frame queried in order to determine * the negotiated content type. * * \param wopt * `fstrm_writer_options` object. * \param content_type * The "Content Type" string to copy. Note that this string is not * NUL-terminated and may contain embedded NULs. * \param len_content_type * The number of bytes in `content_type`. * * \retval #fstrm_res_success * The "Content Type" field was successfully added. * \retval #fstrm_res_failure * The "Content Type" string is too long. */ fstrm_res fstrm_writer_options_add_content_type( struct fstrm_writer_options *wopt, const void *content_type, size_t len_content_type); /** * Initialize a new `fstrm_writer` object based on an underlying `fstrm_rdwr` * object and an `fstrm_writer_options` object. * * The underlying `fstrm_rdwr` object MUST have a `write` method. It MAY * optionally have a `read` method, in which case the stream will be treated as * a bi-directional, handshaked stream. Otherwise, if there is no `read` method * the stream will be treated as a uni-directional stream. * * This function is useful for implementing functions that return new types of * `fstrm_writer` objects, such as fstrm_file_writer_init() and * fstrm_unix_writer_init(). * * After a successful call to this function, the ownership of the `fstrm_rdwr` * object passes from the caller to the `fstrm_writer` object. The caller * should perform no further calls on the `fstrm_rdwr` object. The `fstrm_rdwr` * object will be cleaned up on a call to fstrm_writer_destroy(). * * \param wopt * `fstrm_writer_options` object. May be NULL, in which case default values * will be used. * * \param rdwr * Pointer to `fstrm_rdwr` object. Must be non-NULL. The `fstrm_rdwr` * object must have a `write` method, and may optionally have a `read` * method. * * \return * `fstrm_writer` object. * \retval * NULL on failure. */ struct fstrm_writer * fstrm_writer_init( const struct fstrm_writer_options *wopt, struct fstrm_rdwr **rdwr); /** * Destroy an `fstrm_writer` object. This implicitly calls fstrm_writer_close() * if necessary. * * \param w * Pointer to `fstrm_writer` object. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_writer_destroy(struct fstrm_writer **w); /** * Open an `fstrm_writer` object and prepare it to write data. For * bi-directional writer implementations, this performs content type * negotiation. * * This function may fail if there was an underlying problem opening the output * stream. * * \param w * `fstrm_writer` object. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_writer_open(struct fstrm_writer *w); /** * Close an `fstrm_writer` object. Open it has been closed, no data frames may * subsequently be written. * * Calling this function is optional; it may be implicitly invoked by a call to * fstrm_writer_destroy(). * * \param w * `fstrm_writer` object. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ fstrm_res fstrm_writer_close(struct fstrm_writer *w); /** * Write a data frame to an `fstrm_writer` object. * * This function implicitly calls fstrm_writer_open() if necessary. * * \param w * `fstrm_writer` object. * \param[in] data * Buffer containing the data frame payload. * \param[in] len_data * The number of bytes in `data`. * * \retval #fstrm_res_success * The data frame was successfully written. * \retval #fstrm_res_failure */ fstrm_res fstrm_writer_write( struct fstrm_writer *w, const void *data, size_t len_data); /** * Write multiple data frames to an `fstrm_writer` object. * * This function implicitly calls fstrm_writer_open() if necessary. * * Data frames are passed similarly to the `writev()` system call, with an array * of `struct iovec` objects describing the data frame payloads and their * lengths. The complete set of data frames will be written to the output * stream after a successful call. * * \param w * `fstrm_writer` object. * \param iov * Array of `struct iovec` objects. * \param iovcnt * Number of `struct iovec` objects in `iov`. * * \retval #fstrm_res_success * The data frames were successfully written. * \retval #fstrm_res_failure */ fstrm_res fstrm_writer_writev( struct fstrm_writer *w, const struct iovec *iov, int iovcnt); /** * Obtain a pointer to an `fstrm_control` object used during processing. Objects * returned by this function are owned by the `fstrm_reader` object and must not * be modified by the caller. After a call to fstrm_reader_destroy() these * pointers will no longer be valid. * * For example, with bi-directional streams this function can be used to obtain * a pointer to the ACCEPT control frame, which can be queried to see which * "Content Type" was negotiated during the opening of the writer. * * This function implicitly calls fstrm_writer_open() if necessary. * * \param w * `fstrm_writer` object. * \param type * Which control frame to return. * \param[out] control * The `fstrm_control` object. * * \retval #fstrm_res_success * If an `fstrm_control` object was returned. * \retval #fstrm_res_failure */ fstrm_res fstrm_writer_get_control( struct fstrm_writer *w, fstrm_control_type type, struct fstrm_control **control); /**@}*/ #endif /* FSTRM_WRITER_H */ PK|Z&]K%K%rdwr.hnu[/* * Copyright (c) 2014 by Farsight Security, Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef FSTRM_RDWR_H #define FSTRM_RDWR_H /** * \defgroup fstrm_rdwr fstrm_rdwr * * `fstrm_rdwr` is an interface for abstracting the process of reading and * writing data to byte streams. It allows extending the `fstrm` library to * support reading and writing Frame Streams data to new kinds of byte stream * transports. (It also allows building mock interfaces for testing the correct * functioning of the library.) * * `fstrm_rdwr` is a low-level interface that is used in conjunction with the * higher level \ref fstrm_reader and \ref fstrm_writer interfaces. The * following methods need to be defined for `fstrm_rdwr` implementations: * * Method name | Method type | Method description * ------------ | ----------------------------- | ------------------ * `destroy` | #fstrm_rdwr_destroy_func | Destroys the instance. * `open` | #fstrm_rdwr_open_func | Opens the stream. * `close` | #fstrm_rdwr_close_func | Closes the stream. * `read` | #fstrm_rdwr_read_func | Reads bytes from the stream. * `write` | #fstrm_rdwr_write_func | Writes bytes to the stream. * * The `destroy` method is optional. It cleans up any remaining resources * associated with the instance. * * The `open` method is required. It should perform the actual opening of the * byte stream and prepare it to read or write data. * * The `close` method is required. It should perform the actual closing of the * byte stream. * * If the `fstrm_rdwr` object is to be used in an `fstrm_reader` object, it must * have a `read` method. If the `fstrm_rdwr` object embedded in an * `fstrm_reader` object also has a `write` method, the stream will be * considered bi-directional (that is, it supports both reading and writing) and * handshaking will be performed. If a `read` method is supplied but a `write` * method is not, the reader's stream will instead be considered * uni-directional. See \ref fstrm_reader for details. * * If the `fstrm_rdwr` object is to be used in an `fstrm_writer` object, it must * have a `write` method. If the `fstrm_rdwr` object embedded in an * `fstrm_writer` object also has a `read` method, the stream will be considered * bi-directional and shaking will be performed. If a `write` method is supplied * but a `read` method is not, the writer's stream will instead be considered * uni-directional. See \ref fstrm_writer for details. * * An `fstrm_rdwr` instance is created with a call to `fstrm_rdwr_init()`, * optionally passing a pointer to some state object associated with the * instance. This pointer will be passed as the first argument to each of the * methods described above. Then, the various `fstrm_rdwr_set_*()` functions * should be used to configure the functions to be used to invoke the methods * required for the `fstrm_rdwr` object. * * @{ */ /** * `destroy` method function type. This method is invoked to deallocate any * per-stream resources used by an `fstrm_rdwr` implementation. * * \see fstrm_rdwr_set_destroy() * * \param obj * The `obj` value passed to `fstrm_rdwr_init()`. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ typedef fstrm_res (*fstrm_rdwr_destroy_func)(void *obj); /** * `open` method function type. This method is invoked to open the stream and * prepare it for reading or writing. For example, if an `fstrm_rdwr` * implementation is backed by file I/O, this method might be responsible for * opening a file descriptor. * * \see fstrm_rdwr_set_open() * * \param obj * The `obj` value passed to `fstrm_rdwr_init()`. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ typedef fstrm_res (*fstrm_rdwr_open_func)(void *obj); /** * `close` method function type. This method is invoked to close the stream. For * example, if an `fstrm_rdwr` implementation is backed by file I/O, this method * might be responsible for closing a file descriptor. * * \see fstrm_rdwr_set_close() * * \param obj * The `obj` value passed to `fstrm_rdwr_init()`. * * \retval #fstrm_res_success * \retval #fstrm_res_failure */ typedef fstrm_res (*fstrm_rdwr_close_func)(void *obj); /** * `read` method function type. This method is used to read data from a stream. * It must satisfy the full amount of data requested, unless the stream has * ended. * * \see fstrm_rdwr_set_read() * * \param obj * The `obj` value passed to `fstrm_rdwr_init()`. * \param data * The buffer in which to place the data read. * \param count * The number of bytes requested. * * \retval #fstrm_res_success * The data was read successfully. * \retval #fstrm_res_failure * An unexpected failure occurred. * \retval #fstrm_res_stop * The end of the stream has occurred. */ typedef fstrm_res (*fstrm_rdwr_read_func)(void *obj, void *data, size_t count); /** * `write` method function type. This method is used to write data to a stream. * It must perform the full write of all data, unless an error has occurred. * * \see fstrm_rdwr_set_write() * * \param obj * The `obj` value passed to `fstrm_rdwr_init()`. * \param iov * Array of `struct iovec` objects. * \param iovcnt * Number of `struct iovec` objects in `iov`. * * \return #fstrm_res_success * \return #fstrm_res_failure */ typedef fstrm_res (*fstrm_rdwr_write_func)(void *obj, const struct iovec *iov, int iovcnt); /** * Initialize a new `fstrm_rdwr` object. * * \param obj * Per-object state. * * \return * `fstrm_rdwr` object. * \retval * NULL on failure. */ struct fstrm_rdwr * fstrm_rdwr_init(void *obj); /** * Destroy an `fstrm_rdwr` object. This invokes the underlying `destroy` method * as well. * * \param rdwr * Pointer to an `fstrm_rdwr` object. * * \return #fstrm_res_success * \return #fstrm_res_failure */ fstrm_res fstrm_rdwr_destroy(struct fstrm_rdwr **rdwr); /** * Invoke the `open` method on an `fstrm_rdwr` object. * * \param rdwr * The `fstrm_rdwr` object. * * \return #fstrm_res_success * \return #fstrm_res_failure */ fstrm_res fstrm_rdwr_open(struct fstrm_rdwr *rdwr); /** * Invoke the `close` method on an `fstrm_rdwr` object. * * \param rdwr * The `fstrm_rdwr` object. * * \return #fstrm_res_success * \return #fstrm_res_failure */ fstrm_res fstrm_rdwr_close(struct fstrm_rdwr *rdwr); /** * Invoke the `read` method on an `fstrm_rdwr` object. * * \param rdwr * The `fstrm_rdwr` object. * \param data * The buffer in which to place the data read. * \param count * The number of bytes to read. * * \return #fstrm_res_success * \return #fstrm_res_failure * \return #fstrm_res_stop */ fstrm_res fstrm_rdwr_read(struct fstrm_rdwr *rdwr, void *data, size_t count); /** * Invoke the `write` method on an `fstrm_rdwr` object. * * \param rdwr * The `fstrm_rdwr` object. * \param iov * Array of `struct iovec` objects. * \param iovcnt * Number of `struct iovec` objects in `iov`. * * \return #fstrm_res_success * \return #fstrm_res_failure */ fstrm_res fstrm_rdwr_write(struct fstrm_rdwr *rdwr, const struct iovec *iov, int iovcnt); /** * Set the `destroy` method for an `fstrm_rdwr` object. * * \param rdwr * The `fstrm_rdwr` object. * \param fn * Function to use. */ void fstrm_rdwr_set_destroy( struct fstrm_rdwr *rdwr, fstrm_rdwr_destroy_func fn); /** * Set the `open` method for an `fstrm_rdwr` object. * * \param rdwr * The `fstrm_rdwr` object. * \param fn * Function to use. */ void fstrm_rdwr_set_open( struct fstrm_rdwr *rdwr, fstrm_rdwr_open_func fn); /** * Set the `close` method for an `fstrm_rdwr` object. * * \param rdwr * The `fstrm_rdwr` object. * \param fn * Function to use. */ void fstrm_rdwr_set_close( struct fstrm_rdwr *rdwr, fstrm_rdwr_close_func fn); /** * Set the `read` method for an `fstrm_rdwr` object. * * \param rdwr * The `fstrm_rdwr` object. * \param fn * Function to use. */ void fstrm_rdwr_set_read( struct fstrm_rdwr *rdwr, fstrm_rdwr_read_func fn); /** * Set the `write` method for an `fstrm_rdwr` object. * * \param rdwr * The `fstrm_rdwr` object. * \param fn * Function to use. */ void fstrm_rdwr_set_write( struct fstrm_rdwr *rdwr, fstrm_rdwr_write_func fn); /**@}*/ #endif /* FSTRM_RDWR_H */ PK|Z`f file.hnu[PK|Zqn  tcp_writer.hnu[PK|Z(x<x<iothr.hnu[PK|ZS S Vunix_writer.hnu[PK|Z[sF(PP 7bcontrol.hnu[PK|Z+0reader.hnu[PK|Zw!! writer.hnu[PK|Z&]K%K%Yrdwr.hnu[PKE