cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

socket.h (14210B)


      1/*
      2 * Licensed to the Apache Software Foundation (ASF) under one
      3 * or more contributor license agreements.  See the NOTICE file
      4 * distributed with this work for additional information
      5 * regarding copyright ownership.  The ASF licenses this file
      6 * to you under the Apache License, Version 2.0 (the
      7 * "License"); you may not use this file except in compliance
      8 * with the License.  You may obtain a copy of the License at
      9 *
     10 *   http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing,
     13 * software distributed under the License is distributed on an
     14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     15 * KIND, either express or implied.  See the License for the
     16 * specific language governing permissions and limitations
     17 * under the License.
     18 */
     19
     20#ifndef _GUAC_SOCKET_H
     21#define _GUAC_SOCKET_H
     22
     23/**
     24 * Defines the guac_socket object and functionss for using and manipulating it.
     25 *
     26 * @file socket.h
     27 */
     28
     29#include "client-types.h"
     30#include "socket-constants.h"
     31#include "socket-fntypes.h"
     32#include "socket-types.h"
     33#include "timestamp-types.h"
     34
     35#include <pthread.h>
     36#include <stdint.h>
     37#include <unistd.h>
     38
     39struct guac_socket {
     40
     41    /**
     42     * Arbitrary socket-specific data.
     43     */
     44    void* data;
     45
     46    /**
     47     * Handler which will be called when data needs to be read from the socket.
     48     */
     49    guac_socket_read_handler* read_handler;
     50
     51    /**
     52     * Handler which will be called whenever data is written to this socket.
     53     */
     54    guac_socket_write_handler* write_handler;
     55
     56    /**
     57     * Handler which will be called whenever this socket needs to be flushed.
     58     */
     59    guac_socket_flush_handler* flush_handler;
     60
     61    /**
     62     * Handler which will be called whenever a socket needs to be acquired for
     63     * exclusive access, such as when an instruction is about to be written.
     64     */
     65    guac_socket_lock_handler* lock_handler;
     66
     67    /**
     68     * Handler which will be called whenever exclusive access to a socket is
     69     * being released, such as when an instruction has finished being written.
     70     */
     71    guac_socket_unlock_handler* unlock_handler;
     72
     73    /**
     74     * Handler which will be called whenever guac_socket_select() is invoked
     75     * on this socket.
     76     */
     77    guac_socket_select_handler* select_handler;
     78
     79    /**
     80     * Handler which will be called when the socket is free'd (closed).
     81     */
     82    guac_socket_free_handler* free_handler;
     83
     84    /**
     85     * The current state of this guac_socket.
     86     */
     87    guac_socket_state state;
     88
     89    /**
     90     * The timestamp associated with the time the last block of data was
     91     * written to this guac_socket.
     92     */
     93    guac_timestamp last_write_timestamp;
     94
     95    /**
     96     * The number of bytes present in the base64 "ready" buffer.
     97     */
     98    int __ready;
     99
    100    /**
    101     * The base64 "ready" buffer. Once this buffer is filled, base64 data is
    102     * flushed to the main write buffer.
    103     */
    104    int __ready_buf[3];
    105
    106    /**
    107     * Whether automatic keep-alive is enabled.
    108     */
    109    int __keep_alive_enabled;
    110
    111    /**
    112     * The keep-alive thread.
    113     */
    114    pthread_t __keep_alive_thread;
    115
    116};
    117
    118/**
    119 * Allocates a new, completely blank guac_socket. This guac_socket will do
    120 * absolutely nothing when used unless its handlers are defined.
    121 *
    122 * @returns A newly-allocated guac_socket, or NULL if the guac_socket could
    123 *          not be allocated.
    124 */
    125guac_socket* guac_socket_alloc();
    126
    127/**
    128 * Frees the given guac_socket and all associated resources.
    129 *
    130 * @param socket The guac_socket to free.
    131 */
    132void guac_socket_free(guac_socket* socket);
    133
    134/**
    135 * Declares that the given socket must automatically send a keep-alive ping
    136 * to ensure neither side of the socket times out while the socket is open.
    137 * This ping will take the form of a "nop" instruction.
    138 *
    139 * @param socket
    140 *     The guac_socket to declare as requiring an automatic keep-alive ping.
    141 */
    142void guac_socket_require_keep_alive(guac_socket* socket);
    143
    144/**
    145 * Marks the beginning of a Guacamole protocol instruction.
    146 *
    147 * @param socket
    148 *     The guac_socket beginning an instruction.
    149 */
    150void guac_socket_instruction_begin(guac_socket* socket);
    151
    152/**
    153 * Marks the end of a Guacamole protocol instruction.
    154 *
    155 * @param socket
    156 *     The guac_socket ending an instruction.
    157 */
    158void guac_socket_instruction_end(guac_socket* socket);
    159
    160/**
    161 * Allocates and initializes a new guac_socket object with the given open
    162 * file descriptor. The file descriptor will be automatically closed when
    163 * the allocated guac_socket is freed.
    164 *
    165 * If an error occurs while allocating the guac_socket object, NULL is returned,
    166 * and guac_error is set appropriately.
    167 *
    168 * @param fd An open file descriptor that this guac_socket object should manage.
    169 * @return A newly allocated guac_socket object associated with the given
    170 *         file descriptor, or NULL if an error occurs while allocating
    171 *         the guac_socket object.
    172 */
    173guac_socket* guac_socket_open(int fd);
    174
    175/**
    176 * Allocates and initializes a new guac_socket which writes all data via
    177 * nest instructions to the given existing, open guac_socket. Freeing the
    178 * returned guac_socket has no effect on the underlying, nested guac_socket.
    179 *
    180 * If an error occurs while allocating the guac_socket object, NULL is returned,
    181 * and guac_error is set appropriately.
    182 *
    183 * @deprecated
    184 *     The "nest" instruction and the corresponding guac_socket
    185 *     implementation are no longer necessary, having been replaced by
    186 *     the streaming instructions ("blob", "ack", "end"). Code using nested
    187 *     sockets or the "nest" instruction should instead write to a normal
    188 *     socket directly.
    189 *
    190 * @param parent The guac_socket this new guac_socket should write nest
    191 *               instructions to.
    192 * @param index The stream index to use for the written nest instructions.
    193 * @return A newly allocated guac_socket object associated with the given
    194 *         guac_socket and stream index, or NULL if an error occurs while
    195 *         allocating the guac_socket object.
    196 */
    197guac_socket* guac_socket_nest(guac_socket* parent, int index);
    198
    199/**
    200 * Allocates and initializes a new guac_socket which delegates all socket
    201 * operations to the given primary socket, while simultaneously duplicating all
    202 * written data to the secondary socket. Freeing the returned guac_socket will
    203 * free both primary and secondary sockets.
    204 *
    205 * Return values (error codes) will come only from the primary socket. Locks
    206 * (like those used by guac_socket_instruction_begin() and
    207 * guac_socket_instruction_end()) will affect only the primary socket.
    208 *
    209 * If an error occurs while allocating the guac_socket object, NULL is returned,
    210 * and guac_error is set appropriately.
    211 *
    212 * @param primary
    213 *     The primary guac_socket to which all socket operations should be
    214 *     delegated. The error codes returned by socket operations, if any, will
    215 *     always come from this socket. This socket will also be the only socket
    216 *     locked when instructions begin (or unlocked when instructions end).
    217 *
    218 * @param secondary
    219 *     The secondary guac_socket to which all data written to the primary
    220 *     guac_socket should be copied. If an error prevents the write from
    221 *     succeeding, that error will be ignored. Only errors from the primary
    222 *     guac_socket will be acknowledged.
    223 *
    224 * @return
    225 *     A newly allocated guac_socket object associated with the given primary
    226 *     and secondary sockets, or NULL if an error occurs while allocating the
    227 *     guac_socket object.
    228 */
    229guac_socket* guac_socket_tee(guac_socket* primary, guac_socket* secondary);
    230
    231/**
    232 * Allocates and initializes a new guac_socket which duplicates all
    233 * instructions written across the sockets of each connected user of the
    234 * given guac_client. The returned socket is a write-only socket. Attempts
    235 * to read from the socket will fail. If a write occurs while no users are
    236 * connected, that write will simply be dropped.
    237 *
    238 * Return values (error codes) from each user's socket will not affect the
    239 * in-progress write, but each failing user will be forcibly stopped with
    240 * guac_user_stop().
    241 *
    242 * If an error occurs while allocating the guac_socket object, NULL is returned,
    243 * and guac_error is set appropriately.
    244 *
    245 * @param client
    246 *     The client associated with the group of connected users across which
    247 *     duplicates of all instructions should be written.
    248 *
    249 * @return
    250 *     A write-only guac_socket object which broadcasts copies of all
    251 *     instructions written across all non-pending connected users of the given
    252 *     guac_client, or NULL if an error occurs while allocating the guac_socket
    253 *     object.
    254 */
    255guac_socket* guac_socket_broadcast(guac_client* client);
    256
    257/**
    258 * Allocates and initializes a new guac_socket which duplicates all
    259 * instructions written across the sockets of each pending connected
    260 * user of the given guac_client. The returned socket is a write-only socket.
    261 * Attempts to read from the socket will fail.  If a write occurs while no
    262 * users are connected, that write will simply be dropped.
    263 *
    264 * Return values (error codes) from each user's socket will not affect the
    265 * in-progress write, but each failing user will be forcibly stopped with
    266 * guac_user_stop().
    267 *
    268 * If an error occurs while allocating the guac_socket object, NULL is returned,
    269 * and guac_error is set appropriately.
    270 *
    271 * @param client
    272 *     The client associated with the group of pending users across which
    273 *     duplicates of all instructions should be written.
    274 *
    275 * @return
    276 *     A write-only guac_socket object which broadcasts copies of all
    277 *     instructions written across all pending connected users of the given
    278 *     guac_client, or NULL if an error occurs while allocating the guac_socket
    279 *     object.
    280 */
    281guac_socket* guac_socket_broadcast_pending(guac_client* client);
    282
    283/**
    284 * Writes the given unsigned int to the given guac_socket object. The data
    285 * written may be buffered until the buffer is flushed automatically or
    286 * manually.
    287 *
    288 * If an error occurs while writing, a non-zero value is returned, and
    289 * guac_error is set appropriately.
    290 *
    291 * @param socket The guac_socket object to write to.
    292 * @param i The unsigned int to write.
    293 * @return Zero on success, or non-zero if an error occurs while writing.
    294 */
    295ssize_t guac_socket_write_int(guac_socket* socket, int64_t i);
    296
    297/**
    298 * Writes the given string to the given guac_socket object. The data
    299 * written may be buffered until the buffer is flushed automatically or
    300 * manually.
    301 *
    302 * If an error occurs while writing, a non-zero value is returned, and
    303 * guac_error is set appropriately.
    304 *
    305 * @param socket The guac_socket object to write to.
    306 * @param str The string to write.
    307 * @return Zero on success, or non-zero if an error occurs while writing.
    308*/
    309ssize_t guac_socket_write_string(guac_socket* socket, const char* str);
    310
    311/**
    312 * Writes the given binary data to the given guac_socket object as base64-
    313 * encoded data. The data written may be buffered until the buffer is flushed
    314 * automatically or manually. Beware that, because base64 data is buffered
    315 * on top of the write buffer already used, a call to guac_socket_flush_base64()
    316 * MUST be made before non-base64 writes (or writes of an independent block of
    317 * base64 data) can be made.
    318 *
    319 * If an error occurs while writing, a non-zero value is returned, and
    320 * guac_error is set appropriately.
    321 *
    322 * @param socket The guac_socket object to write to.
    323 * @param buf A buffer containing the data to write.
    324 * @param count The number of bytes to write.
    325 * @return Zero on success, or non-zero if an error occurs while writing.
    326 */
    327ssize_t guac_socket_write_base64(guac_socket* socket, const void* buf, size_t count);
    328
    329/**
    330 * Writes the given data to the specified socket. The data written may be
    331 * buffered until the buffer is flushed automatically or manually.
    332 *
    333 * If an error occurs while writing, a non-zero value is returned, and
    334 * guac_error is set appropriately.
    335 *
    336 * @param socket The guac_socket object to write to.
    337 * @param buf A buffer containing the data to write.
    338 * @param count The number of bytes to write.
    339 * @return Zero on success, or non-zero if an error occurs while writing.
    340 */
    341ssize_t guac_socket_write(guac_socket* socket, const void* buf, size_t count);
    342
    343/**
    344 * Attempts to read data from the socket, filling up to the specified number
    345 * of bytes in the given buffer.
    346 *
    347 * If an error occurs while writing, a non-zero value is returned, and
    348 * guac_error is set appropriately.
    349 *
    350 * @param socket The guac_socket to read from.
    351 * @param buf The buffer to read bytes into.
    352 * @param count The maximum number of bytes to read.
    353 * @return The number of bytes read, or non-zero if an error occurs while
    354 *         reading.
    355 */
    356ssize_t guac_socket_read(guac_socket* socket, void* buf, size_t count);
    357
    358/**
    359 * Flushes the base64 buffer, writing padding characters as necessary.
    360 *
    361 * If an error occurs while writing, a non-zero value is returned, and
    362 * guac_error is set appropriately.
    363 *
    364 * @param socket The guac_socket object to flush
    365 * @return Zero on success, or non-zero if an error occurs during flush.
    366 */
    367ssize_t guac_socket_flush_base64(guac_socket* socket);
    368
    369/**
    370 * Flushes the write buffer.
    371 *
    372 * If an error occurs while writing, a non-zero value is returned, and
    373 * guac_error is set appropriately.
    374 *
    375 * @param socket The guac_socket object to flush
    376 * @return Zero on success, or non-zero if an error occurs during flush.
    377 */
    378ssize_t guac_socket_flush(guac_socket* socket);
    379
    380/**
    381 * Waits for input to be available on the given guac_socket object until the
    382 * specified timeout elapses.
    383 *
    384 * If an error occurs while waiting, a negative value is returned, and
    385 * guac_error is set appropriately.
    386 *
    387 * If a timeout occurs while waiting, zero value is returned, and
    388 * guac_error is set to GUAC_STATUS_INPUT_TIMEOUT.
    389 *
    390 * @param socket The guac_socket object to wait for.
    391 * @param usec_timeout The maximum number of microseconds to wait for data, or
    392 *                     -1 to potentially wait forever.
    393 * @return Positive on success, zero if the timeout elapsed and no data is
    394 *         available, negative on error.
    395 */
    396int guac_socket_select(guac_socket* socket, int usec_timeout);
    397
    398#endif
    399