diff --git a/src/libguac/audio.c b/src/libguac/audio.c index cc577c71..0f6a6aad 100644 --- a/src/libguac/audio.c +++ b/src/libguac/audio.c @@ -117,6 +117,12 @@ guac_audio_stream* guac_audio_stream_alloc(guac_client* client, audio->client = client; audio->stream = guac_client_alloc_stream(client); + /* Abort allocation if underlying stream cannot be allocated */ + if (audio->stream == NULL) { + free(audio); + return NULL; + } + /* Load PCM properties */ audio->rate = rate; audio->channels = channels; @@ -188,6 +194,9 @@ void guac_audio_stream_free(guac_audio_stream* audio) { if (audio->encoder != NULL && audio->encoder->end_handler) audio->encoder->end_handler(audio); + /* Release stream back to client pool */ + guac_client_free_stream(audio->client, audio->stream); + /* Free associated data */ free(audio); diff --git a/src/libguac/guacamole/audio.h b/src/libguac/guacamole/audio.h index df41772f..2f030ec4 100644 --- a/src/libguac/guacamole/audio.h +++ b/src/libguac/guacamole/audio.h @@ -148,7 +148,8 @@ struct guac_audio_stream { * @return * The newly allocated guac_audio_stream, or NULL if no audio stream could * be allocated due to lack of support on the part of the connecting - * Guacamole client. + * Guacamole client or due to reaching the maximum number of active + * streams. */ guac_audio_stream* guac_audio_stream_alloc(guac_client* client, guac_audio_encoder* encoder, int rate, int channels, int bps); diff --git a/src/libguac/guacamole/client.h b/src/libguac/guacamole/client.h index 88d1f416..71d48f22 100644 --- a/src/libguac/guacamole/client.h +++ b/src/libguac/guacamole/client.h @@ -383,7 +383,8 @@ void guac_client_free_layer(guac_client* client, guac_layer* layer); * The client to allocate the stream for. * * @return - * The next available stream, or a newly allocated stream. + * The next available stream, or a newly allocated stream, or NULL if the + * maximum number of active streams has been reached. */ guac_stream* guac_client_alloc_stream(guac_client* client); diff --git a/src/libguac/guacamole/user.h b/src/libguac/guacamole/user.h index 702160fa..fac42b98 100644 --- a/src/libguac/guacamole/user.h +++ b/src/libguac/guacamole/user.h @@ -574,8 +574,12 @@ int guac_user_handle_instruction(guac_user* user, const char* opcode, * Allocates a new stream. An arbitrary index is automatically assigned * if no previously-allocated stream is available for use. * - * @param user The user to allocate the stream for. - * @return The next available stream, or a newly allocated stream. + * @param user + * The user to allocate the stream for. + * + * @return + * The next available stream, or a newly allocated stream, or NULL if the + * maximum number of active streams has been reached. */ guac_stream* guac_user_alloc_stream(guac_user* user); diff --git a/src/protocols/rdp/beep.c b/src/protocols/rdp/beep.c index e91a7afe..46e80fd5 100644 --- a/src/protocols/rdp/beep.c +++ b/src/protocols/rdp/beep.c @@ -123,6 +123,15 @@ BOOL guac_rdp_beep_play_sound(rdpContext* context, guac_audio_stream* beep = guac_audio_stream_alloc(client, NULL, GUAC_RDP_BEEP_SAMPLE_RATE, 1, 8); + /* Stream availability is not guaranteed */ + if (beep == NULL) { + guac_client_log(client, GUAC_LOG_DEBUG, "Ignoring request to beep " + "for %" PRIu32 " millseconds at %" PRIu32 " Hz as no audio " + "stream could be allocated.", play_sound->duration, + play_sound->frequency); + return TRUE; + } + /* Limit maximum duration of each beep */ int duration = play_sound->duration; if (duration > GUAC_RDP_BEEP_MAX_DURATION)