[asterisk-commits] mjordan: branch mjordan/12-careful-ws r416576 - in /team/mjordan/12-careful-w...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jun 18 09:21:37 CDT 2014
Author: mjordan
Date: Wed Jun 18 09:21:29 2014
New Revision: 416576
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=416576
Log:
Add careful write stuff for websockets + config options
Modified:
team/mjordan/12-careful-ws/UPGRADE.txt
team/mjordan/12-careful-ws/channels/chan_sip.c
team/mjordan/12-careful-ws/channels/sip/include/sip.h
team/mjordan/12-careful-ws/configs/ari.conf.sample
team/mjordan/12-careful-ws/configs/sip.conf.sample
team/mjordan/12-careful-ws/include/asterisk/http_websocket.h
team/mjordan/12-careful-ws/include/asterisk/res_pjsip.h
team/mjordan/12-careful-ws/res/ari/ari_websockets.c
team/mjordan/12-careful-ws/res/ari/config.c
team/mjordan/12-careful-ws/res/ari/internal.h
team/mjordan/12-careful-ws/res/res_ari.c
team/mjordan/12-careful-ws/res/res_http_websocket.c
team/mjordan/12-careful-ws/res/res_pjsip/config_transport.c
team/mjordan/12-careful-ws/res/res_pjsip_transport_websocket.c
Modified: team/mjordan/12-careful-ws/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/UPGRADE.txt?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/UPGRADE.txt (original)
+++ team/mjordan/12-careful-ws/UPGRADE.txt Wed Jun 18 09:21:29 2014
@@ -34,6 +34,11 @@
accordingly. The changed strings are:
- "Exited on signal $EXITSIGNAL" => "Asterisk exited on signal $EXITSIGNAL."
- "Asterisk Died" => "Asterisk on $MACHINE died (sig $EXITSIGNAL)"
+
+ - Added a compatibility option for chan_sip, 'websocket_write_timeout'.
+ When connections exist where Asterisk writes a substantial amount of data
+ and the connected clients are slow to process the received data, it may be
+ necessary to adjust this value. Default is 100 ms.
From 12.3.0 to 12.3.1:
Modified: team/mjordan/12-careful-ws/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/channels/chan_sip.c?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/channels/chan_sip.c (original)
+++ team/mjordan/12-careful-ws/channels/chan_sip.c Wed Jun 18 09:21:29 2014
@@ -2668,6 +2668,10 @@
goto end;
}
+ if (ast_websocket_set_timeout(session, sip_cfg.websocket_write_timeout)) {
+ goto end;
+ }
+
while ((res = ast_wait_for_input(ast_websocket_fd(session), -1)) > 0) {
char *payload;
uint64_t payload_len;
@@ -32215,6 +32219,12 @@
ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
} else if (!strcasecmp(v->name, "refer_addheaders")) {
global_refer_addheaders = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "websocket_write_timeout")) {
+ if (sscanf(v->value, "%30d", &sip_cfg.websocket_write_timeout) != 1
+ || sip_cfg.websocket_write_timeout < 0) {
+ ast_log(LOG_WARNING, "'%s' is not a valid websocket_write_timeout value at line %d. Using default.\n", v->value, v->lineno);
+ sip_cfg.websocket_write_timeout = DEFAULT_WEBSOCKET_WRITE_TIMEOUT;
+ }
}
}
Modified: team/mjordan/12-careful-ws/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/channels/sip/include/sip.h?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/channels/sip/include/sip.h (original)
+++ team/mjordan/12-careful-ws/channels/sip/include/sip.h Wed Jun 18 09:21:29 2014
@@ -771,6 +771,7 @@
struct ast_format_cap *caps; /*!< Supported codecs */
int tcp_enabled;
int default_max_forwards; /*!< Default max forwards (SIP Anti-loop) */
+ int websocket_write_timeout; /*!< Socket write timeout for websocket transports, in ms */
};
struct ast_websocket;
Modified: team/mjordan/12-careful-ws/configs/ari.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/configs/ari.conf.sample?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/configs/ari.conf.sample (original)
+++ team/mjordan/12-careful-ws/configs/ari.conf.sample Wed Jun 18 09:21:29 2014
@@ -22,3 +22,9 @@
; When set to plain, the password is in plaintext.
;
;password_format = plain
+;
+; If the connection for this user accepts input slowly,
+; the timeout for writes to it can be increased to keep it
+; from being disconnected (value is in milliseconds)
+;
+;write_timeout = 100
Modified: team/mjordan/12-careful-ws/configs/sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/configs/sip.conf.sample?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/configs/sip.conf.sample (original)
+++ team/mjordan/12-careful-ws/configs/sip.conf.sample Wed Jun 18 09:21:29 2014
@@ -228,6 +228,12 @@
;tcpauthlimit = 100 ; tcpauthlimit specifies the maximum number of
; unauthenticated sessions that will be allowed
; to connect at any given time. (default: 100)
+
+;websocket_write_timeout = 100 ; Default write timeout to set on websocket transports.
+ ; This value may need to be adjusted for connections where
+ ; Asterisk must write a substantial amount of data and the
+ ; receiving clients are slow to process the received information.
+ ; Value is in milliseconds; default is 100 ms.
transport=udp ; Set the default transports. The order determines the primary default transport.
; If tcpenable=no and the transport set is tcp, we will fallback to UDP.
Modified: team/mjordan/12-careful-ws/include/asterisk/http_websocket.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/include/asterisk/http_websocket.h?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/include/asterisk/http_websocket.h (original)
+++ team/mjordan/12-careful-ws/include/asterisk/http_websocket.h Wed Jun 18 09:21:29 2014
@@ -23,6 +23,12 @@
#include "asterisk/optional_api.h"
#include <errno.h>
+
+/*! \brief Default websocket write timeout, in ms */
+#define DEFAULT_WEBSOCKET_WRITE_TIMEOUT 100
+
+/*! \brief Default websocket write timeout, in ms (as a string) */
+#define DEFAULT_WEBSOCKET_WRITE_TIMEOUT_STR "100"
/*!
* \file http_websocket.h
@@ -234,4 +240,14 @@
*/
AST_OPTIONAL_API(int, ast_websocket_set_nonblock, (struct ast_websocket *session), { errno = ENOSYS; return -1;});
+/*!
+ * \brief Set the timeout on a non-blocking WebSocket session.
+ *
+ * \since 11.11.0
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+AST_OPTIONAL_API(int, ast_websocket_set_timeout, (struct ast_websocket *session, int timeout), {return -1;});
+
#endif
Modified: team/mjordan/12-careful-ws/include/asterisk/res_pjsip.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/include/asterisk/res_pjsip.h?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/include/asterisk/res_pjsip.h (original)
+++ team/mjordan/12-careful-ws/include/asterisk/res_pjsip.h Wed Jun 18 09:21:29 2014
@@ -126,6 +126,8 @@
unsigned int tos;
/*! QOS COS value */
unsigned int cos;
+ /*! Write timeout */
+ int write_timeout;
};
/*!
Modified: team/mjordan/12-careful-ws/res/ari/ari_websockets.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/res/ari/ari_websockets.c?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/res/ari/ari_websockets.c (original)
+++ team/mjordan/12-careful-ws/res/ari/ari_websockets.c Wed Jun 18 09:21:29 2014
@@ -56,8 +56,13 @@
struct ast_websocket *ws_session, int (*validator)(struct ast_json *))
{
RAII_VAR(struct ast_ari_websocket_session *, session, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_ari_conf *, config, ast_ari_config_get(), ao2_cleanup);
if (ws_session == NULL) {
+ return NULL;
+ }
+
+ if (config == NULL || config->general == NULL) {
return NULL;
}
@@ -70,6 +75,11 @@
"ARI web socket failed to set nonblock; closing: %s\n",
strerror(errno));
return NULL;
+ }
+
+ if (ast_websocket_set_timeout(ws_session, config->general->write_timeout)) {
+ ast_log(LOG_WARNING, "Failed to set write timeout %d on ARI web socket\n",
+ config->general->write_timeout);
}
session = ao2_alloc(sizeof(*session), websocket_session_dtor);
Modified: team/mjordan/12-careful-ws/res/ari/config.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/res/ari/config.c?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/res/ari/config.c (original)
+++ team/mjordan/12-careful-ws/res/ari/config.c Wed Jun 18 09:21:29 2014
@@ -27,6 +27,7 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/config_options.h"
+#include "asterisk/http_websocket.h"
#include "internal.h"
/*! \brief Locking container for safe configuration access. */
@@ -320,6 +321,9 @@
aco_option_register(&cfg_info, "allowed_origins", ACO_EXACT, general_options,
"", OPT_STRINGFIELD_T, 0,
STRFLDSET(struct ast_ari_conf_general, allowed_origins));
+ aco_option_register(&cfg_info, "write_timeout", ACO_EXACT, general_options,
+ DEFAULT_WEBSOCKET_WRITE_TIMEOUT_STR, OPT_INT_T, PARSE_IN_RANGE,
+ FLDSET(struct ast_ari_conf_general, write_timeout), 1, INT_MAX);
aco_option_register(&cfg_info, "type", ACO_EXACT, user, NULL,
OPT_NOOP_T, 0, 0);
Modified: team/mjordan/12-careful-ws/res/ari/internal.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/res/ari/internal.h?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/res/ari/internal.h (original)
+++ team/mjordan/12-careful-ws/res/ari/internal.h Wed Jun 18 09:21:29 2014
@@ -65,6 +65,8 @@
struct ast_ari_conf_general {
/*! Enabled by default, disabled if false. */
int enabled;
+ /*! Write timeout for websocket connections */
+ int write_timeout;
/*! Encoding format used during output (default compact). */
enum ast_json_encoding_format format;
/*! Authentication realm */
Modified: team/mjordan/12-careful-ws/res/res_ari.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/res/res_ari.c?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/res/res_ari.c (original)
+++ team/mjordan/12-careful-ws/res/res_ari.c Wed Jun 18 09:21:29 2014
@@ -94,6 +94,14 @@
<ref type="filename">http.conf</ref>
<ref type="link">https://wiki.asterisk.org/wiki/display/AST/Asterisk+Builtin+mini-HTTP+Server</ref>
</see-also>
+ </configOption>
+ <configOption name="write_timeout">
+ <synopsis>The timeout (in milliseconds) to set on WebSocket connections for this user.</synopsis>
+ <description>
+ <para>If the connection for this user accepts input slowly,
+ the timeout for writes to it can be increased to keep it
+ from being disconnected (value is in milliseconds)</para>
+ </description>
</configOption>
<configOption name="pretty">
<synopsis>Responses from ARI are formatted to be human readable</synopsis>
Modified: team/mjordan/12-careful-ws/res/res_http_websocket.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/res/res_http_websocket.c?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/res/res_http_websocket.c (original)
+++ team/mjordan/12-careful-ws/res/res_http_websocket.c Wed Jun 18 09:21:29 2014
@@ -68,6 +68,9 @@
#define MAX_WS_HDR_SZ 14
#define MIN_WS_HDR_SZ 2
+/*! \brief Default socket timeout, in ms */
+#define DEFAULT_WEBSOCKET_TIMEOUT 100
+
/*! \brief Structure definition for session */
struct ast_websocket {
FILE *f; /*!< Pointer to the file instance used for writing and reading */
@@ -77,6 +80,7 @@
size_t payload_len; /*!< Length of the payload */
char *payload; /*!< Pointer to the payload */
size_t reconstruct; /*!< Number of bytes before a reconstructed payload will be returned and a new one started */
+ int timeout; /*!< The timeout for operations on the socket */
unsigned int secure:1; /*!< Bit to indicate that the transport is secure */
unsigned int closing:1; /*!< Bit to indicate that the session is in the process of being closed */
unsigned int close_sent:1; /*!< Bit to indicate that the session close opcode has been sent and no further data will be sent */
@@ -255,7 +259,7 @@
session->close_sent = 1;
ao2_lock(session);
- res = (fwrite(frame, 1, 4, session->f) == 4) ? 0 : -1;
+ res = ast_careful_fwrite(session->f, session->fd, frame, 4, session->timeout);
ao2_unlock(session);
return res;
}
@@ -298,13 +302,12 @@
ao2_unlock(session);
return -1;
}
-
- if (fwrite(frame, 1, header_size, session->f) != header_size) {
+ if (ast_careful_fwrite(session->f, session->fd, frame, header_size, session->timeout)) {
ao2_unlock(session);
return -1;
}
- if (fwrite(payload, 1, actual_length, session->f) != actual_length) {
+ if (ast_careful_fwrite(session->f, session->fd, payload, actual_length, session->timeout)) {
ao2_unlock(session);
return -1;
}
@@ -362,6 +365,13 @@
if ((flags = fcntl(session->fd, F_SETFL, flags)) == -1) {
return -1;
}
+
+ return 0;
+}
+
+int AST_OPTIONAL_API_NAME(ast_websocket_set_timeout)(struct ast_websocket *session, int timeout)
+{
+ session->timeout = timeout;
return 0;
}
@@ -511,7 +521,11 @@
/* Per the RFC for PING we need to send back an opcode with the application data as received */
if (*opcode == AST_WEBSOCKET_OPCODE_PING) {
- ast_websocket_write(session, AST_WEBSOCKET_OPCODE_PONG, *payload, *payload_len);
+ if (ast_websocket_write(session, AST_WEBSOCKET_OPCODE_PONG, *payload, *payload_len)) {
+ *payload_len = 0;
+ ast_websocket_close(session, 1009);
+ return 0;
+ }
}
session->payload = new_payload;
@@ -685,6 +699,7 @@
ao2_ref(protocol_handler, -1);
return 0;
}
+ session->timeout = DEFAULT_WEBSOCKET_TIMEOUT;
combined = ast_alloca(combined_length);
snprintf(combined, combined_length, "%s%s", key, WEBSOCKET_GUID);
Modified: team/mjordan/12-careful-ws/res/res_pjsip/config_transport.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/res/res_pjsip/config_transport.c?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/res/res_pjsip/config_transport.c (original)
+++ team/mjordan/12-careful-ws/res/res_pjsip/config_transport.c Wed Jun 18 09:21:29 2014
@@ -28,6 +28,7 @@
#include "asterisk/sorcery.h"
#include "asterisk/acl.h"
#include "include/res_pjsip_private.h"
+#include "asterisk/http_websocket.h"
static int sip_transport_to_ami(const struct ast_sip_transport *transport,
struct ast_str **buf)
@@ -668,6 +669,7 @@
ast_sorcery_object_field_register_custom(sorcery, "transport", "local_net", "", transport_localnet_handler, localnet_to_str, localnet_to_vl, 0, 0);
ast_sorcery_object_field_register_custom(sorcery, "transport", "tos", "0", transport_tos_handler, tos_to_str, NULL, 0, 0);
ast_sorcery_object_field_register(sorcery, "transport", "cos", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_transport, cos));
+ ast_sorcery_object_field_register(sorcery, "transport", "write_timeout", DEFAULT_WEBSOCKET_WRITE_TIMEOUT_STR, OPT_INT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_transport, write_timeout), 1, INT_MAX);
ast_sip_register_endpoint_formatter(&endpoint_transport_formatter);
Modified: team/mjordan/12-careful-ws/res/res_pjsip_transport_websocket.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-careful-ws/res/res_pjsip_transport_websocket.c?view=diff&rev=416576&r1=416575&r2=416576
==============================================================================
--- team/mjordan/12-careful-ws/res/res_pjsip_transport_websocket.c (original)
+++ team/mjordan/12-careful-ws/res/res_pjsip_transport_websocket.c Wed Jun 18 09:21:29 2014
@@ -207,6 +207,39 @@
return (read_data->payload_len == recvd) ? 0 : -1;
}
+static int get_write_timeout(void)
+{
+ int write_timeout = -1;
+ struct ao2_container *transports;
+
+ transports = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "transport", AST_RETRIEVE_FLAG_ALL, NULL);
+
+ if (transports) {
+ struct ao2_iterator it_transports;
+ struct ast_sip_transport *transport;
+
+ for (it_transports = ao2_iterator_init(transports, 0);
+ (transport = ao2_iterator_next(&it_transports));
+ ao2_cleanup(transport)) {
+ if (transport->type != AST_TRANSPORT_WS && transport->type != AST_TRANSPORT_WSS) {
+ continue;
+ }
+ ast_debug(5, "Found %s transport with write timeout: %d\n",
+ transport->type == AST_TRANSPORT_WS ? "WS" : "WSS",
+ transport->write_timeout);
+ write_timeout = MAX(write_timeout, transport->write_timeout);
+ }
+ ao2_cleanup(transports);
+ }
+
+ if (write_timeout < 0) {
+ write_timeout = DEFAULT_WEBSOCKET_WRITE_TIMEOUT;
+ }
+
+ ast_debug(1, "Write timeout for WS/WSS transports: %d\n", write_timeout);
+ return write_timeout;
+}
+
/*!
\brief WebSocket connection handler.
*/
@@ -218,6 +251,11 @@
struct transport_read_data read_data;
if (ast_websocket_set_nonblock(session)) {
+ ast_websocket_unref(session);
+ return;
+ }
+
+ if (ast_websocket_set_timeout(session, get_write_timeout())) {
ast_websocket_unref(session);
return;
}
More information about the asterisk-commits
mailing list