mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2025-12-23 07:10:08 +01:00
Switch over to using getaddrinfo for TCP clients & servers to enable IPv6
This commit is contained in:
parent
79d3004e26
commit
ee71e1ff60
10 changed files with 473 additions and 250 deletions
27
ChangeLog
27
ChangeLog
|
|
@ -1,3 +1,30 @@
|
||||||
|
2007-07-24 Daniel P. Berrange <dan@berrange.com>
|
||||||
|
|
||||||
|
* bus/dbus-daemon.1: Add docs on new syntax options for the bus
|
||||||
|
address strings
|
||||||
|
|
||||||
|
* dbus/dbus-address.c: Allow * in addresses (for binding to all
|
||||||
|
addresses).
|
||||||
|
|
||||||
|
* dbus/dbus-sysdeps.h:
|
||||||
|
* dbus/dbus-sysdeps-unix.c: Re-write to use getaddrinfo instead
|
||||||
|
of gethostbyname to enable protocol independant name lookup,
|
||||||
|
making IPv6 work
|
||||||
|
|
||||||
|
* dbus/dbus-server-socket.h:
|
||||||
|
* dbus/dbus-server-socket.c: Add support for 'family' in the
|
||||||
|
address string to specify ipv4 vs ipv6. Use a port string to
|
||||||
|
allow for service resolution. Allow for binding to multiple
|
||||||
|
sockets at once in case of dual IPv4 & IPv6 stacks.
|
||||||
|
|
||||||
|
* dbus/dbus-server-unix.c: Pass in an array of file descriptors
|
||||||
|
instead of a single one.
|
||||||
|
|
||||||
|
* dbus/dbus-transport-socket.h:
|
||||||
|
* dbus/dbus-transport-socket.c: Add support for 'family' in the
|
||||||
|
address string to specify ipv4 vs ipv6. Use a port string to
|
||||||
|
allow for service resolution.
|
||||||
|
|
||||||
2007-07-24 Havoc Pennington <hp@redhat.com>
|
2007-07-24 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* configure.in: add AM_PROG_CC_C_O to allow per-target CPPFLAGS
|
* configure.in: add AM_PROG_CC_C_O to allow per-target CPPFLAGS
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,15 @@ started services or other interested parties with
|
||||||
the last address given in <listen> first. That is,
|
the last address given in <listen> first. That is,
|
||||||
apps will try to connect to the last <listen> address first.
|
apps will try to connect to the last <listen> address first.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
tcp sockets can accept IPv4 addresses, IPv6 addresses or hostnames.
|
||||||
|
If a hostname resolves to multiple addresses, the server will bind
|
||||||
|
to all of them. The family=ipv4 or family=ipv6 options can be used
|
||||||
|
to force it to bind to a subset of addresses
|
||||||
|
|
||||||
|
.PP
|
||||||
|
Example: <listen>tcp:host=localhost,port=0,family=ipv4</listen>
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
A special case is using a port number of zero (or omitting the port),
|
A special case is using a port number of zero (or omitting the port),
|
||||||
which means to choose an available port selected by the operating
|
which means to choose an available port selected by the operating
|
||||||
|
|
@ -231,11 +240,15 @@ reports its own address, such as when DBUS_SESSION_BUS_ADDRESS is set.
|
||||||
Example: <listen>tcp:host=localhost,port=0</listen>
|
Example: <listen>tcp:host=localhost,port=0</listen>
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
tcp addresses also allow an all_interfaces=true option, which will
|
tcp addresses also allow a bind=hostname option, which will override
|
||||||
cause the bus to listen on all local address (INADDR_ANY) and not only
|
the host option specifying what address to bind to, without changing
|
||||||
the specified host. However, the specified host will still be used as
|
the address reported by the bus. The bind option can also take a
|
||||||
the reported address of the server. The specified host should be a
|
special name '*' to cause the bus to listen on all local address
|
||||||
valid name of the local machine or weird stuff will happen.
|
(INADDR_ANY). The specified host should be a valid name of the local
|
||||||
|
machine or weird stuff will happen.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
Example: <listen>tcp:host=localhost,bind=*,port=0</listen>
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.I "<auth>"
|
.I "<auth>"
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ _dbus_set_bad_address (DBusError *error,
|
||||||
(b) == '_' || \
|
(b) == '_' || \
|
||||||
(b) == '/' || \
|
(b) == '/' || \
|
||||||
(b) == '\\' || \
|
(b) == '\\' || \
|
||||||
|
(b) == '*' || \
|
||||||
(b) == '.')
|
(b) == '.')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -691,7 +692,6 @@ static const char* invalid_escaped_values[] = {
|
||||||
"%",
|
"%",
|
||||||
"$",
|
"$",
|
||||||
" ",
|
" ",
|
||||||
"*"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
dbus_bool_t
|
dbus_bool_t
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,9 @@ typedef struct DBusServerSocket DBusServerSocket;
|
||||||
struct DBusServerSocket
|
struct DBusServerSocket
|
||||||
{
|
{
|
||||||
DBusServer base; /**< Parent class members. */
|
DBusServer base; /**< Parent class members. */
|
||||||
int fd; /**< File descriptor or -1 if disconnected. */
|
int n_fds; /**< Number of active file handles */
|
||||||
DBusWatch *watch; /**< File descriptor watch. */
|
int *fds; /**< File descriptor or -1 if disconnected. */
|
||||||
|
DBusWatch **watch; /**< File descriptor watch. */
|
||||||
char *socket_name; /**< Name of domain socket, to unlink if appropriate */
|
char *socket_name; /**< Name of domain socket, to unlink if appropriate */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -56,15 +57,19 @@ static void
|
||||||
socket_finalize (DBusServer *server)
|
socket_finalize (DBusServer *server)
|
||||||
{
|
{
|
||||||
DBusServerSocket *socket_server = (DBusServerSocket*) server;
|
DBusServerSocket *socket_server = (DBusServerSocket*) server;
|
||||||
|
int i;
|
||||||
|
|
||||||
_dbus_server_finalize_base (server);
|
_dbus_server_finalize_base (server);
|
||||||
|
|
||||||
if (socket_server->watch)
|
for (i = 0 ; i < socket_server->n_fds ; i++)
|
||||||
{
|
if (socket_server->watch[i])
|
||||||
_dbus_watch_unref (socket_server->watch);
|
{
|
||||||
socket_server->watch = NULL;
|
_dbus_watch_unref (socket_server->watch[i]);
|
||||||
}
|
socket_server->watch[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_free (socket_server->fds);
|
||||||
|
dbus_free (socket_server->watch);
|
||||||
dbus_free (socket_server->socket_name);
|
dbus_free (socket_server->socket_name);
|
||||||
dbus_free (server);
|
dbus_free (server);
|
||||||
}
|
}
|
||||||
|
|
@ -149,10 +154,21 @@ socket_handle_watch (DBusWatch *watch,
|
||||||
{
|
{
|
||||||
DBusServer *server = data;
|
DBusServer *server = data;
|
||||||
DBusServerSocket *socket_server = data;
|
DBusServerSocket *socket_server = data;
|
||||||
|
#ifndef DBUS_DISABLE_ASSERT
|
||||||
|
int i;
|
||||||
|
dbus_bool_t found = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
SERVER_LOCK (server);
|
SERVER_LOCK (server);
|
||||||
|
|
||||||
_dbus_assert (watch == socket_server->watch);
|
#ifndef DBUS_DISABLE_ASSERT
|
||||||
|
for (i = 0 ; i < socket_server->n_fds ; i++)
|
||||||
|
{
|
||||||
|
if (socket_server->watch[i] == watch)
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
_dbus_assert (found);
|
||||||
|
#endif
|
||||||
|
|
||||||
_dbus_verbose ("Handling client connection, flags 0x%x\n", flags);
|
_dbus_verbose ("Handling client connection, flags 0x%x\n", flags);
|
||||||
|
|
||||||
|
|
@ -199,19 +215,23 @@ static void
|
||||||
socket_disconnect (DBusServer *server)
|
socket_disconnect (DBusServer *server)
|
||||||
{
|
{
|
||||||
DBusServerSocket *socket_server = (DBusServerSocket*) server;
|
DBusServerSocket *socket_server = (DBusServerSocket*) server;
|
||||||
|
int i;
|
||||||
|
|
||||||
HAVE_LOCK_CHECK (server);
|
HAVE_LOCK_CHECK (server);
|
||||||
|
|
||||||
if (socket_server->watch)
|
for (i = 0 ; i < socket_server->n_fds ; i++)
|
||||||
{
|
{
|
||||||
_dbus_server_remove_watch (server,
|
if (socket_server->watch[i])
|
||||||
socket_server->watch);
|
{
|
||||||
_dbus_watch_unref (socket_server->watch);
|
_dbus_server_remove_watch (server,
|
||||||
socket_server->watch = NULL;
|
socket_server->watch[i]);
|
||||||
}
|
_dbus_watch_unref (socket_server->watch[i]);
|
||||||
|
socket_server->watch[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
_dbus_close_socket (socket_server->fd, NULL);
|
_dbus_close_socket (socket_server->fds[i], NULL);
|
||||||
socket_server->fd = -1;
|
socket_server->fds[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (socket_server->socket_name != NULL)
|
if (socket_server->socket_name != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -236,89 +256,128 @@ static const DBusServerVTable socket_vtable = {
|
||||||
* been successfully invoked on it. The server will use accept() to
|
* been successfully invoked on it. The server will use accept() to
|
||||||
* accept new client connections.
|
* accept new client connections.
|
||||||
*
|
*
|
||||||
* @param fd the file descriptor.
|
* @param fds list of file descriptors.
|
||||||
|
* @param n_fds number of file descriptors
|
||||||
* @param address the server's address
|
* @param address the server's address
|
||||||
* @returns the new server, or #NULL if no memory.
|
* @returns the new server, or #NULL if no memory.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
DBusServer*
|
DBusServer*
|
||||||
_dbus_server_new_for_socket (int fd,
|
_dbus_server_new_for_socket (int *fds,
|
||||||
|
int n_fds,
|
||||||
const DBusString *address)
|
const DBusString *address)
|
||||||
{
|
{
|
||||||
DBusServerSocket *socket_server;
|
DBusServerSocket *socket_server;
|
||||||
DBusServer *server;
|
DBusServer *server;
|
||||||
DBusWatch *watch;
|
int i;
|
||||||
|
|
||||||
socket_server = dbus_new0 (DBusServerSocket, 1);
|
socket_server = dbus_new0 (DBusServerSocket, 1);
|
||||||
if (socket_server == NULL)
|
if (socket_server == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
watch = _dbus_watch_new (fd,
|
socket_server->fds = dbus_new (int, n_fds);
|
||||||
DBUS_WATCH_READABLE,
|
if (!socket_server->fds)
|
||||||
TRUE,
|
goto failed_0;
|
||||||
socket_handle_watch, socket_server,
|
|
||||||
NULL);
|
socket_server->watch = dbus_new0 (DBusWatch *, n_fds);
|
||||||
if (watch == NULL)
|
if (!socket_server->watch)
|
||||||
|
goto failed_1;
|
||||||
|
|
||||||
|
for (i = 0 ; i < n_fds ; i++)
|
||||||
{
|
{
|
||||||
dbus_free (socket_server);
|
DBusWatch *watch;
|
||||||
return NULL;
|
|
||||||
|
watch = _dbus_watch_new (fds[i],
|
||||||
|
DBUS_WATCH_READABLE,
|
||||||
|
TRUE,
|
||||||
|
socket_handle_watch, socket_server,
|
||||||
|
NULL);
|
||||||
|
if (watch == NULL)
|
||||||
|
goto failed_2;
|
||||||
|
|
||||||
|
socket_server->n_fds++;
|
||||||
|
socket_server->fds[i] = fds[i];
|
||||||
|
socket_server->watch[i] = watch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_dbus_server_init_base (&socket_server->base,
|
if (!_dbus_server_init_base (&socket_server->base,
|
||||||
&socket_vtable, address))
|
&socket_vtable, address))
|
||||||
{
|
goto failed_2;
|
||||||
_dbus_watch_unref (watch);
|
|
||||||
dbus_free (socket_server);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
server = (DBusServer*) socket_server;
|
server = (DBusServer*)socket_server;
|
||||||
|
|
||||||
SERVER_LOCK (server);
|
SERVER_LOCK (server);
|
||||||
|
|
||||||
if (!_dbus_server_add_watch (&socket_server->base,
|
for (i = 0 ; i < n_fds ; i++)
|
||||||
watch))
|
|
||||||
{
|
{
|
||||||
SERVER_UNLOCK (server);
|
if (!_dbus_server_add_watch (&socket_server->base,
|
||||||
_dbus_server_finalize_base (&socket_server->base);
|
socket_server->watch[i]))
|
||||||
_dbus_watch_unref (watch);
|
{
|
||||||
dbus_free (socket_server);
|
int j;
|
||||||
return NULL;
|
for (j = 0 ; j < i ; j++)
|
||||||
}
|
_dbus_server_remove_watch (server,
|
||||||
|
socket_server->watch[j]);
|
||||||
|
|
||||||
socket_server->fd = fd;
|
SERVER_UNLOCK (server);
|
||||||
socket_server->watch = watch;
|
_dbus_server_finalize_base (&socket_server->base);
|
||||||
|
goto failed_2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SERVER_UNLOCK (server);
|
SERVER_UNLOCK (server);
|
||||||
|
|
||||||
return (DBusServer*) socket_server;
|
return (DBusServer*) socket_server;
|
||||||
|
|
||||||
|
failed_2:
|
||||||
|
for (i = 0 ; i < n_fds ; i++)
|
||||||
|
{
|
||||||
|
if (socket_server->watch[i] != NULL)
|
||||||
|
{
|
||||||
|
_dbus_watch_unref (socket_server->watch[i]);
|
||||||
|
socket_server->watch[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbus_free (socket_server->watch);
|
||||||
|
|
||||||
|
failed_1:
|
||||||
|
dbus_free (socket_server->fds);
|
||||||
|
|
||||||
|
failed_0:
|
||||||
|
dbus_free (socket_server);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new server listening on TCP.
|
* Creates a new server listening on TCP.
|
||||||
* If inaddr_any is TRUE, listens on all local interfaces.
|
* If host is NULL, it will default to localhost.
|
||||||
* Otherwise, it resolves the hostname and listens only on
|
* If bind is NULL, it will default to the value for the host
|
||||||
* the resolved address of the hostname. The hostname is used
|
* parameter, and if that is NULL, then localhost
|
||||||
* even if inaddr_any is TRUE, as the hostname to report when
|
* If bind is a hostname, it will be resolved and will listen
|
||||||
* dbus_server_get_address() is called. If the hostname is #NULL,
|
* on all returned addresses.
|
||||||
* localhost is used.
|
* If family is NULL, hostname resolution will try all address
|
||||||
|
* families, otherwise it can be ipv4 or ipv6 to restrict the
|
||||||
|
* addresses considered.
|
||||||
*
|
*
|
||||||
* @param host the hostname to listen on.
|
* @param host the hostname to report for the listen address
|
||||||
|
* @param bind the hostname to listen on
|
||||||
* @param port the port to listen on or 0 to let the OS choose
|
* @param port the port to listen on or 0 to let the OS choose
|
||||||
* @param inaddr_any #TRUE to listen on all local interfaces
|
* @param family
|
||||||
* @param error location to store reason for failure.
|
* @param error location to store reason for failure.
|
||||||
* @returns the new server, or #NULL on failure.
|
* @returns the new server, or #NULL on failure.
|
||||||
*/
|
*/
|
||||||
DBusServer*
|
DBusServer*
|
||||||
_dbus_server_new_for_tcp_socket (const char *host,
|
_dbus_server_new_for_tcp_socket (const char *host,
|
||||||
dbus_uint32_t port,
|
const char *bind,
|
||||||
dbus_bool_t inaddr_any,
|
const char *port,
|
||||||
|
const char *family,
|
||||||
DBusError *error)
|
DBusError *error)
|
||||||
{
|
{
|
||||||
DBusServer *server;
|
DBusServer *server;
|
||||||
int listen_fd;
|
int *listen_fds = NULL;
|
||||||
|
int nlisten_fds = 0, i;
|
||||||
DBusString address;
|
DBusString address;
|
||||||
DBusString host_str;
|
DBusString host_str;
|
||||||
|
DBusString port_str;
|
||||||
|
|
||||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||||
|
|
||||||
|
|
@ -328,44 +387,77 @@ _dbus_server_new_for_tcp_socket (const char *host,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_dbus_string_init (&port_str))
|
||||||
|
{
|
||||||
|
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
||||||
|
goto failed_0;
|
||||||
|
}
|
||||||
|
|
||||||
if (host == NULL)
|
if (host == NULL)
|
||||||
host = "localhost";
|
host = "localhost";
|
||||||
|
|
||||||
listen_fd = _dbus_listen_tcp_socket (host, &port, inaddr_any, error);
|
if (port == NULL)
|
||||||
_dbus_fd_set_close_on_exec (listen_fd);
|
port = "0";
|
||||||
|
|
||||||
|
if (bind == NULL)
|
||||||
|
bind = host;
|
||||||
|
else if (strcmp (bind, "*") == 0)
|
||||||
|
bind = NULL;
|
||||||
|
|
||||||
|
nlisten_fds =_dbus_listen_tcp_socket (bind, port, family,
|
||||||
|
&port_str,
|
||||||
|
&listen_fds, error);
|
||||||
|
if (nlisten_fds <= 0)
|
||||||
|
{
|
||||||
|
_DBUS_ASSERT_ERROR_IS_SET(error);
|
||||||
|
goto failed_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0 ; i < nlisten_fds ; i++)
|
||||||
|
_dbus_fd_set_close_on_exec (listen_fds[i]);
|
||||||
|
|
||||||
_dbus_string_init_const (&host_str, host);
|
_dbus_string_init_const (&host_str, host);
|
||||||
if (!_dbus_string_append (&address, "tcp:host=") ||
|
if (!_dbus_string_append (&address, "tcp:host=") ||
|
||||||
!_dbus_address_append_escaped (&address, &host_str) ||
|
!_dbus_address_append_escaped (&address, &host_str) ||
|
||||||
!_dbus_string_append (&address, ",port=") ||
|
!_dbus_string_append (&address, ",port=") ||
|
||||||
!_dbus_string_append_int (&address, port))
|
!_dbus_string_append (&address, _dbus_string_get_const_data(&port_str)))
|
||||||
{
|
{
|
||||||
_dbus_string_free (&address);
|
|
||||||
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
||||||
return NULL;
|
goto failed_2;
|
||||||
}
|
}
|
||||||
|
if (family &&
|
||||||
|
(!_dbus_string_append (&address, ",family=") ||
|
||||||
if (listen_fd < 0)
|
!_dbus_string_append (&address, family)))
|
||||||
{
|
{
|
||||||
_dbus_string_free (&address);
|
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
||||||
return NULL;
|
goto failed_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
server = _dbus_server_new_for_socket (listen_fd, &address);
|
server = _dbus_server_new_for_socket (listen_fds, nlisten_fds, &address);
|
||||||
if (server == NULL)
|
if (server == NULL)
|
||||||
{
|
{
|
||||||
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
||||||
_dbus_close_socket (listen_fd, NULL);
|
goto failed_2;
|
||||||
_dbus_string_free (&address);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_dbus_string_free (&port_str);
|
||||||
_dbus_string_free (&address);
|
_dbus_string_free (&address);
|
||||||
|
dbus_free(listen_fds);
|
||||||
|
|
||||||
return server;
|
return server;
|
||||||
|
|
||||||
|
failed_2:
|
||||||
|
for (i = 0 ; i < nlisten_fds ; i++)
|
||||||
|
_dbus_close_socket (listen_fds[i], NULL);
|
||||||
|
dbus_free(listen_fds);
|
||||||
|
|
||||||
|
failed_1:
|
||||||
|
_dbus_string_free (&port_str);
|
||||||
|
|
||||||
|
failed_0:
|
||||||
|
_dbus_string_free (&address);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -395,55 +487,16 @@ _dbus_server_listen_socket (DBusAddressEntry *entry,
|
||||||
{
|
{
|
||||||
const char *host;
|
const char *host;
|
||||||
const char *port;
|
const char *port;
|
||||||
const char *all_interfaces;
|
const char *bind;
|
||||||
dbus_bool_t inaddr_any;
|
const char *family;
|
||||||
long lport;
|
|
||||||
|
|
||||||
host = dbus_address_entry_get_value (entry, "host");
|
host = dbus_address_entry_get_value (entry, "host");
|
||||||
|
bind = dbus_address_entry_get_value (entry, "bind");
|
||||||
port = dbus_address_entry_get_value (entry, "port");
|
port = dbus_address_entry_get_value (entry, "port");
|
||||||
all_interfaces = dbus_address_entry_get_value (entry, "all_interfaces");
|
family = dbus_address_entry_get_value (entry, "family");
|
||||||
|
|
||||||
inaddr_any = FALSE;
|
*server_p = _dbus_server_new_for_tcp_socket (host, bind, port,
|
||||||
if (all_interfaces != NULL)
|
family, error);
|
||||||
{
|
|
||||||
if (strcmp (all_interfaces, "true") == 0)
|
|
||||||
{
|
|
||||||
inaddr_any = TRUE;
|
|
||||||
}
|
|
||||||
else if (strcmp (all_interfaces, "false") == 0)
|
|
||||||
{
|
|
||||||
inaddr_any = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_dbus_set_bad_address(error, NULL, NULL,
|
|
||||||
"all_interfaces flag in tcp: address should be 'true' or 'false'");
|
|
||||||
return DBUS_SERVER_LISTEN_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port == NULL)
|
|
||||||
{
|
|
||||||
lport = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dbus_bool_t sresult;
|
|
||||||
DBusString str;
|
|
||||||
|
|
||||||
_dbus_string_init_const (&str, port);
|
|
||||||
sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
|
|
||||||
_dbus_string_free (&str);
|
|
||||||
|
|
||||||
if (sresult == FALSE || lport < 0 || lport > 65535)
|
|
||||||
{
|
|
||||||
_dbus_set_bad_address(error, NULL, NULL,
|
|
||||||
"Port is not an integer between 0 and 65535");
|
|
||||||
return DBUS_SERVER_LISTEN_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*server_p = _dbus_server_new_for_tcp_socket (host, lport, inaddr_any, error);
|
|
||||||
|
|
||||||
if (*server_p)
|
if (*server_p)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,13 @@
|
||||||
|
|
||||||
DBUS_BEGIN_DECLS
|
DBUS_BEGIN_DECLS
|
||||||
|
|
||||||
DBusServer* _dbus_server_new_for_socket (int fd,
|
DBusServer* _dbus_server_new_for_socket (int *fds,
|
||||||
|
int n_fds,
|
||||||
const DBusString *address);
|
const DBusString *address);
|
||||||
DBusServer* _dbus_server_new_for_tcp_socket (const char *host,
|
DBusServer* _dbus_server_new_for_tcp_socket (const char *host,
|
||||||
dbus_uint32_t port,
|
const char *bind,
|
||||||
dbus_bool_t inaddr_any,
|
const char *port,
|
||||||
|
const char *family,
|
||||||
DBusError *error);
|
DBusError *error);
|
||||||
DBusServerListenResult _dbus_server_listen_socket (DBusAddressEntry *entry,
|
DBusServerListenResult _dbus_server_listen_socket (DBusAddressEntry *entry,
|
||||||
DBusServer **server_p,
|
DBusServer **server_p,
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ _dbus_server_new_for_domain_socket (const char *path,
|
||||||
goto failed_1;
|
goto failed_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
server = _dbus_server_new_for_socket (listen_fd, &address);
|
server = _dbus_server_new_for_socket (&listen_fd, 1, &address);
|
||||||
if (server == NULL)
|
if (server == NULL)
|
||||||
{
|
{
|
||||||
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
||||||
|
|
|
||||||
|
|
@ -737,65 +737,94 @@ _dbus_listen_unix_socket (const char *path,
|
||||||
* nonblocking.
|
* nonblocking.
|
||||||
*
|
*
|
||||||
* @param host the host name to connect to
|
* @param host the host name to connect to
|
||||||
* @param port the prot to connect to
|
* @param port the port to connect to
|
||||||
|
* @param family the address family to listen on, NULL for all
|
||||||
* @param error return location for error code
|
* @param error return location for error code
|
||||||
* @returns connection file descriptor or -1 on error
|
* @returns connection file descriptor or -1 on error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
_dbus_connect_tcp_socket (const char *host,
|
_dbus_connect_tcp_socket (const char *host,
|
||||||
dbus_uint32_t port,
|
const char *port,
|
||||||
|
const char *family,
|
||||||
DBusError *error)
|
DBusError *error)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd = -1, res;
|
||||||
struct sockaddr_in addr;
|
struct addrinfo hints;
|
||||||
struct hostent *he;
|
struct addrinfo *ai, *tmp;
|
||||||
struct in_addr *haddr;
|
|
||||||
|
|
||||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||||
|
|
||||||
|
|
||||||
if (!_dbus_open_tcp_socket (&fd, error))
|
if (!_dbus_open_tcp_socket (&fd, error))
|
||||||
{
|
{
|
||||||
_DBUS_ASSERT_ERROR_IS_SET(error);
|
_DBUS_ASSERT_ERROR_IS_SET(error);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_DBUS_ASSERT_ERROR_IS_CLEAR(error);
|
_DBUS_ASSERT_ERROR_IS_CLEAR(error);
|
||||||
|
|
||||||
if (host == NULL)
|
_DBUS_ZERO (hints);
|
||||||
host = "localhost";
|
|
||||||
|
|
||||||
he = gethostbyname (host);
|
if (!family)
|
||||||
if (he == NULL)
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
else if (!strcmp(family, "ipv4"))
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
else if (!strcmp(family, "ipv6"))
|
||||||
|
hints.ai_family = AF_INET6;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
dbus_set_error (error,
|
dbus_set_error (error,
|
||||||
_dbus_error_from_errno (errno),
|
_dbus_error_from_errno (errno),
|
||||||
"Failed to lookup hostname: %s",
|
"Unknown address family %s", family);
|
||||||
host);
|
|
||||||
_dbus_close (fd, NULL);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "Family %s\n", family ? family : "none");
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_ADDRCONFIG;
|
||||||
|
|
||||||
haddr = ((struct in_addr *) (he->h_addr_list)[0]);
|
if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
|
||||||
|
|
||||||
_DBUS_ZERO (addr);
|
|
||||||
memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons (port);
|
|
||||||
|
|
||||||
if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
|
|
||||||
{
|
{
|
||||||
dbus_set_error (error,
|
dbus_set_error (error,
|
||||||
_dbus_error_from_errno (errno),
|
_dbus_error_from_errno (errno),
|
||||||
"Failed to connect to socket %s:%d %s",
|
"Failed to lookup host/port: \"%s:%s\": %s (%d)",
|
||||||
host, port, _dbus_strerror (errno));
|
host, port, gai_strerror(res), res);
|
||||||
|
|
||||||
_dbus_close (fd, NULL);
|
_dbus_close (fd, NULL);
|
||||||
fd = -1;
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmp = ai;
|
||||||
|
while (tmp)
|
||||||
|
{
|
||||||
|
if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
|
||||||
|
{
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
_DBUS_ASSERT_ERROR_IS_SET(error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
_DBUS_ASSERT_ERROR_IS_CLEAR(error);
|
||||||
|
|
||||||
|
if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
|
||||||
|
{
|
||||||
|
_dbus_close(fd, NULL);
|
||||||
|
fd = -1;
|
||||||
|
tmp = tmp->ai_next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
dbus_set_error (error,
|
||||||
|
_dbus_error_from_errno (errno),
|
||||||
|
"Failed to connect to socket \"%s:%s\" %s",
|
||||||
|
host, port, _dbus_strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!_dbus_set_fd_nonblocking (fd, error))
|
if (!_dbus_set_fd_nonblocking (fd, error))
|
||||||
{
|
{
|
||||||
_dbus_close (fd, NULL);
|
_dbus_close (fd, NULL);
|
||||||
|
|
@ -814,88 +843,186 @@ _dbus_connect_tcp_socket (const char *host,
|
||||||
* If inaddr_any is specified, the hostname is ignored.
|
* If inaddr_any is specified, the hostname is ignored.
|
||||||
*
|
*
|
||||||
* @param host the host name to listen on
|
* @param host the host name to listen on
|
||||||
* @param port the prot to listen on, if zero a free port will be used
|
* @param port the port to listen on, if zero a free port will be used
|
||||||
* @param inaddr_any TRUE to listen on all local interfaces instead of on the host name
|
* @param family the address family to listen on, NULL for all
|
||||||
|
* @param retport string to return the actual port listened on
|
||||||
|
* @param fds_p location to store returned file descriptors
|
||||||
* @param error return location for errors
|
* @param error return location for errors
|
||||||
* @returns the listening file descriptor or -1 on error
|
* @returns the number of listening file descriptors or -1 on error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
_dbus_listen_tcp_socket (const char *host,
|
_dbus_listen_tcp_socket (const char *host,
|
||||||
dbus_uint32_t *port,
|
const char *port,
|
||||||
dbus_bool_t inaddr_any,
|
const char *family,
|
||||||
|
DBusString *retport,
|
||||||
|
int **fds_p,
|
||||||
DBusError *error)
|
DBusError *error)
|
||||||
{
|
{
|
||||||
int listen_fd;
|
int nlisten_fd = 0, *listen_fd = NULL, res, i;
|
||||||
struct sockaddr_in addr;
|
struct addrinfo hints;
|
||||||
socklen_t len = (socklen_t) sizeof (struct sockaddr);
|
struct addrinfo *ai, *tmp;
|
||||||
|
|
||||||
|
*fds_p = NULL;
|
||||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||||
|
|
||||||
if (!_dbus_open_tcp_socket (&listen_fd, error))
|
_DBUS_ZERO (hints);
|
||||||
{
|
|
||||||
_DBUS_ASSERT_ERROR_IS_SET(error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
_DBUS_ASSERT_ERROR_IS_CLEAR(error);
|
|
||||||
|
|
||||||
_DBUS_ZERO (addr);
|
if (!family)
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
if (inaddr_any)
|
else if (!strcmp(family, "ipv4"))
|
||||||
{
|
hints.ai_family = AF_INET;
|
||||||
addr.sin_addr.s_addr = INADDR_ANY;
|
else if (!strcmp(family, "ipv6"))
|
||||||
}
|
hints.ai_family = AF_INET6;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct hostent *he;
|
dbus_set_error (error,
|
||||||
struct in_addr *haddr;
|
_dbus_error_from_errno (errno),
|
||||||
|
"Unknown address family %s", family);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
he = gethostbyname (host);
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
if (he == NULL)
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
|
||||||
|
|
||||||
|
redo_lookup_with_port:
|
||||||
|
if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
|
||||||
|
{
|
||||||
|
dbus_set_error (error,
|
||||||
|
_dbus_error_from_errno (errno),
|
||||||
|
"Failed to lookup host/port: \"%s:%s\": %s (%d)",
|
||||||
|
host ? host : "*", port, gai_strerror(res), res);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = ai;
|
||||||
|
while (tmp)
|
||||||
|
{
|
||||||
|
int fd = -1, *newlisten_fd;
|
||||||
|
if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
|
||||||
{
|
{
|
||||||
dbus_set_error (error,
|
_DBUS_ASSERT_ERROR_IS_SET(error);
|
||||||
_dbus_error_from_errno (errno),
|
goto failed;
|
||||||
"Failed to lookup hostname: %s",
|
}
|
||||||
host);
|
_DBUS_ASSERT_ERROR_IS_CLEAR(error);
|
||||||
_dbus_close (listen_fd, NULL);
|
|
||||||
return -1;
|
if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
|
||||||
|
{
|
||||||
|
_dbus_close(fd, NULL);
|
||||||
|
if (errno == EADDRINUSE)
|
||||||
|
{
|
||||||
|
/* Depending on kernel policy, it may or may not
|
||||||
|
be neccessary to bind to both IPv4 & 6 addresses
|
||||||
|
so ignore EADDRINUSE here */
|
||||||
|
tmp = tmp->ai_next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||||
|
"Failed to bind socket \"%s:%s\": %s",
|
||||||
|
host ? host : "*", port, _dbus_strerror (errno));
|
||||||
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
haddr = ((struct in_addr *) (he->h_addr_list)[0]);
|
if (listen (fd, 30 /* backlog */) < 0)
|
||||||
|
{
|
||||||
|
_dbus_close (fd, NULL);
|
||||||
|
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||||
|
"Failed to listen on socket \"%s:%s\": %s",
|
||||||
|
host ? host : "*", port, _dbus_strerror (errno));
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
|
newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
|
||||||
|
if (!newlisten_fd)
|
||||||
|
{
|
||||||
|
_dbus_close (fd, NULL);
|
||||||
|
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||||
|
"Failed to allocate file handle array: %s",
|
||||||
|
_dbus_strerror (errno));
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
listen_fd = newlisten_fd;
|
||||||
|
listen_fd[nlisten_fd] = fd;
|
||||||
|
nlisten_fd++;
|
||||||
|
|
||||||
|
if (!_dbus_string_get_length(retport))
|
||||||
|
{
|
||||||
|
/* If the user didn't specify a port, or used 0, then
|
||||||
|
the kernel chooses a port. After the first address
|
||||||
|
is bound to, we need to force all remaining addresses
|
||||||
|
to use the same port */
|
||||||
|
if (!port || !strcmp(port, "0"))
|
||||||
|
{
|
||||||
|
struct sockaddr_storage addr;
|
||||||
|
socklen_t addrlen;
|
||||||
|
char portbuf[50];
|
||||||
|
|
||||||
|
addrlen = sizeof(addr);
|
||||||
|
getsockname(fd, (struct sockaddr*) &addr, &addrlen);
|
||||||
|
|
||||||
|
if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
|
||||||
|
portbuf, sizeof(portbuf),
|
||||||
|
NI_NUMERICHOST)) != 0)
|
||||||
|
{
|
||||||
|
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||||
|
"Failed to resolve port \"%s:%s\": %s (%s)",
|
||||||
|
host ? host : "*", port, gai_strerror(res), res);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
if (!_dbus_string_append(retport, portbuf))
|
||||||
|
{
|
||||||
|
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release current address list & redo lookup */
|
||||||
|
port = _dbus_string_get_const_data(retport);
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
goto redo_lookup_with_port;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!_dbus_string_append(retport, port))
|
||||||
|
{
|
||||||
|
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = tmp->ai_next;
|
||||||
}
|
}
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
ai = NULL;
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
if (!nlisten_fd)
|
||||||
addr.sin_port = htons (*port);
|
|
||||||
|
|
||||||
if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
|
|
||||||
{
|
{
|
||||||
|
errno = EADDRINUSE;
|
||||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
dbus_set_error (error, _dbus_error_from_errno (errno),
|
||||||
"Failed to bind socket \"%s:%d\": %s",
|
"Failed to bind socket \"%s:%s\": %s",
|
||||||
host, *port, _dbus_strerror (errno));
|
host ? host : "*", port, _dbus_strerror (errno));
|
||||||
_dbus_close (listen_fd, NULL);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen (listen_fd, 30 /* backlog */) < 0)
|
for (i = 0 ; i < nlisten_fd ; i++)
|
||||||
{
|
{
|
||||||
dbus_set_error (error, _dbus_error_from_errno (errno),
|
if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
|
||||||
"Failed to listen on socket \"%s:%d\": %s",
|
{
|
||||||
host, *port, _dbus_strerror (errno));
|
goto failed;
|
||||||
_dbus_close (listen_fd, NULL);
|
}
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getsockname(listen_fd, (struct sockaddr*) &addr, &len);
|
*fds_p = listen_fd;
|
||||||
*port = (dbus_uint32_t) ntohs(addr.sin_port);
|
|
||||||
|
|
||||||
if (!_dbus_set_fd_nonblocking (listen_fd, error))
|
return nlisten_fd;
|
||||||
{
|
|
||||||
_dbus_close (listen_fd, NULL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return listen_fd;
|
failed:
|
||||||
|
if (ai)
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
for (i = 0 ; i < nlisten_fd ; i++)
|
||||||
|
_dbus_close(listen_fd[i], NULL);
|
||||||
|
dbus_free(listen_fd);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dbus_bool_t
|
static dbus_bool_t
|
||||||
|
|
|
||||||
|
|
@ -144,11 +144,14 @@ int _dbus_write_socket_two (int fd,
|
||||||
int start2,
|
int start2,
|
||||||
int len2);
|
int len2);
|
||||||
int _dbus_connect_tcp_socket (const char *host,
|
int _dbus_connect_tcp_socket (const char *host,
|
||||||
dbus_uint32_t port,
|
const char *port,
|
||||||
|
const char *family,
|
||||||
DBusError *error);
|
DBusError *error);
|
||||||
int _dbus_listen_tcp_socket (const char *host,
|
int _dbus_listen_tcp_socket (const char *host,
|
||||||
dbus_uint32_t *port,
|
const char *port,
|
||||||
dbus_bool_t inaddr_any,
|
const char *family,
|
||||||
|
DBusString *retport,
|
||||||
|
int **fds_p,
|
||||||
DBusError *error);
|
DBusError *error);
|
||||||
int _dbus_accept (int listen_fd);
|
int _dbus_accept (int listen_fd);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1204,15 +1204,18 @@ _dbus_transport_new_for_socket (int fd,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new transport for the given hostname and port.
|
* Creates a new transport for the given hostname and port.
|
||||||
|
* If host is NULL, it will default to localhost
|
||||||
*
|
*
|
||||||
* @param host the host to connect to
|
* @param host the host to connect to
|
||||||
* @param port the port to connect to
|
* @param port the port to connect to
|
||||||
|
* @param family the address family to connect to
|
||||||
* @param error location to store reason for failure.
|
* @param error location to store reason for failure.
|
||||||
* @returns a new transport, or #NULL on failure.
|
* @returns a new transport, or #NULL on failure.
|
||||||
*/
|
*/
|
||||||
DBusTransport*
|
DBusTransport*
|
||||||
_dbus_transport_new_for_tcp_socket (const char *host,
|
_dbus_transport_new_for_tcp_socket (const char *host,
|
||||||
dbus_int32_t port,
|
const char *port,
|
||||||
|
const char *family,
|
||||||
DBusError *error)
|
DBusError *error)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
@ -1227,19 +1230,26 @@ _dbus_transport_new_for_tcp_socket (const char *host,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (host == NULL)
|
||||||
|
host = "localhost";
|
||||||
|
|
||||||
if (!_dbus_string_append (&address, "tcp:"))
|
if (!_dbus_string_append (&address, "tcp:"))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (host != NULL &&
|
if (!_dbus_string_append (&address, "host=") ||
|
||||||
(!_dbus_string_append (&address, "host=") ||
|
!_dbus_string_append (&address, host))
|
||||||
!_dbus_string_append (&address, host)))
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!_dbus_string_append (&address, ",port=") ||
|
if (!_dbus_string_append (&address, ",port=") ||
|
||||||
!_dbus_string_append_int (&address, port))
|
!_dbus_string_append (&address, port))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
fd = _dbus_connect_tcp_socket (host, port, error);
|
if (family != NULL &&
|
||||||
|
(!_dbus_string_append (&address, "family=") ||
|
||||||
|
!_dbus_string_append (&address, family)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
fd = _dbus_connect_tcp_socket (host, port, family, error);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
_DBUS_ASSERT_ERROR_IS_SET (error);
|
_DBUS_ASSERT_ERROR_IS_SET (error);
|
||||||
|
|
@ -1249,7 +1259,7 @@ _dbus_transport_new_for_tcp_socket (const char *host,
|
||||||
|
|
||||||
_dbus_fd_set_close_on_exec (fd);
|
_dbus_fd_set_close_on_exec (fd);
|
||||||
|
|
||||||
_dbus_verbose ("Successfully connected to tcp socket %s:%d\n",
|
_dbus_verbose ("Successfully connected to tcp socket %s:%s\n",
|
||||||
host, port);
|
host, port);
|
||||||
|
|
||||||
transport = _dbus_transport_new_for_socket (fd, NULL, &address);
|
transport = _dbus_transport_new_for_socket (fd, NULL, &address);
|
||||||
|
|
@ -1293,9 +1303,7 @@ _dbus_transport_open_socket(DBusAddressEntry *entry,
|
||||||
{
|
{
|
||||||
const char *host = dbus_address_entry_get_value (entry, "host");
|
const char *host = dbus_address_entry_get_value (entry, "host");
|
||||||
const char *port = dbus_address_entry_get_value (entry, "port");
|
const char *port = dbus_address_entry_get_value (entry, "port");
|
||||||
DBusString str;
|
const char *family = dbus_address_entry_get_value (entry, "family");
|
||||||
long lport;
|
|
||||||
dbus_bool_t sresult;
|
|
||||||
|
|
||||||
if (port == NULL)
|
if (port == NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -1303,18 +1311,7 @@ _dbus_transport_open_socket(DBusAddressEntry *entry,
|
||||||
return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
|
return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
_dbus_string_init_const (&str, port);
|
*transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, error);
|
||||||
sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
|
|
||||||
_dbus_string_free (&str);
|
|
||||||
|
|
||||||
if (sresult == FALSE || lport <= 0 || lport > 65535)
|
|
||||||
{
|
|
||||||
_dbus_set_bad_address (error, NULL, NULL,
|
|
||||||
"Port is not an integer between 0 and 65535");
|
|
||||||
return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
*transport_p = _dbus_transport_new_for_tcp_socket (host, lport, error);
|
|
||||||
if (*transport_p == NULL)
|
if (*transport_p == NULL)
|
||||||
{
|
{
|
||||||
_DBUS_ASSERT_ERROR_IS_SET (error);
|
_DBUS_ASSERT_ERROR_IS_SET (error);
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ DBusTransport* _dbus_transport_new_for_socket (int f
|
||||||
const DBusString *server_guid,
|
const DBusString *server_guid,
|
||||||
const DBusString *address);
|
const DBusString *address);
|
||||||
DBusTransport* _dbus_transport_new_for_tcp_socket (const char *host,
|
DBusTransport* _dbus_transport_new_for_tcp_socket (const char *host,
|
||||||
dbus_int32_t port,
|
const char *port,
|
||||||
|
const char *family,
|
||||||
DBusError *error);
|
DBusError *error);
|
||||||
DBusTransportOpenResult _dbus_transport_open_socket (DBusAddressEntry *entry,
|
DBusTransportOpenResult _dbus_transport_open_socket (DBusAddressEntry *entry,
|
||||||
DBusTransport **transport_p,
|
DBusTransport **transport_p,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue