mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-12-15 15:04:34 +08:00
obexd: Fix not closing socket when connection attempt fails
When connection attempt fails the socket were left opened as it is not assigned to the session, also when the connection does succeed the socket is closed twice when the session is removed. To fix those issues session now holds a reference to the GIOChannel returned bt bt_io_connect so that the connection can properly close when releasing, in addiction to that it also is marked to not close the socket when the connection succeeds so that when removing the session it doesn't close the socket twice. Thanks for Vitja Makarov <vitja.makarov@gmail.com> for reporting this.
This commit is contained in:
parent
ef84cfa6e2
commit
27906878d9
@ -173,8 +173,10 @@ static void session_free(struct session_data *session)
|
||||
if (session->obex != NULL)
|
||||
gw_obex_close(session->obex);
|
||||
|
||||
if (session->sock > 2)
|
||||
close(session->sock);
|
||||
if (session->io != NULL) {
|
||||
g_io_channel_shutdown(session->io, TRUE, NULL);
|
||||
g_io_channel_unref(session->io);
|
||||
}
|
||||
|
||||
if (session->path)
|
||||
session_unregistered(session);
|
||||
@ -215,13 +217,17 @@ static void rfcomm_callback(GIOChannel *io, GError *err, gpointer user_data)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* do not close when gw_obex is using the fd */
|
||||
g_io_channel_set_close_on_unref(session->io, FALSE);
|
||||
g_io_channel_unref(session->io);
|
||||
session->io = NULL;
|
||||
|
||||
fd = g_io_channel_unix_get_fd(io);
|
||||
|
||||
obex = gw_obex_setup_fd(fd, session->target,
|
||||
session->target_len, NULL, NULL);
|
||||
|
||||
callback->session->sock = fd;
|
||||
callback->session->obex = obex;
|
||||
session->obex = obex;
|
||||
|
||||
done:
|
||||
callback->func(callback->session, callback->data);
|
||||
@ -231,9 +237,9 @@ done:
|
||||
g_free(callback);
|
||||
}
|
||||
|
||||
static int rfcomm_connect(const bdaddr_t *src,
|
||||
const bdaddr_t *dst, uint8_t channel,
|
||||
BtIOConnect function, gpointer user_data)
|
||||
static GIOChannel *rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst,
|
||||
uint8_t channel, BtIOConnect function,
|
||||
gpointer user_data)
|
||||
{
|
||||
GIOChannel *io;
|
||||
GError *err = NULL;
|
||||
@ -245,11 +251,11 @@ static int rfcomm_connect(const bdaddr_t *src,
|
||||
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
|
||||
BT_IO_OPT_INVALID);
|
||||
if (io != NULL)
|
||||
return 0;
|
||||
return io;
|
||||
|
||||
error("%s", err->message);
|
||||
g_error_free(err);
|
||||
return -EIO;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void search_callback(uint8_t type, uint16_t status,
|
||||
@ -309,8 +315,11 @@ static void search_callback(uint8_t type, uint16_t status,
|
||||
|
||||
callback->session->channel = channel;
|
||||
|
||||
if (rfcomm_connect(&callback->session->src, &callback->session->dst,
|
||||
channel, rfcomm_callback, callback) == 0) {
|
||||
callback->session->io = rfcomm_connect(&callback->session->src,
|
||||
&callback->session->dst,
|
||||
channel, rfcomm_callback,
|
||||
callback);
|
||||
if (callback->session->io != NULL) {
|
||||
sdp_close(callback->sdp);
|
||||
return;
|
||||
}
|
||||
@ -418,7 +427,6 @@ struct session_data *session_create(const char *source,
|
||||
return NULL;
|
||||
|
||||
session->refcount = 1;
|
||||
session->sock = -1;
|
||||
session->channel = channel;
|
||||
|
||||
session->conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
|
||||
@ -465,8 +473,11 @@ struct session_data *session_create(const char *source,
|
||||
callback->data = user_data;
|
||||
|
||||
if (session->channel > 0) {
|
||||
err = rfcomm_connect(&session->src, &session->dst,
|
||||
session->channel, rfcomm_callback, callback);
|
||||
session->io = rfcomm_connect(&session->src, &session->dst,
|
||||
session->channel,
|
||||
rfcomm_callback,
|
||||
callback);
|
||||
err = (session->io == NULL) ? -EINVAL : 0;
|
||||
} else {
|
||||
callback->sdp = service_connect(&session->src, &session->dst,
|
||||
service_callback, callback);
|
||||
|
@ -40,10 +40,10 @@ struct session_data {
|
||||
int target_len;
|
||||
uuid_t uuid; /* Bluetooth Service Class */
|
||||
gchar *path; /* Session path */
|
||||
int sock;
|
||||
DBusConnection *conn;
|
||||
DBusMessage *msg;
|
||||
GwObex *obex;
|
||||
GIOChannel *io;
|
||||
struct agent_data *agent;
|
||||
struct session_callback *callback;
|
||||
gchar *owner; /* Session owner */
|
||||
|
Loading…
Reference in New Issue
Block a user