mirror of
https://github.com/weechat/weechat.git
synced 2026-07-10 11:43:13 +02:00
relay/api: fix decoding of large websocket frames in remote client (closes #2107)
This commit is contained in:
@@ -466,8 +466,8 @@ relay_remote_network_recv_buffer (struct t_relay_remote *remote,
|
||||
const char *buffer, int buffer_size)
|
||||
{
|
||||
struct t_relay_websocket_frame *frames;
|
||||
char *partial_ws_frame;
|
||||
int rc, i, num_frames, partial_ws_frame_size;
|
||||
int rc, i, buffer2_size, num_frames;
|
||||
char *buffer2;
|
||||
|
||||
/* if authenticating is in progress, check if it was successful */
|
||||
if (remote->status == RELAY_STATUS_AUTHENTICATING)
|
||||
@@ -476,26 +476,51 @@ relay_remote_network_recv_buffer (struct t_relay_remote *remote,
|
||||
}
|
||||
else if (remote->status == RELAY_STATUS_CONNECTED)
|
||||
{
|
||||
partial_ws_frame = NULL;
|
||||
partial_ws_frame_size = 0;
|
||||
buffer2 = NULL;
|
||||
buffer2_size = 0;
|
||||
if (remote->partial_ws_frame)
|
||||
{
|
||||
buffer2_size = buffer_size + remote->partial_ws_frame_size;
|
||||
buffer2 = malloc (buffer2_size);
|
||||
if (!buffer2)
|
||||
{
|
||||
weechat_printf (
|
||||
NULL,
|
||||
_("%sremote[%s]: not enough memory"),
|
||||
weechat_prefix ("error"),
|
||||
remote->name);
|
||||
return;
|
||||
}
|
||||
memcpy (buffer2, remote->partial_ws_frame,
|
||||
remote->partial_ws_frame_size);
|
||||
memcpy (buffer2 + remote->partial_ws_frame_size,
|
||||
buffer, buffer_size);
|
||||
}
|
||||
frames = NULL;
|
||||
num_frames = 0;
|
||||
rc = relay_websocket_decode_frame (
|
||||
(const unsigned char *)buffer,
|
||||
buffer_size,
|
||||
(buffer2) ? (unsigned char *)buffer2 : (const unsigned char *)buffer,
|
||||
(buffer2) ? (unsigned long long)buffer2_size : (unsigned long long)buffer_size,
|
||||
0, /* expect_masked_frame */
|
||||
remote->ws_deflate,
|
||||
&frames,
|
||||
&num_frames,
|
||||
&partial_ws_frame,
|
||||
&partial_ws_frame_size);
|
||||
&remote->partial_ws_frame,
|
||||
&remote->partial_ws_frame_size);
|
||||
if (buffer2)
|
||||
free (buffer2);
|
||||
if (!rc)
|
||||
{
|
||||
/* fatal error when decoding frame: close connection */
|
||||
for (i = 0; i < num_frames; i++)
|
||||
if (frames)
|
||||
{
|
||||
if (frames[i].payload)
|
||||
free (frames[i].payload);
|
||||
for (i = 0; i < num_frames; i++)
|
||||
{
|
||||
if (frames[i].payload)
|
||||
free (frames[i].payload);
|
||||
}
|
||||
free (frames);
|
||||
}
|
||||
free (frames);
|
||||
weechat_printf (
|
||||
NULL,
|
||||
_("%sremote[%s]: error decoding websocket frame"),
|
||||
|
||||
@@ -327,6 +327,8 @@ relay_remote_alloc (const char *name)
|
||||
new_remote->gnutls_sess = NULL;
|
||||
new_remote->ws_deflate = relay_websocket_deflate_alloc ();
|
||||
new_remote->synced = 0;
|
||||
new_remote->partial_ws_frame = NULL;
|
||||
new_remote->partial_ws_frame_size = 0;
|
||||
new_remote->prev_remote = NULL;
|
||||
new_remote->next_remote = NULL;
|
||||
|
||||
@@ -487,7 +489,8 @@ relay_remote_new_with_infolist (struct t_infolist *infolist)
|
||||
{
|
||||
struct t_relay_remote *new_remote;
|
||||
Bytef *ptr_dict;
|
||||
int dict_size;
|
||||
int dict_size, ws_frame_size;
|
||||
void *ptr_ws_frame;
|
||||
|
||||
new_remote = malloc (sizeof (*new_remote));
|
||||
if (!new_remote)
|
||||
@@ -550,6 +553,16 @@ relay_remote_new_with_infolist (struct t_infolist *infolist)
|
||||
}
|
||||
}
|
||||
new_remote->synced = weechat_infolist_integer (infolist, "synced");
|
||||
ptr_ws_frame = weechat_infolist_buffer (infolist, "partial_ws_frame", &ws_frame_size);
|
||||
if (ptr_ws_frame && (ws_frame_size > 0))
|
||||
{
|
||||
new_remote->partial_ws_frame = malloc (ws_frame_size);
|
||||
if (new_remote->partial_ws_frame)
|
||||
{
|
||||
memcpy (new_remote->partial_ws_frame, ptr_ws_frame, ws_frame_size);
|
||||
new_remote->partial_ws_frame_size = ws_frame_size;
|
||||
}
|
||||
}
|
||||
new_remote->prev_remote = NULL;
|
||||
new_remote->next_remote = relay_remotes;
|
||||
if (relay_remotes)
|
||||
@@ -766,6 +779,8 @@ relay_remote_free (struct t_relay_remote *remote)
|
||||
if (remote->hook_fd)
|
||||
weechat_unhook (remote->hook_fd);
|
||||
relay_websocket_deflate_free (remote->ws_deflate);
|
||||
if (remote->partial_ws_frame)
|
||||
free (remote->partial_ws_frame);
|
||||
|
||||
free (remote);
|
||||
|
||||
@@ -835,6 +850,8 @@ relay_remote_add_to_infolist (struct t_infolist *infolist,
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "sock", -1))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_buffer (ptr_item, "partial_ws_frame", NULL, 0))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -842,6 +859,8 @@ relay_remote_add_to_infolist (struct t_infolist *infolist,
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "sock", remote->sock))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_buffer (ptr_item, "partial_ws_frame", remote->partial_ws_frame, remote->partial_ws_frame_size))
|
||||
return 0;
|
||||
}
|
||||
if (remote->ws_deflate->strm_deflate || remote->ws_deflate->strm_inflate)
|
||||
{
|
||||
@@ -916,6 +935,9 @@ relay_remote_print_log ()
|
||||
weechat_log_printf (" gnutls_sess . . . . . . : 0x%lx", ptr_remote->gnutls_sess);
|
||||
relay_websocket_deflate_print_log (ptr_remote->ws_deflate, "");
|
||||
weechat_log_printf (" synced. . . . . . . . . : %d", ptr_remote->synced);
|
||||
weechat_log_printf (" partial_ws_frame. . . . . : %p (%d bytes)",
|
||||
ptr_remote->partial_ws_frame,
|
||||
ptr_remote->partial_ws_frame_size);
|
||||
weechat_log_printf (" prev_remote . . . . . . : 0x%lx", ptr_remote->prev_remote);
|
||||
weechat_log_printf (" next_remote . . . . . . : 0x%lx", ptr_remote->next_remote);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@ struct t_relay_remote
|
||||
gnutls_session_t gnutls_sess; /* gnutls session (only if TLS used) */
|
||||
struct t_relay_websocket_deflate *ws_deflate; /* websocket deflate data */
|
||||
int synced; /* 1 if synced with remote */
|
||||
char *partial_ws_frame; /* part. binary websocket frame recv */
|
||||
int partial_ws_frame_size; /* size of partial websocket frame */
|
||||
struct t_relay_remote *prev_remote;/* link to previous remote */
|
||||
struct t_relay_remote *next_remote;/* link to next remote */
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user