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