Improved streamdump file format
This commit is contained in:
parent
2a6950f366
commit
60720e7706
@ -395,7 +395,7 @@ int main(int argc, char* argv[])
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!stream_dump_register_handlers(context, CONNECTION_STATE_MCS_CONNECT))
|
||||
if (!stream_dump_register_handlers(context, CONNECTION_STATE_MCS_CONNECT, FALSE))
|
||||
goto fail;
|
||||
|
||||
if (freerdp_client_start(context) != 0)
|
||||
|
@ -65,7 +65,7 @@ int main(int argc, char* argv[])
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!stream_dump_register_handlers(context, CONNECTION_STATE_MCS_CONNECT))
|
||||
if (!stream_dump_register_handlers(context, CONNECTION_STATE_MCS_CONNECT, FALSE))
|
||||
goto out;
|
||||
|
||||
if (freerdp_client_start(context) != 0)
|
||||
|
@ -2374,6 +2374,42 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
{
|
||||
settings->RedirectDrives = enable;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "dump")
|
||||
{
|
||||
BOOL failed = FALSE;
|
||||
size_t count = 0;
|
||||
char** args = CommandLineParseCommaSeparatedValues(arg->Value, &count);
|
||||
if (!args || (count != 2))
|
||||
failed = TRUE;
|
||||
else
|
||||
{
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_TransportDumpFile, args[1]))
|
||||
failed = TRUE;
|
||||
else if (strcmp(args[0], "replay") == 0)
|
||||
{
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_TransportDump, FALSE))
|
||||
failed = TRUE;
|
||||
else if (!freerdp_settings_set_bool(settings, FreeRDP_TransportDumpReplay,
|
||||
TRUE))
|
||||
failed = TRUE;
|
||||
}
|
||||
else if (strcmp(args[0], "record") == 0)
|
||||
{
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_TransportDump, TRUE))
|
||||
failed = TRUE;
|
||||
else if (!freerdp_settings_set_bool(settings, FreeRDP_TransportDumpReplay,
|
||||
FALSE))
|
||||
failed = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
failed = TRUE;
|
||||
}
|
||||
}
|
||||
free(args);
|
||||
if (failed)
|
||||
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "disable-output")
|
||||
{
|
||||
freerdp_settings_set_bool(settings, FreeRDP_DeactivateClientDecoding, enable);
|
||||
|
@ -125,6 +125,8 @@ static const COMMAND_LINE_ARGUMENT_A global_cmd_args[] = {
|
||||
"later\" option in MSTSC." },
|
||||
{ "drives", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
|
||||
"Redirect all mount points as shares" },
|
||||
{ "dump", COMMAND_LINE_VALUE_REQUIRED, "<record|replay>,<file>", NULL, NULL, -1, NULL,
|
||||
"record or replay dump" },
|
||||
{ "dvc", COMMAND_LINE_VALUE_REQUIRED, "<channel>[,<options>]", NULL, NULL, -1, NULL,
|
||||
"Dynamic virtual channel" },
|
||||
{ "dynamic-resolution", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL,
|
||||
|
@ -34,15 +34,19 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
FREERDP_API BOOL stream_dump_read_line(FILE* fp, wStream* s, UINT64* pts, size_t* pOffset);
|
||||
FREERDP_API BOOL stream_dump_write_line(FILE* fp, wStream* s);
|
||||
typedef enum
|
||||
{
|
||||
STREAM_MSG_SRV_RX = 1,
|
||||
STREAM_MSG_SRV_TX = 2
|
||||
} StreamDumpDirection;
|
||||
|
||||
FREERDP_API SSIZE_T stream_dump_append(const rdpContext* context, const char* name, wStream* s,
|
||||
FREERDP_API SSIZE_T stream_dump_append(const rdpContext* context, UINT32 flags, wStream* s,
|
||||
size_t* offset);
|
||||
FREERDP_API SSIZE_T stream_dump_get(const rdpContext* context, const char* name, wStream* s,
|
||||
FREERDP_API SSIZE_T stream_dump_get(const rdpContext* context, UINT32* flags, wStream* s,
|
||||
size_t* offset, UINT64* pts);
|
||||
|
||||
FREERDP_API BOOL stream_dump_register_handlers(rdpContext* context, CONNECTION_STATE state);
|
||||
FREERDP_API BOOL stream_dump_register_handlers(rdpContext* context, CONNECTION_STATE state,
|
||||
BOOL isServer);
|
||||
|
||||
FREERDP_API rdpStreamDumpContext* stream_dump_new(void);
|
||||
FREERDP_API void stream_dump_free(rdpStreamDumpContext* dump);
|
||||
|
@ -1,9 +1,10 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Static Virtual Channel Interface
|
||||
*
|
||||
* Copyright 2021 Armin Novak
|
||||
* Copyright 2021 Thincast Technologies GmbH
|
||||
* RDP session stream dump interface
|
||||
*
|
||||
* Copyright 2022 Armin Novak
|
||||
* Copyright 2022 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -27,6 +28,8 @@
|
||||
#include <freerdp/streamdump.h>
|
||||
#include <freerdp/transport_io.h>
|
||||
|
||||
#include "streamdump.h"
|
||||
|
||||
struct stream_dump_context
|
||||
{
|
||||
rdpTransportIo io;
|
||||
@ -35,16 +38,41 @@ struct stream_dump_context
|
||||
size_t replayOffset;
|
||||
UINT64 replayTime;
|
||||
CONNECTION_STATE state;
|
||||
BOOL isServer;
|
||||
};
|
||||
|
||||
BOOL stream_dump_read_line(FILE* fp, wStream* s, UINT64* pts, size_t* pOffset)
|
||||
static UINT32 crc32b(const BYTE* data, size_t length)
|
||||
{
|
||||
size_t x;
|
||||
UINT32 crc = 0xFFFFFFFF;
|
||||
|
||||
for (x = 0; x < length; x++)
|
||||
{
|
||||
const UINT32 d = data[x] & 0xFF;
|
||||
crc = crc ^ d;
|
||||
for (int j = 7; j >= 0; j--)
|
||||
{
|
||||
UINT32 mask = -(crc & 1);
|
||||
crc = (crc >> 1) ^ (0xEDB88320 & mask);
|
||||
}
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
#if !defined(BUILD_TESTING)
|
||||
static
|
||||
#endif
|
||||
BOOL
|
||||
stream_dump_read_line(FILE* fp, wStream* s, UINT64* pts, size_t* pOffset, UINT32* flags)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
UINT64 ts;
|
||||
UINT64 size = 0;
|
||||
size_t r;
|
||||
UINT32 crc32;
|
||||
BYTE received;
|
||||
|
||||
if (!fp || !s)
|
||||
if (!fp || !s || !flags)
|
||||
return FALSE;
|
||||
|
||||
if (pOffset)
|
||||
@ -53,14 +81,26 @@ BOOL stream_dump_read_line(FILE* fp, wStream* s, UINT64* pts, size_t* pOffset)
|
||||
r = fread(&ts, 1, sizeof(ts), fp);
|
||||
if (r != sizeof(ts))
|
||||
goto fail;
|
||||
r = fread(&received, 1, sizeof(received), fp);
|
||||
if (r != sizeof(received))
|
||||
goto fail;
|
||||
r = fread(&crc32, 1, sizeof(crc32), fp);
|
||||
if (r != sizeof(crc32))
|
||||
goto fail;
|
||||
r = fread(&size, 1, sizeof(size), fp);
|
||||
if (r != sizeof(size))
|
||||
goto fail;
|
||||
if (received)
|
||||
*flags = STREAM_MSG_SRV_RX;
|
||||
else
|
||||
*flags = STREAM_MSG_SRV_TX;
|
||||
if (!Stream_EnsureRemainingCapacity(s, size))
|
||||
goto fail;
|
||||
r = fread(Stream_Pointer(s), 1, size, fp);
|
||||
if (r != size)
|
||||
goto fail;
|
||||
if (crc32 != crc32b(Stream_Pointer(s), size))
|
||||
goto fail;
|
||||
Stream_Seek(s, size);
|
||||
|
||||
if (pOffset)
|
||||
@ -80,7 +120,11 @@ fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL stream_dump_write_line(FILE* fp, wStream* s)
|
||||
#if !defined(BUILD_TESTING)
|
||||
static
|
||||
#endif
|
||||
BOOL
|
||||
stream_dump_write_line(FILE* fp, UINT32 flags, wStream* s)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
const UINT64 t = GetTickCount64();
|
||||
@ -91,9 +135,17 @@ BOOL stream_dump_write_line(FILE* fp, wStream* s)
|
||||
return FALSE;
|
||||
|
||||
{
|
||||
const UINT32 crc32 = crc32b(data, size);
|
||||
const BYTE received = flags & STREAM_MSG_SRV_RX;
|
||||
size_t r = fwrite(&t, 1, sizeof(t), fp);
|
||||
if (r != sizeof(t))
|
||||
goto fail;
|
||||
r = fwrite(&received, 1, sizeof(received), fp);
|
||||
if (r != sizeof(received))
|
||||
goto fail;
|
||||
r = fwrite(&crc32, 1, sizeof(crc32), fp);
|
||||
if (r != sizeof(crc32))
|
||||
goto fail;
|
||||
r = fwrite(&size, 1, sizeof(size), fp);
|
||||
if (r != sizeof(size))
|
||||
goto fail;
|
||||
@ -107,10 +159,9 @@ fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static FILE* stream_dump_get_file(const rdpSettings* settings, const char* name, const char* mode)
|
||||
static FILE* stream_dump_get_file(const rdpSettings* settings, const char* mode)
|
||||
{
|
||||
const char* cfolder;
|
||||
char* folder = NULL;
|
||||
char* file = NULL;
|
||||
FILE* fp = NULL;
|
||||
|
||||
@ -119,58 +170,40 @@ static FILE* stream_dump_get_file(const rdpSettings* settings, const char* name,
|
||||
|
||||
cfolder = freerdp_settings_get_string(settings, FreeRDP_TransportDumpFile);
|
||||
if (!cfolder)
|
||||
folder = GetKnownSubPath(KNOWN_PATH_TEMP, "freerdp-transport-dump");
|
||||
file = GetKnownSubPath(KNOWN_PATH_TEMP, "freerdp-transport-dump");
|
||||
else
|
||||
folder = _strdup(cfolder);
|
||||
|
||||
if (!folder)
|
||||
goto fail;
|
||||
|
||||
if (name)
|
||||
{
|
||||
char buffer[8192] = { 0 };
|
||||
int rc = _snprintf(buffer, sizeof(buffer), "%s.dump", name);
|
||||
if ((rc <= 0) || ((size_t)rc >= sizeof(buffer)))
|
||||
goto fail;
|
||||
|
||||
if (!winpr_PathFileExists(folder))
|
||||
{
|
||||
if (!winpr_PathMakePath(folder, NULL))
|
||||
goto fail;
|
||||
}
|
||||
file = GetCombinedPath(folder, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!winpr_PathFileExists(folder))
|
||||
goto fail;
|
||||
file = _strdup(folder);
|
||||
}
|
||||
file = _strdup(cfolder);
|
||||
|
||||
if (!file)
|
||||
goto fail;
|
||||
|
||||
fp = winpr_fopen(file, mode);
|
||||
fail:
|
||||
free(folder);
|
||||
free(file);
|
||||
return fp;
|
||||
}
|
||||
|
||||
SSIZE_T stream_dump_append(const rdpContext* context, const char* name, wStream* s, size_t* offset)
|
||||
SSIZE_T stream_dump_append(const rdpContext* context, UINT32 flags, wStream* s, size_t* offset)
|
||||
{
|
||||
SSIZE_T rc = -1;
|
||||
FILE* fp;
|
||||
const UINT32 mask = STREAM_MSG_SRV_RX | STREAM_MSG_SRV_TX;
|
||||
CONNECTION_STATE state = freerdp_get_state(context);
|
||||
int r;
|
||||
|
||||
if (!context || !s || !offset)
|
||||
return -1;
|
||||
|
||||
if ((flags & STREAM_MSG_SRV_RX) && (flags & STREAM_MSG_SRV_TX))
|
||||
return -1;
|
||||
|
||||
if ((flags & mask) == 0)
|
||||
return -1;
|
||||
|
||||
if (state < context->dump->state)
|
||||
return 0;
|
||||
|
||||
fp = stream_dump_get_file(context->settings, name, "ab");
|
||||
fp = stream_dump_get_file(context->settings, "ab");
|
||||
if (!fp)
|
||||
return -1;
|
||||
|
||||
@ -178,7 +211,7 @@ SSIZE_T stream_dump_append(const rdpContext* context, const char* name, wStream*
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
if (!stream_dump_write_line(fp, s))
|
||||
if (!stream_dump_write_line(fp, flags, s))
|
||||
goto fail;
|
||||
rc = _ftelli64(fp);
|
||||
if (rc < 0)
|
||||
@ -189,7 +222,7 @@ fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
SSIZE_T stream_dump_get(const rdpContext* context, const char* name, wStream* s, size_t* offset,
|
||||
SSIZE_T stream_dump_get(const rdpContext* context, UINT32* flags, wStream* s, size_t* offset,
|
||||
UINT64* pts)
|
||||
{
|
||||
SSIZE_T rc = -1;
|
||||
@ -198,14 +231,14 @@ SSIZE_T stream_dump_get(const rdpContext* context, const char* name, wStream* s,
|
||||
|
||||
if (!context || !s || !offset)
|
||||
return -1;
|
||||
fp = stream_dump_get_file(context->settings, name, "rb");
|
||||
fp = stream_dump_get_file(context->settings, "rb");
|
||||
if (!fp)
|
||||
return -1;
|
||||
r = _fseeki64(fp, *offset, SEEK_SET);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
if (!stream_dump_read_line(fp, s, pts, offset))
|
||||
if (!stream_dump_read_line(fp, s, pts, offset, flags))
|
||||
goto fail;
|
||||
|
||||
rc = _ftelli64(fp);
|
||||
@ -223,7 +256,8 @@ static int stream_dump_transport_write(rdpTransport* transport, wStream* s)
|
||||
WINPR_ASSERT(ctx->dump);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
r = stream_dump_append(ctx, "write", s, &ctx->dump->writeDumpOffset);
|
||||
r = stream_dump_append(ctx, ctx->dump->isServer ? STREAM_MSG_SRV_TX : STREAM_MSG_SRV_RX, s,
|
||||
&ctx->dump->writeDumpOffset);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
|
||||
@ -244,7 +278,9 @@ static int stream_dump_transport_read(rdpTransport* transport, wStream* s)
|
||||
rc = ctx->dump->io.ReadPdu(transport, s);
|
||||
if (rc > 0)
|
||||
{
|
||||
SSIZE_T r = stream_dump_append(ctx, "read", s, &ctx->dump->readDumpOffset);
|
||||
SSIZE_T r =
|
||||
stream_dump_append(ctx, ctx->dump->isServer ? STREAM_MSG_SRV_RX : STREAM_MSG_SRV_TX, s,
|
||||
&ctx->dump->readDumpOffset);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
}
|
||||
@ -295,13 +331,17 @@ static int stream_dump_replay_transport_read(rdpTransport* transport, wStream* s
|
||||
size_t size = 0;
|
||||
time_t slp = 0;
|
||||
UINT64 ts = 0;
|
||||
UINT32 flags = 0;
|
||||
|
||||
WINPR_ASSERT(ctx);
|
||||
WINPR_ASSERT(ctx->dump);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (stream_dump_get(ctx, NULL, s, &ctx->dump->replayOffset, &ts) < 0)
|
||||
return -1;
|
||||
do
|
||||
{
|
||||
if (stream_dump_get(ctx, &flags, s, &ctx->dump->replayOffset, &ts) < 0)
|
||||
return -1;
|
||||
} while (flags & STREAM_MSG_SRV_RX);
|
||||
|
||||
if ((ctx->dump->replayTime > 0) && (ts > ctx->dump->replayTime))
|
||||
slp = ts - ctx->dump->replayTime;
|
||||
@ -368,11 +408,12 @@ static BOOL stream_dump_register_read_handlers(rdpContext* context)
|
||||
return freerdp_set_io_callbacks(context, &dump);
|
||||
}
|
||||
|
||||
BOOL stream_dump_register_handlers(rdpContext* context, CONNECTION_STATE state)
|
||||
BOOL stream_dump_register_handlers(rdpContext* context, CONNECTION_STATE state, BOOL isServer)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
WINPR_ASSERT(context->dump);
|
||||
context->dump->state = state;
|
||||
context->dump->isServer = isServer;
|
||||
if (!stream_dump_register_write_handlers(context))
|
||||
return FALSE;
|
||||
return stream_dump_register_read_handlers(context);
|
||||
|
45
libfreerdp/core/streamdump.h
Normal file
45
libfreerdp/core/streamdump.h
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
*
|
||||
* RDP session stream dump interface
|
||||
*
|
||||
* Copyright 2022 Armin Novak
|
||||
* Copyright 2022 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_STREAMDUMP_INTERNAL
|
||||
#define FREERDP_STREAMDUMP_INTERNAL
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#if !defined(BUILD_TESTING)
|
||||
static
|
||||
#else
|
||||
FREERDP_LOCAL
|
||||
#endif
|
||||
BOOL
|
||||
stream_dump_read_line(FILE* fp, wStream* s, UINT64* pts, size_t* pOffset, UINT32* flags);
|
||||
|
||||
#if !defined(BUILD_TESTING)
|
||||
static
|
||||
#else
|
||||
FREERDP_LOCAL
|
||||
#endif
|
||||
BOOL
|
||||
stream_dump_write_line(FILE* fp, UINT32 flags, wStream* s);
|
||||
|
||||
#endif
|
@ -7,6 +7,8 @@
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/streamdump.h>
|
||||
|
||||
#include "../streamdump.h"
|
||||
|
||||
static BOOL test_entry_read_write(void)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
@ -14,10 +16,12 @@ static BOOL test_entry_read_write(void)
|
||||
wStream *sw = NULL, *sr = NULL;
|
||||
size_t offset = 0, x;
|
||||
UINT64 ts = 0;
|
||||
UINT32 flags = 0;
|
||||
BYTE tmp[16] = { 0 };
|
||||
char tmp2[64] = { 0 };
|
||||
char* name = NULL;
|
||||
size_t entrysize = sizeof(UINT64) + sizeof(UINT64);
|
||||
size_t entrysize = sizeof(UINT64) /* timestamp */ + sizeof(BYTE) /* direction */ +
|
||||
sizeof(UINT32) /* CRC */ + sizeof(UINT64) /* size */;
|
||||
|
||||
winpr_RAND(tmp, sizeof(tmp));
|
||||
|
||||
@ -45,14 +49,14 @@ static BOOL test_entry_read_write(void)
|
||||
fp = fopen(name, "wb");
|
||||
if (!fp)
|
||||
goto fail;
|
||||
if (!stream_dump_write_line(fp, sw))
|
||||
if (!stream_dump_write_line(fp, 0, sw))
|
||||
goto fail;
|
||||
fclose(fp);
|
||||
|
||||
fp = fopen(name, "rb");
|
||||
if (!fp)
|
||||
goto fail;
|
||||
if (!stream_dump_read_line(fp, sr, &ts, &offset))
|
||||
if (!stream_dump_read_line(fp, sr, &ts, &offset, &flags))
|
||||
goto fail;
|
||||
|
||||
if (entrysize != offset)
|
||||
|
@ -923,6 +923,7 @@ static int hook_peer_write_pdu(rdpTransport* transport, wStream* s)
|
||||
CONNECTION_STATE state;
|
||||
testPeerContext* peerCtx;
|
||||
size_t offset = 0;
|
||||
UINT32 flags = 0;
|
||||
rdpContext* context = transport_get_context(transport);
|
||||
|
||||
WINPR_ASSERT(context);
|
||||
@ -954,18 +955,22 @@ static int hook_peer_write_pdu(rdpTransport* transport, wStream* s)
|
||||
if (!ls)
|
||||
goto fail;
|
||||
|
||||
while (stream_dump_get(context, NULL, ls, &offset, &ts) > 0)
|
||||
while (stream_dump_get(context, &flags, ls, &offset, &ts) > 0)
|
||||
{
|
||||
int rc;
|
||||
if ((last_ts > 0) && (ts > last_ts))
|
||||
/* Skip messages from client. */
|
||||
if (flags & STREAM_MSG_SRV_TX)
|
||||
{
|
||||
UINT64 diff = ts - last_ts;
|
||||
Sleep(diff);
|
||||
if ((last_ts > 0) && (ts > last_ts))
|
||||
{
|
||||
UINT64 diff = ts - last_ts;
|
||||
Sleep(diff);
|
||||
}
|
||||
last_ts = ts;
|
||||
rc = peerCtx->io.WritePdu(transport, ls);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
}
|
||||
last_ts = ts;
|
||||
rc = peerCtx->io.WritePdu(transport, ls);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
Stream_SetPosition(ls, 0);
|
||||
}
|
||||
|
||||
|
@ -542,7 +542,7 @@ static BOOL pf_server_initialize_peer_connection(freerdp_peer* peer)
|
||||
pdata->server_receive_channel_data_original = peer->ReceiveChannelData;
|
||||
peer->ReceiveChannelData = pf_server_receive_channel_data_hook;
|
||||
|
||||
if (!stream_dump_register_handlers(peer->context, CONNECTION_STATE_NEGO))
|
||||
if (!stream_dump_register_handlers(peer->context, CONNECTION_STATE_NEGO, TRUE))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user