From f3fd4d60ad5de9f0c6576f6e100f944792fed255 Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Sat, 10 Mar 2007 08:04:39 +0000 Subject: * dbus/dbus-sysdeps.h (_dbus_listen_tcp_socket): changed type or port to pointer, because the port is given back. * dbus/dbus-server-socket.c (_dbus_server_new_for_tcp_socket): implemented returning tcp port. Skipping port parameter and non integer port values in config statement needs more effort. * dbus/dbus-sysdeps-unix.c, dbus/dbus-sysdeps-win.c (_dbus_listen_tcp_socket): return the real used tcp port. * bus/dbus-daemon.1.in: added tcp examples --- ChangeLog | 15 +++++++++++++++ bus/dbus-daemon.1.in | 11 +++++++++++ dbus/dbus-server-socket.c | 9 +++++---- dbus/dbus-sysdeps-unix.c | 16 +++++++++++----- dbus/dbus-sysdeps-win.c | 18 ++++++++++-------- dbus/dbus-sysdeps.h | 2 +- 6 files changed, 53 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 42f5854d..fbac4bf0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2007-03-09 Ralf Habacker + + * dbus/dbus-sysdeps.h (_dbus_listen_tcp_socket): + changed type or port to pointer, because the port is given back. + + * dbus/dbus-server-socket.c (_dbus_server_new_for_tcp_socket): + implemented returning tcp port. Skipping port parameter + and non integer port values in config statement + needs more effort. + + * dbus/dbus-sysdeps-unix.c, dbus/dbus-sysdeps-win.c + (_dbus_listen_tcp_socket): return the real used tcp port. + + * bus/dbus-daemon.1.in: added tcp examples + 2007-03-09 Ralf Habacker * cmake/config.h.cmake: win32 msvc bug fix diff --git a/bus/dbus-daemon.1.in b/bus/dbus-daemon.1.in index 5c846836..acee933a 100644 --- a/bus/dbus-daemon.1.in +++ b/bus/dbus-daemon.1.in @@ -210,6 +210,9 @@ a transport name plus possible parameters/options. .PP Example: unix:path=/tmp/foo +.PP +Example: tcp:host=localhost,port=1234 + .PP If there are multiple elements, then the bus listens on multiple addresses. The bus will pass its address to @@ -217,6 +220,14 @@ started services or other interested parties with the last address given in first. That is, apps will try to connect to the last address first. +.PP +A special case is using a port number of zero which means to +pick up a random free port. The real used port number could be retrieved +by using the --print-address command line parameter. + +.PP +Example: tcp:host=localhost,port=0 + .TP .I "" diff --git a/dbus/dbus-server-socket.c b/dbus/dbus-server-socket.c index 5c11e145..3a0da35f 100644 --- a/dbus/dbus-server-socket.c +++ b/dbus/dbus-server-socket.c @@ -323,6 +323,9 @@ _dbus_server_new_for_tcp_socket (const char *host, if (host == NULL) host = "localhost"; + + listen_fd = _dbus_listen_tcp_socket (host, &port, error); + _dbus_fd_set_close_on_exec (listen_fd); _dbus_string_init_const (&host_str, host); if (!_dbus_string_append (&address, "tcp:host=") || @@ -334,9 +337,7 @@ _dbus_server_new_for_tcp_socket (const char *host, dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; } - - listen_fd = _dbus_listen_tcp_socket (host, port, error); - _dbus_fd_set_close_on_exec (listen_fd); + if (listen_fd < 0) { @@ -401,7 +402,7 @@ _dbus_server_listen_socket (DBusAddressEntry *entry, sresult = _dbus_string_parse_int (&str, 0, &lport, NULL); _dbus_string_free (&str); - if (sresult == FALSE || lport <= 0 || lport > 65535) + if (sresult == FALSE || lport < 0 || lport > 65535) { _dbus_set_bad_address(error, NULL, NULL, "Port is not an integer between 0 and 65535"); diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 23296712..13375fe8 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -766,21 +766,24 @@ _dbus_connect_tcp_socket (const char *host, * Creates a socket and binds it to the given path, * then listens on the socket. The socket is * set to be nonblocking. + * In case of port=0 a random free port is used and + * returned in the port parameter. * * @param host the host name to listen on - * @param port the prot to listen on + * @param port the prot to listen on, if zero a free port will be used * @param error return location for errors * @returns the listening file descriptor or -1 on error */ int _dbus_listen_tcp_socket (const char *host, - dbus_uint32_t port, + dbus_uint32_t *port, DBusError *error) { int listen_fd; struct sockaddr_in addr; struct hostent *he; struct in_addr *haddr; + socklen_t len = (socklen_t) sizeof (struct sockaddr); _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -808,13 +811,13 @@ _dbus_listen_tcp_socket (const char *host, _DBUS_ZERO (addr); memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr)); addr.sin_family = AF_INET; - addr.sin_port = htons (port); + addr.sin_port = htons (*port); if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr))) { dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to bind socket \"%s:%d\": %s", - host, port, _dbus_strerror (errno)); + host, *port, _dbus_strerror (errno)); _dbus_close (listen_fd, NULL); return -1; } @@ -823,11 +826,14 @@ _dbus_listen_tcp_socket (const char *host, { dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to listen on socket \"%s:%d\": %s", - host, port, _dbus_strerror (errno)); + host, *port, _dbus_strerror (errno)); _dbus_close (listen_fd, NULL); return -1; } + getsockname(listen_fd, (struct sockaddr*) &addr, &len); + *port = (dbus_uint32_t) ntohs(addr.sin_port); + if (!_dbus_set_fd_nonblocking (listen_fd, error)) { _dbus_close (listen_fd, NULL); diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 32243d09..9f62e5ba 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -3438,16 +3438,18 @@ _dbus_daemon_init(const char *host, dbus_uint32_t port); * Creates a socket and binds it to the given port, * then listens on the socket. The socket is * set to be nonblocking. + * In case of port=0 a random free port is used and + * returned in the port parameter. * * @param host the interface to listen on, NULL for loopback, empty for any - * @param port the port 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 error return location for errors * @returns the listening file descriptor or -1 on error */ int _dbus_listen_tcp_socket (const char *host, - dbus_uint32_t port, + dbus_uint32_t *port, DBusError *error) { DBusSocket slisten; @@ -3455,7 +3457,7 @@ _dbus_listen_tcp_socket (const char *host, struct sockaddr_in addr; struct hostent *he; struct in_addr *haddr; - int len = sizeof (struct sockaddr); + socklen_t len = (socklen_t) sizeof (struct sockaddr); struct in_addr ina; @@ -3504,14 +3506,14 @@ _dbus_listen_tcp_socket (const char *host, _DBUS_ZERO (addr); memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr)); addr.sin_family = AF_INET; - addr.sin_port = htons (port); + addr.sin_port = htons (*port); if (bind (slisten.fd, (struct sockaddr*) &addr, sizeof (struct sockaddr))) { DBUS_SOCKET_SET_ERRNO (); dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to bind socket \"%s:%d\": %s", - host, port, _dbus_strerror (errno)); + host, *port, _dbus_strerror (errno)); DBUS_CLOSE_SOCKET (slisten.fd); return -1; } @@ -3521,14 +3523,14 @@ _dbus_listen_tcp_socket (const char *host, DBUS_SOCKET_SET_ERRNO (); dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to listen on socket \"%s:%d\": %s", - host, port, _dbus_strerror (errno)); + host, *port, _dbus_strerror (errno)); DBUS_CLOSE_SOCKET (slisten.fd); return -1; } - getsockname(slisten.fd, (struct sockaddr*) &addr, &len); - + *port = (dbus_uint32_t) ntohs(addr.sin_port); + _dbus_daemon_init(host, ntohs(addr.sin_port)); handle = _dbus_socket_to_handle (&slisten); diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 8ca1cad9..9c1bec98 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -141,7 +141,7 @@ int _dbus_connect_tcp_socket (const char *host, dbus_uint32_t port, DBusError *error); int _dbus_listen_tcp_socket (const char *host, - dbus_uint32_t port, + dbus_uint32_t *port, DBusError *error); int _dbus_accept (int listen_fd); -- cgit