2012-09-20 07:51:34 +04:00
|
|
|
/**
|
|
|
|
* xrdp: A Remote Desktop Protocol server.
|
|
|
|
*
|
2014-03-02 11:26:40 +04:00
|
|
|
* Copyright (C) Jay Sorg 2004-2014
|
2012-09-20 07:51:34 +04:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* generic transport
|
|
|
|
*/
|
2008-08-22 10:08:11 +04:00
|
|
|
|
2017-03-03 07:33:23 +03:00
|
|
|
#if defined(HAVE_CONFIG_H)
|
|
|
|
#include <config_ac.h>
|
|
|
|
#endif
|
|
|
|
|
2008-08-22 10:08:11 +04:00
|
|
|
#include "os_calls.h"
|
2020-12-21 15:36:00 +03:00
|
|
|
#include "string_calls.h"
|
2008-08-22 10:08:11 +04:00
|
|
|
#include "trans.h"
|
|
|
|
#include "arch.h"
|
|
|
|
#include "parse.h"
|
2014-11-26 05:55:37 +03:00
|
|
|
#include "ssl_calls.h"
|
2020-08-02 07:34:31 +03:00
|
|
|
#include "log.h"
|
2008-08-22 10:08:11 +04:00
|
|
|
|
2015-07-06 09:14:46 +03:00
|
|
|
#define MAX_SBYTES 0
|
|
|
|
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
/** Time between polls of is_term when connecting */
|
|
|
|
#define CONNECT_TERM_POLL_MS 3000
|
|
|
|
/** Time we wait before another connect() attempt if one fails immediately */
|
|
|
|
#define CONNECT_DELAY_ON_FAIL_MS 2000
|
|
|
|
|
2014-08-22 10:13:33 +04:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2016-07-08 04:24:31 +03:00
|
|
|
trans_tls_recv(struct trans *self, char *ptr, int len)
|
2014-08-22 10:13:33 +04:00
|
|
|
{
|
|
|
|
if (self->tls == NULL)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
2014-11-26 05:55:37 +03:00
|
|
|
return ssl_tls_read(self->tls, ptr, len);
|
2014-08-22 10:13:33 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2016-07-08 04:24:31 +03:00
|
|
|
trans_tls_send(struct trans *self, const char *data, int len)
|
2014-08-22 10:13:33 +04:00
|
|
|
{
|
|
|
|
if (self->tls == NULL)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
2014-11-26 05:55:37 +03:00
|
|
|
return ssl_tls_write(self->tls, data, len);
|
2014-08-22 10:13:33 +04:00
|
|
|
}
|
|
|
|
|
2014-11-22 07:49:01 +03:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2014-11-22 07:49:01 +03:00
|
|
|
trans_tls_can_recv(struct trans *self, int sck, int millis)
|
|
|
|
{
|
|
|
|
if (self->tls == NULL)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
2014-11-26 05:55:37 +03:00
|
|
|
return ssl_tls_can_recv(self->tls, sck, millis);
|
2014-11-22 07:49:01 +03:00
|
|
|
}
|
|
|
|
|
2014-08-22 10:13:33 +04:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2016-07-08 04:24:31 +03:00
|
|
|
trans_tcp_recv(struct trans *self, char *ptr, int len)
|
2014-08-22 10:13:33 +04:00
|
|
|
{
|
|
|
|
return g_tcp_recv(self->sck, ptr, len, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2016-07-08 04:24:31 +03:00
|
|
|
trans_tcp_send(struct trans *self, const char *data, int len)
|
2014-08-22 10:13:33 +04:00
|
|
|
{
|
|
|
|
return g_tcp_send(self->sck, data, len, 0);
|
|
|
|
}
|
|
|
|
|
2014-11-22 07:49:01 +03:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2014-11-22 07:49:01 +03:00
|
|
|
trans_tcp_can_recv(struct trans *self, int sck, int millis)
|
|
|
|
{
|
2015-10-08 08:17:12 +03:00
|
|
|
return g_sck_can_recv(sck, millis);
|
2014-11-22 07:49:01 +03:00
|
|
|
}
|
|
|
|
|
2008-08-22 10:08:11 +04:00
|
|
|
/*****************************************************************************/
|
2014-07-26 09:14:19 +04:00
|
|
|
struct trans *
|
2008-08-22 10:08:11 +04:00
|
|
|
trans_create(int mode, int in_size, int out_size)
|
|
|
|
{
|
2014-07-26 09:14:19 +04:00
|
|
|
struct trans *self = (struct trans *) NULL;
|
2012-09-20 07:51:34 +04:00
|
|
|
|
2014-07-26 09:14:19 +04:00
|
|
|
self = (struct trans *) g_malloc(sizeof(struct trans), 1);
|
2012-09-20 07:51:34 +04:00
|
|
|
|
|
|
|
if (self != NULL)
|
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
self->sck = -1;
|
2012-09-20 07:51:34 +04:00
|
|
|
make_stream(self->in_s);
|
|
|
|
init_stream(self->in_s, in_size);
|
|
|
|
make_stream(self->out_s);
|
|
|
|
init_stream(self->out_s, out_size);
|
|
|
|
self->mode = mode;
|
2014-07-15 19:29:40 +04:00
|
|
|
self->tls = 0;
|
2014-08-22 10:13:33 +04:00
|
|
|
/* assign tcp calls by default */
|
|
|
|
self->trans_recv = trans_tcp_recv;
|
|
|
|
self->trans_send = trans_tcp_send;
|
2014-11-22 07:49:01 +03:00
|
|
|
self->trans_can_recv = trans_tcp_can_recv;
|
2012-09-20 07:51:34 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
void
|
2012-09-20 07:51:34 +04:00
|
|
|
trans_delete(struct trans *self)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2012-09-20 07:51:34 +04:00
|
|
|
if (self == 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-14 12:14:22 +03:00
|
|
|
/* Call the user-specified destructor if one exists */
|
|
|
|
if (self->extra_destructor != NULL)
|
|
|
|
{
|
|
|
|
self->extra_destructor(self);
|
|
|
|
}
|
|
|
|
|
2012-09-20 07:51:34 +04:00
|
|
|
free_stream(self->in_s);
|
|
|
|
free_stream(self->out_s);
|
|
|
|
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
if (self->sck >= 0)
|
2012-09-20 07:51:34 +04:00
|
|
|
{
|
|
|
|
g_tcp_close(self->sck);
|
|
|
|
}
|
|
|
|
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
self->sck = -1;
|
2012-09-20 07:51:34 +04:00
|
|
|
|
|
|
|
if (self->listen_filename != 0)
|
|
|
|
{
|
|
|
|
g_file_delete(self->listen_filename);
|
|
|
|
g_free(self->listen_filename);
|
|
|
|
}
|
|
|
|
|
2014-07-23 16:31:45 +04:00
|
|
|
if (self->tls != 0)
|
|
|
|
{
|
2014-11-26 05:55:37 +03:00
|
|
|
ssl_tls_delete(self->tls);
|
2014-07-23 16:31:45 +04:00
|
|
|
}
|
|
|
|
|
2012-09-20 07:51:34 +04:00
|
|
|
g_free(self);
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
|
|
|
|
2017-06-22 21:38:37 +03:00
|
|
|
/*****************************************************************************/
|
|
|
|
void
|
|
|
|
trans_delete_from_child(struct trans *self)
|
|
|
|
{
|
|
|
|
if (self == 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self->listen_filename != 0)
|
|
|
|
{
|
|
|
|
g_free(self->listen_filename);
|
|
|
|
self->listen_filename = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
trans_delete(self);
|
|
|
|
}
|
|
|
|
|
2008-08-22 10:08:11 +04:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2012-09-20 07:51:34 +04:00
|
|
|
trans_get_wait_objs(struct trans *self, tbus *objs, int *count)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2012-09-20 07:51:34 +04:00
|
|
|
if (self == 0)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self->status != TRANS_STATUS_UP)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
objs[*count] = self->sck;
|
|
|
|
(*count)++;
|
2014-11-22 07:49:01 +03:00
|
|
|
|
2022-01-27 19:31:53 +03:00
|
|
|
if (self->tls != NULL && (objs[*count] = ssl_get_rwo(self->tls)) != 0)
|
2014-11-22 07:49:01 +03:00
|
|
|
{
|
2022-01-27 19:31:53 +03:00
|
|
|
(*count)++;
|
2014-11-22 07:49:01 +03:00
|
|
|
}
|
|
|
|
|
2012-09-20 07:51:34 +04:00
|
|
|
return 0;
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
|
|
|
|
2013-09-24 05:08:22 +04:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2014-07-26 09:14:19 +04:00
|
|
|
trans_get_wait_objs_rw(struct trans *self, tbus *robjs, int *rcount,
|
2015-07-13 11:10:48 +03:00
|
|
|
tbus *wobjs, int *wcount, int *timeout)
|
2013-09-24 05:08:22 +04:00
|
|
|
{
|
2015-07-06 09:14:46 +03:00
|
|
|
if (self == 0)
|
2013-09-24 05:08:22 +04:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-07-06 09:14:46 +03:00
|
|
|
if (self->status != TRANS_STATUS_UP)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((self->si != 0) && (self->si->source[self->my_source] > MAX_SBYTES))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (trans_get_wait_objs(self, robjs, rcount) != 0)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-24 05:08:22 +04:00
|
|
|
if (self->wait_s != 0)
|
|
|
|
{
|
|
|
|
wobjs[*wcount] = self->sck;
|
|
|
|
(*wcount)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2015-07-06 09:14:46 +03:00
|
|
|
trans_send_waiting(struct trans *self, int block)
|
2013-09-24 05:08:22 +04:00
|
|
|
{
|
|
|
|
struct stream *temp_s;
|
|
|
|
int bytes;
|
|
|
|
int sent;
|
|
|
|
int timeout;
|
|
|
|
int cont;
|
|
|
|
|
|
|
|
timeout = block ? 100 : 0;
|
|
|
|
cont = 1;
|
|
|
|
while (cont)
|
|
|
|
{
|
|
|
|
if (self->wait_s != 0)
|
|
|
|
{
|
|
|
|
temp_s = self->wait_s;
|
|
|
|
if (g_tcp_can_send(self->sck, timeout))
|
|
|
|
{
|
|
|
|
bytes = (int) (temp_s->end - temp_s->p);
|
2014-08-22 10:13:33 +04:00
|
|
|
sent = self->trans_send(self, temp_s->p, bytes);
|
2013-09-24 05:08:22 +04:00
|
|
|
if (sent > 0)
|
|
|
|
{
|
|
|
|
temp_s->p += sent;
|
2015-07-06 09:14:46 +03:00
|
|
|
if (temp_s->source != 0)
|
|
|
|
{
|
|
|
|
temp_s->source[0] -= sent;
|
|
|
|
}
|
2013-09-24 05:08:22 +04:00
|
|
|
if (temp_s->p >= temp_s->end)
|
|
|
|
{
|
2015-07-06 09:14:46 +03:00
|
|
|
self->wait_s = temp_s->next;
|
2013-09-24 05:08:22 +04:00
|
|
|
free_stream(temp_s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (sent == 0)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!g_tcp_last_error_would_block(self->sck))
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-01-12 05:06:29 +03:00
|
|
|
else if (block)
|
|
|
|
{
|
|
|
|
/* check for term here */
|
|
|
|
if (self->is_term != 0)
|
|
|
|
{
|
|
|
|
if (self->is_term())
|
|
|
|
{
|
|
|
|
/* term */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-09-24 05:08:22 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cont = block;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-08-22 10:08:11 +04:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2012-09-20 07:51:34 +04:00
|
|
|
trans_check_wait_objs(struct trans *self)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2014-07-26 09:14:19 +04:00
|
|
|
tbus in_sck = (tbus) 0;
|
|
|
|
struct trans *in_trans = (struct trans *) NULL;
|
2012-09-20 07:51:34 +04:00
|
|
|
int read_bytes = 0;
|
2022-12-07 12:44:56 +03:00
|
|
|
unsigned int to_read = 0;
|
|
|
|
unsigned int read_so_far = 0;
|
2012-09-20 07:51:34 +04:00
|
|
|
int rv = 0;
|
2020-08-07 13:48:22 +03:00
|
|
|
enum xrdp_source cur_source;
|
2012-09-20 07:51:34 +04:00
|
|
|
|
|
|
|
if (self == 0)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2012-09-20 07:51:34 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self->status != TRANS_STATUS_UP)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
|
|
|
if (self->type1 == TRANS_TYPE_LISTENER) /* listening */
|
|
|
|
{
|
2015-10-08 08:17:12 +03:00
|
|
|
if (g_sck_can_recv(self->sck, 0))
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2022-04-22 13:56:23 +03:00
|
|
|
in_sck = g_sck_accept(self->sck);
|
2012-09-20 07:51:34 +04:00
|
|
|
if (in_sck == -1)
|
|
|
|
{
|
|
|
|
if (g_tcp_last_error_would_block(self->sck))
|
|
|
|
{
|
|
|
|
/* ok, but shouldn't happen */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (in_sck != -1)
|
|
|
|
{
|
|
|
|
if (self->trans_conn_in != 0) /* is function assigned */
|
|
|
|
{
|
|
|
|
in_trans = trans_create(self->mode, self->in_s->size,
|
|
|
|
self->out_s->size);
|
|
|
|
in_trans->sck = in_sck;
|
|
|
|
in_trans->type1 = TRANS_TYPE_SERVER;
|
|
|
|
in_trans->status = TRANS_STATUS_UP;
|
2013-08-18 00:32:53 +04:00
|
|
|
in_trans->is_term = self->is_term;
|
2023-01-17 13:55:19 +03:00
|
|
|
g_file_set_cloexec(in_sck, 1);
|
2016-04-28 04:16:45 +03:00
|
|
|
g_sck_set_non_blocking(in_sck);
|
2012-09-20 07:51:34 +04:00
|
|
|
if (self->trans_conn_in(self, in_trans) != 0)
|
|
|
|
{
|
|
|
|
trans_delete(in_trans);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_tcp_close(in_sck);
|
|
|
|
}
|
|
|
|
}
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
}
|
|
|
|
else /* connected server or client (2 or 3) */
|
|
|
|
{
|
2015-07-06 09:14:46 +03:00
|
|
|
if (self->si != 0 && self->si->source[self->my_source] > MAX_SBYTES)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2015-07-06 09:14:46 +03:00
|
|
|
}
|
2015-07-12 11:38:30 +03:00
|
|
|
else if (self->trans_can_recv(self, self->sck, 0))
|
2015-07-06 09:14:46 +03:00
|
|
|
{
|
2022-12-07 12:44:56 +03:00
|
|
|
/* CVE-2022-23479 - check a malicious caller hasn't managed
|
|
|
|
* to set the header_size to an unreasonable value */
|
|
|
|
if (self->header_size > (unsigned int)self->in_s->size)
|
|
|
|
{
|
|
|
|
LOG(LOG_LEVEL_ERROR,
|
|
|
|
"trans_check_wait_objs: Reading %u bytes beyond buffer",
|
|
|
|
self->header_size - (unsigned int)self->in_s->size);
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-08-07 13:48:22 +03:00
|
|
|
cur_source = XRDP_SOURCE_NONE;
|
2015-07-06 09:14:46 +03:00
|
|
|
if (self->si != 0)
|
|
|
|
{
|
|
|
|
cur_source = self->si->cur_source;
|
|
|
|
self->si->cur_source = self->my_source;
|
|
|
|
}
|
2022-12-07 12:44:56 +03:00
|
|
|
read_so_far = self->in_s->end - self->in_s->data;
|
2012-09-20 07:51:34 +04:00
|
|
|
to_read = self->header_size - read_so_far;
|
|
|
|
|
|
|
|
if (to_read > 0)
|
|
|
|
{
|
2014-08-22 10:13:33 +04:00
|
|
|
read_bytes = self->trans_recv(self, self->in_s->end, to_read);
|
2012-09-20 07:51:34 +04:00
|
|
|
|
|
|
|
if (read_bytes == -1)
|
|
|
|
{
|
|
|
|
if (g_tcp_last_error_would_block(self->sck))
|
|
|
|
{
|
|
|
|
/* ok, but shouldn't happen */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
2015-07-06 09:14:46 +03:00
|
|
|
if (self->si != 0)
|
|
|
|
{
|
|
|
|
self->si->cur_source = cur_source;
|
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (read_bytes == 0)
|
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
2015-07-06 09:14:46 +03:00
|
|
|
if (self->si != 0)
|
|
|
|
{
|
|
|
|
self->si->cur_source = cur_source;
|
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
self->in_s->end += read_bytes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-07 12:44:56 +03:00
|
|
|
read_so_far = self->in_s->end - self->in_s->data;
|
2012-09-20 07:51:34 +04:00
|
|
|
|
|
|
|
if (read_so_far == self->header_size)
|
|
|
|
{
|
|
|
|
if (self->trans_data_in != 0)
|
|
|
|
{
|
|
|
|
rv = self->trans_data_in(self);
|
2014-02-26 08:33:19 +04:00
|
|
|
if (self->no_stream_init_on_data_in == 0)
|
|
|
|
{
|
|
|
|
init_stream(self->in_s, 0);
|
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
}
|
|
|
|
}
|
2015-07-06 09:14:46 +03:00
|
|
|
if (self->si != 0)
|
|
|
|
{
|
|
|
|
self->si->cur_source = cur_source;
|
|
|
|
}
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
2015-07-06 09:14:46 +03:00
|
|
|
if (trans_send_waiting(self, 0) != 0)
|
2013-09-24 05:08:22 +04:00
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
return 1;
|
|
|
|
}
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
2016-01-12 05:06:29 +03:00
|
|
|
|
2012-09-20 07:51:34 +04:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2012-09-20 07:51:34 +04:00
|
|
|
trans_force_read_s(struct trans *self, struct stream *in_s, int size)
|
|
|
|
{
|
|
|
|
int rcvd;
|
|
|
|
|
2020-04-14 13:01:52 +03:00
|
|
|
if (self->status != TRANS_STATUS_UP ||
|
2021-03-06 18:45:27 +03:00
|
|
|
size < 0 || !s_check_rem_out(in_s, size))
|
2012-09-20 07:51:34 +04:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
2020-04-14 13:01:52 +03:00
|
|
|
|
2012-09-20 07:51:34 +04:00
|
|
|
while (size > 0)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2016-04-07 02:37:34 +03:00
|
|
|
rcvd = self->trans_recv(self, in_s->end, size);
|
|
|
|
if (rcvd == -1)
|
2012-09-20 07:51:34 +04:00
|
|
|
{
|
2016-04-07 02:37:34 +03:00
|
|
|
if (g_tcp_last_error_would_block(self->sck))
|
2012-09-20 07:51:34 +04:00
|
|
|
{
|
2016-04-07 02:37:34 +03:00
|
|
|
if (!self->trans_can_recv(self, self->sck, 100))
|
2016-01-12 05:06:29 +03:00
|
|
|
{
|
2016-04-07 02:37:34 +03:00
|
|
|
/* check for term here */
|
|
|
|
if (self->is_term != 0)
|
|
|
|
{
|
|
|
|
if (self->is_term())
|
|
|
|
{
|
|
|
|
/* term */
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
}
|
|
|
|
}
|
2016-04-07 02:37:34 +03:00
|
|
|
else
|
2012-09-20 07:51:34 +04:00
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
return 1;
|
|
|
|
}
|
2016-04-07 02:37:34 +03:00
|
|
|
}
|
|
|
|
else if (rcvd == 0)
|
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
return 1;
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
2010-05-04 11:37:22 +04:00
|
|
|
else
|
|
|
|
{
|
2016-04-07 02:37:34 +03:00
|
|
|
in_s->end += rcvd;
|
|
|
|
size -= rcvd;
|
2010-05-04 11:37:22 +04:00
|
|
|
}
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
return 0;
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2012-09-20 07:51:34 +04:00
|
|
|
trans_force_read(struct trans *self, int size)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2012-09-20 07:51:34 +04:00
|
|
|
return trans_force_read_s(self, self->in_s, size);
|
|
|
|
}
|
2008-08-22 10:08:11 +04:00
|
|
|
|
2012-09-20 07:51:34 +04:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2012-09-20 07:51:34 +04:00
|
|
|
trans_force_write_s(struct trans *self, struct stream *out_s)
|
|
|
|
{
|
|
|
|
int size;
|
|
|
|
int total;
|
|
|
|
int sent;
|
|
|
|
|
|
|
|
if (self->status != TRANS_STATUS_UP)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2010-10-21 09:46:32 +04:00
|
|
|
return 1;
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
2014-07-26 09:14:19 +04:00
|
|
|
size = (int) (out_s->end - out_s->data);
|
2012-09-20 07:51:34 +04:00
|
|
|
total = 0;
|
2015-07-06 09:14:46 +03:00
|
|
|
if (trans_send_waiting(self, 1) != 0)
|
2013-09-24 05:08:22 +04:00
|
|
|
{
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
return 1;
|
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
while (total < size)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2016-04-07 02:37:34 +03:00
|
|
|
sent = self->trans_send(self, out_s->data + total, size - total);
|
|
|
|
if (sent == -1)
|
2012-09-20 07:51:34 +04:00
|
|
|
{
|
2016-04-07 02:37:34 +03:00
|
|
|
if (g_tcp_last_error_would_block(self->sck))
|
2012-09-20 07:51:34 +04:00
|
|
|
{
|
2016-04-07 02:37:34 +03:00
|
|
|
if (!g_tcp_can_send(self->sck, 100))
|
2016-01-12 05:06:29 +03:00
|
|
|
{
|
2016-04-07 02:37:34 +03:00
|
|
|
/* check for term here */
|
|
|
|
if (self->is_term != 0)
|
|
|
|
{
|
|
|
|
if (self->is_term())
|
|
|
|
{
|
|
|
|
/* term */
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
}
|
|
|
|
}
|
2016-04-07 02:37:34 +03:00
|
|
|
else
|
2012-09-20 07:51:34 +04:00
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
return 1;
|
|
|
|
}
|
2016-04-07 02:37:34 +03:00
|
|
|
}
|
|
|
|
else if (sent == 0)
|
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
return 1;
|
2012-09-20 07:51:34 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-04-07 02:37:34 +03:00
|
|
|
total = total + sent;
|
2012-09-20 07:51:34 +04:00
|
|
|
}
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
return 0;
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2012-09-20 07:51:34 +04:00
|
|
|
trans_force_write(struct trans *self)
|
2010-05-04 11:37:22 +04:00
|
|
|
{
|
2012-09-20 07:51:34 +04:00
|
|
|
return trans_force_write_s(self, self->out_s);
|
2010-05-04 11:37:22 +04:00
|
|
|
}
|
|
|
|
|
2013-09-23 23:16:52 +04:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2015-07-06 09:14:46 +03:00
|
|
|
trans_write_copy_s(struct trans *self, struct stream *out_s)
|
2013-09-23 23:16:52 +04:00
|
|
|
{
|
|
|
|
int size;
|
2015-07-06 09:14:46 +03:00
|
|
|
int sent;
|
2013-09-24 05:08:22 +04:00
|
|
|
struct stream *wait_s;
|
|
|
|
struct stream *temp_s;
|
2015-07-06 09:14:46 +03:00
|
|
|
char *out_data;
|
2013-09-23 23:16:52 +04:00
|
|
|
|
|
|
|
if (self->status != TRANS_STATUS_UP)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
2015-07-06 09:14:46 +03:00
|
|
|
/* try to send any left over */
|
|
|
|
if (trans_send_waiting(self, 0) != 0)
|
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
out_data = out_s->data;
|
|
|
|
sent = 0;
|
2014-07-26 09:14:19 +04:00
|
|
|
size = (int) (out_s->end - out_s->data);
|
2015-07-06 09:14:46 +03:00
|
|
|
if (self->wait_s == 0)
|
|
|
|
{
|
|
|
|
/* if no left over, try to send this new data */
|
|
|
|
if (g_tcp_can_send(self->sck, 0))
|
|
|
|
{
|
|
|
|
sent = self->trans_send(self, out_s->data, size);
|
|
|
|
if (sent > 0)
|
|
|
|
{
|
|
|
|
out_data += sent;
|
|
|
|
size -= sent;
|
|
|
|
}
|
|
|
|
else if (sent == 0)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!g_tcp_last_error_would_block(self->sck))
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (size < 1)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* did not send right away, have to copy */
|
2015-12-12 07:37:43 +03:00
|
|
|
make_stream(wait_s);
|
2013-09-24 05:08:22 +04:00
|
|
|
init_stream(wait_s, size);
|
2015-07-06 09:14:46 +03:00
|
|
|
if (self->si != 0)
|
|
|
|
{
|
2020-08-07 13:48:22 +03:00
|
|
|
if ((self->si->cur_source != XRDP_SOURCE_NONE) &&
|
2021-03-06 18:45:27 +03:00
|
|
|
(self->si->cur_source != self->my_source))
|
2015-07-06 09:14:46 +03:00
|
|
|
{
|
|
|
|
self->si->source[self->si->cur_source] += size;
|
|
|
|
wait_s->source = self->si->source + self->si->cur_source;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out_uint8a(wait_s, out_data, size);
|
2013-09-24 05:08:22 +04:00
|
|
|
s_mark_end(wait_s);
|
2013-09-24 06:17:50 +04:00
|
|
|
wait_s->p = wait_s->data;
|
2013-09-24 05:08:22 +04:00
|
|
|
if (self->wait_s == 0)
|
2013-09-23 23:16:52 +04:00
|
|
|
{
|
2013-09-24 05:08:22 +04:00
|
|
|
self->wait_s = wait_s;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
temp_s = self->wait_s;
|
2015-07-06 09:14:46 +03:00
|
|
|
while (temp_s->next != 0)
|
2013-09-23 23:16:52 +04:00
|
|
|
{
|
2015-07-06 09:14:46 +03:00
|
|
|
temp_s = temp_s->next;
|
2013-09-23 23:16:52 +04:00
|
|
|
}
|
2015-07-06 09:14:46 +03:00
|
|
|
temp_s->next = wait_s;
|
2013-09-23 23:16:52 +04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-07-06 09:14:46 +03:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2021-03-06 18:45:27 +03:00
|
|
|
trans_write_copy(struct trans *self)
|
2015-07-06 09:14:46 +03:00
|
|
|
{
|
|
|
|
return trans_write_copy_s(self, self->out_s);
|
|
|
|
}
|
|
|
|
|
2010-05-04 11:37:22 +04:00
|
|
|
/*****************************************************************************/
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
|
|
|
|
/* Shim to apply the function signature of g_tcp_connect()
|
|
|
|
* to g_tcp_local_connect()
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
local_connect_shim(int fd, const char *server, const char *port)
|
|
|
|
{
|
|
|
|
return g_tcp_local_connect(fd, port);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************//**
|
|
|
|
* Waits for an asynchronous connect to complete.
|
|
|
|
* @param self - Transport object
|
|
|
|
* @param start_time Start time of connect (from g_time3())
|
|
|
|
* @param timeout Total wait timeout
|
|
|
|
* @return 0 - connect succeeded, 1 - Connect failed
|
|
|
|
*
|
|
|
|
* If the transport is set up for checking a termination object, this
|
|
|
|
* on a regular basis.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
poll_for_async_connect(struct trans *self, int start_time, int timeout)
|
|
|
|
{
|
|
|
|
int rv = 1;
|
|
|
|
int ms_remaining = timeout - (g_time3() - start_time);
|
|
|
|
|
|
|
|
while (ms_remaining > 0)
|
|
|
|
{
|
|
|
|
int poll_time = ms_remaining;
|
2022-09-03 02:48:01 +03:00
|
|
|
/* Lower bound for waiting for a result */
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
if (poll_time < 100)
|
|
|
|
{
|
|
|
|
poll_time = 100;
|
|
|
|
}
|
|
|
|
/* Limit the wait time if we need to poll for termination */
|
|
|
|
if (self->is_term != NULL && poll_time > CONNECT_TERM_POLL_MS)
|
|
|
|
{
|
|
|
|
poll_time = CONNECT_TERM_POLL_MS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_tcp_can_send(self->sck, poll_time))
|
|
|
|
{
|
|
|
|
/* Connect has finished - return the socket status */
|
|
|
|
rv = g_sck_socket_ok(self->sck) ? 0 : 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for program termination */
|
|
|
|
if (self->is_term != NULL && self->is_term())
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ms_remaining = timeout - (g_time3() - start_time);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2012-09-20 07:51:34 +04:00
|
|
|
trans_connect(struct trans *self, const char *server, const char *port,
|
|
|
|
int timeout)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
int start_time = g_time3();
|
2012-09-20 07:51:34 +04:00
|
|
|
int error;
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
int ms_before_next_connect;
|
2015-08-19 07:10:23 +03:00
|
|
|
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
/*
|
|
|
|
* Function pointers which we use in the main loop to avoid
|
|
|
|
* having to switch on the socket mode */
|
|
|
|
int (*f_alloc_socket)(void);
|
|
|
|
int (*f_connect)(int fd, const char *server, const char *port);
|
2008-08-22 10:08:11 +04:00
|
|
|
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
switch (self->mode)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
case TRANS_MODE_TCP:
|
|
|
|
f_alloc_socket = g_tcp_socket;
|
|
|
|
f_connect = g_tcp_connect;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TRANS_MODE_UNIX:
|
|
|
|
f_alloc_socket = g_tcp_local_socket;
|
|
|
|
f_connect = local_connect_shim;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
LOG(LOG_LEVEL_ERROR, "Bad socket mode %d", self->mode);
|
|
|
|
return 1;
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
while (1)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
/* Check the program isn't terminating */
|
|
|
|
if (self->is_term != NULL && self->is_term())
|
2015-08-19 07:10:23 +03:00
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
error = 1;
|
|
|
|
break;
|
2015-08-19 07:10:23 +03:00
|
|
|
}
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
|
|
|
|
/* Allocate a new socket */
|
|
|
|
if (self->sck >= 0)
|
2015-08-19 07:10:23 +03:00
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
g_tcp_close(self->sck);
|
2015-08-19 07:10:23 +03:00
|
|
|
}
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
self->sck = f_alloc_socket();
|
|
|
|
|
2014-07-27 00:33:23 +04:00
|
|
|
if (self->sck < 0)
|
2015-08-19 07:10:23 +03:00
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
error = 1;
|
|
|
|
break;
|
2015-08-19 07:10:23 +03:00
|
|
|
}
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
|
|
|
|
/* Try to connect asynchronously */
|
2023-01-17 13:55:19 +03:00
|
|
|
g_file_set_cloexec(self->sck, 1);
|
2012-09-20 07:51:34 +04:00
|
|
|
g_tcp_set_non_blocking(self->sck);
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
error = f_connect(self->sck, server, port);
|
|
|
|
if (error == 0)
|
|
|
|
{
|
|
|
|
/* Connect was immediately successful */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_tcp_last_error_would_block(self->sck))
|
2015-08-19 07:10:23 +03:00
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
/* Async connect is in progress */
|
|
|
|
if (poll_for_async_connect(self, start_time, timeout) == 0)
|
2015-08-19 07:10:23 +03:00
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
/* Async connect was successful */
|
|
|
|
error = 0;
|
2015-08-19 07:10:23 +03:00
|
|
|
break;
|
|
|
|
}
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
/* No need to wait any more before the next connect attempt */
|
|
|
|
ms_before_next_connect = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Connect failed immediately. Wait a bit before the next
|
|
|
|
* attempt */
|
|
|
|
ms_before_next_connect = CONNECT_DELAY_ON_FAIL_MS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Have we reached the total timeout yet? */
|
|
|
|
int ms_left = timeout - (g_time3() - start_time);
|
|
|
|
if (ms_left <= 0)
|
|
|
|
{
|
|
|
|
error = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Sleep a bit before trying again */
|
|
|
|
if (ms_before_next_connect > 0)
|
|
|
|
{
|
|
|
|
if (ms_before_next_connect > ms_left)
|
2015-08-19 07:10:23 +03:00
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
ms_before_next_connect = ms_left;
|
2015-08-19 07:10:23 +03:00
|
|
|
}
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
g_sleep(ms_before_next_connect);
|
2015-08-19 07:10:23 +03:00
|
|
|
}
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
|
|
|
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
if (error != 0)
|
2012-09-20 07:51:34 +04:00
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
if (self->sck >= 0)
|
2012-09-20 07:51:34 +04:00
|
|
|
{
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
g_tcp_close(self->sck);
|
|
|
|
self->sck = -1;
|
2012-09-20 07:51:34 +04:00
|
|
|
}
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
self->status = TRANS_STATUS_DOWN;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
self->status = TRANS_STATUS_UP; /* ok */
|
|
|
|
self->type1 = TRANS_TYPE_CLIENT; /* client */
|
2012-09-20 07:51:34 +04:00
|
|
|
}
|
|
|
|
|
Rework transport connect logic
There are a number of ways the existing transport connect logic in
trans_connect could be improved for POSIX compatibility, and also
slightly tidied up:-
1) The same socket is re-used for multiple connect attempts following
failure which isn't behaviour defined by POSIX.1-2017 (although it
works on Linux).
2) An asynchronous connect is started, and then after a short
delay connect() is called again on the same socket. POSIX.1-2017
is clear that in this situation EALREADY is returned before the
connection is established, but is silent on the behaviour expected
when the connection is established. Returning success is an option,
but so is returning EISCONN. The current code assumes the connect()
call will succeed.
3) The code contains two virtually identical, quite complex loops for
TCP and UNIX sockets, differing only in the calls to create a socket
and connect it.
4) trans_connect() contains looping and retry logic, but this isn't
seen as sufficient by the chansrv connect code in xrdp/xrdp_mm.c and
the Xorg connect code in xup/xup.c. Both of these implement their own
looping and retry logic on top of the logic in trans_connect(),
resulting in slightly unpredictable behaviour with regard to
timeouts.
5) A socket number can technically be zero, but in a couple of places
this isn't allowed for.
This PR attempts to correct the implementation of trans_connect(),
and also to simplify the areas it is called from.
As part of the PR, the signature of the server_is_term member of the
xrdp module interface is changed to match the signature expected by the
is_term member of a struct trans. This allows for trans_connect()
in xrdp modules to directly access g_is_term() within the main xrdp
executable. At the moment this functionality is only used by the xup
module.
2022-03-31 16:33:06 +03:00
|
|
|
return error;
|
2010-05-04 11:37:22 +04:00
|
|
|
}
|
|
|
|
|
2008-08-22 10:08:11 +04:00
|
|
|
/*****************************************************************************/
|
2014-07-27 00:33:23 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return 0 on success, 1 on failure
|
|
|
|
*/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2021-04-19 18:32:04 +03:00
|
|
|
trans_listen_address(struct trans *self, const char *port, const char *address)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2022-04-01 13:51:11 +03:00
|
|
|
if (self->sck >= 0)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2012-09-20 07:51:34 +04:00
|
|
|
g_tcp_close(self->sck);
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
|
|
|
|
2012-09-20 07:51:34 +04:00
|
|
|
if (self->mode == TRANS_MODE_TCP) /* tcp */
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2012-09-20 07:51:34 +04:00
|
|
|
self->sck = g_tcp_socket();
|
2014-07-27 00:33:23 +04:00
|
|
|
if (self->sck < 0)
|
2021-03-06 18:45:27 +03:00
|
|
|
{
|
2014-07-27 00:33:23 +04:00
|
|
|
return 1;
|
2021-03-06 18:45:27 +03:00
|
|
|
}
|
2014-07-27 00:33:23 +04:00
|
|
|
|
2023-01-17 13:55:19 +03:00
|
|
|
g_file_set_cloexec(self->sck, 1);
|
2012-09-20 07:51:34 +04:00
|
|
|
g_tcp_set_non_blocking(self->sck);
|
|
|
|
|
|
|
|
if (g_tcp_bind_address(self->sck, port, address) == 0)
|
|
|
|
{
|
|
|
|
if (g_tcp_listen(self->sck) == 0)
|
|
|
|
{
|
|
|
|
self->status = TRANS_STATUS_UP; /* ok */
|
|
|
|
self->type1 = TRANS_TYPE_LISTENER; /* listener */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2009-09-05 07:29:43 +04:00
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
else if (self->mode == TRANS_MODE_UNIX) /* unix socket */
|
2009-09-05 07:29:43 +04:00
|
|
|
{
|
2012-09-20 07:51:34 +04:00
|
|
|
g_free(self->listen_filename);
|
|
|
|
self->listen_filename = 0;
|
|
|
|
g_file_delete(port);
|
2014-07-27 00:33:23 +04:00
|
|
|
|
2012-09-20 07:51:34 +04:00
|
|
|
self->sck = g_tcp_local_socket();
|
2014-07-27 00:33:23 +04:00
|
|
|
if (self->sck < 0)
|
2021-03-06 18:45:27 +03:00
|
|
|
{
|
2014-07-27 00:33:23 +04:00
|
|
|
return 1;
|
2021-03-06 18:45:27 +03:00
|
|
|
}
|
2014-07-27 00:33:23 +04:00
|
|
|
|
2023-01-17 13:55:19 +03:00
|
|
|
g_file_set_cloexec(self->sck, 1);
|
2012-09-20 07:51:34 +04:00
|
|
|
g_tcp_set_non_blocking(self->sck);
|
|
|
|
|
|
|
|
if (g_tcp_local_bind(self->sck, port) == 0)
|
|
|
|
{
|
|
|
|
self->listen_filename = g_strdup(port);
|
|
|
|
|
|
|
|
if (g_tcp_listen(self->sck) == 0)
|
|
|
|
{
|
2014-05-16 05:04:04 +04:00
|
|
|
g_chmod_hex(port, 0x0660);
|
2012-09-20 07:51:34 +04:00
|
|
|
self->status = TRANS_STATUS_UP; /* ok */
|
|
|
|
self->type1 = TRANS_TYPE_LISTENER; /* listener */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
2017-09-22 02:13:05 +03:00
|
|
|
else if (self->mode == TRANS_MODE_VSOCK) /* vsock socket */
|
|
|
|
{
|
2017-11-07 03:06:36 +03:00
|
|
|
self->sck = g_sck_vsock_socket();
|
2017-09-22 02:13:05 +03:00
|
|
|
if (self->sck < 0)
|
2017-11-07 22:51:23 +03:00
|
|
|
{
|
2017-09-22 02:13:05 +03:00
|
|
|
return 1;
|
2017-11-07 22:51:23 +03:00
|
|
|
}
|
2017-09-22 02:13:05 +03:00
|
|
|
|
2023-01-17 13:55:19 +03:00
|
|
|
g_file_set_cloexec(self->sck, 1);
|
2017-09-22 02:13:05 +03:00
|
|
|
g_tcp_set_non_blocking(self->sck);
|
|
|
|
|
2019-07-02 03:56:50 +03:00
|
|
|
if (g_sck_vsock_bind_address(self->sck, port, address) == 0)
|
2017-09-22 02:13:05 +03:00
|
|
|
{
|
|
|
|
if (g_tcp_listen(self->sck) == 0)
|
|
|
|
{
|
|
|
|
self->status = TRANS_STATUS_UP; /* ok */
|
|
|
|
self->type1 = TRANS_TYPE_LISTENER; /* listener */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-06-30 09:59:18 +03:00
|
|
|
else if (self->mode == TRANS_MODE_TCP4) /* tcp4 */
|
|
|
|
{
|
|
|
|
self->sck = g_tcp4_socket();
|
|
|
|
if (self->sck < 0)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
2023-01-17 13:55:19 +03:00
|
|
|
g_file_set_cloexec(self->sck, 1);
|
2019-06-30 09:59:18 +03:00
|
|
|
g_tcp_set_non_blocking(self->sck);
|
2019-07-02 03:56:50 +03:00
|
|
|
if (g_tcp4_bind_address(self->sck, port, address) == 0)
|
2019-06-30 09:59:18 +03:00
|
|
|
{
|
|
|
|
if (g_tcp_listen(self->sck) == 0)
|
|
|
|
{
|
|
|
|
self->status = TRANS_STATUS_UP; /* ok */
|
|
|
|
self->type1 = TRANS_TYPE_LISTENER; /* listener */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (self->mode == TRANS_MODE_TCP6) /* tcp6 */
|
|
|
|
{
|
|
|
|
self->sck = g_tcp6_socket();
|
|
|
|
if (self->sck < 0)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
2023-01-17 13:55:19 +03:00
|
|
|
g_file_set_cloexec(self->sck, 1);
|
2019-06-30 09:59:18 +03:00
|
|
|
g_tcp_set_non_blocking(self->sck);
|
2019-07-02 03:56:50 +03:00
|
|
|
if (g_tcp6_bind_address(self->sck, port, address) == 0)
|
2019-06-30 09:59:18 +03:00
|
|
|
{
|
|
|
|
if (g_tcp_listen(self->sck) == 0)
|
|
|
|
{
|
|
|
|
self->status = TRANS_STATUS_UP; /* ok */
|
|
|
|
self->type1 = TRANS_TYPE_LISTENER; /* listener */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-09-20 07:51:34 +04:00
|
|
|
return 1;
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
|
|
|
|
2010-10-20 08:23:13 +04:00
|
|
|
/*****************************************************************************/
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2021-04-19 18:32:04 +03:00
|
|
|
trans_listen(struct trans *self, const char *port)
|
2010-10-20 08:23:13 +04:00
|
|
|
{
|
2012-09-20 07:51:34 +04:00
|
|
|
return trans_listen_address(self, port, "0.0.0.0");
|
2010-10-20 08:23:13 +04:00
|
|
|
}
|
|
|
|
|
2008-08-22 10:08:11 +04:00
|
|
|
/*****************************************************************************/
|
2014-07-26 09:14:19 +04:00
|
|
|
struct stream *
|
2012-09-20 07:51:34 +04:00
|
|
|
trans_get_in_s(struct trans *self)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2014-07-26 09:14:19 +04:00
|
|
|
struct stream *rv = (struct stream *) NULL;
|
2012-09-20 07:51:34 +04:00
|
|
|
|
|
|
|
if (self == NULL)
|
|
|
|
{
|
2014-07-26 09:14:19 +04:00
|
|
|
rv = (struct stream *) NULL;
|
2012-09-20 07:51:34 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rv = self->in_s;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2014-07-26 09:14:19 +04:00
|
|
|
struct stream *
|
2012-09-20 07:51:34 +04:00
|
|
|
trans_get_out_s(struct trans *self, int size)
|
2008-08-22 10:08:11 +04:00
|
|
|
{
|
2014-07-26 09:14:19 +04:00
|
|
|
struct stream *rv = (struct stream *) NULL;
|
2012-09-20 07:51:34 +04:00
|
|
|
|
|
|
|
if (self == NULL)
|
|
|
|
{
|
2014-07-26 09:14:19 +04:00
|
|
|
rv = (struct stream *) NULL;
|
2012-09-20 07:51:34 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
init_stream(self->out_s, size);
|
|
|
|
rv = self->out_s;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
2008-08-22 10:08:11 +04:00
|
|
|
}
|
2016-01-12 05:06:29 +03:00
|
|
|
|
2014-07-23 16:31:45 +04:00
|
|
|
/*****************************************************************************/
|
|
|
|
/* returns error */
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2016-08-25 21:20:47 +03:00
|
|
|
trans_set_tls_mode(struct trans *self, const char *key, const char *cert,
|
2016-12-13 09:49:13 +03:00
|
|
|
long ssl_protocols, const char *tls_ciphers)
|
2014-07-23 16:31:45 +04:00
|
|
|
{
|
2014-11-26 05:55:37 +03:00
|
|
|
self->tls = ssl_tls_create(self, key, cert);
|
2014-07-26 09:14:19 +04:00
|
|
|
if (self->tls == NULL)
|
|
|
|
{
|
2020-08-02 07:34:31 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "trans_set_tls_mode: ssl_tls_create malloc error");
|
2014-07-26 09:14:19 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-12-13 09:49:13 +03:00
|
|
|
if (ssl_tls_accept(self->tls, ssl_protocols, tls_ciphers) != 0)
|
2014-07-26 09:14:19 +04:00
|
|
|
{
|
2020-08-02 07:34:31 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "trans_set_tls_mode: ssl_tls_accept failed");
|
2014-07-26 09:14:19 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* assign tls functions */
|
2014-08-22 10:13:33 +04:00
|
|
|
self->trans_recv = trans_tls_recv;
|
|
|
|
self->trans_send = trans_tls_send;
|
2014-11-22 07:49:01 +03:00
|
|
|
self->trans_can_recv = trans_tls_can_recv;
|
2014-07-26 09:14:19 +04:00
|
|
|
|
2022-01-27 19:31:53 +03:00
|
|
|
self->ssl_protocol = ssl_get_version(self->tls);
|
|
|
|
self->cipher_name = ssl_get_cipher_name(self->tls);
|
2016-09-09 09:42:04 +03:00
|
|
|
|
2014-07-26 09:14:19 +04:00
|
|
|
return 0;
|
2014-07-23 16:31:45 +04:00
|
|
|
}
|
2016-01-12 05:06:29 +03:00
|
|
|
|
2014-07-23 16:31:45 +04:00
|
|
|
/*****************************************************************************/
|
|
|
|
/* returns error */
|
2017-03-12 19:35:00 +03:00
|
|
|
int
|
2014-07-23 16:31:45 +04:00
|
|
|
trans_shutdown_tls_mode(struct trans *self)
|
|
|
|
{
|
2014-07-26 09:14:19 +04:00
|
|
|
if (self->tls != NULL)
|
|
|
|
{
|
2014-11-26 05:55:37 +03:00
|
|
|
return ssl_tls_disconnect(self->tls);
|
2014-07-26 09:14:19 +04:00
|
|
|
}
|
|
|
|
|
2014-08-22 10:13:33 +04:00
|
|
|
/* assign callback back to tcp cal */
|
|
|
|
self->trans_recv = trans_tcp_recv;
|
|
|
|
self->trans_send = trans_tcp_send;
|
2014-11-22 07:49:01 +03:00
|
|
|
self->trans_can_recv = trans_tcp_can_recv;
|
2014-08-22 10:13:33 +04:00
|
|
|
|
2014-07-26 09:14:19 +04:00
|
|
|
return 0;
|
2014-07-23 16:31:45 +04:00
|
|
|
}
|