DBusString host_str; /* Initialized as const later, not freed */
DBusString port_str = _DBUS_STRING_INIT_INVALID;
DBusNonceFile *noncefile = NULL;
-
+ const char *family_used = NULL;
+
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
if (!_dbus_string_init (&address))
nlisten_fds =_dbus_listen_tcp_socket (bind, port, family,
&port_str,
+ &family_used,
&listen_fds, error);
if (nlisten_fds <= 0)
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
goto failed;
}
- if (family &&
+ if (family_used &&
(!_dbus_string_append (&address, ",family=") ||
- !_dbus_string_append (&address, family)))
+ !_dbus_string_append (&address, family_used)))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
goto failed;
* @param port the port to listen on, if zero a free port will be used
* @param family the address family to listen on, NULL for all
* @param retport string to return the actual port listened on
+ * @param retfamily string to return the actual family listened on
* @param fds_p location to store returned file descriptors
* @param error return location for errors
* @returns the number of listening file descriptors or -1 on error
const char *port,
const char *family,
DBusString *retport,
+ const char **retfamily,
DBusSocket **fds_p,
DBusError *error)
{
struct addrinfo hints;
struct addrinfo *ai, *tmp;
unsigned int reuseaddr;
+ dbus_bool_t have_ipv4 = FALSE;
+ dbus_bool_t have_ipv6 = FALSE;
*fds_p = NULL;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
listen_fd[nlisten_fd].fd = fd;
nlisten_fd++;
+ if (tmp->ai_addr->sa_family == AF_INET)
+ have_ipv4 = TRUE;
+ else if (tmp->ai_addr->sa_family == AF_INET6)
+ have_ipv6 = TRUE;
+
if (!_dbus_string_get_length(retport))
{
/* If the user didn't specify a port, or used 0, then
goto failed;
}
+ if (have_ipv4 && !have_ipv6)
+ *retfamily = "ipv4";
+ else if (!have_ipv4 && have_ipv6)
+ *retfamily = "ipv6";
+
for (i = 0 ; i < nlisten_fd ; i++)
{
if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
* @param port the port to listen on, if zero a free port will be used
* @param family the address family to listen on, NULL for all
* @param retport string to return the actual port listened on
+ * @param retfamily string to return the actual family listened on
* @param fds_p location to store returned file descriptors
* @param error return location for errors
* @returns the number of listening file descriptors or -1 on error
*/
-
int
_dbus_listen_tcp_socket (const char *host,
const char *port,
const char *family,
DBusString *retport,
+ const char **retfamily,
DBusSocket **fds_p,
DBusError *error)
{
DBusSocket *listen_fd = NULL;
struct addrinfo hints;
struct addrinfo *ai, *tmp;
+ dbus_bool_t have_ipv4 = FALSE;
+ dbus_bool_t have_ipv6 = FALSE;
// On Vista, sockaddr_gen must be a sockaddr_in6, and not a sockaddr_in6_old
//That's required for family == IPv6(which is the default on Vista if family is not given)
listen_fd[nlisten_fd] = fd;
nlisten_fd++;
+ if (tmp->ai_addr->sa_family == AF_INET)
+ have_ipv4 = TRUE;
+ else if (tmp->ai_addr->sa_family == AF_INET6)
+ have_ipv6 = TRUE;
+
if (!_dbus_string_get_length(retport))
{
/* If the user didn't specify a port, or used 0, then
goto failed;
}
+ if (have_ipv4 && !have_ipv6)
+ *retfamily = "ipv4";
+ else if (!have_ipv4 && have_ipv6)
+ *retfamily = "ipv6";
+
sscanf(_dbus_string_get_const_data(retport), "%d", &port_num);
for (i = 0 ; i < nlisten_fd ; i++)
const char *port,
const char *family,
DBusString *retport,
+ const char **retfamily,
DBusSocket **fds_p,
DBusError *error);
DBusSocket _dbus_accept (DBusSocket listen_fd);