�ɲɾ�����ӯ�����һ��ˣ��������С���˴��ͣ�������P���ҹ��ñ˽��ά�Բ��������˸߸ԣ�������ơ��ҹ��ñ�����ά�Բ���ˡ���˳^�ӣ������ӡ� ���ͯj�ӣ��ƺ���ӣ� ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!PK0]2 ..LICENSEnu[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. PK0]2 .. COPYRIGHTnu[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. PKjM1]`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 */ PKjM1](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 */ PKjM1]qn 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 */ PKjM1]S 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 */ PKjM1]+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 */ PKjM1]w!!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 */ PKjM1]&]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 */ PKjM1][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 */ PK0]2 ..LICENSEnu[PK0]2 .. eCOPYRIGHTnu[PKjM1]`f file.hnu[PKjM1](x<x<iothr.hnu[PKjM1]qn ?Rtcp_writer.hnu[PKjM1]S S s_unix_writer.hnu[PKjM1]+0kreader.hnu[PKjM1]w!!writer.hnu[PKjM1]&]K%K%erdwr.hnu[PKjM1][sF(PP control.hnu[PK "