Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions client/qdb-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,22 +104,49 @@ static int connect_to_daemon(struct qdb_handle *qh) {
int len;
int fd;

/* Try RW socket first */
if ((fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1) {
perror("socket");
goto error;
}

remote.sun_family = AF_UNIX;
if (qh->vmname) {
snprintf(remote.sun_path, sizeof(remote.sun_path), QDB_DAEMON_PATH_PATTERN, qh->vmname);
snprintf(remote.sun_path, sizeof(remote.sun_path), QDB_DAEMON_PATH_RW_PATTERN, qh->vmname);
} else {
snprintf(remote.sun_path, sizeof(remote.sun_path), QDB_DAEMON_LOCAL_PATH);
snprintf(remote.sun_path, sizeof(remote.sun_path), QDB_DAEMON_LOCAL_RW_PATH);
}

len = strlen(remote.sun_path) + sizeof(remote.sun_family);
if (connect(fd, (struct sockaddr *) &remote, len) == -1) {
if (connect(fd, (struct sockaddr *) &remote, len) != -1) {
goto success;
}

/* Cleanup if that fails */
if (fd >= 0)
close(fd);

/* Try RO socket next */
if ((fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1) {
perror("socket");
goto error;
}

remote.sun_family = AF_UNIX;
if (qh->vmname) {
snprintf(remote.sun_path, sizeof(remote.sun_path), QDB_DAEMON_PATH_RO_PATTERN, qh->vmname);
} else {
snprintf(remote.sun_path, sizeof(remote.sun_path), QDB_DAEMON_LOCAL_RO_PATH);
}

len = strlen(remote.sun_path) + sizeof(remote.sun_family);
if (connect(fd, (struct sockaddr *) &remote, len) != -1) {
goto success;
}

goto error;

success:
qh->fd = fd;
return 1;

Expand Down
14 changes: 14 additions & 0 deletions daemon/db-cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,13 @@ static int handle_write(struct db_daemon_data *d, struct client *client,
char untrusted_data[QDB_MAX_DATA];
char *data;

#ifndef _WIN32
if (client != NULL && !client->can_write) {
fprintf(stderr, "write attempted by read-only client\n");
return discard_data_and_send_error(d, client, hdr);
}
#endif

if (!read_vchan_or_client(d, client, untrusted_data, hdr->data_len)) {
return 0;
}
Expand Down Expand Up @@ -448,6 +455,13 @@ static int handle_write(struct db_daemon_data *d, struct client *client,
/* this command is valid on both client socket and vchan */
static int handle_rm(struct db_daemon_data *d, struct client *client,
struct qdb_hdr *hdr) {
#ifndef _WIN32
if (client != NULL && !client->can_write) {
fprintf(stderr, "write attempted by read-only client\n");
return discard_data_and_send_error(d, client, hdr);
}
#endif

if (hdr->data_len > 0) {
fprintf(stderr, "CMD_RM shouldn't have data field\n");
/* recovery path */
Expand Down
Loading